diff options
-rw-r--r-- | Xi/Makefile.am | 2 | ||||
-rw-r--r-- | Xi/chpkpair.c | 12 | ||||
-rw-r--r-- | Xi/extinit.c | 8 | ||||
-rw-r--r-- | Xi/regpair.c | 108 | ||||
-rw-r--r-- | Xi/regpair.h | 43 | ||||
-rw-r--r-- | dix/devices.c | 52 | ||||
-rw-r--r-- | dix/dispatch.c | 1 | ||||
-rw-r--r-- | include/input.h | 7 |
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 */ |