xserver-multidpi/hw/dmx/dmx.c
Tiago Vignatti cbd4d5dbb7 xserver: delete pervasively use of DISPATCH_PROC
Some functions had to be moved around due some missing static definitions.
Another minor clean up like inexistent function declarations and etc were made
also.

Part of this patch was cooked using:
sed -i -e '/static DISPATCH_PROC*.*;/d' `git ls-files`

Signed-off-by: Tiago Vignatti <tiago.vignatti@nokia.com>
Reviewed-by: Mikhail Gusarov <dottedmag@dottedmag.net>
2010-09-28 16:45:05 +03:00

1096 lines
33 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;
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 Success;
}
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 Success;
}
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 Success;
}
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 Success;
}
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 = 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, n);
swapl(&rep.length, n);
swapl(&rep.status, n);
swapl(&rep.errorScreen, n);
}
WriteToClient(client,
sizeof(xDMXChangeScreensAttributesReply),
(char *)&rep);
return Success;
}
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 = 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, n);
swapl(&rep.length, n);
swapl(&rep.status, n);
swapl(&rep.physicalScreen, n);
}
WriteToClient(client,
sizeof(xDMXAddScreenReply),
(char *)&rep);
return Success;
}
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 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 (!(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 = 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, 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);
}
free(vis);
free(pos);
free(windows);
free(screens);
return Success;
}
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 Success;
}
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 Success;
}
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 Success;
}
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 Success;
}
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 = 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, n);
swapl(&rep.length, n);
swapl(&rep.status, n);
swapl(&rep.physicalId, n);
}
WriteToClient(client, sizeof(xDMXAddInputReply), (char *)&rep);
return Success;
}
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 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)
{
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;
}
}
/** Initialize the extension. */
void DMXExtensionInit(void)
{
ExtensionEntry *extEntry;
if ((extEntry = AddExtension(DMX_EXTENSION_NAME, 0, 0,
ProcDMXDispatch, SProcDMXDispatch,
NULL, StandardMinorOpcode)))
DMXCode = extEntry->base;
}