diff options
Diffstat (limited to 'Xi/chaccess.c')
-rw-r--r-- | Xi/chaccess.c | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/Xi/chaccess.c b/Xi/chaccess.c new file mode 100644 index 000000000..5005e9435 --- /dev/null +++ b/Xi/chaccess.c @@ -0,0 +1,177 @@ +/* + +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. + +*/ + +#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/XIproto.h> +#include "extnsionst.h" +#include "extinit.h" /* LookupDeviceIntRec */ +#include "exevents.h" +#include "exglobals.h" + +#include "chaccess.h" + +/*********************************************************************** + * This procedure allows a client to change window access control. + */ + +int +SProcXChangeWindowAccess(ClientPtr client) +{ + char n; + REQUEST(xChangeWindowAccessReq); + + swaps(&stuff->length, n); + swapl(&stuff->win, n); + return ProcXChangeWindowAccess(client); +} + +int +ProcXChangeWindowAccess(ClientPtr client) +{ + int padding, err, i; + CARD8* deviceids = NULL; + WindowPtr win; + DeviceIntPtr* perm_devices = NULL; + DeviceIntPtr* deny_devices = NULL; + REQUEST(xChangeWindowAccessReq); + REQUEST_AT_LEAST_SIZE(xChangeWindowAccessReq); + + + padding = (4 - ((stuff->npermit + stuff->ndeny) % 4)) % 4; + + if (stuff->length != ((sizeof(xChangeWindowAccessReq) + + (stuff->npermit + stuff->ndeny + padding)) >> 2)) + { + SendErrorToClient(client, IReqCode, X_ChangeWindowAccess, + 0, BadLength); + return Success; + } + + + err = dixLookupWindow(&win, stuff->win, client, DixWriteAccess); + if (err != Success) + { + SendErrorToClient(client, IReqCode, X_ChangeWindowAccess, + stuff->win, err); + return Success; + } + + /* Are we clearing? if so, ignore the rest */ + if (stuff->clear) + { + err = ACClearWindowAccess(client, win, stuff->clear); + if (err != Success) + SendErrorToClient(client, IReqCode, X_ChangeWindowAccess, 0, err); + return Success; + } + + if (stuff->npermit || stuff->ndeny) + deviceids = (CARD8*)&stuff[1]; + + if (stuff->npermit) + { + perm_devices = + (DeviceIntPtr*)xalloc(stuff->npermit * sizeof(DeviceIntPtr)); + if (!perm_devices) + { + ErrorF("ProcXChangeWindowAccess: alloc failure.\n"); + SendErrorToClient(client, IReqCode, X_ChangeWindowAccess, 0, + BadImplementation); + return Success; + } + + /* if one of the devices cannot be accessed, we don't do anything.*/ + for (i = 0; i < stuff->npermit; i++) + { + perm_devices[i] = LookupDeviceIntRec(deviceids[i]); + if (!perm_devices[i]) + { + xfree(perm_devices); + SendErrorToClient(client, IReqCode, X_ChangeWindowAccess, + deviceids[i], BadDevice); + return Success; + } + } + } + + if (stuff->ndeny) + { + deny_devices = + (DeviceIntPtr*)xalloc(stuff->ndeny * sizeof(DeviceIntPtr)); + if (!deny_devices) + { + ErrorF("ProcXChangeWindowAccecss: alloc failure.\n"); + SendErrorToClient(client, IReqCode, X_ChangeWindowAccess, 0, + BadImplementation); + + xfree(perm_devices); + return Success; + } + + for (i = 0; i < stuff->ndeny; i++) + { + deny_devices[i] = + LookupDeviceIntRec(deviceids[i+stuff->npermit]); + + if (!deny_devices[i]) + { + xfree(perm_devices); + xfree(deny_devices); + SendErrorToClient(client, IReqCode, X_ChangeWindowAccess, + deviceids[i + stuff->npermit], BadDevice); + return Success; + } + } + } + + err = ACChangeWindowAccess(client, win, stuff->defaultRule, + perm_devices, stuff->npermit, + deny_devices, stuff->ndeny); + if (err != Success) + { + SendErrorToClient(client, IReqCode, X_ChangeWindowAccess, + stuff->win, err); + return Success; + } + + xfree(perm_devices); + xfree(deny_devices); + return Success; +} + |