1706f2543Smrg/*
2706f2543Smrg * Copyright 2002-2004 Red Hat Inc., Durham, North Carolina.
3706f2543Smrg *
4706f2543Smrg * All Rights Reserved.
5706f2543Smrg *
6706f2543Smrg * Permission is hereby granted, free of charge, to any person obtaining
7706f2543Smrg * a copy of this software and associated documentation files (the
8706f2543Smrg * "Software"), to deal in the Software without restriction, including
9706f2543Smrg * without limitation on the rights to use, copy, modify, merge,
10706f2543Smrg * publish, distribute, sublicense, and/or sell copies of the Software,
11706f2543Smrg * and to permit persons to whom the Software is furnished to do so,
12706f2543Smrg * subject to the following conditions:
13706f2543Smrg *
14706f2543Smrg * The above copyright notice and this permission notice (including the
15706f2543Smrg * next paragraph) shall be included in all copies or substantial
16706f2543Smrg * portions of the Software.
17706f2543Smrg *
18706f2543Smrg * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
19706f2543Smrg * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
20706f2543Smrg * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
21706f2543Smrg * NON-INFRINGEMENT.  IN NO EVENT SHALL RED HAT AND/OR THEIR SUPPLIERS
22706f2543Smrg * BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
23706f2543Smrg * ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
24706f2543Smrg * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
25706f2543Smrg * SOFTWARE.
26706f2543Smrg */
27706f2543Smrg
28706f2543Smrg/*
29706f2543Smrg * Authors:
30706f2543Smrg *   Rickard E. (Rik) Faith <faith@redhat.com>
31706f2543Smrg *
32706f2543Smrg */
33706f2543Smrg
34706f2543Smrg/** \file
35706f2543Smrg * This file implements the server-side part of the DMX protocol. A
36706f2543Smrg * vector of fucntions is provided at extension initialization time, so
37706f2543Smrg * most all of the useful functions in this file are declared static and
38706f2543Smrg * do not appear in the doxygen documentation.
39706f2543Smrg *
40706f2543Smrg * Much of the low-level work is done by functions in \a dmxextension.c
41706f2543Smrg *
42706f2543Smrg * Please see the Client-to-Server DMX Extension to the X Protocol
43706f2543Smrg * document for details about the protocol.  */
44706f2543Smrg
45706f2543Smrg#ifdef HAVE_DMX_CONFIG_H
46706f2543Smrg#include <dmx-config.h>
47706f2543Smrg#endif
48706f2543Smrg
49706f2543Smrg#include <X11/X.h>
50706f2543Smrg#include <X11/Xproto.h>
51706f2543Smrg#include "misc.h"
52706f2543Smrg#include "os.h"
53706f2543Smrg#include "dixstruct.h"
54706f2543Smrg#include "extnsionst.h"
55706f2543Smrg#include "opaque.h"
56706f2543Smrg
57706f2543Smrg#include "dmxextension.h"
58706f2543Smrg#include <X11/extensions/dmxproto.h>
59706f2543Smrg#include <X11/extensions/dmx.h>
60706f2543Smrg#include "protocol-versions.h"
61706f2543Smrg
62706f2543Smrg#ifdef PANORAMIX
63706f2543Smrg#include "panoramiX.h"
64706f2543Smrgextern unsigned long XRT_WINDOW;
65706f2543Smrgextern int           PanoramiXNumScreens;
66706f2543Smrg#endif
67706f2543Smrg
68706f2543Smrgextern void DMXExtensionInit(void);
69706f2543Smrg
70706f2543Smrgstatic unsigned char DMXCode;
71706f2543Smrg
72706f2543Smrg
73706f2543Smrg
74706f2543Smrgstatic int _DMXXineramaActive(void)
75706f2543Smrg{
76706f2543Smrg#ifdef PANORAMIX
77706f2543Smrg    return !noPanoramiXExtension;
78706f2543Smrg#endif
79706f2543Smrg    return 0;
80706f2543Smrg}
81706f2543Smrg
82706f2543Smrgstatic void dmxSetScreenAttribute(int bit, DMXScreenAttributesPtr attr,
83706f2543Smrg                                  CARD32 value)
84706f2543Smrg{
85706f2543Smrg    switch (1 << bit) {
86706f2543Smrg    case DMXScreenWindowWidth:   attr->screenWindowWidth   = value; break;
87706f2543Smrg    case DMXScreenWindowHeight:  attr->screenWindowHeight  = value; break;
88706f2543Smrg    case DMXScreenWindowXoffset: attr->screenWindowXoffset = value; break;
89706f2543Smrg    case DMXScreenWindowYoffset: attr->screenWindowYoffset = value; break;
90706f2543Smrg    case DMXRootWindowWidth:     attr->rootWindowWidth     = value; break;
91706f2543Smrg    case DMXRootWindowHeight:    attr->rootWindowHeight    = value; break;
92706f2543Smrg    case DMXRootWindowXoffset:   attr->rootWindowXoffset   = value; break;
93706f2543Smrg    case DMXRootWindowYoffset:   attr->rootWindowYoffset   = value; break;
94706f2543Smrg    case DMXRootWindowXorigin:   attr->rootWindowXorigin   = value; break;
95706f2543Smrg    case DMXRootWindowYorigin:   attr->rootWindowYorigin   = value; break;
96706f2543Smrg    }
97706f2543Smrg}
98706f2543Smrg
99706f2543Smrgstatic int dmxFetchScreenAttributes(unsigned int mask,
100706f2543Smrg                                    DMXScreenAttributesPtr attr,
101706f2543Smrg                                    CARD32 *value_list)
102706f2543Smrg{
103706f2543Smrg    int    i;
104706f2543Smrg    CARD32 *value = value_list;
105706f2543Smrg    int    count  = 0;
106706f2543Smrg
107706f2543Smrg    for (i = 0; i < 32; i++) {
108706f2543Smrg        if (mask & (1 << i)) {
109706f2543Smrg            dmxSetScreenAttribute(i, attr, *value);
110706f2543Smrg            ++value;
111706f2543Smrg            ++count;
112706f2543Smrg        }
113706f2543Smrg    }
114706f2543Smrg    return count;
115706f2543Smrg}
116706f2543Smrg
117706f2543Smrgstatic void dmxSetDesktopAttribute(int bit, DMXDesktopAttributesPtr attr,
118706f2543Smrg                                   CARD32 value)
119706f2543Smrg{
120706f2543Smrg    switch (1 << bit) {
121706f2543Smrg    case DMXDesktopWidth:  attr->width  = value; break;
122706f2543Smrg    case DMXDesktopHeight: attr->height = value; break;
123706f2543Smrg    case DMXDesktopShiftX: attr->shiftX = value; break;
124706f2543Smrg    case DMXDesktopShiftY: attr->shiftY = value; break;
125706f2543Smrg    }
126706f2543Smrg}
127706f2543Smrg
128706f2543Smrgstatic int dmxFetchDesktopAttributes(unsigned int mask,
129706f2543Smrg                                     DMXDesktopAttributesPtr attr,
130706f2543Smrg                                     CARD32 *value_list)
131706f2543Smrg{
132706f2543Smrg    int    i;
133706f2543Smrg    CARD32 *value = value_list;
134706f2543Smrg    int    count  = 0;
135706f2543Smrg
136706f2543Smrg    for (i = 0; i < 32; i++) {
137706f2543Smrg        if (mask & (1 << i)) {
138706f2543Smrg            dmxSetDesktopAttribute(i, attr, *value);
139706f2543Smrg	    ++value;
140706f2543Smrg            ++count;
141706f2543Smrg        }
142706f2543Smrg    }
143706f2543Smrg    return count;
144706f2543Smrg}
145706f2543Smrg
146706f2543Smrgstatic void dmxSetInputAttribute(int bit, DMXInputAttributesPtr attr,
147706f2543Smrg                                 CARD32 value)
148706f2543Smrg{
149706f2543Smrg    switch (1 << bit) {
150706f2543Smrg    case DMXInputType:           attr->inputType      = value;   break;
151706f2543Smrg    case DMXInputPhysicalScreen: attr->physicalScreen = value;   break;
152706f2543Smrg    case DMXInputSendsCore:      attr->sendsCore      = !!value; break;
153706f2543Smrg    }
154706f2543Smrg}
155706f2543Smrg
156706f2543Smrgstatic int dmxFetchInputAttributes(unsigned int mask,
157706f2543Smrg                                   DMXInputAttributesPtr attr,
158706f2543Smrg                                   CARD32 *value_list)
159706f2543Smrg{
160706f2543Smrg    int    i;
161706f2543Smrg    CARD32 *value = value_list;
162706f2543Smrg    int    count  = 0;
163706f2543Smrg
164706f2543Smrg    for (i = 0; i < 32; i++) {
165706f2543Smrg        if (mask & (1 << i)) {
166706f2543Smrg            dmxSetInputAttribute(i, attr, *value);
167706f2543Smrg            ++value;
168706f2543Smrg            ++count;
169706f2543Smrg        }
170706f2543Smrg    }
171706f2543Smrg    return count;
172706f2543Smrg}
173706f2543Smrg
174706f2543Smrgstatic int ProcDMXQueryVersion(ClientPtr client)
175706f2543Smrg{
176706f2543Smrg    xDMXQueryVersionReply rep;
177706f2543Smrg    int                   n;
178706f2543Smrg
179706f2543Smrg    REQUEST_SIZE_MATCH(xDMXQueryVersionReq);
180706f2543Smrg
181706f2543Smrg    rep.type           = X_Reply;
182706f2543Smrg    rep.sequenceNumber = client->sequence;
183706f2543Smrg    rep.length         = 0;
184706f2543Smrg    rep.majorVersion   = SERVER_DMX_MAJOR_VERSION;
185706f2543Smrg    rep.minorVersion   = SERVER_DMX_MINOR_VERSION;
186706f2543Smrg    rep.patchVersion   = SERVER_DMX_PATCH_VERSION;
187706f2543Smrg    if (client->swapped) {
188706f2543Smrg    	swaps(&rep.sequenceNumber, n);
189706f2543Smrg        swapl(&rep.length, n);
190706f2543Smrg	swapl(&rep.majorVersion, n);
191706f2543Smrg	swapl(&rep.minorVersion, n);
192706f2543Smrg	swapl(&rep.patchVersion, n);
193706f2543Smrg    }
194706f2543Smrg    WriteToClient(client, sizeof(xDMXQueryVersionReply), (char *)&rep);
195706f2543Smrg    return Success;
196706f2543Smrg}
197706f2543Smrg
198706f2543Smrgstatic int ProcDMXSync(ClientPtr client)
199706f2543Smrg{
200706f2543Smrg    xDMXSyncReply rep;
201706f2543Smrg    int           n;
202706f2543Smrg
203706f2543Smrg    REQUEST_SIZE_MATCH(xDMXSyncReq);
204706f2543Smrg
205706f2543Smrg    dmxFlushPendingSyncs();
206706f2543Smrg
207706f2543Smrg    rep.type           = X_Reply;
208706f2543Smrg    rep.sequenceNumber = client->sequence;
209706f2543Smrg    rep.length         = 0;
210706f2543Smrg    rep.status         = 0;
211706f2543Smrg    if (client->swapped) {
212706f2543Smrg        swaps(&rep.sequenceNumber, n);
213706f2543Smrg        swapl(&rep.length, n);
214706f2543Smrg        swapl(&rep.status, n);
215706f2543Smrg    }
216706f2543Smrg    WriteToClient(client, sizeof(xDMXSyncReply), (char *)&rep);
217706f2543Smrg    return Success;
218706f2543Smrg}
219706f2543Smrg
220706f2543Smrgstatic int ProcDMXForceWindowCreation(ClientPtr client)
221706f2543Smrg{
222706f2543Smrg    xDMXForceWindowCreationReply rep;
223706f2543Smrg    REQUEST(xDMXForceWindowCreationReq);
224706f2543Smrg    WindowPtr     pWin;
225706f2543Smrg    int           n;
226706f2543Smrg
227706f2543Smrg    REQUEST_SIZE_MATCH(xDMXForceWindowCreationReq);
228706f2543Smrg
229706f2543Smrg#ifdef PANORAMIX
230706f2543Smrg    if (!noPanoramiXExtension) {
231706f2543Smrg        PanoramiXRes *win;
232706f2543Smrg        int          i;
233706f2543Smrg
234706f2543Smrg        if (Success != dixLookupResourceByType((pointer*) &win,
235706f2543Smrg					       stuff->window, XRT_WINDOW,
236706f2543Smrg					       client, DixReadAccess))
237706f2543Smrg            return -1;           /* BadWindow */
238706f2543Smrg
239706f2543Smrg        FOR_NSCREENS(i) {
240706f2543Smrg            if (Success != dixLookupWindow(&pWin, win->info[i].id, client,
241706f2543Smrg					   DixReadAccess))
242706f2543Smrg                return -1;       /* BadWindow */
243706f2543Smrg
244706f2543Smrg            dmxForceWindowCreation(pWin);
245706f2543Smrg        }
246706f2543Smrg        goto doreply;
247706f2543Smrg    }
248706f2543Smrg#endif
249706f2543Smrg
250706f2543Smrg    if (Success != dixLookupWindow(&pWin, stuff->window, client,
251706f2543Smrg				   DixReadAccess))
252706f2543Smrg        return -1;               /* BadWindow */
253706f2543Smrg
254706f2543Smrg    dmxForceWindowCreation(pWin);
255706f2543Smrg  doreply:
256706f2543Smrg    dmxFlushPendingSyncs();
257706f2543Smrg    rep.type           = X_Reply;
258706f2543Smrg    rep.sequenceNumber = client->sequence;
259706f2543Smrg    rep.length         = 0;
260706f2543Smrg    rep.status         = 0;
261706f2543Smrg    if (client->swapped) {
262706f2543Smrg        swaps(&rep.sequenceNumber, n);
263706f2543Smrg        swapl(&rep.length, n);
264706f2543Smrg        swapl(&rep.status, n);
265706f2543Smrg    }
266706f2543Smrg    WriteToClient(client, sizeof(xDMXForceWindowCreationReply), (char *)&rep);
267706f2543Smrg    return Success;
268706f2543Smrg}
269706f2543Smrg
270706f2543Smrgstatic int ProcDMXGetScreenCount(ClientPtr client)
271706f2543Smrg{
272706f2543Smrg    xDMXGetScreenCountReply rep;
273706f2543Smrg    int                     n;
274706f2543Smrg
275706f2543Smrg    REQUEST_SIZE_MATCH(xDMXGetScreenCountReq);
276706f2543Smrg
277706f2543Smrg    rep.type           = X_Reply;
278706f2543Smrg    rep.sequenceNumber = client->sequence;
279706f2543Smrg    rep.length         = 0;
280706f2543Smrg    rep.screenCount    = dmxGetNumScreens();
281706f2543Smrg    if (client->swapped) {
282706f2543Smrg    	swaps(&rep.sequenceNumber, n);
283706f2543Smrg        swapl(&rep.length, n);
284706f2543Smrg        swapl(&rep.screenCount, n);
285706f2543Smrg    }
286706f2543Smrg    WriteToClient(client, sizeof(xDMXGetScreenCountReply), (char *)&rep);
287706f2543Smrg    return Success;
288706f2543Smrg}
289706f2543Smrg
290706f2543Smrgstatic int ProcDMXGetScreenAttributes(ClientPtr client)
291706f2543Smrg{
292706f2543Smrg    REQUEST(xDMXGetScreenAttributesReq);
293706f2543Smrg    xDMXGetScreenAttributesReply rep;
294706f2543Smrg    int                          n;
295706f2543Smrg    int                          length;
296706f2543Smrg    int                          paddedLength;
297706f2543Smrg    DMXScreenAttributesRec       attr;
298706f2543Smrg
299706f2543Smrg    REQUEST_SIZE_MATCH(xDMXGetScreenAttributesReq);
300706f2543Smrg
301706f2543Smrg    if (stuff->physicalScreen < 0
302706f2543Smrg        || stuff->physicalScreen >= dmxGetNumScreens()) return BadValue;
303706f2543Smrg
304706f2543Smrg    if (!dmxGetScreenAttributes(stuff->physicalScreen, &attr))
305706f2543Smrg        return BadValue;
306706f2543Smrg
307706f2543Smrg    rep.logicalScreen       = attr.logicalScreen;
308706f2543Smrg    rep.screenWindowWidth   = attr.screenWindowWidth;
309706f2543Smrg    rep.screenWindowHeight  = attr.screenWindowHeight;
310706f2543Smrg    rep.screenWindowXoffset = attr.screenWindowXoffset;
311706f2543Smrg    rep.screenWindowYoffset = attr.screenWindowYoffset;
312706f2543Smrg    rep.rootWindowWidth     = attr.rootWindowWidth;
313706f2543Smrg    rep.rootWindowHeight    = attr.rootWindowHeight;
314706f2543Smrg    rep.rootWindowXoffset   = attr.rootWindowXoffset;
315706f2543Smrg    rep.rootWindowYoffset   = attr.rootWindowYoffset;
316706f2543Smrg    rep.rootWindowXorigin   = attr.rootWindowXorigin;
317706f2543Smrg    rep.rootWindowYorigin   = attr.rootWindowYorigin;
318706f2543Smrg
319706f2543Smrg    length                  = attr.displayName ? strlen(attr.displayName) : 0;
320706f2543Smrg    paddedLength            = pad_to_int32(length);
321706f2543Smrg    rep.type                = X_Reply;
322706f2543Smrg    rep.sequenceNumber      = client->sequence;
323706f2543Smrg    rep.length              = bytes_to_int32((sizeof(xDMXGetScreenAttributesReply) - sizeof(xGenericReply))
324706f2543Smrg                                             + paddedLength);
325706f2543Smrg    rep.displayNameLength   = length;
326706f2543Smrg
327706f2543Smrg    if (client->swapped) {
328706f2543Smrg    	swaps(&rep.sequenceNumber, n);
329706f2543Smrg        swapl(&rep.length, n);
330706f2543Smrg        swapl(&rep.displayNameLength, n);
331706f2543Smrg        swapl(&rep.logicalScreen, n);
332706f2543Smrg        swaps(&rep.screenWindowWidth, n);
333706f2543Smrg        swaps(&rep.screenWindowHeight, n);
334706f2543Smrg        swaps(&rep.screenWindowXoffset, n);
335706f2543Smrg        swaps(&rep.screenWindowYoffset, n);
336706f2543Smrg        swaps(&rep.rootWindowWidth, n);
337706f2543Smrg        swaps(&rep.rootWindowHeight, n);
338706f2543Smrg        swaps(&rep.rootWindowXoffset, n);
339706f2543Smrg        swaps(&rep.rootWindowYoffset, n);
340706f2543Smrg        swaps(&rep.rootWindowXorigin, n);
341706f2543Smrg        swaps(&rep.rootWindowYorigin, n);
342706f2543Smrg    }
343706f2543Smrg    WriteToClient(client, sizeof(xDMXGetScreenAttributesReply), (char *)&rep);
344706f2543Smrg    if (length) WriteToClient(client, length, (char *)attr.displayName);
345706f2543Smrg    return Success;
346706f2543Smrg}
347706f2543Smrg
348706f2543Smrgstatic int ProcDMXChangeScreensAttributes(ClientPtr client)
349706f2543Smrg{
350706f2543Smrg    REQUEST(xDMXChangeScreensAttributesReq);
351706f2543Smrg    xDMXChangeScreensAttributesReply rep;
352706f2543Smrg    int                              n;
353706f2543Smrg    int                              status = DMX_BAD_XINERAMA;
354706f2543Smrg    unsigned int                     mask   = 0;
355706f2543Smrg    unsigned int                     i;
356706f2543Smrg    CARD32                           *screen_list;
357706f2543Smrg    CARD32                           *mask_list;
358706f2543Smrg    CARD32                           *value_list;
359706f2543Smrg    DMXScreenAttributesPtr           attribs;
360706f2543Smrg    int                              errorScreen = 0;
361706f2543Smrg    unsigned int                     len;
362706f2543Smrg    int                              ones = 0;
363706f2543Smrg
364706f2543Smrg
365706f2543Smrg    REQUEST_AT_LEAST_SIZE(xDMXChangeScreensAttributesReq);
366706f2543Smrg    len = client->req_len - bytes_to_int32(sizeof(xDMXChangeScreensAttributesReq));
367706f2543Smrg    if (len < stuff->screenCount + stuff->maskCount)
368706f2543Smrg        return BadLength;
369706f2543Smrg
370706f2543Smrg    screen_list = (CARD32 *)(stuff + 1);
371706f2543Smrg    mask_list   = &screen_list[stuff->screenCount];
372706f2543Smrg    value_list  = &mask_list[stuff->maskCount];
373706f2543Smrg
374706f2543Smrg    for (i = 0; i < stuff->maskCount; i++) ones += Ones(mask_list[i]);
375706f2543Smrg    if (len != stuff->screenCount + stuff->maskCount + ones)
376706f2543Smrg        return BadLength;
377706f2543Smrg
378706f2543Smrg    if (!_DMXXineramaActive()) goto noxinerama;
379706f2543Smrg
380706f2543Smrg    if (!(attribs = malloc(stuff->screenCount * sizeof(*attribs))))
381706f2543Smrg        return BadAlloc;
382706f2543Smrg
383706f2543Smrg    for (i = 0; i < stuff->screenCount; i++) {
384706f2543Smrg        int count;
385706f2543Smrg
386706f2543Smrg        if (i < stuff->maskCount) mask = mask_list[i];
387706f2543Smrg        dmxGetScreenAttributes(screen_list[i], &attribs[i]);
388706f2543Smrg        count = dmxFetchScreenAttributes(mask, &attribs[i], value_list);
389706f2543Smrg        value_list += count;
390706f2543Smrg    }
391706f2543Smrg
392706f2543Smrg#if PANORAMIX
393706f2543Smrg    status = dmxConfigureScreenWindows(stuff->screenCount,
394706f2543Smrg				       screen_list,
395706f2543Smrg				       attribs,
396706f2543Smrg				       &errorScreen);
397706f2543Smrg#endif
398706f2543Smrg
399706f2543Smrg    free(attribs);
400706f2543Smrg
401706f2543Smrg    if (status == BadValue) return status;
402706f2543Smrg
403706f2543Smrg  noxinerama:
404706f2543Smrg    rep.type           = X_Reply;
405706f2543Smrg    rep.sequenceNumber = client->sequence;
406706f2543Smrg    rep.length         = 0;
407706f2543Smrg    rep.status         = status;
408706f2543Smrg    rep.errorScreen    = errorScreen;
409706f2543Smrg    if (client->swapped) {
410706f2543Smrg        swaps(&rep.sequenceNumber, n);
411706f2543Smrg        swapl(&rep.length, n);
412706f2543Smrg        swapl(&rep.status, n);
413706f2543Smrg        swapl(&rep.errorScreen, n);
414706f2543Smrg    }
415706f2543Smrg    WriteToClient(client,
416706f2543Smrg                  sizeof(xDMXChangeScreensAttributesReply),
417706f2543Smrg                  (char *)&rep);
418706f2543Smrg    return Success;
419706f2543Smrg}
420706f2543Smrg
421706f2543Smrgstatic int ProcDMXAddScreen(ClientPtr client)
422706f2543Smrg{
423706f2543Smrg    REQUEST(xDMXAddScreenReq);
424706f2543Smrg    xDMXAddScreenReply     rep;
425706f2543Smrg    int                    n;
426706f2543Smrg    int                    status = 0;
427706f2543Smrg    CARD32                 *value_list;
428706f2543Smrg    DMXScreenAttributesRec attr;
429706f2543Smrg    int                    count;
430706f2543Smrg    char                   *name;
431706f2543Smrg    int                    len;
432706f2543Smrg    int                    paddedLength;
433706f2543Smrg
434706f2543Smrg    REQUEST_AT_LEAST_SIZE(xDMXAddScreenReq);
435706f2543Smrg    paddedLength = pad_to_int32(stuff->displayNameLength);
436706f2543Smrg    len          = client->req_len - bytes_to_int32(sizeof(xDMXAddScreenReq));
437706f2543Smrg    if (len != Ones(stuff->valueMask) + paddedLength/4)
438706f2543Smrg        return BadLength;
439706f2543Smrg
440706f2543Smrg    memset(&attr, 0, sizeof(attr));
441706f2543Smrg    dmxGetScreenAttributes(stuff->physicalScreen, &attr);
442706f2543Smrg    value_list = (CARD32 *)(stuff + 1);
443706f2543Smrg    count      = dmxFetchScreenAttributes(stuff->valueMask, &attr, value_list);
444706f2543Smrg
445706f2543Smrg    if (!(name = malloc(stuff->displayNameLength + 1 + 4)))
446706f2543Smrg        return BadAlloc;
447706f2543Smrg    memcpy(name, &value_list[count], stuff->displayNameLength);
448706f2543Smrg    name[stuff->displayNameLength] = '\0';
449706f2543Smrg    attr.displayName = name;
450706f2543Smrg
451706f2543Smrg    status = dmxAttachScreen(stuff->physicalScreen, &attr);
452706f2543Smrg
453706f2543Smrg    free(name);
454706f2543Smrg
455706f2543Smrg    rep.type           = X_Reply;
456706f2543Smrg    rep.sequenceNumber = client->sequence;
457706f2543Smrg    rep.length         = 0;
458706f2543Smrg    rep.status         = status;
459706f2543Smrg    rep.physicalScreen = stuff->physicalScreen;
460706f2543Smrg    if (client->swapped) {
461706f2543Smrg        swaps(&rep.sequenceNumber, n);
462706f2543Smrg        swapl(&rep.length, n);
463706f2543Smrg        swapl(&rep.status, n);
464706f2543Smrg        swapl(&rep.physicalScreen, n);
465706f2543Smrg    }
466706f2543Smrg    WriteToClient(client,
467706f2543Smrg                  sizeof(xDMXAddScreenReply),
468706f2543Smrg                  (char *)&rep);
469706f2543Smrg    return Success;
470706f2543Smrg}
471706f2543Smrg
472706f2543Smrgstatic int ProcDMXRemoveScreen(ClientPtr client)
473706f2543Smrg{
474706f2543Smrg    REQUEST(xDMXRemoveScreenReq);
475706f2543Smrg    xDMXRemoveScreenReply rep;
476706f2543Smrg    int                   n;
477706f2543Smrg    int                   status = 0;
478706f2543Smrg
479706f2543Smrg    REQUEST_SIZE_MATCH(xDMXRemoveScreenReq);
480706f2543Smrg
481706f2543Smrg    status = dmxDetachScreen(stuff->physicalScreen);
482706f2543Smrg
483706f2543Smrg    rep.type           = X_Reply;
484706f2543Smrg    rep.sequenceNumber = client->sequence;
485706f2543Smrg    rep.length         = 0;
486706f2543Smrg    rep.status         = status;
487706f2543Smrg    if (client->swapped) {
488706f2543Smrg        swaps(&rep.sequenceNumber, n);
489706f2543Smrg        swapl(&rep.length, n);
490706f2543Smrg        swapl(&rep.status, n);
491706f2543Smrg    }
492706f2543Smrg    WriteToClient(client,
493706f2543Smrg                  sizeof(xDMXRemoveScreenReply),
494706f2543Smrg                  (char *)&rep);
495706f2543Smrg    return Success;
496706f2543Smrg}
497706f2543Smrg
498706f2543Smrg
499706f2543Smrg#ifdef PANORAMIX
500706f2543Smrgstatic int dmxPopulatePanoramiX(ClientPtr client, Window window,
501706f2543Smrg                                CARD32 *screens, CARD32 *windows,
502706f2543Smrg                                xRectangle *pos, xRectangle *vis)
503706f2543Smrg{
504706f2543Smrg    WindowPtr              pWin;
505706f2543Smrg    PanoramiXRes           *win;
506706f2543Smrg    int                    i;
507706f2543Smrg    int                    count = 0;
508706f2543Smrg    DMXWindowAttributesRec attr;
509706f2543Smrg
510706f2543Smrg    if (Success != dixLookupResourceByType((pointer*) &win,
511706f2543Smrg					   window, XRT_WINDOW,
512706f2543Smrg					   client, DixReadAccess))
513706f2543Smrg        return -1;               /* BadWindow */
514706f2543Smrg
515706f2543Smrg    FOR_NSCREENS(i) {
516706f2543Smrg        if (Success != dixLookupWindow(&pWin, win->info[i].id, client,
517706f2543Smrg				       DixReadAccess))
518706f2543Smrg            return -1;          /* BadWindow */
519706f2543Smrg        if (dmxGetWindowAttributes(pWin, &attr)) {
520706f2543Smrg            screens[count] = attr.screen;
521706f2543Smrg            windows[count] = attr.window;
522706f2543Smrg            pos[count]     = attr.pos;
523706f2543Smrg            vis[count]     = attr.vis;
524706f2543Smrg            ++count;            /* Only count existing windows */
525706f2543Smrg        }
526706f2543Smrg    }
527706f2543Smrg    return count;
528706f2543Smrg}
529706f2543Smrg#endif
530706f2543Smrg
531706f2543Smrgstatic int dmxPopulate(ClientPtr client, Window window, CARD32 *screens,
532706f2543Smrg                       CARD32 *windows, xRectangle *pos, xRectangle *vis)
533706f2543Smrg{
534706f2543Smrg    WindowPtr              pWin;
535706f2543Smrg    DMXWindowAttributesRec attr;
536706f2543Smrg
537706f2543Smrg#ifdef PANORAMIX
538706f2543Smrg    if (!noPanoramiXExtension)
539706f2543Smrg        return dmxPopulatePanoramiX(client, window, screens, windows,
540706f2543Smrg                                    pos, vis);
541706f2543Smrg#endif
542706f2543Smrg
543706f2543Smrg    if (Success != dixLookupWindow(&pWin, window, client, DixReadAccess))
544706f2543Smrg        return -1;               /* BadWindow */
545706f2543Smrg
546706f2543Smrg    dmxGetWindowAttributes(pWin, &attr);
547706f2543Smrg    *screens = attr.screen;
548706f2543Smrg    *windows = attr.window;
549706f2543Smrg    *pos     = attr.pos;
550706f2543Smrg    *vis     = attr.vis;
551706f2543Smrg    return 1;
552706f2543Smrg}
553706f2543Smrg
554706f2543Smrgstatic int dmxMaxNumScreens(void)
555706f2543Smrg{
556706f2543Smrg#ifdef PANORAMIX
557706f2543Smrg    if (!noPanoramiXExtension) return PanoramiXNumScreens;
558706f2543Smrg#endif
559706f2543Smrg    return 1;
560706f2543Smrg}
561706f2543Smrg
562706f2543Smrgstatic int ProcDMXGetWindowAttributes(ClientPtr client)
563706f2543Smrg{
564706f2543Smrg    REQUEST(xDMXGetWindowAttributesReq);
565706f2543Smrg    xDMXGetWindowAttributesReply rep;
566706f2543Smrg    int                          i, n;
567706f2543Smrg    CARD32                       *screens;
568706f2543Smrg    CARD32                       *windows;
569706f2543Smrg    xRectangle                   *pos, *vis;
570706f2543Smrg    int                          count = dmxMaxNumScreens();
571706f2543Smrg
572706f2543Smrg    REQUEST_SIZE_MATCH(xDMXGetWindowAttributesReq);
573706f2543Smrg
574706f2543Smrg    if (!(screens = malloc(count * sizeof(*screens))))
575706f2543Smrg        return BadAlloc;
576706f2543Smrg    if (!(windows = malloc(count * sizeof(*windows)))) {
577706f2543Smrg        free(screens);
578706f2543Smrg        return BadAlloc;
579706f2543Smrg    }
580706f2543Smrg    if (!(pos = malloc(count * sizeof(*pos)))) {
581706f2543Smrg        free(windows);
582706f2543Smrg        free(screens);
583706f2543Smrg        return BadAlloc;
584706f2543Smrg    }
585706f2543Smrg    if (!(vis = malloc(count * sizeof(*vis)))) {
586706f2543Smrg        free(pos);
587706f2543Smrg        free(windows);
588706f2543Smrg        free(screens);
589706f2543Smrg        return BadAlloc;
590706f2543Smrg    }
591706f2543Smrg
592706f2543Smrg    if ((count = dmxPopulate(client, stuff->window, screens, windows,
593706f2543Smrg                             pos, vis)) < 0) {
594706f2543Smrg        free(vis);
595706f2543Smrg        free(pos);
596706f2543Smrg        free(windows);
597706f2543Smrg        free(screens);
598706f2543Smrg        return BadWindow;
599706f2543Smrg    }
600706f2543Smrg
601706f2543Smrg    rep.type           = X_Reply;
602706f2543Smrg    rep.sequenceNumber = client->sequence;
603706f2543Smrg    rep.length         = count * 6;
604706f2543Smrg    rep.screenCount    = count;
605706f2543Smrg    if (client->swapped) {
606706f2543Smrg    	swaps(&rep.sequenceNumber, n);
607706f2543Smrg        swapl(&rep.length, n);
608706f2543Smrg        swapl(&rep.screenCount, n);
609706f2543Smrg        for (i = 0; i < count; i++) {
610706f2543Smrg            swapl(&screens[i], n);
611706f2543Smrg            swapl(&windows[i], n);
612706f2543Smrg
613706f2543Smrg            swaps(&pos[i].x, n);
614706f2543Smrg            swaps(&pos[i].y, n);
615706f2543Smrg            swaps(&pos[i].width, n);
616706f2543Smrg            swaps(&pos[i].height, n);
617706f2543Smrg
618706f2543Smrg            swaps(&vis[i].x, n);
619706f2543Smrg            swaps(&vis[i].y, n);
620706f2543Smrg            swaps(&vis[i].width, n);
621706f2543Smrg            swaps(&vis[i].height, n);
622706f2543Smrg        }
623706f2543Smrg    }
624706f2543Smrg
625706f2543Smrg    dmxFlushPendingSyncs();
626706f2543Smrg
627706f2543Smrg    WriteToClient(client, sizeof(xDMXGetWindowAttributesReply), (char *)&rep);
628706f2543Smrg    if (count) {
629706f2543Smrg        WriteToClient(client, count * sizeof(*screens), (char *)screens);
630706f2543Smrg        WriteToClient(client, count * sizeof(*windows), (char *)windows);
631706f2543Smrg        WriteToClient(client, count * sizeof(*pos),     (char *)pos);
632706f2543Smrg        WriteToClient(client, count * sizeof(*vis),     (char *)vis);
633706f2543Smrg    }
634706f2543Smrg
635706f2543Smrg    free(vis);
636706f2543Smrg    free(pos);
637706f2543Smrg    free(windows);
638706f2543Smrg    free(screens);
639706f2543Smrg
640706f2543Smrg    return Success;
641706f2543Smrg}
642706f2543Smrg
643706f2543Smrgstatic int ProcDMXGetDesktopAttributes(ClientPtr client)
644706f2543Smrg{
645706f2543Smrg    xDMXGetDesktopAttributesReply rep;
646706f2543Smrg    int                           n;
647706f2543Smrg    DMXDesktopAttributesRec       attr;
648706f2543Smrg
649706f2543Smrg    REQUEST_SIZE_MATCH(xDMXGetDesktopAttributesReq);
650706f2543Smrg
651706f2543Smrg    dmxGetDesktopAttributes(&attr);
652706f2543Smrg
653706f2543Smrg    rep.width               = attr.width;
654706f2543Smrg    rep.height              = attr.height;
655706f2543Smrg    rep.shiftX              = attr.shiftX;
656706f2543Smrg    rep.shiftY              = attr.shiftY;
657706f2543Smrg
658706f2543Smrg    rep.type                = X_Reply;
659706f2543Smrg    rep.sequenceNumber      = client->sequence;
660706f2543Smrg    rep.length              = 0;
661706f2543Smrg
662706f2543Smrg    if (client->swapped) {
663706f2543Smrg    	swaps(&rep.sequenceNumber, n);
664706f2543Smrg        swapl(&rep.length, n);
665706f2543Smrg        swapl(&rep.width, n);
666706f2543Smrg        swapl(&rep.height, n);
667706f2543Smrg        swapl(&rep.shiftX, n);
668706f2543Smrg        swapl(&rep.shiftY, n);
669706f2543Smrg    }
670706f2543Smrg    WriteToClient(client, sizeof(xDMXGetDesktopAttributesReply), (char *)&rep);
671706f2543Smrg    return Success;
672706f2543Smrg}
673706f2543Smrg
674706f2543Smrgstatic int ProcDMXChangeDesktopAttributes(ClientPtr client)
675706f2543Smrg{
676706f2543Smrg    REQUEST(xDMXChangeDesktopAttributesReq);
677706f2543Smrg    xDMXChangeDesktopAttributesReply rep;
678706f2543Smrg    int                              n;
679706f2543Smrg    int                              status = DMX_BAD_XINERAMA;
680706f2543Smrg    CARD32                           *value_list;
681706f2543Smrg    DMXDesktopAttributesRec          attr;
682706f2543Smrg    int                              len;
683706f2543Smrg
684706f2543Smrg    REQUEST_AT_LEAST_SIZE(xDMXChangeDesktopAttributesReq);
685706f2543Smrg    len = client->req_len - (sizeof(xDMXChangeDesktopAttributesReq) >> 2);
686706f2543Smrg    if (len != Ones(stuff->valueMask))
687706f2543Smrg        return BadLength;
688706f2543Smrg
689706f2543Smrg    if (!_DMXXineramaActive()) goto noxinerama;
690706f2543Smrg
691706f2543Smrg    value_list = (CARD32 *)(stuff + 1);
692706f2543Smrg
693706f2543Smrg    dmxGetDesktopAttributes(&attr);
694706f2543Smrg    dmxFetchDesktopAttributes(stuff->valueMask, &attr, value_list);
695706f2543Smrg
696706f2543Smrg#if PANORAMIX
697706f2543Smrg    status = dmxConfigureDesktop(&attr);
698706f2543Smrg#endif
699706f2543Smrg    if (status == BadValue) return status;
700706f2543Smrg
701706f2543Smrg  noxinerama:
702706f2543Smrg    rep.type           = X_Reply;
703706f2543Smrg    rep.sequenceNumber = client->sequence;
704706f2543Smrg    rep.length         = 0;
705706f2543Smrg    rep.status         = status;
706706f2543Smrg    if (client->swapped) {
707706f2543Smrg        swaps(&rep.sequenceNumber, n);
708706f2543Smrg        swapl(&rep.length, n);
709706f2543Smrg        swapl(&rep.status, n);
710706f2543Smrg    }
711706f2543Smrg    WriteToClient(client,
712706f2543Smrg                  sizeof(xDMXChangeDesktopAttributesReply),
713706f2543Smrg                  (char *)&rep);
714706f2543Smrg    return Success;
715706f2543Smrg}
716706f2543Smrg
717706f2543Smrgstatic int ProcDMXGetInputCount(ClientPtr client)
718706f2543Smrg{
719706f2543Smrg    xDMXGetInputCountReply rep;
720706f2543Smrg    int                     n;
721706f2543Smrg
722706f2543Smrg    REQUEST_SIZE_MATCH(xDMXGetInputCountReq);
723706f2543Smrg
724706f2543Smrg    rep.type           = X_Reply;
725706f2543Smrg    rep.sequenceNumber = client->sequence;
726706f2543Smrg    rep.length         = 0;
727706f2543Smrg    rep.inputCount     = dmxGetInputCount();
728706f2543Smrg    if (client->swapped) {
729706f2543Smrg    	swaps(&rep.sequenceNumber, n);
730706f2543Smrg        swapl(&rep.length, n);
731706f2543Smrg        swapl(&rep.inputCount, n);
732706f2543Smrg    }
733706f2543Smrg    WriteToClient(client, sizeof(xDMXGetInputCountReply), (char *)&rep);
734706f2543Smrg    return Success;
735706f2543Smrg}
736706f2543Smrg
737706f2543Smrgstatic int ProcDMXGetInputAttributes(ClientPtr client)
738706f2543Smrg{
739706f2543Smrg    REQUEST(xDMXGetInputAttributesReq);
740706f2543Smrg    xDMXGetInputAttributesReply rep;
741706f2543Smrg    int                          n;
742706f2543Smrg    int                          length;
743706f2543Smrg    int                          paddedLength;
744706f2543Smrg    DMXInputAttributesRec        attr;
745706f2543Smrg
746706f2543Smrg    REQUEST_SIZE_MATCH(xDMXGetInputAttributesReq);
747706f2543Smrg
748706f2543Smrg    if (dmxGetInputAttributes(stuff->deviceId, &attr)) return BadValue;
749706f2543Smrg    rep.inputType      = attr.inputType;
750706f2543Smrg    rep.physicalScreen = attr.physicalScreen;
751706f2543Smrg    rep.physicalId     = attr.physicalId;
752706f2543Smrg    rep.isCore         = attr.isCore;
753706f2543Smrg    rep.sendsCore      = attr.sendsCore;
754706f2543Smrg    rep.detached       = attr.detached;
755706f2543Smrg
756706f2543Smrg    length             = attr.name ? strlen(attr.name) : 0;
757706f2543Smrg    paddedLength       = pad_to_int32(length);
758706f2543Smrg    rep.type           = X_Reply;
759706f2543Smrg    rep.sequenceNumber = client->sequence;
760706f2543Smrg    rep.length         = bytes_to_int32(paddedLength);
761706f2543Smrg    rep.nameLength     = length;
762706f2543Smrg    if (client->swapped) {
763706f2543Smrg    	swaps(&rep.sequenceNumber, n);
764706f2543Smrg        swapl(&rep.length, n);
765706f2543Smrg        swapl(&rep.inputType, n);
766706f2543Smrg        swapl(&rep.physicalScreen, n);
767706f2543Smrg        swapl(&rep.physicalId, n);
768706f2543Smrg        swapl(&rep.nameLength, n);
769706f2543Smrg    }
770706f2543Smrg    WriteToClient(client, sizeof(xDMXGetInputAttributesReply), (char *)&rep);
771706f2543Smrg    if (length) WriteToClient(client, length, (char *)attr.name);
772706f2543Smrg    return Success;
773706f2543Smrg}
774706f2543Smrg
775706f2543Smrgstatic int ProcDMXAddInput(ClientPtr client)
776706f2543Smrg{
777706f2543Smrg    REQUEST(xDMXAddInputReq);
778706f2543Smrg    xDMXAddInputReply      rep;
779706f2543Smrg    int                    n;
780706f2543Smrg    int                    status = 0;
781706f2543Smrg    CARD32                 *value_list;
782706f2543Smrg    DMXInputAttributesRec  attr;
783706f2543Smrg    int                    count;
784706f2543Smrg    char                   *name;
785706f2543Smrg    int                    len;
786706f2543Smrg    int                    paddedLength;
787706f2543Smrg    int                    id     = -1;
788706f2543Smrg
789706f2543Smrg    REQUEST_AT_LEAST_SIZE(xDMXAddInputReq);
790706f2543Smrg    paddedLength = pad_to_int32(stuff->displayNameLength);
791706f2543Smrg    len          = client->req_len - (sizeof(xDMXAddInputReq) >> 2);
792706f2543Smrg    if (len != Ones(stuff->valueMask) + paddedLength/4)
793706f2543Smrg        return BadLength;
794706f2543Smrg
795706f2543Smrg    memset(&attr, 0, sizeof(attr));
796706f2543Smrg    value_list = (CARD32 *)(stuff + 1);
797706f2543Smrg    count      = dmxFetchInputAttributes(stuff->valueMask, &attr, value_list);
798706f2543Smrg
799706f2543Smrg    if (!(name = malloc(stuff->displayNameLength + 1 + 4)))
800706f2543Smrg        return BadAlloc;
801706f2543Smrg    memcpy(name, &value_list[count], stuff->displayNameLength);
802706f2543Smrg    name[stuff->displayNameLength] = '\0';
803706f2543Smrg    attr.name = name;
804706f2543Smrg
805706f2543Smrg    status = dmxAddInput(&attr, &id);
806706f2543Smrg
807706f2543Smrg    free(name);
808706f2543Smrg
809706f2543Smrg    if (status) return status;
810706f2543Smrg
811706f2543Smrg    rep.type           = X_Reply;
812706f2543Smrg    rep.sequenceNumber = client->sequence;
813706f2543Smrg    rep.length         = 0;
814706f2543Smrg    rep.status         = status;
815706f2543Smrg    rep.physicalId     = id;
816706f2543Smrg    if (client->swapped) {
817706f2543Smrg        swaps(&rep.sequenceNumber, n);
818706f2543Smrg        swapl(&rep.length, n);
819706f2543Smrg        swapl(&rep.status, n);
820706f2543Smrg        swapl(&rep.physicalId, n);
821706f2543Smrg    }
822706f2543Smrg    WriteToClient(client, sizeof(xDMXAddInputReply), (char *)&rep);
823706f2543Smrg    return Success;
824706f2543Smrg}
825706f2543Smrg
826706f2543Smrgstatic int ProcDMXRemoveInput(ClientPtr client)
827706f2543Smrg{
828706f2543Smrg    REQUEST(xDMXRemoveInputReq);
829706f2543Smrg    xDMXRemoveInputReply     rep;
830706f2543Smrg    int                      n;
831706f2543Smrg    int                      status = 0;
832706f2543Smrg
833706f2543Smrg    REQUEST_SIZE_MATCH(xDMXRemoveInputReq);
834706f2543Smrg
835706f2543Smrg    status = dmxRemoveInput(stuff->physicalId);
836706f2543Smrg
837706f2543Smrg    if (status) return status;
838706f2543Smrg
839706f2543Smrg    rep.type           = X_Reply;
840706f2543Smrg    rep.sequenceNumber = client->sequence;
841706f2543Smrg    rep.length         = 0;
842706f2543Smrg    rep.status         = status;
843706f2543Smrg    if (client->swapped) {
844706f2543Smrg        swaps(&rep.sequenceNumber, n);
845706f2543Smrg        swapl(&rep.length, n);
846706f2543Smrg        swapl(&rep.status, n);
847706f2543Smrg    }
848706f2543Smrg    WriteToClient(client, sizeof(xDMXRemoveInputReply), (char *)&rep);
849706f2543Smrg    return Success;
850706f2543Smrg}
851706f2543Smrg
852706f2543Smrgstatic int ProcDMXDispatch(ClientPtr client)
853706f2543Smrg{
854706f2543Smrg    REQUEST(xReq);
855706f2543Smrg
856706f2543Smrg    switch (stuff->data) {
857706f2543Smrg    case X_DMXQueryVersion:         return ProcDMXQueryVersion(client);
858706f2543Smrg    case X_DMXSync:                 return ProcDMXSync(client);
859706f2543Smrg    case X_DMXForceWindowCreation:  return ProcDMXForceWindowCreation(client);
860706f2543Smrg    case X_DMXGetScreenCount:       return ProcDMXGetScreenCount(client);
861706f2543Smrg    case X_DMXGetScreenAttributes:  return ProcDMXGetScreenAttributes(client);
862706f2543Smrg    case X_DMXChangeScreensAttributes:
863706f2543Smrg        return ProcDMXChangeScreensAttributes(client);
864706f2543Smrg    case X_DMXAddScreen:            return ProcDMXAddScreen(client);
865706f2543Smrg    case X_DMXRemoveScreen:         return ProcDMXRemoveScreen(client);
866706f2543Smrg    case X_DMXGetWindowAttributes:  return ProcDMXGetWindowAttributes(client);
867706f2543Smrg    case X_DMXGetDesktopAttributes: return ProcDMXGetDesktopAttributes(client);
868706f2543Smrg    case X_DMXChangeDesktopAttributes:
869706f2543Smrg        return ProcDMXChangeDesktopAttributes(client);
870706f2543Smrg    case X_DMXGetInputCount:        return ProcDMXGetInputCount(client);
871706f2543Smrg    case X_DMXGetInputAttributes:   return ProcDMXGetInputAttributes(client);
872706f2543Smrg    case X_DMXAddInput:             return ProcDMXAddInput(client);
873706f2543Smrg    case X_DMXRemoveInput:          return ProcDMXRemoveInput(client);
874706f2543Smrg
875706f2543Smrg    case X_DMXGetScreenInformationDEPRECATED:
876706f2543Smrg    case X_DMXForceWindowCreationDEPRECATED:
877706f2543Smrg    case X_DMXReconfigureScreenDEPRECATED:
878706f2543Smrg        return BadImplementation;
879706f2543Smrg
880706f2543Smrg    default:                        return BadRequest;
881706f2543Smrg    }
882706f2543Smrg}
883706f2543Smrg
884706f2543Smrgstatic int SProcDMXQueryVersion(ClientPtr client)
885706f2543Smrg{
886706f2543Smrg    int n;
887706f2543Smrg    REQUEST(xDMXQueryVersionReq);
888706f2543Smrg
889706f2543Smrg    swaps(&stuff->length, n);
890706f2543Smrg    REQUEST_SIZE_MATCH(xDMXQueryVersionReq);
891706f2543Smrg    return ProcDMXQueryVersion(client);
892706f2543Smrg}
893706f2543Smrg
894706f2543Smrgstatic int SProcDMXSync(ClientPtr client)
895706f2543Smrg{
896706f2543Smrg    int n;
897706f2543Smrg    REQUEST(xDMXSyncReq);
898706f2543Smrg
899706f2543Smrg    swaps(&stuff->length, n);
900706f2543Smrg    REQUEST_SIZE_MATCH(xDMXSyncReq);
901706f2543Smrg    return ProcDMXSync(client);
902706f2543Smrg}
903706f2543Smrg
904706f2543Smrgstatic int SProcDMXForceWindowCreation(ClientPtr client)
905706f2543Smrg{
906706f2543Smrg    int n;
907706f2543Smrg    REQUEST(xDMXForceWindowCreationReq);
908706f2543Smrg
909706f2543Smrg    swaps(&stuff->length, n);
910706f2543Smrg    REQUEST_SIZE_MATCH(xDMXForceWindowCreationReq);
911706f2543Smrg    swaps(&stuff->window, n);
912706f2543Smrg    return ProcDMXForceWindowCreation(client);
913706f2543Smrg}
914706f2543Smrg
915706f2543Smrgstatic int SProcDMXGetScreenCount(ClientPtr client)
916706f2543Smrg{
917706f2543Smrg    int n;
918706f2543Smrg    REQUEST(xDMXGetScreenCountReq);
919706f2543Smrg
920706f2543Smrg    swaps(&stuff->length, n);
921706f2543Smrg    REQUEST_SIZE_MATCH(xDMXGetScreenCountReq);
922706f2543Smrg    return ProcDMXGetScreenCount(client);
923706f2543Smrg}
924706f2543Smrg
925706f2543Smrgstatic int SProcDMXGetScreenAttributes(ClientPtr client)
926706f2543Smrg{
927706f2543Smrg    int n;
928706f2543Smrg    REQUEST(xDMXGetScreenAttributesReq);
929706f2543Smrg
930706f2543Smrg    swaps(&stuff->length, n);
931706f2543Smrg    REQUEST_SIZE_MATCH(xDMXGetScreenAttributesReq);
932706f2543Smrg    swapl(&stuff->physicalScreen, n);
933706f2543Smrg    return ProcDMXGetScreenAttributes(client);
934706f2543Smrg}
935706f2543Smrg
936706f2543Smrgstatic int SProcDMXChangeScreensAttributes(ClientPtr client)
937706f2543Smrg{
938706f2543Smrg    int n;
939706f2543Smrg    REQUEST(xDMXChangeScreensAttributesReq);
940706f2543Smrg
941706f2543Smrg    swaps(&stuff->length, n);
942706f2543Smrg    REQUEST_AT_LEAST_SIZE(xDMXGetScreenAttributesReq);
943706f2543Smrg    swapl(&stuff->screenCount, n);
944706f2543Smrg    swapl(&stuff->maskCount, n);
945706f2543Smrg    SwapRestL(stuff);
946706f2543Smrg    return ProcDMXGetScreenAttributes(client);
947706f2543Smrg}
948706f2543Smrg
949706f2543Smrgstatic int SProcDMXAddScreen(ClientPtr client)
950706f2543Smrg{
951706f2543Smrg    int n;
952706f2543Smrg    int paddedLength;
953706f2543Smrg    REQUEST(xDMXAddScreenReq);
954706f2543Smrg
955706f2543Smrg    swaps(&stuff->length, n);
956706f2543Smrg    REQUEST_AT_LEAST_SIZE(xDMXAddScreenReq);
957706f2543Smrg    swapl(&stuff->displayNameLength, n);
958706f2543Smrg    swapl(&stuff->valueMask, n);
959706f2543Smrg    paddedLength = pad_to_int32(stuff->displayNameLength);
960706f2543Smrg    SwapLongs((CARD32 *)(stuff+1), LengthRestL(stuff) - paddedLength/4);
961706f2543Smrg    return ProcDMXAddScreen(client);
962706f2543Smrg}
963706f2543Smrg
964706f2543Smrgstatic int SProcDMXRemoveScreen(ClientPtr client)
965706f2543Smrg{
966706f2543Smrg    int n;
967706f2543Smrg    REQUEST(xDMXRemoveScreenReq);
968706f2543Smrg
969706f2543Smrg    swaps(&stuff->length, n);
970706f2543Smrg    REQUEST_SIZE_MATCH(xDMXRemoveScreenReq);
971706f2543Smrg    swapl(&stuff->physicalScreen, n);
972706f2543Smrg    return ProcDMXRemoveScreen(client);
973706f2543Smrg}
974706f2543Smrg
975706f2543Smrgstatic int SProcDMXGetWindowAttributes(ClientPtr client)
976706f2543Smrg{
977706f2543Smrg    int n;
978706f2543Smrg    REQUEST(xDMXGetWindowAttributesReq);
979706f2543Smrg
980706f2543Smrg    swaps(&stuff->length, n);
981706f2543Smrg    REQUEST_SIZE_MATCH(xDMXGetWindowAttributesReq);
982706f2543Smrg    swapl(&stuff->window, n);
983706f2543Smrg    return ProcDMXGetWindowAttributes(client);
984706f2543Smrg}
985706f2543Smrg
986706f2543Smrgstatic int SProcDMXGetDesktopAttributes(ClientPtr client)
987706f2543Smrg{
988706f2543Smrg    int n;
989706f2543Smrg    REQUEST(xDMXGetDesktopAttributesReq);
990706f2543Smrg
991706f2543Smrg    swaps(&stuff->length, n);
992706f2543Smrg    REQUEST_SIZE_MATCH(xDMXGetDesktopAttributesReq);
993706f2543Smrg    return ProcDMXGetDesktopAttributes(client);
994706f2543Smrg}
995706f2543Smrg
996706f2543Smrgstatic int SProcDMXChangeDesktopAttributes(ClientPtr client)
997706f2543Smrg{
998706f2543Smrg    int n;
999706f2543Smrg    REQUEST(xDMXChangeDesktopAttributesReq);
1000706f2543Smrg
1001706f2543Smrg    swaps(&stuff->length, n);
1002706f2543Smrg    REQUEST_AT_LEAST_SIZE(xDMXChangeDesktopAttributesReq);
1003706f2543Smrg    swapl(&stuff->valueMask, n);
1004706f2543Smrg    SwapRestL(stuff);
1005706f2543Smrg    return ProcDMXChangeDesktopAttributes(client);
1006706f2543Smrg}
1007706f2543Smrg
1008706f2543Smrgstatic int SProcDMXGetInputCount(ClientPtr client)
1009706f2543Smrg{
1010706f2543Smrg    int n;
1011706f2543Smrg    REQUEST(xDMXGetInputCountReq);
1012706f2543Smrg
1013706f2543Smrg    swaps(&stuff->length, n);
1014706f2543Smrg    REQUEST_SIZE_MATCH(xDMXGetInputCountReq);
1015706f2543Smrg    return ProcDMXGetInputCount(client);
1016706f2543Smrg}
1017706f2543Smrg
1018706f2543Smrgstatic int SProcDMXGetInputAttributes(ClientPtr client)
1019706f2543Smrg{
1020706f2543Smrg    int n;
1021706f2543Smrg    REQUEST(xDMXGetInputAttributesReq);
1022706f2543Smrg
1023706f2543Smrg    swaps(&stuff->length, n);
1024706f2543Smrg    REQUEST_SIZE_MATCH(xDMXGetInputAttributesReq);
1025706f2543Smrg    swapl(&stuff->deviceId, n);
1026706f2543Smrg    return ProcDMXGetInputAttributes(client);
1027706f2543Smrg}
1028706f2543Smrg
1029706f2543Smrgstatic int SProcDMXAddInput(ClientPtr client)
1030706f2543Smrg{
1031706f2543Smrg    int n;
1032706f2543Smrg    int paddedLength;
1033706f2543Smrg    REQUEST(xDMXAddInputReq);
1034706f2543Smrg
1035706f2543Smrg    swaps(&stuff->length, n);
1036706f2543Smrg    REQUEST_AT_LEAST_SIZE(xDMXAddInputReq);
1037706f2543Smrg    swapl(&stuff->displayNameLength, n);
1038706f2543Smrg    swapl(&stuff->valueMask, n);
1039706f2543Smrg    paddedLength = pad_to_int32(stuff->displayNameLength);
1040706f2543Smrg    SwapLongs((CARD32 *)(stuff+1), LengthRestL(stuff) - paddedLength/4);
1041706f2543Smrg    return ProcDMXAddInput(client);
1042706f2543Smrg}
1043706f2543Smrg
1044706f2543Smrgstatic int SProcDMXRemoveInput(ClientPtr client)
1045706f2543Smrg{
1046706f2543Smrg    int n;
1047706f2543Smrg    REQUEST(xDMXRemoveInputReq);
1048706f2543Smrg
1049706f2543Smrg    swaps(&stuff->length, n);
1050706f2543Smrg    REQUEST_SIZE_MATCH(xDMXRemoveInputReq);
1051706f2543Smrg    swapl(&stuff->physicalId, n);
1052706f2543Smrg    return ProcDMXRemoveInput(client);
1053706f2543Smrg}
1054706f2543Smrg
1055706f2543Smrgstatic int SProcDMXDispatch (ClientPtr client)
1056706f2543Smrg{
1057706f2543Smrg    REQUEST(xReq);
1058706f2543Smrg
1059706f2543Smrg    switch (stuff->data) {
1060706f2543Smrg    case X_DMXQueryVersion:         return SProcDMXQueryVersion(client);
1061706f2543Smrg    case X_DMXSync:                 return SProcDMXSync(client);
1062706f2543Smrg    case X_DMXForceWindowCreation:  return SProcDMXForceWindowCreation(client);
1063706f2543Smrg    case X_DMXGetScreenCount:       return SProcDMXGetScreenCount(client);
1064706f2543Smrg    case X_DMXGetScreenAttributes:  return SProcDMXGetScreenAttributes(client);
1065706f2543Smrg    case X_DMXChangeScreensAttributes:
1066706f2543Smrg        return SProcDMXChangeScreensAttributes(client);
1067706f2543Smrg    case X_DMXAddScreen:            return SProcDMXAddScreen(client);
1068706f2543Smrg    case X_DMXRemoveScreen:         return SProcDMXRemoveScreen(client);
1069706f2543Smrg    case X_DMXGetWindowAttributes:  return SProcDMXGetWindowAttributes(client);
1070706f2543Smrg    case X_DMXGetDesktopAttributes:
1071706f2543Smrg        return SProcDMXGetDesktopAttributes(client);
1072706f2543Smrg    case X_DMXChangeDesktopAttributes:
1073706f2543Smrg        return SProcDMXChangeDesktopAttributes(client);
1074706f2543Smrg    case X_DMXGetInputCount:        return SProcDMXGetInputCount(client);
1075706f2543Smrg    case X_DMXGetInputAttributes:   return SProcDMXGetInputAttributes(client);
1076706f2543Smrg    case X_DMXAddInput:             return SProcDMXAddInput(client);
1077706f2543Smrg    case X_DMXRemoveInput:          return SProcDMXRemoveInput(client);
1078706f2543Smrg
1079706f2543Smrg    case X_DMXGetScreenInformationDEPRECATED:
1080706f2543Smrg    case X_DMXForceWindowCreationDEPRECATED:
1081706f2543Smrg    case X_DMXReconfigureScreenDEPRECATED:
1082706f2543Smrg        return BadImplementation;
1083706f2543Smrg
1084706f2543Smrg    default:                        return BadRequest;
1085706f2543Smrg    }
1086706f2543Smrg}
1087706f2543Smrg
1088706f2543Smrg/** Initialize the extension. */
1089706f2543Smrgvoid DMXExtensionInit(void)
1090706f2543Smrg{
1091706f2543Smrg    ExtensionEntry *extEntry;
1092706f2543Smrg
1093706f2543Smrg    if ((extEntry = AddExtension(DMX_EXTENSION_NAME, 0, 0,
1094706f2543Smrg                                 ProcDMXDispatch, SProcDMXDispatch,
1095706f2543Smrg                                 NULL, StandardMinorOpcode)))
1096706f2543Smrg	DMXCode = extEntry->base;
1097706f2543Smrg}
1098