--- xc/include/extensions/XI.h.hotplug~ 2004-04-23 18:43:06.000000000 +0000 +++ xc/include/extensions/XI.h 2005-05-29 16:45:46.000000000 +0000 @@ -110,6 +110,10 @@ #define sz_xGetDeviceControlReply 32 #define sz_xChangeDeviceControlReq 8 #define sz_xChangeDeviceControlReply 32 +#define sz_xAddInputDeviceReq 4 +#define sz_xAddInputDeviceReply 32 +#define sz_xRemoveInputDeviceReq 4 +#define sz_xRemoveInputDeviceReply 32 #define INAME "XInputExtension" @@ -137,6 +141,7 @@ #define XInput_Add_XDeviceBell 2 #define XInput_Add_XSetDeviceValuators 3 #define XInput_Add_XChangeDeviceControl 4 +#define XInput_Add_XAddInputDevice 5 #define XI_Absent 0 #define XI_Present 1 @@ -153,6 +158,9 @@ #define XI_Add_XChangeDeviceControl_Major 1 #define XI_Add_XChangeDeviceControl_Minor 3 +#define XI_Add_XAddInputDevice_Major 1 +#define XI_Add_XAddInputDevice_Minor 4 + #define DEVICE_RESOLUTION 1 #define NoSuchExtension 1 @@ -244,6 +252,8 @@ #define _deviceOwnerGrabButton 8 #define _noExtensionEvent 9 +#define _devicePresence 0 + #define XI_BadDevice 0 #define XI_BadEvent 1 #define XI_BadMode 2 --- xc/include/extensions/XInput.h.hotplug~ 2004-04-23 18:43:06.000000000 +0000 +++ xc/include/extensions/XInput.h 2005-05-29 16:45:47.000000000 +0000 @@ -149,6 +149,13 @@ #define NoExtensionEvent(d,type,_class) \ { _class = ((XDevice *) d)->device_id << 8 | _noExtensionEvent;} +#define DevicePresence(dpy, type, _class) \ + { \ + extern int_XiGetDevicePresenceNotifyEvent(Display *); \ + type = _XiGetDevicePresenceNotifyEvent(dpy); \ + _class = (0x10000 | _devicePresence); \ + } + #define BadDevice(dpy,error) _xibaddevice(dpy, &error) #define BadClass(dpy,error) _xibadclass(dpy, &error) @@ -418,6 +425,24 @@ /******************************************************************* * + * DevicePresenceNotify event. This event is sent when the list of + * input devices changes. No information about the change is + * contained in this event, the client should use XListInputDevices() + * to learn what has changed. + * + */ + +typedef struct { + int type; + unsigned long serial; /* # of last request processed by server */ + Bool send_event; /* true if this came from a SendEvent request */ + Display *display; /* Display the event was read from */ + Window window; /* unused */ + Time time; +} XDevicePresenceNotifyEvent; + +/******************************************************************* + * * Control structures for input devices that support input class * Feedback. These are used by the XGetFeedbackControl and * XChangeFeedbackControl functions. @@ -824,6 +849,11 @@ char buttons[32]; } XButtonState; +typedef struct { + char *name; + char *value; +} XDeviceOption; + /******************************************************************* * * Function definitions. @@ -1120,6 +1150,19 @@ XDeviceControl* /* control */ ); +extern int XAddInputDevice( + Display* /* display */, + _Xconst char* /* name */, + _Xconst char* /* driver */, + XDeviceOption* /* options */, + int /* nOptions */ +); + +extern int XRemoveInputDevice( + Display* /* display */, + _Xconst char* /* name */ +); + _XFUNCPROTOEND #endif /* _XINPUT_H_ */ --- xc/include/extensions/XIproto.h.hotplug~ 2004-04-23 18:43:06.000000000 +0000 +++ xc/include/extensions/XIproto.h 2005-05-29 16:45:47.000000000 +0000 @@ -72,7 +72,7 @@ #define numInputClasses 7 -#define IEVENTS 15 +#define IEVENTS 16 #define IERRORS 5 #define CLIENT_REQ 1 @@ -113,6 +113,7 @@ #define XI_ChangeDeviceNotify 12 #define XI_DeviceKeystateNotify 13 #define XI_DeviceButtonstateNotify 14 +#define XI_DevicePresenceNotify 15 /********************************************************* * @@ -156,6 +157,10 @@ #define X_GetDeviceControl 34 #define X_ChangeDeviceControl 35 +/* Added in version 1.4 */ +#define X_AddInputDevice 36 +#define X_RemoveInputDevice 37 + /********************************************************* * * Protocol request and reply structures. @@ -1348,6 +1353,65 @@ /* End of merged section */ +/********************************************************* + * + * AddInputDevice. + * + */ + +typedef struct { + char *name; + char *value; +} xDeviceOption; + +typedef struct { + CARD8 reqType; /* input extension major code */ + CARD8 ReqType; /* always X_AddInputDevce */ + CARD16 length B16; +} xAddInputDeviceReq; + +typedef struct { + CARD8 repType; /* X_Reply */ + CARD8 RepType; /* always X_AddInputDevce */ + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD8 status; + BYTE pad1, pad2, pad3; + CARD32 pad02 B32; + CARD32 pad03 B32; + CARD32 pad04 B32; + CARD32 pad05 B32; + CARD32 pad06 B32; +} xAddInputDeviceReply; + + +/********************************************************* + * + * RemoveInputDevice. + * + */ + +typedef struct { + CARD8 reqType; /* input extension major code */ + CARD8 ReqType; /* always X_RemoveInputDevce */ + CARD16 length B16; +} xRemoveInputDeviceReq; + +typedef struct { + CARD8 repType; /* X_Reply */ + CARD8 RepType; /* always X_RemoveInputDevce */ + CARD16 sequenceNumber B16; + CARD32 length B32; + CARD8 status; + BYTE pad1, pad2, pad3; + CARD32 pad02 B32; + CARD32 pad03 B32; + CARD32 pad04 B32; + CARD32 pad05 B32; + CARD32 pad06 B32; +} xRemoveInputDeviceReply; + + /********************************************************** * * Input extension events. @@ -1523,6 +1587,26 @@ CARD32 pad04 B32; } changeDeviceNotify; +/********************************************************** + * + * devicePresenceNotify. + * + */ + +typedef struct + { + BYTE type; + BYTE pad00; + CARD16 sequenceNumber B16; + Time time B32; + CARD32 pad01 B32; + CARD32 pad02 B32; + CARD32 pad03 B32; + CARD32 pad04 B32; + CARD32 pad05 B32; + CARD32 pad06 B32; + } devicePresenceNotify; + #undef Window #undef Time #undef KeyCode --- xc/lib/Xi/Imakefile.hotplug~ 2004-04-23 18:43:44.000000000 +0000 +++ xc/lib/Xi/Imakefile 2005-05-29 16:45:47.000000000 +0000 @@ -25,7 +25,8 @@ #endif DEFINES = $(ALLOC_DEFINES) -SRCS = XAllowDv.c \ +SRCS = XAddDev.c \ + XAllowDv.c \ XChgDCtl.c \ XChgFCtl.c \ XChgKbd.c \ @@ -51,6 +52,7 @@ XListDev.c \ XOpenDev.c \ XQueryDv.c \ + XRmDev.c \ XSelect.c \ XSetBMap.c \ XSetDVal.c \ @@ -62,7 +64,8 @@ XUngrDvB.c \ XUngrDvK.c \ XExtInt.c -OBJS = XAllowDv.o \ +OBJS = XAddDev.o \ + XAllowDv.o \ XChgDCtl.o \ XChgFCtl.o \ XChgKbd.o \ @@ -88,6 +91,7 @@ XListDev.o \ XOpenDev.o \ XQueryDv.o \ + XRmDev.o \ XSelect.o \ XSetBMap.o \ XSetDVal.o \ --- xc/lib/Xi/XExtInt.c.hotplug~ 2004-04-23 18:43:44.000000000 +0000 +++ xc/lib/Xi/XExtInt.c 2005-05-29 16:45:47.000000000 +0000 @@ -122,7 +122,9 @@ {XI_Present, XI_Add_XSetDeviceValuators_Major, XI_Add_XSetDeviceValuators_Minor}, {XI_Present, XI_Add_XChangeDeviceControl_Major, - XI_Add_XChangeDeviceControl_Minor}}; + XI_Add_XChangeDeviceControl_Minor}, + {XI_Present, XI_Add_XAddInputDevice_Major, + XI_Add_XAddInputDevice_Minor}}; /*********************************************************************** * @@ -245,6 +247,14 @@ return (((y + (y >> 3)) & 030707070707) % 077); } +static int +_XiGetDevicePresenceNotifyEvent(Display *dpy) +{ + XExtDisplayInfo *info = XInput_find_display (dpy); + + return info->codes->first_event + XI_DevicePresenceNotify; +} + /*********************************************************************** * * Handle Input extension events. @@ -263,11 +273,10 @@ XExtDisplayInfo *info = XInput_find_display (dpy); XEvent *save = (XEvent *) info->data; + type = event->u.u.type & 0x7f; reltype = (type - info->codes->first_event); - - if (reltype != XI_DeviceValuator && reltype != XI_DeviceKeystateNotify && reltype != XI_DeviceButtonstateNotify) @@ -654,6 +663,23 @@ return (ENQUEUE_EVENT); } break; + + case XI_DevicePresenceNotify: + { + XDevicePresenceNotifyEvent *ev = + (XDevicePresenceNotifyEvent *) re; + devicePresenceNotify *ev2 = (devicePresenceNotify *) event; + + fprintf(stderr, "got DevicePresenceNotify event (reltype=%d)\n", + reltype); + + *ev = *(XDevicePresenceNotifyEvent *) save; + ev->window = 0; + ev->time = ev2->time; + return (ENQUEUE_EVENT); + } + break; + default: printf ("XInputWireToEvent: UNKNOWN WIRE EVENT! type=%d\n",type); break; --- xc/lib/Xi/XIint.h.hotplug~ 2004-04-23 18:43:44.000000000 +0000 +++ xc/lib/Xi/XIint.h 2005-05-29 16:45:47.000000000 +0000 @@ -22,4 +22,6 @@ _Xconst char* ); +extern int _XiPutString(Display *dpy, _Xconst char *s); + #endif --- xc/lib/Xi/XAddDev.c.hotplug~ 2005-05-29 16:48:23.000000000 +0000 +++ xc/lib/Xi/XAddDev.c 2005-05-29 16:48:36.000000000 +0000 @@ -0,0 +1,77 @@ +/* + * Copyright © 2004 Red Hat, Inc. + * + * 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, and that the name of Red Hat not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. Red Hat makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL RED HAT + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Kristian Høgsberg (krh@redhat.com) + */ + +#include +#include +#include +#include +#include +#include "XIint.h" + +int +_XiPutString(Display *dpy, _Xconst char *s) +{ + CARD16 length; + + length = strlen(s); + Data (dpy, (char *) &length, sizeof length); + Data (dpy, s, length); + + return 1 + ((length + 3) >> 2); +} + +int +XAddInputDevice(Display *dpy, _Xconst char *name, _Xconst char *driver, + XDeviceOption *options, int numOptions) +{ + xAddInputDeviceReq *req; + xAddInputDeviceReply rep; + CARD16 card16NumOptions; + int i; + XExtDisplayInfo *info = XInput_find_display (dpy); + + LockDisplay (dpy); + if (_XiCheckExtInit(dpy, XInput_Add_XAddInputDevice) == -1) + return NoSuchExtension; + + GetReq(AddInputDevice,req); + req->reqType = info->codes->major_opcode; + req->ReqType = X_AddInputDevice; + req->length += _XiPutString(dpy, name); + req->length += _XiPutString(dpy, driver); + + card16NumOptions = numOptions; + Data(dpy, (char *) &card16NumOptions, sizeof card16NumOptions); + req->length++; + + for (i = 0; i < numOptions; i++) { + req->length += _XiPutString(dpy, options[i].name); + req->length += _XiPutString(dpy, options[i].value); + } + + _XReply (dpy, (xReply *) &rep, 0, xFalse); + UnlockDisplay(dpy); + SyncHandle(); + + return rep.status; +} --- xc/lib/Xi/XRmDev.c.hotplug~ 2005-05-29 16:48:26.000000000 +0000 +++ xc/lib/Xi/XRmDev.c 2005-05-29 16:48:36.000000000 +0000 @@ -0,0 +1,53 @@ +/* + * Copyright © 2004 Red Hat, Inc. + * + * 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, and that the name of Red Hat not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. Red Hat makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL RED HAT + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Kristian Høgsberg (krh@redhat.com) + */ + +#include +#include +#include +#include +#include +#include "XIint.h" + + +int +XRemoveInputDevice(Display *dpy, _Xconst char *name) +{ + xRemoveInputDeviceReq *req; + xRemoveInputDeviceReply rep; + XExtDisplayInfo *info = XInput_find_display (dpy); + + LockDisplay (dpy); + if (_XiCheckExtInit(dpy, XInput_Add_XAddInputDevice) == -1) + return NoSuchExtension; + + GetReq(RemoveInputDevice,req); + req->reqType = info->codes->major_opcode; + req->ReqType = X_RemoveInputDevice; + req->length += _XiPutString(dpy, name); + + _XReply (dpy, (xReply *) &rep, 0, xFalse); + UnlockDisplay(dpy); + SyncHandle(); + + return rep.status; +} --- xc/programs/Xserver/Xi/Imakefile.hotplug~ 2004-04-23 18:45:06.000000000 +0000 +++ xc/programs/Xserver/Xi/Imakefile 2005-05-29 16:45:47.000000000 +0000 @@ -7,7 +7,8 @@ #include - SRCS = allowev.c \ + SRCS = adddev.c \ + allowev.c \ chgkbd.c \ chgdctl.c \ chgfctl.c \ @@ -34,6 +35,7 @@ listdev.c \ opendev.c \ queryst.c \ + rmdev.c \ selectev.c \ sendexev.c \ setdval.c \ @@ -46,7 +48,8 @@ ungrdevb.c \ ungrdevk.c - OBJS = allowev.o \ + OBJS = adddev.o \ + allowev.o \ chgkbd.o \ chgdctl.o \ chgfctl.o \ @@ -73,6 +76,7 @@ listdev.o \ opendev.o \ queryst.o \ + rmdev.o \ selectev.o \ sendexev.o \ setdval.o \ --- xc/programs/Xserver/Xi/exglobals.h.hotplug~ 2004-04-23 18:45:06.000000000 +0000 +++ xc/programs/Xserver/Xi/exglobals.h 2005-05-29 16:45:47.000000000 +0000 @@ -48,6 +48,7 @@ extern Mask DeviceOwnerGrabButtonMask; extern Mask DeviceButtonGrabMask; extern Mask DeviceButtonMotionMask; +extern Mask DevicePresenceNotifyMask; extern Mask PropagateMask[]; extern int DeviceValuator; @@ -64,6 +65,7 @@ extern int DeviceKeyStateNotify; extern int DeviceButtonStateNotify; extern int DeviceMappingNotify; +extern int DevicePresenceNotify; extern int ChangeDeviceNotify; extern int RT_INPUTCLIENT; --- xc/programs/Xserver/Xi/extinit.c.hotplug~ 2005-04-30 12:44:24.000000000 +0000 +++ xc/programs/Xserver/Xi/extinit.c 2005-05-29 16:45:47.000000000 +0000 @@ -72,6 +72,7 @@ #include "swaprep.h" /* modules local to Xi */ +#include "adddev.h" #include "allowev.h" #include "chgdctl.h" #include "chgfctl.h" @@ -98,6 +99,7 @@ #include "listdev.h" #include "opendev.h" #include "queryst.h" +#include "rmdev.h" #include "selectev.h" #include "sendexev.h" #include "chgkmap.h" @@ -163,6 +165,7 @@ Mask DeviceOwnerGrabButtonMask; Mask DeviceButtonGrabMask; Mask DeviceButtonMotionMask; +Mask DevicePresenceNotifyMask; int DeviceValuator; int DeviceKeyPress; @@ -179,6 +182,7 @@ int DeviceButtonStateNotify; int DeviceMappingNotify; int ChangeDeviceNotify; +int DevicePresenceNotify; int RT_INPUTCLIENT; @@ -200,8 +204,8 @@ static XExtensionVersion thisversion = {XI_Present, - XI_Add_XChangeDeviceControl_Major, - XI_Add_XChangeDeviceControl_Minor}; + XI_Add_XAddInputDevice_Major, + XI_Add_XAddInputDevice_Minor}; /********************************************************************** * @@ -244,6 +248,7 @@ EventSwapVector[DeviceButtonStateNotify] = SEventIDispatch; EventSwapVector[DeviceMappingNotify] = SEventIDispatch; EventSwapVector[ChangeDeviceNotify] = SEventIDispatch; + EventSwapVector[DevicePresenceNotify] = SEventIDispatch; } else { @@ -333,6 +338,10 @@ return(ProcXGetDeviceControl(client)); else if (stuff->data == X_ChangeDeviceControl) return(ProcXChangeDeviceControl(client)); + else if (stuff->data == X_AddInputDevice) + return(ProcXAddInputDevice(client)); + else if (stuff->data == X_RemoveInputDevice) + return(ProcXRemoveInputDevice(client)); else { SendErrorToClient(client, IReqCode, stuff->data, 0, BadRequest); @@ -424,6 +433,10 @@ return(SProcXGetDeviceControl(client)); else if (stuff->data == X_ChangeDeviceControl) return(SProcXChangeDeviceControl(client)); + else if (stuff->data == X_AddInputDevice) + return(SProcXAddInputDevice(client)); + else if (stuff->data == X_RemoveInputDevice) + return(SProcXRemoveInputDevice(client)); else { SendErrorToClient(client, IReqCode, stuff->data, 0, BadRequest); @@ -491,6 +504,10 @@ SRepXGetDeviceControl (client, len, (xGetDeviceControlReply *)rep); else if (rep->RepType == X_ChangeDeviceControl) SRepXChangeDeviceControl (client, len, (xChangeDeviceControlReply *)rep); + else if (rep->RepType == X_AddInputDevice) + SRepXAddInputDevice (client, len, (xAddInputDeviceReply *)rep); + else if (rep->RepType == X_RemoveInputDevice) + SRepXRemoveInputDevice (client, len, (xRemoveInputDeviceReply *)rep); else { FatalError("XINPUT confused sending swapped reply"); @@ -563,6 +580,8 @@ DO_SWAP(SDeviceMappingNotifyEvent, deviceMappingNotify); else if (type == ChangeDeviceNotify) DO_SWAP(SChangeDeviceNotifyEvent, changeDeviceNotify); + else if (type == DevicePresenceNotify) + DO_SWAP(SDevicePresenceNotifyEvent, devicePresenceNotify); else { FatalError("XInputExtension: Impossible event!\n"); @@ -672,6 +691,18 @@ swapl(&to->time, n); } +void +SDevicePresenceNotifyEvent (from, to) + devicePresenceNotify *from; + devicePresenceNotify *to; + { + register char n; + + *to = *from; + swaps(&to->sequenceNumber,n); + swapl(&to->time, n); + } + /************************************************************************ * * This function sets up extension event types and masks. @@ -699,6 +730,7 @@ ChangeDeviceNotify = DeviceMappingNotify + 1; DeviceKeyStateNotify = ChangeDeviceNotify + 1; DeviceButtonStateNotify = DeviceKeyStateNotify + 1; + DevicePresenceNotify = DeviceButtonStateNotify + 1; event_base[KeyClass] = DeviceKeyPress; event_base[ButtonClass] = DeviceButtonPress; @@ -772,6 +804,9 @@ DeviceOwnerGrabButtonMask = GetNextExtEventMask(); SetEventInfo (DeviceOwnerGrabButtonMask, _deviceOwnerGrabButton); SetEventInfo (0, _noExtensionEvent); + + DevicePresenceNotifyMask = GetNextExtEventMask(); + SetMaskForExtEvent(DevicePresenceNotifyMask, DevicePresenceNotify); } /************************************************************************ @@ -850,6 +885,7 @@ EventSwapVector[DeviceButtonStateNotify] = NotImplemented; EventSwapVector[DeviceMappingNotify] = NotImplemented; EventSwapVector[ChangeDeviceNotify] = NotImplemented; + EventSwapVector[DevicePresenceNotify] = NotImplemented; RestoreExtensionEvents (); } --- xc/programs/Xserver/Xi/selectev.c.hotplug~ 2005-04-30 12:44:24.000000000 +0000 +++ xc/programs/Xserver/Xi/selectev.c 2005-05-29 16:45:47.000000000 +0000 @@ -73,6 +73,53 @@ extern Mask ExtExclusiveMasks[]; extern Mask ExtValidMasks[]; +static int +HandleDevicePresenceMask(ClientPtr client, WindowPtr win, + XEventClass *cls, CARD16 *count) +{ + int i, j; + Mask mask; + + /* We use the device ID 256 to select events that aren't bound to + * any device. For now we only handle the device presence event, + * but this could be extended to other events that aren't bound to + * a device. + * + * In order not to break in CreateMaskFromList() we remove the + * entries with device ID 256 from the XEventClass array. + */ + + mask = 0; + for (i = 0, j = 0; i < *count; i++) { + if (cls[i] >> 8 != 256) { + cls[j] = cls[i]; + j++; + continue; + } + + switch (cls[i] & 0xff) { + case _devicePresence: + mask |= DevicePresenceNotifyMask; + break; + } + } + + *count = j; + + if (mask == 0) + return Success; + + /* We always only use mksidx = 0 for events not bound to + * devices */ + + if (AddExtensionClient (win, client, mask, 0) != Success) + return BadAlloc; + + RecalculateDeviceDeliverableEvents(win); + + return Success; +} + /*********************************************************************** * * Handle requests from clients with a different byte order. @@ -135,6 +182,16 @@ return Success; } + if (HandleDevicePresenceMask(client, pWin, + (XEventClass *)&stuff[1], + &stuff->count) != Success) + { + SendErrorToClient(client, IReqCode, X_SelectExtensionEvent, 0, + BadAlloc); + return Success; + } + + if ((ret = CreateMaskFromList (client, (XEventClass *)&stuff[1], stuff->count, tmp, NULL, X_SelectExtensionEvent)) != Success) return Success; --- xc/programs/Xserver/Xi/stubs.c.hotplug~ 2005-04-30 12:44:24.000000000 +0000 +++ xc/programs/Xserver/Xi/stubs.c 2005-05-29 16:45:47.000000000 +0000 @@ -311,3 +311,16 @@ return (BadMatch); } } + +int +AddAndEnableInputDevice (const char *name, const char *driver, + xDeviceOption *options_list, int num_options) +{ + return !Success; +} + +int +DisableAndRemoveInputDevice (const char *name) +{ + return !Success; +} --- xc/programs/Xserver/Xi/adddev.c.hotplug~ 2005-05-29 16:47:43.000000000 +0000 +++ xc/programs/Xserver/Xi/adddev.c 2005-05-29 16:48:07.000000000 +0000 @@ -0,0 +1,197 @@ +/* + * Copyright © 2004 Red Hat, Inc. + * + * 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, and that the name of Red Hat not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. Red Hat makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL RED HAT + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Kristian Høgsberg (krh@redhat.com) + */ + +/*********************************************************************** + * + * Request to add an extension input device. + * + */ + +#define NEED_EVENTS +#define NEED_REPLIES +#include "X.h" /* for inputstr.h */ +#include "Xproto.h" /* Request macro */ +#include "inputstr.h" /* DeviceIntPtr */ +#include "XI.h" +#include "XIproto.h" +#include "XIstubs.h" +#include "windowstr.h" /* window structure */ +#include "extnsionst.h" +#include "extinit.h" /* LookupDeviceIntRec */ +#include "exglobals.h" +#include "chgptr.h" + +#include "adddev.h" + +int +SProcXAddInputDevice(ClientPtr client) +{ + register char n; + + REQUEST(xAddInputDeviceReq); + swaps(&stuff->length, n); + return ProcXAddInputDevice(client); +} + +int +XiGetString(ClientPtr client, char *end, char **p, char **res) +{ + int length; + char *str; + char n; + + *res = NULL; + if (*p + 4 > end) + return BadLength; + + length = ** (CARD16 **) p; + *p += 4; + if (client->swapped) { + swaps(&length, n); + } + + if (*p + length > end) + return BadLength; + + str = xalloc(length + 1); + if (str == NULL) + return BadAlloc; + + memcpy(str, *p, length); + str[length] = '\0'; + *p += (length + 3) & ~3; + + *res = str; + return Success; +} + +static void +FreeDeviceOptionList(xDeviceOption *option_list, int noptions) +{ + int i; + + for (i = 0; i < noptions; i++) { + xfree(option_list[i].name); + xfree(option_list[i].value); + } + xfree(option_list); +} + +/*********************************************************************** + * + * This procedure causes the server to add a new input device. + * + */ + +int +ProcXAddInputDevice(ClientPtr client) +{ + char *name, *driver, *p, *end; + int res, noptions, i; + xDeviceOption *option_list; + xAddInputDeviceReply rep; + devicePresenceNotify ev; + DeviceIntRec dummyDev; + + REQUEST(xAddInputDeviceReq); + REQUEST_AT_LEAST_SIZE(xAddInputDeviceReq); + + noptions = 0; + option_list = NULL; + + p = (char *) &stuff[1]; + end = p + stuff->length * 4; + + res = XiGetString(client, end, &p, &name); + if (res != Success) + goto exit_failure; + + res = XiGetString(client, end, &p, &driver); + if (res != Success) + goto exit_failure; + + if (p + 4 > end) { + SendErrorToClient(client, IReqCode, X_AddInputDevice, 0, BadLength); + return Success; + } + + noptions = * (CARD16 *) p; + p += 4; + option_list = xcalloc(sizeof(xDeviceOption), noptions); + for (i = 0; i < noptions; i++) { + res = XiGetString(client, end, &p, &option_list[i].name); + if (res != Success) + goto exit_failure; + + res = XiGetString(client, end, &p, &option_list[i].value); + if (res != Success) + goto exit_failure; + } + + res = AddAndEnableInputDevice(name, driver, option_list, noptions); + if (res != Success) + goto exit_failure; + + ev.type = DevicePresenceNotify; + ev.time = currentTime.milliseconds; + + dummyDev.id = 0; + SendEventToAllWindows (&dummyDev, DevicePresenceNotifyMask, + (xEvent *)&ev, 1); + + rep.repType = X_Reply; + rep.RepType = X_AddInputDevice; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.status = res; + + WriteReplyToClient(client, sizeof (xAddInputDeviceReply), &rep); + xfree(name); + FreeDeviceOptionList(option_list, noptions); + + return Success; + + exit_failure: + xfree(name); + FreeDeviceOptionList(option_list, noptions); + + SendErrorToClient(client, IReqCode, X_AddInputDevice, 0, res); + return Success; +} + +/*********************************************************************** + * + * This procedure writes the reply for the XOpenDevice function, + * if the client and server have a different byte ordering. + * + */ + +void +SRepXAddInputDevice (ClientPtr client, int size, xAddInputDeviceReply *rep) +{ + register char n; + + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + WriteToClient(client, size, (char *)rep); +} --- xc/programs/Xserver/Xi/adddev.h.hotplug~ 2005-05-29 16:47:45.000000000 +0000 +++ xc/programs/Xserver/Xi/adddev.h 2005-05-29 16:48:07.000000000 +0000 @@ -0,0 +1,39 @@ +/* + * Copyright © 2004 Red Hat, Inc. + * + * 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, and that the name of Red Hat not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. Red Hat makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL RED HAT + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Kristian Høgsberg (krh@redhat.com) + */ + +#ifndef ADDDEV_H +#define ADDDEV_H 1 + +int +XiGetString(ClientPtr client, char *end, char **p, char **res); + +int +SProcXAddInputDevice(ClientPtr client); + +int +ProcXAddInputDevice(ClientPtr client); + +void +SRepXAddInputDevice (ClientPtr client, int size, xAddInputDeviceReply *rep); + +#endif /* ADDDEV_H */ --- xc/programs/Xserver/Xi/rmdev.h.hotplug~ 2005-05-29 16:47:48.000000000 +0000 +++ xc/programs/Xserver/Xi/rmdev.h 2005-05-29 16:48:07.000000000 +0000 @@ -0,0 +1,37 @@ +/* + * Copyright © 2004 Red Hat, Inc. + * + * 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, and that the name of Red Hat not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. Red Hat makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL RED HAT + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Kristian Høgsberg (krh@redhat.com) + */ + +#ifndef RMDEV_H +#define RMDEV_H 1 + +int +SProcXRemoveInputDevice(ClientPtr client); + +int +ProcXRemoveInputDevice(ClientPtr client); + +void +SRepXRemoveInputDevice (ClientPtr client, int size, + xRemoveInputDeviceReply *rep); + +#endif /* RMDEV_H */ --- xc/programs/Xserver/Xi/rmdev.c.hotplug~ 2005-05-29 16:47:49.000000000 +0000 +++ xc/programs/Xserver/Xi/rmdev.c 2005-05-29 16:48:07.000000000 +0000 @@ -0,0 +1,107 @@ +/* + * Copyright © 2004 Red Hat, Inc. + * + * 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, and that the name of Red Hat not be used in advertising or + * publicity pertaining to distribution of the software without specific, + * written prior permission. Red Hat makes no representations about the + * suitability of this software for any purpose. It is provided "as is" + * without express or implied warranty. + * + * RED HAT DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL + * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL RED HAT + * BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION + * OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN + * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + * + * Author: Kristian Høgsberg (krh@redhat.com) + */ + +#define NEED_EVENTS +#define NEED_REPLIES +#include "X.h" /* for inputstr.h */ +#include "Xproto.h" /* Request macro */ +#include "inputstr.h" /* DeviceIntPtr */ +#include "XI.h" +#include "XIproto.h" +#include "XIstubs.h" +#include "windowstr.h" /* window structure */ +#include "extnsionst.h" +#include "extinit.h" /* LookupDeviceIntRec */ +#include "exglobals.h" +#include "chgptr.h" + +#include "adddev.h" +#include "rmdev.h" + +int +SProcXRemoveInputDevice(ClientPtr client) +{ + register char n; + + REQUEST(xRemoveInputDeviceReq); + swaps(&stuff->length, n); + return ProcXRemoveInputDevice(client); +} + +int +ProcXRemoveInputDevice(ClientPtr client) +{ + char *name, *p, *end; + int res; + xRemoveInputDeviceReply rep; + devicePresenceNotify ev; + DeviceIntRec dummyDev; + + REQUEST(xRemoveInputDeviceReq); + REQUEST_AT_LEAST_SIZE(xRemoveInputDeviceReq); + + p = (char *) &stuff[1]; + end = p + stuff->length * 4; + + res = XiGetString(client, end, &p, &name); + if (res != Success) + goto exit_failure; + + res = DisableAndRemoveInputDevice(name); + if (res != Success) + goto exit_failure; + + ev.type = DevicePresenceNotify; + ev.time = currentTime.milliseconds; + + dummyDev.id = 0; + SendEventToAllWindows (&dummyDev, DevicePresenceNotifyMask, + (xEvent *)&ev, 1); + rep.repType = X_Reply; + rep.RepType = X_RemoveInputDevice; + rep.length = 0; + rep.sequenceNumber = client->sequence; + rep.status = res; + + WriteReplyToClient(client, sizeof (xRemoveInputDeviceReply), &rep); + xfree(name); + + return Success; + + exit_failure: + xfree(name); + + SendErrorToClient(client, IReqCode, X_AddInputDevice, 0, res); + return Success; +} + +void +SRepXRemoveInputDevice (ClientPtr client, int size, + xRemoveInputDeviceReply *rep) +{ + register char n; + + swaps(&rep->sequenceNumber, n); + swapl(&rep->length, n); + WriteToClient(client, size, (char *)rep); +} --- xc/programs/Xserver/Xprint/ddxInit.c.hotplug~ 2005-04-30 12:44:24.000000000 +0000 +++ xc/programs/Xserver/Xprint/ddxInit.c 2005-05-29 16:45:47.000000000 +0000 @@ -359,6 +359,18 @@ return BadMatch; } +int +AddAndEnableInputDevice (const char *name, const char *driver, + xDeviceOption *options_list, int num_options) +{ + return !Success; +} + +int +DisableAndRemoveInputDevice (const char *name) +{ + return !Success; +} #endif /* XINPUT */ --- xc/programs/Xserver/hw/darwin/darwinXinput.c.hotplug~ 2005-04-30 12:44:30.000000000 +0000 +++ xc/programs/Xserver/hw/darwin/darwinXinput.c 2005-05-29 16:45:47.000000000 +0000 @@ -308,3 +308,16 @@ return (BadMatch); } } + +int +AddAndEnableInputDevice (const char *name, const char *driver, + xDeviceOption *options_list, int num_options) +{ + return !Success; +} + +int +DisableAndRemoveInputDevice (const char *name) +{ + return !Success; +} --- xc/programs/Xserver/hw/dmx/input/dmxxinput.c.hotplug~ 2005-04-30 12:44:40.000000000 +0000 +++ xc/programs/Xserver/hw/dmx/input/dmxxinput.c 2005-05-29 16:45:47.000000000 +0000 @@ -150,3 +150,16 @@ { return BadMatch; } + +int +AddAndEnableInputDevice (const char *name, const char *driver, + xDeviceOption *options_list, int num_options) +{ + return !Success; +} + +int +DisableAndRemoveInputDevice (const char *name) +{ + return !Success; +} --- xc/programs/Xserver/hw/xfree86/common/xf86Helper.c.hotplug~ 2005-04-30 12:44:46.000000000 +0000 +++ xc/programs/Xserver/hw/xfree86/common/xf86Helper.c 2005-05-29 16:45:47.000000000 +0000 @@ -136,6 +136,19 @@ xf86InputDriverList[drvIndex] = NULL; } +InputDriverPtr +xf86LookupInputDriver(const char *name) +{ + int i; + + for (i = 0; i < xf86NumInputDrivers; i++) { + if (xf86InputDriverList[i] && xf86InputDriverList[i]->driverName && + xf86NameCmp(name, xf86InputDriverList[i]->driverName) == 0) + return xf86InputDriverList[i]; + } + return NULL; +} + void xf86AddModuleInfo(ModuleInfoPtr info, pointer module) { @@ -370,6 +383,19 @@ xfree(pInp); } +InputInfoPtr +xf86LookupInput(const char *name) +{ + InputInfoPtr p; + + for (p = xf86InputDevs; p != NULL; p = p->next) { + if (strcmp(name, p->name) == 0) + return p; + } + + return NULL; +} + Bool xf86AddPixFormat(ScrnInfoPtr pScrn, int depth, int bpp, int pad) { --- xc/programs/Xserver/hw/xfree86/common/xf86Init.c.hotplug~ 2005-04-30 12:44:46.000000000 +0000 +++ xc/programs/Xserver/hw/xfree86/common/xf86Init.c 2005-05-29 16:45:47.000000000 +0000 @@ -996,20 +996,6 @@ } -static InputDriverPtr -MatchInput(IDevPtr pDev) -{ - int i; - - for (i = 0; i < xf86NumInputDrivers; i++) { - if (xf86InputDriverList[i] && xf86InputDriverList[i]->driverName && - xf86NameCmp(pDev->driver, xf86InputDriverList[i]->driverName) == 0) - return xf86InputDriverList[i]; - } - return NULL; -} - - /* * InitInput -- * Initialize all supported input devices. @@ -1046,7 +1032,7 @@ } #endif - if ((pDrv = MatchInput(pDev)) == NULL) { + if ((pDrv = xf86LookupInputDriver(pDev->driver)) == NULL) { xf86Msg(X_ERROR, "No Input driver matching `%s'\n", pDev->driver); /* XXX For now, just continue. */ continue; --- xc/programs/Xserver/hw/xfree86/common/xf86Xinput.c.hotplug~ 2005-04-30 12:44:46.000000000 +0000 +++ xc/programs/Xserver/hw/xfree86/common/xf86Xinput.c 2005-05-29 16:45:47.000000000 +0000 @@ -61,6 +61,7 @@ #include "xf86Xinput.h" #ifdef XINPUT #include "XIstubs.h" +#include "xf86Optrec.h" #endif #include "mipointer.h" #include "xf86InPriv.h" @@ -616,6 +617,112 @@ return (*local->control_proc)(local, control); } } + +int +AddAndEnableInputDevice (const char *name, const char *driver, + xDeviceOption *option_list, int num_options) +{ + IDevRec *idev; + InputDriverPtr drv; + InputInfoPtr pInfo; + DeviceIntPtr dev; + int i; + + pInfo = xf86LookupInput(name); + if (pInfo != NULL) { + /* Device already present */ + return BadName; + } + + if (!xf86LoadOneModule((char *) driver, NULL)) { + return BadName; + } + + drv = xf86LookupInputDriver(driver); + if (drv == NULL) { + xf86Msg(X_ERROR, "No Input driver matching `%s'\n", driver); + return BadName; + } + + if (!drv->PreInit) { + xf86Msg(X_ERROR, + "Input driver `%s' has no PreInit function (ignoring)\n", + drv->driverName); + return BadImplementation; + } + + idev = xalloc(sizeof *idev); + idev->identifier = xstrdup(name); + idev->driver = xstrdup(driver); + idev->commonOptions = NULL; + for (i = 0; i < num_options; i++) + idev->commonOptions = xf86addNewOption(idev->commonOptions, + option_list[i].name, + option_list[i].value); + idev->extraOptions = NULL; + + pInfo = drv->PreInit(drv, idev, 0); + + if (!pInfo) { + xf86Msg(X_ERROR, "PreInit returned NULL for \"%s\"\n", name); + return BadMatch; + } + else if (!(pInfo->flags & XI86_CONFIGURED)) { + xf86Msg(X_ERROR, "PreInit failed for input device \"%s\"\n", name); + xf86DeleteInput(pInfo, 0); + return BadMatch; + } + + xf86ActivateDevice(pInfo); + + dev = pInfo->dev; + dev->inited = ((*dev->deviceProc)(dev, DEVICE_INIT) == Success); + if (dev->inited && dev->startup) + EnableDevice(dev); + + return Success; +} + +int +DisableAndRemoveInputDevice(const char *identifier) +{ + InputInfoPtr pInfo; + LocalDevicePtr local = (LocalDevicePtr) pInfo; + DeviceIntPtr dev; + + ErrorF("DisableAndRemoveInputDevice(\"%s\"): not implemented yet\n", + identifier); + + /* TODO: + * + * - if XInput clients have selected input from this device, + * clean that up + * Is this really needed? + * + */ + + pInfo = xf86LookupInput(identifier); + if (pInfo == NULL) + { + return BadName; + } + + local = (LocalDevicePtr) pInfo; + + if ((local->flags & XI86_CORE_POINTER) || + (local->flags & XI86_CORE_KEYBOARD)) + { + return BadMatch; + } + + dev = pInfo->dev; + RemoveDevice(dev); + + xf86DeleteInput(pInfo, 0); + + return Success; +} + #endif /* --- xc/programs/Xserver/hw/xfree86/common/xf86Xinput.h.hotplug~ 2005-04-30 12:44:46.000000000 +0000 +++ xc/programs/Xserver/hw/xfree86/common/xf86Xinput.h 2005-05-29 16:45:47.000000000 +0000 @@ -210,8 +210,10 @@ /* xf86Helper.c */ void xf86AddInputDriver(InputDriverPtr driver, pointer module, int flags); void xf86DeleteInputDriver(int drvIndex); +InputDriverPtr xf86LookupInputDriver(const char *name); InputInfoPtr xf86AllocateInput(InputDriverPtr drv, int flags); void xf86DeleteInput(InputInfoPtr pInp, int flags); +InputInfoPtr xf86LookupInput(const char *name); /* xf86Option.c */ void xf86CollectInputOptions(InputInfoPtr pInfo, const char **defaultOpts, --- xc/programs/Xserver/include/XIstubs.h.hotplug~ 2004-04-23 19:54:23.000000000 +0000 +++ xc/programs/Xserver/include/XIstubs.h 2005-05-29 16:45:47.000000000 +0000 @@ -73,4 +73,15 @@ DeviceIntPtr /* dev */, xDeviceCtl * /* control */); +int +AddAndEnableInputDevice ( + const char * /* name */, + const char * /* driver */, + xDeviceOption * /* options_list */, + int /* num_options*/); + +int +DisableAndRemoveInputDevice ( + const char * /* name */); + #endif /* XI_STUBS_H */ --- xc/programs/Xserver/include/extinit.h.hotplug~ 2004-04-23 19:54:23.000000000 +0000 +++ xc/programs/Xserver/include/extinit.h 2005-05-29 16:45:47.000000000 +0000 @@ -93,6 +93,12 @@ ); void +SDevicePresenceNotifyEvent ( + devicePresenceNotify * /* from */, + devicePresenceNotify * /* to */ + ); + +void SChangeDeviceNotifyEvent ( changeDeviceNotify * /* from */, changeDeviceNotify * /* to */ @@ -104,6 +110,7 @@ deviceMappingNotify * /* to */ ); + void FixExtensionEvents ( ExtensionEntry * /* extEntry */