xserver-multidpi/hw/dmx/dmx.c
Jon TURNEY 6e2f5912b6 dmx: Correctly compute DMXGetScreenAttributes reply length
Correctly allow for excess length of DMXGetScreenAttributes reply
over standard 32 byte reply in addition to the displayName string
when computing the length of reply

http://bugs.freedesktop.org/show_bug.cgi?id=24685

Signed-off-by: Jon TURNEY <jon.turney@dronecode.org.uk>
Reviewed-by:  Julien Cristau <jcristau@debian.org>
Signed-off-by: Keith Packard <keithp@keithp.com>
(cherry picked from commit 50a5c32430)
2009-11-03 13:19:47 +10:00

1128 lines
35 KiB
C

/*
* Copyright 2002-2004 Red Hat Inc., Durham, North Carolina.
*
* All Rights Reserved.
*
* Permission is hereby granted, free of charge, to any person obtaining
* a copy of this software and associated documentation files (the
* "Software"), to deal in the Software without restriction, including
* without limitation on the rights to use, copy, modify, merge,
* publish, distribute, sublicense, and/or sell copies of the Software,
* and to permit persons to whom the Software is furnished to do so,
* subject to the following conditions:
*
* The above copyright notice and this permission notice (including the
* next paragraph) 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
* NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
* 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.
*/
/*
* Authors:
* Rickard E. (Rik) Faith <faith@redhat.com>
*
*/
/** \file
* This file implements the server-side part of the DMX protocol. A
* vector of fucntions is provided at extension initialization time, so
* most all of the useful functions in this file are declared static and
* do not appear in the doxygen documentation.
*
* Much of the low-level work is done by functions in #dmxextension.c
*
* Please see the Client-to-Server DMX Extension to the X Protocol
* document for details about the protocol. */
#ifdef HAVE_DMX_CONFIG_H
#include <dmx-config.h>
#endif
#include <X11/X.h>
#include <X11/Xproto.h>
#include "misc.h"
#include "os.h"
#include "dixstruct.h"
#include "extnsionst.h"
#include "opaque.h"
#include "dmxextension.h"
#include <X11/extensions/dmxproto.h>
#include <X11/extensions/dmx.h>
#include "protocol-versions.h"
#ifdef PANORAMIX
#include "panoramiX.h"
extern unsigned long XRT_WINDOW;
extern int PanoramiXNumScreens;
#endif
extern void DMXExtensionInit(void);
static unsigned char DMXCode;
static DISPATCH_PROC(ProcDMXDispatch);
static DISPATCH_PROC(ProcDMXQueryVersion);
static DISPATCH_PROC(ProcDMXSync);
static DISPATCH_PROC(ProcDMXForceWindowCreation);
static DISPATCH_PROC(ProcDMXGetScreenCount);
static DISPATCH_PROC(ProcDMXGetScreenAttributes);
static DISPATCH_PROC(ProcDMXChangeScreensAttributes);
static DISPATCH_PROC(ProcDMXAddScreen);
static DISPATCH_PROC(ProcDMXRemoveScreen);
static DISPATCH_PROC(ProcDMXGetWindowAttributes);
static DISPATCH_PROC(ProcDMXGetDesktopAttributes);
static DISPATCH_PROC(ProcDMXChangeDesktopAttributes);
static DISPATCH_PROC(ProcDMXGetInputCount);
static DISPATCH_PROC(ProcDMXGetInputAttributes);
static DISPATCH_PROC(ProcDMXAddInput);
static DISPATCH_PROC(ProcDMXRemoveInput);
static DISPATCH_PROC(SProcDMXDispatch);
static DISPATCH_PROC(SProcDMXQueryVersion);
static DISPATCH_PROC(SProcDMXSync);
static DISPATCH_PROC(SProcDMXForceWindowCreation);
static DISPATCH_PROC(SProcDMXGetScreenCount);
static DISPATCH_PROC(SProcDMXGetScreenAttributes);
static DISPATCH_PROC(SProcDMXChangeScreensAttributes);
static DISPATCH_PROC(SProcDMXAddScreen);
static DISPATCH_PROC(SProcDMXRemoveScreen);
static DISPATCH_PROC(SProcDMXGetWindowAttributes);
static DISPATCH_PROC(SProcDMXGetDesktopAttributes);
static DISPATCH_PROC(SProcDMXChangeDesktopAttributes);
static DISPATCH_PROC(SProcDMXGetInputCount);
static DISPATCH_PROC(SProcDMXGetInputAttributes);
static DISPATCH_PROC(SProcDMXAddInput);
static DISPATCH_PROC(SProcDMXRemoveInput);
static int _DMXXineramaActive(void)
{
#ifdef PANORAMIX
return !noPanoramiXExtension;
#endif
return 0;
}
/** Initialize the extension. */
void DMXExtensionInit(void)
{
ExtensionEntry *extEntry;
if ((extEntry = AddExtension(DMX_EXTENSION_NAME, 0, 0,
ProcDMXDispatch, SProcDMXDispatch,
NULL, StandardMinorOpcode)))
DMXCode = extEntry->base;
}
static void dmxSetScreenAttribute(int bit, DMXScreenAttributesPtr attr,
CARD32 value)
{
switch (1 << bit) {
case DMXScreenWindowWidth: attr->screenWindowWidth = value; break;
case DMXScreenWindowHeight: attr->screenWindowHeight = value; break;
case DMXScreenWindowXoffset: attr->screenWindowXoffset = value; break;
case DMXScreenWindowYoffset: attr->screenWindowYoffset = value; break;
case DMXRootWindowWidth: attr->rootWindowWidth = value; break;
case DMXRootWindowHeight: attr->rootWindowHeight = value; break;
case DMXRootWindowXoffset: attr->rootWindowXoffset = value; break;
case DMXRootWindowYoffset: attr->rootWindowYoffset = value; break;
case DMXRootWindowXorigin: attr->rootWindowXorigin = value; break;
case DMXRootWindowYorigin: attr->rootWindowYorigin = value; break;
}
}
static int dmxFetchScreenAttributes(unsigned int mask,
DMXScreenAttributesPtr attr,
CARD32 *value_list)
{
int i;
CARD32 *value = value_list;
int count = 0;
for (i = 0; i < 32; i++) {
if (mask & (1 << i)) {
dmxSetScreenAttribute(i, attr, *value);
++value;
++count;
}
}
return count;
}
static void dmxSetDesktopAttribute(int bit, DMXDesktopAttributesPtr attr,
CARD32 value)
{
switch (1 << bit) {
case DMXDesktopWidth: attr->width = value; break;
case DMXDesktopHeight: attr->height = value; break;
case DMXDesktopShiftX: attr->shiftX = value; break;
case DMXDesktopShiftY: attr->shiftY = value; break;
}
}
static int dmxFetchDesktopAttributes(unsigned int mask,
DMXDesktopAttributesPtr attr,
CARD32 *value_list)
{
int i;
CARD32 *value = value_list;
int count = 0;
for (i = 0; i < 32; i++) {
if (mask & (1 << i)) {
dmxSetDesktopAttribute(i, attr, *value);
++value;
++count;
}
}
return count;
}
static void dmxSetInputAttribute(int bit, DMXInputAttributesPtr attr,
CARD32 value)
{
switch (1 << bit) {
case DMXInputType: attr->inputType = value; break;
case DMXInputPhysicalScreen: attr->physicalScreen = value; break;
case DMXInputSendsCore: attr->sendsCore = !!value; break;
}
}
static int dmxFetchInputAttributes(unsigned int mask,
DMXInputAttributesPtr attr,
CARD32 *value_list)
{
int i;
CARD32 *value = value_list;
int count = 0;
for (i = 0; i < 32; i++) {
if (mask & (1 << i)) {
dmxSetInputAttribute(i, attr, *value);
++value;
++count;
}
}
return count;
}
static int ProcDMXQueryVersion(ClientPtr client)
{
xDMXQueryVersionReply rep;
int n;
REQUEST_SIZE_MATCH(xDMXQueryVersionReq);
rep.type = X_Reply;
rep.sequenceNumber = client->sequence;
rep.length = 0;
rep.majorVersion = SERVER_DMX_MAJOR_VERSION;
rep.minorVersion = SERVER_DMX_MINOR_VERSION;
rep.patchVersion = SERVER_DMX_PATCH_VERSION;
if (client->swapped) {
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n);
swapl(&rep.majorVersion, n);
swapl(&rep.minorVersion, n);
swapl(&rep.patchVersion, n);
}
WriteToClient(client, sizeof(xDMXQueryVersionReply), (char *)&rep);
return client->noClientException;
}
static int ProcDMXSync(ClientPtr client)
{
xDMXSyncReply rep;
int n;
REQUEST_SIZE_MATCH(xDMXSyncReq);
dmxFlushPendingSyncs();
rep.type = X_Reply;
rep.sequenceNumber = client->sequence;
rep.length = 0;
rep.status = 0;
if (client->swapped) {
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n);
swapl(&rep.status, n);
}
WriteToClient(client, sizeof(xDMXSyncReply), (char *)&rep);
return client->noClientException;
}
static int ProcDMXForceWindowCreation(ClientPtr client)
{
xDMXForceWindowCreationReply rep;
REQUEST(xDMXForceWindowCreationReq);
WindowPtr pWin;
int n;
REQUEST_SIZE_MATCH(xDMXForceWindowCreationReq);
#ifdef PANORAMIX
if (!noPanoramiXExtension) {
PanoramiXRes *win;
int i;
if (!(win = SecurityLookupIDByType(client, stuff->window, XRT_WINDOW,
DixReadAccess)))
return -1; /* BadWindow */
FOR_NSCREENS(i) {
if (Success != dixLookupWindow(&pWin, win->info[i].id, client,
DixReadAccess))
return -1; /* BadWindow */
dmxForceWindowCreation(pWin);
}
goto doreply;
}
#endif
if (Success != dixLookupWindow(&pWin, stuff->window, client,
DixReadAccess))
return -1; /* BadWindow */
dmxForceWindowCreation(pWin);
doreply:
dmxFlushPendingSyncs();
rep.type = X_Reply;
rep.sequenceNumber = client->sequence;
rep.length = 0;
rep.status = 0;
if (client->swapped) {
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n);
swapl(&rep.status, n);
}
WriteToClient(client, sizeof(xDMXForceWindowCreationReply), (char *)&rep);
return Success;
}
static int ProcDMXGetScreenCount(ClientPtr client)
{
xDMXGetScreenCountReply rep;
int n;
REQUEST_SIZE_MATCH(xDMXGetScreenCountReq);
rep.type = X_Reply;
rep.sequenceNumber = client->sequence;
rep.length = 0;
rep.screenCount = dmxGetNumScreens();
if (client->swapped) {
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n);
swapl(&rep.screenCount, n);
}
WriteToClient(client, sizeof(xDMXGetScreenCountReply), (char *)&rep);
return client->noClientException;
}
static int ProcDMXGetScreenAttributes(ClientPtr client)
{
REQUEST(xDMXGetScreenAttributesReq);
xDMXGetScreenAttributesReply rep;
int n;
int length;
int paddedLength;
DMXScreenAttributesRec attr;
REQUEST_SIZE_MATCH(xDMXGetScreenAttributesReq);
if (stuff->physicalScreen < 0
|| stuff->physicalScreen >= dmxGetNumScreens()) return BadValue;
if (!dmxGetScreenAttributes(stuff->physicalScreen, &attr))
return BadValue;
rep.logicalScreen = attr.logicalScreen;
rep.screenWindowWidth = attr.screenWindowWidth;
rep.screenWindowHeight = attr.screenWindowHeight;
rep.screenWindowXoffset = attr.screenWindowXoffset;
rep.screenWindowYoffset = attr.screenWindowYoffset;
rep.rootWindowWidth = attr.rootWindowWidth;
rep.rootWindowHeight = attr.rootWindowHeight;
rep.rootWindowXoffset = attr.rootWindowXoffset;
rep.rootWindowYoffset = attr.rootWindowYoffset;
rep.rootWindowXorigin = attr.rootWindowXorigin;
rep.rootWindowYorigin = attr.rootWindowYorigin;
length = attr.displayName ? strlen(attr.displayName) : 0;
paddedLength = pad_to_int32(length);
rep.type = X_Reply;
rep.sequenceNumber = client->sequence;
rep.length = bytes_to_int32((sizeof(xDMXGetScreenAttributesReply) - sizeof(xGenericReply))
+ paddedLength);
rep.displayNameLength = length;
if (client->swapped) {
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n);
swapl(&rep.displayNameLength, n);
swapl(&rep.logicalScreen, n);
swaps(&rep.screenWindowWidth, n);
swaps(&rep.screenWindowHeight, n);
swaps(&rep.screenWindowXoffset, n);
swaps(&rep.screenWindowYoffset, n);
swaps(&rep.rootWindowWidth, n);
swaps(&rep.rootWindowHeight, n);
swaps(&rep.rootWindowXoffset, n);
swaps(&rep.rootWindowYoffset, n);
swaps(&rep.rootWindowXorigin, n);
swaps(&rep.rootWindowYorigin, n);
}
WriteToClient(client, sizeof(xDMXGetScreenAttributesReply), (char *)&rep);
if (length) WriteToClient(client, length, (char *)attr.displayName);
return client->noClientException;
}
static int ProcDMXChangeScreensAttributes(ClientPtr client)
{
REQUEST(xDMXChangeScreensAttributesReq);
xDMXChangeScreensAttributesReply rep;
int n;
int status = DMX_BAD_XINERAMA;
unsigned int mask = 0;
unsigned int i;
CARD32 *screen_list;
CARD32 *mask_list;
CARD32 *value_list;
DMXScreenAttributesPtr attribs;
int errorScreen = 0;
unsigned int len;
int ones = 0;
REQUEST_AT_LEAST_SIZE(xDMXChangeScreensAttributesReq);
len = client->req_len - bytes_to_int32(sizeof(xDMXChangeScreensAttributesReq));
if (len < stuff->screenCount + stuff->maskCount)
return BadLength;
screen_list = (CARD32 *)(stuff + 1);
mask_list = &screen_list[stuff->screenCount];
value_list = &mask_list[stuff->maskCount];
for (i = 0; i < stuff->maskCount; i++) ones += Ones(mask_list[i]);
if (len != stuff->screenCount + stuff->maskCount + ones)
return BadLength;
if (!_DMXXineramaActive()) goto noxinerama;
if (!(attribs = xalloc(stuff->screenCount * sizeof(*attribs))))
return BadAlloc;
for (i = 0; i < stuff->screenCount; i++) {
int count;
if (i < stuff->maskCount) mask = mask_list[i];
dmxGetScreenAttributes(screen_list[i], &attribs[i]);
count = dmxFetchScreenAttributes(mask, &attribs[i], value_list);
value_list += count;
}
#if PANORAMIX
status = dmxConfigureScreenWindows(stuff->screenCount,
screen_list,
attribs,
&errorScreen);
#endif
xfree(attribs);
if (status == BadValue) return status;
noxinerama:
rep.type = X_Reply;
rep.sequenceNumber = client->sequence;
rep.length = 0;
rep.status = status;
rep.errorScreen = errorScreen;
if (client->swapped) {
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n);
swapl(&rep.status, n);
swapl(&rep.errorScreen, n);
}
WriteToClient(client,
sizeof(xDMXChangeScreensAttributesReply),
(char *)&rep);
return client->noClientException;
}
static int ProcDMXAddScreen(ClientPtr client)
{
REQUEST(xDMXAddScreenReq);
xDMXAddScreenReply rep;
int n;
int status = 0;
CARD32 *value_list;
DMXScreenAttributesRec attr;
int count;
char *name;
int len;
int paddedLength;
REQUEST_AT_LEAST_SIZE(xDMXAddScreenReq);
paddedLength = pad_to_int32(stuff->displayNameLength);
len = client->req_len - bytes_to_int32(sizeof(xDMXAddScreenReq));
if (len != Ones(stuff->valueMask) + paddedLength/4)
return BadLength;
memset(&attr, 0, sizeof(attr));
dmxGetScreenAttributes(stuff->physicalScreen, &attr);
value_list = (CARD32 *)(stuff + 1);
count = dmxFetchScreenAttributes(stuff->valueMask, &attr, value_list);
if (!(name = xalloc(stuff->displayNameLength + 1 + 4)))
return BadAlloc;
memcpy(name, &value_list[count], stuff->displayNameLength);
name[stuff->displayNameLength] = '\0';
attr.displayName = name;
status = dmxAttachScreen(stuff->physicalScreen, &attr);
xfree(name);
rep.type = X_Reply;
rep.sequenceNumber = client->sequence;
rep.length = 0;
rep.status = status;
rep.physicalScreen = stuff->physicalScreen;
if (client->swapped) {
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n);
swapl(&rep.status, n);
swapl(&rep.physicalScreen, n);
}
WriteToClient(client,
sizeof(xDMXAddScreenReply),
(char *)&rep);
return client->noClientException;
}
static int ProcDMXRemoveScreen(ClientPtr client)
{
REQUEST(xDMXRemoveScreenReq);
xDMXRemoveScreenReply rep;
int n;
int status = 0;
REQUEST_SIZE_MATCH(xDMXRemoveScreenReq);
status = dmxDetachScreen(stuff->physicalScreen);
rep.type = X_Reply;
rep.sequenceNumber = client->sequence;
rep.length = 0;
rep.status = status;
if (client->swapped) {
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n);
swapl(&rep.status, n);
}
WriteToClient(client,
sizeof(xDMXRemoveScreenReply),
(char *)&rep);
return client->noClientException;
}
#ifdef PANORAMIX
static int dmxPopulatePanoramiX(ClientPtr client, Window window,
CARD32 *screens, CARD32 *windows,
xRectangle *pos, xRectangle *vis)
{
WindowPtr pWin;
PanoramiXRes *win;
int i;
int count = 0;
DMXWindowAttributesRec attr;
if (!(win = SecurityLookupIDByType(client, window, XRT_WINDOW,
DixReadAccess)))
return -1; /* BadWindow */
FOR_NSCREENS(i) {
if (Success != dixLookupWindow(&pWin, win->info[i].id, client,
DixReadAccess))
return -1; /* BadWindow */
if (dmxGetWindowAttributes(pWin, &attr)) {
screens[count] = attr.screen;
windows[count] = attr.window;
pos[count] = attr.pos;
vis[count] = attr.vis;
++count; /* Only count existing windows */
}
}
return count;
}
#endif
static int dmxPopulate(ClientPtr client, Window window, CARD32 *screens,
CARD32 *windows, xRectangle *pos, xRectangle *vis)
{
WindowPtr pWin;
DMXWindowAttributesRec attr;
#ifdef PANORAMIX
if (!noPanoramiXExtension)
return dmxPopulatePanoramiX(client, window, screens, windows,
pos, vis);
#endif
if (Success != dixLookupWindow(&pWin, window, client, DixReadAccess))
return -1; /* BadWindow */
dmxGetWindowAttributes(pWin, &attr);
*screens = attr.screen;
*windows = attr.window;
*pos = attr.pos;
*vis = attr.vis;
return 1;
}
static int dmxMaxNumScreens(void)
{
#ifdef PANORAMIX
if (!noPanoramiXExtension) return PanoramiXNumScreens;
#endif
return 1;
}
static int ProcDMXGetWindowAttributes(ClientPtr client)
{
REQUEST(xDMXGetWindowAttributesReq);
xDMXGetWindowAttributesReply rep;
int i, n;
CARD32 *screens;
CARD32 *windows;
xRectangle *pos, *vis;
int count = dmxMaxNumScreens();
REQUEST_SIZE_MATCH(xDMXGetWindowAttributesReq);
if (!(screens = xalloc(count * sizeof(*screens))))
return BadAlloc;
if (!(windows = xalloc(count * sizeof(*windows)))) {
xfree(screens);
return BadAlloc;
}
if (!(pos = xalloc(count * sizeof(*pos)))) {
xfree(windows);
xfree(screens);
return BadAlloc;
}
if (!(vis = xalloc(count * sizeof(*vis)))) {
xfree(pos);
xfree(windows);
xfree(screens);
return BadAlloc;
}
if ((count = dmxPopulate(client, stuff->window, screens, windows,
pos, vis)) < 0) {
xfree(vis);
xfree(pos);
xfree(windows);
xfree(screens);
return BadWindow;
}
rep.type = X_Reply;
rep.sequenceNumber = client->sequence;
rep.length = count * 6;
rep.screenCount = count;
if (client->swapped) {
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n);
swapl(&rep.screenCount, n);
for (i = 0; i < count; i++) {
swapl(&screens[i], n);
swapl(&windows[i], n);
swaps(&pos[i].x, n);
swaps(&pos[i].y, n);
swaps(&pos[i].width, n);
swaps(&pos[i].height, n);
swaps(&vis[i].x, n);
swaps(&vis[i].y, n);
swaps(&vis[i].width, n);
swaps(&vis[i].height, n);
}
}
dmxFlushPendingSyncs();
WriteToClient(client, sizeof(xDMXGetWindowAttributesReply), (char *)&rep);
if (count) {
WriteToClient(client, count * sizeof(*screens), (char *)screens);
WriteToClient(client, count * sizeof(*windows), (char *)windows);
WriteToClient(client, count * sizeof(*pos), (char *)pos);
WriteToClient(client, count * sizeof(*vis), (char *)vis);
}
xfree(vis);
xfree(pos);
xfree(windows);
xfree(screens);
return client->noClientException;
}
static int ProcDMXGetDesktopAttributes(ClientPtr client)
{
xDMXGetDesktopAttributesReply rep;
int n;
DMXDesktopAttributesRec attr;
REQUEST_SIZE_MATCH(xDMXGetDesktopAttributesReq);
dmxGetDesktopAttributes(&attr);
rep.width = attr.width;
rep.height = attr.height;
rep.shiftX = attr.shiftX;
rep.shiftY = attr.shiftY;
rep.type = X_Reply;
rep.sequenceNumber = client->sequence;
rep.length = 0;
if (client->swapped) {
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n);
swapl(&rep.width, n);
swapl(&rep.height, n);
swapl(&rep.shiftX, n);
swapl(&rep.shiftY, n);
}
WriteToClient(client, sizeof(xDMXGetDesktopAttributesReply), (char *)&rep);
return client->noClientException;
}
static int ProcDMXChangeDesktopAttributes(ClientPtr client)
{
REQUEST(xDMXChangeDesktopAttributesReq);
xDMXChangeDesktopAttributesReply rep;
int n;
int status = DMX_BAD_XINERAMA;
CARD32 *value_list;
DMXDesktopAttributesRec attr;
int len;
REQUEST_AT_LEAST_SIZE(xDMXChangeDesktopAttributesReq);
len = client->req_len - (sizeof(xDMXChangeDesktopAttributesReq) >> 2);
if (len != Ones(stuff->valueMask))
return BadLength;
if (!_DMXXineramaActive()) goto noxinerama;
value_list = (CARD32 *)(stuff + 1);
dmxGetDesktopAttributes(&attr);
dmxFetchDesktopAttributes(stuff->valueMask, &attr, value_list);
#if PANORAMIX
status = dmxConfigureDesktop(&attr);
#endif
if (status == BadValue) return status;
noxinerama:
rep.type = X_Reply;
rep.sequenceNumber = client->sequence;
rep.length = 0;
rep.status = status;
if (client->swapped) {
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n);
swapl(&rep.status, n);
}
WriteToClient(client,
sizeof(xDMXChangeDesktopAttributesReply),
(char *)&rep);
return client->noClientException;
}
static int ProcDMXGetInputCount(ClientPtr client)
{
xDMXGetInputCountReply rep;
int n;
REQUEST_SIZE_MATCH(xDMXGetInputCountReq);
rep.type = X_Reply;
rep.sequenceNumber = client->sequence;
rep.length = 0;
rep.inputCount = dmxGetInputCount();
if (client->swapped) {
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n);
swapl(&rep.inputCount, n);
}
WriteToClient(client, sizeof(xDMXGetInputCountReply), (char *)&rep);
return client->noClientException;
}
static int ProcDMXGetInputAttributes(ClientPtr client)
{
REQUEST(xDMXGetInputAttributesReq);
xDMXGetInputAttributesReply rep;
int n;
int length;
int paddedLength;
DMXInputAttributesRec attr;
REQUEST_SIZE_MATCH(xDMXGetInputAttributesReq);
if (dmxGetInputAttributes(stuff->deviceId, &attr)) return BadValue;
rep.inputType = attr.inputType;
rep.physicalScreen = attr.physicalScreen;
rep.physicalId = attr.physicalId;
rep.isCore = attr.isCore;
rep.sendsCore = attr.sendsCore;
rep.detached = attr.detached;
length = attr.name ? strlen(attr.name) : 0;
paddedLength = pad_to_int32(length);
rep.type = X_Reply;
rep.sequenceNumber = client->sequence;
rep.length = bytes_to_int32(paddedLength);
rep.nameLength = length;
if (client->swapped) {
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n);
swapl(&rep.inputType, n);
swapl(&rep.physicalScreen, n);
swapl(&rep.physicalId, n);
swapl(&rep.nameLength, n);
}
WriteToClient(client, sizeof(xDMXGetInputAttributesReply), (char *)&rep);
if (length) WriteToClient(client, length, (char *)attr.name);
return client->noClientException;
}
static int ProcDMXAddInput(ClientPtr client)
{
REQUEST(xDMXAddInputReq);
xDMXAddInputReply rep;
int n;
int status = 0;
CARD32 *value_list;
DMXInputAttributesRec attr;
int count;
char *name;
int len;
int paddedLength;
int id = -1;
REQUEST_AT_LEAST_SIZE(xDMXAddInputReq);
paddedLength = pad_to_int32(stuff->displayNameLength);
len = client->req_len - (sizeof(xDMXAddInputReq) >> 2);
if (len != Ones(stuff->valueMask) + paddedLength/4)
return BadLength;
memset(&attr, 0, sizeof(attr));
value_list = (CARD32 *)(stuff + 1);
count = dmxFetchInputAttributes(stuff->valueMask, &attr, value_list);
if (!(name = xalloc(stuff->displayNameLength + 1 + 4)))
return BadAlloc;
memcpy(name, &value_list[count], stuff->displayNameLength);
name[stuff->displayNameLength] = '\0';
attr.name = name;
status = dmxAddInput(&attr, &id);
xfree(name);
if (status) return status;
rep.type = X_Reply;
rep.sequenceNumber = client->sequence;
rep.length = 0;
rep.status = status;
rep.physicalId = id;
if (client->swapped) {
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n);
swapl(&rep.status, n);
swapl(&rep.physicalId, n);
}
WriteToClient(client, sizeof(xDMXAddInputReply), (char *)&rep);
return client->noClientException;
}
static int ProcDMXRemoveInput(ClientPtr client)
{
REQUEST(xDMXRemoveInputReq);
xDMXRemoveInputReply rep;
int n;
int status = 0;
REQUEST_SIZE_MATCH(xDMXRemoveInputReq);
status = dmxRemoveInput(stuff->physicalId);
if (status) return status;
rep.type = X_Reply;
rep.sequenceNumber = client->sequence;
rep.length = 0;
rep.status = status;
if (client->swapped) {
swaps(&rep.sequenceNumber, n);
swapl(&rep.length, n);
swapl(&rep.status, n);
}
WriteToClient(client, sizeof(xDMXRemoveInputReply), (char *)&rep);
return client->noClientException;
}
static int ProcDMXDispatch(ClientPtr client)
{
REQUEST(xReq);
switch (stuff->data) {
case X_DMXQueryVersion: return ProcDMXQueryVersion(client);
case X_DMXSync: return ProcDMXSync(client);
case X_DMXForceWindowCreation: return ProcDMXForceWindowCreation(client);
case X_DMXGetScreenCount: return ProcDMXGetScreenCount(client);
case X_DMXGetScreenAttributes: return ProcDMXGetScreenAttributes(client);
case X_DMXChangeScreensAttributes:
return ProcDMXChangeScreensAttributes(client);
case X_DMXAddScreen: return ProcDMXAddScreen(client);
case X_DMXRemoveScreen: return ProcDMXRemoveScreen(client);
case X_DMXGetWindowAttributes: return ProcDMXGetWindowAttributes(client);
case X_DMXGetDesktopAttributes: return ProcDMXGetDesktopAttributes(client);
case X_DMXChangeDesktopAttributes:
return ProcDMXChangeDesktopAttributes(client);
case X_DMXGetInputCount: return ProcDMXGetInputCount(client);
case X_DMXGetInputAttributes: return ProcDMXGetInputAttributes(client);
case X_DMXAddInput: return ProcDMXAddInput(client);
case X_DMXRemoveInput: return ProcDMXRemoveInput(client);
case X_DMXGetScreenInformationDEPRECATED:
case X_DMXForceWindowCreationDEPRECATED:
case X_DMXReconfigureScreenDEPRECATED:
return BadImplementation;
default: return BadRequest;
}
}
static int SProcDMXQueryVersion(ClientPtr client)
{
int n;
REQUEST(xDMXQueryVersionReq);
swaps(&stuff->length, n);
REQUEST_SIZE_MATCH(xDMXQueryVersionReq);
return ProcDMXQueryVersion(client);
}
static int SProcDMXSync(ClientPtr client)
{
int n;
REQUEST(xDMXSyncReq);
swaps(&stuff->length, n);
REQUEST_SIZE_MATCH(xDMXSyncReq);
return ProcDMXSync(client);
}
static int SProcDMXForceWindowCreation(ClientPtr client)
{
int n;
REQUEST(xDMXForceWindowCreationReq);
swaps(&stuff->length, n);
REQUEST_SIZE_MATCH(xDMXForceWindowCreationReq);
swaps(&stuff->window, n);
return ProcDMXForceWindowCreation(client);
}
static int SProcDMXGetScreenCount(ClientPtr client)
{
int n;
REQUEST(xDMXGetScreenCountReq);
swaps(&stuff->length, n);
REQUEST_SIZE_MATCH(xDMXGetScreenCountReq);
return ProcDMXGetScreenCount(client);
}
static int SProcDMXGetScreenAttributes(ClientPtr client)
{
int n;
REQUEST(xDMXGetScreenAttributesReq);
swaps(&stuff->length, n);
REQUEST_SIZE_MATCH(xDMXGetScreenAttributesReq);
swapl(&stuff->physicalScreen, n);
return ProcDMXGetScreenAttributes(client);
}
static int SProcDMXChangeScreensAttributes(ClientPtr client)
{
int n;
REQUEST(xDMXChangeScreensAttributesReq);
swaps(&stuff->length, n);
REQUEST_AT_LEAST_SIZE(xDMXGetScreenAttributesReq);
swapl(&stuff->screenCount, n);
swapl(&stuff->maskCount, n);
SwapRestL(stuff);
return ProcDMXGetScreenAttributes(client);
}
static int SProcDMXAddScreen(ClientPtr client)
{
int n;
int paddedLength;
REQUEST(xDMXAddScreenReq);
swaps(&stuff->length, n);
REQUEST_AT_LEAST_SIZE(xDMXAddScreenReq);
swapl(&stuff->displayNameLength, n);
swapl(&stuff->valueMask, n);
paddedLength = pad_to_int32(stuff->displayNameLength);
SwapLongs((CARD32 *)(stuff+1), LengthRestL(stuff) - paddedLength/4);
return ProcDMXAddScreen(client);
}
static int SProcDMXRemoveScreen(ClientPtr client)
{
int n;
REQUEST(xDMXRemoveScreenReq);
swaps(&stuff->length, n);
REQUEST_SIZE_MATCH(xDMXRemoveScreenReq);
swapl(&stuff->physicalScreen, n);
return ProcDMXRemoveScreen(client);
}
static int SProcDMXGetWindowAttributes(ClientPtr client)
{
int n;
REQUEST(xDMXGetWindowAttributesReq);
swaps(&stuff->length, n);
REQUEST_SIZE_MATCH(xDMXGetWindowAttributesReq);
swapl(&stuff->window, n);
return ProcDMXGetWindowAttributes(client);
}
static int SProcDMXGetDesktopAttributes(ClientPtr client)
{
int n;
REQUEST(xDMXGetDesktopAttributesReq);
swaps(&stuff->length, n);
REQUEST_SIZE_MATCH(xDMXGetDesktopAttributesReq);
return ProcDMXGetDesktopAttributes(client);
}
static int SProcDMXChangeDesktopAttributes(ClientPtr client)
{
int n;
REQUEST(xDMXChangeDesktopAttributesReq);
swaps(&stuff->length, n);
REQUEST_AT_LEAST_SIZE(xDMXChangeDesktopAttributesReq);
swapl(&stuff->valueMask, n);
SwapRestL(stuff);
return ProcDMXChangeDesktopAttributes(client);
}
static int SProcDMXGetInputCount(ClientPtr client)
{
int n;
REQUEST(xDMXGetInputCountReq);
swaps(&stuff->length, n);
REQUEST_SIZE_MATCH(xDMXGetInputCountReq);
return ProcDMXGetInputCount(client);
}
static int SProcDMXGetInputAttributes(ClientPtr client)
{
int n;
REQUEST(xDMXGetInputAttributesReq);
swaps(&stuff->length, n);
REQUEST_SIZE_MATCH(xDMXGetInputAttributesReq);
swapl(&stuff->deviceId, n);
return ProcDMXGetInputAttributes(client);
}
static int SProcDMXAddInput(ClientPtr client)
{
int n;
int paddedLength;
REQUEST(xDMXAddInputReq);
swaps(&stuff->length, n);
REQUEST_AT_LEAST_SIZE(xDMXAddInputReq);
swapl(&stuff->displayNameLength, n);
swapl(&stuff->valueMask, n);
paddedLength = pad_to_int32(stuff->displayNameLength);
SwapLongs((CARD32 *)(stuff+1), LengthRestL(stuff) - paddedLength/4);
return ProcDMXAddInput(client);
}
static int SProcDMXRemoveInput(ClientPtr client)
{
int n;
REQUEST(xDMXRemoveInputReq);
swaps(&stuff->length, n);
REQUEST_SIZE_MATCH(xDMXRemoveInputReq);
swapl(&stuff->physicalId, n);
return ProcDMXRemoveInput(client);
}
static int SProcDMXDispatch (ClientPtr client)
{
REQUEST(xReq);
switch (stuff->data) {
case X_DMXQueryVersion: return SProcDMXQueryVersion(client);
case X_DMXSync: return SProcDMXSync(client);
case X_DMXForceWindowCreation: return SProcDMXForceWindowCreation(client);
case X_DMXGetScreenCount: return SProcDMXGetScreenCount(client);
case X_DMXGetScreenAttributes: return SProcDMXGetScreenAttributes(client);
case X_DMXChangeScreensAttributes:
return SProcDMXChangeScreensAttributes(client);
case X_DMXAddScreen: return SProcDMXAddScreen(client);
case X_DMXRemoveScreen: return SProcDMXRemoveScreen(client);
case X_DMXGetWindowAttributes: return SProcDMXGetWindowAttributes(client);
case X_DMXGetDesktopAttributes:
return SProcDMXGetDesktopAttributes(client);
case X_DMXChangeDesktopAttributes:
return SProcDMXChangeDesktopAttributes(client);
case X_DMXGetInputCount: return SProcDMXGetInputCount(client);
case X_DMXGetInputAttributes: return SProcDMXGetInputAttributes(client);
case X_DMXAddInput: return SProcDMXAddInput(client);
case X_DMXRemoveInput: return SProcDMXRemoveInput(client);
case X_DMXGetScreenInformationDEPRECATED:
case X_DMXForceWindowCreationDEPRECATED:
case X_DMXReconfigureScreenDEPRECATED:
return BadImplementation;
default: return BadRequest;
}
}