xserver-multidpi/hw/dmx/dmx.c
Keith Packard 9838b7032e Introduce a consistent coding style
This is strictly the application of the script 'x-indent-all.sh'
from util/modular. Compared to the patch that Daniel posted in
January, I've added a few indent flags:

	-bap
	-psl
	-T PrivatePtr
	-T pmWait
	-T _XFUNCPROTOBEGIN
	-T _XFUNCPROTOEND
	-T _X_EXPORT

The typedefs were needed to make the output of sdksyms.sh match the
previous output, otherwise, the code is formatted badly enough that
sdksyms.sh generates incorrect output.

The generated code was compared with the previous version and found to
be essentially identical -- "assert" line numbers and BUILD_TIME were
the only differences found.

The comparison was done with this script:

dir1=$1
dir2=$2

for dir in $dir1 $dir2; do
	(cd $dir && find . -name '*.o' | while read file; do
		dir=`dirname $file`
		base=`basename $file .o`
		dump=$dir/$base.dump
		objdump -d $file > $dump
	done)
done

find $dir1 -name '*.dump' | while read dump; do
	otherdump=`echo $dump | sed "s;$dir1;$dir2;"`
	diff -u $dump $otherdump
done

Signed-off-by: Keith Packard <keithp@keithp.com>
Acked-by: Daniel Stone <daniel@fooishbar.org>
Acked-by: Alan Coopersmith <alan.coopersmith@oracle.com>
2012-03-21 13:54:42 -07:00

