aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/Xi/exevents.c
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/Xi/exevents.c')
-rw-r--r--xorg-server/Xi/exevents.c1403
1 files changed, 740 insertions, 663 deletions
diff --git a/xorg-server/Xi/exevents.c b/xorg-server/Xi/exevents.c
index 0bb84f86c..0211e72b7 100644
--- a/xorg-server/Xi/exevents.c
+++ b/xorg-server/Xi/exevents.c
@@ -52,17 +52,17 @@ SOFTWARE.
*
*/
-#define NEED_EVENTS
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
#endif
+#include "inputstr.h"
#include <X11/X.h>
#include <X11/Xproto.h>
#include <X11/extensions/XI.h>
#include <X11/extensions/XIproto.h>
+#include <X11/extensions/XI2proto.h>
#include <X11/extensions/geproto.h>
-#include "inputstr.h"
#include "windowstr.h"
#include "miscstruct.h"
#include "region.h"
@@ -74,12 +74,12 @@ SOFTWARE.
#include "scrnintstr.h"
#include "listdev.h" /* for CopySwapXXXClass */
#include "xace.h"
+#include "xiquerydevice.h" /* For List*Info */
+#include "eventconvert.h"
+#include "eventstr.h"
-#ifdef XKB
#include <X11/extensions/XKBproto.h>
#include "xkbsrv.h"
-extern Bool XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool sendNotifies);
-#endif
#define WID(w) ((w) ? ((w)->drawable.id) : 0)
#define AllModifiersMask ( \
@@ -87,8 +87,6 @@ extern Bool XkbCopyKeymap(XkbDescPtr src, XkbDescPtr dst, Bool sendNotifies);
Mod3Mask | Mod4Mask | Mod5Mask )
#define AllButtonsMask ( \
Button1Mask | Button2Mask | Button3Mask | Button4Mask | Button5Mask )
-#define Motion_Filter(class) (DevicePointerMotionMask | \
- (class)->state | (class)->motionMask)
Bool ShouldFreeInputMasks(WindowPtr /* pWin */ ,
Bool /* ignoreSelectedEvents */
@@ -99,6 +97,22 @@ static Bool MakeInputMasks(WindowPtr /* pWin */
/* Used to sture classes currently not in use by an MD */
extern DevPrivateKey UnusedClassesPrivateKey;
+/*
+ * Only let the given client know of core events which will affect its
+ * interpretation of input events, if the client's ClientPointer (or the
+ * paired keyboard) is the current device.
+ */
+int
+XIShouldNotify(ClientPtr client, DeviceIntPtr dev)
+{
+ DeviceIntPtr current_ptr = PickPointer(client);
+ DeviceIntPtr current_kbd = GetPairedDevice(current_ptr);
+
+ if (dev == current_kbd || dev == current_ptr)
+ return 1;
+
+ return 0;
+}
void
RegisterOtherDevice(DeviceIntPtr device)
@@ -108,25 +122,17 @@ RegisterOtherDevice(DeviceIntPtr device)
}
Bool
-IsPointerEvent(xEvent* xE)
+IsPointerEvent(InternalEvent* event)
{
- switch(xE->u.u.type)
+ switch(event->any.type)
{
- case ButtonPress:
- case ButtonRelease:
- case MotionNotify:
- case EnterNotify:
- case LeaveNotify:
+ case ET_ButtonPress:
+ case ET_ButtonRelease:
+ case ET_Motion:
+ /* XXX: enter/leave ?? */
return TRUE;
default:
- if (xE->u.u.type == DeviceButtonPress ||
- xE->u.u.type == DeviceButtonRelease ||
- xE->u.u.type == DeviceMotionNotify ||
- xE->u.u.type == ProximityIn ||
- xE->u.u.type == ProximityOut)
- {
- return TRUE;
- }
+ break;
}
return FALSE;
}
@@ -186,88 +192,23 @@ XIGetDevice(xEvent* xE)
* This code is basically the old SwitchCoreKeyboard.
*/
-void
+static void
CopyKeyClass(DeviceIntPtr device, DeviceIntPtr master)
{
- static DeviceIntPtr lastMapNotifyDevice = NULL;
- KeyClassPtr mk, dk; /* master, device */
- BOOL sendNotify = FALSE;
+ KeyClassPtr mk = master->key;
+ KeyClassPtr dk = device->key;
int i;
if (device == master)
return;
- dk = device->key;
- mk = master->key;
+ mk->sourceid = device->id;
- if (device != dixLookupPrivate(&master->devPrivates,
- CoreDevicePrivateKey)) {
- memcpy(mk->modifierMap, dk->modifierMap, MAP_LENGTH);
+ for (i = 0; i < 8; i++)
+ mk->modifierKeyCount[i] = dk->modifierKeyCount[i];
- if (dk->maxKeysPerModifier)
- {
- mk->modifierKeyMap = xrealloc(mk->modifierKeyMap,
- 8 * dk->maxKeysPerModifier);
- if (!mk->modifierKeyMap)
- FatalError("[Xi] no memory for class shift.\n");
- memcpy(mk->modifierKeyMap, dk->modifierKeyMap,
- (8 * dk->maxKeysPerModifier));
- } else
- {
- xfree(mk->modifierKeyMap);
- mk->modifierKeyMap = NULL;
- }
-
- mk->maxKeysPerModifier = dk->maxKeysPerModifier;
- mk->curKeySyms.minKeyCode = dk->curKeySyms.minKeyCode;
- mk->curKeySyms.maxKeyCode = dk->curKeySyms.maxKeyCode;
- SetKeySymsMap(&mk->curKeySyms, &dk->curKeySyms);
-
- /*
- * Copy state from the extended keyboard to core. If you omit this,
- * holding Ctrl on keyboard one, and pressing Q on keyboard two, will
- * cause your app to quit. This feels wrong to me, hence the below
- * code.
- *
- * XXX: If you synthesise core modifier events, the state will get
- * clobbered here. You'll have to work out something sensible
- * to fix that. Good luck.
- */
-
-#define KEYBOARD_MASK (ShiftMask | LockMask | ControlMask | Mod1Mask | \
- Mod2Mask | Mod3Mask | Mod4Mask | Mod5Mask)
- mk->state &= ~(KEYBOARD_MASK);
- mk->state |= (dk->state & KEYBOARD_MASK);
-#undef KEYBOARD_MASK
- for (i = 0; i < 8; i++)
- mk->modifierKeyCount[i] = dk->modifierKeyCount[i];
-
-#ifdef XKB
- if (!noXkbExtension && dk->xkbInfo && dk->xkbInfo->desc) {
- if (!mk->xkbInfo || !mk->xkbInfo->desc)
- {
- XkbInitDevice(master);
- XkbFinishDeviceInit(master);
- }
- if (!XkbCopyKeymap(dk->xkbInfo->desc, mk->xkbInfo->desc, True))
- FatalError("Couldn't pivot keymap from device to core!\n");
- }
-#endif
-
- dixSetPrivate(&master->devPrivates, CoreDevicePrivateKey, device);
- sendNotify = TRUE;
- } else if (lastMapNotifyDevice != master)
- sendNotify = TRUE;
-
- if (sendNotify)
- {
- SendMappingNotify(master, MappingKeyboard,
- mk->curKeySyms.minKeyCode,
- (mk->curKeySyms.maxKeyCode -
- mk->curKeySyms.minKeyCode),
- serverClient);
- lastMapNotifyDevice = master;
- }
+ if (!XkbCopyDeviceKeymap(master, device))
+ FatalError("Couldn't pivot keymap from device to core!\n");
}
/**
@@ -280,82 +221,6 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to)
{
ClassesPtr classes;
- if (from->kbdfeed)
- {
- KbdFeedbackPtr *k, it;
-
- if (!to->kbdfeed)
- {
- classes = dixLookupPrivate(&to->devPrivates,
- UnusedClassesPrivateKey);
- to->kbdfeed = classes->kbdfeed;
- }
-
- k = &to->kbdfeed;
- for(it = from->kbdfeed; it; it = it->next)
- {
- if (!(*k))
- {
- *k = xcalloc(1, sizeof(KbdFeedbackClassRec));
- if (!*k)
- {
- ErrorF("[Xi] Cannot alloc memory for class copy.");
- return;
- }
- }
- (*k)->BellProc = it->BellProc;
- (*k)->CtrlProc = it->CtrlProc;
- (*k)->ctrl = it->ctrl;
-#ifdef XKB
- if ((*k)->xkb_sli)
- XkbFreeSrvLedInfo((*k)->xkb_sli);
- (*k)->xkb_sli = XkbCopySrvLedInfo(from, it->xkb_sli, *k, NULL);
-#endif
-
- k = &(*k)->next;
- }
- } else if (to->kbdfeed && !from->kbdfeed)
- {
- ClassesPtr classes;
- classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey);
- classes->kbdfeed = to->kbdfeed;
- to->kbdfeed = NULL;
- }
-
- if (from->ptrfeed)
- {
- PtrFeedbackPtr *p, it;
- if (!to->ptrfeed)
- {
- classes = dixLookupPrivate(&to->devPrivates,
- UnusedClassesPrivateKey);
- to->ptrfeed = classes->ptrfeed;
- }
-
- p = &to->ptrfeed;
- for (it = from->ptrfeed; it; it = it->next)
- {
- if (!(*p))
- {
- *p = xcalloc(1, sizeof(PtrFeedbackClassRec));
- if (!*p)
- {
- ErrorF("[Xi] Cannot alloc memory for class copy.");
- return;
- }
- }
- (*p)->CtrlProc = it->CtrlProc;
- (*p)->ctrl = it->ctrl;
-
- p = &(*p)->next;
- }
- } else if (to->ptrfeed && !from->ptrfeed)
- {
- ClassesPtr classes;
- classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey);
- classes->ptrfeed = to->ptrfeed;
- to->ptrfeed = NULL;
- }
if (from->intfeed)
{
@@ -491,11 +356,9 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to)
}
(*l)->CtrlProc = it->CtrlProc;
(*l)->ctrl = it->ctrl;
-#ifdef XKB
if ((*l)->xkb_sli)
XkbFreeSrvLedInfo((*l)->xkb_sli);
(*l)->xkb_sli = XkbCopySrvLedInfo(from, it->xkb_sli, NULL, *l);
-#endif
l = &(*l)->next;
}
@@ -508,74 +371,161 @@ DeepCopyFeedbackClasses(DeviceIntPtr from, DeviceIntPtr to)
}
}
-/**
- * Copies the CONTENT of the classes of device from into the classes in device
- * to. From and to are identical after finishing.
- *
- * If to does not have classes from currenly has, the classes are stored in
- * to's devPrivates system. Later, we recover it again from there if needed.
- * Saves a few memory allocations.
- */
-
-void
-DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
+static void
+DeepCopyKeyboardClasses(DeviceIntPtr from, DeviceIntPtr to)
{
ClassesPtr classes;
/* XkbInitDevice (->XkbInitIndicatorMap->XkbFindSrvLedInfo) relies on the
* kbdfeed to be set up properly, so let's do the feedback classes first.
*/
- DeepCopyFeedbackClasses(from, to);
+ if (from->kbdfeed)
+ {
+ KbdFeedbackPtr *k, it;
+
+ if (!to->kbdfeed)
+ {
+ classes = dixLookupPrivate(&to->devPrivates,
+ UnusedClassesPrivateKey);
+
+ to->kbdfeed = classes->kbdfeed;
+ if (!to->kbdfeed)
+ InitKeyboardDeviceStruct(to, NULL, NULL, NULL);
+ }
+
+ k = &to->kbdfeed;
+ for(it = from->kbdfeed; it; it = it->next)
+ {
+ if (!(*k))
+ {
+ *k = xcalloc(1, sizeof(KbdFeedbackClassRec));
+ if (!*k)
+ {
+ ErrorF("[Xi] Cannot alloc memory for class copy.");
+ return;
+ }
+ }
+ (*k)->BellProc = it->BellProc;
+ (*k)->CtrlProc = it->CtrlProc;
+ (*k)->ctrl = it->ctrl;
+ if ((*k)->xkb_sli)
+ XkbFreeSrvLedInfo((*k)->xkb_sli);
+ (*k)->xkb_sli = XkbCopySrvLedInfo(from, it->xkb_sli, *k, NULL);
+
+ k = &(*k)->next;
+ }
+ } else if (to->kbdfeed && !from->kbdfeed)
+ {
+ ClassesPtr classes;
+ classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey);
+ classes->kbdfeed = to->kbdfeed;
+ to->kbdfeed = NULL;
+ }
if (from->key)
{
- KeyCode *oldModKeyMap;
- KeySym *oldMap;
-#ifdef XKB
- struct _XkbSrvInfo *oldXkbInfo;
-#endif
if (!to->key)
{
classes = dixLookupPrivate(&to->devPrivates,
- UnusedClassesPrivateKey);
+ UnusedClassesPrivateKey);
to->key = classes->key;
if (!to->key)
+ InitKeyboardDeviceStruct(to, NULL, NULL, NULL);
+ else
+ classes->key = NULL;
+ }
+
+ CopyKeyClass(from, to);
+ } else if (to->key && !from->key)
+ {
+ ClassesPtr classes;
+ classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey);
+ classes->key = to->key;
+ to->key = NULL;
+ }
+
+ /* We can't just copy over the focus class. When an app sets the focus,
+ * it'll do so on the master device. Copying the SDs focus means losing
+ * the focus.
+ * So we only copy the focus class if the device didn't have one,
+ * otherwise we leave it as it is.
+ */
+ if (from->focus)
+ {
+ if (!to->focus)
+ {
+ WindowPtr *oldTrace;
+
+ classes = dixLookupPrivate(&to->devPrivates,
+ UnusedClassesPrivateKey);
+ to->focus = classes->focus;
+ if (!to->focus)
{
- to->key = xcalloc(1, sizeof(KeyClassRec));
- if (!to->key)
+ to->focus = xcalloc(1, sizeof(FocusClassRec));
+ if (!to->focus)
FatalError("[Xi] no memory for class shift.\n");
} else
- classes->key = NULL;
+ classes->focus = NULL;
+
+ oldTrace = to->focus->trace;
+ memcpy(to->focus, from->focus, sizeof(FocusClassRec));
+ to->focus->trace = xrealloc(oldTrace,
+ to->focus->traceSize * sizeof(WindowPtr));
+ if (!to->focus->trace && to->focus->traceSize)
+ FatalError("[Xi] no memory for trace.\n");
+ memcpy(to->focus->trace, from->focus->trace,
+ from->focus->traceSize * sizeof(WindowPtr));
+ to->focus->sourceid = from->id;
}
+ } else if (to->focus)
+ {
+ ClassesPtr classes;
+ classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey);
+ classes->focus = to->focus;
+ to->focus = NULL;
+ }
- oldModKeyMap = to->key->modifierKeyMap;
- oldMap = to->key->curKeySyms.map;
-#ifdef XKB
- oldXkbInfo = to->key->xkbInfo;
-#endif
+}
- if (!oldMap) /* newly created key struct */
+static void
+DeepCopyPointerClasses(DeviceIntPtr from, DeviceIntPtr to)
+{
+ ClassesPtr classes;
+
+ /* Feedback classes must be copied first */
+ if (from->ptrfeed)
+ {
+ PtrFeedbackPtr *p, it;
+ if (!to->ptrfeed)
{
- int bytes = (to->key->curKeySyms.maxKeyCode -
- to->key->curKeySyms.minKeyCode + 1) *
- to->key->curKeySyms.mapWidth;
- oldMap = (KeySym *)xcalloc(sizeof(KeySym), bytes);
- memcpy(oldMap, from->key->curKeySyms.map, bytes);
+ classes = dixLookupPrivate(&to->devPrivates,
+ UnusedClassesPrivateKey);
+ to->ptrfeed = classes->ptrfeed;
}
- to->key->modifierKeyMap = oldModKeyMap;
- to->key->curKeySyms.map = oldMap;
-#ifdef XKB
- to->key->xkbInfo = oldXkbInfo;
-#endif
+ p = &to->ptrfeed;
+ for (it = from->ptrfeed; it; it = it->next)
+ {
+ if (!(*p))
+ {
+ *p = xcalloc(1, sizeof(PtrFeedbackClassRec));
+ if (!*p)
+ {
+ ErrorF("[Xi] Cannot alloc memory for class copy.");
+ return;
+ }
+ }
+ (*p)->CtrlProc = it->CtrlProc;
+ (*p)->ctrl = it->ctrl;
- CopyKeyClass(from, to);
- } else if (to->key && !from->key)
+ p = &(*p)->next;
+ }
+ } else if (to->ptrfeed && !from->ptrfeed)
{
ClassesPtr classes;
classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey);
- classes->key = to->key;
- to->key = NULL;
+ classes->ptrfeed = to->ptrfeed;
+ to->ptrfeed = NULL;
}
if (from->valuator)
@@ -592,7 +542,7 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
to->valuator = xrealloc(to->valuator, sizeof(ValuatorClassRec) +
from->valuator->numAxes * sizeof(AxisInfo) +
- from->valuator->numAxes * sizeof(unsigned int));
+ from->valuator->numAxes * sizeof(double));
v = to->valuator;
if (!v)
FatalError("[Xi] no memory for class shift.\n");
@@ -601,7 +551,9 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
v->axes = (AxisInfoPtr)&v[1];
memcpy(v->axes, from->valuator->axes, v->numAxes * sizeof(AxisInfo));
- v->axisVal = (int*)(v->axes + from->valuator->numAxes);
+ v->axisVal = (double*)(v->axes + from->valuator->numAxes);
+ v->sourceid = from->id;
+ v->mode = from->valuator->mode;
} else if (to->valuator && !from->valuator)
{
ClassesPtr classes;
@@ -626,7 +578,6 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
classes->button = NULL;
}
-#ifdef XKB
if (from->button->xkb_acts)
{
if (!to->button->xkb_acts)
@@ -639,7 +590,10 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
sizeof(XkbAction));
} else
xfree(to->button->xkb_acts);
-#endif
+
+ memcpy(to->button->labels, from->button->labels,
+ from->button->numButtons * sizeof(Atom));
+ to->button->sourceid = from->id;
} else if (to->button && !from->button)
{
ClassesPtr classes;
@@ -648,47 +602,6 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
to->button = NULL;
}
-
- /* We can't just copy over the focus class. When an app sets the focus,
- * it'll do so on the master device. Copying the SDs focus means losing
- * the focus.
- * So we only copy the focus class if the device didn't have one,
- * otherwise we leave it as it is.
- */
- if (from->focus)
- {
- if (!to->focus)
- {
- WindowPtr *oldTrace;
-
- classes = dixLookupPrivate(&to->devPrivates,
- UnusedClassesPrivateKey);
- to->focus = classes->focus;
- if (!to->focus)
- {
- to->focus = xcalloc(1, sizeof(FocusClassRec));
- if (!to->focus)
- FatalError("[Xi] no memory for class shift.\n");
- } else
- classes->focus = NULL;
-
- oldTrace = to->focus->trace;
- memcpy(to->focus, from->focus, sizeof(FocusClassRec));
- to->focus->trace = xrealloc(oldTrace,
- to->focus->traceSize * sizeof(WindowPtr));
- if (!to->focus->trace && to->focus->traceSize)
- FatalError("[Xi] no memory for trace.\n");
- memcpy(to->focus->trace, from->focus->trace,
- from->focus->traceSize * sizeof(WindowPtr));
- }
- } else if (to->focus)
- {
- ClassesPtr classes;
- classes = dixLookupPrivate(&to->devPrivates, UnusedClassesPrivateKey);
- classes->focus = to->focus;
- to->focus = NULL;
- }
-
if (from->proximity)
{
if (!to->proximity)
@@ -705,6 +618,7 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
classes->proximity = NULL;
}
memcpy(to->proximity, from->proximity, sizeof(ProximityClassRec));
+ to->proximity->sourceid = from->id;
} else if (to->proximity)
{
ClassesPtr classes;
@@ -729,6 +643,7 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
classes->absolute = NULL;
}
memcpy(to->absolute, from->absolute, sizeof(AbsoluteClassRec));
+ to->absolute->sourceid = from->id;
} else if (to->absolute)
{
ClassesPtr classes;
@@ -738,6 +653,78 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
}
}
+/**
+ * Copies the CONTENT of the classes of device from into the classes in device
+ * to. From and to are identical after finishing.
+ *
+ * If to does not have classes from currenly has, the classes are stored in
+ * to's devPrivates system. Later, we recover it again from there if needed.
+ * Saves a few memory allocations.
+ */
+void
+DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to, DeviceChangedEvent *dce)
+{
+ /* generic feedback classes, not tied to pointer and/or keyboard */
+ DeepCopyFeedbackClasses(from, to);
+
+ if ((dce->flags & DEVCHANGE_KEYBOARD_EVENT))
+ DeepCopyKeyboardClasses(from, to);
+ if ((dce->flags & DEVCHANGE_POINTER_EVENT))
+ DeepCopyPointerClasses(from, to);
+}
+
+
+/**
+ * Send an XI2 DeviceChangedEvent to all interested clients.
+ */
+void
+XISendDeviceChangedEvent(DeviceIntPtr device, DeviceIntPtr master, DeviceChangedEvent *dce)
+{
+ xXIDeviceChangedEvent *dcce;
+ int rc;
+
+ rc = EventToXI2((InternalEvent*)dce, (xEvent**)&dcce);
+ if (rc != Success)
+ {
+ ErrorF("[Xi] event conversion from DCE failed with code %d\n", rc);
+ return;
+ }
+
+ /* we don't actually swap if there's a NullClient, swapping is done
+ * later when event is delivered. */
+ SendEventToAllWindows(master, XI_DeviceChangedMask, (xEvent*)dcce, 1);
+ xfree(dcce);
+}
+
+static void
+ChangeMasterDeviceClasses(DeviceIntPtr device, DeviceChangedEvent *dce)
+{
+ DeviceIntPtr slave;
+ int rc;
+
+ /* For now, we don't have devices that change physically. */
+ if (!IsMaster(device))
+ return;
+
+ rc = dixLookupDevice(&slave, dce->sourceid, serverClient, DixReadAccess);
+
+ if (rc != Success)
+ return; /* Device has disappeared */
+
+ if (!slave->u.master)
+ return; /* set floating since the event */
+
+ if (slave->u.master->id != dce->masterid)
+ return; /* not our slave anymore, don't care */
+
+ /* FIXME: we probably need to send a DCE for the new slave now */
+
+ device->public.devicePrivate = slave->public.devicePrivate;
+
+ /* FIXME: the classes may have changed since we generated the event. */
+ DeepCopyDeviceClasses(slave, device, dce);
+ XISendDeviceChangedEvent(slave, device, dce);
+}
/**
* Update the device state according to the data in the event.
@@ -745,147 +732,106 @@ DeepCopyDeviceClasses(DeviceIntPtr from, DeviceIntPtr to)
* return values are
* DEFAULT ... process as normal
* DONT_PROCESS ... return immediately from caller
- * IS_REPEAT .. event is a repeat event.
*/
#define DEFAULT 0
#define DONT_PROCESS 1
-#define IS_REPEAT 2
int
-UpdateDeviceState(DeviceIntPtr device, xEvent* xE, int count)
+UpdateDeviceState(DeviceIntPtr device, DeviceEvent* event)
{
int i;
int key = 0,
- bit = 0;
+ bit = 0,
+ last_valuator;
KeyClassPtr k = NULL;
ButtonClassPtr b = NULL;
ValuatorClassPtr v = NULL;
- deviceValuator *xV = (deviceValuator *) xE;
BYTE *kptr = NULL;
- CARD16 modifiers = 0,
- mask = 0;
- /* currently no other generic event modifies the device */
- if (xE->u.u.type == GenericEvent)
- return DEFAULT;
+ /* This event is always the first we get, before the actual events with
+ * the data. However, the way how the DDX is set up, "device" will
+ * actually be the slave device that caused the event.
+ */
+ switch(event->type)
+ {
+ case ET_DeviceChanged:
+ ChangeMasterDeviceClasses(device, (DeviceChangedEvent*)event);
+ return DONT_PROCESS; /* event has been sent already */
+ case ET_Motion:
+ case ET_ButtonPress:
+ case ET_ButtonRelease:
+ case ET_KeyPress:
+ case ET_KeyRelease:
+ case ET_ProximityIn:
+ case ET_ProximityOut:
+ break;
+ default:
+ /* other events don't update the device */
+ return DEFAULT;
+ }
k = device->key;
v = device->valuator;
b = device->button;
+ key = event->detail.key;
+ bit = 1 << (key & 7);
- if (xE->u.u.type != DeviceValuator)
+ /* Update device axis */
+ /* Check valuators first */
+ last_valuator = -1;
+ for (i = 0; i < MAX_VALUATORS; i++)
{
- key = xE->u.u.detail;
- bit = 1 << (key & 7);
+ if (BitIsOn(&event->valuators.mask, i))
+ {
+ if (!v)
+ {
+ ErrorF("[Xi] Valuators reported for non-valuator device '%s'. "
+ "Ignoring event.\n", device->name);
+ return DONT_PROCESS;
+ } else if (v->numAxes < i)
+ {
+ ErrorF("[Xi] Too many valuators reported for device '%s'. "
+ "Ignoring event.\n", device->name);
+ return DONT_PROCESS;
+ }
+ last_valuator = i;
+ }
}
- /* Update device axis */
- /* Don't update valuators for the VCP, it never sends XI events anyway */
- for (i = 1; !device->isMaster && i < count; i++) {
- if ((++xV)->type == DeviceValuator) {
- int *axisvals;
- int first = xV->first_valuator;
- BOOL change = FALSE;
-
-
- if (xV->num_valuators &&
- (!v || (xV->num_valuators &&
- (first + xV->num_valuators > v->numAxes))))
- FatalError("Bad valuators reported for device %s\n",
- device->name);
- if (v && v->axisVal) {
- /* v->axisVal is always in absolute coordinates. Only the
- * delivery mode changes.
- * If device is mode Absolute
- * dev = event
- * If device is mode Relative
- * swap = (event - device)
- * dev = event
- * event = delta
- */
- int delta;
- axisvals = v->axisVal;
- if (v->mode == Relative) /* device reports relative */
- change = TRUE;
-
- switch (xV->num_valuators) {
- case 6:
- if (change) delta = xV->valuator5 - *(axisvals + first + 5);
- *(axisvals + first + 5) = xV->valuator5;
- if (change) xV->valuator5 = delta;
- case 5:
- if (change) delta = xV->valuator4 - *(axisvals + first + 4);
- *(axisvals + first + 4) = xV->valuator4;
- if (change) xV->valuator4 = delta;
- case 4:
- if (change) delta = xV->valuator3 - *(axisvals + first + 3);
- *(axisvals + first + 3) = xV->valuator3;
- if (change) xV->valuator3 = delta;
- case 3:
- if (change) delta = xV->valuator2 - *(axisvals + first + 2);
- *(axisvals + first + 2) = xV->valuator2;
- if (change) xV->valuator2 = delta;
- case 2:
- if (change) delta = xV->valuator1 - *(axisvals + first + 1);
- *(axisvals + first + 1) = xV->valuator1;
- if (change) xV->valuator1 = delta;
- case 1:
- if (change) delta = xV->valuator0 - *(axisvals + first);
- *(axisvals + first) = xV->valuator0;
- if (change) xV->valuator0 = delta;
- case 0:
- default:
- break;
- }
- }
- }
+ for (i = 0; i <= last_valuator && i < v->numAxes; i++)
+ {
+ if (BitIsOn(&event->valuators.mask, i))
+ {
+ /* XXX: Relative/Absolute mode */
+ v->axisVal[i] = event->valuators.data[i];
+ v->axisVal[i] += event->valuators.data_frac[i];
+ }
}
- if (xE->u.u.type == DeviceKeyPress) {
+ if (event->type == ET_KeyPress) {
if (!k)
return DONT_PROCESS;
- modifiers = k->modifierMap[key];
kptr = &k->down[key >> 3];
- if (*kptr & bit) { /* allow ddx to generate multiple downs */
- return IS_REPEAT;
- }
+ /* don't allow ddx to generate multiple downs, but repeats are okay */
+ if ((*kptr & bit) && !event->key_repeat)
+ return DONT_PROCESS;
if (device->valuator)
device->valuator->motionHintWindow = NullWindow;
*kptr |= bit;
- k->prev_state = k->state;
- for (i = 0, mask = 1; modifiers; i++, mask <<= 1) {
- if (mask & modifiers) {
- /* This key affects modifier "i" */
- k->modifierKeyCount[i]++;
- k->state |= mask;
- modifiers &= ~mask;
- }
- }
- } else if (xE->u.u.type == DeviceKeyRelease) {
+ } else if (event->type == ET_KeyRelease) {
if (!k)
return DONT_PROCESS;
kptr = &k->down[key >> 3];
if (!(*kptr & bit)) /* guard against duplicates */
return DONT_PROCESS;
- modifiers = k->modifierMap[key];
if (device->valuator)
device->valuator->motionHintWindow = NullWindow;
*kptr &= ~bit;
- k->prev_state = k->state;
- for (i = 0, mask = 1; modifiers; i++, mask <<= 1) {
- if (mask & modifiers) {
- /* This key affects modifier "i" */
- if (--k->modifierKeyCount[i] <= 0) {
- k->modifierKeyCount[i] = 0;
- k->state &= ~mask;
- }
- modifiers &= ~mask;
- }
- }
- } else if (xE->u.u.type == DeviceButtonPress) {
+ } else if (event->type == ET_ButtonPress) {
+ Mask mask;
if (!b)
return DONT_PROCESS;
@@ -901,15 +847,21 @@ UpdateDeviceState(DeviceIntPtr device, xEvent* xE, int count)
b->motionMask = DeviceButtonMotionMask;
if (b->map[key] <= 5)
b->state |= (Button1Mask >> 1) << b->map[key];
- SetMaskForEvent(device->id, Motion_Filter(b), DeviceMotionNotify);
- } else if (xE->u.u.type == DeviceButtonRelease) {
+
+ /* Add state and motionMask to the filter for this event */
+ mask = DevicePointerMotionMask | b->state | b->motionMask;
+ SetMaskForEvent(device->id, mask, DeviceMotionNotify);
+ mask = PointerMotionMask | b->state | b->motionMask;
+ SetMaskForEvent(device->id, mask, MotionNotify);
+ } else if (event->type == ET_ButtonRelease) {
+ Mask mask;
if (!b)
return DONT_PROCESS;
kptr = &b->down[key>>3];
if (!(*kptr & bit))
return DONT_PROCESS;
- if (device->isMaster) {
+ if (IsMaster(device)) {
DeviceIntPtr sd;
/*
@@ -918,7 +870,9 @@ UpdateDeviceState(DeviceIntPtr device, xEvent* xE, int count)
* event being delivered through the slave first
*/
for (sd = inputInfo.devices; sd; sd = sd->next) {
- if (sd->isMaster || sd->u.master != device)
+ if (IsMaster(sd) || sd->u.master != device)
+ continue;
+ if (!sd->button)
continue;
if ((sd->button->down[key>>3] & bit) != 0)
return DONT_PROCESS;
@@ -933,35 +887,76 @@ UpdateDeviceState(DeviceIntPtr device, xEvent* xE, int count)
b->motionMask = 0;
if (b->map[key] <= 5)
b->state &= ~((Button1Mask >> 1) << b->map[key]);
- SetMaskForEvent(device->id, Motion_Filter(b), DeviceMotionNotify);
- } else if (xE->u.u.type == ProximityIn)
+
+ /* Add state and motionMask to the filter for this event */
+ mask = DevicePointerMotionMask | b->state | b->motionMask;
+ SetMaskForEvent(device->id, mask, DeviceMotionNotify);
+ mask = PointerMotionMask | b->state | b->motionMask;
+ SetMaskForEvent(device->id, mask, MotionNotify);
+ } else if (event->type == ET_ProximityIn)
device->valuator->mode &= ~OutOfProximity;
- else if (xE->u.u.type == ProximityOut)
+ else if (event->type == ET_ProximityOut)
device->valuator->mode |= OutOfProximity;
return DEFAULT;
}
+static void
+ProcessRawEvent(RawDeviceEvent *ev, DeviceIntPtr device)
+{
+ GrabPtr grab = device->deviceGrab.grab;
+
+ if (grab)
+ DeliverGrabbedEvent((InternalEvent*)ev, device, FALSE);
+ else { /* deliver to all root windows */
+ xEvent *xi;
+ int i;
+
+ i = EventToXI2((InternalEvent*)ev, (xEvent**)&xi);
+ if (i != Success)
+ {
+ ErrorF("[Xi] %s: XI2 conversion failed in ProcessRawEvent (%d)\n",
+ device->name, i);
+ return;
+ }
+
+ for (i = 0; i < screenInfo.numScreens; i++)
+ DeliverEventsToWindow(device, WindowTable[i], xi, 1,
+ GetEventFilter(device, xi), NULL);
+ xfree(xi);
+ }
+}
+
/**
* Main device event processing function.
* Called from when processing the events from the event queue.
*
*/
void
-ProcessOtherEvent(xEventPtr xE, DeviceIntPtr device, int count)
+ProcessOtherEvent(InternalEvent *ev, DeviceIntPtr device)
{
- int i;
- CARD16 modifiers;
- GrabPtr grab = device->deviceGrab.grab;
+ GrabPtr grab;
Bool deactivateDeviceGrab = FALSE;
int key = 0, rootX, rootY;
ButtonClassPtr b;
KeyClassPtr k;
ValuatorClassPtr v;
- deviceValuator *xV = (deviceValuator *) xE;
int ret = 0;
- int state;
+ int state, i;
DeviceIntPtr mouse = NULL, kbd = NULL;
+ DeviceEvent *event = (DeviceEvent*)ev;
+
+ CHECKEVENT(ev);
+
+ if (ev->any.type == ET_RawKeyPress ||
+ ev->any.type == ET_RawKeyRelease ||
+ ev->any.type == ET_RawButtonPress ||
+ ev->any.type == ET_RawButtonRelease ||
+ ev->any.type == ET_RawMotion)
+ {
+ ProcessRawEvent((RawDeviceEvent*)ev, device);
+ return;
+ }
if (IsPointerDevice(device))
{
@@ -978,10 +973,34 @@ ProcessOtherEvent(xEventPtr xE, DeviceIntPtr device, int count)
}
/* State needs to be assembled BEFORE the device is updated. */
- state = (kbd) ? kbd->key->state : 0;
- state |= (mouse) ? (mouse->button->state) : 0;
+ state = (kbd && kbd->key) ? XkbStateFieldFromRec(&kbd->key->xkbInfo->state) : 0;
+ state |= (mouse && mouse->button) ? (mouse->button->state) : 0;
+
+ for (i = 0; mouse && mouse->button && i < mouse->button->numButtons; i++)
+ if (BitIsOn(mouse->button->down, i))
+ SetBit(event->buttons, i);
- ret = UpdateDeviceState(device, xE, count);
+ if (kbd && kbd->key)
+ {
+ XkbStatePtr state;
+ /* we need the state before the event happens */
+ if (event->type == ET_KeyPress || event->type == ET_KeyRelease)
+ state = &kbd->key->xkbInfo->prev_state;
+ else
+ state = &kbd->key->xkbInfo->state;
+
+ event->mods.base = state->base_mods;
+ event->mods.latched = state->latched_mods;
+ event->mods.locked = state->locked_mods;
+ event->mods.effective = state->mods;
+
+ event->group.base = state->base_group;
+ event->group.latched = state->latched_group;
+ event->group.locked = state->locked_group;
+ event->group.effective = state->group;
+ }
+
+ ret = UpdateDeviceState(device, event);
if (ret == DONT_PROCESS)
return;
@@ -989,19 +1008,31 @@ ProcessOtherEvent(xEventPtr xE, DeviceIntPtr device, int count)
b = device->button;
k = device->key;
- if (device->isMaster)
- CheckMotion(xE, device);
-
- if (xE->u.u.type != DeviceValuator && xE->u.u.type != GenericEvent) {
- GetSpritePosition(device, &rootX, &rootY);
- xE->u.keyButtonPointer.rootX = rootX;
- xE->u.keyButtonPointer.rootY = rootY;
- NoticeEventTime(xE);
+ if (IsMaster(device) || !device->u.master)
+ CheckMotion(event, device);
- xE->u.keyButtonPointer.state = state;
-
- key = xE->u.u.detail;
+ switch (event->type)
+ {
+ case ET_Motion:
+ case ET_ButtonPress:
+ case ET_ButtonRelease:
+ case ET_KeyPress:
+ case ET_KeyRelease:
+ case ET_ProximityIn:
+ case ET_ProximityOut:
+ GetSpritePosition(device, &rootX, &rootY);
+ event->root_x = rootX;
+ event->root_y = rootY;
+ NoticeEventTime((InternalEvent*)event);
+ event->corestate = state;
+ key = event->detail.key;
+ break;
+ default:
+ break;
}
+
+#if 0
+ /* FIXME: I'm broken. Please fix me. Thanks */
if (DeviceEventCallback) {
DeviceEventInfoRec eventinfo;
@@ -1009,84 +1040,70 @@ ProcessOtherEvent(xEventPtr xE, DeviceIntPtr device, int count)
eventinfo.count = count;
CallCallbacks(&DeviceEventCallback, (pointer) & eventinfo);
}
+#endif
+ grab = device->deviceGrab.grab;
- /* Valuator event handling */
- /* Don't care about valuators for the VCP, it never sends XI events */
-
- for (i = 1; !device->isMaster && i < count; i++) {
- if ((++xV)->type == DeviceValuator) {
- int first = xV->first_valuator;
- if (xV->num_valuators
- && (!v
- || (xV->num_valuators
- && (first + xV->num_valuators > v->numAxes))))
- FatalError("Bad valuators reported for device %s\n",
- device->name);
- xV->device_state = 0;
- if (k)
- xV->device_state |= k->state;
- if (b)
- xV->device_state |= b->state;
- }
+ switch(event->type)
+ {
+ case ET_KeyPress:
+ if (!grab && CheckDeviceGrabs(device, event, 0)) {
+ device->deviceGrab.activatingKey = key;
+ return;
+ }
+ break;
+ case ET_KeyRelease:
+ if (grab && device->deviceGrab.fromPassiveGrab &&
+ (key == device->deviceGrab.activatingKey) &&
+ (device->deviceGrab.grab->type == KeyPress ||
+ device->deviceGrab.grab->type == DeviceKeyPress ||
+ device->deviceGrab.grab->type == XI_KeyPress))
+ deactivateDeviceGrab = TRUE;
+ break;
+ case ET_ButtonPress:
+ event->detail.button = b->map[key];
+ if (!event->detail.button) { /* there's no button 0 */
+ event->detail.button = key;
+ return;
+ }
+ if (!grab && CheckDeviceGrabs(device, event, 0))
+ {
+ /* if a passive grab was activated, the event has been sent
+ * already */
+ return;
+ }
+ break;
+ case ET_ButtonRelease:
+ event->detail.button = b->map[key];
+ if (!event->detail.button) { /* there's no button 0 */
+ event->detail.button = key;
+ return;
+ }
+ if (grab && !b->buttonsDown &&
+ device->deviceGrab.fromPassiveGrab &&
+ (device->deviceGrab.grab->type == ButtonPress ||
+ device->deviceGrab.grab->type == DeviceButtonPress ||
+ device->deviceGrab.grab->type == XI_ButtonPress))
+ deactivateDeviceGrab = TRUE;
+ default:
+ break;
}
- if (xE->u.u.type == DeviceKeyPress) {
- if (ret == IS_REPEAT) { /* allow ddx to generate multiple downs */
- modifiers = k->modifierMap[key];
- if (!modifiers) {
- xE->u.u.type = DeviceKeyRelease;
- ProcessOtherEvent(xE, device, count);
- xE->u.u.type = DeviceKeyPress;
- /* release can have side effects, don't fall through */
- ProcessOtherEvent(xE, device, count);
- }
- return;
- }
- if (!grab && CheckDeviceGrabs(device, xE, 0, count)) {
- device->deviceGrab.activatingKey = key;
- return;
- }
- } else if (xE->u.u.type == DeviceKeyRelease) {
- if (device->deviceGrab.fromPassiveGrab &&
- (key == device->deviceGrab.activatingKey))
- deactivateDeviceGrab = TRUE;
- } else if (xE->u.u.type == DeviceButtonPress) {
- xE->u.u.detail = b->map[key];
- if (xE->u.u.detail == 0) {
- xE->u.u.detail = key;
- return;
- }
- if (!grab && CheckDeviceGrabs(device, xE, 0, count))
- {
- /* if a passive grab was activated, the event has been sent
- * already */
- return;
- }
-
- } else if (xE->u.u.type == DeviceButtonRelease) {
- xE->u.u.detail = b->map[key];
- if (xE->u.u.detail == 0) {
- xE->u.u.detail = key;
- return;
- }
- if (!b->buttonsDown && device->deviceGrab.fromPassiveGrab)
- deactivateDeviceGrab = TRUE;
- }
if (grab)
- DeliverGrabbedEvent(xE, device, deactivateDeviceGrab, count);
- else if (device->focus && !IsPointerEvent(xE))
- DeliverFocusedEvent(device, xE, GetSpriteWindow(device), count);
+ DeliverGrabbedEvent((InternalEvent*)event, device, deactivateDeviceGrab);
+ else if (device->focus && !IsPointerEvent((InternalEvent*)ev))
+ DeliverFocusedEvent(device, (InternalEvent*)event,
+ GetSpriteWindow(device));
else
- DeliverDeviceEvents(GetSpriteWindow(device), xE, NullGrab, NullWindow,
- device, count);
+ DeliverDeviceEvents(GetSpriteWindow(device), (InternalEvent*)event,
+ NullGrab, NullWindow, device);
if (deactivateDeviceGrab == TRUE)
(*device->deviceGrab.DeactivateGrab) (device);
- xE->u.u.detail = key;
+ event->detail.key = key;
}
-_X_EXPORT int
+int
InitProximityClassDeviceStruct(DeviceIntPtr dev)
{
ProximityClassPtr proxc;
@@ -1094,6 +1111,7 @@ InitProximityClassDeviceStruct(DeviceIntPtr dev)
proxc = (ProximityClassPtr) xalloc(sizeof(ProximityClassRec));
if (!proxc)
return FALSE;
+ proxc->sourceid = dev->id;
dev->proximity = proxc;
return TRUE;
}
@@ -1107,14 +1125,16 @@ InitProximityClassDeviceStruct(DeviceIntPtr dev)
*
* @see InitValuatorClassDeviceStruct
*/
-_X_EXPORT void
-InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, int minval, int maxval,
+void
+InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, Atom label, int minval, int maxval,
int resolution, int min_res, int max_res)
{
AxisInfoPtr ax;
if (!dev || !dev->valuator || minval > maxval)
return;
+ if (axnum >= dev->valuator->numAxes)
+ return;
ax = dev->valuator->axes + axnum;
@@ -1123,6 +1143,7 @@ InitValuatorAxisStruct(DeviceIntPtr dev, int axnum, int minval, int maxval,
ax->resolution = resolution;
ax->min_resolution = min_res;
ax->max_resolution = max_res;
+ ax->label = label;
}
static void
@@ -1143,7 +1164,8 @@ FixDeviceStateNotify(DeviceIntPtr dev, deviceStateNotify * ev, KeyClassPtr k,
memcpy((char*)ev->buttons, (char*)b->down, 4);
} else if (k) {
ev->classes_reported |= (1 << KeyClass);
- ev->num_keys = k->curKeySyms.maxKeyCode - k->curKeySyms.minKeyCode;
+ ev->num_keys = k->xkbInfo->desc->max_key_code -
+ k->xkbInfo->desc->min_key_code;
memmove((char *)&ev->keys[0], (char *)k->down, 4);
}
if (v) {
@@ -1191,21 +1213,65 @@ DeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail,
WindowPtr pWin)
{
deviceFocus event;
+ xXIFocusInEvent *xi2event;
+ DeviceIntPtr mouse;
+ int btlen, len, i;
+
+ mouse = (IsMaster(dev) || dev->u.master) ? GetMaster(dev, MASTER_POINTER) : dev;
+
+ /* XI 2 event */
+ btlen = (mouse->button) ? bits_to_bytes(mouse->button->numButtons) : 0;
+ btlen = bytes_to_int32(btlen);
+ len = sizeof(xXIFocusInEvent) + btlen * 4;
+
+ xi2event = xcalloc(1, len);
+ xi2event->type = GenericEvent;
+ xi2event->extension = IReqCode;
+ xi2event->evtype = type;
+ xi2event->length = bytes_to_int32(len - sizeof(xEvent));
+ xi2event->buttons_len = btlen;
+ xi2event->detail = detail;
+ xi2event->time = currentTime.milliseconds;
+ xi2event->deviceid = dev->id;
+ xi2event->sourceid = dev->id; /* a device doesn't change focus by itself */
+ xi2event->mode = mode;
+ xi2event->root_x = FP1616(mouse->spriteInfo->sprite->hot.x, 0);
+ xi2event->root_y = FP1616(mouse->spriteInfo->sprite->hot.y, 0);
+
+ for (i = 0; mouse && mouse->button && i < mouse->button->numButtons; i++)
+ if (BitIsOn(mouse->button->down, i))
+ SetBit(&xi2event[1], i);
+
+ if (dev->key)
+ {
+ xi2event->mods.base_mods = dev->key->xkbInfo->state.base_mods;
+ xi2event->mods.latched_mods = dev->key->xkbInfo->state.latched_mods;
+ xi2event->mods.locked_mods = dev->key->xkbInfo->state.locked_mods;
+ xi2event->mods.effective_mods = dev->key->xkbInfo->state.mods;
+
+ xi2event->group.base_group = dev->key->xkbInfo->state.base_group;
+ xi2event->group.latched_group = dev->key->xkbInfo->state.latched_group;
+ xi2event->group.locked_group = dev->key->xkbInfo->state.locked_group;
+ xi2event->group.effective_group = dev->key->xkbInfo->state.group;
+ }
- if (type == FocusIn)
- type = DeviceFocusIn;
- else
- type = DeviceFocusOut;
+ FixUpEventFromWindow(dev, (xEvent*)xi2event, pWin, None, FALSE);
+
+ DeliverEventsToWindow(dev, pWin, (xEvent*)xi2event, 1,
+ GetEventFilter(dev, (xEvent*)xi2event), NullGrab);
+ xfree(xi2event);
+
+ /* XI 1.x event */
event.deviceid = dev->id;
event.mode = mode;
- event.type = type;
+ event.type = (type == XI_FocusIn) ? DeviceFocusIn : DeviceFocusOut;
event.detail = detail;
event.window = pWin->drawable.id;
event.time = currentTime.milliseconds;
- (void)DeliverEventsToWindow(dev, pWin, (xEvent *) & event, 1,
- DeviceFocusChangeMask, NullGrab, dev->id);
+ DeliverEventsToWindow(dev, pWin, (xEvent *) & event, 1,
+ DeviceFocusChangeMask, NullGrab);
if ((type == DeviceFocusIn) &&
(wOtherInputMasks(pWin)) &&
@@ -1227,7 +1293,8 @@ DeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail,
evcount++;
}
if ((k = dev->key) != NULL) {
- nkeys = k->curKeySyms.maxKeyCode - k->curKeySyms.minKeyCode;
+ nkeys = k->xkbInfo->desc->max_key_code -
+ k->xkbInfo->desc->min_key_code;
if (nkeys > 32)
evcount++;
if (nbuttons > 0) {
@@ -1300,147 +1367,203 @@ DeviceFocusEvent(DeviceIntPtr dev, int type, int mode, int detail,
}
}
- (void)DeliverEventsToWindow(dev, pWin, (xEvent *) sev, evcount,
- DeviceStateNotifyMask, NullGrab, dev->id);
+ DeliverEventsToWindow(dev, pWin, (xEvent *) sev, evcount,
+ DeviceStateNotifyMask, NullGrab);
xfree(sev);
}
}
int
-GrabButton(ClientPtr client, DeviceIntPtr dev, BYTE this_device_mode,
- BYTE other_devices_mode, CARD16 modifiers,
- DeviceIntPtr modifier_device, CARD8 button, Window grabWindow,
- BOOL ownerEvents, Cursor rcursor, Window rconfineTo, Mask eventMask)
+CheckGrabValues(ClientPtr client, GrabParameters* param)
{
- WindowPtr pWin, confineTo;
- CursorPtr cursor;
- GrabPtr grab;
- Mask access_mode = DixGrabAccess;
- int rc;
+ if (param->grabtype != GRABTYPE_CORE &&
+ param->grabtype != GRABTYPE_XI &&
+ param->grabtype != GRABTYPE_XI2)
+ {
+ ErrorF("[Xi] grabtype is invalid. This is a bug.\n");
+ return BadImplementation;
+ }
- if ((this_device_mode != GrabModeSync) &&
- (this_device_mode != GrabModeAsync)) {
- client->errorValue = this_device_mode;
+ if ((param->this_device_mode != GrabModeSync) &&
+ (param->this_device_mode != GrabModeAsync)) {
+ client->errorValue = param->this_device_mode;
return BadValue;
}
- if ((other_devices_mode != GrabModeSync) &&
- (other_devices_mode != GrabModeAsync)) {
- client->errorValue = other_devices_mode;
+ if ((param->other_devices_mode != GrabModeSync) &&
+ (param->other_devices_mode != GrabModeAsync)) {
+ client->errorValue = param->other_devices_mode;
return BadValue;
}
- if ((modifiers != AnyModifier) && (modifiers & ~AllModifiersMask)) {
- client->errorValue = modifiers;
+
+ if (param->grabtype != GRABTYPE_XI2 && (param->modifiers != AnyModifier) &&
+ (param->modifiers & ~AllModifiersMask)) {
+ client->errorValue = param->modifiers;
return BadValue;
}
- if ((ownerEvents != xFalse) && (ownerEvents != xTrue)) {
- client->errorValue = ownerEvents;
+
+ if ((param->ownerEvents != xFalse) && (param->ownerEvents != xTrue)) {
+ client->errorValue = param->ownerEvents;
return BadValue;
}
- rc = dixLookupWindow(&pWin, grabWindow, client, DixSetAttrAccess);
+ return Success;
+}
+
+int
+GrabButton(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr modifier_device,
+ int button, GrabParameters *param, GrabType grabtype,
+ GrabMask *mask)
+{
+ WindowPtr pWin, confineTo;
+ CursorPtr cursor;
+ GrabPtr grab;
+ int rc, type = -1;
+ Mask access_mode = DixGrabAccess;
+
+ rc = CheckGrabValues(client, param);
if (rc != Success)
return rc;
- if (rconfineTo == None)
+ if (param->confineTo == None)
confineTo = NullWindow;
else {
- rc = dixLookupWindow(&confineTo, rconfineTo, client, DixSetAttrAccess);
+ rc = dixLookupWindow(&confineTo, param->confineTo, client, DixSetAttrAccess);
if (rc != Success)
return rc;
}
- if (rcursor == None)
+ if (param->cursor == None)
cursor = NullCursor;
else {
- rc = dixLookupResourceByType((pointer *)&cursor, rcursor, RT_CURSOR,
- client, DixUseAccess);
+ rc = dixLookupResourceByType((pointer *)&cursor, param->cursor,
+ RT_CURSOR, client, DixUseAccess);
if (rc != Success)
{
- client->errorValue = rcursor;
+ client->errorValue = param->cursor;
return (rc == BadValue) ? BadCursor : rc;
}
access_mode |= DixForceAccess;
}
- if (this_device_mode == GrabModeSync || other_devices_mode == GrabModeSync)
+ if (param->this_device_mode == GrabModeSync || param->other_devices_mode == GrabModeSync)
access_mode |= DixFreezeAccess;
rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode);
if (rc != Success)
return rc;
+ rc = dixLookupWindow(&pWin, param->grabWindow, client, DixSetAttrAccess);
+ if (rc != Success)
+ return rc;
- grab = CreateGrab(client->index, dev, pWin, eventMask,
- (Bool) ownerEvents, (Bool) this_device_mode,
- (Bool) other_devices_mode, modifier_device, modifiers,
- DeviceButtonPress, button, confineTo, cursor);
+ if (grabtype == GRABTYPE_XI)
+ type = DeviceButtonPress;
+ else if (grabtype == GRABTYPE_XI2)
+ type = XI_ButtonPress;
+
+ grab = CreateGrab(client->index, dev, modifier_device, pWin, grabtype,
+ mask, param, type, button, confineTo, cursor);
if (!grab)
return BadAlloc;
return AddPassiveGrabToList(client, grab);
}
+/**
+ * Grab the given key. If grabtype is GRABTYPE_XI, the key is a keycode. If
+ * grabtype is GRABTYPE_XI2, the key is a keysym.
+ */
int
-GrabKey(ClientPtr client, DeviceIntPtr dev, BYTE this_device_mode,
- BYTE other_devices_mode, CARD16 modifiers,
- DeviceIntPtr modifier_device, CARD8 key, Window grabWindow,
- BOOL ownerEvents, Mask mask)
+GrabKey(ClientPtr client, DeviceIntPtr dev, DeviceIntPtr modifier_device,
+ int key, GrabParameters *param, GrabType grabtype, GrabMask *mask)
{
WindowPtr pWin;
GrabPtr grab;
KeyClassPtr k = dev->key;
Mask access_mode = DixGrabAccess;
- int rc;
+ int rc, type = -1;
+ rc = CheckGrabValues(client, param);
+ if (rc != Success)
+ return rc;
if (k == NULL)
return BadMatch;
- if ((other_devices_mode != GrabModeSync) &&
- (other_devices_mode != GrabModeAsync)) {
- client->errorValue = other_devices_mode;
- return BadValue;
- }
- if ((this_device_mode != GrabModeSync) &&
- (this_device_mode != GrabModeAsync)) {
- client->errorValue = this_device_mode;
- return BadValue;
- }
- if (((key > k->curKeySyms.maxKeyCode) || (key < k->curKeySyms.minKeyCode))
- && (key != AnyKey)) {
- client->errorValue = key;
- return BadValue;
- }
- if ((modifiers != AnyModifier) && (modifiers & ~AllModifiersMask)) {
- client->errorValue = modifiers;
- return BadValue;
- }
- if ((ownerEvents != xTrue) && (ownerEvents != xFalse)) {
- client->errorValue = ownerEvents;
- return BadValue;
- }
- rc = dixLookupWindow(&pWin, grabWindow, client, DixSetAttrAccess);
+ if (grabtype == GRABTYPE_XI)
+ {
+ if ((key > k->xkbInfo->desc->max_key_code ||
+ key < k->xkbInfo->desc->min_key_code)
+ && (key != AnyKey)) {
+ client->errorValue = key;
+ return BadValue;
+ }
+ type = DeviceKeyPress;
+ } else if (grabtype == GRABTYPE_XI2)
+ type = XI_KeyPress;
+
+ rc = dixLookupWindow(&pWin, param->grabWindow, client, DixSetAttrAccess);
if (rc != Success)
return rc;
- if (this_device_mode == GrabModeSync || other_devices_mode == GrabModeSync)
+ if (param->this_device_mode == GrabModeSync || param->other_devices_mode == GrabModeSync)
access_mode |= DixFreezeAccess;
rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode);
if (rc != Success)
return rc;
- grab = CreateGrab(client->index, dev, pWin,
- mask, ownerEvents, this_device_mode, other_devices_mode,
- modifier_device, modifiers, DeviceKeyPress, key,
- NullWindow, NullCursor);
+ grab = CreateGrab(client->index, dev, modifier_device, pWin, grabtype,
+ mask, param, type, key, NULL, NULL);
if (!grab)
return BadAlloc;
return AddPassiveGrabToList(client, grab);
}
+/* Enter/FocusIn grab */
+int
+GrabWindow(ClientPtr client, DeviceIntPtr dev, int type,
+ GrabParameters *param, GrabMask *mask)
+{
+ WindowPtr pWin;
+ CursorPtr cursor;
+ GrabPtr grab;
+ Mask access_mode = DixGrabAccess;
+ int rc;
+
+ rc = CheckGrabValues(client, param);
+ if (rc != Success)
+ return rc;
+
+ rc = dixLookupWindow(&pWin, param->grabWindow, client, DixSetAttrAccess);
+ if (rc != Success)
+ return rc;
+ if (param->cursor == None)
+ cursor = NullCursor;
+ else {
+ rc = dixLookupResourceByType((pointer *)&cursor, param->cursor,
+ RT_CURSOR, client, DixUseAccess);
+ if (rc != Success)
+ {
+ client->errorValue = param->cursor;
+ return (rc == BadValue) ? BadCursor : rc;
+ }
+ access_mode |= DixForceAccess;
+ }
+ if (param->this_device_mode == GrabModeSync || param->other_devices_mode == GrabModeSync)
+ access_mode |= DixFreezeAccess;
+ rc = XaceHook(XACE_DEVICE_ACCESS, client, dev, access_mode);
+ if (rc != Success)
+ return rc;
+
+ grab = CreateGrab(client->index, dev, dev, pWin, GRABTYPE_XI2,
+ mask, param, (type == XIGrabtypeEnter) ? XI_Enter : XI_FocusIn,
+ 0, NULL, cursor);
+
+ if (!grab)
+ return BadAlloc;
+
+ return AddPassiveGrabToList(client, grab);
+}
+
int
SelectForWindow(DeviceIntPtr dev, WindowPtr pWin, ClientPtr client,
- Mask mask, Mask exclusivemasks, Mask validmasks)
+ Mask mask, Mask exclusivemasks)
{
int mskidx = dev->id;
int i, ret;
Mask check;
InputClientsPtr others;
- if (mask & ~validmasks) {
- client->errorValue = mask;
- return BadValue;
- }
check = (mask & exclusivemasks);
if (wOtherInputMasks(pWin)) {
if (check & wOtherInputMasks(pWin)->inputEvents[mskidx]) { /* It is illegal for two different
@@ -1528,15 +1651,20 @@ RecalculateDeviceDeliverableEvents(WindowPtr pWin)
InputClientsPtr others;
struct _OtherInputMasks *inputMasks; /* default: NULL */
WindowPtr pChild, tmp;
- int i;
+ int i, j;
pChild = pWin;
while (1) {
if ((inputMasks = wOtherInputMasks(pChild)) != 0) {
+ for (i = 0; i < EMASKSIZE; i++)
+ memset(inputMasks->xi2mask[i], 0, sizeof(inputMasks->xi2mask[i]));
for (others = inputMasks->inputClients; others;
others = others->next) {
for (i = 0; i < EMASKSIZE; i++)
inputMasks->inputEvents[i] |= others->mask[i];
+ for (i = 0; i < EMASKSIZE; i++)
+ for (j = 0; j < XI2MASKSIZE; j++)
+ inputMasks->xi2mask[i][j] |= others->xi2mask[i][j];
}
for (i = 0; i < EMASKSIZE; i++)
inputMasks->deliverableEvents[i] = inputMasks->inputEvents[i];
@@ -1644,7 +1772,7 @@ SendEvent(ClientPtr client, DeviceIntPtr d, Window dest, Bool propagate,
ev->u.u.type |= 0x80;
if (propagate) {
for (; pWin; pWin = pWin->parent) {
- if (DeliverEventsToWindow(d, pWin, ev, count, mask, NullGrab, d->id))
+ if (DeliverEventsToWindow(d, pWin, ev, count, mask, NullGrab))
return Success;
if (pWin == effectiveFocus)
return Success;
@@ -1654,7 +1782,7 @@ SendEvent(ClientPtr client, DeviceIntPtr d, Window dest, Bool propagate,
break;
}
} else if (!XaceHook(XACE_SEND_ACCESS, client, NULL, pWin, ev, count))
- (void)(DeliverEventsToWindow(d, pWin, ev, count, mask, NullGrab, d->id));
+ DeliverEventsToWindow(d, pWin, ev, count, mask, NullGrab);
return Success;
}
@@ -1682,111 +1810,6 @@ SetButtonMapping(ClientPtr client, DeviceIntPtr dev, int nElts, BYTE * map)
}
int
-SetModifierMapping(ClientPtr client, DeviceIntPtr dev, int len, int rlen,
- int numKeyPerModifier, KeyCode * inputMap, KeyClassPtr * k)
-{
- KeyCode *map = NULL;
- int inputMapLen;
- int i;
-
- *k = dev->key;
- if (*k == NULL)
- return BadMatch;
- if (len != ((numKeyPerModifier << 1) + rlen))
- return BadLength;
-
- inputMapLen = 8 * numKeyPerModifier;
-
- /*
- * Now enforce the restriction that "all of the non-zero keycodes must be
- * in the range specified by min-keycode and max-keycode in the
- * connection setup (else a Value error)"
- */
- i = inputMapLen;
- while (i--) {
- if (inputMap[i]
- && (inputMap[i] < (*k)->curKeySyms.minKeyCode
- || inputMap[i] > (*k)->curKeySyms.maxKeyCode)) {
- client->errorValue = inputMap[i];
- return -1; /* BadValue collides with MappingFailed */
- }
- }
-
- /*
- * Now enforce the restriction that none of the old or new
- * modifier keys may be down while we change the mapping, and
- * that the DDX layer likes the choice.
- */
- if (!AllModifierKeysAreUp(dev, (*k)->modifierKeyMap,
- (int)(*k)->maxKeysPerModifier, inputMap,
- (int)numKeyPerModifier)
- || !AllModifierKeysAreUp(dev, inputMap, (int)numKeyPerModifier,
- (*k)->modifierKeyMap,
- (int)(*k)->maxKeysPerModifier)) {
- return MappingBusy;
- } else {
- for (i = 0; i < inputMapLen; i++) {
- if (inputMap[i] && !LegalModifier(inputMap[i], dev)) {
- return MappingFailed;
- }
- }
- }
-
- /*
- * Now build the keyboard's modifier bitmap from the
- * list of keycodes.
- */
- if (inputMapLen) {
- map = (KeyCode *) xalloc(inputMapLen);
- if (!map)
- return BadAlloc;
- }
- if ((*k)->modifierKeyMap)
- xfree((*k)->modifierKeyMap);
- if (inputMapLen) {
- (*k)->modifierKeyMap = map;
- memmove((char *)(*k)->modifierKeyMap, (char *)inputMap, inputMapLen);
- } else
- (*k)->modifierKeyMap = NULL;
-
- (*k)->maxKeysPerModifier = numKeyPerModifier;
- for (i = 0; i < MAP_LENGTH; i++)
- (*k)->modifierMap[i] = 0;
- for (i = 0; i < inputMapLen; i++)
- if (inputMap[i]) {
- (*k)->modifierMap[inputMap[i]]
- |= (1 << (i / (*k)->maxKeysPerModifier));
- }
-
- return (MappingSuccess);
-}
-
-void
-SendDeviceMappingNotify(ClientPtr client, CARD8 request,
- KeyCode firstKeyCode, CARD8 count, DeviceIntPtr dev)
-{
- xEvent event;
- deviceMappingNotify *ev = (deviceMappingNotify *) & event;
-
- ev->type = DeviceMappingNotify;
- ev->request = request;
- ev->deviceid = dev->id;
- ev->time = currentTime.milliseconds;
- if (request == MappingKeyboard) {
- ev->firstKeyCode = firstKeyCode;
- ev->count = count;
- }
-
-#ifdef XKB
- if (!noXkbExtension && (request == MappingKeyboard ||
- request == MappingModifier))
- XkbApplyMappingChange(dev, request, firstKeyCode, count, client);
-#endif
-
- SendEventToAllWindows(dev, DeviceMappingNotifyMask, (xEvent *) ev, 1);
-}
-
-int
ChangeKeyMapping(ClientPtr client,
DeviceIntPtr dev,
unsigned len,
@@ -1803,8 +1826,8 @@ ChangeKeyMapping(ClientPtr client,
if (len != (keyCodes * keySymsPerKeyCode))
return BadLength;
- if ((firstKeyCode < k->curKeySyms.minKeyCode) ||
- (firstKeyCode + keyCodes - 1 > k->curKeySyms.maxKeyCode)) {
+ if ((firstKeyCode < k->xkbInfo->desc->min_key_code) ||
+ (firstKeyCode + keyCodes - 1 > k->xkbInfo->desc->max_key_code)) {
client->errorValue = firstKeyCode;
return BadValue;
}
@@ -1816,9 +1839,10 @@ ChangeKeyMapping(ClientPtr client,
keysyms.maxKeyCode = firstKeyCode + keyCodes - 1;
keysyms.mapWidth = keySymsPerKeyCode;
keysyms.map = map;
- if (!SetKeySymsMap(&k->curKeySyms, &keysyms))
- return BadAlloc;
- SendDeviceMappingNotify(client, MappingKeyboard, firstKeyCode, keyCodes, dev);
+
+ XkbApplyMappingChange(dev, &keysyms, firstKeyCode, keyCodes, NULL,
+ serverClient);
+
return client->noClientException;
}
@@ -1847,7 +1871,8 @@ DeleteDeviceFromAnyExtEvents(WindowPtr pWin, DeviceIntPtr dev)
switch (dev->focus->revert) {
case RevertToNone:
- DoFocusEvents(dev, pWin, NoneWin, focusEventMode);
+ if (!ActivateFocusInGrab(dev, pWin, NoneWin))
+ DoFocusEvents(dev, pWin, NoneWin, focusEventMode);
dev->focus->win = NoneWin;
dev->focus->traceGood = 0;
break;
@@ -1858,26 +1883,34 @@ DeleteDeviceFromAnyExtEvents(WindowPtr pWin, DeviceIntPtr dev)
dev->focus->traceGood--;
}
while (!parent->realized);
- DoFocusEvents(dev, pWin, parent, focusEventMode);
+ if (!ActivateFocusInGrab(dev, pWin, parent))
+ DoFocusEvents(dev, pWin, parent, focusEventMode);
dev->focus->win = parent;
dev->focus->revert = RevertToNone;
break;
case RevertToPointerRoot:
- DoFocusEvents(dev, pWin, PointerRootWin, focusEventMode);
+ if (!ActivateFocusInGrab(dev, pWin, PointerRootWin))
+ DoFocusEvents(dev, pWin, PointerRootWin, focusEventMode);
dev->focus->win = PointerRootWin;
dev->focus->traceGood = 0;
break;
case RevertToFollowKeyboard:
- if (inputInfo.keyboard->focus->win) {
- DoFocusEvents(dev, pWin, inputInfo.keyboard->focus->win,
- focusEventMode);
+ {
+ DeviceIntPtr kbd = GetMaster(dev, MASTER_KEYBOARD);
+ if (!kbd || (kbd == dev && kbd != inputInfo.keyboard))
+ kbd = inputInfo.keyboard;
+ if (kbd->focus->win) {
+ if (!ActivateFocusInGrab(dev, pWin, kbd->focus->win))
+ DoFocusEvents(dev, pWin, kbd->focus->win, focusEventMode);
dev->focus->win = FollowKeyboardWin;
dev->focus->traceGood = 0;
} else {
- DoFocusEvents(dev, pWin, NoneWin, focusEventMode);
+ if (!ActivateFocusInGrab(dev, pWin, NoneWin))
+ DoFocusEvents(dev, pWin, NoneWin, focusEventMode);
dev->focus->win = NoneWin;
dev->focus->traceGood = 0;
}
+ }
break;
}
}
@@ -1896,8 +1929,6 @@ DeleteWindowFromAnyExtEvents(WindowPtr pWin, Bool freeResources)
struct _OtherInputMasks *inputMasks;
for (dev = inputInfo.devices; dev; dev = dev->next) {
- if (dev == inputInfo.pointer || dev == inputInfo.keyboard)
- continue;
DeleteDeviceFromAnyExtEvents(pWin, dev);
}
@@ -1944,7 +1975,7 @@ CheckDeviceGrabAndHintWindow(WindowPtr pWin, int type,
DeviceIntPtr dev;
dixLookupDevice(&dev, xE->deviceid & DEVICE_BITS, serverClient,
- DixReadAccess);
+ DixGrabAccess);
if (!dev)
return;
@@ -1964,7 +1995,6 @@ CheckDeviceGrabAndHintWindow(WindowPtr pWin, int type,
tempGrab.pointerMode = GrabModeAsync;
tempGrab.confineTo = NullWindow;
tempGrab.cursor = NullCursor;
- tempGrab.genericMasks = NULL;
tempGrab.next = NULL;
(*dev->deviceGrab.ActivateGrab) (dev, &tempGrab, currentTime, TRUE);
}
@@ -2063,7 +2093,7 @@ FindInterestedChildren(DeviceIntPtr dev, WindowPtr p1, Mask mask,
while (p1) {
p2 = p1->firstChild;
- (void)DeliverEventsToWindow(dev, p1, ev, count, mask, NullGrab, dev->id);
+ DeliverEventsToWindow(dev, p1, ev, count, mask, NullGrab);
FindInterestedChildren(dev, p2, mask, ev, count);
p1 = p1->nextSib;
}
@@ -2085,9 +2115,56 @@ SendEventToAllWindows(DeviceIntPtr dev, Mask mask, xEvent * ev, int count)
pWin = WindowTable[i];
if (!pWin)
continue;
- (void)DeliverEventsToWindow(dev, pWin, ev, count, mask, NullGrab, dev->id);
+ DeliverEventsToWindow(dev, pWin, ev, count, mask, NullGrab);
p1 = pWin->firstChild;
FindInterestedChildren(dev, p1, mask, ev, count);
}
}
+/**
+ * Set the XI2 mask for the given client on the given window.
+ * @param dev The device to set the mask for.
+ * @param win The window to set the mask on.
+ * @param client The client setting the mask.
+ * @param len Number of bytes in mask.
+ * @param mask Event mask in the form of (1 << eventtype)
+ */
+int
+XISetEventMask(DeviceIntPtr dev, WindowPtr win, ClientPtr client,
+ unsigned int len, unsigned char* mask)
+{
+ OtherInputMasks *masks;
+ InputClientsPtr others = NULL;
+
+ masks = wOtherInputMasks(win);
+ if (masks)
+ {
+ for (others = wOtherInputMasks(win)->inputClients; others;
+ others = others->next) {
+ if (SameClient(others, client)) {
+ memset(others->xi2mask[dev->id], 0,
+ sizeof(others->xi2mask[dev->id]));
+ break;
+ }
+ }
+ }
+
+ len = min(len, sizeof(others->xi2mask[dev->id]));
+
+ if (len && !others)
+ {
+ if (AddExtensionClient(win, client, 0, 0) != Success)
+ return BadAlloc;
+ others= wOtherInputMasks(win)->inputClients;
+ }
+
+ if (others)
+ memset(others->xi2mask[dev->id], 0, sizeof(others->xi2mask[dev->id]));
+
+ if (len)
+ memcpy(others->xi2mask[dev->id], mask, len);
+
+ RecalculateDeviceDeliverableEvents(win);
+
+ return Success;
+}