summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPeter Hutterer <peter@cs.unisa.edu.au>2007-10-19 14:36:37 +0930
committerPeter Hutterer <peter@cs.unisa.edu.au>2007-10-19 14:36:37 +0930
commit5ba738935f0d786e4670adf3b05ad42fc5e710fd (patch)
tree56db5c2939989c23fa562b3acec1ceabca0d65bf
parent6dcde0e9c1d068d9fc4a772d29d1d4c6cc57aeb9 (diff)
Xi: remove ChangePointerKeyboardPairing in favour of ChangeDeviceHierarchy.
-rw-r--r--Xi/Makefile.am4
-rw-r--r--Xi/chdevhier.c231
-rw-r--r--Xi/chdevhier.h45
-rw-r--r--Xi/extinit.c14
-rw-r--r--dix/devices.c1
5 files changed, 284 insertions, 11 deletions
diff --git a/Xi/Makefile.am b/Xi/Makefile.am
index 2cf11a042..407928df1 100644
--- a/Xi/Makefile.am
+++ b/Xi/Makefile.am
@@ -9,6 +9,8 @@ libXi_la_SOURCES = \
chdevcur.h \
chgdctl.c \
chgdctl.h \
+ chdevhier.c \
+ chdevhier.h \
chgfctl.c \
chgfctl.h \
chgkbd.c \
@@ -19,8 +21,6 @@ libXi_la_SOURCES = \
chgprop.h \
chgptr.c \
chgptr.h \
- chpkpair.c \
- chpkpair.h \
chaccess.c \
chaccess.h \
closedev.c \
diff --git a/Xi/chdevhier.c b/Xi/chdevhier.c
new file mode 100644
index 000000000..c916c0f47
--- /dev/null
+++ b/Xi/chdevhier.c
@@ -0,0 +1,231 @@
+/*
+
+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 change in the device hierarchy.
+ *
+ */
+
+
+#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 "scrnintstr.h" /* screen structure */
+#include <X11/extensions/XI.h>
+#include <X11/extensions/XInput.h>
+#include <X11/extensions/XIproto.h>
+#include <X11/extensions/geproto.h>
+#include "extnsionst.h"
+#include "extinit.h" /* LookupDeviceIntRec */
+#include "exevents.h"
+#include "exglobals.h"
+#include "geext.h"
+
+#include "chdevhier.h"
+
+
+/***********************************************************************
+ *
+ * This procedure allows a client to change the device hierarchy through
+ * adding new master devices, removing them, etc.
+ *
+ */
+
+int SProcXChangeDeviceHierarchy(ClientPtr client)
+{
+ char n;
+
+ REQUEST(xChangeDeviceHierarchyReq);
+ swaps(&stuff->length, n);
+ return (ProcXChangeDeviceHierarchy(client));
+}
+
+#define SWAPIF(cmd) if (client->swapped) { cmd; }
+
+int
+ProcXChangeDeviceHierarchy(ClientPtr client)
+{
+ DeviceIntPtr ptr, keybd;
+ xAnyHierarchyChangeInfo *any;
+ int required_len = sizeof(xChangeDeviceHierarchyReq);
+ char n;
+
+ REQUEST(xChangeDeviceHierarchyReq);
+ REQUEST_AT_LEAST_SIZE(xChangeDeviceHierarchyReq);
+
+ /* XXX: check if client is allowed to change hierarch */
+
+
+ any = (xAnyHierarchyChangeInfo*)&stuff[1];
+ while(stuff->num_changes--)
+ {
+ SWAPIF(swapl(&any->type, n));
+ SWAPIF(swaps(&any->length, n));
+
+ required_len += any->length;
+ if ((stuff->length * 4) < required_len)
+ return BadLength;
+
+ switch(any->type)
+ {
+ case CH_CreateMasterDevice:
+ {
+ xCreateMasterInfo* c = (xCreateMasterInfo*)any;
+ char* name;
+ int ret;
+
+ SWAPIF(swaps(&c->namelen, n));
+ name = xcalloc(c->namelen + 1, sizeof(char));
+ strncpy(name, (char*)&c[1], c->namelen);
+
+ ret = AllocMasterDevice(name, &ptr, &keybd);
+ if (ret != Success)
+ {
+ xfree(name);
+ return ret;
+ }
+
+ if (!c->sendCore)
+ ptr->coreEvents = keybd->coreEvents = FALSE;
+
+ ActivateDevice(ptr);
+ ActivateDevice(keybd);
+
+ if (c->enable)
+ {
+ EnableDevice(ptr);
+ EnableDevice(keybd);
+ }
+ xfree(name);
+ }
+ break;
+ case CH_RemoveMasterDevice:
+ {
+ xRemoveMasterInfo* r = (xRemoveMasterInfo*)any;
+
+ if (r->returnMode != AttachToMaster &&
+ r->returnMode != Floating)
+ return BadValue;
+
+ ptr = LookupDeviceIntRec(r->deviceid);
+ if (!ptr || !ptr->isMaster)
+ return BadDevice;
+
+ /* XXX: For now, don't allow removal of VCP, VCK */
+ if (ptr == inputInfo.pointer ||
+ ptr == inputInfo.keyboard)
+ return BadDevice;
+
+ /* disable keyboards first */
+ if (IsPointerDevice(ptr))
+ keybd = ptr->spriteInfo->paired;
+ else
+ {
+ keybd = ptr;
+ ptr = keybd->spriteInfo->paired;
+ }
+
+ /* Disabling sends the devices floating, reattach them if
+ * desired. */
+ if (r->returnMode == AttachToMaster)
+ {
+ DeviceIntPtr attached,
+ newptr,
+ newkeybd;
+
+ newptr = LookupDeviceIntRec(r->returnPointer);
+ newkeybd = LookupDeviceIntRec(r->returnKeyboard);
+ if (!newptr || !newptr->isMaster ||
+ !newkeybd || !newkeybd->isMaster)
+ return BadDevice;
+
+ for (attached = inputInfo.devices;
+ attached;
+ attached = attached->next)
+ {
+ if (!attached->isMaster) {
+ if (attached->u.master == ptr)
+ AttachDevice(client, attached, newptr);
+ if (attached->u.master == keybd)
+ AttachDevice(client, attached, newkeybd);
+ }
+ }
+ }
+
+ /* can't disable until we removed pairing */
+ keybd->spriteInfo->paired = NULL;
+ ptr->spriteInfo->paired = NULL;
+ DisableDevice(keybd);
+ DisableDevice(ptr);
+
+ RemoveDevice(keybd);
+ RemoveDevice(ptr);
+ }
+ break;
+ case CH_ChangeAttachment:
+ {
+ xChangeAttachmentInfo* c = (xChangeAttachmentInfo*)any;
+
+ ptr = LookupDeviceIntRec(c->deviceid);
+ if (!ptr || ptr->isMaster)
+ return BadDevice;
+
+ if (c->changeMode == Floating)
+ AttachDevice(client, ptr, NULL);
+ else
+ {
+ DeviceIntPtr newmaster = LookupDeviceIntRec(c->newMaster);
+ if (!newmaster || !newmaster->isMaster)
+ return BadDevice;
+
+ if ((IsPointerDevice(newmaster) &&
+ !IsPointerDevice(ptr)) ||
+ (IsKeyboardDevice(newmaster) &&
+ !IsKeyboardDevice(ptr)))
+ return BadDevice;
+ AttachDevice(client, ptr, newmaster);
+ }
+
+ }
+ break;
+ }
+
+ any = (xAnyHierarchyChangeInfo*)((char*)any + any->length);
+ }
+
+ return Success;
+}
+
diff --git a/Xi/chdevhier.h b/Xi/chdevhier.h
new file mode 100644
index 000000000..1853fa720
--- /dev/null
+++ b/Xi/chdevhier.h
@@ -0,0 +1,45 @@
+/*
+
+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 change in the device hierarchy.
+ *
+ */
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#ifndef CHDEVHIER_H
+#define CHDEVHIER_H 1
+
+int SProcXChangeDeviceHierarchy(ClientPtr /* client */);
+int ProcXChangeDeviceHierarchy(ClientPtr /* client */);
+
+#endif
diff --git a/Xi/extinit.c b/Xi/extinit.c
index c1b6eedae..c933e55b8 100644
--- a/Xi/extinit.c
+++ b/Xi/extinit.c
@@ -79,11 +79,11 @@ SOFTWARE.
#include "chaccess.h"
#include "chdevcur.h"
#include "chgdctl.h"
+#include "chdevhier.h"
#include "chgfctl.h"
#include "chgkbd.h"
#include "chgprop.h"
#include "chgptr.h"
-#include "chpkpair.h"
#include "closedev.h"
#include "extgrbdev.h"
#include "devbell.h"
@@ -328,8 +328,8 @@ ProcIDispatch(ClientPtr client)
return (ProcXWarpDevicePointer(client));
else if (stuff->data == X_ChangeDeviceCursor)
return (ProcXChangeDeviceCursor(client));
- else if (stuff->data == X_ChangePointerKeyboardPairing)
- return (ProcXChangePointerKeyboardPairing(client));
+ else if (stuff->data == X_ChangeDeviceHierarchy)
+ return (ProcXChangeDeviceHierarchy(client));
else if (stuff->data == X_XiSelectEvent)
return (ProcXiSelectEvent(client));
else if (stuff->data == X_RegisterPairingClient)
@@ -445,8 +445,8 @@ SProcIDispatch(ClientPtr client)
return (SProcXWarpDevicePointer(client));
else if (stuff->data == X_ChangeDeviceCursor)
return (SProcXChangeDeviceCursor(client));
- else if (stuff->data == X_ChangePointerKeyboardPairing)
- return (SProcXChangePointerKeyboardPairing(client));
+ else if (stuff->data == X_ChangeDeviceHierarchy)
+ return (SProcXChangeDeviceHierarchy(client));
else if (stuff->data == X_XiSelectEvent)
return (SProcXiSelectEvent(client));
else if (stuff->data == X_RegisterPairingClient)
@@ -1153,10 +1153,6 @@ XIGEEventSwap(xGenericEvent* from, xGenericEvent* to)
swaps(&from->sequenceNumber, n);
switch(from->evtype)
{
- case XI_PointerKeyboardPairingChangedNotify:
- SPointerKeyboardPairingChangedNotifyEvent
- ((pairingChangedNotify*)from, (pairingChangedNotify*)to);
- break;
case XI_RawDeviceEvent:
SRawDeviceEvent((rawDeviceEvent*)from, (rawDeviceEvent*)to);
break;
diff --git a/dix/devices.c b/dix/devices.c
index af086a437..d97133980 100644
--- a/dix/devices.c
+++ b/dix/devices.c
@@ -2343,6 +2343,7 @@ AllocMasterDevice(char* name, DeviceIntPtr* ptr, DeviceIntPtr* keybd)
{
DeviceIntPtr pointer;
DeviceIntPtr keyboard;
+ *ptr = *keybd = NULL;
pointer = AddInputDevice(CorePointerProc, TRUE);
if (!pointer)