summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Xi/Makefile.am2
-rw-r--r--Xi/chpkpair.c12
-rw-r--r--Xi/extinit.c8
-rw-r--r--Xi/regpair.c108
-rw-r--r--Xi/regpair.h43
-rw-r--r--dix/devices.c52
-rw-r--r--dix/dispatch.c1
-rw-r--r--include/input.h7
8 files changed, 232 insertions, 1 deletions
diff --git a/Xi/Makefile.am b/Xi/Makefile.am
index 90000308d..5d3417e65 100644
--- a/Xi/Makefile.am
+++ b/Xi/Makefile.am
@@ -62,6 +62,8 @@ libXi_la_SOURCES = \
querydp.h \
queryst.c \
queryst.h \
+ regpair.c \
+ regpair.h \
selectev.c \
selectev.h \
sendexev.c \
diff --git a/Xi/chpkpair.c b/Xi/chpkpair.c
index b8624178d..8e79a7502 100644
--- a/Xi/chpkpair.c
+++ b/Xi/chpkpair.c
@@ -73,10 +73,13 @@ int
ProcXChangePointerKeyboardPairing(register ClientPtr client)
{
DeviceIntPtr pPointer, pKeyboard;
+ int ret;
REQUEST(xChangePointerKeyboardPairingReq);
REQUEST_SIZE_MATCH(xChangePointerKeyboardPairingReq);
+ /* check if client is registered */
+
pPointer = LookupDeviceIntRec(stuff->pointer);
if (pPointer == NULL)
{
@@ -93,7 +96,14 @@ ProcXChangePointerKeyboardPairing(register ClientPtr client)
return Success;
}
- pKeyboard->pSprite = pPointer->pSprite;
+ ret = PairDevices(client, pPointer, pKeyboard);
+ if (ret != Success)
+ {
+ SendErrorToClient(client, IReqCode, X_ChangePointerKeyboardPairing,
+ 0, ret);
+ return Success;
+ }
+
/* TODO: generate event here... */
return Success;
diff --git a/Xi/extinit.c b/Xi/extinit.c
index a08ec77fa..cf4f509e9 100644
--- a/Xi/extinit.c
+++ b/Xi/extinit.c
@@ -102,6 +102,7 @@ SOFTWARE.
#include "opendev.h"
#include "querydp.h"
#include "queryst.h"
+#include "regpair.h"
#include "selectev.h"
#include "sendexev.h"
#include "chgkmap.h"
@@ -355,6 +356,8 @@ ProcIDispatch(register ClientPtr client)
return (ProcXChangeDeviceCursor(client));
else if (stuff->data == X_ChangePointerKeyboardPairing)
return (ProcXChangePointerKeyboardPairing(client));
+ else if (stuff->data == X_RegisterPairingClient)
+ return (ProcXRegisterPairingClient(client));
else {
SendErrorToClient(client, IReqCode, stuff->data, 0, BadRequest);
}
@@ -452,6 +455,8 @@ SProcIDispatch(register ClientPtr client)
return (SProcXChangeDeviceCursor(client));
else if (stuff->data == X_ChangePointerKeyboardPairing)
return (SProcXChangePointerKeyboardPairing(client));
+ else if (stuff->data == X_RegisterPairingClient)
+ return (SProcXRegisterPairingClient(client));
else {
SendErrorToClient(client, IReqCode, stuff->data, 0, BadRequest);
}
@@ -527,6 +532,9 @@ SReplyIDispatch(ClientPtr client, int len, xGrabDeviceReply * rep)
else if (rep->RepType == X_QueryDevicePointer)
SRepXQueryDevicePointer(client, len,
(xQueryDevicePointerReply *) rep);
+ else if (rep->RepType == X_RegisterPairingClient)
+ SRepXRegisterPairingClient(client, len,
+ (xRegisterPairingClientReply *) rep);
else {
FatalError("XINPUT confused sending swapped reply");
}
diff --git a/Xi/regpair.c b/Xi/regpair.c
new file mode 100644
index 000000000..cfaddb841
--- /dev/null
+++ b/Xi/regpair.c
@@ -0,0 +1,108 @@
+/*
+
+Copyright 2007 Peter Hutterer <peter@cs.unisa.edu.au>
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice 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 AUTHOR 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.
+
+Except as contained in this notice, the name of the author shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from the author.
+
+*/
+
+/***********************************************************************
+ *
+ * Request to authenticate as pairing client
+ *
+ */
+
+#define NEED_EVENTS
+#define NEED_REPLIES
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h> /* for inputstr.h */
+#include <X11/Xproto.h> /* Request macro */
+#include "inputstr.h" /* DeviceIntPtr */
+#include "windowstr.h" /* window structure */
+#include <X11/extensions/XI.h>
+#include <X11/extensions/XIproto.h>
+#include "extnsionst.h"
+#include "exevents.h"
+#include "exglobals.h"
+
+#include "regpair.h"
+
+/***********************************************************************
+ *
+ * This procedure allows a client to register the pairing of a pointer
+ * with a keyboard.
+ *
+ */
+
+int
+SProcXRegisterPairingClient(ClientPtr client)
+{
+ char n;
+ REQUEST(xRegisterPairingClientReq);
+ swaps(&stuff->length, n);
+ return ProcXRegisterPairingClient(client);
+}
+
+int
+ProcXRegisterPairingClient(ClientPtr client)
+{
+ xRegisterPairingClientReply rep;
+
+ REQUEST(xRegisterPairingClientReq);
+ REQUEST_SIZE_MATCH(xRegisterPairingClientReq);
+
+ if (stuff->disable)
+ UnregisterPairingClient(client);
+
+ rep.repType = X_Reply;
+ rep.RepType = X_RegisterPairingClient;
+ rep.length = 0;
+ rep.sequenceNumber = client->sequence;
+ rep.success = stuff->disable || RegisterPairingClient(client);
+
+ WriteReplyToClient(client, sizeof(xRegisterPairingClientReply), &rep);
+ return Success;
+}
+
+/***********************************************************************
+ *
+ * This procedure writes the reply for the XRegisterPairingClient function,
+ * if the client and server have a different byte ordering.
+ *
+ */
+
+void
+SRepXRegisterPairingClient(ClientPtr client, int size,
+ xRegisterPairingClientReply* rep)
+{
+ register char n;
+
+ swaps(&rep->sequenceNumber, n);
+ swapl(&rep->length, n);
+ WriteToClient(client, size, (char *)rep);
+}
+
diff --git a/Xi/regpair.h b/Xi/regpair.h
new file mode 100644
index 000000000..b2bfaff3e
--- /dev/null
+++ b/Xi/regpair.h
@@ -0,0 +1,43 @@
+/*
+
+Copyright 2007 Peter Hutterer <peter@cs.unisa.edu.au>
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice 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 AUTHOR 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.
+
+Except as contained in this notice, the name of the author shall
+not be used in advertising or otherwise to promote the sale, use or
+other dealings in this Software without prior written authorization
+from the author.
+
+*/
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef REGPAIR_H
+#define REGPAIR_H 1
+
+int SProcXRegisterPairingClient(ClientPtr /* client */);
+int ProcXRegisterPairingClient(ClientPtr /* client */);
+
+void SRepXRegisterPairingClient(ClientPtr /* client */,
+ int /* size */,
+ xRegisterPairingClientReply* /* rep */);
+
+#endif /* REGPAIR_H */
diff --git a/dix/devices.c b/dix/devices.c
index bc7ca892c..ad5cd5042 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -81,6 +81,9 @@ SOFTWARE.
int CoreDevicePrivatesIndex = 0, CoreDevicePrivatesGeneration = -1;
+/* The client that is allowed to change pointer-keyboard pairings. */
+static ClientPtr pairingClient = NULL;
+
DeviceIntPtr
AddInputDevice(DeviceProc deviceProc, Bool autoStart)
{
@@ -1926,5 +1929,54 @@ ProcQueryKeymap(ClientPtr client)
bzero((char *)&rep.map[0], 32);
WriteReplyToClient(client, sizeof(xQueryKeymapReply), &rep);
+
+ return Success;
+}
+
+/* Pair the keyboard to the pointer device. Keyboard events will follow the
+ * pointer sprite.
+ */
+int
+PairDevices(ClientPtr client, DeviceIntPtr pointer, DeviceIntPtr keyboard)
+{
+ if (!pairingClient)
+ RegisterPairingClient(client);
+ else if (pairingClient != client)
+ return BadAccess;
+
+ keyboard->pSprite = pointer->pSprite;
return Success;
}
+
+/*
+ * Register a client to be able to pair devices.
+ */
+Bool
+RegisterPairingClient(ClientPtr client)
+{
+ if (!pairingClient)
+ {
+ pairingClient = client;
+ } else if (pairingClient != client)
+ {
+ return False;
+ }
+ return True;
+}
+
+/*
+ * Unregister pairing client;
+ */
+Bool
+UnregisterPairingClient(ClientPtr client)
+{
+ if (pairingClient)
+ {
+ if ( pairingClient == client)
+ {
+ pairingClient = NULL;
+ } else
+ return False;
+ }
+ return True;
+}
diff --git a/dix/dispatch.c b/dix/dispatch.c
index d44687ec3..a795d17a5 100644
--- a/dix/dispatch.c
+++ b/dix/dispatch.c
@@ -3568,6 +3568,7 @@ CloseDownClient(register ClientPtr client)
DeleteClientFromAnySelections(client);
ReleaseActiveGrabs(client);
DeleteClientFontStuff(client);
+ UnregisterPairingClient(client); /* other clients can pair devices */
if (!really_close_down)
{
/* This frees resources that should never be retained
diff --git a/include/input.h b/include/input.h
index 96a28a5a1..d2e26efc1 100644
--- a/include/input.h
+++ b/include/input.h
@@ -454,4 +454,11 @@ extern void DDXRingBell(
int pitch,
int duration);
+extern int PairDevices(ClientPtr client,
+ DeviceIntPtr pointer,
+ DeviceIntPtr keyboard);
+
+extern Bool RegisterPairingClient(ClientPtr client);
+extern Bool UnregisterPairingClient(ClientPtr client);
+
#endif /* INPUT_H */