Merge remote-tracking branch 'whot/for-keith'
This commit is contained in:
commit
522f8bcc03
|
@ -885,7 +885,7 @@ ProcessOtherEvent(InternalEvent *ev, DeviceIntPtr device)
|
||||||
int key = 0, rootX, rootY;
|
int key = 0, rootX, rootY;
|
||||||
ButtonClassPtr b;
|
ButtonClassPtr b;
|
||||||
int ret = 0;
|
int ret = 0;
|
||||||
int state, i;
|
int corestate, i;
|
||||||
DeviceIntPtr mouse = NULL, kbd = NULL;
|
DeviceIntPtr mouse = NULL, kbd = NULL;
|
||||||
DeviceEvent *event = &ev->device_event;
|
DeviceEvent *event = &ev->device_event;
|
||||||
|
|
||||||
|
@ -915,9 +915,9 @@ ProcessOtherEvent(InternalEvent *ev, DeviceIntPtr device)
|
||||||
mouse = NULL;
|
mouse = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* State needs to be assembled BEFORE the device is updated. */
|
/* core state needs to be assembled BEFORE the device is updated. */
|
||||||
state = (kbd && kbd->key) ? XkbStateFieldFromRec(&kbd->key->xkbInfo->state) : 0;
|
corestate = (kbd && kbd->key) ? XkbStateFieldFromRec(&kbd->key->xkbInfo->state) : 0;
|
||||||
state |= (mouse && mouse->button) ? (mouse->button->state) : 0;
|
corestate |= (mouse && mouse->button) ? (mouse->button->state) : 0;
|
||||||
|
|
||||||
for (i = 0; mouse && mouse->button && i < mouse->button->numButtons; i++)
|
for (i = 0; mouse && mouse->button && i < mouse->button->numButtons; i++)
|
||||||
if (BitIsOn(mouse->button->down, i))
|
if (BitIsOn(mouse->button->down, i))
|
||||||
|
@ -965,7 +965,7 @@ ProcessOtherEvent(InternalEvent *ev, DeviceIntPtr device)
|
||||||
event->root_x = rootX;
|
event->root_x = rootX;
|
||||||
event->root_y = rootY;
|
event->root_y = rootY;
|
||||||
NoticeEventTime((InternalEvent*)event);
|
NoticeEventTime((InternalEvent*)event);
|
||||||
event->corestate = state;
|
event->corestate = corestate;
|
||||||
key = event->detail.key;
|
key = event->detail.key;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -1002,11 +1002,9 @@ ProcessOtherEvent(InternalEvent *ev, DeviceIntPtr device)
|
||||||
deactivateDeviceGrab = TRUE;
|
deactivateDeviceGrab = TRUE;
|
||||||
break;
|
break;
|
||||||
case ET_ButtonPress:
|
case ET_ButtonPress:
|
||||||
event->detail.button = b->map[key];
|
if (b->map[key] == 0) /* there's no button 0 */
|
||||||
if (!event->detail.button) { /* there's no button 0 */
|
|
||||||
event->detail.button = key;
|
|
||||||
return;
|
return;
|
||||||
}
|
event->detail.button = b->map[key];
|
||||||
if (!grab && CheckDeviceGrabs(device, event, 0))
|
if (!grab && CheckDeviceGrabs(device, event, 0))
|
||||||
{
|
{
|
||||||
/* if a passive grab was activated, the event has been sent
|
/* if a passive grab was activated, the event has been sent
|
||||||
|
@ -1015,11 +1013,9 @@ ProcessOtherEvent(InternalEvent *ev, DeviceIntPtr device)
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case ET_ButtonRelease:
|
case ET_ButtonRelease:
|
||||||
event->detail.button = b->map[key];
|
if (b->map[key] == 0) /* there's no button 0 */
|
||||||
if (!event->detail.button) { /* there's no button 0 */
|
|
||||||
event->detail.button = key;
|
|
||||||
return;
|
return;
|
||||||
}
|
event->detail.button = b->map[key];
|
||||||
if (grab && !b->buttonsDown &&
|
if (grab && !b->buttonsDown &&
|
||||||
device->deviceGrab.fromPassiveGrab &&
|
device->deviceGrab.fromPassiveGrab &&
|
||||||
(device->deviceGrab.grab->type == ButtonPress ||
|
(device->deviceGrab.grab->type == ButtonPress ||
|
||||||
|
@ -1033,7 +1029,7 @@ ProcessOtherEvent(InternalEvent *ev, DeviceIntPtr device)
|
||||||
|
|
||||||
if (grab)
|
if (grab)
|
||||||
DeliverGrabbedEvent((InternalEvent*)event, device, deactivateDeviceGrab);
|
DeliverGrabbedEvent((InternalEvent*)event, device, deactivateDeviceGrab);
|
||||||
else if (device->focus && !IsPointerEvent((InternalEvent*)ev))
|
else if (device->focus && !IsPointerEvent(ev))
|
||||||
DeliverFocusedEvent(device, (InternalEvent*)event,
|
DeliverFocusedEvent(device, (InternalEvent*)event,
|
||||||
GetSpriteWindow(device));
|
GetSpriteWindow(device));
|
||||||
else
|
else
|
||||||
|
@ -1631,6 +1627,7 @@ SelectForWindow(DeviceIntPtr dev, WindowPtr pWin, ClientPtr client,
|
||||||
static void
|
static void
|
||||||
FreeInputClient(InputClientsPtr *other)
|
FreeInputClient(InputClientsPtr *other)
|
||||||
{
|
{
|
||||||
|
xi2mask_free(&(*other)->xi2mask);
|
||||||
free(*other);
|
free(*other);
|
||||||
*other = NULL;
|
*other = NULL;
|
||||||
}
|
}
|
||||||
|
@ -1653,6 +1650,9 @@ AddExtensionClient(WindowPtr pWin, ClientPtr client, Mask mask, int mskidx)
|
||||||
return BadAlloc;
|
return BadAlloc;
|
||||||
if (!pWin->optional->inputMasks && !MakeInputMasks(pWin))
|
if (!pWin->optional->inputMasks && !MakeInputMasks(pWin))
|
||||||
goto bail;
|
goto bail;
|
||||||
|
others->xi2mask = xi2mask_new();
|
||||||
|
if (!others->xi2mask)
|
||||||
|
goto bail;
|
||||||
others->mask[mskidx] = mask;
|
others->mask[mskidx] = mask;
|
||||||
others->resource = FakeClientID(client->index);
|
others->resource = FakeClientID(client->index);
|
||||||
others->next = pWin->optional->inputMasks->inputClients;
|
others->next = pWin->optional->inputMasks->inputClients;
|
||||||
|
@ -1674,6 +1674,12 @@ MakeInputMasks(WindowPtr pWin)
|
||||||
imasks = calloc(1, sizeof(struct _OtherInputMasks));
|
imasks = calloc(1, sizeof(struct _OtherInputMasks));
|
||||||
if (!imasks)
|
if (!imasks)
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
imasks->xi2mask = xi2mask_new();
|
||||||
|
if (!imasks->xi2mask)
|
||||||
|
{
|
||||||
|
free(imasks);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
pWin->optional->inputMasks = imasks;
|
pWin->optional->inputMasks = imasks;
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
@ -1681,6 +1687,7 @@ MakeInputMasks(WindowPtr pWin)
|
||||||
static void
|
static void
|
||||||
FreeInputMask(OtherInputMasks **imask)
|
FreeInputMask(OtherInputMasks **imask)
|
||||||
{
|
{
|
||||||
|
xi2mask_free(&(*imask)->xi2mask);
|
||||||
free(*imask);
|
free(*imask);
|
||||||
*imask = NULL;
|
*imask = NULL;
|
||||||
}
|
}
|
||||||
|
@ -1691,20 +1698,17 @@ RecalculateDeviceDeliverableEvents(WindowPtr pWin)
|
||||||
InputClientsPtr others;
|
InputClientsPtr others;
|
||||||
struct _OtherInputMasks *inputMasks; /* default: NULL */
|
struct _OtherInputMasks *inputMasks; /* default: NULL */
|
||||||
WindowPtr pChild, tmp;
|
WindowPtr pChild, tmp;
|
||||||
int i, j;
|
int i;
|
||||||
|
|
||||||
pChild = pWin;
|
pChild = pWin;
|
||||||
while (1) {
|
while (1) {
|
||||||
if ((inputMasks = wOtherInputMasks(pChild)) != 0) {
|
if ((inputMasks = wOtherInputMasks(pChild)) != 0) {
|
||||||
for (i = 0; i < EMASKSIZE; i++)
|
xi2mask_zero(inputMasks->xi2mask, -1);
|
||||||
memset(inputMasks->xi2mask[i], 0, sizeof(inputMasks->xi2mask[i]));
|
|
||||||
for (others = inputMasks->inputClients; others;
|
for (others = inputMasks->inputClients; others;
|
||||||
others = others->next) {
|
others = others->next) {
|
||||||
for (i = 0; i < EMASKSIZE; i++)
|
for (i = 0; i < EMASKSIZE; i++)
|
||||||
inputMasks->inputEvents[i] |= others->mask[i];
|
inputMasks->inputEvents[i] |= others->mask[i];
|
||||||
for (i = 0; i < EMASKSIZE; i++)
|
xi2mask_merge(inputMasks->xi2mask, others->xi2mask);
|
||||||
for (j = 0; j < XI2MASKSIZE; j++)
|
|
||||||
inputMasks->xi2mask[i][j] |= others->xi2mask[i][j];
|
|
||||||
}
|
}
|
||||||
for (i = 0; i < EMASKSIZE; i++)
|
for (i = 0; i < EMASKSIZE; i++)
|
||||||
inputMasks->deliverableEvents[i] = inputMasks->inputEvents[i];
|
inputMasks->deliverableEvents[i] = inputMasks->inputEvents[i];
|
||||||
|
@ -2024,20 +2028,25 @@ CheckDeviceGrabAndHintWindow(WindowPtr pWin, int type,
|
||||||
dev->valuator->motionHintWindow = pWin;
|
dev->valuator->motionHintWindow = pWin;
|
||||||
else if ((type == DeviceButtonPress) && (!grab) &&
|
else if ((type == DeviceButtonPress) && (!grab) &&
|
||||||
(deliveryMask & DeviceButtonGrabMask)) {
|
(deliveryMask & DeviceButtonGrabMask)) {
|
||||||
GrabRec tempGrab;
|
GrabPtr tempGrab;
|
||||||
|
|
||||||
tempGrab.device = dev;
|
tempGrab = AllocGrab();
|
||||||
tempGrab.resource = client->clientAsMask;
|
if (!tempGrab)
|
||||||
tempGrab.window = pWin;
|
return;
|
||||||
tempGrab.ownerEvents =
|
|
||||||
|
tempGrab->device = dev;
|
||||||
|
tempGrab->resource = client->clientAsMask;
|
||||||
|
tempGrab->window = pWin;
|
||||||
|
tempGrab->ownerEvents =
|
||||||
(deliveryMask & DeviceOwnerGrabButtonMask) ? TRUE : FALSE;
|
(deliveryMask & DeviceOwnerGrabButtonMask) ? TRUE : FALSE;
|
||||||
tempGrab.eventMask = deliveryMask;
|
tempGrab->eventMask = deliveryMask;
|
||||||
tempGrab.keyboardMode = GrabModeAsync;
|
tempGrab->keyboardMode = GrabModeAsync;
|
||||||
tempGrab.pointerMode = GrabModeAsync;
|
tempGrab->pointerMode = GrabModeAsync;
|
||||||
tempGrab.confineTo = NullWindow;
|
tempGrab->confineTo = NullWindow;
|
||||||
tempGrab.cursor = NullCursor;
|
tempGrab->cursor = NullCursor;
|
||||||
tempGrab.next = NULL;
|
tempGrab->next = NULL;
|
||||||
(*dev->deviceGrab.ActivateGrab) (dev, &tempGrab, currentTime, TRUE);
|
(*dev->deviceGrab.ActivateGrab) (dev, tempGrab, currentTime, TRUE);
|
||||||
|
FreeGrab(tempGrab);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2183,14 +2192,12 @@ XISetEventMask(DeviceIntPtr dev, WindowPtr win, ClientPtr client,
|
||||||
for (others = wOtherInputMasks(win)->inputClients; others;
|
for (others = wOtherInputMasks(win)->inputClients; others;
|
||||||
others = others->next) {
|
others = others->next) {
|
||||||
if (SameClient(others, client)) {
|
if (SameClient(others, client)) {
|
||||||
memset(others->xi2mask[dev->id], 0,
|
xi2mask_zero(others->xi2mask, dev->id);
|
||||||
sizeof(others->xi2mask[dev->id]));
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
len = min(len, sizeof(others->xi2mask[dev->id]));
|
|
||||||
|
|
||||||
if (len && !others)
|
if (len && !others)
|
||||||
{
|
{
|
||||||
|
@ -2199,11 +2206,14 @@ XISetEventMask(DeviceIntPtr dev, WindowPtr win, ClientPtr client,
|
||||||
others= wOtherInputMasks(win)->inputClients;
|
others= wOtherInputMasks(win)->inputClients;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (others)
|
if (others) {
|
||||||
memset(others->xi2mask[dev->id], 0, sizeof(others->xi2mask[dev->id]));
|
xi2mask_zero(others->xi2mask, dev->id);
|
||||||
|
len = min(len, xi2mask_mask_size(others->xi2mask));
|
||||||
|
}
|
||||||
|
|
||||||
if (len)
|
if (len) {
|
||||||
memcpy(others->xi2mask[dev->id], mask, len);
|
xi2mask_set_one_mask(others->xi2mask, dev->id, mask, len);
|
||||||
|
}
|
||||||
|
|
||||||
RecalculateDeviceDeliverableEvents(win);
|
RecalculateDeviceDeliverableEvents(win);
|
||||||
|
|
||||||
|
|
|
@ -96,7 +96,7 @@ ProcXUngrabDeviceButton(ClientPtr client)
|
||||||
DeviceIntPtr dev;
|
DeviceIntPtr dev;
|
||||||
DeviceIntPtr mdev;
|
DeviceIntPtr mdev;
|
||||||
WindowPtr pWin;
|
WindowPtr pWin;
|
||||||
GrabRec temporaryGrab;
|
GrabPtr temporaryGrab;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
REQUEST(xUngrabDeviceButtonReq);
|
REQUEST(xUngrabDeviceButtonReq);
|
||||||
|
@ -126,17 +126,23 @@ ProcXUngrabDeviceButton(ClientPtr client)
|
||||||
(stuff->modifiers & ~AllModifiersMask))
|
(stuff->modifiers & ~AllModifiersMask))
|
||||||
return BadValue;
|
return BadValue;
|
||||||
|
|
||||||
temporaryGrab.resource = client->clientAsMask;
|
temporaryGrab = AllocGrab();
|
||||||
temporaryGrab.device = dev;
|
if (!temporaryGrab)
|
||||||
temporaryGrab.window = pWin;
|
return BadAlloc;
|
||||||
temporaryGrab.type = DeviceButtonPress;
|
|
||||||
temporaryGrab.grabtype = GRABTYPE_XI;
|
|
||||||
temporaryGrab.modifierDevice = mdev;
|
|
||||||
temporaryGrab.modifiersDetail.exact = stuff->modifiers;
|
|
||||||
temporaryGrab.modifiersDetail.pMask = NULL;
|
|
||||||
temporaryGrab.detail.exact = stuff->button;
|
|
||||||
temporaryGrab.detail.pMask = NULL;
|
|
||||||
|
|
||||||
DeletePassiveGrabFromList(&temporaryGrab);
|
temporaryGrab->resource = client->clientAsMask;
|
||||||
|
temporaryGrab->device = dev;
|
||||||
|
temporaryGrab->window = pWin;
|
||||||
|
temporaryGrab->type = DeviceButtonPress;
|
||||||
|
temporaryGrab->grabtype = GRABTYPE_XI;
|
||||||
|
temporaryGrab->modifierDevice = mdev;
|
||||||
|
temporaryGrab->modifiersDetail.exact = stuff->modifiers;
|
||||||
|
temporaryGrab->modifiersDetail.pMask = NULL;
|
||||||
|
temporaryGrab->detail.exact = stuff->button;
|
||||||
|
temporaryGrab->detail.pMask = NULL;
|
||||||
|
|
||||||
|
DeletePassiveGrabFromList(temporaryGrab);
|
||||||
|
|
||||||
|
FreeGrab(temporaryGrab);
|
||||||
return Success;
|
return Success;
|
||||||
}
|
}
|
||||||
|
|
|
@ -98,7 +98,7 @@ ProcXUngrabDeviceKey(ClientPtr client)
|
||||||
DeviceIntPtr dev;
|
DeviceIntPtr dev;
|
||||||
DeviceIntPtr mdev;
|
DeviceIntPtr mdev;
|
||||||
WindowPtr pWin;
|
WindowPtr pWin;
|
||||||
GrabRec temporaryGrab;
|
GrabPtr temporaryGrab;
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
REQUEST(xUngrabDeviceKeyReq);
|
REQUEST(xUngrabDeviceKeyReq);
|
||||||
|
@ -133,17 +133,22 @@ ProcXUngrabDeviceKey(ClientPtr client)
|
||||||
(stuff->modifiers & ~AllModifiersMask))
|
(stuff->modifiers & ~AllModifiersMask))
|
||||||
return BadValue;
|
return BadValue;
|
||||||
|
|
||||||
temporaryGrab.resource = client->clientAsMask;
|
temporaryGrab = AllocGrab();
|
||||||
temporaryGrab.device = dev;
|
if (!temporaryGrab)
|
||||||
temporaryGrab.window = pWin;
|
return BadAlloc;
|
||||||
temporaryGrab.type = DeviceKeyPress;
|
|
||||||
temporaryGrab.grabtype = GRABTYPE_XI;
|
|
||||||
temporaryGrab.modifierDevice = mdev;
|
|
||||||
temporaryGrab.modifiersDetail.exact = stuff->modifiers;
|
|
||||||
temporaryGrab.modifiersDetail.pMask = NULL;
|
|
||||||
temporaryGrab.detail.exact = stuff->key;
|
|
||||||
temporaryGrab.detail.pMask = NULL;
|
|
||||||
|
|
||||||
DeletePassiveGrabFromList(&temporaryGrab);
|
temporaryGrab->resource = client->clientAsMask;
|
||||||
|
temporaryGrab->device = dev;
|
||||||
|
temporaryGrab->window = pWin;
|
||||||
|
temporaryGrab->type = DeviceKeyPress;
|
||||||
|
temporaryGrab->grabtype = GRABTYPE_XI;
|
||||||
|
temporaryGrab->modifierDevice = mdev;
|
||||||
|
temporaryGrab->modifiersDetail.exact = stuff->modifiers;
|
||||||
|
temporaryGrab->modifiersDetail.pMask = NULL;
|
||||||
|
temporaryGrab->detail.exact = stuff->key;
|
||||||
|
temporaryGrab->detail.pMask = NULL;
|
||||||
|
|
||||||
|
DeletePassiveGrabFromList(temporaryGrab);
|
||||||
|
FreeGrab(temporaryGrab);
|
||||||
return Success;
|
return Success;
|
||||||
}
|
}
|
||||||
|
|
|
@ -200,6 +200,19 @@ unwind:
|
||||||
return rc;
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
disable_clientpointer(DeviceIntPtr dev)
|
||||||
|
{
|
||||||
|
int i;
|
||||||
|
|
||||||
|
for (i = 0; i < currentMaxClients; i++)
|
||||||
|
{
|
||||||
|
ClientPtr client = clients[i];
|
||||||
|
if (client && client->clientPtr == dev)
|
||||||
|
client->clientPtr = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
remove_master(ClientPtr client, xXIRemoveMasterInfo *r,
|
remove_master(ClientPtr client, xXIRemoveMasterInfo *r,
|
||||||
int flags[MAXDEVICES])
|
int flags[MAXDEVICES])
|
||||||
|
@ -250,6 +263,8 @@ remove_master(ClientPtr client, xXIRemoveMasterInfo *r,
|
||||||
if (rc != Success)
|
if (rc != Success)
|
||||||
goto unwind;
|
goto unwind;
|
||||||
|
|
||||||
|
disable_clientpointer(ptr);
|
||||||
|
|
||||||
/* Disabling sends the devices floating, reattach them if
|
/* Disabling sends the devices floating, reattach them if
|
||||||
* desired. */
|
* desired. */
|
||||||
if (r->return_mode == XIAttachToMaster)
|
if (r->return_mode == XIAttachToMaster)
|
||||||
|
|
|
@ -41,6 +41,7 @@
|
||||||
#include "exglobals.h" /* BadDevice */
|
#include "exglobals.h" /* BadDevice */
|
||||||
#include "exevents.h"
|
#include "exevents.h"
|
||||||
#include "xigrabdev.h"
|
#include "xigrabdev.h"
|
||||||
|
#include "inpututils.h"
|
||||||
|
|
||||||
int
|
int
|
||||||
SProcXIGrabDevice(ClientPtr client)
|
SProcXIGrabDevice(ClientPtr client)
|
||||||
|
@ -64,7 +65,7 @@ ProcXIGrabDevice(ClientPtr client)
|
||||||
xXIGrabDeviceReply rep;
|
xXIGrabDeviceReply rep;
|
||||||
int ret = Success;
|
int ret = Success;
|
||||||
uint8_t status;
|
uint8_t status;
|
||||||
GrabMask mask;
|
GrabMask mask = { 0 };
|
||||||
int mask_len;
|
int mask_len;
|
||||||
|
|
||||||
REQUEST(xXIGrabDeviceReq);
|
REQUEST(xXIGrabDeviceReq);
|
||||||
|
@ -81,9 +82,13 @@ ProcXIGrabDevice(ClientPtr client)
|
||||||
stuff->mask_len * 4) != Success)
|
stuff->mask_len * 4) != Success)
|
||||||
return BadValue;
|
return BadValue;
|
||||||
|
|
||||||
mask_len = min(sizeof(mask.xi2mask[stuff->deviceid]), stuff->mask_len * 4);
|
mask.xi2mask = xi2mask_new();
|
||||||
memset(mask.xi2mask, 0, sizeof(mask.xi2mask));
|
if (!mask.xi2mask)
|
||||||
memcpy(mask.xi2mask, (char*)&stuff[1], mask_len);
|
return BadAlloc;
|
||||||
|
|
||||||
|
mask_len = min(xi2mask_mask_size(mask.xi2mask), stuff->mask_len * 4);
|
||||||
|
/* FIXME: I think the old code was broken here */
|
||||||
|
xi2mask_set_one_mask(mask.xi2mask, dev->id, (unsigned char*)&stuff[1], mask_len);
|
||||||
|
|
||||||
ret = GrabDevice(client, dev, stuff->grab_mode,
|
ret = GrabDevice(client, dev, stuff->grab_mode,
|
||||||
stuff->paired_device_mode,
|
stuff->paired_device_mode,
|
||||||
|
@ -96,6 +101,8 @@ ProcXIGrabDevice(ClientPtr client)
|
||||||
None /* confineTo */,
|
None /* confineTo */,
|
||||||
&status);
|
&status);
|
||||||
|
|
||||||
|
xi2mask_free(&mask.xi2mask);
|
||||||
|
|
||||||
if (ret != Success)
|
if (ret != Success)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
|
|
|
@ -44,6 +44,7 @@
|
||||||
#include "xipassivegrab.h"
|
#include "xipassivegrab.h"
|
||||||
#include "dixgrabs.h"
|
#include "dixgrabs.h"
|
||||||
#include "misc.h"
|
#include "misc.h"
|
||||||
|
#include "inpututils.h"
|
||||||
|
|
||||||
int
|
int
|
||||||
SProcXIPassiveGrabDevice(ClientPtr client)
|
SProcXIPassiveGrabDevice(ClientPtr client)
|
||||||
|
@ -82,7 +83,7 @@ ProcXIPassiveGrabDevice(ClientPtr client)
|
||||||
int i, ret = Success;
|
int i, ret = Success;
|
||||||
uint32_t *modifiers;
|
uint32_t *modifiers;
|
||||||
xXIGrabModifierInfo *modifiers_failed;
|
xXIGrabModifierInfo *modifiers_failed;
|
||||||
GrabMask mask;
|
GrabMask mask = { 0 };
|
||||||
GrabParameters param;
|
GrabParameters param;
|
||||||
void *tmp;
|
void *tmp;
|
||||||
int mask_len;
|
int mask_len;
|
||||||
|
@ -124,9 +125,12 @@ ProcXIPassiveGrabDevice(ClientPtr client)
|
||||||
stuff->mask_len * 4) != Success)
|
stuff->mask_len * 4) != Success)
|
||||||
return BadValue;
|
return BadValue;
|
||||||
|
|
||||||
mask_len = min(sizeof(mask.xi2mask[stuff->deviceid]), stuff->mask_len * 4);
|
mask.xi2mask = xi2mask_new();
|
||||||
memset(mask.xi2mask, 0, sizeof(mask.xi2mask));
|
if (!mask.xi2mask)
|
||||||
memcpy(mask.xi2mask[stuff->deviceid], &stuff[1], mask_len * 4);
|
return BadAlloc;
|
||||||
|
|
||||||
|
mask_len = min(xi2mask_mask_size(mask.xi2mask), stuff->mask_len * 4);
|
||||||
|
xi2mask_set_one_mask(mask.xi2mask, stuff->deviceid, (unsigned char*)&stuff[1], mask_len * 4);
|
||||||
|
|
||||||
rep.repType = X_Reply;
|
rep.repType = X_Reply;
|
||||||
rep.RepType = X_XIPassiveGrabDevice;
|
rep.RepType = X_XIPassiveGrabDevice;
|
||||||
|
@ -212,6 +216,7 @@ ProcXIPassiveGrabDevice(ClientPtr client)
|
||||||
|
|
||||||
free(modifiers_failed);
|
free(modifiers_failed);
|
||||||
out:
|
out:
|
||||||
|
xi2mask_free(&mask.xi2mask);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -253,7 +258,7 @@ ProcXIPassiveUngrabDevice(ClientPtr client)
|
||||||
{
|
{
|
||||||
DeviceIntPtr dev, mod_dev;
|
DeviceIntPtr dev, mod_dev;
|
||||||
WindowPtr win;
|
WindowPtr win;
|
||||||
GrabRec tempGrab;
|
GrabPtr tempGrab;
|
||||||
uint32_t* modifiers;
|
uint32_t* modifiers;
|
||||||
int i, rc;
|
int i, rc;
|
||||||
|
|
||||||
|
@ -293,29 +298,36 @@ ProcXIPassiveUngrabDevice(ClientPtr client)
|
||||||
|
|
||||||
mod_dev = (IsFloating(dev)) ? dev : GetMaster(dev, MASTER_KEYBOARD);
|
mod_dev = (IsFloating(dev)) ? dev : GetMaster(dev, MASTER_KEYBOARD);
|
||||||
|
|
||||||
tempGrab.resource = client->clientAsMask;
|
|
||||||
tempGrab.device = dev;
|
tempGrab = AllocGrab();
|
||||||
tempGrab.window = win;
|
if (!tempGrab)
|
||||||
|
return BadAlloc;
|
||||||
|
|
||||||
|
tempGrab->resource = client->clientAsMask;
|
||||||
|
tempGrab->device = dev;
|
||||||
|
tempGrab->window = win;
|
||||||
switch(stuff->grab_type)
|
switch(stuff->grab_type)
|
||||||
{
|
{
|
||||||
case XIGrabtypeButton: tempGrab.type = XI_ButtonPress; break;
|
case XIGrabtypeButton: tempGrab->type = XI_ButtonPress; break;
|
||||||
case XIGrabtypeKeycode: tempGrab.type = XI_KeyPress; break;
|
case XIGrabtypeKeycode: tempGrab->type = XI_KeyPress; break;
|
||||||
case XIGrabtypeEnter: tempGrab.type = XI_Enter; break;
|
case XIGrabtypeEnter: tempGrab->type = XI_Enter; break;
|
||||||
case XIGrabtypeFocusIn: tempGrab.type = XI_FocusIn; break;
|
case XIGrabtypeFocusIn: tempGrab->type = XI_FocusIn; break;
|
||||||
}
|
}
|
||||||
tempGrab.grabtype = GRABTYPE_XI2;
|
tempGrab->grabtype = GRABTYPE_XI2;
|
||||||
tempGrab.modifierDevice = mod_dev;
|
tempGrab->modifierDevice = mod_dev;
|
||||||
tempGrab.modifiersDetail.pMask = NULL;
|
tempGrab->modifiersDetail.pMask = NULL;
|
||||||
tempGrab.detail.exact = stuff->detail;
|
tempGrab->detail.exact = stuff->detail;
|
||||||
tempGrab.detail.pMask = NULL;
|
tempGrab->detail.pMask = NULL;
|
||||||
|
|
||||||
modifiers = (uint32_t*)&stuff[1];
|
modifiers = (uint32_t*)&stuff[1];
|
||||||
|
|
||||||
for (i = 0; i < stuff->num_modifiers; i++, modifiers++)
|
for (i = 0; i < stuff->num_modifiers; i++, modifiers++)
|
||||||
{
|
{
|
||||||
tempGrab.modifiersDetail.exact = *modifiers;
|
tempGrab->modifiersDetail.exact = *modifiers;
|
||||||
DeletePassiveGrabFromList(&tempGrab);
|
DeletePassiveGrabFromList(tempGrab);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FreeGrab(tempGrab);
|
||||||
|
|
||||||
return Success;
|
return Success;
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,6 +33,7 @@
|
||||||
#include "exglobals.h"
|
#include "exglobals.h"
|
||||||
#include "exevents.h"
|
#include "exevents.h"
|
||||||
#include <X11/extensions/XI2proto.h>
|
#include <X11/extensions/XI2proto.h>
|
||||||
|
#include "inpututils.h"
|
||||||
|
|
||||||
#include "xiselectev.h"
|
#include "xiselectev.h"
|
||||||
|
|
||||||
|
@ -249,7 +250,7 @@ ProcXIGetSelectedEvents(ClientPtr client)
|
||||||
for (i = 0; i < MAXDEVICES; i++)
|
for (i = 0; i < MAXDEVICES; i++)
|
||||||
{
|
{
|
||||||
int j;
|
int j;
|
||||||
unsigned char *devmask = others->xi2mask[i];
|
const unsigned char *devmask = xi2mask_get_one_mask(others->xi2mask, i);
|
||||||
|
|
||||||
if (i > 2)
|
if (i > 2)
|
||||||
{
|
{
|
||||||
|
@ -259,7 +260,7 @@ ProcXIGetSelectedEvents(ClientPtr client)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
for (j = XI2MASKSIZE - 1; j >= 0; j--)
|
for (j = xi2mask_mask_size(others->xi2mask) - 1; j >= 0; j--)
|
||||||
{
|
{
|
||||||
if (devmask[j] != 0)
|
if (devmask[j] != 0)
|
||||||
{
|
{
|
||||||
|
|
|
@ -73,6 +73,7 @@ SOFTWARE.
|
||||||
#include "dixevents.h"
|
#include "dixevents.h"
|
||||||
#include "mipointer.h"
|
#include "mipointer.h"
|
||||||
#include "eventstr.h"
|
#include "eventstr.h"
|
||||||
|
#include "dixgrabs.h"
|
||||||
|
|
||||||
#include <X11/extensions/XI.h>
|
#include <X11/extensions/XI.h>
|
||||||
#include <X11/extensions/XI2.h>
|
#include <X11/extensions/XI2.h>
|
||||||
|
@ -273,6 +274,7 @@ AddInputDevice(ClientPtr client, DeviceProc deviceProc, Bool autoStart)
|
||||||
dev->deviceGrab.grabTime = currentTime;
|
dev->deviceGrab.grabTime = currentTime;
|
||||||
dev->deviceGrab.ActivateGrab = ActivateKeyboardGrab;
|
dev->deviceGrab.ActivateGrab = ActivateKeyboardGrab;
|
||||||
dev->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab;
|
dev->deviceGrab.DeactivateGrab = DeactivateKeyboardGrab;
|
||||||
|
dev->deviceGrab.activeGrab = AllocGrab();
|
||||||
|
|
||||||
XkbSetExtension(dev, ProcessKeyboardEvent);
|
XkbSetExtension(dev, ProcessKeyboardEvent);
|
||||||
|
|
||||||
|
@ -941,6 +943,7 @@ CloseDevice(DeviceIntPtr dev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FreeGrab(dev->deviceGrab.activeGrab);
|
||||||
free(dev->deviceGrab.sync.event);
|
free(dev->deviceGrab.sync.event);
|
||||||
free(dev->config_info); /* Allocated in xf86ActivateDevice. */
|
free(dev->config_info); /* Allocated in xf86ActivateDevice. */
|
||||||
free(dev->last.scroll);
|
free(dev->last.scroll);
|
||||||
|
|
284
dix/events.c
284
dix/events.c
|
@ -420,12 +420,6 @@ GetXI2EventFilterMask(int evtype)
|
||||||
return (1 << (evtype % 8));
|
return (1 << (evtype % 8));
|
||||||
}
|
}
|
||||||
|
|
||||||
static inline int
|
|
||||||
GetXI2EventFilterOffset(int evtype)
|
|
||||||
{
|
|
||||||
return (evtype / 8);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* For the given event, return the matching event filter. This filter may then
|
* For the given event, return the matching event filter. This filter may then
|
||||||
* be AND'ed with the selected event mask.
|
* be AND'ed with the selected event mask.
|
||||||
|
@ -459,12 +453,15 @@ GetEventFilter(DeviceIntPtr dev, xEvent *event)
|
||||||
* for the event_type.
|
* for the event_type.
|
||||||
*/
|
*/
|
||||||
static int
|
static int
|
||||||
GetXI2MaskByte(unsigned char xi2mask[][XI2MASKSIZE], DeviceIntPtr dev, int event_type)
|
GetXI2MaskByte(XI2Mask *mask, DeviceIntPtr dev, int event_type)
|
||||||
{
|
{
|
||||||
int byte = GetXI2EventFilterOffset(event_type);
|
/* we just return the matching filter because that's the only use
|
||||||
return xi2mask[dev->id][byte] |
|
* for this mask anyway.
|
||||||
xi2mask[XIAllDevices][byte] |
|
*/
|
||||||
(IsMaster(dev) ? xi2mask[XIAllMasterDevices][byte] : 0);
|
if (xi2mask_isset(mask, dev, event_type))
|
||||||
|
return GetXI2EventFilterMask(event_type);
|
||||||
|
else
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -476,16 +473,14 @@ Bool
|
||||||
WindowXI2MaskIsset(DeviceIntPtr dev, WindowPtr win, xEvent* ev)
|
WindowXI2MaskIsset(DeviceIntPtr dev, WindowPtr win, xEvent* ev)
|
||||||
{
|
{
|
||||||
OtherInputMasks *inputMasks = wOtherInputMasks(win);
|
OtherInputMasks *inputMasks = wOtherInputMasks(win);
|
||||||
int filter;
|
|
||||||
int evtype;
|
int evtype;
|
||||||
|
|
||||||
if (!inputMasks || xi2_get_type(ev) == 0)
|
if (!inputMasks || xi2_get_type(ev) == 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
evtype = ((xGenericEvent*)ev)->evtype;
|
evtype = ((xGenericEvent*)ev)->evtype;
|
||||||
filter = GetEventFilter(dev, ev);
|
|
||||||
|
|
||||||
return !!(GetXI2MaskByte(inputMasks->xi2mask, dev, evtype) & filter);
|
return xi2mask_isset(inputMasks->xi2mask, dev, evtype);
|
||||||
}
|
}
|
||||||
|
|
||||||
Mask
|
Mask
|
||||||
|
@ -1132,12 +1127,14 @@ NoticeEventTime(InternalEvent *ev)
|
||||||
void
|
void
|
||||||
EnqueueEvent(InternalEvent *ev, DeviceIntPtr device)
|
EnqueueEvent(InternalEvent *ev, DeviceIntPtr device)
|
||||||
{
|
{
|
||||||
QdEventPtr tail = *syncEvents.pendtail;
|
QdEventPtr tail;
|
||||||
QdEventPtr qe;
|
QdEventPtr qe;
|
||||||
SpritePtr pSprite = device->spriteInfo->sprite;
|
SpritePtr pSprite = device->spriteInfo->sprite;
|
||||||
int eventlen;
|
int eventlen;
|
||||||
DeviceEvent *event = &ev->device_event;
|
DeviceEvent *event = &ev->device_event;
|
||||||
|
|
||||||
|
tail = list_last_entry(&syncEvents.pending, QdEventRec, next);
|
||||||
|
|
||||||
NoticeTime((InternalEvent*)event);
|
NoticeTime((InternalEvent*)event);
|
||||||
|
|
||||||
/* Fix for key repeating bug. */
|
/* Fix for key repeating bug. */
|
||||||
|
@ -1196,15 +1193,13 @@ EnqueueEvent(InternalEvent *ev, DeviceIntPtr device)
|
||||||
qe = malloc(sizeof(QdEventRec) + eventlen);
|
qe = malloc(sizeof(QdEventRec) + eventlen);
|
||||||
if (!qe)
|
if (!qe)
|
||||||
return;
|
return;
|
||||||
qe->next = (QdEventPtr)NULL;
|
list_init(&qe->next);
|
||||||
qe->device = device;
|
qe->device = device;
|
||||||
qe->pScreen = pSprite->hotPhys.pScreen;
|
qe->pScreen = pSprite->hotPhys.pScreen;
|
||||||
qe->months = currentTime.months;
|
qe->months = currentTime.months;
|
||||||
qe->event = (InternalEvent *)(qe + 1);
|
qe->event = (InternalEvent *)(qe + 1);
|
||||||
memcpy(qe->event, event, eventlen);
|
memcpy(qe->event, event, eventlen);
|
||||||
if (tail)
|
list_append(&qe->next, &syncEvents.pending);
|
||||||
syncEvents.pendtail = &tail->next;
|
|
||||||
*syncEvents.pendtail = qe;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -1216,22 +1211,20 @@ EnqueueEvent(InternalEvent *ev, DeviceIntPtr device)
|
||||||
* If there is none, we're done. If there is at least one device that is not
|
* If there is none, we're done. If there is at least one device that is not
|
||||||
* frozen, then re-run from the beginning of the event queue.
|
* frozen, then re-run from the beginning of the event queue.
|
||||||
*/
|
*/
|
||||||
static void
|
void
|
||||||
PlayReleasedEvents(void)
|
PlayReleasedEvents(void)
|
||||||
{
|
{
|
||||||
QdEventPtr *prev, qe;
|
QdEventPtr tmp;
|
||||||
|
QdEventPtr qe;
|
||||||
DeviceIntPtr dev;
|
DeviceIntPtr dev;
|
||||||
DeviceIntPtr pDev;
|
DeviceIntPtr pDev;
|
||||||
|
|
||||||
prev = &syncEvents.pending;
|
restart:
|
||||||
while ( (qe = *prev) )
|
list_for_each_entry_safe(qe, tmp, &syncEvents.pending, next) {
|
||||||
{
|
|
||||||
if (!qe->device->deviceGrab.sync.frozen)
|
if (!qe->device->deviceGrab.sync.frozen)
|
||||||
{
|
{
|
||||||
*prev = qe->next;
|
list_del(&qe->next);
|
||||||
pDev = qe->device;
|
pDev = qe->device;
|
||||||
if (*syncEvents.pendtail == *prev)
|
|
||||||
syncEvents.pendtail = prev;
|
|
||||||
if (qe->event->any.type == ET_Motion)
|
if (qe->event->any.type == ET_Motion)
|
||||||
CheckVirtualMotion(pDev, qe, NullWindow);
|
CheckVirtualMotion(pDev, qe, NullWindow);
|
||||||
syncEvents.time.months = qe->months;
|
syncEvents.time.months = qe->months;
|
||||||
|
@ -1268,12 +1261,11 @@ PlayReleasedEvents(void)
|
||||||
;
|
;
|
||||||
if (!dev)
|
if (!dev)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
/* Playing the event may have unfrozen another device. */
|
/* Playing the event may have unfrozen another device. */
|
||||||
/* So to play it safe, restart at the head of the queue */
|
/* So to play it safe, restart at the head of the queue */
|
||||||
prev = &syncEvents.pending;
|
goto restart;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
prev = &qe->next;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1314,7 +1306,8 @@ ComputeFreezes(void)
|
||||||
for (dev = inputInfo.devices; dev; dev = dev->next)
|
for (dev = inputInfo.devices; dev; dev = dev->next)
|
||||||
FreezeThaw(dev, dev->deviceGrab.sync.other ||
|
FreezeThaw(dev, dev->deviceGrab.sync.other ||
|
||||||
(dev->deviceGrab.sync.state >= FROZEN));
|
(dev->deviceGrab.sync.state >= FROZEN));
|
||||||
if (syncEvents.playingEvents || (!replayDev && !syncEvents.pending))
|
if (syncEvents.playingEvents ||
|
||||||
|
(!replayDev && list_is_empty(&syncEvents.pending)))
|
||||||
return;
|
return;
|
||||||
syncEvents.playingEvents = TRUE;
|
syncEvents.playingEvents = TRUE;
|
||||||
if (replayDev)
|
if (replayDev)
|
||||||
|
@ -1511,8 +1504,8 @@ ActivatePointerGrab(DeviceIntPtr mouse, GrabPtr grab,
|
||||||
grabinfo->grabTime = time;
|
grabinfo->grabTime = time;
|
||||||
if (grab->cursor)
|
if (grab->cursor)
|
||||||
grab->cursor->refcnt++;
|
grab->cursor->refcnt++;
|
||||||
grabinfo->activeGrab = *grab;
|
CopyGrab(grabinfo->activeGrab, grab);
|
||||||
grabinfo->grab = &grabinfo->activeGrab;
|
grabinfo->grab = grabinfo->activeGrab;
|
||||||
grabinfo->fromPassiveGrab = isPassive;
|
grabinfo->fromPassiveGrab = isPassive;
|
||||||
grabinfo->implicitGrab = autoGrab & ImplicitGrabMask;
|
grabinfo->implicitGrab = autoGrab & ImplicitGrabMask;
|
||||||
PostNewCursor(mouse);
|
PostNewCursor(mouse);
|
||||||
|
@ -1588,8 +1581,8 @@ ActivateKeyboardGrab(DeviceIntPtr keybd, GrabPtr grab, TimeStamp time, Bool pass
|
||||||
grabinfo->grabTime = syncEvents.time;
|
grabinfo->grabTime = syncEvents.time;
|
||||||
else
|
else
|
||||||
grabinfo->grabTime = time;
|
grabinfo->grabTime = time;
|
||||||
grabinfo->activeGrab = *grab;
|
CopyGrab(grabinfo->activeGrab, grab);
|
||||||
grabinfo->grab = &grabinfo->activeGrab;
|
grabinfo->grab = grabinfo->activeGrab;
|
||||||
grabinfo->fromPassiveGrab = passive;
|
grabinfo->fromPassiveGrab = passive;
|
||||||
grabinfo->implicitGrab = passive & ImplicitGrabMask;
|
grabinfo->implicitGrab = passive & ImplicitGrabMask;
|
||||||
CheckGrabForSyncs(keybd, (Bool)grab->keyboardMode, (Bool)grab->pointerMode);
|
CheckGrabForSyncs(keybd, (Bool)grab->keyboardMode, (Bool)grab->pointerMode);
|
||||||
|
@ -1978,7 +1971,7 @@ static BOOL
|
||||||
ActivateImplicitGrab(DeviceIntPtr dev, ClientPtr client, WindowPtr win,
|
ActivateImplicitGrab(DeviceIntPtr dev, ClientPtr client, WindowPtr win,
|
||||||
xEvent *event, Mask deliveryMask)
|
xEvent *event, Mask deliveryMask)
|
||||||
{
|
{
|
||||||
GrabRec tempGrab;
|
GrabPtr tempGrab;
|
||||||
OtherInputMasks *inputMasks;
|
OtherInputMasks *inputMasks;
|
||||||
CARD8 type = event->u.u.type;
|
CARD8 type = event->u.u.type;
|
||||||
GrabType grabtype;
|
GrabType grabtype;
|
||||||
|
@ -1992,30 +1985,32 @@ ActivateImplicitGrab(DeviceIntPtr dev, ClientPtr client, WindowPtr win,
|
||||||
else
|
else
|
||||||
return FALSE;
|
return FALSE;
|
||||||
|
|
||||||
memset(&tempGrab, 0, sizeof(GrabRec));
|
tempGrab = AllocGrab();
|
||||||
tempGrab.next = NULL;
|
if (!tempGrab)
|
||||||
tempGrab.device = dev;
|
return FALSE;
|
||||||
tempGrab.resource = client->clientAsMask;
|
tempGrab->next = NULL;
|
||||||
tempGrab.window = win;
|
tempGrab->device = dev;
|
||||||
tempGrab.ownerEvents = (deliveryMask & OwnerGrabButtonMask) ? TRUE : FALSE;
|
tempGrab->resource = client->clientAsMask;
|
||||||
tempGrab.eventMask = deliveryMask;
|
tempGrab->window = win;
|
||||||
tempGrab.keyboardMode = GrabModeAsync;
|
tempGrab->ownerEvents = (deliveryMask & OwnerGrabButtonMask) ? TRUE : FALSE;
|
||||||
tempGrab.pointerMode = GrabModeAsync;
|
tempGrab->eventMask = deliveryMask;
|
||||||
tempGrab.confineTo = NullWindow;
|
tempGrab->keyboardMode = GrabModeAsync;
|
||||||
tempGrab.cursor = NullCursor;
|
tempGrab->pointerMode = GrabModeAsync;
|
||||||
tempGrab.type = type;
|
tempGrab->confineTo = NullWindow;
|
||||||
tempGrab.grabtype = grabtype;
|
tempGrab->cursor = NullCursor;
|
||||||
|
tempGrab->type = type;
|
||||||
|
tempGrab->grabtype = grabtype;
|
||||||
|
|
||||||
/* get the XI and XI2 device mask */
|
/* get the XI and XI2 device mask */
|
||||||
inputMasks = wOtherInputMasks(win);
|
inputMasks = wOtherInputMasks(win);
|
||||||
tempGrab.deviceMask = (inputMasks) ? inputMasks->inputEvents[dev->id]: 0;
|
tempGrab->deviceMask = (inputMasks) ? inputMasks->inputEvents[dev->id]: 0;
|
||||||
|
|
||||||
if (inputMasks)
|
if (inputMasks)
|
||||||
memcpy(tempGrab.xi2mask, inputMasks->xi2mask,
|
xi2mask_merge(tempGrab->xi2mask, inputMasks->xi2mask);
|
||||||
sizeof(tempGrab.xi2mask));
|
|
||||||
|
|
||||||
(*dev->deviceGrab.ActivateGrab)(dev, &tempGrab,
|
(*dev->deviceGrab.ActivateGrab)(dev, tempGrab,
|
||||||
currentTime, TRUE | ImplicitGrabMask);
|
currentTime, TRUE | ImplicitGrabMask);
|
||||||
|
FreeGrab(tempGrab);
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2560,10 +2555,7 @@ EventIsDeliverable(DeviceIntPtr dev, InternalEvent* event, WindowPtr win)
|
||||||
|
|
||||||
if ((type = GetXI2Type(event)) != 0)
|
if ((type = GetXI2Type(event)) != 0)
|
||||||
{
|
{
|
||||||
filter = GetXI2EventFilterMask(type);
|
if (inputMasks && xi2mask_isset(inputMasks->xi2mask, dev, type))
|
||||||
|
|
||||||
if (inputMasks &&
|
|
||||||
(GetXI2MaskByte(inputMasks->xi2mask, dev, type) & filter))
|
|
||||||
rc |= EVENT_XI2_MASK;
|
rc |= EVENT_XI2_MASK;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3659,7 +3651,7 @@ CheckPassiveGrabsOnWindow(
|
||||||
{
|
{
|
||||||
SpritePtr pSprite = device->spriteInfo->sprite;
|
SpritePtr pSprite = device->spriteInfo->sprite;
|
||||||
GrabPtr grab = wPassiveGrabs(pWin);
|
GrabPtr grab = wPassiveGrabs(pWin);
|
||||||
GrabRec tempGrab;
|
GrabPtr tempGrab;
|
||||||
GrabInfoPtr grabinfo;
|
GrabInfoPtr grabinfo;
|
||||||
#define CORE_MATCH 0x1
|
#define CORE_MATCH 0x1
|
||||||
#define XI_MATCH 0x2
|
#define XI_MATCH 0x2
|
||||||
|
@ -3668,27 +3660,30 @@ CheckPassiveGrabsOnWindow(
|
||||||
|
|
||||||
if (!grab)
|
if (!grab)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
tempGrab = AllocGrab();
|
||||||
|
|
||||||
/* Fill out the grab details, but leave the type for later before
|
/* Fill out the grab details, but leave the type for later before
|
||||||
* comparing */
|
* comparing */
|
||||||
switch (event->any.type)
|
switch (event->any.type)
|
||||||
{
|
{
|
||||||
case ET_KeyPress:
|
case ET_KeyPress:
|
||||||
case ET_KeyRelease:
|
case ET_KeyRelease:
|
||||||
tempGrab.detail.exact = event->device_event.detail.key;
|
tempGrab->detail.exact = event->device_event.detail.key;
|
||||||
break;
|
break;
|
||||||
case ET_ButtonPress:
|
case ET_ButtonPress:
|
||||||
case ET_ButtonRelease:
|
case ET_ButtonRelease:
|
||||||
tempGrab.detail.exact = event->device_event.detail.button;
|
tempGrab->detail.exact = event->device_event.detail.button;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
tempGrab.detail.exact = 0;
|
tempGrab->detail.exact = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
tempGrab.window = pWin;
|
tempGrab->window = pWin;
|
||||||
tempGrab.device = device;
|
tempGrab->device = device;
|
||||||
tempGrab.detail.pMask = NULL;
|
tempGrab->detail.pMask = NULL;
|
||||||
tempGrab.modifiersDetail.pMask = NULL;
|
tempGrab->modifiersDetail.pMask = NULL;
|
||||||
tempGrab.next = NULL;
|
tempGrab->next = NULL;
|
||||||
for (; grab; grab = grab->next)
|
for (; grab; grab = grab->next)
|
||||||
{
|
{
|
||||||
DeviceIntPtr gdev;
|
DeviceIntPtr gdev;
|
||||||
|
@ -3713,29 +3708,29 @@ CheckPassiveGrabsOnWindow(
|
||||||
|
|
||||||
if (gdev && gdev->key)
|
if (gdev && gdev->key)
|
||||||
xkbi= gdev->key->xkbInfo;
|
xkbi= gdev->key->xkbInfo;
|
||||||
tempGrab.modifierDevice = grab->modifierDevice;
|
tempGrab->modifierDevice = grab->modifierDevice;
|
||||||
tempGrab.modifiersDetail.exact = xkbi ? xkbi->state.grab_mods : 0;
|
tempGrab->modifiersDetail.exact = xkbi ? xkbi->state.grab_mods : 0;
|
||||||
|
|
||||||
/* Check for XI2 and XI grabs first */
|
/* Check for XI2 and XI grabs first */
|
||||||
tempGrab.type = GetXI2Type(event);
|
tempGrab->type = GetXI2Type(event);
|
||||||
tempGrab.grabtype = GRABTYPE_XI2;
|
tempGrab->grabtype = GRABTYPE_XI2;
|
||||||
if (GrabMatchesSecond(&tempGrab, grab, FALSE))
|
if (GrabMatchesSecond(tempGrab, grab, FALSE))
|
||||||
match = XI2_MATCH;
|
match = XI2_MATCH;
|
||||||
|
|
||||||
if (!match)
|
if (!match)
|
||||||
{
|
{
|
||||||
tempGrab.grabtype = GRABTYPE_XI;
|
tempGrab->grabtype = GRABTYPE_XI;
|
||||||
if ((tempGrab.type = GetXIType(event)) &&
|
if ((tempGrab->type = GetXIType(event)) &&
|
||||||
(GrabMatchesSecond(&tempGrab, grab, FALSE)))
|
(GrabMatchesSecond(tempGrab, grab, FALSE)))
|
||||||
match = XI_MATCH;
|
match = XI_MATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Check for a core grab (ignore the device when comparing) */
|
/* Check for a core grab (ignore the device when comparing) */
|
||||||
if (!match && checkCore)
|
if (!match && checkCore)
|
||||||
{
|
{
|
||||||
tempGrab.grabtype = GRABTYPE_CORE;
|
tempGrab->grabtype = GRABTYPE_CORE;
|
||||||
if ((tempGrab.type = GetCoreType(event)) &&
|
if ((tempGrab->type = GetCoreType(event)) &&
|
||||||
(GrabMatchesSecond(&tempGrab, grab, TRUE)))
|
(GrabMatchesSecond(tempGrab, grab, TRUE)))
|
||||||
match = CORE_MATCH;
|
match = CORE_MATCH;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3763,7 +3758,7 @@ CheckPassiveGrabsOnWindow(
|
||||||
Since XGrabDeviceButton requires to specify the
|
Since XGrabDeviceButton requires to specify the
|
||||||
modifierDevice explicitly, we don't override this choice.
|
modifierDevice explicitly, we don't override this choice.
|
||||||
*/
|
*/
|
||||||
if (tempGrab.type < GenericEvent)
|
if (tempGrab->type < GenericEvent)
|
||||||
{
|
{
|
||||||
grab->device = device;
|
grab->device = device;
|
||||||
grab->modifierDevice = GetMaster(device, MASTER_KEYBOARD);
|
grab->modifierDevice = GetMaster(device, MASTER_KEYBOARD);
|
||||||
|
@ -3802,7 +3797,7 @@ CheckPassiveGrabsOnWindow(
|
||||||
if (match & (XI_MATCH | CORE_MATCH))
|
if (match & (XI_MATCH | CORE_MATCH))
|
||||||
{
|
{
|
||||||
event->device_event.corestate &= 0x1f00;
|
event->device_event.corestate &= 0x1f00;
|
||||||
event->device_event.corestate |= tempGrab.modifiersDetail.exact &
|
event->device_event.corestate |= tempGrab->modifiersDetail.exact &
|
||||||
(~0x1f00);
|
(~0x1f00);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3863,6 +3858,7 @@ CheckPassiveGrabsOnWindow(
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
FreeGrab(tempGrab);
|
||||||
return grab;
|
return grab;
|
||||||
#undef CORE_MATCH
|
#undef CORE_MATCH
|
||||||
#undef XI_MATCH
|
#undef XI_MATCH
|
||||||
|
@ -4150,12 +4146,11 @@ DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev,
|
||||||
if (rc == Success)
|
if (rc == Success)
|
||||||
{
|
{
|
||||||
int evtype = xi2_get_type(xi2);
|
int evtype = xi2_get_type(xi2);
|
||||||
mask = GetXI2MaskByte(grab->xi2mask, thisDev, evtype);
|
mask = xi2mask_isset(grab->xi2mask, thisDev, evtype);
|
||||||
/* try XI2 event */
|
/* try XI2 event */
|
||||||
FixUpEventFromWindow(pSprite, xi2, grab->window, None, TRUE);
|
FixUpEventFromWindow(pSprite, xi2, grab->window, None, TRUE);
|
||||||
/* XXX: XACE */
|
/* XXX: XACE */
|
||||||
deliveries = TryClientEvents(rClient(grab), thisDev, xi2, 1, mask,
|
deliveries = TryClientEvents(rClient(grab), thisDev, xi2, 1, mask, 1, grab);
|
||||||
GetEventFilter(thisDev, xi2), grab);
|
|
||||||
} else if (rc != BadMatch)
|
} else if (rc != BadMatch)
|
||||||
ErrorF("[dix] %s: XI2 conversion failed in DGE (%d, %d). Skipping delivery.\n",
|
ErrorF("[dix] %s: XI2 conversion failed in DGE (%d, %d). Skipping delivery.\n",
|
||||||
thisDev->name, event->any.type, rc);
|
thisDev->name, event->any.type, rc);
|
||||||
|
@ -4629,9 +4624,8 @@ DeviceEnterLeaveEvent(
|
||||||
if (grab)
|
if (grab)
|
||||||
{
|
{
|
||||||
Mask mask;
|
Mask mask;
|
||||||
mask = GetXI2MaskByte(grab->xi2mask, mouse, type);
|
mask = xi2mask_isset(grab->xi2mask, mouse, type);
|
||||||
TryClientEvents(rClient(grab), mouse, (xEvent*)event, 1, mask,
|
TryClientEvents(rClient(grab), mouse, (xEvent*)event, 1, mask, 1, grab);
|
||||||
filter, grab);
|
|
||||||
} else {
|
} else {
|
||||||
if (!WindowXI2MaskIsset(mouse, pWin, (xEvent*)event))
|
if (!WindowXI2MaskIsset(mouse, pWin, (xEvent*)event))
|
||||||
goto out;
|
goto out;
|
||||||
|
@ -5080,29 +5074,30 @@ GrabDevice(ClientPtr client, DeviceIntPtr dev,
|
||||||
*status = GrabFrozen;
|
*status = GrabFrozen;
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GrabRec tempGrab;
|
GrabPtr tempGrab;
|
||||||
|
|
||||||
/* Otherwise segfaults happen on grabbed MPX devices */
|
tempGrab = AllocGrab();
|
||||||
memset(&tempGrab, 0, sizeof(GrabRec));
|
|
||||||
|
|
||||||
tempGrab.next = NULL;
|
tempGrab->next = NULL;
|
||||||
tempGrab.window = pWin;
|
tempGrab->window = pWin;
|
||||||
tempGrab.resource = client->clientAsMask;
|
tempGrab->resource = client->clientAsMask;
|
||||||
tempGrab.ownerEvents = ownerEvents;
|
tempGrab->ownerEvents = ownerEvents;
|
||||||
tempGrab.keyboardMode = keyboard_mode;
|
tempGrab->keyboardMode = keyboard_mode;
|
||||||
tempGrab.pointerMode = pointer_mode;
|
tempGrab->pointerMode = pointer_mode;
|
||||||
if (grabtype == GRABTYPE_CORE)
|
if (grabtype == GRABTYPE_CORE)
|
||||||
tempGrab.eventMask = mask->core;
|
tempGrab->eventMask = mask->core;
|
||||||
else if (grabtype == GRABTYPE_XI)
|
else if (grabtype == GRABTYPE_XI)
|
||||||
tempGrab.eventMask = mask->xi;
|
tempGrab->eventMask = mask->xi;
|
||||||
else
|
else
|
||||||
memcpy(tempGrab.xi2mask, mask->xi2mask, sizeof(tempGrab.xi2mask));
|
xi2mask_merge(tempGrab->xi2mask, mask->xi2mask);
|
||||||
tempGrab.device = dev;
|
tempGrab->device = dev;
|
||||||
tempGrab.cursor = cursor;
|
tempGrab->cursor = cursor;
|
||||||
tempGrab.confineTo = confineTo;
|
tempGrab->confineTo = confineTo;
|
||||||
tempGrab.grabtype = grabtype;
|
tempGrab->grabtype = grabtype;
|
||||||
(*grabInfo->ActivateGrab)(dev, &tempGrab, time, FALSE);
|
(*grabInfo->ActivateGrab)(dev, tempGrab, time, FALSE);
|
||||||
*status = GrabSuccess;
|
*status = GrabSuccess;
|
||||||
|
|
||||||
|
FreeGrab(tempGrab);
|
||||||
}
|
}
|
||||||
return Success;
|
return Success;
|
||||||
}
|
}
|
||||||
|
@ -5258,6 +5253,7 @@ void
|
||||||
InitEvents(void)
|
InitEvents(void)
|
||||||
{
|
{
|
||||||
int i;
|
int i;
|
||||||
|
QdEventPtr qe, tmp;
|
||||||
|
|
||||||
inputInfo.numDevices = 0;
|
inputInfo.numDevices = 0;
|
||||||
inputInfo.devices = (DeviceIntPtr)NULL;
|
inputInfo.devices = (DeviceIntPtr)NULL;
|
||||||
|
@ -5271,13 +5267,10 @@ InitEvents(void)
|
||||||
|
|
||||||
syncEvents.replayDev = (DeviceIntPtr)NULL;
|
syncEvents.replayDev = (DeviceIntPtr)NULL;
|
||||||
syncEvents.replayWin = NullWindow;
|
syncEvents.replayWin = NullWindow;
|
||||||
while (syncEvents.pending)
|
if (syncEvents.pending.next)
|
||||||
{
|
list_for_each_entry_safe(qe, tmp, &syncEvents.pending, next)
|
||||||
QdEventPtr next = syncEvents.pending->next;
|
free(qe);
|
||||||
free(syncEvents.pending);
|
list_init(&syncEvents.pending);
|
||||||
syncEvents.pending = next;
|
|
||||||
}
|
|
||||||
syncEvents.pendtail = &syncEvents.pending;
|
|
||||||
syncEvents.playingEvents = FALSE;
|
syncEvents.playingEvents = FALSE;
|
||||||
syncEvents.time.months = 0;
|
syncEvents.time.months = 0;
|
||||||
syncEvents.time.milliseconds = 0; /* hardly matters */
|
syncEvents.time.milliseconds = 0; /* hardly matters */
|
||||||
|
@ -5423,7 +5416,7 @@ ProcUngrabKey(ClientPtr client)
|
||||||
{
|
{
|
||||||
REQUEST(xUngrabKeyReq);
|
REQUEST(xUngrabKeyReq);
|
||||||
WindowPtr pWin;
|
WindowPtr pWin;
|
||||||
GrabRec tempGrab;
|
GrabPtr tempGrab;
|
||||||
DeviceIntPtr keybd = PickKeyboard(client);
|
DeviceIntPtr keybd = PickKeyboard(client);
|
||||||
int rc;
|
int rc;
|
||||||
|
|
||||||
|
@ -5445,21 +5438,27 @@ ProcUngrabKey(ClientPtr client)
|
||||||
client->errorValue = stuff->modifiers;
|
client->errorValue = stuff->modifiers;
|
||||||
return BadValue;
|
return BadValue;
|
||||||
}
|
}
|
||||||
tempGrab.resource = client->clientAsMask;
|
tempGrab = AllocGrab();
|
||||||
tempGrab.device = keybd;
|
if (!tempGrab)
|
||||||
tempGrab.window = pWin;
|
return BadAlloc;
|
||||||
tempGrab.modifiersDetail.exact = stuff->modifiers;
|
tempGrab->resource = client->clientAsMask;
|
||||||
tempGrab.modifiersDetail.pMask = NULL;
|
tempGrab->device = keybd;
|
||||||
tempGrab.modifierDevice = keybd;
|
tempGrab->window = pWin;
|
||||||
tempGrab.type = KeyPress;
|
tempGrab->modifiersDetail.exact = stuff->modifiers;
|
||||||
tempGrab.grabtype = GRABTYPE_CORE;
|
tempGrab->modifiersDetail.pMask = NULL;
|
||||||
tempGrab.detail.exact = stuff->key;
|
tempGrab->modifierDevice = keybd;
|
||||||
tempGrab.detail.pMask = NULL;
|
tempGrab->type = KeyPress;
|
||||||
tempGrab.next = NULL;
|
tempGrab->grabtype = GRABTYPE_CORE;
|
||||||
|
tempGrab->detail.exact = stuff->key;
|
||||||
|
tempGrab->detail.pMask = NULL;
|
||||||
|
tempGrab->next = NULL;
|
||||||
|
|
||||||
if (!DeletePassiveGrabFromList(&tempGrab))
|
if (!DeletePassiveGrabFromList(tempGrab))
|
||||||
return BadAlloc;
|
rc = BadAlloc;
|
||||||
return Success;
|
|
||||||
|
FreeGrab(tempGrab);
|
||||||
|
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -5623,7 +5622,7 @@ ProcUngrabButton(ClientPtr client)
|
||||||
{
|
{
|
||||||
REQUEST(xUngrabButtonReq);
|
REQUEST(xUngrabButtonReq);
|
||||||
WindowPtr pWin;
|
WindowPtr pWin;
|
||||||
GrabRec tempGrab;
|
GrabPtr tempGrab;
|
||||||
int rc;
|
int rc;
|
||||||
DeviceIntPtr ptr;
|
DeviceIntPtr ptr;
|
||||||
|
|
||||||
|
@ -5640,21 +5639,26 @@ ProcUngrabButton(ClientPtr client)
|
||||||
|
|
||||||
ptr = PickPointer(client);
|
ptr = PickPointer(client);
|
||||||
|
|
||||||
tempGrab.resource = client->clientAsMask;
|
tempGrab = AllocGrab();
|
||||||
tempGrab.device = ptr;
|
if (!tempGrab)
|
||||||
tempGrab.window = pWin;
|
return BadAlloc;
|
||||||
tempGrab.modifiersDetail.exact = stuff->modifiers;
|
tempGrab->resource = client->clientAsMask;
|
||||||
tempGrab.modifiersDetail.pMask = NULL;
|
tempGrab->device = ptr;
|
||||||
tempGrab.modifierDevice = GetMaster(ptr, MASTER_KEYBOARD);
|
tempGrab->window = pWin;
|
||||||
tempGrab.type = ButtonPress;
|
tempGrab->modifiersDetail.exact = stuff->modifiers;
|
||||||
tempGrab.detail.exact = stuff->button;
|
tempGrab->modifiersDetail.pMask = NULL;
|
||||||
tempGrab.grabtype = GRABTYPE_CORE;
|
tempGrab->modifierDevice = GetMaster(ptr, MASTER_KEYBOARD);
|
||||||
tempGrab.detail.pMask = NULL;
|
tempGrab->type = ButtonPress;
|
||||||
tempGrab.next = NULL;
|
tempGrab->detail.exact = stuff->button;
|
||||||
|
tempGrab->grabtype = GRABTYPE_CORE;
|
||||||
|
tempGrab->detail.pMask = NULL;
|
||||||
|
tempGrab->next = NULL;
|
||||||
|
|
||||||
if (!DeletePassiveGrabFromList(&tempGrab))
|
if (!DeletePassiveGrabFromList(tempGrab))
|
||||||
return BadAlloc;
|
rc = BadAlloc;
|
||||||
return Success;
|
|
||||||
|
FreeGrab(tempGrab);
|
||||||
|
return rc;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
84
dix/grabs.c
84
dix/grabs.c
|
@ -60,6 +60,7 @@ SOFTWARE.
|
||||||
#include "dixgrabs.h"
|
#include "dixgrabs.h"
|
||||||
#include "xace.h"
|
#include "xace.h"
|
||||||
#include "exevents.h"
|
#include "exevents.h"
|
||||||
|
#include "inpututils.h"
|
||||||
|
|
||||||
#define BITMASK(i) (((Mask)1) << ((i) & 31))
|
#define BITMASK(i) (((Mask)1) << ((i) & 31))
|
||||||
#define MASKIDX(i) ((i) >> 5)
|
#define MASKIDX(i) ((i) >> 5)
|
||||||
|
@ -122,13 +123,15 @@ PrintDeviceGrabInfo(DeviceIntPtr dev)
|
||||||
}
|
}
|
||||||
else if (grab->grabtype == GRABTYPE_XI2)
|
else if (grab->grabtype == GRABTYPE_XI2)
|
||||||
{
|
{
|
||||||
for (i = 0; i < EMASKSIZE; i++)
|
for (i = 0; i < xi2mask_num_masks(grab->xi2mask); i++)
|
||||||
{
|
{
|
||||||
|
const unsigned char *mask;
|
||||||
int print;
|
int print;
|
||||||
print = 0;
|
print = 0;
|
||||||
for (j = 0; j < XI2MASKSIZE; j++)
|
for (j = 0; j < XI2MASKSIZE; j++)
|
||||||
{
|
{
|
||||||
if (grab->xi2mask[i][j])
|
mask = xi2mask_get_one_mask(grab->xi2mask, i);
|
||||||
|
if (mask[j])
|
||||||
{
|
{
|
||||||
print = 1;
|
print = 1;
|
||||||
break;
|
break;
|
||||||
|
@ -137,8 +140,8 @@ PrintDeviceGrabInfo(DeviceIntPtr dev)
|
||||||
if (!print)
|
if (!print)
|
||||||
continue;
|
continue;
|
||||||
ErrorF(" xi2 event mask for device %d: 0x", dev->id);
|
ErrorF(" xi2 event mask for device %d: 0x", dev->id);
|
||||||
for (j = 0; j < XI2MASKSIZE; j++)
|
for (j = 0; j < xi2mask_mask_size(grab->xi2mask); j++)
|
||||||
ErrorF("%x", grab->xi2mask[i][j]);
|
ErrorF("%x", mask[j]);
|
||||||
ErrorF("\n");
|
ErrorF("\n");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -180,6 +183,22 @@ UngrabAllDevices(Bool kill_client)
|
||||||
ErrorF("End list of ungrabbed devices\n");
|
ErrorF("End list of ungrabbed devices\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
GrabPtr
|
||||||
|
AllocGrab(void)
|
||||||
|
{
|
||||||
|
GrabPtr grab = calloc(1, sizeof(GrabRec));
|
||||||
|
|
||||||
|
if (grab) {
|
||||||
|
grab->xi2mask = xi2mask_new();
|
||||||
|
if (!grab->xi2mask) {
|
||||||
|
free(grab);
|
||||||
|
grab = NULL;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return grab;
|
||||||
|
}
|
||||||
|
|
||||||
GrabPtr
|
GrabPtr
|
||||||
CreateGrab(
|
CreateGrab(
|
||||||
int client,
|
int client,
|
||||||
|
@ -196,7 +215,7 @@ CreateGrab(
|
||||||
{
|
{
|
||||||
GrabPtr grab;
|
GrabPtr grab;
|
||||||
|
|
||||||
grab = calloc(1, sizeof(GrabRec));
|
grab = AllocGrab();
|
||||||
if (!grab)
|
if (!grab)
|
||||||
return (GrabPtr)NULL;
|
return (GrabPtr)NULL;
|
||||||
grab->resource = FakeClientID(client);
|
grab->resource = FakeClientID(client);
|
||||||
|
@ -219,14 +238,14 @@ CreateGrab(
|
||||||
grab->next = NULL;
|
grab->next = NULL;
|
||||||
|
|
||||||
if (grabtype == GRABTYPE_XI2)
|
if (grabtype == GRABTYPE_XI2)
|
||||||
memcpy(grab->xi2mask, mask->xi2mask, sizeof(mask->xi2mask));
|
xi2mask_merge(grab->xi2mask, mask->xi2mask);
|
||||||
if (cursor)
|
if (cursor)
|
||||||
cursor->refcnt++;
|
cursor->refcnt++;
|
||||||
return grab;
|
return grab;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
void
|
||||||
FreeGrab(GrabPtr pGrab)
|
FreeGrab(GrabPtr pGrab)
|
||||||
{
|
{
|
||||||
free(pGrab->modifiersDetail.pMask);
|
free(pGrab->modifiersDetail.pMask);
|
||||||
|
@ -235,9 +254,60 @@ FreeGrab(GrabPtr pGrab)
|
||||||
if (pGrab->cursor)
|
if (pGrab->cursor)
|
||||||
FreeCursor(pGrab->cursor, (Cursor)0);
|
FreeCursor(pGrab->cursor, (Cursor)0);
|
||||||
|
|
||||||
|
xi2mask_free(&pGrab->xi2mask);
|
||||||
free(pGrab);
|
free(pGrab);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Bool
|
||||||
|
CopyGrab(GrabPtr dst, const GrabPtr src)
|
||||||
|
{
|
||||||
|
Mask *mdetails_mask = NULL;
|
||||||
|
Mask *details_mask = NULL;
|
||||||
|
XI2Mask *xi2mask;
|
||||||
|
|
||||||
|
if (src->cursor)
|
||||||
|
src->cursor->refcnt++;
|
||||||
|
|
||||||
|
if (src->modifiersDetail.pMask) {
|
||||||
|
int len = MasksPerDetailMask * sizeof(Mask);
|
||||||
|
mdetails_mask = malloc(len);
|
||||||
|
if (!mdetails_mask)
|
||||||
|
return FALSE;
|
||||||
|
memcpy(mdetails_mask, src->modifiersDetail.pMask, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (src->detail.pMask) {
|
||||||
|
int len = MasksPerDetailMask * sizeof(Mask);
|
||||||
|
details_mask = malloc(len);
|
||||||
|
if (!details_mask) {
|
||||||
|
free(mdetails_mask);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
memcpy(details_mask, src->detail.pMask, len);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dst->xi2mask) {
|
||||||
|
xi2mask = xi2mask_new();
|
||||||
|
if (!xi2mask) {
|
||||||
|
free(mdetails_mask);
|
||||||
|
free(details_mask);
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
xi2mask = dst->xi2mask;
|
||||||
|
xi2mask_zero(xi2mask, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
*dst = *src;
|
||||||
|
dst->modifiersDetail.pMask = mdetails_mask;
|
||||||
|
dst->detail.pMask = details_mask;
|
||||||
|
dst->xi2mask = xi2mask;
|
||||||
|
|
||||||
|
xi2mask_merge(dst->xi2mask, src->xi2mask);
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
int
|
int
|
||||||
DeletePassiveGrab(pointer value, XID id)
|
DeletePassiveGrab(pointer value, XID id)
|
||||||
{
|
{
|
||||||
|
|
181
dix/inpututils.c
181
dix/inpututils.c
|
@ -892,3 +892,184 @@ double_to_fp3232(double in)
|
||||||
ret.frac = frac_d;
|
ret.frac = frac_d;
|
||||||
return ret;
|
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];
|
||||||
|
}
|
||||||
|
|
|
@ -83,7 +83,7 @@ typedef enum {
|
||||||
*/
|
*/
|
||||||
#define ABI_ANSIC_VERSION SET_ABI_VERSION(0, 4)
|
#define ABI_ANSIC_VERSION SET_ABI_VERSION(0, 4)
|
||||||
#define ABI_VIDEODRV_VERSION SET_ABI_VERSION(12, 0)
|
#define ABI_VIDEODRV_VERSION SET_ABI_VERSION(12, 0)
|
||||||
#define ABI_XINPUT_VERSION SET_ABI_VERSION(14, 0)
|
#define ABI_XINPUT_VERSION SET_ABI_VERSION(15, 0)
|
||||||
#define ABI_EXTENSION_VERSION SET_ABI_VERSION(6, 0)
|
#define ABI_EXTENSION_VERSION SET_ABI_VERSION(6, 0)
|
||||||
#define ABI_FONT_VERSION SET_ABI_VERSION(0, 6)
|
#define ABI_FONT_VERSION SET_ABI_VERSION(0, 6)
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,10 @@
|
||||||
#ifndef _XAALOCAL_H
|
#ifndef _XAALOCAL_H
|
||||||
#define _XAALOCAL_H
|
#define _XAALOCAL_H
|
||||||
|
|
||||||
|
#ifdef HAVE_XORG_CONFIG_H
|
||||||
|
#include <xorg-config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
/* This file is very unorganized ! */
|
/* This file is very unorganized ! */
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -339,6 +339,7 @@ extern _X_EXPORT void NoticeEventTime(InternalEvent *ev);
|
||||||
extern void EnqueueEvent(
|
extern void EnqueueEvent(
|
||||||
InternalEvent * /* ev */,
|
InternalEvent * /* ev */,
|
||||||
DeviceIntPtr /* device */);
|
DeviceIntPtr /* device */);
|
||||||
|
extern void PlayReleasedEvents(void);
|
||||||
|
|
||||||
extern void ActivatePointerGrab(
|
extern void ActivatePointerGrab(
|
||||||
DeviceIntPtr /* mouse */,
|
DeviceIntPtr /* mouse */,
|
||||||
|
|
|
@ -31,6 +31,10 @@ struct _GrabParameters;
|
||||||
extern void PrintDeviceGrabInfo(DeviceIntPtr dev);
|
extern void PrintDeviceGrabInfo(DeviceIntPtr dev);
|
||||||
extern void UngrabAllDevices(Bool kill_client);
|
extern void UngrabAllDevices(Bool kill_client);
|
||||||
|
|
||||||
|
extern GrabPtr AllocGrab(void);
|
||||||
|
extern void FreeGrab(GrabPtr grab);
|
||||||
|
extern Bool CopyGrab(GrabPtr dst, const GrabPtr src);
|
||||||
|
|
||||||
extern GrabPtr CreateGrab(
|
extern GrabPtr CreateGrab(
|
||||||
int /* client */,
|
int /* client */,
|
||||||
DeviceIntPtr /* device */,
|
DeviceIntPtr /* device */,
|
||||||
|
|
|
@ -205,6 +205,7 @@ extern _X_EXPORT KeybdCtrl defaultKeyboardControl;
|
||||||
extern _X_EXPORT PtrCtrl defaultPointerControl;
|
extern _X_EXPORT PtrCtrl defaultPointerControl;
|
||||||
|
|
||||||
typedef struct _InputOption InputOption;
|
typedef struct _InputOption InputOption;
|
||||||
|
typedef struct _XI2Mask XI2Mask;
|
||||||
|
|
||||||
typedef struct _InputAttributes {
|
typedef struct _InputAttributes {
|
||||||
char *product;
|
char *product;
|
||||||
|
|
|
@ -118,7 +118,7 @@ typedef struct _InputClients {
|
||||||
XID resource; /**< id for putting into resource manager */
|
XID resource; /**< id for putting into resource manager */
|
||||||
Mask mask[EMASKSIZE]; /**< Actual XI event mask, deviceid is index */
|
Mask mask[EMASKSIZE]; /**< Actual XI event mask, deviceid is index */
|
||||||
/** XI2 event masks. One per device, each bit is a mask of (1 << type) */
|
/** XI2 event masks. One per device, each bit is a mask of (1 << type) */
|
||||||
unsigned char xi2mask[EMASKSIZE][XI2MASKSIZE];
|
struct _XI2Mask *xi2mask;
|
||||||
} InputClients;
|
} InputClients;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -148,7 +148,7 @@ typedef struct _OtherInputMasks {
|
||||||
/** The clients that selected for events */
|
/** The clients that selected for events */
|
||||||
InputClientsPtr inputClients;
|
InputClientsPtr inputClients;
|
||||||
/* XI2 event masks. One per device, each bit is a mask of (1 << type) */
|
/* XI2 event masks. One per device, each bit is a mask of (1 << type) */
|
||||||
unsigned char xi2mask[EMASKSIZE][XI2MASKSIZE];
|
struct _XI2Mask *xi2mask;
|
||||||
} OtherInputMasks;
|
} OtherInputMasks;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -176,7 +176,7 @@ typedef enum {
|
||||||
union _GrabMask {
|
union _GrabMask {
|
||||||
Mask core;
|
Mask core;
|
||||||
Mask xi;
|
Mask xi;
|
||||||
char xi2mask[EMASKSIZE][XI2MASKSIZE];
|
struct _XI2Mask *xi2mask;
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -210,7 +210,7 @@ typedef struct _GrabRec {
|
||||||
Mask eventMask;
|
Mask eventMask;
|
||||||
Mask deviceMask;
|
Mask deviceMask;
|
||||||
/* XI2 event masks. One per device, each bit is a mask of (1 << type) */
|
/* XI2 event masks. One per device, each bit is a mask of (1 << type) */
|
||||||
unsigned char xi2mask[EMASKSIZE][XI2MASKSIZE];
|
struct _XI2Mask *xi2mask;
|
||||||
} GrabRec;
|
} GrabRec;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -451,7 +451,7 @@ typedef struct _GrabInfoRec {
|
||||||
TimeStamp grabTime;
|
TimeStamp grabTime;
|
||||||
Bool fromPassiveGrab; /* true if from passive grab */
|
Bool fromPassiveGrab; /* true if from passive grab */
|
||||||
Bool implicitGrab; /* implicit from ButtonPress */
|
Bool implicitGrab; /* implicit from ButtonPress */
|
||||||
GrabRec activeGrab;
|
GrabPtr activeGrab;
|
||||||
GrabPtr grab;
|
GrabPtr grab;
|
||||||
CARD8 activatingKey;
|
CARD8 activatingKey;
|
||||||
void (*ActivateGrab) (
|
void (*ActivateGrab) (
|
||||||
|
@ -575,7 +575,7 @@ extern _X_EXPORT InputInfo inputInfo;
|
||||||
/* for keeping the events for devices grabbed synchronously */
|
/* for keeping the events for devices grabbed synchronously */
|
||||||
typedef struct _QdEvent *QdEventPtr;
|
typedef struct _QdEvent *QdEventPtr;
|
||||||
typedef struct _QdEvent {
|
typedef struct _QdEvent {
|
||||||
QdEventPtr next;
|
struct list next;
|
||||||
DeviceIntPtr device;
|
DeviceIntPtr device;
|
||||||
ScreenPtr pScreen; /* what screen the pointer was on */
|
ScreenPtr pScreen; /* what screen the pointer was on */
|
||||||
unsigned long months; /* milliseconds is in the event */
|
unsigned long months; /* milliseconds is in the event */
|
||||||
|
@ -591,8 +591,8 @@ typedef struct _QdEvent {
|
||||||
* replayed and processed as if they would come from the device directly.
|
* replayed and processed as if they would come from the device directly.
|
||||||
*/
|
*/
|
||||||
typedef struct _EventSyncInfo {
|
typedef struct _EventSyncInfo {
|
||||||
QdEventPtr pending, /**< list of queued events */
|
struct list pending;
|
||||||
*pendtail; /**< last event in list */
|
|
||||||
/** The device to replay events for. Only set in AllowEvents(), in which
|
/** The device to replay events for. Only set in AllowEvents(), in which
|
||||||
* case it is set to the device specified in the request. */
|
* case it is set to the device specified in the request. */
|
||||||
DeviceIntPtr replayDev; /* kludgy rock to put flag for */
|
DeviceIntPtr replayDev; /* kludgy rock to put flag for */
|
||||||
|
@ -622,4 +622,10 @@ static inline WindowPtr DeepestSpriteWin(SpritePtr sprite)
|
||||||
return sprite->spriteTrace[sprite->spriteTraceGood - 1];
|
return sprite->spriteTrace[sprite->spriteTraceGood - 1];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
struct _XI2Mask {
|
||||||
|
unsigned char **masks; /* event mask in masks[deviceid][event type byte] */
|
||||||
|
size_t nmasks; /* number of masks */
|
||||||
|
size_t mask_size; /* size of each mask in bytes */
|
||||||
|
};
|
||||||
|
|
||||||
#endif /* INPUTSTRUCT_H */
|
#endif /* INPUTSTRUCT_H */
|
||||||
|
|
|
@ -46,4 +46,16 @@ FP1616 double_to_fp1616(double in);
|
||||||
double fp1616_to_double(FP1616 in);
|
double fp1616_to_double(FP1616 in);
|
||||||
double fp3232_to_double(FP3232 in);
|
double fp3232_to_double(FP3232 in);
|
||||||
|
|
||||||
|
|
||||||
|
XI2Mask* xi2mask_new(void);
|
||||||
|
XI2Mask* xi2mask_new_with_size(size_t, size_t); /* don't use it */
|
||||||
|
void xi2mask_free(XI2Mask** mask);
|
||||||
|
Bool xi2mask_isset(XI2Mask* mask, const DeviceIntPtr dev, int event_type);
|
||||||
|
void xi2mask_set(XI2Mask *mask, int deviceid, int event_type);
|
||||||
|
void xi2mask_zero(XI2Mask *mask, int deviceid);
|
||||||
|
void xi2mask_merge(XI2Mask *dest, const XI2Mask *source);
|
||||||
|
size_t xi2mask_num_masks(const XI2Mask *mask);
|
||||||
|
size_t xi2mask_mask_size(const XI2Mask *mask);
|
||||||
|
void xi2mask_set_one_mask(XI2Mask *xi2mask, int deviceid, const unsigned char *mask, size_t mask_size);
|
||||||
|
const unsigned char* xi2mask_get_one_mask(const XI2Mask *xi2mask, int deviceid);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -28,6 +28,7 @@
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @file Classic doubly-link circular list implementation.
|
* @file Classic doubly-link circular list implementation.
|
||||||
|
* For real usage examples of the linked list, see the file test/list.c
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* We need to keep a list of struct foo in the parent struct bar, i.e. what
|
* We need to keep a list of struct foo in the parent struct bar, i.e. what
|
||||||
|
@ -35,16 +36,16 @@
|
||||||
*
|
*
|
||||||
* struct bar {
|
* struct bar {
|
||||||
* ...
|
* ...
|
||||||
* struct foo *foos; -----> struct foo {}, struct foo {}, struct foo{}
|
* struct foo *list_of_foos; -----> struct foo {}, struct foo {}, struct foo{}
|
||||||
* ...
|
* ...
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
* We need one list head in bar and a list element in all foos (both are of
|
* We need one list head in bar and a list element in all list_of_foos (both are of
|
||||||
* data type 'struct list').
|
* data type 'struct list').
|
||||||
*
|
*
|
||||||
* struct bar {
|
* struct bar {
|
||||||
* ...
|
* ...
|
||||||
* struct list foos;
|
* struct list list_of_foos;
|
||||||
* ...
|
* ...
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
|
@ -58,27 +59,27 @@
|
||||||
*
|
*
|
||||||
* struct bar bar;
|
* struct bar bar;
|
||||||
* ...
|
* ...
|
||||||
* list_init(&bar.foos);
|
* list_init(&bar.list_of_foos);
|
||||||
*
|
*
|
||||||
* Then we create the first element and add it to this list:
|
* Then we create the first element and add it to this list:
|
||||||
*
|
*
|
||||||
* struct foo *foo = malloc(...);
|
* struct foo *foo = malloc(...);
|
||||||
* ....
|
* ....
|
||||||
* list_add(&foo->entry, &bar.foos);
|
* list_add(&foo->entry, &bar.list_of_foos);
|
||||||
*
|
*
|
||||||
* Repeat the above for each element you want to add to the list. Deleting
|
* Repeat the above for each element you want to add to the list. Deleting
|
||||||
* works with the element itself.
|
* works with the element itself.
|
||||||
* list_del(&foo->entry);
|
* list_del(&foo->entry);
|
||||||
* free(foo);
|
* free(foo);
|
||||||
*
|
*
|
||||||
* Note: calling list_del(&bar.foos) will set bar.foos to an empty
|
* Note: calling list_del(&bar.list_of_foos) will set bar.list_of_foos to an empty
|
||||||
* list again.
|
* list again.
|
||||||
*
|
*
|
||||||
* Looping through the list requires a 'struct foo' as iterator and the
|
* Looping through the list requires a 'struct foo' as iterator and the
|
||||||
* name of the field the subnodes use.
|
* name of the field the subnodes use.
|
||||||
*
|
*
|
||||||
* struct foo *iterator;
|
* struct foo *iterator;
|
||||||
* list_for_each_entry(iterator, &bar.foos, entry) {
|
* list_for_each_entry(iterator, &bar.list_of_foos, entry) {
|
||||||
* if (iterator->something == ...)
|
* if (iterator->something == ...)
|
||||||
* ...
|
* ...
|
||||||
* }
|
* }
|
||||||
|
@ -87,7 +88,7 @@
|
||||||
* loop. You need to run the safe for-each loop instead:
|
* loop. You need to run the safe for-each loop instead:
|
||||||
*
|
*
|
||||||
* struct foo *iterator, *next;
|
* struct foo *iterator, *next;
|
||||||
* list_for_each_entry_safe(iterator, next, &bar.foos, entry) {
|
* list_for_each_entry_safe(iterator, next, &bar.list_of_foos, entry) {
|
||||||
* if (...)
|
* if (...)
|
||||||
* list_del(&iterator->entry);
|
* list_del(&iterator->entry);
|
||||||
* }
|
* }
|
||||||
|
@ -96,14 +97,8 @@
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The linkage struct for list nodes. This struct must be part of your
|
* The linkage struct for list nodes. This struct must be part of your
|
||||||
* to-be-linked struct.
|
* to-be-linked struct. struct list is required for both the head of the
|
||||||
*
|
* list and for each list node.
|
||||||
* Example:
|
|
||||||
* struct foo {
|
|
||||||
* int a;
|
|
||||||
* void *b;
|
|
||||||
* struct list *mylist;
|
|
||||||
* }
|
|
||||||
*
|
*
|
||||||
* Position and name of the struct list field is irrelevant.
|
* Position and name of the struct list field is irrelevant.
|
||||||
* There are no requirements that elements of a list are of the same type.
|
* There are no requirements that elements of a list are of the same type.
|
||||||
|
@ -118,7 +113,7 @@ struct list {
|
||||||
* Initialize the list as an empty list.
|
* Initialize the list as an empty list.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* list_init(&foo->mylist);
|
* list_init(&bar->list_of_foos);
|
||||||
*
|
*
|
||||||
* @param The list to initialized.
|
* @param The list to initialized.
|
||||||
*/
|
*/
|
||||||
|
@ -140,7 +135,8 @@ __list_add(struct list *entry,
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Insert a new element after the given list head.
|
* Insert a new element after the given list head. The new element does not
|
||||||
|
* need to be initialised as empty list.
|
||||||
* The list changes from:
|
* The list changes from:
|
||||||
* head → some element → ...
|
* head → some element → ...
|
||||||
* to
|
* to
|
||||||
|
@ -148,7 +144,7 @@ __list_add(struct list *entry,
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* struct foo *newfoo = malloc(...);
|
* struct foo *newfoo = malloc(...);
|
||||||
* list_add(&newfoo->mylist, &foo->mylist);
|
* list_add(&newfoo->entry, &bar->list_of_foos);
|
||||||
*
|
*
|
||||||
* @param entry The new element to prepend to the list.
|
* @param entry The new element to prepend to the list.
|
||||||
* @param head The existing list.
|
* @param head The existing list.
|
||||||
|
@ -159,6 +155,28 @@ list_add(struct list *entry, struct list *head)
|
||||||
__list_add(entry, head, head->next);
|
__list_add(entry, head, head->next);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Append a new element to the end of the list given with this list head.
|
||||||
|
*
|
||||||
|
* The list changes from:
|
||||||
|
* head → some element → ... → lastelement
|
||||||
|
* to
|
||||||
|
* head → some element → ... → lastelement → new element
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* struct foo *newfoo = malloc(...);
|
||||||
|
* list_append(&newfoo->entry, &bar->list_of_foos);
|
||||||
|
*
|
||||||
|
* @param entry The new element to prepend to the list.
|
||||||
|
* @param head The existing list.
|
||||||
|
*/
|
||||||
|
static inline void
|
||||||
|
list_append(struct list *entry, struct list *head)
|
||||||
|
{
|
||||||
|
__list_add(entry, head->prev, head);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
static inline void
|
static inline void
|
||||||
__list_del(struct list *prev, struct list *next)
|
__list_del(struct list *prev, struct list *next)
|
||||||
{
|
{
|
||||||
|
@ -176,7 +194,7 @@ __list_del(struct list *prev, struct list *next)
|
||||||
* the list but rather reset the list as empty list.
|
* the list but rather reset the list as empty list.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* list_del(&newfoo->mylist);
|
* list_del(&foo->entry);
|
||||||
*
|
*
|
||||||
* @param entry The element to remove.
|
* @param entry The element to remove.
|
||||||
*/
|
*/
|
||||||
|
@ -191,7 +209,7 @@ list_del(struct list *entry)
|
||||||
* Check if the list is empty.
|
* Check if the list is empty.
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* list_is_empty(&foo->mylist);
|
* list_is_empty(&bar->list_of_foos);
|
||||||
*
|
*
|
||||||
* @return True if the list contains one or more elements or False otherwise.
|
* @return True if the list contains one or more elements or False otherwise.
|
||||||
*/
|
*/
|
||||||
|
@ -206,7 +224,7 @@ list_is_empty(struct list *head)
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* struct foo* f;
|
* struct foo* f;
|
||||||
* f = container_of(&foo->mylist, struct foo, mylist);
|
* f = container_of(&foo->entry, struct foo, entry);
|
||||||
* assert(f == foo);
|
* assert(f == foo);
|
||||||
*
|
*
|
||||||
* @param ptr Pointer to the struct list.
|
* @param ptr Pointer to the struct list.
|
||||||
|
@ -230,7 +248,7 @@ list_is_empty(struct list *head)
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* struct foo *first;
|
* struct foo *first;
|
||||||
* first = list_first_entry(&foo->mylist, struct foo, mylist);
|
* first = list_first_entry(&bar->list_of_foos, struct foo, list_of_foos);
|
||||||
*
|
*
|
||||||
* @param ptr The list head
|
* @param ptr The list head
|
||||||
* @param type Data type of the list element to retrieve
|
* @param type Data type of the list element to retrieve
|
||||||
|
@ -240,6 +258,21 @@ list_is_empty(struct list *head)
|
||||||
#define list_first_entry(ptr, type, member) \
|
#define list_first_entry(ptr, type, member) \
|
||||||
list_entry((ptr)->next, type, member)
|
list_entry((ptr)->next, type, member)
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Retrieve the last list entry for the given listpointer.
|
||||||
|
*
|
||||||
|
* Example:
|
||||||
|
* struct foo *first;
|
||||||
|
* first = list_last_entry(&bar->list_of_foos, struct foo, list_of_foos);
|
||||||
|
*
|
||||||
|
* @param ptr The list head
|
||||||
|
* @param type Data type of the list element to retrieve
|
||||||
|
* @param member Member name of the struct list field in the list element.
|
||||||
|
* @return A pointer to the last list element.
|
||||||
|
*/
|
||||||
|
#define list_last_entry(ptr, type, member) \
|
||||||
|
list_entry((ptr)->prev, type, member)
|
||||||
|
|
||||||
#define __container_of(ptr, sample, member) \
|
#define __container_of(ptr, sample, member) \
|
||||||
(void *)((char *)(ptr) \
|
(void *)((char *)(ptr) \
|
||||||
- ((char *)&(sample)->member - (char *)(sample)))
|
- ((char *)&(sample)->member - (char *)(sample)))
|
||||||
|
@ -248,7 +281,7 @@ list_is_empty(struct list *head)
|
||||||
*
|
*
|
||||||
* Example:
|
* Example:
|
||||||
* struct foo *iterator;
|
* struct foo *iterator;
|
||||||
* list_for_each_entry(iterator, &foo->mylist, mylist) {
|
* list_for_each_entry(iterator, &bar->list_of_foos, entry) {
|
||||||
* [modify iterator]
|
* [modify iterator]
|
||||||
* }
|
* }
|
||||||
*
|
*
|
||||||
|
|
|
@ -359,11 +359,18 @@ typedef struct _CharInfo *CharInfoPtr; /* also in fonts/include/font.h */
|
||||||
extern _X_EXPORT unsigned long globalSerialNumber;
|
extern _X_EXPORT unsigned long globalSerialNumber;
|
||||||
extern _X_EXPORT unsigned long serverGeneration;
|
extern _X_EXPORT unsigned long serverGeneration;
|
||||||
|
|
||||||
#define BUG_WARN(cond) \
|
/* Don't use this directly, use BUG_WARN or BUG_WARN_MSG instead */
|
||||||
|
#define __BUG_WARN_MSG(cond, with_msg, ...) \
|
||||||
do { if (cond) { \
|
do { if (cond) { \
|
||||||
ErrorF("BUG: triggered 'if (" #cond ")'\nBUG: %s:%d in %s()\n", \
|
ErrorF("BUG: triggered 'if (" #cond ")'\nBUG: %s:%d in %s()\n", \
|
||||||
__FILE__, __LINE__, __func__); \
|
__FILE__, __LINE__, __func__); \
|
||||||
|
if (with_msg) ErrorF(__VA_ARGS__); \
|
||||||
xorg_backtrace(); \
|
xorg_backtrace(); \
|
||||||
} } while(0)
|
} } while(0)
|
||||||
|
|
||||||
|
#define BUG_WARN_MSG(cond, msg, ...) \
|
||||||
|
__BUG_WARN_MSG(cond, 1, msg, __VA_ARGS__)
|
||||||
|
|
||||||
|
#define BUG_WARN(cond) __BUG_WARN_MSG(cond, 0, NULL)
|
||||||
|
|
||||||
#endif /* MISC_H */
|
#endif /* MISC_H */
|
||||||
|
|
67
test/input.c
67
test/input.c
|
@ -1674,8 +1674,75 @@ mieq_test(void) {
|
||||||
mieqFini();
|
mieqFini();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Simple check that we're replaying events in-order */
|
||||||
|
static void
|
||||||
|
process_input_proc(InternalEvent *ev, DeviceIntPtr device)
|
||||||
|
{
|
||||||
|
static int last_evtype = -1;
|
||||||
|
|
||||||
|
if (ev->any.header == 0xac)
|
||||||
|
last_evtype = -1;
|
||||||
|
|
||||||
|
assert(ev->any.type == ++last_evtype);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
dix_enqueue_events(void) {
|
||||||
|
#define NEVENTS 5
|
||||||
|
DeviceIntRec dev;
|
||||||
|
InternalEvent ev[NEVENTS];
|
||||||
|
SpriteInfoRec spriteInfo;
|
||||||
|
SpriteRec sprite;
|
||||||
|
QdEventPtr qe;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
memset(&dev, 0, sizeof(dev));
|
||||||
|
dev.public.processInputProc = process_input_proc;
|
||||||
|
|
||||||
|
memset(&spriteInfo, 0, sizeof(spriteInfo));
|
||||||
|
memset(&sprite, 0, sizeof(sprite));
|
||||||
|
dev.spriteInfo = &spriteInfo;
|
||||||
|
spriteInfo.sprite = &sprite;
|
||||||
|
|
||||||
|
InitEvents();
|
||||||
|
assert(list_is_empty(&syncEvents.pending));
|
||||||
|
|
||||||
|
/* this way PlayReleasedEvents really runs through all events in the
|
||||||
|
* queue */
|
||||||
|
inputInfo.devices = &dev;
|
||||||
|
|
||||||
|
/* to reset process_input_proc */
|
||||||
|
ev[0].any.header = 0xac;
|
||||||
|
|
||||||
|
for (i = 0; i < NEVENTS; i++)
|
||||||
|
{
|
||||||
|
ev[i].any.length = sizeof(*ev);
|
||||||
|
ev[i].any.type = i;
|
||||||
|
EnqueueEvent(&ev[i], &dev);
|
||||||
|
assert(!list_is_empty(&syncEvents.pending));
|
||||||
|
qe = list_last_entry(&syncEvents.pending, QdEventRec, next);
|
||||||
|
assert(memcmp(qe->event, &ev[i], ev[i].any.length) == 0);
|
||||||
|
qe = list_first_entry(&syncEvents.pending, QdEventRec, next);
|
||||||
|
assert(memcmp(qe->event, &ev[0], ev[i].any.length) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* calls process_input_proc */
|
||||||
|
dev.deviceGrab.sync.frozen = 1;
|
||||||
|
PlayReleasedEvents();
|
||||||
|
assert(!list_is_empty(&syncEvents.pending));
|
||||||
|
|
||||||
|
|
||||||
|
dev.deviceGrab.sync.frozen = 0;
|
||||||
|
PlayReleasedEvents();
|
||||||
|
assert(list_is_empty(&syncEvents.pending));
|
||||||
|
|
||||||
|
inputInfo.devices = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char** argv)
|
int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
|
dix_enqueue_events();
|
||||||
dix_double_fp_conversion();
|
dix_double_fp_conversion();
|
||||||
dix_input_valuator_masks();
|
dix_input_valuator_masks();
|
||||||
dix_input_attributes();
|
dix_input_attributes();
|
||||||
|
|
37
test/list.c
37
test/list.c
|
@ -88,6 +88,42 @@ test_list_add(void)
|
||||||
assert(memcmp(c, &child[2], sizeof(struct child)) == 0);
|
assert(memcmp(c, &child[2], sizeof(struct child)) == 0);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
static void
|
||||||
|
test_list_append(void)
|
||||||
|
{
|
||||||
|
struct parent parent = {0};
|
||||||
|
struct child child[3];
|
||||||
|
struct child *c;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
list_init(&parent.children);
|
||||||
|
|
||||||
|
list_append(&child[0].node, &parent.children);
|
||||||
|
assert(!list_is_empty(&parent.children));
|
||||||
|
|
||||||
|
c = list_first_entry(&parent.children, struct child, node);
|
||||||
|
assert(memcmp(c, &child[0], sizeof(struct child)) == 0);
|
||||||
|
c = list_last_entry(&parent.children, struct child, node);
|
||||||
|
assert(memcmp(c, &child[0], sizeof(struct child)) == 0);
|
||||||
|
|
||||||
|
list_append(&child[1].node, &parent.children);
|
||||||
|
c = list_first_entry(&parent.children, struct child, node);
|
||||||
|
assert(memcmp(c, &child[0], sizeof(struct child)) == 0);
|
||||||
|
c = list_last_entry(&parent.children, struct child, node);
|
||||||
|
assert(memcmp(c, &child[1], sizeof(struct child)) == 0);
|
||||||
|
|
||||||
|
list_append(&child[2].node, &parent.children);
|
||||||
|
c = list_first_entry(&parent.children, struct child, node);
|
||||||
|
assert(memcmp(c, &child[0], sizeof(struct child)) == 0);
|
||||||
|
c = list_last_entry(&parent.children, struct child, node);
|
||||||
|
assert(memcmp(c, &child[2], sizeof(struct child)) == 0);
|
||||||
|
|
||||||
|
i = 0;
|
||||||
|
list_for_each_entry(c, &parent.children, node) {
|
||||||
|
assert(memcmp(c, &child[i++], sizeof(struct child)) == 0);
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
static void
|
static void
|
||||||
test_list_del(void)
|
test_list_del(void)
|
||||||
{
|
{
|
||||||
|
@ -325,6 +361,7 @@ int main(int argc, char** argv)
|
||||||
{
|
{
|
||||||
test_list_init();
|
test_list_init();
|
||||||
test_list_add();
|
test_list_add();
|
||||||
|
test_list_append();
|
||||||
test_list_del();
|
test_list_del();
|
||||||
test_list_for_each();
|
test_list_for_each();
|
||||||
|
|
||||||
|
|
|
@ -10,7 +10,8 @@ noinst_PROGRAMS = \
|
||||||
protocol-xipassivegrabdevice \
|
protocol-xipassivegrabdevice \
|
||||||
protocol-xiquerypointer \
|
protocol-xiquerypointer \
|
||||||
protocol-xiwarppointer \
|
protocol-xiwarppointer \
|
||||||
protocol-eventconvert
|
protocol-eventconvert \
|
||||||
|
xi2
|
||||||
|
|
||||||
TESTS=$(noinst_PROGRAMS)
|
TESTS=$(noinst_PROGRAMS)
|
||||||
TESTS_ENVIRONMENT = $(XORG_MALLOC_DEBUG_ENV)
|
TESTS_ENVIRONMENT = $(XORG_MALLOC_DEBUG_ENV)
|
||||||
|
@ -34,6 +35,7 @@ protocol_xiquerypointer_LDADD=$(TEST_LDADD)
|
||||||
protocol_xipassivegrabdevice_LDADD=$(TEST_LDADD)
|
protocol_xipassivegrabdevice_LDADD=$(TEST_LDADD)
|
||||||
protocol_xiwarppointer_LDADD=$(TEST_LDADD)
|
protocol_xiwarppointer_LDADD=$(TEST_LDADD)
|
||||||
protocol_eventconvert_LDADD=$(TEST_LDADD)
|
protocol_eventconvert_LDADD=$(TEST_LDADD)
|
||||||
|
xi2_LDADD=$(TEST_LDADD)
|
||||||
|
|
||||||
protocol_xiqueryversion_LDFLAGS=$(AM_LDFLAGS) -Wl,-wrap,WriteToClient
|
protocol_xiqueryversion_LDFLAGS=$(AM_LDFLAGS) -Wl,-wrap,WriteToClient
|
||||||
protocol_xiquerydevice_LDFLAGS=$(AM_LDFLAGS) -Wl,-wrap,WriteToClient
|
protocol_xiquerydevice_LDFLAGS=$(AM_LDFLAGS) -Wl,-wrap,WriteToClient
|
||||||
|
@ -44,6 +46,7 @@ protocol_xigetclientpointer_LDFLAGS=$(AM_LDFLAGS) -Wl,-wrap,WriteToClient -Wl,-w
|
||||||
protocol_xipassivegrabdevice_LDFLAGS=$(AM_LDFLAGS) -Wl,-wrap,GrabButton -Wl,-wrap,dixLookupWindow -Wl,-wrap,WriteToClient
|
protocol_xipassivegrabdevice_LDFLAGS=$(AM_LDFLAGS) -Wl,-wrap,GrabButton -Wl,-wrap,dixLookupWindow -Wl,-wrap,WriteToClient
|
||||||
protocol_xiquerypointer_LDFLAGS=$(AM_LDFLAGS) -Wl,-wrap,WriteToClient -Wl,-wrap,dixLookupWindow
|
protocol_xiquerypointer_LDFLAGS=$(AM_LDFLAGS) -Wl,-wrap,WriteToClient -Wl,-wrap,dixLookupWindow
|
||||||
protocol_xiwarppointer_LDFLAGS=$(AM_LDFLAGS) -Wl,-wrap,WriteToClient -Wl,-wrap,dixLookupWindow
|
protocol_xiwarppointer_LDFLAGS=$(AM_LDFLAGS) -Wl,-wrap,WriteToClient -Wl,-wrap,dixLookupWindow
|
||||||
|
xi2_LDFLAGS=$(AM_LDFLAGS)
|
||||||
|
|
||||||
protocol_xiqueryversion_SOURCES=$(COMMON_SOURCES) protocol-xiqueryversion.c
|
protocol_xiqueryversion_SOURCES=$(COMMON_SOURCES) protocol-xiqueryversion.c
|
||||||
protocol_xiquerydevice_SOURCES=$(COMMON_SOURCES) protocol-xiquerydevice.c
|
protocol_xiquerydevice_SOURCES=$(COMMON_SOURCES) protocol-xiquerydevice.c
|
||||||
|
|
|
@ -0,0 +1,129 @@
|
||||||
|
/**
|
||||||
|
* Copyright © 2011 Red Hat, Inc.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a
|
||||||
|
* copy of this software and associated documentation files (the "Software"),
|
||||||
|
* to deal in the Software without restriction, including without limitation
|
||||||
|
* the rights to use, copy, modify, merge, publish, distribute, sublicense,
|
||||||
|
* and/or sell copies of the Software, and to permit persons to whom the
|
||||||
|
* Software is furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice (including the next
|
||||||
|
* paragraph) shall be included in all copies or substantial portions of the
|
||||||
|
* Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
|
||||||
|
* THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
||||||
|
* DEALINGS IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef HAVE_DIX_CONFIG_H
|
||||||
|
#include <dix-config.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include "inpututils.h"
|
||||||
|
#include "inputstr.h"
|
||||||
|
#include "assert.h"
|
||||||
|
|
||||||
|
static void xi2mask_test(void)
|
||||||
|
{
|
||||||
|
XI2Mask *xi2mask = NULL,
|
||||||
|
*mergemask = NULL;
|
||||||
|
unsigned char *mask;
|
||||||
|
DeviceIntRec dev;
|
||||||
|
int i;
|
||||||
|
|
||||||
|
/* size >= nmasks * 2 for the test cases below */
|
||||||
|
xi2mask = xi2mask_new_with_size(MAXDEVICES + 2, (MAXDEVICES + 2) * 2);
|
||||||
|
assert(xi2mask);
|
||||||
|
assert(xi2mask->nmasks > 0);
|
||||||
|
assert(xi2mask->mask_size > 0);
|
||||||
|
|
||||||
|
assert(xi2mask_mask_size(xi2mask) == xi2mask->mask_size);
|
||||||
|
assert(xi2mask_num_masks(xi2mask) == xi2mask->nmasks);
|
||||||
|
|
||||||
|
mask = calloc(1, xi2mask_mask_size(xi2mask));
|
||||||
|
/* ensure zeros */
|
||||||
|
for (i = 0; i < xi2mask_num_masks(xi2mask); i++) {
|
||||||
|
const unsigned char *m = xi2mask_get_one_mask(xi2mask, i);
|
||||||
|
assert(memcmp(mask, m, xi2mask_mask_size(xi2mask)) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* set various bits */
|
||||||
|
for (i = 0; i < xi2mask_num_masks(xi2mask); i++) {
|
||||||
|
const unsigned char *m;
|
||||||
|
xi2mask_set(xi2mask, i, i);
|
||||||
|
|
||||||
|
dev.id = i;
|
||||||
|
assert(xi2mask_isset(xi2mask, &dev, i));
|
||||||
|
|
||||||
|
m = xi2mask_get_one_mask(xi2mask, i);
|
||||||
|
SetBit(mask, i);
|
||||||
|
assert(memcmp(mask, m, xi2mask_mask_size(xi2mask)) == 0);
|
||||||
|
ClearBit(mask, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* ensure zeros one-by-one */
|
||||||
|
for (i = 0; i < xi2mask_num_masks(xi2mask); i++) {
|
||||||
|
const unsigned char *m = xi2mask_get_one_mask(xi2mask, i);
|
||||||
|
assert(memcmp(mask, m, xi2mask_mask_size(xi2mask)) != 0);
|
||||||
|
xi2mask_zero(xi2mask, i);
|
||||||
|
assert(memcmp(mask, m, xi2mask_mask_size(xi2mask)) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* re-set, zero all */
|
||||||
|
for (i = 0; i < xi2mask_num_masks(xi2mask); i++)
|
||||||
|
xi2mask_set(xi2mask, i, i);
|
||||||
|
xi2mask_zero(xi2mask, -1);
|
||||||
|
|
||||||
|
for (i = 0; i < xi2mask_num_masks(xi2mask); i++) {
|
||||||
|
const unsigned char *m = xi2mask_get_one_mask(xi2mask, i);
|
||||||
|
assert(memcmp(mask, m, xi2mask_mask_size(xi2mask)) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
for (i = 0; i < xi2mask_num_masks(xi2mask); i++) {
|
||||||
|
const unsigned char *m;
|
||||||
|
SetBit(mask, i);
|
||||||
|
xi2mask_set_one_mask(xi2mask, i, mask, xi2mask_mask_size(xi2mask));
|
||||||
|
m = xi2mask_get_one_mask(xi2mask, i);
|
||||||
|
assert(memcmp(mask, m, xi2mask_mask_size(xi2mask)) == 0);
|
||||||
|
ClearBit(mask, i);
|
||||||
|
}
|
||||||
|
|
||||||
|
mergemask = xi2mask_new_with_size(MAXDEVICES + 2, (MAXDEVICES + 2) * 2);
|
||||||
|
for (i = 0; i < xi2mask_num_masks(mergemask); i++) {
|
||||||
|
dev.id = i;
|
||||||
|
xi2mask_set(mergemask, i, i * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
/* xi2mask still has all i bits set, should now also have all i * 2 bits */
|
||||||
|
xi2mask_merge(xi2mask, mergemask);
|
||||||
|
for (i = 0; i < xi2mask_num_masks(mergemask); i++) {
|
||||||
|
const unsigned char *m = xi2mask_get_one_mask(xi2mask, i);
|
||||||
|
SetBit(mask, i);
|
||||||
|
SetBit(mask, i * 2);
|
||||||
|
assert(memcmp(mask, m, xi2mask_mask_size(xi2mask)) == 0);
|
||||||
|
ClearBit(mask, i);
|
||||||
|
ClearBit(mask, i * 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
xi2mask_free(&xi2mask);
|
||||||
|
assert(xi2mask == NULL);
|
||||||
|
|
||||||
|
xi2mask_free(&mergemask);
|
||||||
|
assert(mergemask == NULL);
|
||||||
|
free(mask);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int main(int argc, char** argv)
|
||||||
|
{
|
||||||
|
xi2mask_test();
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
|
@ -179,9 +179,9 @@ CursorDisplayCursor (DeviceIntPtr pDev,
|
||||||
ev.type = XFixesEventBase + XFixesCursorNotify;
|
ev.type = XFixesEventBase + XFixesCursorNotify;
|
||||||
ev.subtype = XFixesDisplayCursorNotify;
|
ev.subtype = XFixesDisplayCursorNotify;
|
||||||
ev.window = e->pWindow->drawable.id;
|
ev.window = e->pWindow->drawable.id;
|
||||||
ev.cursorSerial = pCursor->serialNumber;
|
ev.cursorSerial = pCursor ? pCursor->serialNumber : 0;
|
||||||
ev.timestamp = currentTime.milliseconds;
|
ev.timestamp = currentTime.milliseconds;
|
||||||
ev.name = pCursor->name;
|
ev.name = pCursor ? pCursor->name : None;
|
||||||
WriteEventsToClient (e->pClient, 1, (xEvent *) &ev);
|
WriteEventsToClient (e->pClient, 1, (xEvent *) &ev);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue