xcmisc.c revision 7e31ba66
1/*
2
3Copyright 1993, 1998  The Open Group
4
5Permission to use, copy, modify, distribute, and sell this software and its
6documentation for any purpose is hereby granted without fee, provided that
7the above copyright notice appear in all copies and that both that
8copyright notice and this permission notice appear in supporting
9documentation.
10
11The above copyright notice and this permission notice shall be included
12in all copies or substantial portions of the Software.
13
14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
15OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
16MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
17IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR
18OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
19ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
20OTHER DEALINGS IN THE SOFTWARE.
21
22Except as contained in this notice, the name of The Open Group shall
23not be used in advertising or otherwise to promote the sale, use or
24other dealings in this Software without prior written authorization
25from The Open Group.
26
27*/
28
29#ifdef HAVE_DIX_CONFIG_H
30#include <dix-config.h>
31#endif
32
33#include <X11/X.h>
34#include <X11/Xproto.h>
35#include "misc.h"
36#include "os.h"
37#include "dixstruct.h"
38#include "extnsionst.h"
39#include "swaprep.h"
40#include <X11/extensions/xcmiscproto.h>
41#include "extinit.h"
42
43#include <stdint.h>
44
45static int
46ProcXCMiscGetVersion(ClientPtr client)
47{
48    xXCMiscGetVersionReply rep = {
49        .type = X_Reply,
50        .sequenceNumber = client->sequence,
51        .length = 0,
52        .majorVersion = XCMiscMajorVersion,
53        .minorVersion = XCMiscMinorVersion
54    };
55
56    REQUEST_SIZE_MATCH(xXCMiscGetVersionReq);
57
58    if (client->swapped) {
59        swaps(&rep.sequenceNumber);
60        swaps(&rep.majorVersion);
61        swaps(&rep.minorVersion);
62    }
63    WriteToClient(client, sizeof(xXCMiscGetVersionReply), &rep);
64    return Success;
65}
66
67static int
68ProcXCMiscGetXIDRange(ClientPtr client)
69{
70    xXCMiscGetXIDRangeReply rep;
71    XID min_id, max_id;
72
73    REQUEST_SIZE_MATCH(xXCMiscGetXIDRangeReq);
74    GetXIDRange(client->index, FALSE, &min_id, &max_id);
75    rep = (xXCMiscGetXIDRangeReply) {
76        .type = X_Reply,
77        .sequenceNumber = client->sequence,
78        .length = 0,
79        .start_id = min_id,
80        .count = max_id - min_id + 1
81    };
82    if (client->swapped) {
83        swaps(&rep.sequenceNumber);
84        swapl(&rep.start_id);
85        swapl(&rep.count);
86    }
87    WriteToClient(client, sizeof(xXCMiscGetXIDRangeReply), &rep);
88    return Success;
89}
90
91static int
92ProcXCMiscGetXIDList(ClientPtr client)
93{
94    REQUEST(xXCMiscGetXIDListReq);
95    xXCMiscGetXIDListReply rep;
96    XID *pids;
97    unsigned int count;
98
99    REQUEST_SIZE_MATCH(xXCMiscGetXIDListReq);
100
101    if (stuff->count > UINT32_MAX / sizeof(XID))
102        return BadAlloc;
103
104    pids = xallocarray(stuff->count, sizeof(XID));
105    if (!pids) {
106        return BadAlloc;
107    }
108    count = GetXIDList(client, stuff->count, pids);
109    rep = (xXCMiscGetXIDListReply) {
110        .type = X_Reply,
111        .sequenceNumber = client->sequence,
112        .length = count,
113        .count = count
114    };
115    if (client->swapped) {
116        swaps(&rep.sequenceNumber);
117        swapl(&rep.length);
118        swapl(&rep.count);
119    }
120    WriteToClient(client, sizeof(xXCMiscGetXIDListReply), &rep);
121    if (count) {
122        client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
123        WriteSwappedDataToClient(client, count * sizeof(XID), pids);
124    }
125    free(pids);
126    return Success;
127}
128
129static int
130ProcXCMiscDispatch(ClientPtr client)
131{
132    REQUEST(xReq);
133    switch (stuff->data) {
134    case X_XCMiscGetVersion:
135        return ProcXCMiscGetVersion(client);
136    case X_XCMiscGetXIDRange:
137        return ProcXCMiscGetXIDRange(client);
138    case X_XCMiscGetXIDList:
139        return ProcXCMiscGetXIDList(client);
140    default:
141        return BadRequest;
142    }
143}
144
145static int _X_COLD
146SProcXCMiscGetVersion(ClientPtr client)
147{
148    REQUEST(xXCMiscGetVersionReq);
149
150    swaps(&stuff->length);
151    REQUEST_SIZE_MATCH(xXCMiscGetVersionReq);
152    swaps(&stuff->majorVersion);
153    swaps(&stuff->minorVersion);
154    return ProcXCMiscGetVersion(client);
155}
156
157static int _X_COLD
158SProcXCMiscGetXIDRange(ClientPtr client)
159{
160    REQUEST(xReq);
161
162    swaps(&stuff->length);
163    return ProcXCMiscGetXIDRange(client);
164}
165
166static int _X_COLD
167SProcXCMiscGetXIDList(ClientPtr client)
168{
169    REQUEST(xXCMiscGetXIDListReq);
170    REQUEST_SIZE_MATCH(xXCMiscGetXIDListReq);
171
172    swaps(&stuff->length);
173    swapl(&stuff->count);
174    return ProcXCMiscGetXIDList(client);
175}
176
177static int _X_COLD
178SProcXCMiscDispatch(ClientPtr client)
179{
180    REQUEST(xReq);
181    switch (stuff->data) {
182    case X_XCMiscGetVersion:
183        return SProcXCMiscGetVersion(client);
184    case X_XCMiscGetXIDRange:
185        return SProcXCMiscGetXIDRange(client);
186    case X_XCMiscGetXIDList:
187        return SProcXCMiscGetXIDList(client);
188    default:
189        return BadRequest;
190    }
191}
192
193void
194XCMiscExtensionInit(void)
195{
196    AddExtension(XCMiscExtensionName, 0, 0,
197                 ProcXCMiscDispatch, SProcXCMiscDispatch,
198                 NULL, StandardMinorOpcode);
199}
200