2 * Copyright © 2008 Daniel Stone
4 * Permission is hereby granted, free of charge, to any person obtaining a
5 * copy of this software and associated documentation files (the "Software"),
6 * to deal in the Software without restriction, including without limitation
7 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 * and/or sell copies of the Software, and to permit persons to whom the
9 * Software is furnished to do so, subject to the following conditions:
11 * The above copyright notice and this permission notice (including the next
12 * paragraph) shall be included in all copies or substantial portions of the
15 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
18 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
20 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
21 * DEALINGS IN THE SOFTWARE.
23 * Author: Daniel Stone <daniel@fooishbar.org>
26 #ifdef HAVE_DIX_CONFIG_H
27 #include "dix-config.h"
31 #include "exglobals.h"
38 #include "inpututils.h"
40 #include "scrnintstr.h"
41 #include "optionstr.h"
43 /* Check if a button map change is okay with the device.
44 * Returns -1 for BadValue, as it collides with MappingBusy. */
46 check_butmap_change(DeviceIntPtr dev
, CARD8
*map
, int len
, CARD32
*errval_out
,
51 if (!dev
|| !dev
->button
) {
52 client
->errorValue
= (dev
) ? dev
->id
: 0;
56 ret
= XaceHook(XACE_DEVICE_ACCESS
, client
, dev
, DixManageAccess
);
58 client
->errorValue
= dev
->id
;
62 for (i
= 0; i
< len
; i
++) {
63 if (dev
->button
->map
[i
+ 1] != map
[i
] &&
64 button_is_down(dev
, i
+ 1, BUTTON_PROCESSED
))
72 do_butmap_change(DeviceIntPtr dev
, CARD8
*map
, int len
, ClientPtr client
)
75 xEvent core_mn
= { .u
.u
.type
= MappingNotify
};
76 deviceMappingNotify xi_mn
;
78 /* The map in ButtonClassRec refers to button numbers, whereas the
79 * protocol is zero-indexed. Sigh. */
80 memcpy(&(dev
->button
->map
[1]), map
, len
);
82 core_mn
.u
.mappingNotify
.request
= MappingPointer
;
84 /* 0 is the server client. */
85 for (i
= 1; i
< currentMaxClients
; i
++) {
86 /* Don't send irrelevant events to naïve clients. */
87 if (!clients
[i
] || clients
[i
]->clientState
!= ClientStateRunning
)
90 if (!XIShouldNotify(clients
[i
], dev
))
93 WriteEventsToClient(clients
[i
], 1, &core_mn
);
96 xi_mn
= (deviceMappingNotify
) {
97 .type
= DeviceMappingNotify
,
98 .request
= MappingPointer
,
100 .time
= GetTimeInMillis()
103 SendEventToAllWindows(dev
, DeviceMappingNotifyMask
, (xEvent
*) &xi_mn
, 1);
107 * Does what it says on the box, both for core and Xi.
109 * Faithfully reports any errors encountered while trying to apply the map
110 * to the requested device, faithfully ignores any errors encountered while
111 * trying to apply the map to its master/slaves.
114 ApplyPointerMapping(DeviceIntPtr dev
, CARD8
*map
, int len
, ClientPtr client
)
118 /* If we can't perform the change on the requested device, bail out. */
119 ret
= check_butmap_change(dev
, map
, len
, &client
->errorValue
, client
);
122 do_butmap_change(dev
, map
, len
, client
);
127 /* Check if a modifier map change is okay with the device.
128 * Returns -1 for BadValue, as it collides with MappingBusy; this particular
129 * caveat can be removed with LegalModifier, as we have no other reason to
130 * set MappingFailed. Sigh. */
132 check_modmap_change(ClientPtr client
, DeviceIntPtr dev
, KeyCode
*modmap
)
137 ret
= XaceHook(XACE_DEVICE_ACCESS
, client
, dev
, DixManageAccess
);
143 xkb
= dev
->key
->xkbInfo
->desc
;
145 for (i
= 0; i
< MAP_LENGTH
; i
++) {
149 /* Check that all the new modifiers fall within the advertised
151 if (i
< xkb
->min_key_code
|| i
> xkb
->max_key_code
) {
152 client
->errorValue
= i
;
156 /* Make sure the mapping is okay with the DDX. */
157 if (!LegalModifier(i
, dev
)) {
158 client
->errorValue
= i
;
159 return MappingFailed
;
162 /* None of the new modifiers may be down while we change the
164 if (key_is_down(dev
, i
, KEY_POSTED
| KEY_PROCESSED
)) {
165 client
->errorValue
= i
;
170 /* None of the old modifiers may be down while we change the map,
172 for (i
= xkb
->min_key_code
; i
< xkb
->max_key_code
; i
++) {
173 if (!xkb
->map
->modmap
[i
])
175 if (key_is_down(dev
, i
, KEY_POSTED
| KEY_PROCESSED
)) {
176 client
->errorValue
= i
;
185 check_modmap_change_slave(ClientPtr client
, DeviceIntPtr master
,
186 DeviceIntPtr slave
, CARD8
*modmap
)
188 XkbDescPtr master_xkb
, slave_xkb
;
191 if (!slave
->key
|| !master
->key
)
194 master_xkb
= master
->key
->xkbInfo
->desc
;
195 slave_xkb
= slave
->key
->xkbInfo
->desc
;
197 /* Ignore devices with a clearly different keymap. */
198 if (slave_xkb
->min_key_code
!= master_xkb
->min_key_code
||
199 slave_xkb
->max_key_code
!= master_xkb
->max_key_code
)
202 for (i
= 0; i
< MAP_LENGTH
; i
++) {
206 /* If we have different symbols for any modifier on an
207 * extended keyboard, ignore the whole remap request. */
209 j
< XkbKeyNumSyms(slave_xkb
, i
) &&
210 j
< XkbKeyNumSyms(master_xkb
, i
); j
++)
211 if (XkbKeySymsPtr(slave_xkb
, i
)[j
] !=
212 XkbKeySymsPtr(master_xkb
, i
)[j
])
216 if (check_modmap_change(client
, slave
, modmap
) != Success
)
222 /* Actually change the modifier map, and send notifications. Cannot fail. */
224 do_modmap_change(ClientPtr client
, DeviceIntPtr dev
, CARD8
*modmap
)
226 XkbApplyMappingChange(dev
, NULL
, 0, 0, modmap
, serverClient
);
229 /* Rebuild modmap (key -> mod) from map (mod -> key). */
231 build_modmap_from_modkeymap(CARD8
*modmap
, KeyCode
*modkeymap
,
232 int max_keys_per_mod
)
234 int i
, len
= max_keys_per_mod
* 8;
236 memset(modmap
, 0, MAP_LENGTH
);
238 for (i
= 0; i
< len
; i
++) {
242 if (modkeymap
[i
] >= MAP_LENGTH
)
245 if (modmap
[modkeymap
[i
]])
248 modmap
[modkeymap
[i
]] = 1 << (i
/ max_keys_per_mod
);
255 change_modmap(ClientPtr client
, DeviceIntPtr dev
, KeyCode
*modkeymap
,
256 int max_keys_per_mod
)
259 CARD8 modmap
[MAP_LENGTH
];
262 ret
= build_modmap_from_modkeymap(modmap
, modkeymap
, max_keys_per_mod
);
266 /* If we can't perform the change on the requested device, bail out. */
267 ret
= check_modmap_change(client
, dev
, modmap
);
270 do_modmap_change(client
, dev
, modmap
);
272 /* Change any attached masters/slaves. */
274 for (tmp
= inputInfo
.devices
; tmp
; tmp
= tmp
->next
) {
275 if (!IsMaster(tmp
) && GetMaster(tmp
, MASTER_KEYBOARD
) == dev
)
276 if (check_modmap_change_slave(client
, dev
, tmp
, modmap
))
277 do_modmap_change(client
, tmp
, modmap
);
280 else if (!IsFloating(dev
) &&
281 GetMaster(dev
, MASTER_KEYBOARD
)->lastSlave
== dev
) {
282 /* If this fails, expect the results to be weird. */
283 if (check_modmap_change(client
, dev
->master
, modmap
))
284 do_modmap_change(client
, dev
->master
, modmap
);
291 generate_modkeymap(ClientPtr client
, DeviceIntPtr dev
,
292 KeyCode
**modkeymap_out
, int *max_keys_per_mod_out
)
294 CARD8 keys_per_mod
[8];
295 int max_keys_per_mod
;
296 KeyCode
*modkeymap
= NULL
;
299 ret
= XaceHook(XACE_DEVICE_ACCESS
, client
, dev
, DixGetAttrAccess
);
306 /* Count the number of keys per modifier to determine how wide we
307 * should make the map. */
308 max_keys_per_mod
= 0;
309 for (i
= 0; i
< 8; i
++)
311 for (i
= 8; i
< MAP_LENGTH
; i
++) {
312 for (j
= 0; j
< 8; j
++) {
313 if (dev
->key
->xkbInfo
->desc
->map
->modmap
[i
] & (1 << j
)) {
314 if (++keys_per_mod
[j
] > max_keys_per_mod
)
315 max_keys_per_mod
= keys_per_mod
[j
];
320 if (max_keys_per_mod
!= 0) {
321 modkeymap
= calloc(max_keys_per_mod
* 8, sizeof(KeyCode
));
325 for (i
= 0; i
< 8; i
++)
328 for (i
= 8; i
< MAP_LENGTH
; i
++) {
329 for (j
= 0; j
< 8; j
++) {
330 if (dev
->key
->xkbInfo
->desc
->map
->modmap
[i
] & (1 << j
)) {
331 modkeymap
[(j
* max_keys_per_mod
) + keys_per_mod
[j
]] = i
;
338 *max_keys_per_mod_out
= max_keys_per_mod
;
339 *modkeymap_out
= modkeymap
;
345 * Duplicate the InputAttributes in the most obvious way.
346 * No special memory handling is used to give drivers the maximum
347 * flexibility with the data. Drivers should be able to call realloc on the
348 * product string if needed and perform similar operations.
351 DuplicateInputAttributes(InputAttributes
* attrs
)
353 InputAttributes
*new_attr
;
355 char **tags
, **new_tags
;
360 if (!(new_attr
= calloc(1, sizeof(InputAttributes
))))
363 if (attrs
->product
&& !(new_attr
->product
= strdup(attrs
->product
)))
365 if (attrs
->vendor
&& !(new_attr
->vendor
= strdup(attrs
->vendor
)))
367 if (attrs
->device
&& !(new_attr
->device
= strdup(attrs
->device
)))
369 if (attrs
->pnp_id
&& !(new_attr
->pnp_id
= strdup(attrs
->pnp_id
)))
371 if (attrs
->usb_id
&& !(new_attr
->usb_id
= strdup(attrs
->usb_id
)))
374 new_attr
->flags
= attrs
->flags
;
376 if ((tags
= attrs
->tags
)) {
380 new_attr
->tags
= calloc(ntags
+ 1, sizeof(char *));
385 new_tags
= new_attr
->tags
;
388 *new_tags
= strdup(*tags
);
400 FreeInputAttributes(new_attr
);
405 FreeInputAttributes(InputAttributes
* attrs
)
412 free(attrs
->product
);
418 if ((tags
= attrs
->tags
))
427 * Alloc a valuator mask large enough for num_valuators.
430 valuator_mask_new(int num_valuators
)
432 /* alloc a fixed size mask for now and ignore num_valuators. in the
433 * flying-car future, when we can dynamically alloc the masks and are
434 * not constrained by signals, we can start using num_valuators */
435 ValuatorMask
*mask
= calloc(1, sizeof(ValuatorMask
));
445 valuator_mask_free(ValuatorMask
**mask
)
452 * Sets a range of valuators between first_valuator and num_valuators with
453 * the data in the valuators array. All other values are set to 0.
456 valuator_mask_set_range(ValuatorMask
*mask
, int first_valuator
,
457 int num_valuators
, const int *valuators
)
461 valuator_mask_zero(mask
);
463 for (i
= first_valuator
;
464 i
< min(first_valuator
+ num_valuators
, MAX_VALUATORS
); i
++)
465 valuator_mask_set(mask
, i
, valuators
[i
- first_valuator
]);
469 * Reset mask to zero.
472 valuator_mask_zero(ValuatorMask
*mask
)
474 memset(mask
, 0, sizeof(*mask
));
479 * Returns the current size of the mask (i.e. the highest number of
480 * valuators currently set + 1).
483 valuator_mask_size(const ValuatorMask
*mask
)
485 return mask
->last_bit
+ 1;
489 * Returns the number of valuators set in the given mask.
492 valuator_mask_num_valuators(const ValuatorMask
*mask
)
494 return CountBits(mask
->mask
, min(mask
->last_bit
+ 1, MAX_VALUATORS
));
498 * Return true if the valuator is set in the mask, or false otherwise.
501 valuator_mask_isset(const ValuatorMask
*mask
, int valuator
)
503 return mask
->last_bit
>= valuator
&& BitIsOn(mask
->mask
, valuator
);
507 * Set the valuator to the given floating-point data.
510 valuator_mask_set_double(ValuatorMask
*mask
, int valuator
, double data
)
512 mask
->last_bit
= max(valuator
, mask
->last_bit
);
513 SetBit(mask
->mask
, valuator
);
514 mask
->valuators
[valuator
] = data
;
518 * Set the valuator to the given integer data.
521 valuator_mask_set(ValuatorMask
*mask
, int valuator
, int data
)
523 valuator_mask_set_double(mask
, valuator
, data
);
527 * Return the requested valuator value as a double. If the mask bit is not
528 * set for the given valuator, the returned value is undefined.
531 valuator_mask_get_double(const ValuatorMask
*mask
, int valuator
)
533 return mask
->valuators
[valuator
];
537 * Return the requested valuator value as an integer, rounding towards zero.
538 * If the mask bit is not set for the given valuator, the returned value is
542 valuator_mask_get(const ValuatorMask
*mask
, int valuator
)
544 return trunc(valuator_mask_get_double(mask
, valuator
));
548 * Set value to the requested valuator. If the mask bit is set for this
549 * valuator, value contains the requested valuator value and TRUE is
551 * If the mask bit is not set for this valuator, value is unchanged and
555 valuator_mask_fetch_double(const ValuatorMask
*mask
, int valuator
,
558 if (valuator_mask_isset(mask
, valuator
)) {
559 *value
= valuator_mask_get_double(mask
, valuator
);
567 * Set value to the requested valuator. If the mask bit is set for this
568 * valuator, value contains the requested valuator value and TRUE is
570 * If the mask bit is not set for this valuator, value is unchanged and
574 valuator_mask_fetch(const ValuatorMask
*mask
, int valuator
, int *value
)
576 if (valuator_mask_isset(mask
, valuator
)) {
577 *value
= valuator_mask_get(mask
, valuator
);
585 * Remove the valuator from the mask.
588 valuator_mask_unset(ValuatorMask
*mask
, int valuator
)
590 if (mask
->last_bit
>= valuator
) {
593 ClearBit(mask
->mask
, valuator
);
594 mask
->valuators
[valuator
] = 0.0;
596 for (i
= 0; i
<= mask
->last_bit
; i
++)
597 if (valuator_mask_isset(mask
, i
))
598 lastbit
= max(lastbit
, i
);
599 mask
->last_bit
= lastbit
;
604 valuator_mask_copy(ValuatorMask
*dest
, const ValuatorMask
*src
)
607 memcpy(dest
, src
, sizeof(*dest
));
609 valuator_mask_zero(dest
);
613 CountBits(const uint8_t * mask
, int len
)
618 for (i
= 0; i
< len
; i
++)
619 if (BitIsOn(mask
, i
))
626 * Verifies sanity of the event. If the event is not an internal event,
627 * memdumps the first 32 bytes of event to the log, a backtrace, then kill
631 verify_internal_event(const InternalEvent
*ev
)
633 if (ev
&& ev
->any
.header
!= ET_Internal
) {
635 const unsigned char *data
= (const unsigned char *) ev
;
637 ErrorF("dix: invalid event type %d\n", ev
->any
.header
);
639 for (i
= 0; i
< sizeof(xEvent
); i
++, data
++) {
640 ErrorF("%02hhx ", *data
);
647 FatalError("Wrong event type %d. Aborting server\n", ev
->any
.header
);
652 * Initializes the given event to zero (or default values), for the given
656 init_device_event(DeviceEvent
*event
, DeviceIntPtr dev
, Time ms
)
658 memset(event
, 0, sizeof(DeviceEvent
));
659 event
->header
= ET_Internal
;
660 event
->length
= sizeof(DeviceEvent
);
662 event
->deviceid
= dev
->id
;
663 event
->sourceid
= dev
->id
;
667 event_get_corestate(DeviceIntPtr mouse
, DeviceIntPtr kbd
)
671 /* core state needs to be assembled BEFORE the device is updated. */
673 kbd
->key
) ? XkbStateFieldFromRec(&kbd
->key
->xkbInfo
->
675 corestate
|= (mouse
&& mouse
->button
) ? (mouse
->button
->state
) : 0;
676 corestate
|= (mouse
&& mouse
->touch
) ? (mouse
->touch
->state
) : 0;
682 event_set_state(DeviceIntPtr mouse
, DeviceIntPtr kbd
, DeviceEvent
*event
)
686 for (i
= 0; mouse
&& mouse
->button
&& i
< mouse
->button
->numButtons
; i
++)
687 if (BitIsOn(mouse
->button
->down
, i
))
688 SetBit(event
->buttons
, mouse
->button
->map
[i
]);
690 if (mouse
&& mouse
->touch
&& mouse
->touch
->buttonsDown
> 0)
691 SetBit(event
->buttons
, mouse
->button
->map
[1]);
693 if (kbd
&& kbd
->key
) {
696 /* we need the state before the event happens */
697 if (event
->type
== ET_KeyPress
|| event
->type
== ET_KeyRelease
)
698 state
= &kbd
->key
->xkbInfo
->prev_state
;
700 state
= &kbd
->key
->xkbInfo
->state
;
702 event
->mods
.base
= state
->base_mods
;
703 event
->mods
.latched
= state
->latched_mods
;
704 event
->mods
.locked
= state
->locked_mods
;
705 event
->mods
.effective
= state
->mods
;
707 event
->group
.base
= state
->base_group
;
708 event
->group
.latched
= state
->latched_group
;
709 event
->group
.locked
= state
->locked_group
;
710 event
->group
.effective
= state
->group
;
715 * Return the event filter mask for the given device and the given core or
719 event_get_filter_from_type(DeviceIntPtr dev
, int evtype
)
721 return event_filters
[dev
? dev
->id
: 0][evtype
];
725 * Return the event filter mask for the given device and the given core or
729 event_get_filter_from_xi2type(int evtype
)
731 return (1 << (evtype
% 8));
735 point_on_screen(ScreenPtr pScreen
, int x
, int y
)
737 return x
>= pScreen
->x
&& x
< pScreen
->x
+ pScreen
->width
&&
738 y
>= pScreen
->y
&& y
< pScreen
->y
+ pScreen
->height
;
742 * Update desktop dimensions on the screenInfo struct.
745 update_desktop_dimensions(void)
748 int x1
= INT_MAX
, y1
= INT_MAX
; /* top-left */
749 int x2
= INT_MIN
, y2
= INT_MIN
; /* bottom-right */
751 for (i
= 0; i
< screenInfo
.numScreens
; i
++) {
752 ScreenPtr screen
= screenInfo
.screens
[i
];
754 x1
= min(x1
, screen
->x
);
755 y1
= min(y1
, screen
->y
);
756 x2
= max(x2
, screen
->x
+ screen
->width
);
757 y2
= max(y2
, screen
->y
+ screen
->height
);
762 screenInfo
.width
= x2
- x1
;
763 screenInfo
.height
= y2
- y1
;
767 * Delete the element with the key from the list, freeing all memory
768 * associated with the element..
771 input_option_free(InputOption
*o
)
775 free(o
->opt_comment
);
780 * Create a new InputOption with the key/value pair provided.
781 * If a list is provided, the new options is added to the list and the list
784 * If a new option is added to a list that already contains that option, the
785 * previous option is overwritten.
787 * @param list The list to add to.
788 * @param key Option key, will be copied.
789 * @param value Option value, will be copied.
791 * @return If list is not NULL, the list with the new option added. If list
792 * is NULL, a new option list with one element. On failure, NULL is
796 input_option_new(InputOption
*list
, const char *key
, const char *value
)
798 InputOption
*opt
= NULL
;
804 nt_list_for_each_entry(opt
, list
, list
.next
) {
805 if (strcmp(input_option_get_key(opt
), key
) == 0) {
806 input_option_set_value(opt
, value
);
812 opt
= calloc(1, sizeof(InputOption
));
816 nt_list_init(opt
, list
.next
);
817 input_option_set_key(opt
, key
);
818 input_option_set_value(opt
, value
);
821 nt_list_append(opt
, list
, InputOption
, list
.next
);
830 input_option_free_element(InputOption
*list
, const char *key
)
832 InputOption
*element
;
834 nt_list_for_each_entry(element
, list
, list
.next
) {
835 if (strcmp(input_option_get_key(element
), key
) == 0) {
836 nt_list_del(element
, list
, InputOption
, list
.next
);
838 input_option_free(element
);
846 * Free the list pointed at by opt.
849 input_option_free_list(InputOption
**opt
)
851 InputOption
*element
, *tmp
;
853 nt_list_for_each_entry_safe(element
, tmp
, *opt
, list
.next
) {
854 nt_list_del(element
, *opt
, InputOption
, list
.next
);
856 input_option_free(element
);
862 * Find the InputOption with the given option name.
864 * @return The InputOption or NULL if not present.
867 input_option_find(InputOption
*list
, const char *key
)
869 InputOption
*element
;
871 nt_list_for_each_entry(element
, list
, list
.next
) {
872 if (strcmp(input_option_get_key(element
), key
) == 0)
880 input_option_get_key(const InputOption
*opt
)
882 return opt
->opt_name
;
886 input_option_get_value(const InputOption
*opt
)
892 input_option_set_key(InputOption
*opt
, const char *key
)
896 opt
->opt_name
= strdup(key
);
900 input_option_set_value(InputOption
*opt
, const char *value
)
904 opt
->opt_val
= strdup(value
);
907 /* FP1616/FP3232 conversion functions.
908 * Fixed point types are encoded as signed integral and unsigned frac. So any
909 * negative number -n.m is encoded as floor(n) + (1 - 0.m).
912 fp1616_to_double(FP1616 in
)
914 return pixman_fixed_to_double(in
);
918 fp3232_to_double(FP3232 in
)
922 ret
= (double) in
.integral
;
923 ret
+= (double) in
.frac
* (1.0 / (1ULL << 32)); /* Optimized: ldexp((double)in.frac, -32); */
928 double_to_fp1616(double in
)
930 return pixman_double_to_fixed(in
);
934 double_to_fp3232(double in
)
942 integral
= (int32_t) tmp
;
944 tmp
= (in
- integral
) * (1ULL << 32); /* Optimized: ldexp(in - integral, 32) */
945 frac_d
= (uint32_t) tmp
;
947 ret
.integral
= integral
;
953 * DO NOT USE THIS FUNCTION. It only exists for the test cases. Use
954 * xi2mask_new() instead to get the standard sized masks.
956 * @param nmasks The number of masks (== number of devices)
957 * @param size The size of the masks in bytes
958 * @return The new mask or NULL on allocation error.
961 xi2mask_new_with_size(size_t nmasks
, size_t size
)
965 unsigned char *cursor
;
968 alloc_size
= sizeof(struct _XI2Mask
)
969 + nmasks
* sizeof(unsigned char *)
972 mask
= calloc(1, alloc_size
);
977 mask
->nmasks
= nmasks
;
978 mask
->mask_size
= size
;
980 mask
->masks
= (unsigned char **)(mask
+ 1);
981 cursor
= (unsigned char *)(mask
+ 1) + nmasks
* sizeof(unsigned char *);
983 for (i
= 0; i
< nmasks
; i
++) {
984 mask
->masks
[i
] = cursor
;
991 * Create a new XI2 mask of the standard size, i.e. for all devices + fake
992 * devices and for the highest supported XI2 event type.
994 * @return The new mask or NULL on allocation error.
999 return xi2mask_new_with_size(EMASKSIZE
, XI2MASKSIZE
);
1003 * Frees memory associated with mask and resets mask to NULL.
1006 xi2mask_free(XI2Mask
**mask
)
1016 * Test if the bit for event type is set for this device only.
1018 * @return TRUE if the bit is set, FALSE otherwise
1021 xi2mask_isset_for_device(XI2Mask
*mask
, const DeviceIntPtr dev
, int event_type
)
1023 BUG_WARN(dev
->id
< 0);
1024 BUG_WARN(dev
->id
>= mask
->nmasks
);
1025 BUG_WARN(bits_to_bytes(event_type
+ 1) > mask
->mask_size
);
1027 return BitIsOn(mask
->masks
[dev
->id
], event_type
);
1031 * Test if the bit for event type is set for this device, or the
1032 * XIAllDevices/XIAllMasterDevices (if applicable) is set.
1034 * @return TRUE if the bit is set, FALSE otherwise
1037 xi2mask_isset(XI2Mask
*mask
, const DeviceIntPtr dev
, int event_type
)
1041 if (xi2mask_isset_for_device(mask
, inputInfo
.all_devices
, event_type
))
1043 else if (xi2mask_isset_for_device(mask
, dev
, event_type
))
1045 else if (IsMaster(dev
) && xi2mask_isset_for_device(mask
, inputInfo
.all_master_devices
, event_type
))
1052 * Set the mask bit for this event type for this device.
1055 xi2mask_set(XI2Mask
*mask
, int deviceid
, int event_type
)
1057 BUG_WARN(deviceid
< 0);
1058 BUG_WARN(deviceid
>= mask
->nmasks
);
1059 BUG_WARN(bits_to_bytes(event_type
+ 1) > mask
->mask_size
);
1061 SetBit(mask
->masks
[deviceid
], event_type
);
1065 * Zero out the xi2mask, for the deviceid given. If the deviceid is < 0, all
1069 xi2mask_zero(XI2Mask
*mask
, int deviceid
)
1073 BUG_WARN(deviceid
> 0 && deviceid
>= mask
->nmasks
);
1076 memset(mask
->masks
[deviceid
], 0, mask
->mask_size
);
1078 for (i
= 0; i
< mask
->nmasks
; i
++)
1079 memset(mask
->masks
[i
], 0, mask
->mask_size
);
1083 * Merge source into dest, i.e. dest |= source.
1084 * If the masks are of different size, only the overlapping section is merged.
1087 xi2mask_merge(XI2Mask
*dest
, const XI2Mask
*source
)
1091 for (i
= 0; i
< min(dest
->nmasks
, source
->nmasks
); i
++)
1092 for (j
= 0; j
< min(dest
->mask_size
, source
->mask_size
); j
++)
1093 dest
->masks
[i
][j
] |= source
->masks
[i
][j
];
1097 * @return The number of masks in mask
1100 xi2mask_num_masks(const XI2Mask
*mask
)
1102 return mask
->nmasks
;
1106 * @return The size of each mask in bytes
1109 xi2mask_mask_size(const XI2Mask
*mask
)
1111 return mask
->mask_size
;
1115 * Set the mask for the given deviceid to the source mask.
1116 * If the mask given is larger than the target memory, only the overlapping
1120 xi2mask_set_one_mask(XI2Mask
*xi2mask
, int deviceid
, const unsigned char *mask
,
1123 BUG_WARN(deviceid
< 0);
1124 BUG_WARN(deviceid
>= xi2mask
->nmasks
);
1126 memcpy(xi2mask
->masks
[deviceid
], mask
, min(xi2mask
->mask_size
, mask_size
));
1130 * Get a reference to the XI2mask for this particular device.
1132 const unsigned char *
1133 xi2mask_get_one_mask(const XI2Mask
*mask
, int deviceid
)
1135 BUG_WARN(deviceid
< 0);
1136 BUG_WARN(deviceid
>= mask
->nmasks
);
1138 return mask
->masks
[deviceid
];