1202 lines
		
	
	
		
			31 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			1202 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 "extinit.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
 | |
| 
 | |
| static unsigned char DMXCode;
 | |
| 
 | |
| static int
 | |
| _DMXXineramaActive(void)
 | |
| {
 | |
| #ifdef PANORAMIX
 | |
|     return !noPanoramiXExtension;
 | |
| #else
 | |
|     return 0;
 | |
| #endif
 | |
| }
 | |
| 
 | |
| static void
 | |
| dmxSetScreenAttribute(int bit, DMXScreenAttributesPtr attr, CARD32 value)
 | |
| {
 | |
|     switch (1 << bit) {
 | |
|     case DMXScreenWindowWidth:
 | |
|         attr->screenWindowWidth = value;
 | |
|         break;
 | |
|     case DMXScreenWindowHeight:
 | |
|         attr->screenWindowHeight = value;
 | |
|         break;
 | |
|     case DMXScreenWindowXoffset:
 | |
|         attr->screenWindowXoffset = value;
 | |
|         break;
 | |
|     case DMXScreenWindowYoffset:
 | |
|         attr->screenWindowYoffset = value;
 | |
|         break;
 | |
|     case DMXRootWindowWidth:
 | |
|         attr->rootWindowWidth = value;
 | |
|         break;
 | |
|     case DMXRootWindowHeight:
 | |
|         attr->rootWindowHeight = value;
 | |
|         break;
 | |
|     case DMXRootWindowXoffset:
 | |
|         attr->rootWindowXoffset = value;
 | |
|         break;
 | |
|     case DMXRootWindowYoffset:
 | |
|         attr->rootWindowYoffset = value;
 | |
|         break;
 | |
|     case DMXRootWindowXorigin:
 | |
|         attr->rootWindowXorigin = value;
 | |
|         break;
 | |
|     case DMXRootWindowYorigin:
 | |
|         attr->rootWindowYorigin = value;
 | |
|         break;
 | |
|     }
 | |
| }
 | |
| 
 | |
| static int
 | |
| dmxFetchScreenAttributes(unsigned int mask,
 | |
|                          DMXScreenAttributesPtr attr, CARD32 *value_list)
 | |
| {
 | |
|     int i;
 | |
|     CARD32 *value = value_list;
 | |
|     int count = 0;
 | |
| 
 | |
|     for (i = 0; i < 32; i++) {
 | |
|         if (mask & (1 << i)) {
 | |
|             dmxSetScreenAttribute(i, attr, *value);
 | |
|             ++value;
 | |
|             ++count;
 | |
|         }
 | |
|     }
 | |
|     return count;
 | |
| }
 | |
| 
 | |
| static void
 | |
| dmxSetDesktopAttribute(int bit, DMXDesktopAttributesPtr attr, CARD32 value)
 | |
| {
 | |
|     switch (1 << bit) {
 | |
|     case DMXDesktopWidth:
 | |
|         attr->width = value;
 | |
|         break;
 | |
|     case DMXDesktopHeight:
 | |
|         attr->height = value;
 | |
|         break;
 | |
|     case DMXDesktopShiftX:
 | |
|         attr->shiftX = value;
 | |
|         break;
 | |
|     case DMXDesktopShiftY:
 | |
|         attr->shiftY = value;
 | |
|         break;
 | |
|     }
 | |
| }
 | |
| 
 | |
| static int
 | |
| dmxFetchDesktopAttributes(unsigned int mask,
 | |
|                           DMXDesktopAttributesPtr attr, CARD32 *value_list)
 | |
| {
 | |
|     int i;
 | |
|     CARD32 *value = value_list;
 | |
|     int count = 0;
 | |
| 
 | |
|     for (i = 0; i < 32; i++) {
 | |
|         if (mask & (1 << i)) {
 | |
|             dmxSetDesktopAttribute(i, attr, *value);
 | |
|             ++value;
 | |
|             ++count;
 | |
|         }
 | |
|     }
 | |
|     return count;
 | |
| }
 | |
