diff options
author | marha <marha@users.sourceforge.net> | 2011-09-22 15:20:09 +0200 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2011-09-22 15:20:09 +0200 |
commit | c1e6c7428a8d2c1b60ffac7df7a3f56c300fa983 (patch) | |
tree | 8874978d314129a4f47ee575b076c2d8eb1a8738 /xorg-server/hw/dmx/dmx.c | |
parent | 37466741e35c5eb3b204863a5023bf8d192efc06 (diff) | |
download | vcxsrv-c1e6c7428a8d2c1b60ffac7df7a3f56c300fa983.tar.gz vcxsrv-c1e6c7428a8d2c1b60ffac7df7a3f56c300fa983.tar.bz2 vcxsrv-c1e6c7428a8d2c1b60ffac7df7a3f56c300fa983.zip |
libxtrans libX11 libX11 libXext mesa xserver git update 22 sep 2011
Diffstat (limited to 'xorg-server/hw/dmx/dmx.c')
-rw-r--r-- | xorg-server/hw/dmx/dmx.c | 2165 |
1 files changed, 1068 insertions, 1097 deletions
diff --git a/xorg-server/hw/dmx/dmx.c b/xorg-server/hw/dmx/dmx.c index 5de565f85..01a744849 100644 --- a/xorg-server/hw/dmx/dmx.c +++ b/xorg-server/hw/dmx/dmx.c @@ -1,1097 +1,1068 @@ -/*
- * 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 (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, 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 (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, 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;
-}
+/* + * 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; +} |