Merge remote-tracking branch 'whot/for-keith'

This commit is contained in:
Keith Packard 2011-05-13 13:59:36 -07:00
commit ba5540221f
35 changed files with 926 additions and 770 deletions

View File

@ -52,6 +52,7 @@
#include "mipointer.h"
#include "xserver-properties.h"
#include "exevents.h"
#include "eventstr.h"
#include "inpututils.h"
#include "modinit.h"
@ -61,7 +62,7 @@ extern int DeviceValuator;
/* XTest events are sent during request processing and may be interruped by
* a SIGIO. We need a separate event list to avoid events overwriting each
* other's memory */
static EventListPtr xtest_evlist;
static InternalEvent* xtest_evlist;
/**
* xtestpointer
@ -428,7 +429,7 @@ ProcXTestFakeInput(ClientPtr client)
}
for (i = 0; i < nevents; i++)
mieqProcessDeviceEvent(dev, (InternalEvent*)(xtest_evlist+i)->event, NULL);
mieqProcessDeviceEvent(dev, &xtest_evlist[i], NULL);
if (need_ptr_update)
miPointerUpdateSprite(dev);

View File

@ -77,6 +77,7 @@ SOFTWARE.
#include "xiquerydevice.h" /* For List*Info */
#include "eventconvert.h"
#include "eventstr.h"
#include "inpututils.h"
#include <X11/extensions/XKBproto.h>
#include "xkbsrv.h"
@ -920,7 +921,7 @@ ProcessOtherEvent(InternalEvent *ev, DeviceIntPtr device)
DeviceIntPtr mouse = NULL, kbd = NULL;
DeviceEvent *event = &ev->device_event;
CHECKEVENT(ev);
verify_internal_event(ev);
if (ev->any.type == ET_RawKeyPress ||
ev->any.type == ET_RawKeyRelease ||
@ -1188,6 +1189,108 @@ FixDeviceValuator(DeviceIntPtr dev, deviceValuator * ev, ValuatorClassPtr v,
first += ev->num_valuators;
}
static void
DeliverStateNotifyEvent(DeviceIntPtr dev, WindowPtr win)
{
int evcount = 1;
deviceStateNotify *ev, *sev;
deviceKeyStateNotify *kev;
deviceButtonStateNotify *bev;
KeyClassPtr k;
ButtonClassPtr b;
ValuatorClassPtr v;
int nval = 0, nkeys = 0, nbuttons = 0, first = 0;
if (!(wOtherInputMasks(win)) ||
!(wOtherInputMasks(win)->inputEvents[dev->id] & DeviceStateNotifyMask))
return;
if ((b = dev->button) != NULL) {
nbuttons = b->numButtons;
if (nbuttons > 32)
evcount++;
}
if ((k = dev->key) != NULL) {
nkeys = k->xkbInfo->desc->max_key_code -
k->xkbInfo->desc->min_key_code;
if (nkeys > 32)
evcount++;
if (nbuttons > 0) {
evcount++;
}
}
if ((v = dev->valuator) != NULL) {
nval = v->numAxes;
if (nval > 3)
evcount++;
if (nval > 6) {
if (!(k && b))
evcount++;
if (nval > 9)
evcount += ((nval - 7) / 3);
}
}
sev = ev = (deviceStateNotify *) malloc(evcount * sizeof(xEvent));
FixDeviceStateNotify(dev, ev, NULL, NULL, NULL, first);
if (b != NULL) {
FixDeviceStateNotify(dev, ev++, NULL, b, v, first);
first += 3;
nval -= 3;
if (nbuttons > 32) {
(ev - 1)->deviceid |= MORE_EVENTS;
bev = (deviceButtonStateNotify *) ev++;
bev->type = DeviceButtonStateNotify;
bev->deviceid = dev->id;
memcpy((char*)&bev->buttons[4], (char*)&b->down[4], DOWN_LENGTH - 4);
}
if (nval > 0) {
(ev - 1)->deviceid |= MORE_EVENTS;
FixDeviceValuator(dev, (deviceValuator *) ev++, v, first);
first += 3;
nval -= 3;
}
}
if (k != NULL) {
FixDeviceStateNotify(dev, ev++, k, NULL, v, first);
first += 3;
nval -= 3;
if (nkeys > 32) {
(ev - 1)->deviceid |= MORE_EVENTS;
kev = (deviceKeyStateNotify *) ev++;
kev->type = DeviceKeyStateNotify;
kev->deviceid = dev->id;
memmove((char *)&kev->keys[0], (char *)&k->down[4], 28);
}
if (nval > 0) {
(ev - 1)->deviceid |= MORE_EVENTS;
FixDeviceValuator(dev, (deviceValuator *) ev++, v, first);
first += 3;
nval -= 3;
}
}
while (nval > 0) {
FixDeviceStateNotify(dev, ev++, NULL, NULL, v, first);
first += 3;
nval -= 3;
if (nval > 0) {
(ev - 1)->deviceid |= MORE_EVENTS;
FixDeviceValuator(dev, (deviceValuator *) ev++, v, first);
first += 3;
nval -= 3;
}
}
DeliverEventsToWindow(dev, win, (xEvent *) sev, evcount,
DeviceStateNotifyMask, NullGrab);
free(sev);
}
void
DeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail,
WindowPtr pWin)
@ -1254,104 +1357,8 @@ DeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail,
DeliverEventsToWindow(dev, pWin, (xEvent *) & event, 1,
DeviceFocusChangeMask, NullGrab);
if ((event.type == DeviceFocusIn) &&
(wOtherInputMasks(pWin)) &&
(wOtherInputMasks(pWin)->inputEvents[dev->id] & DeviceStateNotifyMask))
{
int evcount = 1;
deviceStateNotify *ev, *sev;
deviceKeyStateNotify *kev;
deviceButtonStateNotify *bev;
KeyClassPtr k;
ButtonClassPtr b;
ValuatorClassPtr v;
int nval = 0, nkeys = 0, nbuttons = 0, first = 0;
if ((b = dev->button) != NULL) {
nbuttons = b->numButtons;
if (nbuttons > 32)
evcount++;
}
if ((k = dev->key) != NULL) {
nkeys = k->xkbInfo->desc->max_key_code -
k->xkbInfo->desc->min_key_code;
if (nkeys > 32)
evcount++;
if (nbuttons > 0) {
evcount++;
}
}
if ((v = dev->valuator) != NULL) {
nval = v->numAxes;
if (nval > 3)
evcount++;
if (nval > 6) {
if (!(k && b))
evcount++;
if (nval > 9)
evcount += ((nval - 7) / 3);
}
}
sev = ev = (deviceStateNotify *) malloc(evcount * sizeof(xEvent));
FixDeviceStateNotify(dev, ev, NULL, NULL, NULL, first);
if (b != NULL) {
FixDeviceStateNotify(dev, ev++, NULL, b, v, first);
first += 3;
nval -= 3;
if (nbuttons > 32) {
(ev - 1)->deviceid |= MORE_EVENTS;
bev = (deviceButtonStateNotify *) ev++;
bev->type = DeviceButtonStateNotify;
bev->deviceid = dev->id;
memcpy((char*)&bev->buttons[4], (char*)&b->down[4], DOWN_LENGTH - 4);
}
if (nval > 0) {
(ev - 1)->deviceid |= MORE_EVENTS;
FixDeviceValuator(dev, (deviceValuator *) ev++, v, first);
first += 3;
nval -= 3;
}
}
if (k != NULL) {
FixDeviceStateNotify(dev, ev++, k, NULL, v, first);
first += 3;
nval -= 3;
if (nkeys > 32) {
(ev - 1)->deviceid |= MORE_EVENTS;
kev = (deviceKeyStateNotify *) ev++;
kev->type = DeviceKeyStateNotify;
kev->deviceid = dev->id;
memmove((char *)&kev->keys[0], (char *)&k->down[4], 28);
}
if (nval > 0) {
(ev - 1)->deviceid |= MORE_EVENTS;
FixDeviceValuator(dev, (deviceValuator *) ev++, v, first);
first += 3;
nval -= 3;
}
}
while (nval > 0) {
FixDeviceStateNotify(dev, ev++, NULL, NULL, v, first);
first += 3;
nval -= 3;
if (nval > 0) {
(ev - 1)->deviceid |= MORE_EVENTS;
FixDeviceValuator(dev, (deviceValuator *) ev++, v, first);
first += 3;
nval -= 3;
}
}
DeliverEventsToWindow(dev, pWin, (xEvent *) sev, evcount,
DeviceStateNotifyMask, NullGrab);
free(sev);
}
if (event.type == DeviceFocusIn)
DeliverStateNotifyEvent(dev, pWin);
}
int

View File

@ -355,6 +355,7 @@ detach_slave(ClientPtr client, xXIDetachSlaveInfo *c, int flags[MAXDEVICES])
goto unwind;
}
ReleaseButtonsAndKeys(dev);
AttachDevice(client, dev, NULL);
flags[dev->id] |= XISlaveDetached;
@ -406,6 +407,7 @@ attach_slave(ClientPtr client, xXIAttachSlaveInfo *c,
goto unwind;
}
ReleaseButtonsAndKeys(dev);
AttachDevice(client, dev, newmaster);
flags[dev->id] |= XISlaveAttached;

View File

@ -58,7 +58,6 @@ ProcXIQueryVersion(ClientPtr client)
xXIQueryVersionReply rep;
XIClientPtr pXIClient;
int major, minor;
unsigned int sversion, cversion;
REQUEST(xXIQueryVersionReq);
REQUEST_SIZE_MATCH(xXIQueryVersionReq);
@ -72,10 +71,8 @@ ProcXIQueryVersion(ClientPtr client)
pXIClient = dixLookupPrivate(&client->devPrivates, XIClientPrivateKey);
sversion = XIVersion.major_version * 1000 + XIVersion.minor_version;
cversion = stuff->major_version * 1000 + stuff->minor_version;
if (sversion > cversion)
if (version_compare(XIVersion.major_version, XIVersion.minor_version,
stuff->major_version, stuff->minor_version) > 0)
{
major = stuff->major_version;
minor = stuff->minor_version;

View File

@ -2365,10 +2365,10 @@ RecalculateMasterButtons(DeviceIntPtr slave)
* Generate release events for all keys/button currently down on this
* device.
*/
static void
void
ReleaseButtonsAndKeys(DeviceIntPtr dev)
{
EventListPtr eventlist = InitEventList(GetMaximumEventsNum());
InternalEvent* eventlist = InitEventList(GetMaximumEventsNum());
ButtonClassPtr b = dev->button;
KeyClassPtr k = dev->key;
int i, j, nevents;
@ -2383,7 +2383,7 @@ ReleaseButtonsAndKeys(DeviceIntPtr dev)
{
nevents = GetPointerEvents(eventlist, dev, ButtonRelease, i, 0, NULL);
for (j = 0; j < nevents; j++)
mieqProcessDeviceEvent(dev, (InternalEvent*)(eventlist+j)->event, NULL);
mieqProcessDeviceEvent(dev, &eventlist[j], NULL);
}
}
@ -2394,7 +2394,7 @@ ReleaseButtonsAndKeys(DeviceIntPtr dev)
{
nevents = GetKeyboardEvents(eventlist, dev, KeyRelease, i, NULL);
for (j = 0; j < nevents; j++)
mieqProcessDeviceEvent(dev, (InternalEvent*)(eventlist+j)->event, NULL);
mieqProcessDeviceEvent(dev, &eventlist[j], NULL);
}
}
@ -2434,8 +2434,6 @@ AttachDevice(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr master)
free(dev->spriteInfo->sprite);
}
ReleaseButtonsAndKeys(dev);
oldmaster = GetMaster(dev, MASTER_ATTACHED);
dev->master = master;

View File

@ -156,7 +156,7 @@ EventToCore(InternalEvent *event, xEvent **core_out, int *count_out)
case ET_RawButtonRelease:
case ET_RawMotion:
ret = BadMatch;
goto out;
break;
default:
/* XXX: */
ErrorF("[dix] EventToCore: Not implemented yet \n");

View File

