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 127ed6184dfSmrg/* Check if a modifier map change is okay with the device. Negative return 128ed6184dfSmrg * values mean BadValue, positive values mean Mapping{Busy,Failed}, 0 is 129ed6184dfSmrg * Success / MappingSuccess. 130ed6184dfSmrg */ 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 /* None of the new modifiers may be down while we change the 1576747b715Smrg * map. */ 1586747b715Smrg if (key_is_down(dev, i, KEY_POSTED | KEY_PROCESSED)) { 1596747b715Smrg client->errorValue = i; 1606747b715Smrg return MappingBusy; 1616747b715Smrg } 1626747b715Smrg } 1636747b715Smrg 1646747b715Smrg /* None of the old modifiers may be down while we change the map, 1656747b715Smrg * either. */ 1666747b715Smrg for (i = xkb->min_key_code; i < xkb->max_key_code; i++) { 1676747b715Smrg if (!xkb->map->modmap[i]) 1686747b715Smrg continue; 1696747b715Smrg if (key_is_down(dev, i, KEY_POSTED | KEY_PROCESSED)) { 1706747b715Smrg client->errorValue = i; 1716747b715Smrg return MappingBusy; 1726747b715Smrg } 1736747b715Smrg } 1746747b715Smrg 1756747b715Smrg return Success; 1766747b715Smrg} 1776747b715Smrg 1786747b715Smrgstatic int 1796747b715Smrgcheck_modmap_change_slave(ClientPtr client, DeviceIntPtr master, 1806747b715Smrg DeviceIntPtr slave, CARD8 *modmap) 1816747b715Smrg{ 1826747b715Smrg XkbDescPtr master_xkb, slave_xkb; 1836747b715Smrg int i, j; 1846747b715Smrg 1856747b715Smrg if (!slave->key || !master->key) 1866747b715Smrg return 0; 1876747b715Smrg 1886747b715Smrg master_xkb = master->key->xkbInfo->desc; 1896747b715Smrg slave_xkb = slave->key->xkbInfo->desc; 1906747b715Smrg 1916747b715Smrg /* Ignore devices with a clearly different keymap. */ 1926747b715Smrg if (slave_xkb->min_key_code != master_xkb->min_key_code || 1936747b715Smrg slave_xkb->max_key_code != master_xkb->max_key_code) 1946747b715Smrg return 0; 1956747b715Smrg 1966747b715Smrg for (i = 0; i < MAP_LENGTH; i++) { 1976747b715Smrg if (!modmap[i]) 1986747b715Smrg continue; 1996747b715Smrg 2006747b715Smrg /* If we have different symbols for any modifier on an 2016747b715Smrg * extended keyboard, ignore the whole remap request. */ 2026747b715Smrg for (j = 0; 2036747b715Smrg j < XkbKeyNumSyms(slave_xkb, i) && 20435c4bbdfSmrg j < XkbKeyNumSyms(master_xkb, i); j++) 20535c4bbdfSmrg if (XkbKeySymsPtr(slave_xkb, i)[j] != 20635c4bbdfSmrg XkbKeySymsPtr(master_xkb, i)[j]) 2076747b715Smrg return 0; 2086747b715Smrg } 2096747b715Smrg 2106747b715Smrg if (check_modmap_change(client, slave, modmap) != Success) 2116747b715Smrg return 0; 2126747b715Smrg 2136747b715Smrg return 1; 2146747b715Smrg} 2156747b715Smrg 2166747b715Smrg/* Actually change the modifier map, and send notifications. Cannot fail. */ 2176747b715Smrgstatic void 2186747b715Smrgdo_modmap_change(ClientPtr client, DeviceIntPtr dev, CARD8 *modmap) 2196747b715Smrg{ 2206747b715Smrg XkbApplyMappingChange(dev, NULL, 0, 0, modmap, serverClient); 2216747b715Smrg} 2226747b715Smrg 2236747b715Smrg/* Rebuild modmap (key -> mod) from map (mod -> key). */ 22435c4bbdfSmrgstatic int 22535c4bbdfSmrgbuild_modmap_from_modkeymap(CARD8 *modmap, KeyCode *modkeymap, 22635c4bbdfSmrg int max_keys_per_mod) 2276747b715Smrg{ 2286747b715Smrg int i, len = max_keys_per_mod * 8; 2296747b715Smrg 2306747b715Smrg memset(modmap, 0, MAP_LENGTH); 2316747b715Smrg 2326747b715Smrg for (i = 0; i < len; i++) { 2336747b715Smrg if (!modkeymap[i]) 2346747b715Smrg continue; 2356747b715Smrg 23635c4bbdfSmrg#if MAP_LENGTH < 256 2376747b715Smrg if (modkeymap[i] >= MAP_LENGTH) 2386747b715Smrg return BadValue; 23935c4bbdfSmrg#endif 2406747b715Smrg 2416747b715Smrg if (modmap[modkeymap[i]]) 2426747b715Smrg return BadValue; 2436747b715Smrg 2446747b715Smrg modmap[modkeymap[i]] = 1 << (i / max_keys_per_mod); 2456747b715Smrg } 2466747b715Smrg 2476747b715Smrg return Success; 2486747b715Smrg} 2496747b715Smrg 2506747b715Smrgint 2516747b715Smrgchange_modmap(ClientPtr client, DeviceIntPtr dev, KeyCode *modkeymap, 2526747b715Smrg int max_keys_per_mod) 2536747b715Smrg{ 2546747b715Smrg int ret; 2556747b715Smrg CARD8 modmap[MAP_LENGTH]; 2566747b715Smrg DeviceIntPtr tmp; 2576747b715Smrg 2586747b715Smrg ret = build_modmap_from_modkeymap(modmap, modkeymap, max_keys_per_mod); 2596747b715Smrg if (ret != Success) 2606747b715Smrg return ret; 2616747b715Smrg 2626747b715Smrg /* If we can't perform the change on the requested device, bail out. */ 2636747b715Smrg ret = check_modmap_change(client, dev, modmap); 2646747b715Smrg if (ret != Success) 2656747b715Smrg return ret; 2666747b715Smrg do_modmap_change(client, dev, modmap); 2676747b715Smrg 2686747b715Smrg /* Change any attached masters/slaves. */ 2696747b715Smrg if (IsMaster(dev)) { 2706747b715Smrg for (tmp = inputInfo.devices; tmp; tmp = tmp->next) { 27135c4bbdfSmrg if (!IsMaster(tmp) && GetMaster(tmp, MASTER_KEYBOARD) == dev) 2726747b715Smrg if (check_modmap_change_slave(client, dev, tmp, modmap)) 2736747b715Smrg do_modmap_change(client, tmp, modmap); 2746747b715Smrg } 2756747b715Smrg } 27635c4bbdfSmrg else if (!IsFloating(dev) && 27735c4bbdfSmrg GetMaster(dev, MASTER_KEYBOARD)->lastSlave == dev) { 2786747b715Smrg /* If this fails, expect the results to be weird. */ 2791b5d61b8Smrg if (check_modmap_change(client, dev->master, modmap) == Success) 28035c4bbdfSmrg do_modmap_change(client, dev->master, modmap); 2816747b715Smrg } 2826747b715Smrg 2836747b715Smrg return Success; 2846747b715Smrg} 2856747b715Smrg 28635c4bbdfSmrgint 28735c4bbdfSmrggenerate_modkeymap(ClientPtr client, DeviceIntPtr dev, 28835c4bbdfSmrg KeyCode **modkeymap_out, int *max_keys_per_mod_out) 2896747b715Smrg{ 2906747b715Smrg CARD8 keys_per_mod[8]; 2916747b715Smrg int max_keys_per_mod; 2928223e2f2Smrg KeyCode *modkeymap = NULL; 2936747b715Smrg int i, j, ret; 2946747b715Smrg 2956747b715Smrg ret = XaceHook(XACE_DEVICE_ACCESS, client, dev, DixGetAttrAccess); 2966747b715Smrg if (ret != Success) 2976747b715Smrg return ret; 2986747b715Smrg 2996747b715Smrg if (!dev->key) 3006747b715Smrg return BadMatch; 3016747b715Smrg 3026747b715Smrg /* Count the number of keys per modifier to determine how wide we 3036747b715Smrg * should make the map. */ 3046747b715Smrg max_keys_per_mod = 0; 3056747b715Smrg for (i = 0; i < 8; i++) 3066747b715Smrg keys_per_mod[i] = 0; 3076747b715Smrg for (i = 8; i < MAP_LENGTH; i++) { 3086747b715Smrg for (j = 0; j < 8; j++) { 3096747b715Smrg if (dev->key->xkbInfo->desc->map->modmap[i] & (1 << j)) { 3106747b715Smrg if (++keys_per_mod[j] > max_keys_per_mod) 3116747b715Smrg max_keys_per_mod = keys_per_mod[j]; 3126747b715Smrg } 3136747b715Smrg } 3146747b715Smrg } 3156747b715Smrg 3168223e2f2Smrg if (max_keys_per_mod != 0) { 3178223e2f2Smrg modkeymap = calloc(max_keys_per_mod * 8, sizeof(KeyCode)); 3188223e2f2Smrg if (!modkeymap) 3198223e2f2Smrg return BadAlloc; 3206747b715Smrg 3218223e2f2Smrg for (i = 0; i < 8; i++) 3228223e2f2Smrg keys_per_mod[i] = 0; 3236747b715Smrg 3248223e2f2Smrg for (i = 8; i < MAP_LENGTH; i++) { 3258223e2f2Smrg for (j = 0; j < 8; j++) { 3268223e2f2Smrg if (dev->key->xkbInfo->desc->map->modmap[i] & (1 << j)) { 3278223e2f2Smrg modkeymap[(j * max_keys_per_mod) + keys_per_mod[j]] = i; 3288223e2f2Smrg keys_per_mod[j]++; 3298223e2f2Smrg } 3306747b715Smrg } 3316747b715Smrg } 3326747b715Smrg } 3336747b715Smrg 3346747b715Smrg *max_keys_per_mod_out = max_keys_per_mod; 3356747b715Smrg *modkeymap_out = modkeymap; 3366747b715Smrg 3376747b715Smrg return Success; 3386747b715Smrg} 3396747b715Smrg 3406747b715Smrg/** 3416747b715Smrg * Duplicate the InputAttributes in the most obvious way. 3426747b715Smrg * No special memory handling is used to give drivers the maximum 3436747b715Smrg * flexibility with the data. Drivers should be able to call realloc on the 3446747b715Smrg * product string if needed and perform similar operations. 3456747b715Smrg */ 34635c4bbdfSmrgInputAttributes * 34735c4bbdfSmrgDuplicateInputAttributes(InputAttributes * attrs) 3486747b715Smrg{ 3496747b715Smrg InputAttributes *new_attr; 3506747b715Smrg int ntags = 0; 3516747b715Smrg char **tags, **new_tags; 3526747b715Smrg 3536747b715Smrg if (!attrs) 3546747b715Smrg return NULL; 3556747b715Smrg 3566747b715Smrg if (!(new_attr = calloc(1, sizeof(InputAttributes)))) 3576747b715Smrg goto unwind; 3586747b715Smrg 3596747b715Smrg if (attrs->product && !(new_attr->product = strdup(attrs->product))) 3606747b715Smrg goto unwind; 3616747b715Smrg if (attrs->vendor && !(new_attr->vendor = strdup(attrs->vendor))) 3626747b715Smrg goto unwind; 3636747b715Smrg if (attrs->device && !(new_attr->device = strdup(attrs->device))) 3646747b715Smrg goto unwind; 3656747b715Smrg if (attrs->pnp_id && !(new_attr->pnp_id = strdup(attrs->pnp_id))) 3666747b715Smrg goto unwind; 3676747b715Smrg if (attrs->usb_id && !(new_attr->usb_id = strdup(attrs->usb_id))) 3686747b715Smrg goto unwind; 3696747b715Smrg 3706747b715Smrg new_attr->flags = attrs->flags; 3716747b715Smrg 37235c4bbdfSmrg if ((tags = attrs->tags)) { 37335c4bbdfSmrg while (*tags++) 3746747b715Smrg ntags++; 3756747b715Smrg 37635c4bbdfSmrg new_attr->tags = calloc(ntags + 1, sizeof(char *)); 3776747b715Smrg if (!new_attr->tags) 3786747b715Smrg goto unwind; 3796747b715Smrg 3806747b715Smrg tags = attrs->tags; 3816747b715Smrg new_tags = new_attr->tags; 3826747b715Smrg 38335c4bbdfSmrg while (*tags) { 3846747b715Smrg *new_tags = strdup(*tags); 3856747b715Smrg if (!*new_tags) 3866747b715Smrg goto unwind; 3876747b715Smrg 3886747b715Smrg tags++; 3896747b715Smrg new_tags++; 3906747b715Smrg } 3916747b715Smrg } 3926747b715Smrg 3936747b715Smrg return new_attr; 3946747b715Smrg 39535c4bbdfSmrg unwind: 3966747b715Smrg FreeInputAttributes(new_attr); 3976747b715Smrg return NULL; 3986747b715Smrg} 3996747b715Smrg 4006747b715Smrgvoid 40135c4bbdfSmrgFreeInputAttributes(InputAttributes * attrs) 4026747b715Smrg{ 4036747b715Smrg char **tags; 4046747b715Smrg 4056747b715Smrg if (!attrs) 4066747b715Smrg return; 4076747b715Smrg 4086747b715Smrg free(attrs->product); 4096747b715Smrg free(attrs->vendor); 4106747b715Smrg free(attrs->device); 4116747b715Smrg free(attrs->pnp_id); 4126747b715Smrg free(attrs->usb_id); 4136747b715Smrg 4146747b715Smrg if ((tags = attrs->tags)) 41535c4bbdfSmrg while (*tags) 4166747b715Smrg free(*tags++); 4176747b715Smrg 4186747b715Smrg free(attrs->tags); 4196747b715Smrg free(attrs); 4206747b715Smrg} 4216747b715Smrg 4229ace9065Smrg/** 4239ace9065Smrg * Alloc a valuator mask large enough for num_valuators. 4249ace9065Smrg */ 42535c4bbdfSmrgValuatorMask * 4269ace9065Smrgvaluator_mask_new(int num_valuators) 4279ace9065Smrg{ 4289ace9065Smrg /* alloc a fixed size mask for now and ignore num_valuators. in the 4299ace9065Smrg * flying-car future, when we can dynamically alloc the masks and are 4309ace9065Smrg * not constrained by signals, we can start using num_valuators */ 4319ace9065Smrg ValuatorMask *mask = calloc(1, sizeof(ValuatorMask)); 43235c4bbdfSmrg 43335c4bbdfSmrg if (mask == NULL) 43435c4bbdfSmrg return NULL; 43535c4bbdfSmrg 4369ace9065Smrg mask->last_bit = -1; 4379ace9065Smrg return mask; 4389ace9065Smrg} 4399ace9065Smrg 4409ace9065Smrgvoid 4419ace9065Smrgvaluator_mask_free(ValuatorMask **mask) 4429ace9065Smrg{ 4439ace9065Smrg free(*mask); 4449ace9065Smrg *mask = NULL; 4459ace9065Smrg} 4469ace9065Smrg 4479ace9065Smrg/** 4489ace9065Smrg * Sets a range of valuators between first_valuator and num_valuators with 4499ace9065Smrg * the data in the valuators array. All other values are set to 0. 4509ace9065Smrg */ 4519ace9065Smrgvoid 45235c4bbdfSmrgvaluator_mask_set_range(ValuatorMask *mask, int first_valuator, 45335c4bbdfSmrg int num_valuators, const int *valuators) 4549ace9065Smrg{ 4559ace9065Smrg int i; 4569ace9065Smrg 4579ace9065Smrg valuator_mask_zero(mask); 4589ace9065Smrg 45935c4bbdfSmrg for (i = first_valuator; 46035c4bbdfSmrg i < min(first_valuator + num_valuators, MAX_VALUATORS); i++) 4619ace9065Smrg valuator_mask_set(mask, i, valuators[i - first_valuator]); 4629ace9065Smrg} 4639ace9065Smrg 4649ace9065Smrg/** 4659ace9065Smrg * Reset mask to zero. 4669ace9065Smrg */ 4679ace9065Smrgvoid 4689ace9065Smrgvaluator_mask_zero(ValuatorMask *mask) 4699ace9065Smrg{ 4709ace9065Smrg memset(mask, 0, sizeof(*mask)); 4719ace9065Smrg mask->last_bit = -1; 4729ace9065Smrg} 4739ace9065Smrg 4749ace9065Smrg/** 4759ace9065Smrg * Returns the current size of the mask (i.e. the highest number of 4769ace9065Smrg * valuators currently set + 1). 4779ace9065Smrg */ 4789ace9065Smrgint 4799ace9065Smrgvaluator_mask_size(const ValuatorMask *mask) 4809ace9065Smrg{ 4819ace9065Smrg return mask->last_bit + 1; 4829ace9065Smrg} 4839ace9065Smrg 4849ace9065Smrg/** 4859ace9065Smrg * Returns the number of valuators set in the given mask. 4869ace9065Smrg */ 4879ace9065Smrgint 4889ace9065Smrgvaluator_mask_num_valuators(const ValuatorMask *mask) 4899ace9065Smrg{ 4909ace9065Smrg return CountBits(mask->mask, min(mask->last_bit + 1, MAX_VALUATORS)); 4919ace9065Smrg} 4929ace9065Smrg 4939ace9065Smrg/** 4949ace9065Smrg * Return true if the valuator is set in the mask, or false otherwise. 4959ace9065Smrg */ 4969ace9065Smrgint 4979ace9065Smrgvaluator_mask_isset(const ValuatorMask *mask, int valuator) 4989ace9065Smrg{ 4999ace9065Smrg return mask->last_bit >= valuator && BitIsOn(mask->mask, valuator); 5009ace9065Smrg} 5019ace9065Smrg 50235c4bbdfSmrgstatic inline void 50335c4bbdfSmrg_valuator_mask_set_double(ValuatorMask *mask, int valuator, double data) 50435c4bbdfSmrg{ 50535c4bbdfSmrg mask->last_bit = max(valuator, mask->last_bit); 50635c4bbdfSmrg SetBit(mask->mask, valuator); 50735c4bbdfSmrg mask->valuators[valuator] = data; 50835c4bbdfSmrg} 50935c4bbdfSmrg 5109ace9065Smrg/** 51135c4bbdfSmrg * Set the valuator to the given floating-point data. 51235c4bbdfSmrg */ 51335c4bbdfSmrgvoid 51435c4bbdfSmrgvaluator_mask_set_double(ValuatorMask *mask, int valuator, double data) 51535c4bbdfSmrg{ 51635c4bbdfSmrg BUG_WARN_MSG(mask->has_unaccelerated, 51735c4bbdfSmrg "Do not mix valuator types, zero mask first\n"); 51835c4bbdfSmrg _valuator_mask_set_double(mask, valuator, data); 51935c4bbdfSmrg} 52035c4bbdfSmrg 52135c4bbdfSmrg/** 52235c4bbdfSmrg * Set the valuator to the given integer data. 5239ace9065Smrg */ 5249ace9065Smrgvoid 5259ace9065Smrgvaluator_mask_set(ValuatorMask *mask, int valuator, int data) 5269ace9065Smrg{ 52735c4bbdfSmrg valuator_mask_set_double(mask, valuator, data); 52835c4bbdfSmrg} 52935c4bbdfSmrg 53035c4bbdfSmrg/** 53135c4bbdfSmrg * Return the requested valuator value as a double. If the mask bit is not 53235c4bbdfSmrg * set for the given valuator, the returned value is undefined. 53335c4bbdfSmrg */ 53435c4bbdfSmrgdouble 53535c4bbdfSmrgvaluator_mask_get_double(const ValuatorMask *mask, int valuator) 53635c4bbdfSmrg{ 53735c4bbdfSmrg return mask->valuators[valuator]; 5389ace9065Smrg} 5399ace9065Smrg 5409ace9065Smrg/** 54135c4bbdfSmrg * Return the requested valuator value as an integer, rounding towards zero. 54235c4bbdfSmrg * If the mask bit is not set for the given valuator, the returned value is 54335c4bbdfSmrg * undefined. 5449ace9065Smrg */ 5459ace9065Smrgint 5469ace9065Smrgvaluator_mask_get(const ValuatorMask *mask, int valuator) 5479ace9065Smrg{ 54835c4bbdfSmrg return trunc(valuator_mask_get_double(mask, valuator)); 54935c4bbdfSmrg} 55035c4bbdfSmrg 55135c4bbdfSmrg/** 55235c4bbdfSmrg * Set value to the requested valuator. If the mask bit is set for this 55335c4bbdfSmrg * valuator, value contains the requested valuator value and TRUE is 55435c4bbdfSmrg * returned. 55535c4bbdfSmrg * If the mask bit is not set for this valuator, value is unchanged and 55635c4bbdfSmrg * FALSE is returned. 55735c4bbdfSmrg */ 55835c4bbdfSmrgBool 55935c4bbdfSmrgvaluator_mask_fetch_double(const ValuatorMask *mask, int valuator, 56035c4bbdfSmrg double *value) 56135c4bbdfSmrg{ 56235c4bbdfSmrg if (valuator_mask_isset(mask, valuator)) { 56335c4bbdfSmrg *value = valuator_mask_get_double(mask, valuator); 56435c4bbdfSmrg return TRUE; 56535c4bbdfSmrg } 56635c4bbdfSmrg else 56735c4bbdfSmrg return FALSE; 56835c4bbdfSmrg} 56935c4bbdfSmrg 57035c4bbdfSmrg/** 57135c4bbdfSmrg * Set value to the requested valuator. If the mask bit is set for this 57235c4bbdfSmrg * valuator, value contains the requested valuator value and TRUE is 57335c4bbdfSmrg * returned. 57435c4bbdfSmrg * If the mask bit is not set for this valuator, value is unchanged and 57535c4bbdfSmrg * FALSE is returned. 57635c4bbdfSmrg */ 57735c4bbdfSmrgBool 57835c4bbdfSmrgvaluator_mask_fetch(const ValuatorMask *mask, int valuator, int *value) 57935c4bbdfSmrg{ 58035c4bbdfSmrg if (valuator_mask_isset(mask, valuator)) { 58135c4bbdfSmrg *value = valuator_mask_get(mask, valuator); 58235c4bbdfSmrg return TRUE; 58335c4bbdfSmrg } 58435c4bbdfSmrg else 58535c4bbdfSmrg return FALSE; 5869ace9065Smrg} 5879ace9065Smrg 5889ace9065Smrg/** 5899ace9065Smrg * Remove the valuator from the mask. 5909ace9065Smrg */ 5919ace9065Smrgvoid 5929ace9065Smrgvaluator_mask_unset(ValuatorMask *mask, int valuator) 5939ace9065Smrg{ 5949ace9065Smrg if (mask->last_bit >= valuator) { 5959ace9065Smrg int i, lastbit = -1; 5969ace9065Smrg 5979ace9065Smrg ClearBit(mask->mask, valuator); 59835c4bbdfSmrg mask->valuators[valuator] = 0.0; 59935c4bbdfSmrg mask->unaccelerated[valuator] = 0.0; 6009ace9065Smrg 6019ace9065Smrg for (i = 0; i <= mask->last_bit; i++) 6029ace9065Smrg if (valuator_mask_isset(mask, i)) 6039ace9065Smrg lastbit = max(lastbit, i); 6049ace9065Smrg mask->last_bit = lastbit; 60535c4bbdfSmrg 60635c4bbdfSmrg if (mask->last_bit == -1) 60735c4bbdfSmrg mask->has_unaccelerated = FALSE; 6089ace9065Smrg } 6099ace9065Smrg} 6109ace9065Smrg 6119ace9065Smrgvoid 6129ace9065Smrgvaluator_mask_copy(ValuatorMask *dest, const ValuatorMask *src) 6139ace9065Smrg{ 6149ace9065Smrg if (src) 6159ace9065Smrg memcpy(dest, src, sizeof(*dest)); 6169ace9065Smrg else 6179ace9065Smrg valuator_mask_zero(dest); 6189ace9065Smrg} 6199ace9065Smrg 62035c4bbdfSmrgBool 62135c4bbdfSmrgvaluator_mask_has_unaccelerated(const ValuatorMask *mask) 62235c4bbdfSmrg{ 62335c4bbdfSmrg return mask->has_unaccelerated; 62435c4bbdfSmrg} 62535c4bbdfSmrg 62635c4bbdfSmrgvoid 62735c4bbdfSmrgvaluator_mask_drop_unaccelerated(ValuatorMask *mask) 62835c4bbdfSmrg{ 62935c4bbdfSmrg memset(mask->unaccelerated, 0, sizeof(mask->unaccelerated)); 63035c4bbdfSmrg mask->has_unaccelerated = FALSE; 63135c4bbdfSmrg} 63235c4bbdfSmrg 6331b5d61b8Smrgvoid 6341b5d61b8Smrgvaluator_mask_set_absolute_unaccelerated(ValuatorMask *mask, 6351b5d61b8Smrg int valuator, 6361b5d61b8Smrg int absolute, 6371b5d61b8Smrg double unaccel) 6381b5d61b8Smrg{ 6391b5d61b8Smrg BUG_WARN_MSG(mask->last_bit != -1 && !mask->has_unaccelerated, 6401b5d61b8Smrg "Do not mix valuator types, zero mask first\n"); 6411b5d61b8Smrg _valuator_mask_set_double(mask, valuator, absolute); 6421b5d61b8Smrg mask->has_unaccelerated = TRUE; 6431b5d61b8Smrg mask->unaccelerated[valuator] = unaccel; 6441b5d61b8Smrg} 6451b5d61b8Smrg 64635c4bbdfSmrg/** 64735c4bbdfSmrg * Set both accelerated and unaccelerated value for this mask. 64835c4bbdfSmrg */ 64935c4bbdfSmrgvoid 65035c4bbdfSmrgvaluator_mask_set_unaccelerated(ValuatorMask *mask, 65135c4bbdfSmrg int valuator, 65235c4bbdfSmrg double accel, 65335c4bbdfSmrg double unaccel) 65435c4bbdfSmrg{ 65535c4bbdfSmrg BUG_WARN_MSG(mask->last_bit != -1 && !mask->has_unaccelerated, 65635c4bbdfSmrg "Do not mix valuator types, zero mask first\n"); 65735c4bbdfSmrg _valuator_mask_set_double(mask, valuator, accel); 65835c4bbdfSmrg mask->has_unaccelerated = TRUE; 65935c4bbdfSmrg mask->unaccelerated[valuator] = unaccel; 66035c4bbdfSmrg} 66135c4bbdfSmrg 66235c4bbdfSmrgdouble 66335c4bbdfSmrgvaluator_mask_get_accelerated(const ValuatorMask *mask, 66435c4bbdfSmrg int valuator) 66535c4bbdfSmrg{ 66635c4bbdfSmrg return valuator_mask_get_double(mask, valuator); 66735c4bbdfSmrg} 66835c4bbdfSmrg 66935c4bbdfSmrgdouble 67035c4bbdfSmrgvaluator_mask_get_unaccelerated(const ValuatorMask *mask, 67135c4bbdfSmrg int valuator) 67235c4bbdfSmrg{ 67335c4bbdfSmrg return mask->unaccelerated[valuator]; 67435c4bbdfSmrg} 67535c4bbdfSmrg 67635c4bbdfSmrgBool 67735c4bbdfSmrgvaluator_mask_fetch_unaccelerated(const ValuatorMask *mask, 67835c4bbdfSmrg int valuator, 67935c4bbdfSmrg double *accel, 68035c4bbdfSmrg double *unaccel) 68135c4bbdfSmrg{ 68235c4bbdfSmrg if (valuator_mask_isset(mask, valuator)) { 68335c4bbdfSmrg if (accel) 68435c4bbdfSmrg *accel = valuator_mask_get_accelerated(mask, valuator); 68535c4bbdfSmrg if (unaccel) 68635c4bbdfSmrg *unaccel = valuator_mask_get_unaccelerated(mask, valuator); 68735c4bbdfSmrg return TRUE; 68835c4bbdfSmrg } 68935c4bbdfSmrg else 69035c4bbdfSmrg return FALSE; 69135c4bbdfSmrg} 69235c4bbdfSmrg 6939ace9065Smrgint 69435c4bbdfSmrgCountBits(const uint8_t * mask, int len) 6959ace9065Smrg{ 6969ace9065Smrg int i; 6979ace9065Smrg int ret = 0; 6989ace9065Smrg 6999ace9065Smrg for (i = 0; i < len; i++) 7009ace9065Smrg if (BitIsOn(mask, i)) 7019ace9065Smrg ret++; 7029ace9065Smrg 7039ace9065Smrg return ret; 7049ace9065Smrg} 70535c4bbdfSmrg 70635c4bbdfSmrg/** 70735c4bbdfSmrg * Verifies sanity of the event. If the event is not an internal event, 70835c4bbdfSmrg * memdumps the first 32 bytes of event to the log, a backtrace, then kill 70935c4bbdfSmrg * the server. 71035c4bbdfSmrg */ 71135c4bbdfSmrgvoid 71235c4bbdfSmrgverify_internal_event(const InternalEvent *ev) 71335c4bbdfSmrg{ 71435c4bbdfSmrg if (ev && ev->any.header != ET_Internal) { 71535c4bbdfSmrg int i; 71635c4bbdfSmrg const unsigned char *data = (const unsigned char *) ev; 71735c4bbdfSmrg 71835c4bbdfSmrg ErrorF("dix: invalid event type %d\n", ev->any.header); 71935c4bbdfSmrg 72035c4bbdfSmrg for (i = 0; i < sizeof(xEvent); i++, data++) { 72135c4bbdfSmrg ErrorF("%02hhx ", *data); 72235c4bbdfSmrg 72335c4bbdfSmrg if ((i % 8) == 7) 72435c4bbdfSmrg ErrorF("\n"); 72535c4bbdfSmrg } 72635c4bbdfSmrg 72735c4bbdfSmrg xorg_backtrace(); 72835c4bbdfSmrg FatalError("Wrong event type %d. Aborting server\n", ev->any.header); 72935c4bbdfSmrg } 73035c4bbdfSmrg} 73135c4bbdfSmrg 73235c4bbdfSmrg/** 73335c4bbdfSmrg * Initializes the given event to zero (or default values), for the given 73435c4bbdfSmrg * device. 73535c4bbdfSmrg */ 73635c4bbdfSmrgvoid 7371b5d61b8Smrginit_device_event(DeviceEvent *event, DeviceIntPtr dev, Time ms, 7381b5d61b8Smrg enum DeviceEventSource source_type) 73935c4bbdfSmrg{ 74035c4bbdfSmrg memset(event, 0, sizeof(DeviceEvent)); 74135c4bbdfSmrg event->header = ET_Internal; 74235c4bbdfSmrg event->length = sizeof(DeviceEvent); 74335c4bbdfSmrg event->time = ms; 74435c4bbdfSmrg event->deviceid = dev->id; 74535c4bbdfSmrg event->sourceid = dev->id; 7461b5d61b8Smrg event->source_type = source_type; 74735c4bbdfSmrg} 74835c4bbdfSmrg 749ed6184dfSmrg/** 750ed6184dfSmrg * Initializes the given gesture event to zero (or default values), 751ed6184dfSmrg * for the given device. 752ed6184dfSmrg */ 753ed6184dfSmrgvoid 754ed6184dfSmrginit_gesture_event(GestureEvent *event, DeviceIntPtr dev, Time ms) 755ed6184dfSmrg{ 756ed6184dfSmrg memset(event, 0, sizeof(GestureEvent)); 757ed6184dfSmrg event->header = ET_Internal; 758ed6184dfSmrg event->length = sizeof(GestureEvent); 759ed6184dfSmrg event->time = ms; 760ed6184dfSmrg event->deviceid = dev->id; 761ed6184dfSmrg event->sourceid = dev->id; 762ed6184dfSmrg} 763ed6184dfSmrg 76435c4bbdfSmrgint 76535c4bbdfSmrgevent_get_corestate(DeviceIntPtr mouse, DeviceIntPtr kbd) 76635c4bbdfSmrg{ 76735c4bbdfSmrg int corestate; 76835c4bbdfSmrg 76935c4bbdfSmrg /* core state needs to be assembled BEFORE the device is updated. */ 77035c4bbdfSmrg corestate = (kbd && 77135c4bbdfSmrg kbd->key) ? XkbStateFieldFromRec(&kbd->key->xkbInfo-> 77235c4bbdfSmrg state) : 0; 77335c4bbdfSmrg corestate |= (mouse && mouse->button) ? (mouse->button->state) : 0; 77435c4bbdfSmrg corestate |= (mouse && mouse->touch) ? (mouse->touch->state) : 0; 77535c4bbdfSmrg 77635c4bbdfSmrg return corestate; 77735c4bbdfSmrg} 77835c4bbdfSmrg 77935c4bbdfSmrgvoid 78035c4bbdfSmrgevent_set_state(DeviceIntPtr mouse, DeviceIntPtr kbd, DeviceEvent *event) 78135c4bbdfSmrg{ 78235c4bbdfSmrg int i; 78335c4bbdfSmrg 78435c4bbdfSmrg for (i = 0; mouse && mouse->button && i < mouse->button->numButtons; i++) 78535c4bbdfSmrg if (BitIsOn(mouse->button->down, i)) 78635c4bbdfSmrg SetBit(event->buttons, mouse->button->map[i]); 78735c4bbdfSmrg 78835c4bbdfSmrg if (mouse && mouse->touch && mouse->touch->buttonsDown > 0) 78935c4bbdfSmrg SetBit(event->buttons, mouse->button->map[1]); 79035c4bbdfSmrg 79135c4bbdfSmrg if (kbd && kbd->key) { 79235c4bbdfSmrg XkbStatePtr state; 79335c4bbdfSmrg 79435c4bbdfSmrg /* we need the state before the event happens */ 79535c4bbdfSmrg if (event->type == ET_KeyPress || event->type == ET_KeyRelease) 79635c4bbdfSmrg state = &kbd->key->xkbInfo->prev_state; 79735c4bbdfSmrg else 79835c4bbdfSmrg state = &kbd->key->xkbInfo->state; 79935c4bbdfSmrg 80035c4bbdfSmrg event->mods.base = state->base_mods; 80135c4bbdfSmrg event->mods.latched = state->latched_mods; 80235c4bbdfSmrg event->mods.locked = state->locked_mods; 80335c4bbdfSmrg event->mods.effective = state->mods; 80435c4bbdfSmrg 80535c4bbdfSmrg event->group.base = state->base_group; 80635c4bbdfSmrg event->group.latched = state->latched_group; 80735c4bbdfSmrg event->group.locked = state->locked_group; 80835c4bbdfSmrg event->group.effective = state->group; 80935c4bbdfSmrg } 81035c4bbdfSmrg} 81135c4bbdfSmrg 812ed6184dfSmrgvoid 813ed6184dfSmrgevent_set_state_gesture(DeviceIntPtr kbd, GestureEvent *event) 814ed6184dfSmrg{ 815ed6184dfSmrg if (kbd && kbd->key) { 816ed6184dfSmrg XkbStatePtr state= &kbd->key->xkbInfo->state; 817ed6184dfSmrg 818ed6184dfSmrg event->mods.base = state->base_mods; 819ed6184dfSmrg event->mods.latched = state->latched_mods; 820ed6184dfSmrg event->mods.locked = state->locked_mods; 821ed6184dfSmrg event->mods.effective = state->mods; 822ed6184dfSmrg 823ed6184dfSmrg event->group.base = state->base_group; 824ed6184dfSmrg event->group.latched = state->latched_group; 825ed6184dfSmrg event->group.locked = state->locked_group; 826ed6184dfSmrg event->group.effective = state->group; 827ed6184dfSmrg } 828ed6184dfSmrg} 829ed6184dfSmrg 83035c4bbdfSmrg/** 83135c4bbdfSmrg * Return the event filter mask for the given device and the given core or 83235c4bbdfSmrg * XI1 protocol type. 83335c4bbdfSmrg */ 83435c4bbdfSmrgMask 83535c4bbdfSmrgevent_get_filter_from_type(DeviceIntPtr dev, int evtype) 83635c4bbdfSmrg{ 83735c4bbdfSmrg return event_filters[dev ? dev->id : 0][evtype]; 83835c4bbdfSmrg} 83935c4bbdfSmrg 84035c4bbdfSmrg/** 84135c4bbdfSmrg * Return the event filter mask for the given device and the given core or 84235c4bbdfSmrg * XI2 protocol type. 84335c4bbdfSmrg */ 84435c4bbdfSmrgMask 84535c4bbdfSmrgevent_get_filter_from_xi2type(int evtype) 84635c4bbdfSmrg{ 84735c4bbdfSmrg return (1 << (evtype % 8)); 84835c4bbdfSmrg} 84935c4bbdfSmrg 85035c4bbdfSmrgBool 85135c4bbdfSmrgpoint_on_screen(ScreenPtr pScreen, int x, int y) 85235c4bbdfSmrg{ 85335c4bbdfSmrg return x >= pScreen->x && x < pScreen->x + pScreen->width && 85435c4bbdfSmrg y >= pScreen->y && y < pScreen->y + pScreen->height; 85535c4bbdfSmrg} 85635c4bbdfSmrg 85735c4bbdfSmrg/** 85835c4bbdfSmrg * Update desktop dimensions on the screenInfo struct. 85935c4bbdfSmrg */ 86035c4bbdfSmrgvoid 86135c4bbdfSmrgupdate_desktop_dimensions(void) 86235c4bbdfSmrg{ 86335c4bbdfSmrg int i; 86435c4bbdfSmrg int x1 = INT_MAX, y1 = INT_MAX; /* top-left */ 86535c4bbdfSmrg int x2 = INT_MIN, y2 = INT_MIN; /* bottom-right */ 86635c4bbdfSmrg 86735c4bbdfSmrg for (i = 0; i < screenInfo.numScreens; i++) { 86835c4bbdfSmrg ScreenPtr screen = screenInfo.screens[i]; 86935c4bbdfSmrg 87035c4bbdfSmrg x1 = min(x1, screen->x); 87135c4bbdfSmrg y1 = min(y1, screen->y); 87235c4bbdfSmrg x2 = max(x2, screen->x + screen->width); 87335c4bbdfSmrg y2 = max(y2, screen->y + screen->height); 87435c4bbdfSmrg } 87535c4bbdfSmrg 87635c4bbdfSmrg screenInfo.x = x1; 87735c4bbdfSmrg screenInfo.y = y1; 87835c4bbdfSmrg screenInfo.width = x2 - x1; 87935c4bbdfSmrg screenInfo.height = y2 - y1; 88035c4bbdfSmrg} 88135c4bbdfSmrg 88235c4bbdfSmrg/* 88335c4bbdfSmrg * Delete the element with the key from the list, freeing all memory 88435c4bbdfSmrg * associated with the element.. 88535c4bbdfSmrg */ 88635c4bbdfSmrgstatic void 88735c4bbdfSmrginput_option_free(InputOption *o) 88835c4bbdfSmrg{ 88935c4bbdfSmrg free(o->opt_name); 89035c4bbdfSmrg free(o->opt_val); 89135c4bbdfSmrg free(o->opt_comment); 89235c4bbdfSmrg free(o); 89335c4bbdfSmrg} 89435c4bbdfSmrg 89535c4bbdfSmrg/* 89635c4bbdfSmrg * Create a new InputOption with the key/value pair provided. 89735c4bbdfSmrg * If a list is provided, the new options is added to the list and the list 89835c4bbdfSmrg * is returned. 89935c4bbdfSmrg * 90035c4bbdfSmrg * If a new option is added to a list that already contains that option, the 90135c4bbdfSmrg * previous option is overwritten. 90235c4bbdfSmrg * 90335c4bbdfSmrg * @param list The list to add to. 90435c4bbdfSmrg * @param key Option key, will be copied. 90535c4bbdfSmrg * @param value Option value, will be copied. 90635c4bbdfSmrg * 90735c4bbdfSmrg * @return If list is not NULL, the list with the new option added. If list 90835c4bbdfSmrg * is NULL, a new option list with one element. On failure, NULL is 90935c4bbdfSmrg * returned. 91035c4bbdfSmrg */ 91135c4bbdfSmrgInputOption * 91235c4bbdfSmrginput_option_new(InputOption *list, const char *key, const char *value) 91335c4bbdfSmrg{ 91435c4bbdfSmrg InputOption *opt = NULL; 91535c4bbdfSmrg 91635c4bbdfSmrg if (!key) 91735c4bbdfSmrg return NULL; 91835c4bbdfSmrg 91935c4bbdfSmrg if (list) { 92035c4bbdfSmrg nt_list_for_each_entry(opt, list, list.next) { 92135c4bbdfSmrg if (strcmp(input_option_get_key(opt), key) == 0) { 92235c4bbdfSmrg input_option_set_value(opt, value); 92335c4bbdfSmrg return list; 92435c4bbdfSmrg } 92535c4bbdfSmrg } 92635c4bbdfSmrg } 92735c4bbdfSmrg 92835c4bbdfSmrg opt = calloc(1, sizeof(InputOption)); 92935c4bbdfSmrg if (!opt) 93035c4bbdfSmrg return NULL; 93135c4bbdfSmrg 93235c4bbdfSmrg nt_list_init(opt, list.next); 93335c4bbdfSmrg input_option_set_key(opt, key); 93435c4bbdfSmrg input_option_set_value(opt, value); 93535c4bbdfSmrg 93635c4bbdfSmrg if (list) { 93735c4bbdfSmrg nt_list_append(opt, list, InputOption, list.next); 93835c4bbdfSmrg 93935c4bbdfSmrg return list; 94035c4bbdfSmrg } 94135c4bbdfSmrg else 94235c4bbdfSmrg return opt; 94335c4bbdfSmrg} 94435c4bbdfSmrg 94535c4bbdfSmrgInputOption * 94635c4bbdfSmrginput_option_free_element(InputOption *list, const char *key) 94735c4bbdfSmrg{ 94835c4bbdfSmrg InputOption *element; 94935c4bbdfSmrg 95035c4bbdfSmrg nt_list_for_each_entry(element, list, list.next) { 95135c4bbdfSmrg if (strcmp(input_option_get_key(element), key) == 0) { 95235c4bbdfSmrg nt_list_del(element, list, InputOption, list.next); 95335c4bbdfSmrg 95435c4bbdfSmrg input_option_free(element); 95535c4bbdfSmrg break; 95635c4bbdfSmrg } 95735c4bbdfSmrg } 95835c4bbdfSmrg return list; 95935c4bbdfSmrg} 96035c4bbdfSmrg 96135c4bbdfSmrg/** 96235c4bbdfSmrg * Free the list pointed at by opt. 96335c4bbdfSmrg */ 96435c4bbdfSmrgvoid 96535c4bbdfSmrginput_option_free_list(InputOption **opt) 96635c4bbdfSmrg{ 96735c4bbdfSmrg InputOption *element, *tmp; 96835c4bbdfSmrg 96935c4bbdfSmrg nt_list_for_each_entry_safe(element, tmp, *opt, list.next) { 97035c4bbdfSmrg nt_list_del(element, *opt, InputOption, list.next); 97135c4bbdfSmrg 97235c4bbdfSmrg input_option_free(element); 97335c4bbdfSmrg } 97435c4bbdfSmrg *opt = NULL; 97535c4bbdfSmrg} 97635c4bbdfSmrg 97735c4bbdfSmrg/** 97835c4bbdfSmrg * Find the InputOption with the given option name. 97935c4bbdfSmrg * 98035c4bbdfSmrg * @return The InputOption or NULL if not present. 98135c4bbdfSmrg */ 98235c4bbdfSmrgInputOption * 98335c4bbdfSmrginput_option_find(InputOption *list, const char *key) 98435c4bbdfSmrg{ 98535c4bbdfSmrg InputOption *element; 98635c4bbdfSmrg 98735c4bbdfSmrg nt_list_for_each_entry(element, list, list.next) { 98835c4bbdfSmrg if (strcmp(input_option_get_key(element), key) == 0) 98935c4bbdfSmrg return element; 99035c4bbdfSmrg } 99135c4bbdfSmrg 99235c4bbdfSmrg return NULL; 99335c4bbdfSmrg} 99435c4bbdfSmrg 99535c4bbdfSmrgconst char * 99635c4bbdfSmrginput_option_get_key(const InputOption *opt) 99735c4bbdfSmrg{ 99835c4bbdfSmrg return opt->opt_name; 99935c4bbdfSmrg} 100035c4bbdfSmrg 100135c4bbdfSmrgconst char * 100235c4bbdfSmrginput_option_get_value(const InputOption *opt) 100335c4bbdfSmrg{ 100435c4bbdfSmrg return opt->opt_val; 100535c4bbdfSmrg} 100635c4bbdfSmrg 100735c4bbdfSmrgvoid 100835c4bbdfSmrginput_option_set_key(InputOption *opt, const char *key) 100935c4bbdfSmrg{ 101035c4bbdfSmrg free(opt->opt_name); 101135c4bbdfSmrg if (key) 101235c4bbdfSmrg opt->opt_name = strdup(key); 101335c4bbdfSmrg} 101435c4bbdfSmrg 101535c4bbdfSmrgvoid 101635c4bbdfSmrginput_option_set_value(InputOption *opt, const char *value) 101735c4bbdfSmrg{ 101835c4bbdfSmrg free(opt->opt_val); 101935c4bbdfSmrg if (value) 102035c4bbdfSmrg opt->opt_val = strdup(value); 102135c4bbdfSmrg} 102235c4bbdfSmrg 102335c4bbdfSmrg/* FP1616/FP3232 conversion functions. 102435c4bbdfSmrg * Fixed point types are encoded as signed integral and unsigned frac. So any 102535c4bbdfSmrg * negative number -n.m is encoded as floor(n) + (1 - 0.m). 102635c4bbdfSmrg */ 102735c4bbdfSmrgdouble 102835c4bbdfSmrgfp1616_to_double(FP1616 in) 102935c4bbdfSmrg{ 103035c4bbdfSmrg return pixman_fixed_to_double(in); 103135c4bbdfSmrg} 103235c4bbdfSmrg 103335c4bbdfSmrgdouble 103435c4bbdfSmrgfp3232_to_double(FP3232 in) 103535c4bbdfSmrg{ 103635c4bbdfSmrg double ret; 103735c4bbdfSmrg 103835c4bbdfSmrg ret = (double) in.integral; 103935c4bbdfSmrg ret += (double) in.frac * (1.0 / (1ULL << 32)); /* Optimized: ldexp((double)in.frac, -32); */ 104035c4bbdfSmrg return ret; 104135c4bbdfSmrg} 104235c4bbdfSmrg 104335c4bbdfSmrgFP1616 104435c4bbdfSmrgdouble_to_fp1616(double in) 104535c4bbdfSmrg{ 104635c4bbdfSmrg return pixman_double_to_fixed(in); 104735c4bbdfSmrg} 104835c4bbdfSmrg 104935c4bbdfSmrgFP3232 105035c4bbdfSmrgdouble_to_fp3232(double in) 105135c4bbdfSmrg{ 105235c4bbdfSmrg FP3232 ret; 105335c4bbdfSmrg int32_t integral; 105435c4bbdfSmrg double tmp; 105535c4bbdfSmrg uint32_t frac_d; 105635c4bbdfSmrg 105735c4bbdfSmrg tmp = floor(in); 105835c4bbdfSmrg integral = (int32_t) tmp; 105935c4bbdfSmrg 106035c4bbdfSmrg tmp = (in - integral) * (1ULL << 32); /* Optimized: ldexp(in - integral, 32) */ 106135c4bbdfSmrg frac_d = (uint32_t) tmp; 106235c4bbdfSmrg 106335c4bbdfSmrg ret.integral = integral; 106435c4bbdfSmrg ret.frac = frac_d; 106535c4bbdfSmrg return ret; 106635c4bbdfSmrg} 106735c4bbdfSmrg 106835c4bbdfSmrg/** 106935c4bbdfSmrg * DO NOT USE THIS FUNCTION. It only exists for the test cases. Use 107035c4bbdfSmrg * xi2mask_new() instead to get the standard sized masks. 107135c4bbdfSmrg * 107235c4bbdfSmrg * @param nmasks The number of masks (== number of devices) 107335c4bbdfSmrg * @param size The size of the masks in bytes 107435c4bbdfSmrg * @return The new mask or NULL on allocation error. 107535c4bbdfSmrg */ 107635c4bbdfSmrgXI2Mask * 107735c4bbdfSmrgxi2mask_new_with_size(size_t nmasks, size_t size) 107835c4bbdfSmrg{ 107935c4bbdfSmrg int i; 108035c4bbdfSmrg int alloc_size; 108135c4bbdfSmrg unsigned char *cursor; 108235c4bbdfSmrg XI2Mask *mask; 108335c4bbdfSmrg 108435c4bbdfSmrg alloc_size = sizeof(struct _XI2Mask) 108535c4bbdfSmrg + nmasks * sizeof(unsigned char *) 108635c4bbdfSmrg + nmasks * size; 108735c4bbdfSmrg 108835c4bbdfSmrg mask = calloc(1, alloc_size); 108935c4bbdfSmrg 109035c4bbdfSmrg if (!mask) 109135c4bbdfSmrg return NULL; 109235c4bbdfSmrg 109335c4bbdfSmrg mask->nmasks = nmasks; 109435c4bbdfSmrg mask->mask_size = size; 109535c4bbdfSmrg 109635c4bbdfSmrg mask->masks = (unsigned char **)(mask + 1); 109735c4bbdfSmrg cursor = (unsigned char *)(mask + 1) + nmasks * sizeof(unsigned char *); 109835c4bbdfSmrg 109935c4bbdfSmrg for (i = 0; i < nmasks; i++) { 110035c4bbdfSmrg mask->masks[i] = cursor; 110135c4bbdfSmrg cursor += size; 110235c4bbdfSmrg } 110335c4bbdfSmrg return mask; 110435c4bbdfSmrg} 110535c4bbdfSmrg 110635c4bbdfSmrg/** 110735c4bbdfSmrg * Create a new XI2 mask of the standard size, i.e. for all devices + fake 110835c4bbdfSmrg * devices and for the highest supported XI2 event type. 110935c4bbdfSmrg * 111035c4bbdfSmrg * @return The new mask or NULL on allocation error. 111135c4bbdfSmrg */ 111235c4bbdfSmrgXI2Mask * 111335c4bbdfSmrgxi2mask_new(void) 111435c4bbdfSmrg{ 111535c4bbdfSmrg return xi2mask_new_with_size(EMASKSIZE, XI2MASKSIZE); 111635c4bbdfSmrg} 111735c4bbdfSmrg 111835c4bbdfSmrg/** 111935c4bbdfSmrg * Frees memory associated with mask and resets mask to NULL. 112035c4bbdfSmrg */ 112135c4bbdfSmrgvoid 112235c4bbdfSmrgxi2mask_free(XI2Mask **mask) 112335c4bbdfSmrg{ 112435c4bbdfSmrg if (!(*mask)) 112535c4bbdfSmrg return; 112635c4bbdfSmrg 112735c4bbdfSmrg free((*mask)); 112835c4bbdfSmrg *mask = NULL; 112935c4bbdfSmrg} 113035c4bbdfSmrg 113135c4bbdfSmrg/** 113235c4bbdfSmrg * Test if the bit for event type is set for this device only. 113335c4bbdfSmrg * 113435c4bbdfSmrg * @return TRUE if the bit is set, FALSE otherwise 113535c4bbdfSmrg */ 113635c4bbdfSmrgBool 113735c4bbdfSmrgxi2mask_isset_for_device(XI2Mask *mask, const DeviceIntPtr dev, int event_type) 113835c4bbdfSmrg{ 113935c4bbdfSmrg BUG_WARN(dev->id < 0); 114035c4bbdfSmrg BUG_WARN(dev->id >= mask->nmasks); 114135c4bbdfSmrg BUG_WARN(bits_to_bytes(event_type + 1) > mask->mask_size); 114235c4bbdfSmrg 114335c4bbdfSmrg return BitIsOn(mask->masks[dev->id], event_type); 114435c4bbdfSmrg} 114535c4bbdfSmrg 114635c4bbdfSmrg/** 114735c4bbdfSmrg * Test if the bit for event type is set for this device, or the 114835c4bbdfSmrg * XIAllDevices/XIAllMasterDevices (if applicable) is set. 114935c4bbdfSmrg * 115035c4bbdfSmrg * @return TRUE if the bit is set, FALSE otherwise 115135c4bbdfSmrg */ 115235c4bbdfSmrgBool 115335c4bbdfSmrgxi2mask_isset(XI2Mask *mask, const DeviceIntPtr dev, int event_type) 115435c4bbdfSmrg{ 115535c4bbdfSmrg int set = 0; 115635c4bbdfSmrg 115735c4bbdfSmrg if (xi2mask_isset_for_device(mask, inputInfo.all_devices, event_type)) 115835c4bbdfSmrg set = 1; 115935c4bbdfSmrg else if (xi2mask_isset_for_device(mask, dev, event_type)) 116035c4bbdfSmrg set = 1; 116135c4bbdfSmrg else if (IsMaster(dev) && xi2mask_isset_for_device(mask, inputInfo.all_master_devices, event_type)) 116235c4bbdfSmrg set = 1; 116335c4bbdfSmrg 116435c4bbdfSmrg return set; 116535c4bbdfSmrg} 116635c4bbdfSmrg 116735c4bbdfSmrg/** 116835c4bbdfSmrg * Set the mask bit for this event type for this device. 116935c4bbdfSmrg */ 117035c4bbdfSmrgvoid 117135c4bbdfSmrgxi2mask_set(XI2Mask *mask, int deviceid, int event_type) 117235c4bbdfSmrg{ 117335c4bbdfSmrg BUG_WARN(deviceid < 0); 117435c4bbdfSmrg BUG_WARN(deviceid >= mask->nmasks); 117535c4bbdfSmrg BUG_WARN(bits_to_bytes(event_type + 1) > mask->mask_size); 117635c4bbdfSmrg 117735c4bbdfSmrg SetBit(mask->masks[deviceid], event_type); 117835c4bbdfSmrg} 117935c4bbdfSmrg 118035c4bbdfSmrg/** 118135c4bbdfSmrg * Zero out the xi2mask, for the deviceid given. If the deviceid is < 0, all 118235c4bbdfSmrg * masks are zeroed. 118335c4bbdfSmrg */ 118435c4bbdfSmrgvoid 118535c4bbdfSmrgxi2mask_zero(XI2Mask *mask, int deviceid) 118635c4bbdfSmrg{ 118735c4bbdfSmrg int i; 118835c4bbdfSmrg 118935c4bbdfSmrg BUG_WARN(deviceid > 0 && deviceid >= mask->nmasks); 119035c4bbdfSmrg 119135c4bbdfSmrg if (deviceid >= 0) 119235c4bbdfSmrg memset(mask->masks[deviceid], 0, mask->mask_size); 119335c4bbdfSmrg else 119435c4bbdfSmrg for (i = 0; i < mask->nmasks; i++) 119535c4bbdfSmrg memset(mask->masks[i], 0, mask->mask_size); 119635c4bbdfSmrg} 119735c4bbdfSmrg 119835c4bbdfSmrg/** 119935c4bbdfSmrg * Merge source into dest, i.e. dest |= source. 120035c4bbdfSmrg * If the masks are of different size, only the overlapping section is merged. 120135c4bbdfSmrg */ 120235c4bbdfSmrgvoid 120335c4bbdfSmrgxi2mask_merge(XI2Mask *dest, const XI2Mask *source) 120435c4bbdfSmrg{ 120535c4bbdfSmrg int i, j; 120635c4bbdfSmrg 120735c4bbdfSmrg for (i = 0; i < min(dest->nmasks, source->nmasks); i++) 120835c4bbdfSmrg for (j = 0; j < min(dest->mask_size, source->mask_size); j++) 120935c4bbdfSmrg dest->masks[i][j] |= source->masks[i][j]; 121035c4bbdfSmrg} 121135c4bbdfSmrg 121235c4bbdfSmrg/** 121335c4bbdfSmrg * @return The number of masks in mask 121435c4bbdfSmrg */ 121535c4bbdfSmrgsize_t 121635c4bbdfSmrgxi2mask_num_masks(const XI2Mask *mask) 121735c4bbdfSmrg{ 121835c4bbdfSmrg return mask->nmasks; 121935c4bbdfSmrg} 122035c4bbdfSmrg 122135c4bbdfSmrg/** 122235c4bbdfSmrg * @return The size of each mask in bytes 122335c4bbdfSmrg */ 122435c4bbdfSmrgsize_t 122535c4bbdfSmrgxi2mask_mask_size(const XI2Mask *mask) 122635c4bbdfSmrg{ 122735c4bbdfSmrg return mask->mask_size; 122835c4bbdfSmrg} 122935c4bbdfSmrg 123035c4bbdfSmrg/** 123135c4bbdfSmrg * Set the mask for the given deviceid to the source mask. 123235c4bbdfSmrg * If the mask given is larger than the target memory, only the overlapping 123335c4bbdfSmrg * parts are copied. 123435c4bbdfSmrg */ 123535c4bbdfSmrgvoid 123635c4bbdfSmrgxi2mask_set_one_mask(XI2Mask *xi2mask, int deviceid, const unsigned char *mask, 123735c4bbdfSmrg size_t mask_size) 123835c4bbdfSmrg{ 123935c4bbdfSmrg BUG_WARN(deviceid < 0); 124035c4bbdfSmrg BUG_WARN(deviceid >= xi2mask->nmasks); 124135c4bbdfSmrg 124235c4bbdfSmrg memcpy(xi2mask->masks[deviceid], mask, min(xi2mask->mask_size, mask_size)); 124335c4bbdfSmrg} 124435c4bbdfSmrg 124535c4bbdfSmrg/** 124635c4bbdfSmrg * Get a reference to the XI2mask for this particular device. 124735c4bbdfSmrg */ 124835c4bbdfSmrgconst unsigned char * 124935c4bbdfSmrgxi2mask_get_one_mask(const XI2Mask *mask, int deviceid) 125035c4bbdfSmrg{ 125135c4bbdfSmrg BUG_WARN(deviceid < 0); 125235c4bbdfSmrg BUG_WARN(deviceid >= mask->nmasks); 125335c4bbdfSmrg 125435c4bbdfSmrg return mask->masks[deviceid]; 125535c4bbdfSmrg} 1256ed6184dfSmrg 1257ed6184dfSmrg/** 1258ed6184dfSmrg * Copies a sprite data from src to dst sprites. 1259ed6184dfSmrg * 1260ed6184dfSmrg * Returns FALSE on error. 1261ed6184dfSmrg */ 1262ed6184dfSmrgBool 1263ed6184dfSmrgCopySprite(SpritePtr src, SpritePtr dst) 1264ed6184dfSmrg{ 1265ed6184dfSmrg WindowPtr *trace; 1266ed6184dfSmrg if (src->spriteTraceGood > dst->spriteTraceSize) { 1267ed6184dfSmrg trace = reallocarray(dst->spriteTrace, 1268ed6184dfSmrg src->spriteTraceSize, sizeof(*trace)); 1269ed6184dfSmrg if (!trace) { 1270ed6184dfSmrg dst->spriteTraceGood = 0; 1271ed6184dfSmrg return FALSE; 1272ed6184dfSmrg } 1273ed6184dfSmrg dst->spriteTrace = trace; 1274ed6184dfSmrg dst->spriteTraceSize = src->spriteTraceGood; 1275ed6184dfSmrg } 1276ed6184dfSmrg memcpy(dst->spriteTrace, src->spriteTrace, 1277ed6184dfSmrg src->spriteTraceGood * sizeof(*trace)); 1278ed6184dfSmrg dst->spriteTraceGood = src->spriteTraceGood; 1279ed6184dfSmrg return TRUE; 1280ed6184dfSmrg} 1281