1173 lines
31 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 \a 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 int
_DMXXineramaActive(void)
{
#ifdef PANORAMIX
return !noPanoramiXExtension;
#endif
return 0;
}
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;
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);
swapl(&rep.length);
swapl(&rep.majorVersion);
swapl(&rep.minorVersion);
swapl(&rep.patchVersion);
}
WriteToClient(client, sizeof(xDMXQueryVersionReply), (char *) &rep);
return Success;
}
static int
ProcDMXSync(ClientPtr client)
{
xDMXSyncReply rep;
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);
swapl(&rep.length);
swapl(&rep.status);
}
WriteToClient(client, sizeof(xDMXSyncReply), (char *) &rep);
return Success;
}
static int
ProcDMXForceWindowCreation(ClientPtr client)
{
xDMXForceWindowCreationReply rep;
REQUEST(xDMXForceWindowCreationReq);
WindowPtr pWin;
REQUEST_SIZE_MATCH(xDMXForceWindowCreationReq);
#ifdef PANORAMIX
if (!noPanoramiXExtension) {
PanoramiXRes *win;
int i;
if (Success != dixLookupResourceByType((pointer *) &win,
stuff->window, XRT_WINDOW,
client, 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);
swapl(&rep.length);
swapl(&rep.status);
}
WriteToClient(client, sizeof(xDMXForceWindowCreationReply), (char *) &rep);
return Success;
}
static int
ProcDMXGetScreenCount(ClientPtr client)
{
xDMXGetScreenCountReply rep;
REQUEST_SIZE_MATCH(xDMXGetScreenCountReq);
rep.type = X_Reply;
rep.sequenceNumber = client->sequence;
rep.length = 0;
rep.screenCount = dmxGetNumScreens();
if (client->swapped) {
swaps(&rep.sequenceNumber);
swapl(&rep.length);
swapl(&rep.screenCount);
}
WriteToClient(client, sizeof(xDMXGetScreenCountReply), (char *) &rep);
return Success;
}
static int
ProcDMXGetScreenAttributes(ClientPtr client)
{
REQUEST(xDMXGetScreenAttributesReq);
xDMXGetScreenAttributesReply rep;
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);
swapl(&rep.length);
swapl(&rep.displayNameLength);
swapl(&rep.logicalScreen);
swaps(&rep.screenWindowWidth);
swaps(&rep.screenWindowHeight);
swaps(&rep.screenWindowXoffset);
swaps(&rep.screenWindowYoffset);
swaps(&rep.rootWindowWidth);
swaps(&rep.rootWindowHeight);
swaps(&rep.rootWindowXoffset);
swaps(&rep.rootWindowYoffset);
swaps(&rep.rootWindowXorigin);
swaps(&rep.rootWindowYorigin);
}
WriteToClient(client, sizeof(xDMXGetScreenAttributesReply), (char *) &rep);
if (length)
WriteToClient(client, length, (char *) attr.displayName);
return Success;
}
static int
ProcDMXChangeScreensAttributes(ClientPtr client)
{
REQUEST(xDMXChangeScreensAttributesReq);
xDMXChangeScreensAttributesReply rep;
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 = malloc(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
free(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);
swapl(&rep.length);
swapl(&rep.status);
swapl(&rep.errorScreen);
}
WriteToClient(client,
sizeof(xDMXChangeScreensAttributesReply), (char *) &rep);
return Success;
}
static int
ProcDMXAddScreen(ClientPtr client)
{
REQUEST(xDMXAddScreenReq);
xDMXAddScreenReply rep;
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 = malloc(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);
free(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);
swapl(&rep.length);
swapl(&rep.status);
swapl(&rep.physicalScreen);
}
WriteToClient(client, sizeof(xDMXAddScreenReply), (char *) &rep);
return Success;
}
static int
ProcDMXRemoveScreen(ClientPtr client)
{
REQUEST(xDMXRemoveScreenReq);
xDMXRemoveScreenReply rep;
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);
swapl(&rep.length);
swapl(&rep.status);
}
WriteToClient(client, sizeof(xDMXRemoveScreenReply), (char *) &rep);
return Success;
}
#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 (Success != dixLookupResourceByType((pointer *) &win,
window, XRT_WINDOW,
client, 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;
CARD32 *screens;
CARD32 *windows;
xRectangle *pos, *vis;
int count = dmxMaxNumScreens();
REQUEST_SIZE_MATCH(xDMXGetWindowAttributesReq);
if (!(screens = malloc(count * sizeof(*screens))))
return BadAlloc;
if (!(windows = malloc(count * sizeof(*windows)))) {
free(screens);
return BadAlloc;
}
if (!(pos = malloc(count * sizeof(*pos)))) {
free(windows);
free(screens);
return BadAlloc;
}
if (!(vis = malloc(count * sizeof(*vis)))) {
free(pos);
free(windows);
free(screens);
return BadAlloc;
}
if ((count = dmxPopulate(client, stuff->window, screens, windows,
pos, vis)) < 0) {
free(vis);
free(pos);
free(windows);
free(screens);
return BadWindow;
}
rep.type = X_Reply;
rep.sequenceNumber = client->sequence;
rep.length = count * 6;
rep.screenCount = count;
if (client->swapped) {
swaps(&rep.sequenceNumber);
swapl(&rep.length);
swapl(&rep.screenCount);
for (i = 0; i < count; i++) {
swapl(&screens[i]);
swapl(&windows[i]);
swaps(&pos[i].x);
swaps(&pos[i].y);
swaps(&pos[i].width);
swaps(&pos[i].height);
swaps(&vis[i].x);
swaps(&vis[i].y);
swaps(&vis[i].width);
swaps(&vis[i].height);
}
}
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);
}
free(vis);
free(pos);
free(windows);
free(screens);
return Success;
}
static int
ProcDMXGetDesktopAttributes(ClientPtr client)
{
xDMXGetDesktopAttributesReply rep;
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);
swapl(&rep.length);
swaps(&rep.width);
swaps(&rep.height);
swaps(&rep.shiftX);
swaps(&rep.shiftY);
}
WriteToClient(client, sizeof(xDMXGetDesktopAttributesReply), (char *) &rep);
return Success;
}
static int
ProcDMXChangeDesktopAttributes(ClientPtr client)
{
REQUEST(xDMXChangeDesktopAttributesReq);
xDMXChangeDesktopAttributesReply rep;
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);
swapl(&rep.length);
swapl(&rep.status);
}
WriteToClient(client,
sizeof(xDMXChangeDesktopAttributesReply), (char *) &rep);
return Success;
}
static int
ProcDMXGetInputCount(ClientPtr client)
{
xDMXGetInputCountReply rep;
REQUEST_SIZE_MATCH(xDMXGetInputCountReq);
rep.type = X_Reply;
rep.sequenceNumber = client->sequence;
rep.length = 0;
rep.inputCount = dmxGetInputCount();
if (client->swapped) {
swaps(&rep.sequenceNumber);
swapl(&rep.length);
swapl(&rep.inputCount);
}
WriteToClient(client, sizeof(xDMXGetInputCountReply), (char *) &rep);
return Success;
}
static int
ProcDMXGetInputAttributes(ClientPtr client)
{
REQUEST(xDMXGetInputAttributesReq);
xDMXGetInputAttributesReply rep;
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);
swapl(&rep.length);
swapl(&rep.inputType);
swapl(&rep.physicalScreen);
swapl(&rep.physicalId);
swapl(&rep.nameLength);
}
WriteToClient(client, sizeof(xDMXGetInputAttributesReply), (char *) &rep);
if (length)
WriteToClient(client, length, (char *) attr.name);
return Success;
}
static int
ProcDMXAddInput(ClientPtr client)
{
REQUEST(xDMXAddInputReq);
xDMXAddInputReply rep;
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 = malloc(stuff->displayNameLength + 1 + 4)))
return BadAlloc;
memcpy(name, &value_list[count], stuff->displayNameLength);
name[stuff->displayNameLength] = '\0';
attr.name = name;
status = dmxAddInput(&attr, &id);
free(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);
swapl(&rep.length);
swapl(&rep.status);
swapl(&rep.physicalId);
}
WriteToClient(client, sizeof(xDMXAddInputReply), (char *) &rep);
return Success;
}
static int
ProcDMXRemoveInput(ClientPtr client)
{
REQUEST(xDMXRemoveInputReq);
xDMXRemoveInputReply rep;
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);
swapl(&rep.length);
swapl(&rep.status);
}
WriteToClient(client, sizeof(xDMXRemoveInputReply), (char *) &rep);
return Success;
}
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)
{
REQUEST(xDMXQueryVersionReq);
swaps(&stuff->length);
REQUEST_SIZE_MATCH(xDMXQueryVersionReq);
return ProcDMXQueryVersion(client);
}
static int
SProcDMXSync(ClientPtr client)
{
REQUEST(xDMXSyncReq);
swaps(&stuff->length);
REQUEST_SIZE_MATCH(xDMXSyncReq);
return ProcDMXSync(client);
}
static int
SProcDMXForceWindowCreation(ClientPtr client)
{
REQUEST(xDMXForceWindowCreationReq);
swaps(&stuff->length);
REQUEST_SIZE_MATCH(xDMXForceWindowCreationReq);
swapl(&stuff->window);
return ProcDMXForceWindowCreation(client);
}
static int
SProcDMXGetScreenCount(ClientPtr client)
{
REQUEST(xDMXGetScreenCountReq);
swaps(&stuff->length);
REQUEST_SIZE_MATCH(xDMXGetScreenCountReq);
return ProcDMXGetScreenCount(client);
}
static int
SProcDMXGetScreenAttributes(ClientPtr client)
{
REQUEST(xDMXGetScreenAttributesReq);
swaps(&stuff->length);
REQUEST_SIZE_MATCH(xDMXGetScreenAttributesReq);
swapl(&stuff->physicalScreen);
return ProcDMXGetScreenAttributes(client);
}
static int
SProcDMXChangeScreensAttributes(ClientPtr client)
{
REQUEST(xDMXChangeScreensAttributesReq);
swaps(&stuff->length);
REQUEST_AT_LEAST_SIZE(xDMXGetScreenAttributesReq);
swapl(&stuff->screenCount);
swapl(&stuff->maskCount);
SwapRestL(stuff);
return ProcDMXGetScreenAttributes(client);
}
static int
SProcDMXAddScreen(ClientPtr client)
{
int paddedLength;
REQUEST(xDMXAddScreenReq);
swaps(&stuff->length);
REQUEST_AT_LEAST_SIZE(xDMXAddScreenReq);
swapl(&stuff->displayNameLength);
swapl(&stuff->valueMask);
paddedLength = pad_to_int32(stuff->displayNameLength);
SwapLongs((CARD32 *) (stuff + 1), LengthRestL(stuff) - paddedLength / 4);
return ProcDMXAddScreen(client);
}
static int
SProcDMXRemoveScreen(ClientPtr client)
{
REQUEST(xDMXRemoveScreenReq);
swaps(&stuff->length);
REQUEST_SIZE_MATCH(xDMXRemoveScreenReq);
swapl(&stuff->physicalScreen);
return ProcDMXRemoveScreen(client);
}
static int
SProcDMXGetWindowAttributes(ClientPtr client)
{
REQUEST(xDMXGetWindowAttributesReq);
swaps(&stuff->length);
REQUEST_SIZE_MATCH(xDMXGetWindowAttributesReq);
swapl(&stuff->window);
return ProcDMXGetWindowAttributes(client);
}
static int
SProcDMXGetDesktopAttributes(ClientPtr client)
{
REQUEST(xDMXGetDesktopAttributesReq);
swaps(&stuff->length);
REQUEST_SIZE_MATCH(xDMXGetDesktopAttributesReq);
return ProcDMXGetDesktopAttributes(client);
}
static int
SProcDMXChangeDesktopAttributes(ClientPtr client)
{
REQUEST(xDMXChangeDesktopAttributesReq);
swaps(&stuff->length);
REQUEST_AT_LEAST_SIZE(xDMXChangeDesktopAttributesReq);
swapl(&stuff->valueMask);
SwapRestL(stuff);
return ProcDMXChangeDesktopAttributes(client);
}
static int
SProcDMXGetInputCount(ClientPtr client)
{
REQUEST(xDMXGetInputCountReq);
swaps(&stuff->length);
REQUEST_SIZE_MATCH(xDMXGetInputCountReq);
return ProcDMXGetInputCount(client);
}
static int
SProcDMXGetInputAttributes(ClientPtr client)
{
REQUEST(xDMXGetInputAttributesReq);
swaps(&stuff->length);
REQUEST_SIZE_MATCH(xDMXGetInputAttributesReq);
swapl(&stuff->deviceId);
return ProcDMXGetInputAttributes(client);
}
static int
SProcDMXAddInput(ClientPtr client)
{
int paddedLength;
REQUEST(xDMXAddInputReq);
swaps(&stuff->length);
REQUEST_AT_LEAST_SIZE(xDMXAddInputReq);
swapl(&stuff->displayNameLength);
swapl(&stuff->valueMask);
paddedLength = pad_to_int32(stuff->displayNameLength);
SwapLongs((CARD32 *) (stuff + 1), LengthRestL(stuff) - paddedLength / 4);
return ProcDMXAddInput(client);
}
static int
SProcDMXRemoveInput(ClientPtr client)
{
REQUEST(xDMXRemoveInputReq);
swaps(&stuff->length);
REQUEST_SIZE_MATCH(xDMXRemoveInputReq);
swapl(&stuff->physicalId);
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;
}
}
/** Initialize the extension. */
void
DMXExtensionInit(void)
{
ExtensionEntry *extEntry;
if ((extEntry = AddExtension(DMX_EXTENSION_NAME, 0, 0,
ProcDMXDispatch, SProcDMXDispatch,
NULL, StandardMinorOpcode)))
DMXCode = extEntry->base;
}