Abstract valuator masks through a set of APIs.
This commit introduces an abstraction API for handling masked valuators. The
intent is that drivers just allocate a mask, set the data and pass the mask
to the server. The actual storage type of the mask is hidden from the
drivers.
The new calls for drivers are:
valuator_mask_new() /* to allocate a valuator mask */
valuator_mask_zero() /* to reset a mask to zero */
valuator_mask_set() /* to set a valuator value */
The new interface to the server is
xf86PostMotionEventM()
xf86PostButtonEventM()
xf86PostKeyboardEventM()
xf86PostProximityEventM()
all taking a mask instead of the valuator array.
The ValuatorMask is currently defined for MAX_VALUATORS fixed size due to
memory allocation restrictions in SIGIO handlers.
For easier review, a lot of the code still uses separate valuator arrays.
This will be fixed in a later patch.
This patch was initially written by Chase Douglas.
Signed-off-by: Chase Douglas <chase.douglas@canonical.com>
Signed-off-by: Peter Hutterer <peter.hutterer@who-t.net>
Reviewed-by: Chase Douglas <chase.douglas@canonical.com>
This commit is contained in:
142
dix/inpututils.c
142
dix/inpututils.c
@@ -35,6 +35,7 @@
|
||||
#include "xace.h"
|
||||
#include "xkbsrv.h"
|
||||
#include "xkbstr.h"
|
||||
#include "inpututils.h"
|
||||
|
||||
/* Check if a button map change is okay with the device.
|
||||
* Returns -1 for BadValue, as it collides with MappingBusy. */
|
||||
@@ -418,6 +419,147 @@ FreeInputAttributes(InputAttributes *attrs)
|
||||
free(attrs);
|
||||
}
|
||||
|
||||
/**
|
||||
* Alloc a valuator mask large enough for num_valuators.
|
||||
*/
|
||||
ValuatorMask*
|
||||
valuator_mask_new(int num_valuators)
|
||||
{
|
||||
/* alloc a fixed size mask for now and ignore num_valuators. in the
|
||||
* flying-car future, when we can dynamically alloc the masks and are
|
||||
* not constrained by signals, we can start using num_valuators */
|
||||
ValuatorMask *mask = calloc(1, sizeof(ValuatorMask));
|
||||
mask->last_bit = -1;
|
||||
return mask;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets a range of valuators between first_valuator and num_valuators with
|
||||
* the data in the valuators array. All other values are set to 0.
|
||||
*/
|
||||
void
|
||||
valuator_mask_set_range(ValuatorMask *mask, int first_valuator, int num_valuators,
|
||||
const int* valuators)
|
||||
{
|
||||
int i;
|
||||
|
||||
valuator_mask_zero(mask);
|
||||
|
||||
for (i = first_valuator; i < min(first_valuator + num_valuators, MAX_VALUATORS); i++)
|
||||
valuator_mask_set(mask, i, valuators[i - first_valuator]);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset mask to zero.
|
||||
*/
|
||||
void
|
||||
valuator_mask_zero(ValuatorMask *mask)
|
||||
{
|
||||
memset(mask, 0, sizeof(*mask));
|
||||
mask->last_bit = -1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the current size of the mask (i.e. the highest number of
|
||||
* valuators currently set + 1).
|
||||
*/
|
||||
int
|
||||
valuator_mask_size(const ValuatorMask *mask)
|
||||
{
|
||||
return mask->last_bit + 1;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the number of valuators set in the given mask.
|
||||
*/
|
||||
int
|
||||
valuator_mask_num_valuators(const ValuatorMask *mask)
|
||||
{
|
||||
return CountBits(mask->mask, min(mask->last_bit + 1, MAX_VALUATORS));
|
||||
}
|
||||
|
||||
/**
|
||||
* Return true if the valuator is set in the mask, or false otherwise.
|
||||
*/
|
||||
int
|
||||
valuator_mask_isset(const ValuatorMask *mask, int valuator)
|
||||
{
|
||||
return mask->last_bit >= valuator && BitIsOn(mask->mask, valuator);
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the valuator to the given data.
|
||||
*/
|
||||
void
|
||||
valuator_mask_set(ValuatorMask *mask, int valuator, int data)
|
||||
{
|
||||
mask->last_bit = max(valuator, mask->last_bit);
|
||||
SetBit(mask->mask, valuator);
|
||||
mask->valuators[valuator] = data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return the requested valuator value. If the mask bit is not set for the
|
||||
* given valuator, the returned value is undefined.
|
||||
*/
|
||||
int
|
||||
valuator_mask_get(const ValuatorMask *mask, int valuator)
|
||||
{
|
||||
return mask->valuators[valuator];
|
||||
}
|
||||
|
||||
/**
|
||||
* Remove the valuator from the mask.
|
||||
*/
|
||||
void
|
||||
valuator_mask_unset(ValuatorMask *mask, int valuator)
|
||||
{
|
||||
if (mask->last_bit >= valuator) {
|
||||
int i, lastbit = -1;
|
||||
|
||||
ClearBit(mask->mask, valuator);
|
||||
mask->valuators[valuator] = 0;
|
||||
|
||||
for (i = 0; i <= mask->last_bit; i++)
|
||||
if (valuator_mask_isset(mask, i))
|
||||
lastbit = max(lastbit, i);
|
||||
mask->last_bit = lastbit;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Copy the valuator data from the given mask and return it as one closed
|
||||
* array (i.e., with holes where the masks are unset.
|
||||
* If valuators_in is not NULL, the valuator data will be copied into
|
||||
* valuators_in. The caller is responsible to allocate enough memory.
|
||||
*
|
||||
* Otherwise, memory is allocated and returned.
|
||||
*/
|
||||
int*
|
||||
valuator_mask_copy_valuators(const ValuatorMask *mask, int *valuators_in)
|
||||
{
|
||||
int *valuators;
|
||||
|
||||
if (!valuators_in)
|
||||
valuators = calloc(valuator_mask_size(mask), sizeof(int));
|
||||
else
|
||||
valuators = valuators_in;
|
||||
|
||||
memcpy(valuators, mask->valuators,
|
||||
valuator_mask_size(mask) * sizeof(int));
|
||||
|
||||
return valuators;
|
||||
}
|
||||
|
||||
void
|
||||
valuator_mask_copy(ValuatorMask *dest, const ValuatorMask *src)
|
||||
{
|
||||
if (src)
|
||||
memcpy(dest, src, sizeof(*dest));
|
||||
else
|
||||
valuator_mask_zero(dest);
|
||||
}
|
||||
|
||||
int
|
||||
CountBits(const uint8_t *mask, int len)
|
||||
|
||||
Reference in New Issue
Block a user