| 
 | |
| static void
 | |
| dmxSetInputAttribute(int bit, DMXInputAttributesPtr attr, CARD32 value)
 | |
| {
 | |
|     switch (1 << bit) {
 | |
|     case DMXInputType:
 | |
|         attr->inputType = value;
 | |
|         break;
 | |
|     case DMXInputPhysicalScreen:
 | |
|         attr->physicalScreen = value;
 | |
|         break;
 | |
|     case DMXInputSendsCore:
 | |
|         attr->sendsCore = ! !value;
 | |
|         break;
 | |
|     }
 | |
| }
 | |
| 
 | |
| static int
 | |
| dmxFetchInputAttributes(unsigned int mask,
 | |
|                         DMXInputAttributesPtr attr, CARD32 *value_list)
 | |
| {
 | |
|     int i;
 | |
|     CARD32 *value = value_list;
 | |
|     int count = 0;
 | |
| 
 | |
|     for (i = 0; i < 32; i++) {
 | |
|         if (mask & (1 << i)) {
 | |
|             dmxSetInputAttribute(i, attr, *value);
 | |
|             ++value;
 | |
|             ++count;
 | |
|         }
 | |
|     }
 | |
|     return count;
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcDMXQueryVersion(ClientPtr client)
 | |
| {
 | |
|     xDMXQueryVersionReply rep = {
 | |
|         .type = X_Reply,
 | |
|         .sequenceNumber = client->sequence,
 | |
|         .length = 0,
 | |
|         .majorVersion = SERVER_DMX_MAJOR_VERSION,
 | |
|         .minorVersion = SERVER_DMX_MINOR_VERSION,
 | |
|         .patchVersion = SERVER_DMX_PATCH_VERSION
 | |
|     };
 | |
| 
 | |
|     REQUEST_SIZE_MATCH(xDMXQueryVersionReq);
 | |
| 
 | |
|     if (client->swapped) {
 | |
|         swaps(&rep.sequenceNumber);
 | |
|         swapl(&rep.length);
 | |
|         swapl(&rep.majorVersion);
 | |
|         swapl(&rep.minorVersion);
 | |
|         swapl(&rep.patchVersion);
 | |
|     }
 | |
|     WriteToClient(client, sizeof(xDMXQueryVersionReply), &rep);
 | |
|     return Success;
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcDMXSync(ClientPtr client)
 | |
| {
 | |
|     xDMXSyncReply rep;
 | |
| 
 | |
|     REQUEST_SIZE_MATCH(xDMXSyncReq);
 | |
| 
 | |
|     dmxFlushPendingSyncs();
 | |
| 
 | |
|     rep = (xDMXSyncReply) {
 | |
|         .type = X_Reply,
 | |
|         .sequenceNumber = client->sequence,
 | |
|         .length = 0,
 | |
|         .status = 0
 | |
|     };
 | |
|     if (client->swapped) {
 | |
|         swaps(&rep.sequenceNumber);
 | |
|         swapl(&rep.length);
 | |
|         swapl(&rep.status);
 | |
|     }
 | |
|     WriteToClient(client, sizeof(xDMXSyncReply), &rep);
 | |
|     return Success;
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcDMXForceWindowCreation(ClientPtr client)
 | |
| {
 | |
|     xDMXForceWindowCreationReply rep;
 | |
| 
 | |
|     REQUEST(xDMXForceWindowCreationReq);
 | |
|     WindowPtr pWin;
 | |
| 
 | |
|     REQUEST_SIZE_MATCH(xDMXForceWindowCreationReq);
 | |
| 
 | |
| #ifdef PANORAMIX
 | |
|     if (!noPanoramiXExtension) {
 | |
|         PanoramiXRes *win;
 | |
|         int i;
 | |
| 
 | |
|         if (Success != dixLookupResourceByType((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 = (xDMXForceWindowCreationReply) {
 | |
|         .type = X_Reply,
 | |
|         .sequenceNumber = client->sequence,
 | |
|         .length = 0,
 | |
|         .status = 0
 | |
|     };
 | |
|     if (client->swapped) {
 | |
|         swaps(&rep.sequenceNumber);
 | |
|         swapl(&rep.length);
 | |
|         swapl(&rep.status);
 | |
|     }
 | |
|     WriteToClient(client, sizeof(xDMXForceWindowCreationReply), &rep);
 | |
|     return Success;
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcDMXGetScreenCount(ClientPtr client)
 | |
| {
 | |
|     xDMXGetScreenCountReply rep;
 | |
| 
 | |
|     REQUEST_SIZE_MATCH(xDMXGetScreenCountReq);
 | |
| 
 | |
|     rep = (xDMXGetScreenCountReply) {
 | |
|         .type = X_Reply,
 | |
|         .sequenceNumber = client->sequence,
 | |
|         .length = 0,
 | |
|         .screenCount = dmxGetNumScreens()
 | |
|     };
 | |
|     if (client->swapped) {
 | |
|         swaps(&rep.sequenceNumber);
 | |
|         swapl(&rep.length);
 | |
|         swapl(&rep.screenCount);
 | |
|     }
 | |
|     WriteToClient(client, sizeof(xDMXGetScreenCountReply), &rep);
 | |
|     return Success;
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcDMXGetScreenAttributes(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xDMXGetScreenAttributesReq);
 | |
|     xDMXGetScreenAttributesReply rep;
 | |
|     int length;
 | |
|     int paddedLength;
 | |
|     DMXScreenAttributesRec attr;
 | |
| 
 | |
|     REQUEST_SIZE_MATCH(xDMXGetScreenAttributesReq);
 | |
| 
 | |
|     if (stuff->physicalScreen < 0
 | |
|         || stuff->physicalScreen >= dmxGetNumScreens())
 | |
|         return BadValue;
 | |
| 
 | |
|     if (!dmxGetScreenAttributes(stuff->physicalScreen, &attr))
 | |
|         return BadValue;
 | |
| 
 | |
|     length = attr.displayName ? strlen(attr.displayName) : 0;
 | |
|     paddedLength = pad_to_int32(length);
 | |
| 
 | |
|     rep = (xDMXGetScreenAttributesReply) {
 | |
|         .type = X_Reply,
 | |
|         .sequenceNumber = client->sequence,
 | |
|         .length =
 | |
|             bytes_to_int32((sizeof(xDMXGetScreenAttributesReply) -
 | |
|                             sizeof(xGenericReply))
 | |
|                            + paddedLength),
 | |
|         .displayNameLength = length,
 | |
|         .logicalScreen = attr.logicalScreen,
 | |
|         .screenWindowWidth = attr.screenWindowWidth,
 | |
|         .screenWindowHeight = attr.screenWindowHeight,
 | |
|         .screenWindowXoffset = attr.screenWindowXoffset,
 | |
|         .screenWindowYoffset = attr.screenWindowYoffset,
 | |
|         .rootWindowWidth = attr.rootWindowWidth,
 | |
|         .rootWindowHeight = attr.rootWindowHeight,
 | |
|         .rootWindowXoffset = attr.rootWindowXoffset,
 | |
|         .rootWindowYoffset = attr.rootWindowYoffset,
 | |
|         .rootWindowXorigin = attr.rootWindowXorigin,
 | |
|         .rootWindowYorigin = attr.rootWindowYorigin
 | |
|     };
 | |
| 
 | |
|     if (client->swapped) {
 | |
|         swaps(&rep.sequenceNumber);
 | |
|         swapl(&rep.length);
 | |
|         swapl(&rep.displayNameLength);
 | |
|         swapl(&rep.logicalScreen);
 | |
|         swaps(&rep.screenWindowWidth);
 | |
|         swaps(&rep.screenWindowHeight);
 | |
|         swaps(&rep.screenWindowXoffset);
 | |
|         swaps(&rep.screenWindowYoffset);
 | |
|         swaps(&rep.rootWindowWidth);
 | |
|         swaps(&rep.rootWindowHeight);
 | |
|         swaps(&rep.rootWindowXoffset);
 | |
|         swaps(&rep.rootWindowYoffset);
 | |
|         swaps(&rep.rootWindowXorigin);
 | |
|         swaps(&rep.rootWindowYorigin);
 | |
|     }
 | |
|     WriteToClient(client, sizeof(xDMXGetScreenAttributesReply), &rep);
 | |
|     if (length)
 | |
|         WriteToClient(client, length, attr.displayName);
 | |
|     return Success;
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcDMXChangeScreensAttributes(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xDMXChangeScreensAttributesReq);
 | |
|     xDMXChangeScreensAttributesReply rep;
 | |
|     int status = DMX_BAD_XINERAMA;
 | |
|     unsigned int mask = 0;
 | |
|     unsigned int i;
 | |
|     CARD32 *screen_list;
 | |
|     CARD32 *mask_list;
 | |
|     CARD32 *value_list;
 | |
|     DMXScreenAttributesPtr attribs;
 | |
|     int errorScreen = 0;
 | |
|     unsigned int len;
 | |
|     int ones = 0;
 | |
| 
 | |
|     REQUEST_AT_LEAST_SIZE(xDMXChangeScreensAttributesReq);
 | |
|     len =
 | |
|         client->req_len -
 | |
|         bytes_to_int32(sizeof(xDMXChangeScreensAttributesReq));
 | |
|     if (len < stuff->screenCount + stuff->maskCount)
 | |
|         return BadLength;
 | |
| 
 | |
|     screen_list = (CARD32 *) (stuff + 1);
 | |
|     mask_list = &screen_list[stuff->screenCount];
 | |
|     value_list = &mask_list[stuff->maskCount];
 | |
| 
 | |
|     for (i = 0; i < stuff->maskCount; i++)
 | |
|         ones += Ones(mask_list[i]);
 | |
|     if (len != stuff->screenCount + stuff->maskCount + ones)
 | |
|         return BadLength;
 | |
| 
 | |
|     if (!_DMXXineramaActive())
 | |
|         goto noxinerama;
 | |
| 
 | |
|     if (!(attribs = 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 = (xDMXChangeScreensAttributesReply) {
 | |
|         .type = X_Reply,
 | |
|         .sequenceNumber = client->sequence,
 | |
|         .length = 0,
 | |
|         .status = status,
 | |
|         .errorScreen = errorScreen
 | |
|     };
 | |
|     if (client->swapped) {
 | |
|         swaps(&rep.sequenceNumber);
 | |
|         swapl(&rep.length);
 | |
|         swapl(&rep.status);
 | |
|         swapl(&rep.errorScreen);
 | |
|     }
 | |
|     WriteToClient(client, sizeof(xDMXChangeScreensAttributesReply), &rep);
 | |
|     return Success;
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcDMXAddScreen(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xDMXAddScreenReq);
 | |
|     xDMXAddScreenReply rep;
 | |
|     int status = 0;
 | |
|     CARD32 *value_list;
 | |
|     DMXScreenAttributesRec attr;
 | |
|     int count;
 | |
|     char *name;
 | |
|     int len;
 | |
|     int paddedLength;
 | |
| 
 | |
|     REQUEST_AT_LEAST_SIZE(xDMXAddScreenReq);
 | |
|     paddedLength = pad_to_int32(stuff->displayNameLength);
 | |
|     len = client->req_len - bytes_to_int32(sizeof(xDMXAddScreenReq));
 | |
|     if (len != Ones(stuff->valueMask) + paddedLength / 4)
 | |
|         return BadLength;
 | |
| 
 | |
|     memset(&attr, 0, sizeof(attr));
 | |
|     dmxGetScreenAttributes(stuff->physicalScreen, &attr);
 | |
|     value_list = (CARD32 *) (stuff + 1);
 | |
|     count = dmxFetchScreenAttributes(stuff->valueMask, &attr, value_list);
 | |
| 
 | |
|     if (!(name = malloc(stuff->displayNameLength + 1 + 4)))
 | |
|         return BadAlloc;
 | |
|     memcpy(name, &value_list[count], stuff->displayNameLength);
 | |
|     name[stuff->displayNameLength] = '\0';
 | |
|     attr.displayName = name;
 | |
| 
 | |
|     status = dmxAttachScreen(stuff->physicalScreen, &attr);
 | |
| 
 | |
|     free(name);
 | |
| 
 | |
|     rep = (xDMXAddScreenReply) {
 | |
|         .type = X_Reply,
 | |
|         .sequenceNumber = client->sequence,
 | |
|         .length = 0,
 | |
|         .status = status,
 | |
|         .physicalScreen = stuff->physicalScreen
 | |
|     };
 | |
|     if (client->swapped) {
 | |
|         swaps(&rep.sequenceNumber);
 | |
|         swapl(&rep.length);
 | |
|         swapl(&rep.status);
 | |
|         swapl(&rep.physicalScreen);
 | |
|     }
 | |
|     WriteToClient(client, sizeof(xDMXAddScreenReply), &rep);
 | |
|     return Success;
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcDMXRemoveScreen(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xDMXRemoveScreenReq);
 | |
|     xDMXRemoveScreenReply rep;
 | |
|     int status = 0;
 | |
| 
 | |
|     REQUEST_SIZE_MATCH(xDMXRemoveScreenReq);
 | |
| 
 | |
|     status = dmxDetachScreen(stuff->physicalScreen);
 | |
| 
 | |
|     rep = (xDMXRemoveScreenReply) {
 | |
|         .type = X_Reply,
 | |
|         .sequenceNumber = client->sequence,
 | |
|         .length = 0,
 | |
|         .status = status
 | |
|     };
 | |
|     if (client->swapped) {
 | |
|         swaps(&rep.sequenceNumber);
 | |
|         swapl(&rep.length);
 | |
|         swapl(&rep.status);
 | |
|     }
 | |
|     WriteToClient(client, sizeof(xDMXRemoveScreenReply), &rep);
 | |
|     return Success;
 | |
| }
 | |
| 
 | |
| #ifdef PANORAMIX
 | |
| static int
 | |
| dmxPopulatePanoramiX(ClientPtr client, Window window,
 | |
|                      CARD32 *screens, CARD32 *windows,
 | |
|                      xRectangle *pos, xRectangle *vis)
 | |
| {
 | |
|     WindowPtr pWin;
 | |
|     PanoramiXRes *win;
 | |
|     int i;
 | |
|     int count = 0;
 | |
|     DMXWindowAttributesRec attr;
 | |
| 
 | |
|     if (Success != dixLookupResourceByType((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 = (xDMXGetWindowAttributesReply) {
 | |
|         .type = X_Reply,
 | |
|         .sequenceNumber = client->sequence,
 | |
|         .length = count * 6,
 | |
|         .screenCount = count
 | |
|     };
 | |
|     if (client->swapped) {
 | |
|         swaps(&rep.sequenceNumber);
 | |
|         swapl(&rep.length);
 | |
|         swapl(&rep.screenCount);
 | |
|         for (i = 0; i < count; i++) {
 | |
|             swapl(&screens[i]);
 | |
|             swapl(&windows[i]);
 | |
| 
 | |
|             swaps(&pos[i].x);
 | |
|             swaps(&pos[i].y);
 | |
|             swaps(&pos[i].width);
 | |
|             swaps(&pos[i].height);
 | |
| 
 | |
|             swaps(&vis[i].x);
 | |
|             swaps(&vis[i].y);
 | |
|             swaps(&vis[i].width);
 | |
|             swaps(&vis[i].height);
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     dmxFlushPendingSyncs();
 | |
| 
 | |
|     WriteToClient(client, sizeof(xDMXGetWindowAttributesReply), &rep);
 | |
|     if (count) {
 | |
|         WriteToClient(client, count * sizeof(*screens), screens);
 | |
|         WriteToClient(client, count * sizeof(*windows), windows);
 | |
|         WriteToClient(client, count * sizeof(*pos), pos);
 | |
|         WriteToClient(client, count * sizeof(*vis), vis);
 | |
|     }
 | |
| 
 | |
|     free(vis);
 | |
|     free(pos);
 | |
|     free(windows);
 | |
|     free(screens);
 | |
| 
 | |
|     return Success;
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcDMXGetDesktopAttributes(ClientPtr client)
 | |
| {
 | |
|     xDMXGetDesktopAttributesReply rep;
 | |
|     DMXDesktopAttributesRec attr;
 | |
| 
 | |
|     REQUEST_SIZE_MATCH(xDMXGetDesktopAttributesReq);
 | |
| 
 | |
|     dmxGetDesktopAttributes(&attr);
 | |
| 
 | |
|     rep = (xDMXGetDesktopAttributesReply) {
 | |
|         .type = X_Reply,
 | |
|         .sequenceNumber = client->sequence,
 | |
|         .length = 0,
 | |
|         .width = attr.width,
 | |
|         .height = attr.height,
 | |
|         .shiftX = attr.shiftX,
 | |
|         .shiftY = attr.shiftY
 | |
|     };
 | |
| 
 | |
|     if (client->swapped) {
 | |
|         swaps(&rep.sequenceNumber);
 | |
|         swapl(&rep.length);
 | |
|         swaps(&rep.width);
 | |
|         swaps(&rep.height);
 | |
|         swaps(&rep.shiftX);
 | |
|         swaps(&rep.shiftY);
 | |
|     }
 | |
|     WriteToClient(client, sizeof(xDMXGetDesktopAttributesReply), &rep);
 | |
|     return Success;
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcDMXChangeDesktopAttributes(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xDMXChangeDesktopAttributesReq);
 | |
|     xDMXChangeDesktopAttributesReply rep;
 | |
|     int status = DMX_BAD_XINERAMA;
 | |
|     CARD32 *value_list;
 | |
|     DMXDesktopAttributesRec attr;
 | |
|     int len;
 | |
| 
 | |
|     REQUEST_AT_LEAST_SIZE(xDMXChangeDesktopAttributesReq);
 | |
|     len = client->req_len - (sizeof(xDMXChangeDesktopAttributesReq) >> 2);
 | |
|     if (len != Ones(stuff->valueMask))
 | |
|         return BadLength;
 | |
| 
 | |
|     if (!_DMXXineramaActive())
 | |
|         goto noxinerama;
 | |
| 
 | |
|     value_list = (CARD32 *) (stuff + 1);
 | |
| 
 | |
|     dmxGetDesktopAttributes(&attr);
 | |
|     dmxFetchDesktopAttributes(stuff->valueMask, &attr, value_list);
 | |
| 
 | |
| #if PANORAMIX
 | |
|     status = dmxConfigureDesktop(&attr);
 | |
| #endif
 | |
|     if (status == BadValue)
 | |
|         return status;
 | |
| 
 | |
|  noxinerama:
 | |
|     rep = (xDMXChangeDesktopAttributesReply) {
 | |
|         .type = X_Reply,
 | |
|         .sequenceNumber = client->sequence,
 | |
|         .length = 0,
 | |
|         .status = status
 | |
|     };
 | |
|     if (client->swapped) {
 | |
|         swaps(&rep.sequenceNumber);
 | |
|         swapl(&rep.length);
 | |
|         swapl(&rep.status);
 | |
|     }
 | |
|     WriteToClient(client, sizeof(xDMXChangeDesktopAttributesReply), &rep);
 | |
|     return Success;
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcDMXGetInputCount(ClientPtr client)
 | |
| {
 | |
|     xDMXGetInputCountReply rep;
 | |
| 
 | |
|     REQUEST_SIZE_MATCH(xDMXGetInputCountReq);
 | |
| 
 | |
|     rep = (xDMXGetInputCountReply) {
 | |
|         .type = X_Reply,
 | |
|         .sequenceNumber = client->sequence,
 | |
|         .length = 0,
 | |
|         .inputCount = dmxGetInputCount()
 | |
|     };
 | |
|     if (client->swapped) {
 | |
|         swaps(&rep.sequenceNumber);
 | |
|         swapl(&rep.length);
 | |
|         swapl(&rep.inputCount);
 | |
|     }
 | |
|     WriteToClient(client, sizeof(xDMXGetInputCountReply), &rep);
 | |
|     return Success;
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcDMXGetInputAttributes(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xDMXGetInputAttributesReq);
 | |
|     xDMXGetInputAttributesReply rep;
 | |
|     int length;
 | |
|     int paddedLength;
 | |
|     DMXInputAttributesRec attr;
 | |
| 
 | |
|     REQUEST_SIZE_MATCH(xDMXGetInputAttributesReq);
 | |
| 
 | |
|     if (dmxGetInputAttributes(stuff->deviceId, &attr))
 | |
|         return BadValue;
 | |
| 
 | |
|     length = attr.name ? strlen(attr.name) : 0;
 | |
|     paddedLength = pad_to_int32(length);
 | |
| 
 | |
|     rep = (xDMXGetInputAttributesReply) {
 | |
|         .type = X_Reply,
 | |
|         .sequenceNumber = client->sequence,
 | |
|         .length = bytes_to_int32(paddedLength),
 | |
| 
 | |
|         .inputType = attr.inputType,
 | |
|         .physicalScreen = attr.physicalScreen,
 | |
|         .physicalId = attr.physicalId,
 | |
|         .nameLength = length,
 | |
|         .isCore = attr.isCore,
 | |
|         .sendsCore = attr.sendsCore,
 | |
|         .detached = attr.detached
 | |
|     };
 | |
| 
 | |
|     if (client->swapped) {
 | |
|         swaps(&rep.sequenceNumber);
 | |
|         swapl(&rep.length);
 | |
|         swapl(&rep.inputType);
 | |
|         swapl(&rep.physicalScreen);
 | |
|         swapl(&rep.physicalId);
 | |
|         swapl(&rep.nameLength);
 | |
|     }
 | |
|     WriteToClient(client, sizeof(xDMXGetInputAttributesReply), &rep);
 | |
|     if (length)
 | |
|         WriteToClient(client, length, attr.name);
 | |
|     return Success;
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcDMXAddInput(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xDMXAddInputReq);
 | |
|     xDMXAddInputReply rep;
 | |
|     int status = 0;
 | |
|     CARD32 *value_list;
 | |
|     DMXInputAttributesRec attr;
 | |
|     int count;
 | |
|     char *name;
 | |
|     int len;
 | |
|     int paddedLength;
 | |
|     int id = -1;
 | |
| 
 | |
|     REQUEST_AT_LEAST_SIZE(xDMXAddInputReq);
 | |
|     paddedLength = pad_to_int32(stuff->displayNameLength);
 | |
|     len = client->req_len - (sizeof(xDMXAddInputReq) >> 2);
 | |
|     if (len != Ones(stuff->valueMask) + paddedLength / 4)
 | |
|         return BadLength;
 | |
| 
 | |
|     memset(&attr, 0, sizeof(attr));
 | |
|     value_list = (CARD32 *) (stuff + 1);
 | |
|     count = dmxFetchInputAttributes(stuff->valueMask, &attr, value_list);
 | |
| 
 | |
|     if (!(name = malloc(stuff->displayNameLength + 1 + 4)))
 | |
|         return BadAlloc;
 | |
|     memcpy(name, &value_list[count], stuff->displayNameLength);
 | |
|     name[stuff->displayNameLength] = '\0';
 | |
|     attr.name = name;
 | |
| 
 | |
|     status = dmxAddInput(&attr, &id);
 | |
| 
 | |
|     free(name);
 | |
| 
 | |
|     if (status)
 | |
|         return status;
 | |
| 
 | |
|     rep = (xDMXAddInputReply) {
 | |
|         .type = X_Reply,
 | |
|         .sequenceNumber = client->sequence,
 | |
|         .length = 0,
 | |
|         .status = status,
 | |
|         .physicalId = id
 | |
|     };
 | |
|     if (client->swapped) {
 | |
|         swaps(&rep.sequenceNumber);
 | |
|         swapl(&rep.length);
 | |
|         swapl(&rep.status);
 | |
|         swapl(&rep.physicalId);
 | |
|     }
 | |
|     WriteToClient(client, sizeof(xDMXAddInputReply), &rep);
 | |
|     return Success;
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcDMXRemoveInput(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xDMXRemoveInputReq);
 | |
|     xDMXRemoveInputReply rep;
 | |
|     int status = 0;
 | |
| 
 | |
|     REQUEST_SIZE_MATCH(xDMXRemoveInputReq);
 | |
| 
 | |
|     status = dmxRemoveInput(stuff->physicalId);
 | |
| 
 | |
|     if (status)
 | |
|         return status;
 | |
| 
 | |
|     rep = (xDMXRemoveInputReply) {
 | |
|         .type = X_Reply,
 | |
|         .sequenceNumber = client->sequence,
 | |
|         .length = 0,
 | |
|         .status = status
 | |
|     };
 | |
|     if (client->swapped) {
 | |
|         swaps(&rep.sequenceNumber);
 | |
|         swapl(&rep.length);
 | |
|         swapl(&rep.status);
 | |
|     }
 | |
|     WriteToClient(client, sizeof(xDMXRemoveInputReply), &rep);
 | |
|     return Success;
 | |
| }
 | |
| 
 | |
| static int
 | |
| ProcDMXDispatch(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xReq);
 | |
| 
 | |
|     switch (stuff->data) {
 | |
|     case X_DMXQueryVersion:
 | |
|         return ProcDMXQueryVersion(client);
 | |
|     case X_DMXSync:
 | |
|         return ProcDMXSync(client);
 | |
|     case X_DMXForceWindowCreation:
 | |
|         return ProcDMXForceWindowCreation(client);
 | |
|     case X_DMXGetScreenCount:
 | |
|         return ProcDMXGetScreenCount(client);
 | |
|     case X_DMXGetScreenAttributes:
 | |
|         return ProcDMXGetScreenAttributes(client);
 | |
|     case X_DMXChangeScreensAttributes:
 | |
|         return ProcDMXChangeScreensAttributes(client);
 | |
|     case X_DMXAddScreen:
 | |
|         return ProcDMXAddScreen(client);
 | |
|     case X_DMXRemoveScreen:
 | |
|         return ProcDMXRemoveScreen(client);
 | |
|     case X_DMXGetWindowAttributes:
 | |
|         return ProcDMXGetWindowAttributes(client);
 | |
|     case X_DMXGetDesktopAttributes:
 | |
|         return ProcDMXGetDesktopAttributes(client);
 | |
|     case X_DMXChangeDesktopAttributes:
 | |
|         return ProcDMXChangeDesktopAttributes(client);
 | |
|     case X_DMXGetInputCount:
 | |
|         return ProcDMXGetInputCount(client);
 | |
|     case X_DMXGetInputAttributes:
 | |
|         return ProcDMXGetInputAttributes(client);
 | |
|     case X_DMXAddInput:
 | |
|         return ProcDMXAddInput(client);
 | |
|     case X_DMXRemoveInput:
 | |
|         return ProcDMXRemoveInput(client);
 | |
| 
 | |
|     case X_DMXGetScreenInformationDEPRECATED:
 | |
|     case X_DMXForceWindowCreationDEPRECATED:
 | |
|     case X_DMXReconfigureScreenDEPRECATED:
 | |
|         return BadImplementation;
 | |
| 
 | |
|     default:
 | |
|         return BadRequest;
 | |
|     }
 | |
| }
 | |
| 
 | |
| static int
 | |
| 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;
 | |
| }
 |