xserver-multidpi/hw/dmx/dmx.c

1201 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 functions 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 "extinit.h"
#include "opaque.h"
#include "dmx.h"
#include "dmxextension.h"
#include <X11/extensions/dmxproto.h>
#include <X11/extensions/dmx.h>
#include "protocol-versions.h"
#ifdef PANORAMIX
#include "panoramiXsrv.h"
#endif
static unsigned char DMXCode;
static int
_DMXXineramaActive(void)
{
#ifdef PANORAMIX
return !noPanoramiXExtension;
#else
return 0;
#endif
}
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 = {
.type = X_Reply,
.sequenceNumber = client->sequence,
.length = 0,
.majorVersion = SERVER_DMX_MAJOR_VERSION,
.minorVersion = SERVER_DMX_MINOR_VERSION,
.patchVersion = SERVER_DMX_PATCH_VERSION
};
REQUEST_SIZE_MATCH(xDMXQueryVersionReq);
if (client->swapped) {
swaps(&rep.sequenceNumber);
swapl(&rep.length);
swapl(&rep.majorVersion);
swapl(&rep.minorVersion);
swapl(&rep.patchVersion);
}
WriteToClient(client, sizeof(xDMXQueryVersionReply), &rep);
return Success;
}
static int
ProcDMXSync(ClientPtr client)
{
xDMXSyncReply rep;
REQUEST_SIZE_MATCH(xDMXSyncReq);
dmxFlushPendingSyncs();
rep = (xDMXSyncReply) {
.type = X_Reply,
.sequenceNumber = client->sequence,
.length = 0,
.status = 0
};
if (client->swapped) {
swaps(&rep.sequenceNumber);
swapl(&rep.length);
swapl(&rep.status);
}
WriteToClient(client, sizeof(xDMXSyncReply), &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((void **) &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 = (xDMXForceWindowCreationReply) {
.type = X_Reply,
.sequenceNumber = client->sequence,
.length = 0,
.status = 0
};
if (client->swapped) {
swaps(&rep.sequenceNumber);
swapl(&rep.length);
swapl(&rep.status);
}
WriteToClient(client, sizeof(xDMXForceWindowCreationReply), &rep);
return Success;
}
static int
ProcDMXGetScreenCount(ClientPtr client)
{
xDMXGetScreenCountReply rep;
REQUEST_SIZE_MATCH(xDMXGetScreenCountReq);
rep = (xDMXGetScreenCountReply) {
.type = X_Reply,
.sequenceNumber = client->sequence,
.length = 0,
.screenCount = dmxGetNumScreens()
};
if (client->swapped) {
swaps(&rep.sequenceNumber);
swapl(&rep.length);
swapl(&rep.screenCount);
}
WriteToClient(client, sizeof(xDMXGetScreenCountReply), &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;
length = attr.displayName ? strlen(attr.displayName) : 0;
paddedLength = pad_to_int32(length);
rep = (xDMXGetScreenAttributesReply) {
.type = X_Reply,
.sequenceNumber = client->sequence,
.length =
bytes_to_int32((sizeof(xDMXGetScreenAttributesReply) -
sizeof(xGenericReply))
+ paddedLength),
.displayNameLength = length,
.logicalScreen = attr.logicalScreen,
.screenWindowWidth = attr.screenWindowWidth,
.screenWindowHeight = attr.screenWindowHeight,
.screenWindowXoffset = attr.screenWindowXoffset,
.screenWindowYoffset = attr.screenWindowYoffset,
.rootWindowWidth = attr.rootWindowWidth,
.rootWindowHeight = attr.rootWindowHeight,
.rootWindowXoffset = attr.rootWindowXoffset,
.rootWindowYoffset = attr.rootWindowYoffset,
.rootWindowXorigin = attr.rootWindowXorigin,
.rootWindowYorigin = attr.rootWindowYorigin
};
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), &rep);
if (length)
WriteToClient(client, length, 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 = xallocarray(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;
}
#ifdef PANORAMIX
status = dmxConfigureScreenWindows(stuff->screenCount,
screen_list, attribs, &errorScreen);
#endif
free(attribs);
if (status == BadValue)
return status;
noxinerama:
rep = (xDMXChangeScreensAttributesReply) {
.type = X_Reply,
.sequenceNumber = client->sequence,
.length = 0,
.status = status,
.errorScreen = errorScreen
};
if (client->swapped) {
swaps(&rep.sequenceNumber);
swapl(&rep.length);
swapl(&rep.status);
swapl(&rep.errorScreen);
}
WriteToClient(client, sizeof(xDMXChangeScreensAttributesReply), &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 = (xDMXAddScreenReply) {
.type = X_Reply,
.sequenceNumber = client->sequence,
.length = 0,
.status = status,
.physicalScreen = stuff->physicalScreen
};
if (client->swapped) {
swaps(&rep.sequenceNumber);
swapl(&rep.length);
swapl(&rep.status);
swapl(&rep.physicalScreen);
}
WriteToClient(client, sizeof(xDMXAddScreenReply), &rep);
return Success;
}
static int
ProcDMXRemoveScreen(ClientPtr client)
{
REQUEST(xDMXRemoveScreenReq);
xDMXRemoveScreenReply rep;
int status = 0;
REQUEST_SIZE_MATCH(xDMXRemoveScreenReq);
status = dmxDetachScreen(stuff->physicalScreen);
rep = (xDMXRemoveScreenReply) {
.type = X_Reply,
.sequenceNumber = client->sequence,
.length = 0,
.status = status
};
if (client->swapped) {
swaps(&rep.sequenceNumber);
swapl(&rep.length);
swapl(&rep.status);
}
WriteToClient(client, sizeof(xDMXRemoveScreenReply), &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((void **) &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 = xallocarray(count, sizeof(*screens))))
return BadAlloc;
if (!(windows = xallocarray(count, sizeof(*windows)))) {
free(screens);
return BadAlloc;
}
if (!(pos = xallocarray(count, sizeof(*pos)))) {
free(windows);
free(screens);
return BadAlloc;
}
if (!(vis = xallocarray(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 = (xDMXGetWindowAttributesReply) {
.type = X_Reply,
.sequenceNumber = client->sequence,
.length = count * 6,
.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), &rep);
if (count) {
WriteToClient(client, count * sizeof(*screens), screens);
WriteToClient(client, count * sizeof(*windows), windows);
WriteToClient(client, count * sizeof(*pos), pos);
WriteToClient(client, count * sizeof(*vis), 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 = (xDMXGetDesktopAttributesReply) {
.type = X_Reply,
.sequenceNumber = client->sequence,
.length = 0,
.width = attr.width,
.height = attr.height,
.shiftX = attr.shiftX,
.shiftY = attr.shiftY
};
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), &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);
#ifdef PANORAMIX
status = dmxConfigureDesktop(&attr);
#endif
if (status == BadValue)
return status;
noxinerama:
rep = (xDMXChangeDesktopAttributesReply) {
.type = X_Reply,
.sequenceNumber = client->sequence,
.length = 0,
.status = status
};
if (client->swapped) {
swaps(&rep.sequenceNumber);
swapl(&rep.length);
swapl(&rep.status);
}
WriteToClient(client, sizeof(xDMXChangeDesktopAttributesReply), &rep);
return Success;
}
static int
ProcDMXGetInputCount(ClientPtr client)
{
xDMXGetInputCountReply rep;
REQUEST_SIZE_MATCH(xDMXGetInputCountReq);
rep = (xDMXGetInputCountReply) {
.type = X_Reply,
.sequenceNumber = client->sequence,
.length = 0,
.inputCount = dmxGetInputCount()
};
if (client->swapped) {
swaps(&rep.sequenceNumber);
swapl(&rep.length);
swapl(&rep.inputCount);
}
WriteToClient(client, sizeof(xDMXGetInputCountReply), &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;
length = attr.name ? strlen(attr.name) : 0;
paddedLength = pad_to_int32(length);
rep = (xDMXGetInputAttributesReply) {
.type = X_Reply,
.sequenceNumber = client->sequence,
.length = bytes_to_int32(paddedLength),
.inputType = attr.inputType,
.physicalScreen = attr.physicalScreen,
.physicalId = attr.physicalId,
.nameLength = length,
.isCore = attr.isCore,
.sendsCore = attr.sendsCore,
.detached = attr.detached
};
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), &rep);
if (length)
WriteToClient(client, length, 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 = (xDMXAddInputReply) {
.type = X_Reply,
.sequenceNumber = client->sequence,
.length = 0,
.status = status,
.physicalId = id
};
if (client->swapped) {
swaps(&rep.sequenceNumber);
swapl(&rep.length);
swapl(&rep.status);
swapl(&rep.physicalId);
}
WriteToClient(client, sizeof(xDMXAddInputReply), &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 = (xDMXRemoveInputReply) {
.type = X_Reply,
.sequenceNumber = client->sequence,
.length = 0,
.status = status
};
if (client->swapped) {
swaps(&rep.sequenceNumber);
swapl(&rep.length);
swapl(&rep.status);
}
WriteToClient(client, sizeof(xDMXRemoveInputReply), &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 _X_COLD
SProcDMXQueryVersion(ClientPtr client)
{
REQUEST(xDMXQueryVersionReq);
swaps(&stuff->length);
REQUEST_SIZE_MATCH(xDMXQueryVersionReq);
return ProcDMXQueryVersion(client);
}
static int _X_COLD
SProcDMXSync(ClientPtr client)
{
REQUEST(xDMXSyncReq);
swaps(&stuff->length);
REQUEST_SIZE_MATCH(xDMXSyncReq);
return ProcDMXSync(client);
}
static int _X_COLD
SProcDMXForceWindowCreation(ClientPtr client)
{
REQUEST(xDMXForceWindowCreationReq);
swaps(&stuff->length);
REQUEST_SIZE_MATCH(xDMXForceWindowCreationReq);
swapl(&stuff->window);
return ProcDMXForceWindowCreation(client);
}
static int _X_COLD
SProcDMXGetScreenCount(ClientPtr client)
{
REQUEST(xDMXGetScreenCountReq);
swaps(&stuff->length);
REQUEST_SIZE_MATCH(xDMXGetScreenCountReq);
return ProcDMXGetScreenCount(client);
}
static int _X_COLD
SProcDMXGetScreenAttributes(ClientPtr client)
{
REQUEST(xDMXGetScreenAttributesReq);
swaps(&stuff->length);
REQUEST_SIZE_MATCH(xDMXGetScreenAttributesReq);
swapl(&stuff->physicalScreen);
return ProcDMXGetScreenAttributes(client);
}
static int _X_COLD
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 _X_COLD
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 _X_COLD
SProcDMXRemoveScreen(ClientPtr client)
{
REQUEST(xDMXRemoveScreenReq);
swaps(&stuff->length);
REQUEST_SIZE_MATCH(xDMXRemoveScreenReq);
swapl(&stuff->physicalScreen);
return ProcDMXRemoveScreen(client);
}
static int _X_COLD
SProcDMXGetWindowAttributes(ClientPtr client)
{
REQUEST(xDMXGetWindowAttributesReq);
swaps(&stuff->length);
REQUEST_SIZE_MATCH(xDMXGetWindowAttributesReq);
swapl(&stuff->window);
return ProcDMXGetWindowAttributes(client);
}
static int _X_COLD
SProcDMXGetDesktopAttributes(ClientPtr client)
{
REQUEST(xDMXGetDesktopAttributesReq);
swaps(&stuff->length);
REQUEST_SIZE_MATCH(xDMXGetDesktopAttributesReq);
return ProcDMXGetDesktopAttributes(client);
}
static int _X_COLD
SProcDMXChangeDesktopAttributes(ClientPtr client)
{
REQUEST(xDMXChangeDesktopAttributesReq);
swaps(&stuff->length);
REQUEST_AT_LEAST_SIZE(xDMXChangeDesktopAttributesReq);
swapl(&stuff->valueMask);
SwapRestL(stuff);
return ProcDMXChangeDesktopAttributes(client);
}
static int _X_COLD
SProcDMXGetInputCount(ClientPtr client)
{
REQUEST(xDMXGetInputCountReq);
swaps(&stuff->length);
REQUEST_SIZE_MATCH(xDMXGetInputCountReq);
return ProcDMXGetInputCount(client);
}
static int _X_COLD
SProcDMXGetInputAttributes(ClientPtr client)
{
REQUEST(xDMXGetInputAttributesReq);
swaps(&stuff->length);
REQUEST_SIZE_MATCH(xDMXGetInputAttributesReq);
swapl(&stuff->deviceId);
return ProcDMXGetInputAttributes(client);
}
static int _X_COLD
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 _X_COLD
SProcDMXRemoveInput(ClientPtr client)
{
REQUEST(xDMXRemoveInputReq);
swaps(&stuff->length);
REQUEST_SIZE_MATCH(xDMXRemoveInputReq);
swapl(&stuff->physicalId);
return ProcDMXRemoveInput(client);
}
static int _X_COLD
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;
}