9838b7032e
This is strictly the application of the script 'x-indent-all.sh' from util/modular. Compared to the patch that Daniel posted in January, I've added a few indent flags: -bap -psl -T PrivatePtr -T pmWait -T _XFUNCPROTOBEGIN -T _XFUNCPROTOEND -T _X_EXPORT The typedefs were needed to make the output of sdksyms.sh match the previous output, otherwise, the code is formatted badly enough that sdksyms.sh generates incorrect output. The generated code was compared with the previous version and found to be essentially identical -- "assert" line numbers and BUILD_TIME were the only differences found. The comparison was done with this script: dir1=$1 dir2=$2 for dir in $dir1 $dir2; do (cd $dir && find . -name '*.o' | while read file; do dir=`dirname $file` base=`basename $file .o` dump=$dir/$base.dump objdump -d $file > $dump done) done find $dir1 -name '*.dump' | while read dump; do otherdump=`echo $dump | sed "s;$dir1;$dir2;"` diff -u $dump $otherdump done Signed-off-by: Keith Packard <keithp@keithp.com> Acked-by: Daniel Stone <daniel@fooishbar.org> Acked-by: Alan Coopersmith <alan.coopersmith@oracle.com>
1173 lines
31 KiB
C
1173 lines
31 KiB
C
/*
|
|
* Copyright 2002-2004 Red Hat Inc., Durham, North Carolina.
|
|
*
|
|
* All Rights Reserved.
|
|
*
|
|
* Permission is hereby granted, free of charge, to any person obtaining
|
|
* a copy of this software and associated documentation files (the
|
|
* "Software"), to deal in the Software without restriction, including
|
|
* without limitation on the rights to use, copy, modify, merge,
|
|
* publish, distribute, sublicense, and/or sell copies of the Software,
|
|
* and to permit persons to whom the Software is furnished to do so,
|
|
* subject to the following conditions:
|
|
*
|
|
* The above copyright notice and this permission notice (including the
|
|
* next paragraph) shall be included in all copies or substantial
|
|
* portions of the Software.
|
|
*
|
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
|
|
* EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
|
|
* MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
|
|
* NON-INFRINGEMENT. IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
|
|
* BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
|
|
* ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
|
|
* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
* SOFTWARE.
|
|
*/
|
|
|
|
/*
|
|
* Authors:
|
|
* Rickard E. (Rik) Faith <faith@redhat.com>
|
|
*
|
|
*/
|
|
|
|
/** \file
|
|
* This file implements the server-side part of the DMX protocol. A
|
|
* vector of fucntions is provided at extension initialization time, so
|
|
* most all of the useful functions in this file are declared static and
|
|
* do not appear in the doxygen documentation.
|
|
*
|
|
* Much of the low-level work is done by functions in \a dmxextension.c
|
|
*
|
|
* Please see the Client-to-Server DMX Extension to the X Protocol
|
|
* document for details about the protocol. */
|
|
|
|
#ifdef HAVE_DMX_CONFIG_H
|
|
#include <dmx-config.h>
|
|
#endif
|
|
|
|
#include <X11/X.h>
|
|
#include <X11/Xproto.h>
|
|
#include "misc.h"
|
|
#include "os.h"
|
|
#include "dixstruct.h"
|
|
#include "extnsionst.h"
|
|
#include "opaque.h"
|
|
|
|
#include "dmxextension.h"
|
|
#include <X11/extensions/dmxproto.h>
|
|
#include <X11/extensions/dmx.h>
|
|
#include "protocol-versions.h"
|
|
|
|
#ifdef PANORAMIX
|
|
#include "panoramiX.h"
|
|
extern unsigned long XRT_WINDOW;
|
|
extern int PanoramiXNumScreens;
|
|
#endif
|
|
|
|
extern void DMXExtensionInit(void);
|
|
|
|
static unsigned char DMXCode;
|
|
|
|
static int
|
|
_DMXXineramaActive(void)
|
|
{
|
|
#ifdef PANORAMIX
|
|
return !noPanoramiXExtension;
|
|
#endif
|
|
return 0;
|
|
}
|
|
|
|
static void
|
|
dmxSetScreenAttribute(int bit, DMXScreenAttributesPtr attr, CARD32 value)
|
|
{
|
|
switch (1 << bit) {
|
|
case DMXScreenWindowWidth:
|
|
attr->screenWindowWidth = value;
|
|
break;
|
|
case DMXScreenWindowHeight:
|
|
attr->screenWindowHeight = value;
|
|
break;
|
|
case DMXScreenWindowXoffset:
|
|
attr->screenWindowXoffset = value;
|
|
break;
|
|
case DMXScreenWindowYoffset:
|
|
attr->screenWindowYoffset = value;
|
|
break;
|
|
case DMXRootWindowWidth:
|
|
attr->rootWindowWidth = value;
|
|
break;
|
|
case DMXRootWindowHeight:
|
|
attr->rootWindowHeight = value;
|
|
break;
|
|
case DMXRootWindowXoffset:
|
|
attr->rootWindowXoffset = value;
|
|
break;
|
|
case DMXRootWindowYoffset:
|
|
attr->rootWindowYoffset = value;
|
|
break;
|
|
case DMXRootWindowXorigin:
|
|
attr->rootWindowXorigin = value;
|
|
break;
|
|
case DMXRootWindowYorigin:
|
|
attr->rootWindowYorigin = value;
|
|
break;
|
|
}
|
|
}
|
|
|
|
static int
|
|
dmxFetchScreenAttributes(unsigned int mask,
|
|
DMXScreenAttributesPtr attr, CARD32 *value_list)
|
|
{
|
|
int i;
|
|
CARD32 *value = value_list;
|
|
int count = 0;
|
|
|
|
for (i = 0; i < 32; i++) {
|
|
if (mask & (1 << i)) {
|
|
dmxSetScreenAttribute(i, attr, *value);
|
|
++value;
|
|
++count;
|
|
}
|
|
}
|
|
return count;
|
|
}
|
|
|
|
static void
|
|
dmxSetDesktopAttribute(int bit, DMXDesktopAttributesPtr attr, CARD32 value)
|
|
{
|
|
switch (1 << bit) {
|
|
case DMXDesktopWidth:
|
|
attr->width = value;
|
|
break;
|
|
case DMXDesktopHeight:
|
|
attr->height = value;
|
|
break;
|
|
case DMXDesktopShiftX:
|
|
attr->shiftX = value;
|
|
break;
|
|
case DMXDesktopShiftY:
|
|
attr->shiftY = value;
|
|
break;
|
|
}
|
|
}
|
|
|
|
static int
|
|
dmxFetchDesktopAttributes(unsigned int mask,
|
|
DMXDesktopAttributesPtr attr, CARD32 *value_list)
|
|
{
|
|
int i;
|
|
CARD32 *value = value_list;
|
|
int count = 0;
|
|
|
|
for (i = 0; i < 32; i++) {
|
|
if (mask & (1 << i)) {
|
|
dmxSetDesktopAttribute(i, attr, *value);
|
|
++value;
|
|
++count;
|
|
}
|
|
}
|
|
return count;
|
|
}
|
|
|
|
static void
|
|
dmxSetInputAttribute(int bit, DMXInputAttributesPtr attr, CARD32 value)
|
|
{
|
|
switch (1 << bit) {
|
|
case DMXInputType:
|
|
attr->inputType = value;
|
|
break;
|
|
case DMXInputPhysicalScreen:
|
|
attr->physicalScreen = value;
|
|
break;
|
|
case DMXInputSendsCore:
|
|
attr->sendsCore = ! !value;
|
|
break;
|
|
}
|
|
}
|
|
|
|
static int
|
|
dmxFetchInputAttributes(unsigned int mask,
|
|
DMXInputAttributesPtr attr, CARD32 *value_list)
|
|
{
|
|
int i;
|
|
CARD32 *value = value_list;
|
|
int count = 0;
|
|
|
|
for (i = 0; i < 32; i++) {
|
|
if (mask & (1 << i)) {
|
|
dmxSetInputAttribute(i, attr, *value);
|
|
++value;
|
|
++count;
|
|
}
|
|
}
|
|
return count;
|
|
}
|
|
|
|
static int
|
|
ProcDMXQueryVersion(ClientPtr client)
|
|
{
|
|
xDMXQueryVersionReply rep;
|
|
|
|
REQUEST_SIZE_MATCH(xDMXQueryVersionReq);
|
|
|
|
rep.type = X_Reply;
|
|
rep.sequenceNumber = client->sequence;
|
|
rep.length = 0;
|
|
rep.majorVersion = SERVER_DMX_MAJOR_VERSION;
|
|
rep.minorVersion = SERVER_DMX_MINOR_VERSION;
|
|
rep.patchVersion = SERVER_DMX_PATCH_VERSION;
|
|
if (client->swapped) {
|
|
swaps(&rep.sequenceNumber);
|
|
swapl(&rep.length);
|
|
swapl(&rep.majorVersion);
|
|
swapl(&rep.minorVersion);
|
|
swapl(&rep.patchVersion);
|
|
}
|
|
WriteToClient(client, sizeof(xDMXQueryVersionReply), (char *) &rep);
|
|
return Success;
|
|
}
|
|
|
|
static int
|
|
ProcDMXSync(ClientPtr client)
|
|
{
|
|
xDMXSyncReply rep;
|
|
|
|
REQUEST_SIZE_MATCH(xDMXSyncReq);
|
|
|
|
dmxFlushPendingSyncs();
|
|
|
|
rep.type = X_Reply;
|
|
rep.sequenceNumber = client->sequence;
|
|
rep.length = 0;
|
|
rep.status = 0;
|
|
if (client->swapped) {
|
|
swaps(&rep.sequenceNumber);
|
|
swapl(&rep.length);
|
|
swapl(&rep.status);
|
|
}
|
|
WriteToClient(client, sizeof(xDMXSyncReply), (char *) &rep);
|
|
return Success;
|
|
}
|
|
|
|
static int
|
|
ProcDMXForceWindowCreation(ClientPtr client)
|
|
{
|
|
xDMXForceWindowCreationReply rep;
|
|
|
|
REQUEST(xDMXForceWindowCreationReq);
|
|
WindowPtr pWin;
|
|
|
|
REQUEST_SIZE_MATCH(xDMXForceWindowCreationReq);
|
|
|
|
#ifdef PANORAMIX
|
|
if (!noPanoramiXExtension) {
|
|
PanoramiXRes *win;
|
|
int i;
|
|
|
|
if (Success != dixLookupResourceByType((pointer *) &win,
|
|
stuff->window, XRT_WINDOW,
|
|
client, DixReadAccess))
|
|
return -1; /* BadWindow */
|
|
|
|
FOR_NSCREENS(i) {
|
|
if (Success != dixLookupWindow(&pWin, win->info[i].id, client,
|
|
DixReadAccess))
|
|
return -1; /* BadWindow */
|
|
|
|
dmxForceWindowCreation(pWin);
|
|
}
|
|
goto doreply;
|
|
}
|
|
#endif
|
|
|
|
if (Success != dixLookupWindow(&pWin, stuff->window, client, DixReadAccess))
|
|
return -1; /* BadWindow */
|
|
|
|
dmxForceWindowCreation(pWin);
|
|
doreply:
|
|
dmxFlushPendingSyncs();
|
|
rep.type = X_Reply;
|
|
rep.sequenceNumber = client->sequence;
|
|
rep.length = 0;
|
|
rep.status = 0;
|
|
if (client->swapped) {
|
|
swaps(&rep.sequenceNumber);
|
|
swapl(&rep.length);
|
|
swapl(&rep.status);
|
|
}
|
|
WriteToClient(client, sizeof(xDMXForceWindowCreationReply), (char *) &rep);
|
|
return Success;
|
|
}
|
|
|
|
static int
|
|
ProcDMXGetScreenCount(ClientPtr client)
|
|
{
|
|
xDMXGetScreenCountReply rep;
|
|
|
|
REQUEST_SIZE_MATCH(xDMXGetScreenCountReq);
|
|
|
|
rep.type = X_Reply;
|
|
rep.sequenceNumber = client->sequence;
|
|
rep.length = 0;
|
|
rep.screenCount = dmxGetNumScreens();
|
|
if (client->swapped) {
|
|
swaps(&rep.sequenceNumber);
|
|
swapl(&rep.length);
|
|
swapl(&rep.screenCount);
|
|
}
|
|
WriteToClient(client, sizeof(xDMXGetScreenCountReply), (char *) &rep);
|
|
return Success;
|
|
}
|
|
|
|
static int
|
|
ProcDMXGetScreenAttributes(ClientPtr client)
|
|
{
|
|
REQUEST(xDMXGetScreenAttributesReq);
|
|
xDMXGetScreenAttributesReply rep;
|
|
int length;
|
|
int paddedLength;
|
|
DMXScreenAttributesRec attr;
|
|
|
|
REQUEST_SIZE_MATCH(xDMXGetScreenAttributesReq);
|
|
|
|
if (stuff->physicalScreen < 0
|
|
|| stuff->physicalScreen >= dmxGetNumScreens())
|
|
return BadValue;
|
|
|
|
if (!dmxGetScreenAttributes(stuff->physicalScreen, &attr))
|
|
return BadValue;
|
|
|
|
rep.logicalScreen = attr.logicalScreen;
|
|
rep.screenWindowWidth = attr.screenWindowWidth;
|
|
rep.screenWindowHeight = attr.screenWindowHeight;
|
|
rep.screenWindowXoffset = attr.screenWindowXoffset;
|
|
rep.screenWindowYoffset = attr.screenWindowYoffset;
|
|
rep.rootWindowWidth = attr.rootWindowWidth;
|
|
rep.rootWindowHeight = attr.rootWindowHeight;
|
|
rep.rootWindowXoffset = attr.rootWindowXoffset;
|
|
rep.rootWindowYoffset = attr.rootWindowYoffset;
|
|
rep.rootWindowXorigin = attr.rootWindowXorigin;
|
|
rep.rootWindowYorigin = attr.rootWindowYorigin;
|
|
|
|
length = attr.displayName ? strlen(attr.displayName) : 0;
|
|
paddedLength = pad_to_int32(length);
|
|
rep.type = X_Reply;
|
|
rep.sequenceNumber = client->sequence;
|
|
rep.length =
|
|
bytes_to_int32((sizeof(xDMXGetScreenAttributesReply) -
|
|
sizeof(xGenericReply))
|
|
+ paddedLength);
|
|
rep.displayNameLength = length;
|
|
|
|
if (client->swapped) {
|
|
swaps(&rep.sequenceNumber);
|
|
swapl(&rep.length);
|
|
swapl(&rep.displayNameLength);
|
|
swapl(&rep.logicalScreen);
|
|
swaps(&rep.screenWindowWidth);
|
|
swaps(&rep.screenWindowHeight);
|
|
swaps(&rep.screenWindowXoffset);
|
|
swaps(&rep.screenWindowYoffset);
|
|
swaps(&rep.rootWindowWidth);
|
|
swaps(&rep.rootWindowHeight);
|
|
swaps(&rep.rootWindowXoffset);
|
|
swaps(&rep.rootWindowYoffset);
|
|
swaps(&rep.rootWindowXorigin);
|
|
swaps(&rep.rootWindowYorigin);
|
|
}
|
|
WriteToClient(client, sizeof(xDMXGetScreenAttributesReply), (char *) &rep);
|
|
if (length)
|
|
WriteToClient(client, length, (char *) attr.displayName);
|
|
return Success;
|
|
}
|
|
|
|
static int
|
|
ProcDMXChangeScreensAttributes(ClientPtr client)
|
|
{
|
|
REQUEST(xDMXChangeScreensAttributesReq);
|
|
xDMXChangeScreensAttributesReply rep;
|
|
int status = DMX_BAD_XINERAMA;
|
|
unsigned int mask = 0;
|
|
unsigned int i;
|
|
CARD32 *screen_list;
|
|
CARD32 *mask_list;
|
|
CARD32 *value_list;
|
|
DMXScreenAttributesPtr attribs;
|
|
int errorScreen = 0;
|
|
unsigned int len;
|
|
int ones = 0;
|
|
|
|
REQUEST_AT_LEAST_SIZE(xDMXChangeScreensAttributesReq);
|
|
len =
|
|
client->req_len -
|
|
bytes_to_int32(sizeof(xDMXChangeScreensAttributesReq));
|
|
if (len < stuff->screenCount + stuff->maskCount)
|
|
return BadLength;
|
|
|
|
screen_list = (CARD32 *) (stuff + 1);
|
|
mask_list = &screen_list[stuff->screenCount];
|
|
value_list = &mask_list[stuff->maskCount];
|
|
|
|
for (i = 0; i < stuff->maskCount; i++)
|
|
ones += Ones(mask_list[i]);
|
|
if (len != stuff->screenCount + stuff->maskCount + ones)
|
|
return BadLength;
|
|
|
|
if (!_DMXXineramaActive())
|
|
goto noxinerama;
|
|
|
|
if (!(attribs = malloc(stuff->screenCount * sizeof(*attribs))))
|
|
return BadAlloc;
|
|
|
|
for (i = 0; i < stuff->screenCount; i++) {
|
|
int count;
|
|
|
|
if (i < stuff->maskCount)
|
|
mask = mask_list[i];
|
|
dmxGetScreenAttributes(screen_list[i], &attribs[i]);
|
|
count = dmxFetchScreenAttributes(mask, &attribs[i], value_list);
|
|
value_list += count;
|
|
}
|
|
|
|
#if PANORAMIX
|
|
status = dmxConfigureScreenWindows(stuff->screenCount,
|
|
screen_list, attribs, &errorScreen);
|
|
#endif
|
|
|
|
free(attribs);
|
|
|
|
if (status == BadValue)
|
|
return status;
|
|
|
|
noxinerama:
|
|
rep.type = X_Reply;
|
|
rep.sequenceNumber = client->sequence;
|
|
rep.length = 0;
|
|
rep.status = status;
|
|
rep.errorScreen = errorScreen;
|
|
if (client->swapped) {
|
|
swaps(&rep.sequenceNumber);
|
|
swapl(&rep.length);
|
|
swapl(&rep.status);
|
|
swapl(&rep.errorScreen);
|
|
}
|
|
WriteToClient(client,
|
|
sizeof(xDMXChangeScreensAttributesReply), (char *) &rep);
|
|
return Success;
|
|
}
|
|
|
|
static int
|
|
ProcDMXAddScreen(ClientPtr client)
|
|
{
|
|
REQUEST(xDMXAddScreenReq);
|
|
xDMXAddScreenReply rep;
|
|
int status = 0;
|
|
CARD32 *value_list;
|
|
DMXScreenAttributesRec attr;
|
|
int count;
|
|
char *name;
|
|
int len;
|
|
int paddedLength;
|
|
|
|
REQUEST_AT_LEAST_SIZE(xDMXAddScreenReq);
|
|
paddedLength = pad_to_int32(stuff->displayNameLength);
|
|
len = client->req_len - bytes_to_int32(sizeof(xDMXAddScreenReq));
|
|
if (len != Ones(stuff->valueMask) + paddedLength / 4)
|
|
return BadLength;
|
|
|
|
memset(&attr, 0, sizeof(attr));
|
|
dmxGetScreenAttributes(stuff->physicalScreen, &attr);
|
|
value_list = (CARD32 *) (stuff + 1);
|
|
count = dmxFetchScreenAttributes(stuff->valueMask, &attr, value_list);
|
|
|
|
if (!(name = malloc(stuff->displayNameLength + 1 + 4)))
|
|
return BadAlloc;
|
|
memcpy(name, &value_list[count], stuff->displayNameLength);
|
|
name[stuff->displayNameLength] = '\0';
|
|
attr.displayName = name;
|
|
|
|
status = dmxAttachScreen(stuff->physicalScreen, &attr);
|
|
|
|
free(name);
|
|
|
|
rep.type = X_Reply;
|
|
rep.sequenceNumber = client->sequence;
|
|
rep.length = 0;
|
|
rep.status = status;
|
|
rep.physicalScreen = stuff->physicalScreen;
|
|
if (client->swapped) {
|
|
swaps(&rep.sequenceNumber);
|
|
swapl(&rep.length);
|
|
swapl(&rep.status);
|
|
swapl(&rep.physicalScreen);
|
|
}
|
|
WriteToClient(client, sizeof(xDMXAddScreenReply), (char *) &rep);
|
|
return Success;
|
|
}
|
|
|
|
static int
|
|
ProcDMXRemoveScreen(ClientPtr client)
|
|
{
|
|
REQUEST(xDMXRemoveScreenReq);
|
|
xDMXRemoveScreenReply rep;
|
|
int status = 0;
|
|
|
|
REQUEST_SIZE_MATCH(xDMXRemoveScreenReq);
|
|
|
|
status = dmxDetachScreen(stuff->physicalScreen);
|
|
|
|
rep.type = X_Reply;
|
|
rep.sequenceNumber = client->sequence;
|
|
rep.length = 0;
|
|
rep.status = status;
|
|
if (client->swapped) {
|
|
swaps(&rep.sequenceNumber);
|
|
swapl(&rep.length);
|
|
swapl(&rep.status);
|
|
}
|
|
WriteToClient(client, sizeof(xDMXRemoveScreenReply), (char *) &rep);
|
|
return Success;
|
|
}
|
|
|
|
#ifdef PANORAMIX
|
|
static int
|
|
dmxPopulatePanoramiX(ClientPtr client, Window window,
|
|
CARD32 *screens, CARD32 *windows,
|
|
xRectangle *pos, xRectangle *vis)
|
|
{
|
|
WindowPtr pWin;
|
|
PanoramiXRes *win;
|
|
int i;
|
|
int count = 0;
|
|
DMXWindowAttributesRec attr;
|
|
|
|
if (Success != dixLookupResourceByType((pointer *) &win,
|
|
window, XRT_WINDOW,
|
|
client, DixReadAccess))
|
|
return -1; /* BadWindow */
|
|
|
|
FOR_NSCREENS(i) {
|
|
if (Success != dixLookupWindow(&pWin, win->info[i].id, client,
|
|
DixReadAccess))
|
|
return -1; /* BadWindow */
|
|
if (dmxGetWindowAttributes(pWin, &attr)) {
|
|
screens[count] = attr.screen;
|
|
windows[count] = attr.window;
|
|
pos[count] = attr.pos;
|
|
vis[count] = attr.vis;
|
|
++count; /* Only count existing windows */
|
|
}
|
|
}
|
|
return count;
|
|
}
|
|
#endif
|
|
|
|
static int
|
|
dmxPopulate(ClientPtr client, Window window, CARD32 *screens,
|
|
CARD32 *windows, xRectangle *pos, xRectangle *vis)
|
|
{
|
|
WindowPtr pWin;
|
|
DMXWindowAttributesRec attr;
|
|
|
|
#ifdef PANORAMIX
|
|
if (!noPanoramiXExtension)
|
|
return dmxPopulatePanoramiX(client, window, screens, windows, pos, vis);
|
|
#endif
|
|
|
|
if (Success != dixLookupWindow(&pWin, window, client, DixReadAccess))
|
|
return -1; /* BadWindow */
|
|
|
|
dmxGetWindowAttributes(pWin, &attr);
|
|
*screens = attr.screen;
|
|
*windows = attr.window;
|
|
*pos = attr.pos;
|
|
*vis = attr.vis;
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
dmxMaxNumScreens(void)
|
|
{
|
|
#ifdef PANORAMIX
|
|
if (!noPanoramiXExtension)
|
|
return PanoramiXNumScreens;
|
|
#endif
|
|
return 1;
|
|
}
|
|
|
|
static int
|
|
ProcDMXGetWindowAttributes(ClientPtr client)
|
|
{
|
|
REQUEST(xDMXGetWindowAttributesReq);
|
|
xDMXGetWindowAttributesReply rep;
|
|
int i;
|
|
CARD32 *screens;
|
|
CARD32 *windows;
|
|
xRectangle *pos, *vis;
|
|
int count = dmxMaxNumScreens();
|
|
|
|
REQUEST_SIZE_MATCH(xDMXGetWindowAttributesReq);
|
|
|
|
if (!(screens = malloc(count * sizeof(*screens))))
|
|
return BadAlloc;
|
|
if (!(windows = malloc(count * sizeof(*windows)))) {
|
|
free(screens);
|
|
return BadAlloc;
|
|
}
|
|
if (!(pos = malloc(count * sizeof(*pos)))) {
|
|
free(windows);
|
|
free(screens);
|
|
return BadAlloc;
|
|
}
|
|
if (!(vis = malloc(count * sizeof(*vis)))) {
|
|
free(pos);
|
|
free(windows);
|
|
free(screens);
|
|
return BadAlloc;
|
|
}
|
|
|
|
if ((count = dmxPopulate(client, stuff->window, screens, windows,
|
|
pos, vis)) < 0) {
|
|
free(vis);
|
|
free(pos);
|
|
free(windows);
|
|
free(screens);
|
|
return BadWindow;
|
|
}
|
|
|
|
rep.type = X_Reply;
|
|
rep.sequenceNumber = client->sequence;
|
|
rep.length = count * 6;
|
|
rep.screenCount = count;
|
|
if (client->swapped) {
|
|
swaps(&rep.sequenceNumber);
|
|
swapl(&rep.length);
|
|
swapl(&rep.screenCount);
|
|
for (i = 0; i < count; i++) {
|
|
swapl(&screens[i]);
|
|
swapl(&windows[i]);
|
|
|
|
swaps(&pos[i].x);
|
|
swaps(&pos[i].y);
|
|
swaps(&pos[i].width);
|
|
swaps(&pos[i].height);
|
|
|
|
swaps(&vis[i].x);
|
|
swaps(&vis[i].y);
|
|
swaps(&vis[i].width);
|
|
swaps(&vis[i].height);
|
|
}
|
|
}
|
|
|
|
dmxFlushPendingSyncs();
|
|
|
|
WriteToClient(client, sizeof(xDMXGetWindowAttributesReply), (char *) &rep);
|
|
if (count) {
|
|
WriteToClient(client, count * sizeof(*screens), (char *) screens);
|
|
WriteToClient(client, count * sizeof(*windows), (char *) windows);
|
|
WriteToClient(client, count * sizeof(*pos), (char *) pos);
|
|
WriteToClient(client, count * sizeof(*vis), (char *) vis);
|
|
}
|
|
|
|
free(vis);
|
|
free(pos);
|
|
free(windows);
|
|
free(screens);
|
|
|
|
return Success;
|
|
}
|
|
|
|
static int
|
|
ProcDMXGetDesktopAttributes(ClientPtr client)
|
|
{
|
|
xDMXGetDesktopAttributesReply rep;
|
|
DMXDesktopAttributesRec attr;
|
|
|
|
REQUEST_SIZE_MATCH(xDMXGetDesktopAttributesReq);
|
|
|
|
dmxGetDesktopAttributes(&attr);
|
|
|
|
rep.width = attr.width;
|
|
rep.height = attr.height;
|
|
rep.shiftX = attr.shiftX;
|
|
rep.shiftY = attr.shiftY;
|
|
|
|
rep.type = X_Reply;
|
|
rep.sequenceNumber = client->sequence;
|
|
rep.length = 0;
|
|
|
|
if (client->swapped) {
|
|
swaps(&rep.sequenceNumber);
|
|
swapl(&rep.length);
|
|
swaps(&rep.width);
|
|
swaps(&rep.height);
|
|
swaps(&rep.shiftX);
|
|
swaps(&rep.shiftY);
|
|
}
|
|
WriteToClient(client, sizeof(xDMXGetDesktopAttributesReply), (char *) &rep);
|
|
return Success;
|
|
}
|
|
|
|
static int
|
|
ProcDMXChangeDesktopAttributes(ClientPtr client)
|
|
{
|
|
REQUEST(xDMXChangeDesktopAttributesReq);
|
|
xDMXChangeDesktopAttributesReply rep;
|
|
int status = DMX_BAD_XINERAMA;
|
|
CARD32 *value_list;
|
|
DMXDesktopAttributesRec attr;
|
|
int len;
|
|
|
|
REQUEST_AT_LEAST_SIZE(xDMXChangeDesktopAttributesReq);
|
|
len = client->req_len - (sizeof(xDMXChangeDesktopAttributesReq) >> 2);
|
|
if (len != Ones(stuff->valueMask))
|
|
return BadLength;
|
|
|
|
if (!_DMXXineramaActive())
|
|
goto noxinerama;
|
|
|
|
value_list = (CARD32 *) (stuff + 1);
|
|
|
|
dmxGetDesktopAttributes(&attr);
|
|
dmxFetchDesktopAttributes(stuff->valueMask, &attr, value_list);
|
|
|
|
#if PANORAMIX
|
|
status = dmxConfigureDesktop(&attr);
|
|
#endif
|
|
if (status == BadValue)
|
|
return status;
|
|
|
|
noxinerama:
|
|
rep.type = X_Reply;
|
|
rep.sequenceNumber = client->sequence;
|
|
rep.length = 0;
|
|
rep.status = status;
|
|
if (client->swapped) {
|
|
swaps(&rep.sequenceNumber);
|
|
swapl(&rep.length);
|
|
swapl(&rep.status);
|
|
}
|
|
WriteToClient(client,
|
|
sizeof(xDMXChangeDesktopAttributesReply), (char *) &rep);
|
|
return Success;
|
|
}
|
|
|
|
static int
|
|
ProcDMXGetInputCount(ClientPtr client)
|
|
{
|
|
xDMXGetInputCountReply rep;
|
|
|
|
REQUEST_SIZE_MATCH(xDMXGetInputCountReq);
|
|
|
|
rep.type = X_Reply;
|
|
rep.sequenceNumber = client->sequence;
|
|
rep.length = 0;
|
|
rep.inputCount = dmxGetInputCount();
|
|
if (client->swapped) {
|
|
swaps(&rep.sequenceNumber);
|
|
swapl(&rep.length);
|
|
swapl(&rep.inputCount);
|
|
}
|
|
WriteToClient(client, sizeof(xDMXGetInputCountReply), (char *) &rep);
|
|
return Success;
|
|
}
|
|
|
|
static int
|
|
ProcDMXGetInputAttributes(ClientPtr client)
|
|
{
|
|
REQUEST(xDMXGetInputAttributesReq);
|
|
xDMXGetInputAttributesReply rep;
|
|
int length;
|
|
int paddedLength;
|
|
DMXInputAttributesRec attr;
|
|
|
|
REQUEST_SIZE_MATCH(xDMXGetInputAttributesReq);
|
|
|
|
if (dmxGetInputAttributes(stuff->deviceId, &attr))
|
|
return BadValue;
|
|
rep.inputType = attr.inputType;
|
|
rep.physicalScreen = attr.physicalScreen;
|
|
rep.physicalId = attr.physicalId;
|
|
rep.isCore = attr.isCore;
|
|
rep.sendsCore = attr.sendsCore;
|
|
rep.detached = attr.detached;
|
|
|
|
length = attr.name ? strlen(attr.name) : 0;
|
|
paddedLength = pad_to_int32(length);
|
|
rep.type = X_Reply;
|
|
rep.sequenceNumber = client->sequence;
|
|
rep.length = bytes_to_int32(paddedLength);
|
|
rep.nameLength = length;
|
|
if (client->swapped) {
|
|
swaps(&rep.sequenceNumber);
|
|
swapl(&rep.length);
|
|
swapl(&rep.inputType);
|
|
swapl(&rep.physicalScreen);
|
|
swapl(&rep.physicalId);
|
|
swapl(&rep.nameLength);
|
|
}
|
|
WriteToClient(client, sizeof(xDMXGetInputAttributesReply), (char *) &rep);
|
|
if (length)
|
|
WriteToClient(client, length, (char *) attr.name);
|
|
return Success;
|
|
}
|
|
|
|
static int
|
|
ProcDMXAddInput(ClientPtr client)
|
|
{
|
|
REQUEST(xDMXAddInputReq);
|
|
xDMXAddInputReply rep;
|
|
int status = 0;
|
|
CARD32 *value_list;
|
|
DMXInputAttributesRec attr;
|
|
int count;
|
|
char *name;
|
|
int len;
|
|
int paddedLength;
|
|
int id = -1;
|
|
|
|
REQUEST_AT_LEAST_SIZE(xDMXAddInputReq);
|
|
paddedLength = pad_to_int32(stuff->displayNameLength);
|
|
len = client->req_len - (sizeof(xDMXAddInputReq) >> 2);
|
|
if (len != Ones(stuff->valueMask) + paddedLength / 4)
|
|
return BadLength;
|
|
|
|
memset(&attr, 0, sizeof(attr));
|
|
value_list = (CARD32 *) (stuff + 1);
|
|
count = dmxFetchInputAttributes(stuff->valueMask, &attr, value_list);
|
|
|
|
if (!(name = malloc(stuff->displayNameLength + 1 + 4)))
|
|
return BadAlloc;
|
|
memcpy(name, &value_list[count], stuff->displayNameLength);
|
|
name[stuff->displayNameLength] = '\0';
|
|
attr.name = name;
|
|
|
|
status = dmxAddInput(&attr, &id);
|
|
|
|
free(name);
|
|
|
|
if (status)
|
|
return status;
|
|
|
|
rep.type = X_Reply;
|
|
rep.sequenceNumber = client->sequence;
|
|
rep.length = 0;
|
|
rep.status = status;
|
|
rep.physicalId = id;
|
|
if (client->swapped) {
|
|
swaps(&rep.sequenceNumber);
|
|
swapl(&rep.length);
|
|
swapl(&rep.status);
|
|
swapl(&rep.physicalId);
|
|
}
|
|
WriteToClient(client, sizeof(xDMXAddInputReply), (char *) &rep);
|
|
return Success;
|
|
}
|
|
|
|
static int
|
|
ProcDMXRemoveInput(ClientPtr client)
|
|
{
|
|
REQUEST(xDMXRemoveInputReq);
|
|
xDMXRemoveInputReply rep;
|
|
int status = 0;
|
|
|
|
REQUEST_SIZE_MATCH(xDMXRemoveInputReq);
|
|
|
|
status = dmxRemoveInput(stuff->physicalId);
|
|
|
|
if (status)
|
|
return status;
|
|
|
|
rep.type = X_Reply;
|
|
rep.sequenceNumber = client->sequence;
|
|
rep.length = 0;
|
|
rep.status = status;
|
|
if (client->swapped) {
|
|
swaps(&rep.sequenceNumber);
|
|
swapl(&rep.length);
|
|
swapl(&rep.status);
|
|
}
|
|
WriteToClient(client, sizeof(xDMXRemoveInputReply), (char *) &rep);
|
|
return Success;
|
|
}
|
|
|
|
static int
|
|
ProcDMXDispatch(ClientPtr client)
|
|
{
|
|
REQUEST(xReq);
|
|
|
|
switch (stuff->data) {
|
|
case X_DMXQueryVersion:
|
|
return ProcDMXQueryVersion(client);
|
|
case X_DMXSync:
|
|
return ProcDMXSync(client);
|
|
case X_DMXForceWindowCreation:
|
|
return ProcDMXForceWindowCreation(client);
|
|
case X_DMXGetScreenCount:
|
|
return ProcDMXGetScreenCount(client);
|
|
case X_DMXGetScreenAttributes:
|
|
return ProcDMXGetScreenAttributes(client);
|
|
case X_DMXChangeScreensAttributes:
|
|
return ProcDMXChangeScreensAttributes(client);
|
|
case X_DMXAddScreen:
|
|
return ProcDMXAddScreen(client);
|
|
case X_DMXRemoveScreen:
|
|
return ProcDMXRemoveScreen(client);
|
|
case X_DMXGetWindowAttributes:
|
|
return ProcDMXGetWindowAttributes(client);
|
|
case X_DMXGetDesktopAttributes:
|
|
return ProcDMXGetDesktopAttributes(client);
|
|
case X_DMXChangeDesktopAttributes:
|
|
return ProcDMXChangeDesktopAttributes(client);
|
|
case X_DMXGetInputCount:
|
|
return ProcDMXGetInputCount(client);
|
|
case X_DMXGetInputAttributes:
|
|
return ProcDMXGetInputAttributes(client);
|
|
case X_DMXAddInput:
|
|
return ProcDMXAddInput(client);
|
|
case X_DMXRemoveInput:
|
|
return ProcDMXRemoveInput(client);
|
|
|
|
case X_DMXGetScreenInformationDEPRECATED:
|
|
case X_DMXForceWindowCreationDEPRECATED:
|
|
case X_DMXReconfigureScreenDEPRECATED:
|
|
return BadImplementation;
|
|
|
|
default:
|
|
return BadRequest;
|
|
}
|
|
}
|
|
|
|
static int
|
|
SProcDMXQueryVersion(ClientPtr client)
|
|
{
|
|
REQUEST(xDMXQueryVersionReq);
|
|
|
|
swaps(&stuff->length);
|
|
REQUEST_SIZE_MATCH(xDMXQueryVersionReq);
|
|
return ProcDMXQueryVersion(client);
|
|
}
|
|
|
|
static int
|
|
SProcDMXSync(ClientPtr client)
|
|
{
|
|
REQUEST(xDMXSyncReq);
|
|
|
|
swaps(&stuff->length);
|
|
REQUEST_SIZE_MATCH(xDMXSyncReq);
|
|
return ProcDMXSync(client);
|
|
}
|
|
|
|
static int
|
|
SProcDMXForceWindowCreation(ClientPtr client)
|
|
{
|
|
REQUEST(xDMXForceWindowCreationReq);
|
|
|
|
swaps(&stuff->length);
|
|
REQUEST_SIZE_MATCH(xDMXForceWindowCreationReq);
|
|
swapl(&stuff->window);
|
|
return ProcDMXForceWindowCreation(client);
|
|
}
|
|
|
|
static int
|
|
SProcDMXGetScreenCount(ClientPtr client)
|
|
{
|
|
REQUEST(xDMXGetScreenCountReq);
|
|
|
|
swaps(&stuff->length);
|
|
REQUEST_SIZE_MATCH(xDMXGetScreenCountReq);
|
|
return ProcDMXGetScreenCount(client);
|
|
}
|
|
|
|
static int
|
|
SProcDMXGetScreenAttributes(ClientPtr client)
|
|
{
|
|
REQUEST(xDMXGetScreenAttributesReq);
|
|
|
|
swaps(&stuff->length);
|
|
REQUEST_SIZE_MATCH(xDMXGetScreenAttributesReq);
|
|
swapl(&stuff->physicalScreen);
|
|
return ProcDMXGetScreenAttributes(client);
|
|
}
|
|
|
|
static int
|
|
SProcDMXChangeScreensAttributes(ClientPtr client)
|
|
{
|
|
REQUEST(xDMXChangeScreensAttributesReq);
|
|
|
|
swaps(&stuff->length);
|
|
REQUEST_AT_LEAST_SIZE(xDMXGetScreenAttributesReq);
|
|
swapl(&stuff->screenCount);
|
|
swapl(&stuff->maskCount);
|
|
SwapRestL(stuff);
|
|
return ProcDMXGetScreenAttributes(client);
|
|
}
|
|
|
|
static int
|
|
SProcDMXAddScreen(ClientPtr client)
|
|
{
|
|
int paddedLength;
|
|
|
|
REQUEST(xDMXAddScreenReq);
|
|
|
|
swaps(&stuff->length);
|
|
REQUEST_AT_LEAST_SIZE(xDMXAddScreenReq);
|
|
swapl(&stuff->displayNameLength);
|
|
swapl(&stuff->valueMask);
|
|
paddedLength = pad_to_int32(stuff->displayNameLength);
|
|
SwapLongs((CARD32 *) (stuff + 1), LengthRestL(stuff) - paddedLength / 4);
|
|
return ProcDMXAddScreen(client);
|
|
}
|
|
|
|
static int
|
|
SProcDMXRemoveScreen(ClientPtr client)
|
|
{
|
|
REQUEST(xDMXRemoveScreenReq);
|
|
|
|
swaps(&stuff->length);
|
|
REQUEST_SIZE_MATCH(xDMXRemoveScreenReq);
|
|
swapl(&stuff->physicalScreen);
|
|
return ProcDMXRemoveScreen(client);
|
|
}
|
|
|
|
static int
|
|
SProcDMXGetWindowAttributes(ClientPtr client)
|
|
{
|
|
REQUEST(xDMXGetWindowAttributesReq);
|
|
|
|
swaps(&stuff->length);
|
|
REQUEST_SIZE_MATCH(xDMXGetWindowAttributesReq);
|
|
swapl(&stuff->window);
|
|
return ProcDMXGetWindowAttributes(client);
|
|
}
|
|
|
|
static int
|
|
SProcDMXGetDesktopAttributes(ClientPtr client)
|
|
{
|
|
REQUEST(xDMXGetDesktopAttributesReq);
|
|
|
|
swaps(&stuff->length);
|
|
REQUEST_SIZE_MATCH(xDMXGetDesktopAttributesReq);
|
|
return ProcDMXGetDesktopAttributes(client);
|
|
}
|
|
|
|
static int
|
|
SProcDMXChangeDesktopAttributes(ClientPtr client)
|
|
{
|
|
REQUEST(xDMXChangeDesktopAttributesReq);
|
|
|
|
swaps(&stuff->length);
|
|
REQUEST_AT_LEAST_SIZE(xDMXChangeDesktopAttributesReq);
|
|
swapl(&stuff->valueMask);
|
|
SwapRestL(stuff);
|
|
return ProcDMXChangeDesktopAttributes(client);
|
|
}
|
|
|
|
static int
|
|
SProcDMXGetInputCount(ClientPtr client)
|
|
{
|
|
REQUEST(xDMXGetInputCountReq);
|
|
|
|
swaps(&stuff->length);
|
|
REQUEST_SIZE_MATCH(xDMXGetInputCountReq);
|
|
return ProcDMXGetInputCount(client);
|
|
}
|
|
|
|
static int
|
|
SProcDMXGetInputAttributes(ClientPtr client)
|
|
{
|
|
REQUEST(xDMXGetInputAttributesReq);
|
|
|
|
swaps(&stuff->length);
|
|
REQUEST_SIZE_MATCH(xDMXGetInputAttributesReq);
|
|
swapl(&stuff->deviceId);
|
|
return ProcDMXGetInputAttributes(client);
|
|
}
|
|
|
|
static int
|
|
SProcDMXAddInput(ClientPtr client)
|
|
{
|
|
int paddedLength;
|
|
|
|
REQUEST(xDMXAddInputReq);
|
|
|
|
swaps(&stuff->length);
|
|
REQUEST_AT_LEAST_SIZE(xDMXAddInputReq);
|
|
swapl(&stuff->displayNameLength);
|
|
swapl(&stuff->valueMask);
|
|
paddedLength = pad_to_int32(stuff->displayNameLength);
|
|
SwapLongs((CARD32 *) (stuff + 1), LengthRestL(stuff) - paddedLength / 4);
|
|
return ProcDMXAddInput(client);
|
|
}
|
|
|
|
static int
|
|
SProcDMXRemoveInput(ClientPtr client)
|
|
{
|
|
REQUEST(xDMXRemoveInputReq);
|
|
|
|
swaps(&stuff->length);
|
|
REQUEST_SIZE_MATCH(xDMXRemoveInputReq);
|
|
swapl(&stuff->physicalId);
|
|
return ProcDMXRemoveInput(client);
|
|
}
|
|
|
|
static int
|
|
SProcDMXDispatch(ClientPtr client)
|
|
{
|
|
REQUEST(xReq);
|
|
|
|
switch (stuff->data) {
|
|
case X_DMXQueryVersion:
|
|
return SProcDMXQueryVersion(client);
|
|
case X_DMXSync:
|
|
return SProcDMXSync(client);
|
|
case X_DMXForceWindowCreation:
|
|
return SProcDMXForceWindowCreation(client);
|
|
case X_DMXGetScreenCount:
|
|
return SProcDMXGetScreenCount(client);
|
|
case X_DMXGetScreenAttributes:
|
|
return SProcDMXGetScreenAttributes(client);
|
|
case X_DMXChangeScreensAttributes:
|
|
return SProcDMXChangeScreensAttributes(client);
|
|
case X_DMXAddScreen:
|
|
return SProcDMXAddScreen(client);
|
|
case X_DMXRemoveScreen:
|
|
return SProcDMXRemoveScreen(client);
|
|
case X_DMXGetWindowAttributes:
|
|
return SProcDMXGetWindowAttributes(client);
|
|
case X_DMXGetDesktopAttributes:
|
|
return SProcDMXGetDesktopAttributes(client);
|
|
case X_DMXChangeDesktopAttributes:
|
|
return SProcDMXChangeDesktopAttributes(client);
|
|
case X_DMXGetInputCount:
|
|
return SProcDMXGetInputCount(client);
|
|
case X_DMXGetInputAttributes:
|
|
return SProcDMXGetInputAttributes(client);
|
|
case X_DMXAddInput:
|
|
return SProcDMXAddInput(client);
|
|
case X_DMXRemoveInput:
|
|
return SProcDMXRemoveInput(client);
|
|
|
|
case X_DMXGetScreenInformationDEPRECATED:
|
|
case X_DMXForceWindowCreationDEPRECATED:
|
|
case X_DMXReconfigureScreenDEPRECATED:
|
|
return BadImplementation;
|
|
|
|
default:
|
|
return BadRequest;
|
|
}
|
|
}
|
|
|
|
/** Initialize the extension. */
|
|
void
|
|
DMXExtensionInit(void)
|
|
{
|
|
ExtensionEntry *extEntry;
|
|
|
|
if ((extEntry = AddExtension(DMX_EXTENSION_NAME, 0, 0,
|
|
ProcDMXDispatch, SProcDMXDispatch,
|
|
NULL, StandardMinorOpcode)))
|
|
DMXCode = extEntry->base;
|
|
}
|