@ -176,12 +176,23 @@ typedef const char *string;
#define AllEventMasks (LastEventMask|(LastEventMask-1))
#define CORE_EVENT(event) \
(!((event)->u.u.type & EXTENSION_EVENT_BASE) && \
(event)->u.u.type != GenericEvent)
#define XI2_EVENT(event) \
(((event)->u.u.type == GenericEvent) && \
((xGenericEvent*)(event))->extension == IReqCode)
/* @return the core event type or 0 if the event is not a core event */
static inline int
core_get_type(const xEvent *event)
{
int type = event->u.u.type;
return ((type & EXTENSION_EVENT_BASE) || type == GenericEvent) ? 0 : type;
}
/* @return the XI2 event type or 0 if the event is not a XI2 event */
static inline int
xi2_get_type(const xEvent *event)
{
xGenericEvent* e = (xGenericEvent*)event;
return (e->type != GenericEvent || e->extension != IReqCode) ? 0 : e->evtype;
}
/**
* Used to indicate a implicit passive grab created by a ButtonPress event.
@ -345,8 +356,8 @@ extern int DeviceMotionNotify;
/**
* Event masks for each event type.
*
* One set of filters for each device, but only the first layer
* is initialized. The rest is memcpy'd in InitEvents.
* One set of filters for each device, initialized by memcpy of
* default_filter in InitEvents.
*
* Filters are used whether a given event may be delivered to a client,
* usually in the form of if (window-event-mask & filter); then deliver event.
@ -355,7 +366,9 @@ extern int DeviceMotionNotify;
* time a button is pressed, the filter is modified to also contain the
* matching ButtonXMotion mask.
*/
static Mask filters[MAXDEVICES][128] = {
static Mask filters[MAXDEVICES][128];
static const Mask default_filter[128] =
{
NoSuchEvent, /* 0 */
NoSuchEvent, /* 1 */
@ -392,7 +405,7 @@ static Mask filters[MAXDEVICES][128] = {
ColormapChangeMask, /* ColormapNotify */
CantBeFiltered, /* ClientMessage */
CantBeFiltered /* MappingNotify */
}};
};
/**
* For the given event, return the matching event filter. This filter may then
@ -412,10 +425,12 @@ static Mask filters[MAXDEVICES][128] = {
Mask
GetEventFilter(DeviceIntPtr dev, xEvent *event)
{
int evtype = 0;
if (event->u.u.type != GenericEvent)
return filters[dev ? dev->id : 0][event->u.u.type];
else if (XI2_EVENT(event))
return (1 << (((xXIDeviceEvent*)event)->evtype % 8));
else if ((evtype = xi2_get_type(event)))
return (1 << (evtype % 8));
ErrorF("[dix] Unknown device type %d. No filter\n", event->u.u.type);
return 0;
}
@ -430,7 +445,7 @@ GetWindowXI2Mask(DeviceIntPtr dev, WindowPtr win, xEvent* ev)
int filter;
int evtype;
if (!inputMasks || !XI2_EVENT(ev))
if (!inputMasks || xi2_get_type(ev) == 0)
return 0;
evtype = ((xGenericEvent*)ev)->evtype;
@ -444,14 +459,16 @@ GetWindowXI2Mask(DeviceIntPtr dev, WindowPtr win, xEvent* ev)
Mask
GetEventMask(DeviceIntPtr dev, xEvent *event, InputClients* other)
{
int evtype;
/* XI2 filters are only ever 8 bit, so let's return a 8 bit mask */
if (XI2_EVENT(event))
if ((evtype = xi2_get_type(event)))
{
int byte = ((xGenericEvent*)event)->evtype / 8;
int byte = evtype / 8;
return (other->xi2mask[dev->id][byte] |
other->xi2mask[XIAllDevices][byte] |
(IsMaster(dev)? other->xi2mask[XIAllMasterDevices][byte] : 0));
} else if (CORE_EVENT(event))
} else if (core_get_type(event) != 0)
return other->mask[XIAllDevices];
else
return other->mask[dev->id];
@ -1937,6 +1954,159 @@ TryClientEvents (ClientPtr client, DeviceIntPtr dev, xEvent *pEvents,
return 1;
}
static BOOL
ActivateImplicitGrab(DeviceIntPtr dev, ClientPtr client, WindowPtr win,
xEvent *event, Mask deliveryMask)
{
GrabRec tempGrab;
OtherInputMasks *inputMasks;
CARD8 type = event->u.u.type;
GrabType grabtype;
if (type == ButtonPress)
grabtype = GRABTYPE_CORE;
else if (type == DeviceButtonPress)
grabtype = GRABTYPE_XI;
else if ((type = xi2_get_type(event)) == XI_ButtonPress)
grabtype = GRABTYPE_XI2;
else
return FALSE;
memset(&tempGrab, 0, sizeof(GrabRec));
tempGrab.next = NULL;
tempGrab.device = dev;
tempGrab.resource = client->clientAsMask;
tempGrab.window = win;
tempGrab.ownerEvents = (deliveryMask & OwnerGrabButtonMask) ? TRUE : FALSE;
tempGrab.eventMask = deliveryMask;
tempGrab.keyboardMode = GrabModeAsync;
tempGrab.pointerMode = GrabModeAsync;
tempGrab.confineTo = NullWindow;
tempGrab.cursor = NullCursor;
tempGrab.type = type;
tempGrab.grabtype = grabtype;
/* get the XI and XI2 device mask */
inputMasks = wOtherInputMasks(win);
tempGrab.deviceMask = (inputMasks) ? inputMasks->inputEvents[dev->id]: 0;
if (inputMasks)
memcpy(tempGrab.xi2mask, inputMasks->xi2mask,
sizeof(tempGrab.xi2mask));
(*dev->deviceGrab.ActivateGrab)(dev, &tempGrab,
currentTime, TRUE | ImplicitGrabMask);
return TRUE;
}
enum EventDeliveryState {
EVENT_DELIVERED, /**< Event has been delivered to a client */
EVENT_NOT_DELIVERED, /**< Event was not delivered to any client */
EVENT_SKIP, /**< Event can be discarded by the caller */
EVENT_REJECTED, /**< Event was rejected for delivery to the client */
};
/**
* Attempt event delivery to the client owning the window.
*/
static enum EventDeliveryState
DeliverToWindowOwner(DeviceIntPtr dev, WindowPtr win,
xEvent *events, int count, Mask filter,
GrabPtr grab)
{
/* if nobody ever wants to see this event, skip some work */
if (filter != CantBeFiltered &&
!((wOtherEventMasks(win)|win->eventMask) & filter))
return EVENT_SKIP;
if (IsInterferingGrab(wClient(win), dev, events))
return EVENT_SKIP;
if (!XaceHook(XACE_RECEIVE_ACCESS, wClient(win), win, events, count))
{
int attempt = TryClientEvents(wClient(win), dev, events,
count, win->eventMask,
filter, grab);
if (attempt > 0)
return EVENT_DELIVERED;
if (attempt < 0)
return EVENT_REJECTED;
}
return EVENT_NOT_DELIVERED;
}
/**
* Deliver events to clients registered on the window.
*
* @param client_return On successful delivery, set to the recipient.
* @param mask_return On successful delivery, set to the recipient's event
* mask for this event.
*/
static enum EventDeliveryState
DeliverEventToClients(DeviceIntPtr dev, WindowPtr win, xEvent *events,
int count, Mask filter, GrabPtr grab,
ClientPtr *client_return, Mask *mask_return)
{
int attempt;
enum EventDeliveryState rc = EVENT_SKIP;
InputClients *other;
if (core_get_type(events) != 0)
other = (InputClients *)wOtherClients(win);
else if (xi2_get_type(events) != 0)
{
OtherInputMasks *inputMasks = wOtherInputMasks(win);
/* Has any client selected for the event? */
if (!GetWindowXI2Mask(dev, win, events))
goto out;
other = inputMasks->inputClients;
} else {
OtherInputMasks *inputMasks = wOtherInputMasks(win);
/* Has any client selected for the event? */
if (!inputMasks ||
!(inputMasks->inputEvents[dev->id] & filter))
goto out;
other = inputMasks->inputClients;
}
rc = EVENT_NOT_DELIVERED;
for (; other; other = other->next)
{
Mask mask;
ClientPtr client = rClient(other);
if (IsInterferingGrab(client, dev, events))
continue;
mask = GetEventMask(dev, events, other);
if (XaceHook(XACE_RECEIVE_ACCESS, client, win,
events, count))
/* do nothing */;
else if ( (attempt = TryClientEvents(client, dev,
events, count,
mask, filter, grab)) )
{
if (attempt > 0)
{
rc = EVENT_DELIVERED;
*client_return = client;
*mask_return = mask;
/* Success overrides non-success, so if we've been
* successful on one client, return that */
} else if (rc == EVENT_NOT_DELIVERED)
rc = EVENT_REJECTED;
}
}
out:
return rc;
}
/**
* Deliver events to a window. At this point, we do not yet know if the event
* actually needs to be delivered. May activate a grab if the event is a
@ -1955,152 +2125,84 @@ TryClientEvents (ClientPtr client, DeviceIntPtr dev, xEvent *pEvents,
* @param filter Mask based on event type.
* @param grab Possible grab on the device that caused the event.
*
* @return Number of events delivered to various clients.
* @return a positive number if at least one successful delivery has been
* made, 0 if no events were delivered, or a negative number if the event
* has not been delivered _and_ rejected by at least one client.
*/
int
DeliverEventsToWindow(DeviceIntPtr pDev, WindowPtr pWin, xEvent
*pEvents, int count, Mask filter, GrabPtr grab)
{
int deliveries = 0, nondeliveries = 0;
int attempt;
InputClients *other;
ClientPtr client = NullClient;
Mask deliveryMask = 0; /* If a grab occurs due to a button press, then
this mask is the mask of the grab. */
int type = pEvents->u.u.type;
/* Deliver to window owner */
if ((filter == CantBeFiltered) || CORE_EVENT(pEvents))
if ((filter == CantBeFiltered) || core_get_type(pEvents) != 0)
{
/* if nobody ever wants to see this event, skip some work */
if (filter != CantBeFiltered &&
!((wOtherEventMasks(pWin)|pWin->eventMask) & filter))
return 0;
enum EventDeliveryState rc;
if (IsInterferingGrab(wClient(pWin), pDev, pEvents))
rc = DeliverToWindowOwner(pDev, pWin, pEvents, count, filter, grab);
switch(rc)
{
case EVENT_SKIP:
return 0;
if (XaceHook(XACE_RECEIVE_ACCESS, wClient(pWin), pWin, pEvents, count))
/* do nothing */;
else if ( (attempt = TryClientEvents(wClient(pWin), pDev, pEvents,
count, pWin->eventMask,
filter, grab)) )
{
if (attempt > 0)
{
deliveries++;
client = wClient(pWin);
deliveryMask = pWin->eventMask;
} else
nondeliveries--;
}
case EVENT_REJECTED:
nondeliveries--;
break;
case EVENT_DELIVERED:
/* We delivered to the owner, with our event mask */
deliveries++;
client = wClient(pWin);
deliveryMask = pWin->eventMask;
break;
case EVENT_NOT_DELIVERED:
break;
}
}
/* CantBeFiltered means only window owner gets the event */
if (filter != CantBeFiltered)
{
if (CORE_EVENT(pEvents))
other = (InputClients *)wOtherClients(pWin);
else if (XI2_EVENT(pEvents))
enum EventDeliveryState rc;
rc = DeliverEventToClients(pDev, pWin, pEvents, count, filter, grab,
&client, &deliveryMask);
switch(rc)
{
OtherInputMasks *inputMasks = wOtherInputMasks(pWin);
/* Has any client selected for the event? */
if (!GetWindowXI2Mask(pDev, pWin, pEvents))
case EVENT_SKIP:
return 0;
other = inputMasks->inputClients;
} else {
OtherInputMasks *inputMasks = wOtherInputMasks(pWin);
/* Has any client selected for the event? */
if (!inputMasks ||
!(inputMasks->inputEvents[pDev->id] & filter))
return 0;
other = inputMasks->inputClients;
}
for (; other; other = other->next)
{
Mask mask;
if (IsInterferingGrab(rClient(other), pDev, pEvents))
continue;
mask = GetEventMask(pDev, pEvents, other);
if (XaceHook(XACE_RECEIVE_ACCESS, rClient(other), pWin,
pEvents, count))
/* do nothing */;
else if ( (attempt = TryClientEvents(rClient(other), pDev,
pEvents, count,
mask, filter, grab)) )
{
if (attempt > 0)
{
deliveries++;
client = rClient(other);
deliveryMask = mask;
} else
nondeliveries--;
}
case EVENT_REJECTED:
nondeliveries--;
break;
case EVENT_DELIVERED:
deliveries++;
break;
case EVENT_NOT_DELIVERED:
break;
}
}
/*
* Note that since core events are delivered first, an implicit grab may
* be activated on a core grab, stopping the XI events.
*/
if ((type == DeviceButtonPress || type == ButtonPress ||
((XI2_EVENT(pEvents) && ((xGenericEvent*)pEvents)->evtype == XI_ButtonPress)))
&& deliveries
&& (!grab))
{
GrabRec tempGrab;
OtherInputMasks *inputMasks;
memset(&tempGrab, 0, sizeof(GrabRec));
tempGrab.next = NULL;
tempGrab.device = pDev;
tempGrab.resource = client->clientAsMask;
tempGrab.window = pWin;
tempGrab.ownerEvents = (deliveryMask & OwnerGrabButtonMask) ? TRUE : FALSE;
tempGrab.eventMask = deliveryMask;
tempGrab.keyboardMode = GrabModeAsync;
tempGrab.pointerMode = GrabModeAsync;
tempGrab.confineTo = NullWindow;
tempGrab.cursor = NullCursor;
tempGrab.type = type;
if (type == ButtonPress)
tempGrab.grabtype = GRABTYPE_CORE;
else if (type == DeviceButtonPress)
tempGrab.grabtype = GRABTYPE_XI;
else
{
tempGrab.type = ((xGenericEvent*)pEvents)->evtype;
tempGrab.grabtype = GRABTYPE_XI2;
}
/* get the XI and XI2 device mask */
inputMasks = wOtherInputMasks(pWin);
tempGrab.deviceMask = (inputMasks) ? inputMasks->inputEvents[pDev->id]: 0;
if (inputMasks)
memcpy(tempGrab.xi2mask, inputMasks->xi2mask,
sizeof(tempGrab.xi2mask));
(*pDev->deviceGrab.ActivateGrab)(pDev, &tempGrab,
currentTime, TRUE | ImplicitGrabMask);
}
else if ((type == MotionNotify) && deliveries)
pDev->valuator->motionHintWindow = pWin;
else
{
if ((type == DeviceMotionNotify || type == DeviceButtonPress) &&
deliveries)
CheckDeviceGrabAndHintWindow (pWin, type,
(deviceKeyButtonPointer*) pEvents,
grab, client, deliveryMask);
}
if (deliveries)
{
/*
* Note that since core events are delivered first, an implicit grab may
* be activated on a core grab, stopping the XI events.
*/
if (!grab && ActivateImplicitGrab(pDev, client, pWin, pEvents, deliveryMask))
/* grab activated */;
else if ((type == MotionNotify))
pDev->valuator->motionHintWindow = pWin;
else if (type == DeviceMotionNotify || type == DeviceButtonPress)
CheckDeviceGrabAndHintWindow (pWin, type,
(deviceKeyButtonPointer*) pEvents,
grab, client, deliveryMask);
return deliveries;
}
return nondeliveries;
}
@ -2180,7 +2282,7 @@ MaybeDeliverEventsToClient(WindowPtr pWin, xEvent *pEvents,
static Window FindChildForEvent(SpritePtr pSprite, WindowPtr event)
{
WindowPtr w = pSprite->spriteTrace[pSprite->spriteTraceGood-1];
WindowPtr w = DeepestSpriteWin(pSprite);
Window child = None;
/* If the search ends up past the root should the child field be
@ -2224,22 +2326,29 @@ FixUpEventFromWindow(
Window child,
Bool calcChild)
{
int evtype;
if (calcChild)
child = FindChildForEvent(pSprite, pWin);
if (XI2_EVENT(xE))
if ((evtype = xi2_get_type(xE)))
{
xXIDeviceEvent* event = (xXIDeviceEvent*)xE;
if (event->evtype == XI_RawKeyPress ||
event->evtype == XI_RawKeyRelease ||
event->evtype == XI_RawButtonPress ||
event->evtype == XI_RawButtonRelease ||
event->evtype == XI_RawMotion ||
event->evtype == XI_DeviceChanged ||
event->evtype == XI_HierarchyChanged ||
event->evtype == XI_PropertyEvent)
return;
switch (evtype)
{
case XI_RawKeyPress:
case XI_RawKeyRelease:
case XI_RawButtonPress:
case XI_RawButtonRelease:
case XI_RawMotion:
case XI_DeviceChanged:
case XI_HierarchyChanged:
case XI_PropertyEvent:
return;
default:
break;
}
event->root = RootWindow(pSprite)->drawable.id;
event->event = pWin->drawable.id;
@ -2375,7 +2484,7 @@ DeliverDeviceEvents(WindowPtr pWin, InternalEvent *event, GrabPtr grab,
xEvent *xE = NULL, *core = NULL;
int rc, mask, count = 0;
CHECKEVENT(event);
verify_internal_event(event);
while (pWin)
{
@ -2623,7 +2732,7 @@ XYToWindow(SpritePtr pSprite, int x, int y)
else
pWin = pWin->nextSib;
}
return pSprite->spriteTrace[pSprite->spriteTraceGood-1];
return DeepestSpriteWin(pSprite);
}
/**
@ -2661,7 +2770,8 @@ ActivateFocusInGrab(DeviceIntPtr dev, WindowPtr old, WindowPtr win)
event.deviceid = dev->id;
event.sourceid = dev->id;
event.detail.button = 0;
rc = (CheckPassiveGrabsOnWindow(win, dev, &event, FALSE, TRUE) != NULL);
rc = (CheckPassiveGrabsOnWindow(win, dev, (InternalEvent *) &event, FALSE,
TRUE) != NULL);
if (rc)
DoEnterLeaveEvents(dev, dev->id, old, win, XINotifyPassiveUngrab);
return rc;
@ -2698,7 +2808,8 @@ ActivateEnterGrab(DeviceIntPtr dev, WindowPtr old, WindowPtr win)
event.deviceid = dev->id;
event.sourceid = dev->id;
event.detail.button = 0;
rc = (CheckPassiveGrabsOnWindow(win, dev, &event, FALSE, TRUE) != NULL);
rc = (CheckPassiveGrabsOnWindow(win, dev, (InternalEvent *) &event, FALSE,
TRUE) != NULL);
if (rc)
DoEnterLeaveEvents(dev, dev->id, old, win, XINotifyPassiveGrab);
return rc;
@ -2721,7 +2832,7 @@ CheckMotion(DeviceEvent *ev, DeviceIntPtr pDev)
WindowPtr prevSpriteWin, newSpriteWin;
SpritePtr pSprite = pDev->spriteInfo->sprite;
CHECKEVENT(ev);
verify_internal_event(ev);
prevSpriteWin = pSprite->win;
@ -3385,7 +3496,7 @@ GrabPtr
CheckPassiveGrabsOnWindow(
WindowPtr pWin,
DeviceIntPtr device,
DeviceEvent *event,
InternalEvent *event,
BOOL checkCore,
BOOL activate)
{
@ -3402,9 +3513,22 @@ CheckPassiveGrabsOnWindow(
return NULL;
/* Fill out the grab details, but leave the type for later before
* comparing */
switch (event->any.type)
{
case ET_KeyPress:
case ET_KeyRelease:
tempGrab.detail.exact = event->device_event.detail.key;
break;
case ET_ButtonPress:
case ET_ButtonRelease:
tempGrab.detail.exact = event->device_event.detail.button;
break;
default:
tempGrab.detail.exact = 0;
break;
}
tempGrab.window = pWin;
tempGrab.device = device;
tempGrab.detail.exact = event->detail.key;
tempGrab.detail.pMask = NULL;
tempGrab.modifiersDetail.pMask = NULL;
tempGrab.next = NULL;
@ -3412,6 +3536,8 @@ CheckPassiveGrabsOnWindow(
{
DeviceIntPtr gdev;
XkbSrvInfoPtr xkbi = NULL;
xEvent *xE = NULL;
int count, rc;
gdev= grab->modifierDevice;
if (grab->grabtype == GRABTYPE_CORE)
@ -3437,16 +3563,15 @@ CheckPassiveGrabsOnWindow(
tempGrab.modifiersDetail.exact = xkbi ? xkbi->state.grab_mods : 0;
/* Check for XI2 and XI grabs first */
tempGrab.type = GetXI2Type((InternalEvent*)event);
tempGrab.type = GetXI2Type(event);
tempGrab.grabtype = GRABTYPE_XI2;
if (GrabMatchesSecond(&tempGrab, grab, FALSE))
match = XI2_MATCH;
tempGrab.detail.exact = event->detail.key;
if (!match)
{
tempGrab.grabtype = GRABTYPE_XI;
if ((tempGrab.type = GetXIType((InternalEvent*)event)) &&
if ((tempGrab.type = GetXIType(event)) &&
(GrabMatchesSecond(&tempGrab, grab, FALSE)))
match = XI_MATCH;
}
@ -3455,122 +3580,134 @@ CheckPassiveGrabsOnWindow(
if (!match && checkCore)
{
tempGrab.grabtype = GRABTYPE_CORE;
if ((tempGrab.type = GetCoreType((InternalEvent*)event)) &&
if ((tempGrab.type = GetCoreType(event)) &&
(GrabMatchesSecond(&tempGrab, grab, TRUE)))
match = CORE_MATCH;
}
if (match && (!grab->confineTo ||
(grab->confineTo->realized &&
BorderSizeNotEmpty(device, grab->confineTo))))
{
int rc, count = 0;
xEvent *xE = NULL;
if (!match || (grab->confineTo &&
(!grab->confineTo->realized ||
!BorderSizeNotEmpty(device, grab->confineTo))))
continue;
event->corestate &= 0x1f00;
event->corestate |= tempGrab.modifiersDetail.exact & (~0x1f00);
grabinfo = &device->deviceGrab;
/* In some cases a passive core grab may exist, but the client
* already has a core grab on some other device. In this case we
* must not get the grab, otherwise we may never ungrab the
* device.
*/
grabinfo = &device->deviceGrab;
/* In some cases a passive core grab may exist, but the client
* already has a core grab on some other device. In this case we
* must not get the grab, otherwise we may never ungrab the
* device.
*/
if (grab->grabtype == GRABTYPE_CORE)
if (grab->grabtype == GRABTYPE_CORE)
{
DeviceIntPtr other;
BOOL interfering = FALSE;
/* A passive grab may have been created for a different device
than it is assigned to at this point in time.
Update the grab's device and modifier device to reflect the
current state.
Since XGrabDeviceButton requires to specify the
modifierDevice explicitly, we don't override this choice.
*/
if (tempGrab.type < GenericEvent)
{
DeviceIntPtr other;
BOOL interfering = FALSE;
/* A passive grab may have been created for a different device
than it is assigned to at this point in time.
Update the grab's device and modifier device to reflect the
current state.
Since XGrabDeviceButton requires to specify the
modifierDevice explicitly, we don't override this choice.
*/
if (tempGrab.type < GenericEvent)
{
grab->device = device;
grab->modifierDevice = GetPairedDevice(device);
}
for (other = inputInfo.devices; other; other = other->next)
{
GrabPtr othergrab = other->deviceGrab.grab;
if (othergrab && othergrab->grabtype == GRABTYPE_CORE &&
SameClient(grab, rClient(othergrab)) &&
((IsPointerDevice(grab->device) &&
IsPointerDevice(othergrab->device)) ||
(IsKeyboardDevice(grab->device) &&
IsKeyboardDevice(othergrab->device))))
{
interfering = TRUE;
break;
}
}
if (interfering)
continue;
grab->device = device;
grab->modifierDevice = GetPairedDevice(device);
}
if (!activate)
return grab;
if (match & CORE_MATCH)
for (other = inputInfo.devices; other; other = other->next)
{
rc = EventToCore((InternalEvent*)event, &xE, &count);
if (rc != Success)
GrabPtr othergrab = other->deviceGrab.grab;
if (othergrab && othergrab->grabtype == GRABTYPE_CORE &&
SameClient(grab, rClient(othergrab)) &&
((IsPointerDevice(grab->device) &&
IsPointerDevice(othergrab->device)) ||
(IsKeyboardDevice(grab->device) &&
IsKeyboardDevice(othergrab->device))))
{
if (rc != BadMatch)
ErrorF("[dix] %s: core conversion failed in CPGFW "
"(%d, %d).\n", device->name, event->type, rc);
continue;
}
} else if (match & XI2_MATCH)
{
rc = EventToXI2((InternalEvent*)event, &xE);
if (rc != Success)
{
if (rc != BadMatch)
ErrorF("[dix] %s: XI2 conversion failed in CPGFW "
"(%d, %d).\n", device->name, event->type, rc);
continue;
}
count = 1;
} else
{
rc = EventToXI((InternalEvent*)event, &xE, &count);
if (rc != Success)
{
if (rc != BadMatch)
ErrorF("[dix] %s: XI conversion failed in CPGFW "
"(%d, %d).\n", device->name, event->type, rc);
continue;
interfering = TRUE;
break;
}
}
if (interfering)
continue;
}
(*grabinfo->ActivateGrab)(device, grab, currentTime, TRUE);
if (!activate)
{
return grab;
}
else if (!GetXIType(event) && !GetCoreType(event))
{
ErrorF("Event type %d in CheckPassiveGrabsOnWindow is neither"
" XI 1.x nor core\n", event->any.type);
return NULL;
}
if (xE)
/* The only consumers of corestate are Xi 1.x and core events, which
* are guaranteed to come from DeviceEvents. */
if (match & (XI_MATCH | CORE_MATCH))
{
event->device_event.corestate &= 0x1f00;
event->device_event.corestate |= tempGrab.modifiersDetail.exact &
(~0x1f00);
}
if (match & CORE_MATCH)
{
rc = EventToCore(event, &xE, &count);
if (rc != Success)
{
FixUpEventFromWindow(pSprite, xE, grab->window, None, TRUE);
/* XXX: XACE? */
TryClientEvents(rClient(grab), device, xE, count,
GetEventFilter(device, xE),
GetEventFilter(device, xE), grab);
if (rc != BadMatch)
ErrorF("[dix] %s: core conversion failed in CPGFW "
"(%d, %d).\n", device->name, event->any.type, rc);
continue;
}
if (grabinfo->sync.state == FROZEN_NO_EVENT)
{
if (!grabinfo->sync.event)
grabinfo->sync.event = calloc(1, sizeof(InternalEvent));
*grabinfo->sync.event = *event;
grabinfo->sync.state = FROZEN_WITH_EVENT;
} else if (match & XI2_MATCH)
{
rc = EventToXI2(event, &xE);
if (rc != Success)
{
if (rc != BadMatch)
ErrorF("[dix] %s: XI2 conversion failed in CPGFW "
"(%d, %d).\n", device->name, event->any.type, rc);
continue;
}
count = 1;
} else
{
rc = EventToXI(event, &xE, &count);
if (rc != Success)
{
if (rc != BadMatch)
ErrorF("[dix] %s: XI conversion failed in CPGFW "
"(%d, %d).\n", device->name, event->any.type, rc);
continue;
}
}
free(xE);
return grab;
}
(*grabinfo->ActivateGrab)(device, grab, currentTime, TRUE);
if (xE)
{
FixUpEventFromWindow(pSprite, xE, grab->window, None, TRUE);
/* XXX: XACE? */
TryClientEvents(rClient(grab), device, xE, count,
GetEventFilter(device, xE),
GetEventFilter(device, xE), grab);
}
if (grabinfo->sync.state == FROZEN_NO_EVENT)
{
if (!grabinfo->sync.event)
grabinfo->sync.event = calloc(1, sizeof(DeviceEvent));
*grabinfo->sync.event = event->device_event;
grabinfo->sync.state = FROZEN_WITH_EVENT;
}
free(xE);
return grab;
}
return NULL;
#undef CORE_MATCH
@ -3639,7 +3776,8 @@ CheckDeviceGrabs(DeviceIntPtr device, DeviceEvent *event, WindowPtr ancestor)
for (; i < focus->traceGood; i++)
{
pWin = focus->trace[i];
if (CheckPassiveGrabsOnWindow(pWin, device, event, sendCore, TRUE))
if (CheckPassiveGrabsOnWindow(pWin, device, (InternalEvent *) event,
sendCore, TRUE))
{
ret = TRUE;
goto out;
@ -3655,7 +3793,8 @@ CheckDeviceGrabs(DeviceIntPtr device, DeviceEvent *event, WindowPtr ancestor)
for (; i < device->spriteInfo->sprite->spriteTraceGood; i++)
{
pWin = device->spriteInfo->sprite->spriteTrace[i];
if (CheckPassiveGrabsOnWindow(pWin, device, event, sendCore, TRUE))
if (CheckPassiveGrabsOnWindow(pWin, device, (InternalEvent *) event,
sendCore, TRUE))
{
ret = TRUE;
goto out;
@ -3766,8 +3905,10 @@ unwind:
* grab. If not, TryClientEvents() is used.
*
* @param deactivateGrab True if the device's grab should be deactivated.
*
* @return The number of events delivered.
*/
void
int
DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev,
Bool deactivateGrab)
{
@ -3935,6 +4076,8 @@ DeliverGrabbedEvent(InternalEvent *event, DeviceIntPtr thisDev,
free(core);
free(xi);
free(xi2);
return deliveries;
}
/* This function is used to set the key pressed or key released state -
@ -4977,12 +5120,9 @@ InitEvents(void)
inputInfo.off_devices = (DeviceIntPtr)NULL;
inputInfo.keyboard = (DeviceIntPtr)NULL;
inputInfo.pointer = (DeviceIntPtr)NULL;
/* The mask for pointer motion events may have changed in the last server
* generation. See comment above definition of filters. */
filters[0][PointerMotionMask] = MotionNotify;
for (i = 1; i < MAXDEVICES; i++)
for (i = 0; i < MAXDEVICES; i++)
{
memcpy(&filters[i], filters[0], sizeof(filters[0]));
memcpy(&filters[i], default_filter, sizeof(default_filter));
}
syncEvents.replayDev = (DeviceIntPtr)NULL;
@ -5006,8 +5146,7 @@ InitEvents(void)
DontPropagateRefCnts[i] = 0;
}
InputEventListLen = GetMaximumEventsNum();
InputEventList = InitEventList(InputEventListLen);
InputEventList = InitEventList(GetMaximumEventsNum());
if (!InputEventList)
FatalError("[dix] Failed to allocate input event list.\n");
}
@ -5015,8 +5154,7 @@ InitEvents(void)
void
CloseDownEvents(void)
{
FreeEventList(InputEventList, InputEventListLen);
InputEventListLen = 0;
FreeEventList(InputEventList, GetMaximumEventsNum());
InputEventList = NULL;
}

View File

@ -47,6 +47,7 @@
#include "eventstr.h"
#include "eventconvert.h"
#include "inpututils.h"
#include "mi.h"
#include <X11/extensions/XKBproto.h>
#include "xkbsrv.h"
@ -67,19 +68,12 @@
/* Number of motion history events to store. */
#define MOTION_HISTORY_SIZE 256
/* InputEventList is the container list for all input events generated by the
* DDX. The DDX is expected to call GetEventList() and then pass the list into
* Get{Pointer|Keyboard}Events.
/**
* InputEventList is the storage for input events generated by
* QueuePointerEvents, QueueKeyboardEvents, and QueueProximityEvents.
* This list is allocated on startup by the DIX.
*/
EventListPtr InputEventList = NULL;
int InputEventListLen = 0;
int
GetEventList(EventListPtr* list)
{
*list = InputEventList;
return InputEventListLen;
}
InternalEvent* InputEventList = NULL;
/**
* Pick some arbitrary size for Xi motion history.
@ -223,7 +217,7 @@ set_valuators(DeviceIntPtr dev, DeviceEvent* event, ValuatorMask *mask)
}
void
CreateClassesChangedEvent(EventList* event,
CreateClassesChangedEvent(InternalEvent* event,
DeviceIntPtr master,
DeviceIntPtr slave,
int type)
@ -232,7 +226,7 @@ CreateClassesChangedEvent(EventList* event,
DeviceChangedEvent *dce;
CARD32 ms = GetTimeInMillis();
dce = (DeviceChangedEvent*)event->event;
dce = &event->changed_event;
memset(dce, 0, sizeof(DeviceChangedEvent));
dce->deviceid = slave->id;
dce->masterid = master->id;
@ -676,15 +670,15 @@ clipValuators(DeviceIntPtr pDev, ValuatorMask *mask)
* is done in the event processing).
* Pull in the coordinates from the MD if necessary.
*
* @param events Pointer to a pre-allocated event list.
* @param events Pointer to a pre-allocated event array.
* @param dev The slave device that generated an event.
* @param type Either DEVCHANGE_POINTER_EVENT and/or DEVCHANGE_KEYBOARD_EVENT
* @param num_events The current number of events, returns the number of
* events if a DCCE was generated.
* @return The updated @events pointer.
*/
EventListPtr
UpdateFromMaster(EventListPtr events, DeviceIntPtr dev, int type, int *num_events)
InternalEvent*
UpdateFromMaster(InternalEvent* events, DeviceIntPtr dev, int type, int *num_events)
{
DeviceIntPtr master;
@ -924,16 +918,49 @@ updateHistory(DeviceIntPtr dev, ValuatorMask *mask, CARD32 ms)
}
}
static void
queueEventList(DeviceIntPtr device, InternalEvent *events, int nevents)
{
int i;
for (i = 0; i < nevents; i++)
mieqEnqueue(device, &events[i]);
}
/**
* Generate internal events representing this keyboard event and enqueue
* them on the event queue.
*
* This function is not reentrant. Disable signals before calling.
*
* FIXME: flags for relative/abs motion?
*
* @param device The device to generate the event for
* @param type Event type, one of KeyPress or KeyRelease
* @param keycode Key code of the pressed/released key
* @param mask Valuator mask for valuators present for this event.
*
*/
void
QueueKeyboardEvents(DeviceIntPtr device, int type,
int keycode, const ValuatorMask *mask)
{
int nevents;
nevents = GetKeyboardEvents(InputEventList, device, type, keycode, mask);
queueEventList(device, InputEventList, nevents);
}
/**
* Returns a set of InternalEvents for KeyPress/KeyRelease, optionally
* also with valuator events.
*
* events is not NULL-terminated; the return value is the number of events.
* The DDX is responsible for allocating the event structure in the first
* place via GetMaximumEventsNum(), and for freeing it.
* The DDX is responsible for allocating the event list in the first
* place via InitEventList(), and for freeing it.
*
* @return the number of events written into events.
*/
int
GetKeyboardEvents(EventList *events, DeviceIntPtr pDev, int type,
GetKeyboardEvents(InternalEvent *events, DeviceIntPtr pDev, int type,
int key_code, const ValuatorMask *mask_in) {
int num_events = 0;
CARD32 ms = 0;
@ -966,7 +993,7 @@ GetKeyboardEvents(EventList *events, DeviceIntPtr pDev, int type,
ms = GetTimeInMillis();
raw = (RawDeviceEvent*)events->event;
raw = &events->raw_event;
events++;
num_events++;
@ -979,7 +1006,7 @@ GetKeyboardEvents(EventList *events, DeviceIntPtr pDev, int type,
set_raw_valuators(raw, &mask, raw->valuators.data);
event = (DeviceEvent*) events->event;
event = &events->device_event;
init_event(pDev, event, ms);
event->detail.key = key_code;
@ -1000,37 +1027,16 @@ GetKeyboardEvents(EventList *events, DeviceIntPtr pDev, int type,
}
/**
* Initialize an event list and fill with 32 byte sized events.
* Initialize an event array large enough for num_events arrays.
* This event list is to be passed into GetPointerEvents() and
* GetKeyboardEvents().
*
* @param num_events Number of elements in list.
*/
EventListPtr
InternalEvent*
InitEventList(int num_events)
{
EventListPtr events;
int i;
events = (EventListPtr)calloc(num_events, sizeof(EventList));
if (!events)
return NULL;
for (i = 0; i < num_events; i++)
{
events[i].evlen = sizeof(InternalEvent);
events[i].event = calloc(1, sizeof(InternalEvent));
if (!events[i].event)
{
/* rollback */
while(i--)
free(events[i].event);
free(events);
events = NULL;
break;
}
}
InternalEvent *events = calloc(num_events, sizeof(InternalEvent));
return events;
}
@ -1041,41 +1047,50 @@ InitEventList(int num_events)
* @param num_events Number of elements in list.
*/
void
FreeEventList(EventListPtr list, int num_events)
FreeEventList(InternalEvent *list, int num_events)
{
if (!list)
return;
while(num_events--)
free(list[num_events].event);
free(list);
}
static void
transformAbsolute(DeviceIntPtr dev, ValuatorMask *mask)
transformAbsolute(DeviceIntPtr dev, ValuatorMask *mask, int *x, int *y)
{
struct pixman_f_vector p;
/* p' = M * p in homogeneous coordinates */
p.v[0] = (valuator_mask_isset(mask, 0) ? valuator_mask_get(mask, 0) :
dev->last.valuators[0]);
p.v[1] = (valuator_mask_isset(mask, 1) ? valuator_mask_get(mask, 1) :
dev->last.valuators[1]);
p.v[2] = 1.0;
struct pixman_f_vector p = {.v = {*x, *y, 1}};
pixman_f_transform_point(&dev->transform, &p);
if (lround(p.v[0]) != dev->last.valuators[0])
valuator_mask_set(mask, 0, lround(p.v[0]));
if (lround(p.v[1]) != dev->last.valuators[1])
valuator_mask_set(mask, 1, lround(p.v[1]));
*x = lround(p.v[0]);
*y = lround(p.v[1]);
}
/**
* Generate a series of InternalEvents (filled into the EventList)
* representing pointer motion, or button presses.
* Generate internal events representing this pointer event and enqueue them
* on the event queue.
*
* events is not NULL-terminated; the return value is the number of events.
* The DDX is responsible for allocating the event structure in the first
* This function is not reentrant. Disable signals before calling.
*
* @param device The device to generate the event for
* @param type Event type, one of ButtonPress, ButtonRelease, MotionNotify
* @param buttons Button number of the buttons modified. Must be 0 for
* MotionNotify
* @param flags Event modification flags
* @param mask Valuator mask for valuators present for this event.
*/
void
QueuePointerEvents(DeviceIntPtr device, int type,
int buttons, int flags, const ValuatorMask *mask)
{
int nevents;
nevents = GetPointerEvents(InputEventList, device, type, buttons, flags, mask);
queueEventList(device, InputEventList, nevents);
}
/**
* Generate a series of InternalEvents representing pointer motion, or
* button presses.
*
* The DDX is responsible for allocating the events in the first
* place via InitEventList() and GetMaximumEventsNum(), and for freeing it.
*
* In the generated events rootX/Y will be in absolute screen coords and
@ -1085,9 +1100,11 @@ transformAbsolute(DeviceIntPtr dev, ValuatorMask *mask)
* last.valuators[x] of the master device is in absolute screen coords.
*
* master->last.valuators[x] for x > 2 is undefined.
*
* @return the number of events written into events.
*/
int
GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
GetPointerEvents(InternalEvent *events, DeviceIntPtr pDev, int type, int buttons,
int flags, const ValuatorMask *mask_in) {
int num_events = 1;
CARD32 ms;
@ -1125,7 +1142,7 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
events = UpdateFromMaster(events, pDev, DEVCHANGE_POINTER_EVENT, &num_events);
raw = (RawDeviceEvent*)events->event;
raw = &events->raw_event;
events++;
num_events++;
@ -1158,7 +1175,16 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
}
}
transformAbsolute(pDev, &mask);
x = (valuator_mask_isset(&mask, 0) ? valuator_mask_get(&mask, 0) :
pDev->last.valuators[0]);
y = (valuator_mask_isset(&mask, 1) ? valuator_mask_get(&mask, 1) :
pDev->last.valuators[1]);
transformAbsolute(pDev, &mask, &x, &y);
if (valuator_mask_isset(&mask, 0))
valuator_mask_set(&mask, 0, x);
if (valuator_mask_isset(&mask, 1))
valuator_mask_set(&mask, 1, y);
moveAbsolute(pDev, &x, &y, &mask);
} else {
if (flags & POINTER_ACCELERATE) {
@ -1185,7 +1211,7 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
clipValuators(pDev, &mask);
event = (DeviceEvent*) events->event;
event = &events->device_event;
init_event(pDev, event, ms);
if (type == MotionNotify) {
@ -1214,17 +1240,39 @@ GetPointerEvents(EventList *events, DeviceIntPtr pDev, int type, int buttons,
return num_events;
}
/**
* Generate internal events representing this proximity event and enqueue
* them on the event queue.
*
* This function is not reentrant. Disable signals before calling.
*
* @param device The device to generate the event for
* @param type Event type, one of ProximityIn or ProximityOut
* @param keycode Key code of the pressed/released key
* @param mask Valuator mask for valuators present for this event.
*
*/
void
QueueProximityEvents(DeviceIntPtr device, int type,
const ValuatorMask *mask)
{
int nevents;
nevents = GetProximityEvents(InputEventList, device, type, mask);
queueEventList(device, InputEventList, nevents);
}
/**
* Generate ProximityIn/ProximityOut InternalEvents, accompanied by
* valuators.
*
* events is not NULL-terminated; the return value is the number of events.
* The DDX is responsible for allocating the event structure in the first
* place via GetMaximumEventsNum(), and for freeing it.
* The DDX is responsible for allocating the events in the first place via
* InitEventList(), and for freeing it.
*
* @return the number of events written into events.
*/
int
GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type, const ValuatorMask *mask_in)
GetProximityEvents(InternalEvent *events, DeviceIntPtr pDev, int type, const ValuatorMask *mask_in)
{
int num_events = 1, i;
DeviceEvent *event;
@ -1256,7 +1304,7 @@ GetProximityEvents(EventList *events, DeviceIntPtr pDev, int type, const Valuato
events = UpdateFromMaster(events, pDev, DEVCHANGE_POINTER_EVENT, &num_events);
event = (DeviceEvent *) events->event;
event = &events->device_event;
init_event(pDev, event, GetTimeInMillis());
event->type = (type == ProximityIn) ? ET_ProximityIn : ET_ProximityOut;

View File

@ -36,6 +36,7 @@
#include "xkbsrv.h"
#include "xkbstr.h"
#include "inpututils.h"
#include "eventstr.h"
/* Check if a button map change is okay with the device.
* Returns -1 for BadValue, as it collides with MappingBusy. */
@ -556,3 +557,30 @@ CountBits(const uint8_t *mask, int len)
return ret;
}
/**
* Verifies sanity of the event. If the event is not an internal event,
* memdumps the first 32 bytes of event to the log, a backtrace, then kill
* the server.
*/
void verify_internal_event(const InternalEvent *ev)
{
if (ev && ev->any.header != ET_Internal)
{
int i;
unsigned char *data = (unsigned char*)ev;
ErrorF("dix: invalid event type %d\n", ev->any.header);
for (i = 0; i < sizeof(xEvent); i++, data++)
{
ErrorF("%02hx ", *data);
if ((i % 8) == 7)
ErrorF("\n");
}
xorg_backtrace();
FatalError("Wrong event type %d. Aborting server\n", ev->any.header);
}
}

View File

@ -176,19 +176,15 @@ static void enqueueMotion(DevicePtr pDev, int x, int y)
{
GETDMXLOCALFROMPDEV;
DeviceIntPtr p = dmxLocal->pDevice;
int i, nevents, valuators[3];
EventListPtr events;
int valuators[3];
int detail = 0; /* XXX should this be mask of pressed buttons? */
ValuatorMask mask;
valuators[0] = x;
valuators[1] = y;
valuator_mask_set_range(&mask, 0, 2, valuators);
GetEventList(&events);
nevents = GetPointerEvents(events, p, MotionNotify, detail,
POINTER_ABSOLUTE | POINTER_SCREEN, &mask);
for (i = 0; i < nevents; i++)
mieqEnqueue(p, (InternalEvent*)(events + i)->event);
QueuePointerEvents(p, MotionNotify, detail,
POINTER_ABSOLUTE | POINTER_SCREEN, &mask);
return;
}
@ -291,10 +287,7 @@ static void dmxExtMotion(DMXLocalInputInfoPtr dmxLocal,
deviceValuator *xv = (deviceValuator *)xev+1;
int thisX = 0;
int thisY = 0;
int i;
int count;
EventListPtr events;
int nevents;
ValuatorMask mask;
memset(xE, 0, sizeof(xE));
@ -348,6 +341,7 @@ static void dmxExtMotion(DMXLocalInputInfoPtr dmxLocal,
}
count = 2;
} else {
int i;
for (i = 0, count = 0; i < axesCount; i += 6) {
xev->time = GetTimeInMillis();
xev->type = DeviceMotionNotify;
@ -375,11 +369,8 @@ static void dmxExtMotion(DMXLocalInputInfoPtr dmxLocal,
if (block)
dmxSigioBlock();
valuator_mask_set_range(&mask, firstAxis, axesCount, v);
GetEventList(&events);
nevents = GetPointerEvents(events, pDevice, MotionNotify, 0,
POINTER_ABSOLUTE, &mask);
for (i = 0; i < nevents; i++)
mieqEnqueue(pDevice, (InternalEvent*)(events + i)->event);
QueuePointerEvents(pDevice, MotionNotify, 0,
POINTER_ABSOLUTE, &mask);
if (block)
dmxSigioUnblock();
@ -394,8 +385,6 @@ static int dmxTranslateAndEnqueueExtEvent(DMXLocalInputInfoPtr dmxLocal,
XDeviceMotionEvent *me = (XDeviceMotionEvent *)e;
DeviceIntPtr pDevice = dmxLocal->pDevice;
int valuators[MAX_VALUATORS];
EventListPtr events;
int nevents, i;
ValuatorMask mask;
if (!e)
@ -452,12 +441,7 @@ static int dmxTranslateAndEnqueueExtEvent(DMXLocalInputInfoPtr dmxLocal,
valuator_mask_set_range(&mask, ke->first_axis, ke->axes_count, valuators);
if (block)
dmxSigioBlock();
GetEventList(&events);
nevents = GetKeyboardEvents(events, pDevice, event,
ke->keycode, &mask);
for (i = 0; i < nevents; i++)
mieqEnqueue(pDevice, (InternalEvent*)(events + i)->event);
QueueKeyboardEvents(pDevice, event, ke->keycode, &mask);
if (block)
dmxSigioUnblock();
break;
@ -467,12 +451,8 @@ static int dmxTranslateAndEnqueueExtEvent(DMXLocalInputInfoPtr dmxLocal,
valuator_mask_set_range(&mask, ke->first_axis, ke->axes_count, valuators);
if (block)
dmxSigioBlock();
GetEventList(&events);
nevents = GetPointerEvents(events, pDevice, event, ke->keycode,
POINTER_ABSOLUTE, &mask);
for (i = 0; i < nevents; i++)
mieqEnqueue(pDevice, (InternalEvent*)(events + i)->event);
QueuePointerEvents(pDevice, event, ke->keycode,
POINTER_ABSOLUTE, &mask);
if (block)
dmxSigioUnblock();
break;
@ -482,11 +462,7 @@ static int dmxTranslateAndEnqueueExtEvent(DMXLocalInputInfoPtr dmxLocal,
valuator_mask_set_range(&mask, ke->first_axis, ke->axes_count, valuators);
if (block)
dmxSigioBlock();
GetEventList(&events);
nevents = GetProximityEvents(events, pDevice, event, &mask);
for (i = 0; i < nevents; i++)
mieqEnqueue(pDevice, (InternalEvent*)(events + i)->event);
QueueProximityEvents(pDevice, event, &mask);
if (block)
dmxSigioUnblock();
break;
@ -667,8 +643,7 @@ void dmxEnqueue(DevicePtr pDev, int type, int detail, KeySym keySym,
GETDMXINPUTFROMPDEV;
xEvent xE;
DeviceIntPtr p = dmxLocal->pDevice;
int i, nevents, valuators[3];
EventListPtr events;
int valuators[3];
ValuatorMask mask;
DMXDBG2("dmxEnqueue: Enqueuing type=%d detail=0x%0x\n", type, detail);
@ -683,34 +658,25 @@ void dmxEnqueue(DevicePtr pDev, int type, int detail, KeySym keySym,
if (dmxLocal->sendsCore && dmxLocal != dmxLocalCoreKeyboard)
xE.u.u.detail = dmxFixup(pDev, detail, keySym);
GetEventList(&events);
/*ErrorF("KEY %d sym %d\n", detail, (int) keySym);*/
nevents = GetKeyboardEvents(events, p, type, detail, NULL);
for (i = 0; i < nevents; i++)
mieqEnqueue(p, (InternalEvent*)(events + i)->event);
QueueKeyboardEvents(p, type, detail, NULL);
return;
case ButtonPress:
case ButtonRelease:
detail = dmxGetButtonMapping(dmxLocal, detail);
valuator_mask_zero(&mask);
GetEventList(&events);
nevents = GetPointerEvents(events, p, type, detail,
POINTER_ABSOLUTE | POINTER_SCREEN, &mask);
for (i = 0; i < nevents; i++)
mieqEnqueue(p, (InternalEvent*)(events + i)->event);
QueuePointerEvents(p, type, detail,
POINTER_ABSOLUTE | POINTER_SCREEN, &mask);
return;
case MotionNotify:
GetEventList(&events);
valuators[0] = e->xmotion.x;
valuators[1] = e->xmotion.y;
valuators[2] = e->xmotion.state; /* FIXME: WTF?? */
valuator_mask_set_range(&mask, 0, 3, valuators);
nevents = GetPointerEvents(events, p, type, detail,
POINTER_ABSOLUTE | POINTER_SCREEN, &mask);
for (i = 0; i < nevents; i++)
mieqEnqueue(p, (InternalEvent*)(events + i)->event);
QueuePointerEvents(p, type, detail,
POINTER_ABSOLUTE | POINTER_SCREEN, &mask);
return;
case EnterNotify:

View File

@ -66,8 +66,6 @@ static struct KdConfigDevice *kdConfigPointers = NULL;
static KdKeyboardDriver *kdKeyboardDrivers = NULL;
static KdPointerDriver *kdPointerDrivers = NULL;
static EventListPtr kdEvents = NULL;
static Bool kdInputEnabled;
static Bool kdOffScreen;
static unsigned long kdOffScreenTime;
@ -1793,7 +1791,7 @@ void
KdReleaseAllKeys (void)
{
#if 0
int key, nEvents, i;
int key;
KdKeyboardInfo *ki;
KdBlockSigio ();
@ -1803,10 +1801,7 @@ KdReleaseAllKeys (void)
key++) {
if (key_is_down(ki->dixdev, key, KEY_POSTED | KEY_PROCESSED)) {
KdHandleKeyboardEvent(ki, KeyRelease, key);
GetEventList(&kdEvents);
nEvents = GetKeyboardEvents(kdEvents, ki->dixdev, KeyRelease, key, NULL);
for (i = 0; i < nEvents; i++)
KdQueueEvent (ki->dixdev, (kdEvents + i)->event);
QueueGetKeyboardEvents(ki->dixdev, KeyRelease, key, NULL);
}
}
}
@ -1842,7 +1837,7 @@ KdEnqueueKeyboardEvent(KdKeyboardInfo *ki,
unsigned char key_code;
KeyClassPtr keyc = NULL;
KeybdCtrl *ctrl = NULL;
int type, nEvents, i;
int type;
if (!ki || !ki->dixdev || !ki->dixdev->kbdfeed || !ki->dixdev->key)
return;
@ -1862,11 +1857,7 @@ KdEnqueueKeyboardEvent(KdKeyboardInfo *ki,
else
type = KeyPress;
GetEventList(&kdEvents);
nEvents = GetKeyboardEvents(kdEvents, ki->dixdev, type, key_code, NULL);
for (i = 0; i < nEvents; i++)
KdQueueEvent(ki->dixdev, (InternalEvent *)((kdEvents + i)->event));
QueueKeyboardEvents(ki->dixdev, type, key_code, NULL);
}
else {
ErrorF("driver %s wanted to post scancode %d outside of [%d, %d]!\n",
@ -1965,7 +1956,6 @@ void
_KdEnqueuePointerEvent (KdPointerInfo *pi, int type, int x, int y, int z,
int b, int absrel, Bool force)
{
int nEvents = 0, i = 0;
int valuators[3] = { x, y, z };
ValuatorMask mask;
@ -1975,10 +1965,7 @@ _KdEnqueuePointerEvent (KdPointerInfo *pi, int type, int x, int y, int z,
valuator_mask_set_range(&mask, 0, 3, valuators);
GetEventList(&kdEvents);
nEvents = GetPointerEvents(kdEvents, pi->dixdev, type, b, absrel, &mask);
for (i = 0; i < nEvents; i++)
KdQueueEvent(pi->dixdev, (InternalEvent *)((kdEvents + i)->event));
QueuePointerEvents(pi->dixdev, type, b, absrel, &mask);
}
void

View File

@ -376,7 +376,7 @@ static void
xf86ReleaseKeys(DeviceIntPtr pDev)
{
KeyClassPtr keyc;
int i, j, nevents, sigstate;
int i, sigstate;
if (!pDev || !pDev->key)
return;
@ -399,9 +399,7 @@ xf86ReleaseKeys(DeviceIntPtr pDev)
i++) {
if (key_is_down(pDev, i, KEY_POSTED)) {
sigstate = xf86BlockSIGIO ();
nevents = GetKeyboardEvents(xf86Events, pDev, KeyRelease, i, NULL);
for (j = 0; j < nevents; j++)
mieqEnqueue(pDev, (InternalEvent*)(xf86Events + j)->event);
QueueKeyboardEvents(pDev, KeyRelease, i, NULL);
xf86UnblockSIGIO(sigstate);
}
}

View File

@ -806,8 +806,6 @@ InitInput(int argc, char **argv)
mieqInit();
GetEventList(&xf86Events);
/* Initialize all configured input devices */
for (pDev = xf86ConfigLayout.inputs; pDev && *pDev; pDev++) {
/* Replace obsolete keyboard driver with kbd */

View File

@ -148,9 +148,6 @@ extern _X_EXPORT int xf86SetVerbosity(int verb);
extern _X_EXPORT int xf86SetLogVerbosity(int verb);
extern _X_EXPORT Bool xf86CallDriverProbe( struct _DriverRec * drv, Bool detect_only );
/* xf86Xinput.c */
extern _X_EXPORT EventList *xf86Events;
#endif /* _NO_XF86_PROTOTYPES */

View File

@ -99,8 +99,6 @@
return; \
}
EventListPtr xf86Events = NULL;
static int
xf86InputDevicePostInit(DeviceIntPtr dev);
@ -329,8 +327,8 @@ xf86ActivateDevice(InputInfoPtr pInfo)
dev->config_info = xf86SetStrOption(pInfo->options, "config_info", NULL);
if (serverGeneration == 1)
xf86Msg(X_INFO, "XINPUT: Adding extended input device \"%s\" (type: %s)\n",
pInfo->name, pInfo->type_name);
xf86Msg(X_INFO, "XINPUT: Adding extended input device \"%s\" (type: %s, id %d)\n",
pInfo->name, pInfo->type_name, dev->id);
return dev;
}
@ -1012,7 +1010,6 @@ xf86PostMotionEventM(DeviceIntPtr device,
int is_absolute,
const ValuatorMask *mask)
{
int i = 0, nevents = 0;
int flags = 0;
if (valuator_mask_num_valuators(mask) > 0)
@ -1050,11 +1047,7 @@ xf86PostMotionEventM(DeviceIntPtr device,
}
#endif
nevents = GetPointerEvents(xf86Events, device, MotionNotify, 0, flags, mask);
for (i = 0; i < nevents; i++) {
mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event));
}
QueuePointerEvents(device, MotionNotify, 0, flags, mask);
}
void
@ -1099,13 +1092,7 @@ xf86PostProximityEventM(DeviceIntPtr device,
int is_in,
const ValuatorMask *mask)
{
int i, nevents;
nevents = GetProximityEvents(xf86Events, device,
is_in ? ProximityIn : ProximityOut, mask);
for (i = 0; i < nevents; i++)
mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event));
QueueProximityEvents(device, is_in ? ProximityIn : ProximityOut, mask);
}
void
@ -1157,7 +1144,6 @@ xf86PostButtonEventM(DeviceIntPtr device,
int is_down,
const ValuatorMask *mask)
{
int i = 0, nevents = 0;
int flags = 0;
if (valuator_mask_num_valuators(mask) > 0)
@ -1177,13 +1163,9 @@ xf86PostButtonEventM(DeviceIntPtr device,
}
#endif
nevents = GetPointerEvents(xf86Events, device,
is_down ? ButtonPress : ButtonRelease, button,
flags, mask);
for (i = 0; i < nevents; i++)
mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event));
QueuePointerEvents(device,
is_down ? ButtonPress : ButtonRelease, button,
flags, mask);
}
void
@ -1235,8 +1217,6 @@ xf86PostKeyEventM(DeviceIntPtr device,
int is_absolute,
const ValuatorMask *mask)
{
int i = 0, nevents = 0;
#if XFreeXDGA
DeviceIntPtr pointer;
@ -1250,12 +1230,9 @@ xf86PostKeyEventM(DeviceIntPtr device,
}
#endif
nevents = GetKeyboardEvents(xf86Events, device,
is_down ? KeyPress : KeyRelease,
key_code, mask);
for (i = 0; i < nevents; i++)
mieqEnqueue(device, (InternalEvent*)((xf86Events + i)->event));
QueueKeyboardEvents(device,
is_down ? KeyPress : KeyRelease,
key_code, mask);
}
void

View File

@ -43,8 +43,6 @@ is" without express or implied warranty.
CARD32 lastEventTime = 0;
extern EventList *xnestEvents;
void
ProcessInputEvents(void)
{
@ -104,23 +102,17 @@ xnestCollectExposures(void)
void
xnestQueueKeyEvent(int type, unsigned int keycode)
{
int i, n;
GetEventList(&xnestEvents);
lastEventTime = GetTimeInMillis();
n = GetKeyboardEvents(xnestEvents, xnestKeyboardDevice, type, keycode, NULL);
for (i = 0; i < n; i++)
mieqEnqueue(xnestKeyboardDevice, (InternalEvent*)(xnestEvents + i)->event);
QueueKeyboardEvents(xnestKeyboardDevice, type, keycode, NULL);
}
void
xnestCollectEvents(void)
{
XEvent X;
int i, n, valuators[2];
int valuators[2];
ValuatorMask mask;
ScreenPtr pScreen;
GetEventList(&xnestEvents);
while (XCheckIfEvent(xnestDisplay, &X, xnestNotExposurePredicate, NULL)) {
switch (X.type) {
@ -138,20 +130,16 @@ xnestCollectEvents(void)
valuator_mask_set_range(&mask, 0, 0, NULL);
xnestUpdateModifierState(X.xkey.state);
lastEventTime = GetTimeInMillis();
n = GetPointerEvents(xnestEvents, xnestPointerDevice, ButtonPress,
X.xbutton.button, POINTER_RELATIVE, &mask);
for (i = 0; i < n; i++)
mieqEnqueue(xnestPointerDevice, (InternalEvent*)(xnestEvents + i)->event);
QueuePointerEvents(xnestPointerDevice, ButtonPress,
X.xbutton.button, POINTER_RELATIVE, &mask);
break;
case ButtonRelease:
valuator_mask_set_range(&mask, 0, 0, NULL);
xnestUpdateModifierState(X.xkey.state);
lastEventTime = GetTimeInMillis();
n = GetPointerEvents(xnestEvents, xnestPointerDevice, ButtonRelease,
X.xbutton.button, POINTER_RELATIVE, &mask);
for (i = 0; i < n; i++)
mieqEnqueue(xnestPointerDevice, (InternalEvent*)(xnestEvents + i)->event);
QueuePointerEvents(xnestPointerDevice, ButtonRelease,
X.xbutton.button, POINTER_RELATIVE, &mask);
break;
case MotionNotify:
@ -159,10 +147,8 @@ xnestCollectEvents(void)
valuators[1] = X.xmotion.y;
valuator_mask_set_range(&mask, 0, 2, valuators);
lastEventTime = GetTimeInMillis();
n = GetPointerEvents(xnestEvents, xnestPointerDevice, MotionNotify,
0, POINTER_ABSOLUTE, &mask);
for (i = 0; i < n; i++)
mieqEnqueue(xnestPointerDevice, (InternalEvent*)(xnestEvents + i)->event);
QueuePointerEvents(xnestPointerDevice, MotionNotify,
0, POINTER_ABSOLUTE, &mask);
break;
case FocusIn:
@ -193,10 +179,8 @@ xnestCollectEvents(void)
valuators[1] = X.xcrossing.y;
valuator_mask_set_range(&mask, 0, 2, valuators);
lastEventTime = GetTimeInMillis();
n = GetPointerEvents(xnestEvents, xnestPointerDevice, MotionNotify,
0, POINTER_ABSOLUTE, &mask);
for (i = 0; i < n; i++)
mieqEnqueue(xnestPointerDevice, (InternalEvent*)(xnestEvents + i)->event);
QueuePointerEvents(xnestPointerDevice, MotionNotify,
0, POINTER_ABSOLUTE, &mask);
xnestDirectInstallColormaps(pScreen);
}
}

View File

@ -45,8 +45,6 @@ is" without express or implied warranty.
Bool xnestDoFullGeneration = True;
EventList *xnestEvents = NULL;
void
InitOutput(ScreenInfo *screenInfo, int argc, char *argv[])
{
@ -100,8 +98,6 @@ InitInput(int argc, char *argv[])
if (rc != Success)
FatalError("Failed to init Xnest default devices.\n");
GetEventList(&xnestEvents);
mieqInit();
AddEnabledDevice(XConnectionNumber(xnestDisplay));

View File

@ -88,7 +88,7 @@ static pthread_mutex_t fd_add_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t fd_add_ready_cond = PTHREAD_COND_INITIALIZER;
static pthread_t fd_add_tid = NULL;
static EventListPtr darwinEvents = NULL;
static InternalEvent* darwinEvents = NULL;
static pthread_mutex_t mieq_lock = PTHREAD_MUTEX_INITIALIZER;
static pthread_cond_t mieq_ready_cond = PTHREAD_COND_INITIALIZER;
@ -433,7 +433,6 @@ static void DarwinPrepareValuators(DeviceIntPtr pDev, int *valuators, ScreenPtr
void DarwinSendPointerEvents(DeviceIntPtr pDev, int ev_type, int ev_button, float pointer_x, float pointer_y,
float pressure, float tilt_x, float tilt_y) {
static int darwinFakeMouseButtonDown = 0;
int i, num_events;
ScreenPtr screen;
int valuators[5];
@ -486,15 +485,12 @@ void DarwinSendPointerEvents(DeviceIntPtr pDev, int ev_type, int ev_button, floa
darwinEvents_lock(); {
ValuatorMask mask;
valuator_mask_set_range(&mask, 0, (pDev == darwinPointer) ? 2 : 5, valuators);
num_events = GetPointerEvents(darwinEvents, pDev, ev_type, ev_button,
POINTER_ABSOLUTE, &mask);
for(i=0; i<num_events; i++) mieqEnqueue (pDev, (InternalEvent*)darwinEvents[i].event);
if(num_events > 0) DarwinPokeEQ();
QueuePointerEvents(pDev, ev_type, ev_button, POINTER_ABSOLUTE, &mask);
DarwinPokeEQ();
} darwinEvents_unlock();
}
void DarwinSendKeyboardEvents(int ev_type, int keycode) {
int i, num_events;
if(!darwinEvents) {
DEBUG_LOG("DarwinSendKeyboardEvents called before darwinEvents was initialized\n");
@ -502,15 +498,13 @@ void DarwinSendKeyboardEvents(int ev_type, int keycode) {
}
darwinEvents_lock(); {
num_events = GetKeyboardEvents(darwinEvents, darwinKeyboard, ev_type, keycode + MIN_KEYCODE, NULL);
for(i=0; i<num_events; i++) mieqEnqueue(darwinKeyboard, (InternalEvent*)darwinEvents[i].event);
if(num_events > 0) DarwinPokeEQ();
QueueKeyboardEvents(darwinKeyboard, ev_type, keycode + MIN_KEYCODE, NULL);
DarwinPokeEQ();
} darwinEvents_unlock();
}
void DarwinSendProximityEvents(DeviceIntPtr pDev, int ev_type, float pointer_x, float pointer_y,
float pressure, float tilt_x, float tilt_y) {
int i, num_events;
ScreenPtr screen;
int valuators[5];
@ -531,9 +525,8 @@ void DarwinSendProximityEvents(DeviceIntPtr pDev, int ev_type, float pointer_x,
darwinEvents_lock(); {
ValuatorMask mask;
valuator_mask_set_range(&mask, 0, 5, valuators);
num_events = GetProximityEvents(darwinEvents, pDev, ev_type, &mask);
for(i=0; i<num_events; i++) mieqEnqueue (pDev, (InternalEvent*)darwinEvents[i].event);
if(num_events > 0) DarwinPokeEQ();
QueueProximityEvents(pDev, ev_type, &mask);
DarwinPokeEQ();
} darwinEvents_unlock();
}

View File

@ -472,8 +472,7 @@ winKeybdReleaseKeys (void)
void
winSendKeyEvent (DWORD dwKey, Bool fDown)
{
EventListPtr events;
int i, nevents;
InternalEvent* events;
/*
* When alt-tabing between screens we can get phantom key up messages
@ -484,11 +483,7 @@ winSendKeyEvent (DWORD dwKey, Bool fDown)
/* Update the keyState map */
g_winKeyState[dwKey] = fDown;
GetEventList(&events);
nevents = GetKeyboardEvents(events, g_pwinKeyboard, fDown ? KeyPress : KeyRelease, dwKey + MIN_KEYCODE, NULL);
for (i = 0; i < nevents; i++)
mieqEnqueue(g_pwinKeyboard, (InternalEvent*)events[i].event);
QueueKeyboardEvents(g_pwinKeyboard, fDown ? KeyPress : KeyRelease, dwKey + MIN_KEYCODE, NULL);
winDebug("winSendKeyEvent: dwKey: %d, fDown: %d, nEvents %d\n",
dwKey, fDown, nevents);

View File

@ -234,20 +234,14 @@ winMouseWheel (ScreenPtr pScreen, int iDeltaZ)
void
winMouseButtonsSendEvent (int iEventType, int iButton)
{
EventListPtr events;
int i, nevents;
ValuatorMask mask;
if (g_winMouseButtonMap)
iButton = g_winMouseButtonMap[iButton];
valuator_mask_zero(&mask);
GetEventList(&events);
nevents = GetPointerEvents(events, g_pwinPointer, iEventType, iButton,
POINTER_RELATIVE, &mask);
for (i = 0; i < nevents; i++)
mieqEnqueue(g_pwinPointer, (InternalEvent*)events[i].event);
QueuePointerEvents(g_pwinPointer, iEventType, iButton,
POINTER_RELATIVE, &mask);
#if CYGDEBUG
ErrorF("winMouseButtonsSendEvent: iEventType: %d, iButton: %d, nEvents %d\n",
@ -367,20 +361,15 @@ winMouseButtonsHandle (ScreenPtr pScreen,
*/
void winEnqueueMotion(int x, int y)
{
int i, nevents;
int valuators[2];
ValuatorMask mask;
EventListPtr events;
miPointerSetPosition(g_pwinPointer, POINTER_RELATIVE, &x, &y);
valuators[0] = x;
valuators[1] = y;
valuator_mask_set_range(&mask, 0, 2, valuators);
GetEventList(&events);
nevents = GetPointerEvents(events, g_pwinPointer, MotionNotify, 0,
POINTER_ABSOLUTE | POINTER_SCREEN, &mask);
QueuePointerEvents(g_pwinPointer, MotionNotify, 0,
POINTER_ABSOLUTE | POINTER_SCREEN, &mask);
for (i = 0; i < nevents; i++)
mieqEnqueue(g_pwinPointer, (InternalEvent*)events[i].event);
}

View File

@ -375,7 +375,7 @@ extern void ReleaseActiveGrabs(
extern GrabPtr CheckPassiveGrabsOnWindow(
WindowPtr /* pWin */,
DeviceIntPtr /* device */,
DeviceEvent * /* event */,
InternalEvent * /* event */,
BOOL /* checkCore */,
BOOL /* activate */);
@ -415,7 +415,7 @@ extern void DeliverFocusedEvent(
InternalEvent* /* event */,
WindowPtr /* window */);
extern void DeliverGrabbedEvent(
extern int DeliverGrabbedEvent(
InternalEvent* /* event */,
DeviceIntPtr /* thisDev */,
Bool /* deactivateGrab */);

View File

@ -68,10 +68,6 @@ enum EventType {
ET_Internal = 0xFF /* First byte */
};
#define CHECKEVENT(ev) if (ev && ((InternalEvent*)(ev))->any.header != 0xFF) \
FatalError("Wrong event type %d.\n", \
((InternalEvent*)(ev))->any.header);
/**
* Used for ALL input device events internal in the server until
* copied into the matching protocol event.

View File

@ -109,19 +109,8 @@ typedef union _GrabMask GrabMask;
typedef struct _ValuatorMask ValuatorMask;
typedef struct _EventList {
xEvent* event;
int evlen; /* length of allocated memory for event in bytes. This is not
the actual length of the event. The event's actual length is
32 for standard events or 32 +
((xGenericEvent*)event)->length * 4 for GenericEvents.
For events in the EQ, the length is
((InternalEvent*)event)->u.any.length */
} EventList, *EventListPtr;
/* The DIX stores incoming input events in this list */
extern EventListPtr InputEventList;
extern int InputEventListLen;
extern InternalEvent* InputEventList;
typedef int (*DeviceProc)(
DeviceIntPtr /*device*/,
@ -439,22 +428,28 @@ extern _X_EXPORT void CloseInput(void);
extern _X_EXPORT int GetMaximumEventsNum(void);
extern _X_EXPORT int GetEventList(EventListPtr* list);
extern _X_EXPORT EventListPtr InitEventList(int num_events);
extern _X_EXPORT void FreeEventList(EventListPtr list, int num_events);
extern _X_EXPORT InternalEvent *InitEventList(int num_events);
extern _X_EXPORT void FreeEventList(InternalEvent *list, int num_events);
extern void CreateClassesChangedEvent(EventListPtr event,
extern void CreateClassesChangedEvent(InternalEvent *event,
DeviceIntPtr master,
DeviceIntPtr slave,
int type);
extern EventListPtr UpdateFromMaster(
EventListPtr events,
extern InternalEvent * UpdateFromMaster(
InternalEvent *events,
DeviceIntPtr pDev,
int type,
int *num_events);
extern _X_EXPORT int GetPointerEvents(
EventListPtr events,
InternalEvent *events,
DeviceIntPtr pDev,
int type,
int buttons,
int flags,
const ValuatorMask *mask);
extern _X_EXPORT void QueuePointerEvents(
DeviceIntPtr pDev,
int type,
int buttons,
@ -462,14 +457,25 @@ extern _X_EXPORT int GetPointerEvents(
const ValuatorMask *mask);
extern _X_EXPORT int GetKeyboardEvents(
EventListPtr events,
InternalEvent *events,
DeviceIntPtr pDev,
int type,
int key_code,
const ValuatorMask *mask);
extern _X_EXPORT void QueueKeyboardEvents(
DeviceIntPtr pDev,
int type,
int key_code,
const ValuatorMask *mask);
extern int GetProximityEvents(
EventListPtr events,
InternalEvent *events,
DeviceIntPtr pDev,
int type,
const ValuatorMask *mask);
extern void QueueProximityEvents(
DeviceIntPtr pDev,
int type,
const ValuatorMask *mask);
@ -495,6 +501,8 @@ extern _X_EXPORT int GetMotionHistory(
ScreenPtr pScreen,
BOOL core);
extern void ReleaseButtonsAndKeys(DeviceIntPtr dev);
extern int AttachDevice(ClientPtr client,
DeviceIntPtr slave,
DeviceIntPtr master);

View File

@ -591,4 +591,14 @@ typedef struct _EventSyncInfo {
extern EventSyncInfoRec syncEvents;
/**
* Given a sprite, returns the window at the bottom of the trace (i.e. the
* furthest window from the root).
*/
static inline WindowPtr DeepestSpriteWin(SpritePtr sprite)
{
assert(sprite->spriteTraceGood > 0);
return sprite->spriteTrace[sprite->spriteTraceGood - 1];
}
#endif /* INPUTSTRUCT_H */

View File

@ -37,4 +37,6 @@ struct _ValuatorMask {
int valuators[MAX_VALUATORS]; /* valuator data */
};
extern void verify_internal_event(const InternalEvent *ev);
#endif

View File

@ -223,6 +223,24 @@ pad_to_int32(const int bytes) {
extern char**
xstrtokenize(const char *str, const char* separators);
/**
* Compare the two version numbers comprising of major.minor.
*
* @return A value less than 0 if a is less than b, 0 if a is equal to b,
* or a value greater than 0
*/
static inline int
version_compare(uint16_t a_major, uint16_t a_minor,
uint16_t b_major, uint16_t b_minor)
{
int a, b;
a = a_major << 16 | a_minor;
b = b_major << 16 | b_minor;
return (a - b);
}
/* some macros to help swap requests, replies, and events */
#define LengthRestB(stuff) \

View File

@ -64,7 +64,7 @@ in this Software without prior written authorization from The Open Group.
#define DequeueScreen(dev) dev->spriteInfo->sprite->pDequeueScreen
typedef struct _Event {
EventListPtr events;
InternalEvent* events;
ScreenPtr pScreen;
DeviceIntPtr pDev; /* device this event _originated_ from */
} EventRec, *EventPtr;
@ -111,7 +111,7 @@ mieqInit(void)
for (i = 0; i < QUEUE_SIZE; i++)
{
if (miEventQueue.events[i].events == NULL) {
EventListPtr evlist = InitEventList(1);
InternalEvent* evlist = InitEventList(1);
if (!evlist)
FatalError("Could not allocate event queue.\n");
miEventQueue.events[i].events = evlist;
@ -146,7 +146,7 @@ void
mieqEnqueue(DeviceIntPtr pDev, InternalEvent *e)
{
unsigned int oldtail = miEventQueue.tail;
EventListPtr evt;
InternalEvent* evt;
int isMotion = 0;
int evlen;
Time time;
@ -156,7 +156,7 @@ mieqEnqueue(DeviceIntPtr pDev, InternalEvent *e)
pthread_mutex_lock(&miEventQueueMutex);
#endif
CHECKEVENT(e);
verify_internal_event(e);
/* avoid merging events from different devices */
if (e->any.type == ET_Motion)
@ -188,21 +188,7 @@ mieqEnqueue(DeviceIntPtr pDev, InternalEvent *e)
evlen = e->any.length;
evt = miEventQueue.events[oldtail].events;
if (evt->evlen < evlen)
{
evt->evlen = evlen;
evt->event = realloc(evt->event, evt->evlen);
if (!evt->event)
{
ErrorF("[mi] Running out of memory. Tossing event.\n");
#ifdef XQUARTZ
pthread_mutex_unlock(&miEventQueueMutex);
#endif
return;
}
}
memcpy(evt->event, e, evlen);
memcpy(evt, e, evlen);
time = e->any.time;
/* Make sure that event times don't go backwards - this
@ -211,7 +197,7 @@ mieqEnqueue(DeviceIntPtr pDev, InternalEvent *e)
miEventQueue.lastEventTime - time < 10000)
e->any.time = miEventQueue.lastEventTime;
miEventQueue.lastEventTime = ((InternalEvent*)evt->event)->any.time;
miEventQueue.lastEventTime = evt->any.time;
miEventQueue.events[oldtail].pScreen = pDev ? EnqueueScreen(pDev) : NULL;
miEventQueue.events[oldtail].pDev = pDev;
@ -292,8 +278,8 @@ static void
FixUpEventForMaster(DeviceIntPtr mdev, DeviceIntPtr sdev,
InternalEvent* original, InternalEvent *master)
{
CHECKEVENT(original);
CHECKEVENT(master);
verify_internal_event(original);
verify_internal_event(master);
/* Ensure chained button mappings, i.e. that the detail field is the
* value of the mapped button on the SD, not the physical button */
if (original->any.type == ET_ButtonPress ||
@ -323,7 +309,7 @@ CopyGetMasterEvent(DeviceIntPtr sdev,
int type = original->any.type;
int mtype; /* which master type? */
CHECKEVENT(original);
verify_internal_event(original);
/* ET_XQuartz has sdev == NULL */
if (!sdev || IsMaster(sdev) || IsFloating(sdev))
@ -376,7 +362,7 @@ mieqProcessDeviceEvent(DeviceIntPtr dev,
DeviceIntPtr master;
InternalEvent mevent; /* master event */
CHECKEVENT(event);
verify_internal_event(event);
/* Custom event handler */
handler = miEventQueue.handlers[event->any.type];
@ -431,10 +417,8 @@ void
mieqProcessInputEvents(void)
{
EventRec *e = NULL;
int evlen;
ScreenPtr screen;
static InternalEvent *event = NULL;
static size_t event_size = 0;
static InternalEvent event;
DeviceIntPtr dev = NULL,
master = NULL;
@ -445,20 +429,7 @@ mieqProcessInputEvents(void)
while (miEventQueue.head != miEventQueue.tail) {
e = &miEventQueue.events[miEventQueue.head];
evlen = e->events->evlen;
if(evlen > event_size)
{
event = realloc(event, evlen);
event_size = evlen;
}
if (!event)
FatalError("[mi] No memory left for event processing.\n");
memcpy(event, e->events->event, evlen);
event = *e->events;
dev = e->pDev;
screen = e->pScreen;
@ -480,10 +451,10 @@ mieqProcessInputEvents(void)
DPMSSet(serverClient, DPMSModeOn);
#endif
mieqProcessDeviceEvent(dev, event, screen);
mieqProcessDeviceEvent(dev, &event, screen);
/* Update the sprite now. Next event may be from different device. */
if (event->any.type == ET_Motion && master)
if (event.any.type == ET_Motion && master)
miPointerUpdateSprite(dev);
#ifdef XQUARTZ

View File

@ -63,6 +63,7 @@ in this Software without prior written authorization from The Open Group.
# include "dixstruct.h"
# include "inputstr.h"
# include "inpututils.h"
# include "eventstr.h"
DevPrivateKeyRec miPointerScreenKeyRec;
@ -99,7 +100,7 @@ static void miPointerDeviceCleanup(DeviceIntPtr pDev,
ScreenPtr pScreen);
static void miPointerMoveNoEvent (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y);
static EventList* events; /* for WarpPointer MotionNotifies */
static InternalEvent* events; /* for WarpPointer MotionNotifies */
Bool
miPointerInitialize (ScreenPtr pScreen,
@ -689,7 +690,7 @@ miPointerMove (DeviceIntPtr pDev, ScreenPtr pScreen, int x, int y)
darwinEvents_lock();
#endif
for (i = 0; i < nevents; i++)
mieqEnqueue(pDev, (InternalEvent*)events[i].event);
mieqEnqueue(pDev, &events[i]);
#ifdef XQUARTZ
darwinEvents_unlock();
#endif

View File

@ -28,8 +28,8 @@ RRClientKnowsRates (ClientPtr pClient)
{
rrClientPriv(pClient);
return (pRRClient->major_version > 1 ||
(pRRClient->major_version == 1 && pRRClient->minor_version >= 1));
return version_compare(pRRClient->major_version, pRRClient->minor_version,
1, 1) >= 0;
}
static int
@ -47,8 +47,8 @@ ProcRRQueryVersion (ClientPtr client)
rep.length = 0;
rep.sequenceNumber = client->sequence;
if ((stuff->majorVersion * 1000 + stuff->minorVersion) <
(SERVER_RANDR_MAJOR_VERSION * 1000 + SERVER_RANDR_MINOR_VERSION))
if (version_compare(stuff->majorVersion, stuff->minorVersion,
SERVER_RANDR_MAJOR_VERSION, SERVER_RANDR_MINOR_VERSION) < 0)
{
rep.majorVersion = stuff->majorVersion;
rep.minorVersion = stuff->minorVersion;

View File

@ -1,7 +1,7 @@
if ENABLE_UNIT_TESTS
if HAVE_LD_WRAP
SUBDIRS= . xi2
noinst_PROGRAMS = xkb input xtest list
noinst_PROGRAMS = xkb input xtest list misc
check_LTLIBRARIES = libxservertest.la
TESTS=$(noinst_PROGRAMS)
@ -18,6 +18,7 @@ xkb_LDADD=$(TEST_LDADD)
input_LDADD=$(TEST_LDADD)
xtest_LDADD=$(TEST_LDADD)
list_LDADD=$(TEST_LDADD)
misc_LDADD=$(TEST_LDADD)
libxservertest_la_LIBADD = \
$(XSERVER_LIBS) \

62
test/misc.c Normal file
View File

@ -0,0 +1,62 @@
/**
* 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 "misc.h"
static void dix_version_compare(void)
{
int rc;
rc = version_compare(0, 0, 1, 0);
assert(rc < 0);
rc = version_compare(1, 0, 0, 0);
assert(rc > 0);
rc = version_compare(0, 0, 0, 0);
assert(rc == 0);
rc = version_compare(1, 0, 1, 0);
assert(rc == 0);
rc = version_compare(1, 0, 0, 9);
assert(rc > 0);
rc = version_compare(0, 9, 1, 0);
assert(rc < 0);
rc = version_compare(1, 0, 1, 9);
assert(rc < 0);
rc = version_compare(1, 9, 1, 0);
assert(rc > 0);
rc = version_compare(2, 0, 1, 9);
assert(rc > 0);
rc = version_compare(1, 9, 2, 0);
assert(rc < 0);
}
int main(int argc, char** argv)
{
dix_version_compare();
return 0;
}

View File

@ -72,17 +72,17 @@ ProcXFixesQueryVersion(ClientPtr client)
rep.type = X_Reply;
rep.length = 0;
rep.sequenceNumber = client->sequence;
if (stuff->majorVersion < SERVER_XFIXES_MAJOR_VERSION) {
if (version_compare(stuff->majorVersion, stuff->minorVersion,
SERVER_XFIXES_MAJOR_VERSION, SERVER_XFIXES_MAJOR_VERSION) < 0)
{
rep.majorVersion = stuff->majorVersion;
rep.minorVersion = stuff->minorVersion;
} else {
rep.majorVersion = SERVER_XFIXES_MAJOR_VERSION;
if (stuff->majorVersion == SERVER_XFIXES_MAJOR_VERSION &&
stuff->minorVersion < SERVER_XFIXES_MINOR_VERSION)
rep.minorVersion = stuff->minorVersion;
else
rep.minorVersion = SERVER_XFIXES_MINOR_VERSION;
rep.minorVersion = SERVER_XFIXES_MINOR_VERSION;
}
pXFixesClient->major_version = rep.majorVersion;
pXFixesClient->minor_version = rep.minorVersion;
if (client->swapped) {

View File

@ -5586,6 +5586,7 @@ ProcXkbGetKbdByName(ClientPtr client)
{
DeviceIntPtr dev;
DeviceIntPtr tmpd;
DeviceIntPtr master;
xkbGetKbdByNameReply rep = {0};
xkbGetMapReply mrep = {0};
xkbGetCompatMapReply crep = {0};
@ -5611,6 +5612,7 @@ ProcXkbGetKbdByName(ClientPtr client)
return BadAccess;
CHK_KBD_DEVICE(dev, stuff->deviceSpec, client, access_mode);
master = GetMaster(dev, MASTER_KEYBOARD);
xkb = dev->key->xkbInfo->desc;
status= Success;
@ -5869,25 +5871,6 @@ ProcXkbGetKbdByName(ClientPtr client)
}
xkb->ctrls->num_groups= nTG;
for (tmpd = inputInfo.devices; tmpd; tmpd = tmpd->next) {
if ((tmpd == dev) || (!IsMaster(tmpd) && GetMaster(tmpd, MASTER_KEYBOARD) == dev)) {
if (tmpd != dev)
XkbCopyDeviceKeymap(tmpd, dev);
if (tmpd->kbdfeed && tmpd->kbdfeed->xkb_sli) {
old_sli = tmpd->kbdfeed->xkb_sli;
tmpd->kbdfeed->xkb_sli = NULL;
sli = XkbAllocSrvLedInfo(tmpd, tmpd->kbdfeed, NULL, 0);
if (sli) {
sli->explicitState = old_sli->explicitState;
sli->effectiveState = old_sli->effectiveState;
}
tmpd->kbdfeed->xkb_sli = sli;
XkbFreeSrvLedInfo(old_sli);
}
}
}
nkn.deviceID= nkn.oldDeviceID= dev->id;
nkn.minKeyCode= new->min_key_code;
nkn.maxKeyCode= new->max_key_code;
@ -5900,13 +5883,29 @@ ProcXkbGetKbdByName(ClientPtr client)
nkn.changed|= XkbNKN_GeometryMask;
XkbSendNewKeyboardNotify(dev,&nkn);
if (!IsMaster(dev)) {
DeviceIntPtr master = GetMaster(dev, MASTER_KEYBOARD);
if (master && master->lastSlave == dev) {
XkbCopyDeviceKeymap(master, dev);
XkbSendNewKeyboardNotify(dev,&nkn);
}
}
/* Update the map and LED info on the device itself, as well as
* any slaves if it's an MD, or its MD if it's an SD and was the
* last device used on that MD. */
for (tmpd = inputInfo.devices; tmpd; tmpd = tmpd->next) {
if (tmpd != dev && GetMaster(tmpd, MASTER_KEYBOARD) != dev &&
(tmpd != master || dev != master->lastSlave))
continue;
if (tmpd != dev)
XkbCopyDeviceKeymap(tmpd, dev);
if (tmpd->kbdfeed && tmpd->kbdfeed->xkb_sli) {
old_sli = tmpd->kbdfeed->xkb_sli;
tmpd->kbdfeed->xkb_sli = NULL;
sli = XkbAllocSrvLedInfo(tmpd, tmpd->kbdfeed, NULL, 0);
if (sli) {
sli->explicitState = old_sli->explicitState;
sli->effectiveState = old_sli->effectiveState;
}
tmpd->kbdfeed->xkb_sli = sli;
XkbFreeSrvLedInfo(old_sli);
}
}
}
if ((new!=NULL)&&(new!=xkb)) {
XkbFreeKeyboard(new,XkbAllComponentsMask,TRUE);

View File

@ -1351,7 +1351,7 @@ static void
InjectPointerKeyEvents(DeviceIntPtr dev, int type, int button, int flags, ValuatorMask *mask)
{
ScreenPtr pScreen;
EventListPtr events;
InternalEvent* events;
int nevents, i;
DeviceIntPtr ptr, mpointer, lastSlave = NULL;
Bool saveWait;
@ -1377,7 +1377,7 @@ InjectPointerKeyEvents(DeviceIntPtr dev, int type, int button, int flags, Valuat
OsReleaseSignals();
for (i = 0; i < nevents; i++)
mieqProcessDeviceEvent(ptr, (InternalEvent*)events[i].event, NULL);
mieqProcessDeviceEvent(ptr, &events[i], NULL);
FreeEventList(events, GetMaximumEventsNum());

View File

@ -88,11 +88,15 @@ XkbSendLegacyMapNotify(DeviceIntPtr kbd, CARD16 xkb_event, CARD16 changed,
if (!clients[i] || clients[i]->clientState != ClientStateRunning)
continue;
/* Ignore clients which will have already received this.
* Inconsistent with themselves, but consistent with previous
* behaviour.*/
if (xkb_event == XkbMapNotify && (clients[i]->mapNotifyMask & changed))
/* XKB allows clients to restrict the MappingNotify events sent to
* them. This was broken for three years. Sorry. */
if (xkb_event == XkbMapNotify &&
(clients[i]->xkbClientFlags & _XkbClientInitialized) &&
!(clients[i]->mapNotifyMask & changed))
continue;
/* Emulate previous server behaviour: any client which has activated
* XKB will not receive core events emulated from a NewKeyboardNotify
* at all. */
if (xkb_event == XkbNewKeyboardNotify &&
(clients[i]->xkbClientFlags & _XkbClientInitialized))
continue;
@ -164,9 +168,6 @@ XkbSendNewKeyboardNotify(DeviceIntPtr kbd,xkbNewKeyboardNotify *pNKN)
if (!(clients[i]->newKeyboardNotifyMask & changed))
continue;
if (!XIShouldNotify(clients[i], kbd))
continue;
pNKN->sequenceNumber = clients[i]->sequence;
pNKN->time = time;
pNKN->changed = changed;
@ -232,8 +233,7 @@ register CARD16 changed,bState;
if ((!interest->client->clientGone) &&
(interest->client->requestVector != InitialVector) &&
(interest->client->xkbClientFlags&_XkbClientInitialized) &&
(interest->stateNotifyMask&changed) &&
XIShouldNotify(interest->client,kbd)) {
(interest->stateNotifyMask&changed)) {
pSN->sequenceNumber = interest->client->sequence;
pSN->time = time;
pSN->changed = changed;
@ -280,9 +280,6 @@ XkbSendMapNotify(DeviceIntPtr kbd, xkbMapNotify *pMN)
if (!(clients[i]->mapNotifyMask & changed))
continue;
if (!XIShouldNotify(clients[i], kbd))
continue;
pMN->time = time;
pMN->sequenceNumber = clients[i]->sequence;
pMN->changed = changed;
@ -401,8 +398,7 @@ Time time = 0;
if ((!interest->client->clientGone) &&
(interest->client->requestVector != InitialVector) &&
(interest->client->xkbClientFlags&_XkbClientInitialized) &&
(interest->ctrlsNotifyMask&changedControls) &&
XIShouldNotify(interest->client, kbd)) {
(interest->ctrlsNotifyMask&changedControls)) {
if (!initialized) {
pCN->type = XkbEventCode + XkbEventBase;
pCN->xkbType = XkbControlsNotify;
@ -450,7 +446,6 @@ CARD32 state,changed;
if ((!interest->client->clientGone) &&
(interest->client->requestVector != InitialVector) &&
(interest->client->xkbClientFlags&_XkbClientInitialized) &&
XIShouldNotify(interest->client, kbd) &&
(((xkbType==XkbIndicatorStateNotify)&&
(interest->iStateNotifyMask&changed))||
((xkbType==XkbIndicatorMapNotify)&&
@ -534,8 +529,7 @@ XID winID = 0;
if ((!interest->client->clientGone) &&
(interest->client->requestVector != InitialVector) &&
(interest->client->xkbClientFlags&_XkbClientInitialized) &&
(interest->bellNotifyMask) &&
XIShouldNotify(interest->client,kbd)) {
(interest->bellNotifyMask)) {
if (!initialized) {
time = GetTimeInMillis();
bn.type = XkbEventCode + XkbEventBase;
@ -589,8 +583,7 @@ CARD16 sk_delay,db_delay;
if ((!interest->client->clientGone) &&
(interest->client->requestVector != InitialVector) &&
(interest->client->xkbClientFlags&_XkbClientInitialized) &&
(interest->accessXNotifyMask&(1<<pEv->detail)) &&
XIShouldNotify(interest->client, kbd)) {
(interest->accessXNotifyMask&(1<<pEv->detail))) {
if (!initialized) {
pEv->type = XkbEventCode + XkbEventBase;
pEv->xkbType = XkbAccessXNotify;
@ -637,8 +630,7 @@ CARD32 changedIndicators;
if ((!interest->client->clientGone) &&
(interest->client->requestVector != InitialVector) &&
(interest->client->xkbClientFlags&_XkbClientInitialized) &&
(interest->namesNotifyMask&pEv->changed) &&
XIShouldNotify(interest->client, kbd)) {
(interest->namesNotifyMask&pEv->changed)) {
if (!initialized) {
pEv->type = XkbEventCode + XkbEventBase;
pEv->xkbType = XkbNamesNotify;
@ -683,8 +675,7 @@ CARD16 firstSI = 0, nSI = 0, nTotalSI = 0;
if ((!interest->client->clientGone) &&
(interest->client->requestVector != InitialVector) &&
(interest->client->xkbClientFlags&_XkbClientInitialized) &&
(interest->compatNotifyMask) &&
XIShouldNotify(interest->client, kbd)) {
(interest->compatNotifyMask)) {
if (!initialized) {
pEv->type = XkbEventCode + XkbEventBase;
pEv->xkbType = XkbCompatMapNotify;
@ -736,8 +727,7 @@ Time time = 0;
if ((!interest->client->clientGone) &&
(interest->client->requestVector != InitialVector) &&
(interest->client->xkbClientFlags&_XkbClientInitialized) &&
(interest->actionMessageMask) &&
XIShouldNotify(interest->client, kbd)) {
(interest->actionMessageMask)) {
if (!initialized) {
pEv->type = XkbEventCode + XkbEventBase;
pEv->xkbType = XkbActionMessage;
@ -783,8 +773,7 @@ CARD16 reason;
if ((!interest->client->clientGone) &&
(interest->client->requestVector != InitialVector) &&
(interest->client->xkbClientFlags&_XkbClientInitialized) &&
(interest->extDevNotifyMask&reason) &&
XIShouldNotify(interest->client, dev)) {
(interest->extDevNotifyMask&reason)) {
if (!initialized) {
pEv->type = XkbEventCode + XkbEventBase;
pEv->xkbType = XkbExtensionDeviceNotify;