diff --git a/dix/inpututils.c b/dix/inpututils.c
index 49e175822c6ac4528147a98155853116116e3291..1fb9a8a5bb5d4f4e73343a54a5e0a4c4bd1dc09d 100644 (file)
--- a/dix/inpututils.c
+++ b/dix/inpututils.c
#include "xkbstr.h"
#include "inpututils.h"
#include "eventstr.h"
+#include "scrnintstr.h"
/* Check if a button map change is okay with the device.
* Returns -1 for BadValue, as it collides with MappingBusy. */
}
/**
- * Set the valuator to the given data.
+ * Set the valuator to the given floating-point data.
*/
void
-valuator_mask_set(ValuatorMask *mask, int valuator, int data)
+valuator_mask_set_double(ValuatorMask *mask, int valuator, double data)
{
mask->last_bit = max(valuator, mask->last_bit);
SetBit(mask->mask, valuator);
}
/**
- * Return the requested valuator value. If the mask bit is not set for the
- * given valuator, the returned value is undefined.
+ * Set the valuator to the given integer data.
+ */
+void
+valuator_mask_set(ValuatorMask *mask, int valuator, int data)
+{
+ valuator_mask_set_double(mask, valuator, data);
+}
+
+/**
+ * Return the requested valuator value as a double. If the mask bit is not
+ * set for the given valuator, the returned value is undefined.
+ */
+double
+valuator_mask_get_double(const ValuatorMask *mask, int valuator)
+{
+ return mask->valuators[valuator];
+}
+
+/**
+ * Return the requested valuator value as an integer, rounding towards zero.
+ * 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];
+ return trunc(valuator_mask_get_double(mask, valuator));
+}
+
+/**
+ * Set value to the requested valuator. If the mask bit is set for this
+ * valuator, value contains the requested valuator value and TRUE is
+ * returned.
+ * If the mask bit is not set for this valuator, value is unchanged and
+ * FALSE is returned.
+ */
+Bool
+valuator_mask_fetch_double(const ValuatorMask *mask, int valuator, double *value)
+{
+ if (valuator_mask_isset(mask, valuator))
+ {
+ *value = valuator_mask_get_double(mask, valuator);
+ return TRUE;
+ } else
+ return FALSE;
+}
+
+/**
+ * Set value to the requested valuator. If the mask bit is set for this
+ * valuator, value contains the requested valuator value and TRUE is
+ * returned.
+ * If the mask bit is not set for this valuator, value is unchanged and
+ * FALSE is returned.
+ */
+Bool
+valuator_mask_fetch(const ValuatorMask *mask, int valuator, int *value)
+{
+ if (valuator_mask_isset(mask, valuator))
+ {
+ *value = valuator_mask_get(mask, valuator);
+ return TRUE;
+ } else
+ return FALSE;
}
/**
int i, lastbit = -1;
ClearBit(mask->mask, valuator);
- mask->valuators[valuator] = 0;
+ mask->valuators[valuator] = 0.0;
for (i = 0; i <= mask->last_bit; i++)
if (valuator_mask_isset(mask, i))
if (ev && ev->any.header != ET_Internal)
{
int i;
- unsigned char *data = (unsigned char*)ev;
+ const unsigned char *data = (const unsigned char*)ev;
ErrorF("dix: invalid event type %d\n", ev->any.header);
FatalError("Wrong event type %d. Aborting server\n", ev->any.header);
}
}
+
+/**
+ * Initializes the given event to zero (or default values), for the given
+ * device.
+ */
+void init_device_event(DeviceEvent *event, DeviceIntPtr dev, Time ms)
+{
+ memset(event, 0, sizeof(DeviceEvent));
+ event->header = ET_Internal;
+ event->length = sizeof(DeviceEvent);
+ event->time = ms;
+ event->deviceid = dev->id;
+ event->sourceid = dev->id;
+}
+
+int event_get_corestate(DeviceIntPtr mouse, DeviceIntPtr kbd)
+{
+ int corestate;
+ /* core state needs to be assembled BEFORE the device is updated. */
+ corestate = (kbd && kbd->key) ? XkbStateFieldFromRec(&kbd->key->xkbInfo->state) : 0;
+ corestate |= (mouse && mouse->button) ? (mouse->button->state) : 0;
+ corestate |= (mouse && mouse->touch) ? (mouse->touch->state) : 0;
+
+ return corestate;
+}
+
+void event_set_state(DeviceIntPtr mouse, DeviceIntPtr kbd, DeviceEvent *event)
+{
+ int i;
+
+ for (i = 0; mouse && mouse->button && i < mouse->button->numButtons; i++)
+ if (BitIsOn(mouse->button->down, i))
+ SetBit(event->buttons, mouse->button->map[i]);
+
+ if (mouse && mouse->touch && mouse->touch->buttonsDown > 0)
+ SetBit(event->buttons, mouse->button->map[1]);
+
+ if (kbd && kbd->key)
+ {
+ XkbStatePtr state;
+ /* we need the state before the event happens */
+ if (event->type == ET_KeyPress || event->type == ET_KeyRelease)
+ state = &kbd->key->xkbInfo->prev_state;
+ else
+ state = &kbd->key->xkbInfo->state;
+
+ event->mods.base = state->base_mods;
+ event->mods.latched = state->latched_mods;
+ event->mods.locked = state->locked_mods;
+ event->mods.effective = state->mods;
+
+ event->group.base = state->base_group;
+ event->group.latched = state->latched_group;
+ event->group.locked = state->locked_group;
+ event->group.effective = state->group;
+ }
+}
+
+/**
+ * Return the event filter mask for the given device and the given core or
+ * XI1 protocol type.
+ */
+Mask
+event_get_filter_from_type(DeviceIntPtr dev, int evtype)
+{
+ return event_filters[dev ? dev->id : 0][evtype];
+}
+
+/**
+ * Return the event filter mask for the given device and the given core or
+ * XI2 protocol type.
+ */
+Mask
+event_get_filter_from_xi2type(int evtype)
+{
+ return (1 << (evtype % 8));
+}
+
+Bool
+point_on_screen(ScreenPtr pScreen, int x, int y)
+{
+ return x >= pScreen->x && x < pScreen->x + pScreen->width &&
+ y >= pScreen->y && y < pScreen->y + pScreen->height;
+}
+
+/**
+ * Update desktop dimensions on the screenInfo struct.
+ */
+void
+update_desktop_dimensions(void)
+{
+ int i;
+ int x1 = INT_MAX, y1 = INT_MAX; /* top-left */
+ int x2 = INT_MIN, y2 = INT_MIN; /* bottom-right */
+
+ for (i = 0; i < screenInfo.numScreens; i++) {
+ ScreenPtr screen = screenInfo.screens[i];
+ x1 = min(x1, screen->x);
+ y1 = min(y1, screen->y);
+ x2 = max(x2, screen->x + screen->width);
+ y2 = max(y2, screen->y + screen->height);
+ }
+
+ screenInfo.x = x1;
+ screenInfo.y = y1;
+ screenInfo.width = x2 - x1;
+ screenInfo.height = y2 - y1;
+}
+
+
+/* FP1616/FP3232 conversion functions.
+ * Fixed point types are encoded as signed integral and unsigned frac. So any
+ * negative number -n.m is encoded as floor(n) + (1 - 0.m).
+ */
+double
+fp1616_to_double(FP1616 in)
+{
+ double ret;
+
+ ret = (double)(in >> 16);
+ ret += (double)(in & 0xffff) * (1.0 / (1UL << 16)); /* Optimized: ldexp((double)(in & 0xffff), -16); */
+ return ret;
+}
+
+double
+fp3232_to_double(FP3232 in)
+{
+ double ret;
+ ret = (double)in.integral;
+ ret += (double)in.frac * (1.0 / (1ULL << 32)); /* Optimized: ldexp((double)in.frac, -32); */
+ return ret;
+}
+
+
+FP1616
+double_to_fp1616(double in)
+{
+ FP1616 ret;
+ int32_t integral;
+ double tmp;
+ uint32_t frac_d;
+
+ tmp = floor(in);
+ integral = (int32_t)tmp;
+
+ tmp = (in - integral) * (1UL << 16); /* Optimized: ldexp(in - integral, 16) */
+ frac_d = (uint16_t)tmp;
+
+ ret = integral << 16;
+ ret |= frac_d & 0xffff;
+ return ret;
+}
+
+FP3232
+double_to_fp3232(double in)
+{
+ FP3232 ret;
+ int32_t integral;
+ double tmp;
+ uint32_t frac_d;
+
+ tmp = floor(in);
+ integral = (int32_t)tmp;
+
+ tmp = (in - integral) * (1ULL << 32); /* Optimized: ldexp(in - integral, 32) */
+ frac_d = (uint32_t)tmp;
+
+ ret.integral = integral;
+ ret.frac = frac_d;
+ return ret;
+}
+
+/**
+ * DO NOT USE THIS FUNCTION. It only exists for the test cases. Use
+ * xi2mask_new() instead to get the standard sized masks.
+ *
+ * @param nmasks The number of masks (== number of devices)
+ * @param size The size of the masks in bytes
+ * @return The new mask or NULL on allocation error.
+ */
+XI2Mask*
+xi2mask_new_with_size(size_t nmasks, size_t size)
+{
+ int i;
+
+ XI2Mask *mask = calloc(1, sizeof(*mask));
+ if (!mask)
+ return NULL;
+
+
+ mask->nmasks = nmasks;
+ mask->mask_size = size;
+
+ mask->masks = calloc(mask->nmasks, sizeof(*mask->masks));
+ if (!mask->masks)
+ goto unwind;
+
+ for (i = 0; i < mask->nmasks; i++) {
+ mask->masks[i] = calloc(1, mask->mask_size);
+ if (!mask->masks[i])
+ goto unwind;
+ }
+ return mask;
+
+unwind:
+ xi2mask_free(&mask);
+ return NULL;
+}
+
+
+/**
+ * Create a new XI2 mask of the standard size, i.e. for all devices + fake
+ * devices and for the highest supported XI2 event type.
+ *
+ * @return The new mask or NULL on allocation error.
+ */
+XI2Mask*
+xi2mask_new(void)
+{
+ return xi2mask_new_with_size(EMASKSIZE, XI2MASKSIZE);
+}
+
+/**
+ * Frees memory associated with mask and resets mask to NULL.
+ */
+void
+xi2mask_free(XI2Mask** mask)
+{
+ int i;
+
+ if (!(*mask))
+ return;
+
+ for (i = 0; (*mask)->masks && i < (*mask)->nmasks; i++)
+ free((*mask)->masks[i]);
+ free((*mask)->masks);
+ free((*mask));
+ *mask = NULL;
+}
+
+/**
+ * Test if the bit for event type is set for this device, or the
+ * XIAllDevices/XIAllMasterDevices (if applicable) is set.
+ *
+ * @return TRUE if the bit is set, FALSE otherwise
+ */
+Bool
+xi2mask_isset(XI2Mask* mask, const DeviceIntPtr dev, int event_type)
+{
+ int set = 0;
+
+ BUG_WARN(dev->id < 0);
+ BUG_WARN(dev->id >= mask->nmasks);
+ BUG_WARN(bits_to_bytes(event_type + 1) > mask->mask_size);
+
+ set = !!BitIsOn(mask->masks[XIAllDevices], event_type);
+ if (!set)
+ set = !!BitIsOn(mask->masks[dev->id], event_type);
+ if (!set && IsMaster(dev))
+ set = !!BitIsOn(mask->masks[XIAllMasterDevices], event_type);
+
+ return set;
+}
+
+/**
+ * Set the mask bit for this event type for this device.
+ */
+void
+xi2mask_set(XI2Mask *mask, int deviceid, int event_type)
+{
+ BUG_WARN(deviceid < 0);
+ BUG_WARN(deviceid >= mask->nmasks);
+ BUG_WARN(bits_to_bytes(event_type + 1) > mask->mask_size);
+
+ SetBit(mask->masks[deviceid], event_type);
+}
+
+/**
+ * Zero out the xi2mask, for the deviceid given. If the deviceid is < 0, all
+ * masks are zeroed.
+ */
+void
+xi2mask_zero(XI2Mask *mask, int deviceid)
+{
+ int i;
+
+ BUG_WARN(deviceid > 0 && deviceid >= mask->nmasks);
+
+ if (deviceid >= 0)
+ memset(mask->masks[deviceid], 0, mask->mask_size);
+ else
+ for (i = 0; i < mask->nmasks; i++)
+ memset(mask->masks[i], 0, mask->mask_size);
+}
+
+/**
+ * Merge source into dest, i.e. dest |= source.
+ * If the masks are of different size, only the overlapping section is merged.
+ */
+void
+xi2mask_merge(XI2Mask *dest, const XI2Mask *source)
+{
+ int i, j;
+
+ for (i = 0; i < min(dest->nmasks, source->nmasks); i++)
+ for (j = 0; j < min(dest->mask_size, source->mask_size); j++)
+ dest->masks[i][j] |= source->masks[i][j];
+}
+
+/**
+ * @return The number of masks in mask
+ */
+size_t
+xi2mask_num_masks(const XI2Mask *mask)
+{
+ return mask->nmasks;
+}
+
+/**
+ * @return The size of each mask in bytes
+ */
+size_t
+xi2mask_mask_size(const XI2Mask *mask)
+{
+ return mask->mask_size;
+}
+
+/**
+ * Set the mask for the given deviceid to the source mask.
+ * If the mask given is larger than the target memory, only the overlapping
+ * parts are copied.
+ */
+void
+xi2mask_set_one_mask(XI2Mask *xi2mask, int deviceid, const unsigned char *mask, size_t mask_size)
+{
+ BUG_WARN(deviceid < 0);
+ BUG_WARN(deviceid >= xi2mask->nmasks);
+
+ memcpy(xi2mask->masks[deviceid], mask, min(xi2mask->mask_size, mask_size));
+}
+
+/**
+ * Get a reference to the XI2mask for this particular device.
+ */
+const unsigned char*
+xi2mask_get_one_mask(const XI2Mask *mask, int deviceid)
+{
+ BUG_WARN(deviceid < 0);
+ BUG_WARN(deviceid >= mask->nmasks);
+
+ return mask->masks[deviceid];
+}