1*4882a593Smuzhiyun /************************************************************
2*4882a593Smuzhiyun
3*4882a593Smuzhiyun Copyright 1987, 1989, 1998 The Open Group
4*4882a593Smuzhiyun
5*4882a593Smuzhiyun Permission to use, copy, modify, distribute, and sell this software and its
6*4882a593Smuzhiyun documentation for any purpose is hereby granted without fee, provided that
7*4882a593Smuzhiyun the above copyright notice appear in all copies and that both that
8*4882a593Smuzhiyun copyright notice and this permission notice appear in supporting
9*4882a593Smuzhiyun documentation.
10*4882a593Smuzhiyun
11*4882a593Smuzhiyun The above copyright notice and this permission notice shall be included in
12*4882a593Smuzhiyun all copies or substantial portions of the Software.
13*4882a593Smuzhiyun
14*4882a593Smuzhiyun THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15*4882a593Smuzhiyun IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16*4882a593Smuzhiyun FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17*4882a593Smuzhiyun OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
18*4882a593Smuzhiyun AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
19*4882a593Smuzhiyun CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
20*4882a593Smuzhiyun
21*4882a593Smuzhiyun Except as contained in this notice, the name of The Open Group shall not be
22*4882a593Smuzhiyun used in advertising or otherwise to promote the sale, use or other dealings
23*4882a593Smuzhiyun in this Software without prior written authorization from The Open Group.
24*4882a593Smuzhiyun
25*4882a593Smuzhiyun Copyright 1987, 1989 by Digital Equipment Corporation, Maynard, Massachusetts.
26*4882a593Smuzhiyun
27*4882a593Smuzhiyun All Rights Reserved
28*4882a593Smuzhiyun
29*4882a593Smuzhiyun Permission to use, copy, modify, and distribute this software and its
30*4882a593Smuzhiyun documentation for any purpose and without fee is hereby granted,
31*4882a593Smuzhiyun provided that the above copyright notice appear in all copies and that
32*4882a593Smuzhiyun both that copyright notice and this permission notice appear in
33*4882a593Smuzhiyun supporting documentation, and that the name of Digital not be
34*4882a593Smuzhiyun used in advertising or publicity pertaining to distribution of the
35*4882a593Smuzhiyun software without specific, written prior permission.
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
38*4882a593Smuzhiyun ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
39*4882a593Smuzhiyun DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
40*4882a593Smuzhiyun ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
41*4882a593Smuzhiyun WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
42*4882a593Smuzhiyun ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
43*4882a593Smuzhiyun SOFTWARE.
44*4882a593Smuzhiyun
45*4882a593Smuzhiyun ********************************************************/
46*4882a593Smuzhiyun
47*4882a593Smuzhiyun /* The panoramix components contained the following notice */
48*4882a593Smuzhiyun /*****************************************************************
49*4882a593Smuzhiyun
50*4882a593Smuzhiyun Copyright (c) 1991, 1997 Digital Equipment Corporation, Maynard, Massachusetts.
51*4882a593Smuzhiyun
52*4882a593Smuzhiyun Permission is hereby granted, free of charge, to any person obtaining a copy
53*4882a593Smuzhiyun of this software and associated documentation files (the "Software"), to deal
54*4882a593Smuzhiyun in the Software without restriction, including without limitation the rights
55*4882a593Smuzhiyun to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
56*4882a593Smuzhiyun copies of the Software.
57*4882a593Smuzhiyun
58*4882a593Smuzhiyun The above copyright notice and this permission notice shall be included in
59*4882a593Smuzhiyun all copies or substantial portions of the Software.
60*4882a593Smuzhiyun
61*4882a593Smuzhiyun THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
62*4882a593Smuzhiyun IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
63*4882a593Smuzhiyun FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
64*4882a593Smuzhiyun DIGITAL EQUIPMENT CORPORATION BE LIABLE FOR ANY CLAIM, DAMAGES, INCLUDING,
65*4882a593Smuzhiyun BUT NOT LIMITED TO CONSEQUENTIAL OR INCIDENTAL DAMAGES, OR OTHER LIABILITY,
66*4882a593Smuzhiyun WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
67*4882a593Smuzhiyun IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
68*4882a593Smuzhiyun
69*4882a593Smuzhiyun Except as contained in this notice, the name of Digital Equipment Corporation
70*4882a593Smuzhiyun shall not be used in advertising or otherwise to promote the sale, use or other
71*4882a593Smuzhiyun dealings in this Software without prior written authorization from Digital
72*4882a593Smuzhiyun Equipment Corporation.
73*4882a593Smuzhiyun
74*4882a593Smuzhiyun ******************************************************************/
75*4882a593Smuzhiyun
76*4882a593Smuzhiyun /* XSERVER_DTRACE additions:
77*4882a593Smuzhiyun * Copyright (c) 2005-2006, Oracle and/or its affiliates. All rights reserved.
78*4882a593Smuzhiyun *
79*4882a593Smuzhiyun * Permission is hereby granted, free of charge, to any person obtaining a
80*4882a593Smuzhiyun * copy of this software and associated documentation files (the "Software"),
81*4882a593Smuzhiyun * to deal in the Software without restriction, including without limitation
82*4882a593Smuzhiyun * the rights to use, copy, modify, merge, publish, distribute, sublicense,
83*4882a593Smuzhiyun * and/or sell copies of the Software, and to permit persons to whom the
84*4882a593Smuzhiyun * Software is furnished to do so, subject to the following conditions:
85*4882a593Smuzhiyun *
86*4882a593Smuzhiyun * The above copyright notice and this permission notice (including the next
87*4882a593Smuzhiyun * paragraph) shall be included in all copies or substantial portions of the
88*4882a593Smuzhiyun * Software.
89*4882a593Smuzhiyun *
90*4882a593Smuzhiyun * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
91*4882a593Smuzhiyun * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
92*4882a593Smuzhiyun * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
93*4882a593Smuzhiyun * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
94*4882a593Smuzhiyun * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
95*4882a593Smuzhiyun * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
96*4882a593Smuzhiyun * DEALINGS IN THE SOFTWARE.
97*4882a593Smuzhiyun */
98*4882a593Smuzhiyun
99*4882a593Smuzhiyun #ifdef HAVE_DIX_CONFIG_H
100*4882a593Smuzhiyun #include <dix-config.h>
101*4882a593Smuzhiyun #include <version-config.h>
102*4882a593Smuzhiyun #endif
103*4882a593Smuzhiyun
104*4882a593Smuzhiyun #ifdef PANORAMIX_DEBUG
105*4882a593Smuzhiyun #include <stdio.h>
106*4882a593Smuzhiyun int ProcInitialConnection();
107*4882a593Smuzhiyun #endif
108*4882a593Smuzhiyun
109*4882a593Smuzhiyun #include "windowstr.h"
110*4882a593Smuzhiyun #include <X11/fonts/fontstruct.h>
111*4882a593Smuzhiyun #include <X11/fonts/libxfont2.h>
112*4882a593Smuzhiyun #include "dixfontstr.h"
113*4882a593Smuzhiyun #include "gcstruct.h"
114*4882a593Smuzhiyun #include "selection.h"
115*4882a593Smuzhiyun #include "colormapst.h"
116*4882a593Smuzhiyun #include "cursorstr.h"
117*4882a593Smuzhiyun #include "scrnintstr.h"
118*4882a593Smuzhiyun #include "opaque.h"
119*4882a593Smuzhiyun #include "input.h"
120*4882a593Smuzhiyun #include "servermd.h"
121*4882a593Smuzhiyun #include "extnsionst.h"
122*4882a593Smuzhiyun #include "dixfont.h"
123*4882a593Smuzhiyun #include "dispatch.h"
124*4882a593Smuzhiyun #include "swaprep.h"
125*4882a593Smuzhiyun #include "swapreq.h"
126*4882a593Smuzhiyun #include "privates.h"
127*4882a593Smuzhiyun #include "xace.h"
128*4882a593Smuzhiyun #include "inputstr.h"
129*4882a593Smuzhiyun #include "xkbsrv.h"
130*4882a593Smuzhiyun #include "site.h"
131*4882a593Smuzhiyun #include "client.h"
132*4882a593Smuzhiyun
133*4882a593Smuzhiyun #ifdef XSERVER_DTRACE
134*4882a593Smuzhiyun #include "registry.h"
135*4882a593Smuzhiyun #include "probes.h"
136*4882a593Smuzhiyun #endif
137*4882a593Smuzhiyun
138*4882a593Smuzhiyun #define mskcnt ((MAXCLIENTS + 31) / 32)
139*4882a593Smuzhiyun #define BITMASK(i) (1U << ((i) & 31))
140*4882a593Smuzhiyun #define MASKIDX(i) ((i) >> 5)
141*4882a593Smuzhiyun #define MASKWORD(buf, i) buf[MASKIDX(i)]
142*4882a593Smuzhiyun #define BITSET(buf, i) MASKWORD(buf, i) |= BITMASK(i)
143*4882a593Smuzhiyun #define BITCLEAR(buf, i) MASKWORD(buf, i) &= ~BITMASK(i)
144*4882a593Smuzhiyun #define GETBIT(buf, i) (MASKWORD(buf, i) & BITMASK(i))
145*4882a593Smuzhiyun
146*4882a593Smuzhiyun xConnSetupPrefix connSetupPrefix;
147*4882a593Smuzhiyun
148*4882a593Smuzhiyun PaddingInfo PixmapWidthPaddingInfo[33];
149*4882a593Smuzhiyun
150*4882a593Smuzhiyun static ClientPtr grabClient;
151*4882a593Smuzhiyun
152*4882a593Smuzhiyun #define GrabNone 0
153*4882a593Smuzhiyun #define GrabActive 1
154*4882a593Smuzhiyun static int grabState = GrabNone;
155*4882a593Smuzhiyun static long grabWaiters[mskcnt];
156*4882a593Smuzhiyun CallbackListPtr ServerGrabCallback = NULL;
157*4882a593Smuzhiyun HWEventQueuePtr checkForInput[2];
158*4882a593Smuzhiyun int connBlockScreenStart;
159*4882a593Smuzhiyun
160*4882a593Smuzhiyun static void KillAllClients(void);
161*4882a593Smuzhiyun
162*4882a593Smuzhiyun static int nextFreeClientID; /* always MIN free client ID */
163*4882a593Smuzhiyun
164*4882a593Smuzhiyun static int nClients; /* number of authorized clients */
165*4882a593Smuzhiyun
166*4882a593Smuzhiyun CallbackListPtr ClientStateCallback;
167*4882a593Smuzhiyun
168*4882a593Smuzhiyun /* dispatchException & isItTimeToYield must be declared volatile since they
169*4882a593Smuzhiyun * are modified by signal handlers - otherwise optimizer may assume it doesn't
170*4882a593Smuzhiyun * need to actually check value in memory when used and may miss changes from
171*4882a593Smuzhiyun * signal handlers.
172*4882a593Smuzhiyun */
173*4882a593Smuzhiyun volatile char dispatchException = 0;
174*4882a593Smuzhiyun volatile char isItTimeToYield;
175*4882a593Smuzhiyun
176*4882a593Smuzhiyun #define SAME_SCREENS(a, b) (\
177*4882a593Smuzhiyun (a.pScreen == b.pScreen))
178*4882a593Smuzhiyun
179*4882a593Smuzhiyun void
SetInputCheck(HWEventQueuePtr c0,HWEventQueuePtr c1)180*4882a593Smuzhiyun SetInputCheck(HWEventQueuePtr c0, HWEventQueuePtr c1)
181*4882a593Smuzhiyun {
182*4882a593Smuzhiyun checkForInput[0] = c0;
183*4882a593Smuzhiyun checkForInput[1] = c1;
184*4882a593Smuzhiyun }
185*4882a593Smuzhiyun
186*4882a593Smuzhiyun void
UpdateCurrentTime(void)187*4882a593Smuzhiyun UpdateCurrentTime(void)
188*4882a593Smuzhiyun {
189*4882a593Smuzhiyun TimeStamp systime;
190*4882a593Smuzhiyun
191*4882a593Smuzhiyun /* To avoid time running backwards, we must call GetTimeInMillis before
192*4882a593Smuzhiyun * calling ProcessInputEvents.
193*4882a593Smuzhiyun */
194*4882a593Smuzhiyun systime.months = currentTime.months;
195*4882a593Smuzhiyun systime.milliseconds = GetTimeInMillis();
196*4882a593Smuzhiyun if (systime.milliseconds < currentTime.milliseconds)
197*4882a593Smuzhiyun systime.months++;
198*4882a593Smuzhiyun if (InputCheckPending())
199*4882a593Smuzhiyun ProcessInputEvents();
200*4882a593Smuzhiyun if (CompareTimeStamps(systime, currentTime) == LATER)
201*4882a593Smuzhiyun currentTime = systime;
202*4882a593Smuzhiyun }
203*4882a593Smuzhiyun
204*4882a593Smuzhiyun /* Like UpdateCurrentTime, but can't call ProcessInputEvents */
205*4882a593Smuzhiyun void
UpdateCurrentTimeIf(void)206*4882a593Smuzhiyun UpdateCurrentTimeIf(void)
207*4882a593Smuzhiyun {
208*4882a593Smuzhiyun TimeStamp systime;
209*4882a593Smuzhiyun
210*4882a593Smuzhiyun systime.months = currentTime.months;
211*4882a593Smuzhiyun systime.milliseconds = GetTimeInMillis();
212*4882a593Smuzhiyun if (systime.milliseconds < currentTime.milliseconds)
213*4882a593Smuzhiyun systime.months++;
214*4882a593Smuzhiyun if (CompareTimeStamps(systime, currentTime) == LATER)
215*4882a593Smuzhiyun currentTime = systime;
216*4882a593Smuzhiyun }
217*4882a593Smuzhiyun
218*4882a593Smuzhiyun #undef SMART_DEBUG
219*4882a593Smuzhiyun
220*4882a593Smuzhiyun /* in milliseconds */
221*4882a593Smuzhiyun #define SMART_SCHEDULE_DEFAULT_INTERVAL 5
222*4882a593Smuzhiyun #define SMART_SCHEDULE_MAX_SLICE 15
223*4882a593Smuzhiyun
224*4882a593Smuzhiyun #ifdef HAVE_SETITIMER
225*4882a593Smuzhiyun Bool SmartScheduleSignalEnable = TRUE;
226*4882a593Smuzhiyun #endif
227*4882a593Smuzhiyun
228*4882a593Smuzhiyun long SmartScheduleSlice = SMART_SCHEDULE_DEFAULT_INTERVAL;
229*4882a593Smuzhiyun long SmartScheduleInterval = SMART_SCHEDULE_DEFAULT_INTERVAL;
230*4882a593Smuzhiyun long SmartScheduleMaxSlice = SMART_SCHEDULE_MAX_SLICE;
231*4882a593Smuzhiyun long SmartScheduleTime;
232*4882a593Smuzhiyun int SmartScheduleLatencyLimited = 0;
233*4882a593Smuzhiyun static ClientPtr SmartLastClient;
234*4882a593Smuzhiyun static int SmartLastIndex[SMART_MAX_PRIORITY - SMART_MIN_PRIORITY + 1];
235*4882a593Smuzhiyun
236*4882a593Smuzhiyun #ifdef SMART_DEBUG
237*4882a593Smuzhiyun long SmartLastPrint;
238*4882a593Smuzhiyun #endif
239*4882a593Smuzhiyun
240*4882a593Smuzhiyun void Dispatch(void);
241*4882a593Smuzhiyun
242*4882a593Smuzhiyun static struct xorg_list ready_clients;
243*4882a593Smuzhiyun static struct xorg_list saved_ready_clients;
244*4882a593Smuzhiyun struct xorg_list output_pending_clients;
245*4882a593Smuzhiyun
246*4882a593Smuzhiyun static void
init_client_ready(void)247*4882a593Smuzhiyun init_client_ready(void)
248*4882a593Smuzhiyun {
249*4882a593Smuzhiyun xorg_list_init(&ready_clients);
250*4882a593Smuzhiyun xorg_list_init(&saved_ready_clients);
251*4882a593Smuzhiyun xorg_list_init(&output_pending_clients);
252*4882a593Smuzhiyun }
253*4882a593Smuzhiyun
254*4882a593Smuzhiyun Bool
clients_are_ready(void)255*4882a593Smuzhiyun clients_are_ready(void)
256*4882a593Smuzhiyun {
257*4882a593Smuzhiyun return !xorg_list_is_empty(&ready_clients);
258*4882a593Smuzhiyun }
259*4882a593Smuzhiyun
260*4882a593Smuzhiyun /* Client has requests queued or data on the network */
261*4882a593Smuzhiyun void
mark_client_ready(ClientPtr client)262*4882a593Smuzhiyun mark_client_ready(ClientPtr client)
263*4882a593Smuzhiyun {
264*4882a593Smuzhiyun if (xorg_list_is_empty(&client->ready))
265*4882a593Smuzhiyun xorg_list_append(&client->ready, &ready_clients);
266*4882a593Smuzhiyun }
267*4882a593Smuzhiyun
268*4882a593Smuzhiyun /*
269*4882a593Smuzhiyun * Client has requests queued or data on the network, but awaits a
270*4882a593Smuzhiyun * server grab release
271*4882a593Smuzhiyun */
mark_client_saved_ready(ClientPtr client)272*4882a593Smuzhiyun void mark_client_saved_ready(ClientPtr client)
273*4882a593Smuzhiyun {
274*4882a593Smuzhiyun if (xorg_list_is_empty(&client->ready))
275*4882a593Smuzhiyun xorg_list_append(&client->ready, &saved_ready_clients);
276*4882a593Smuzhiyun }
277*4882a593Smuzhiyun
278*4882a593Smuzhiyun /* Client has no requests queued and no data on network */
279*4882a593Smuzhiyun void
mark_client_not_ready(ClientPtr client)280*4882a593Smuzhiyun mark_client_not_ready(ClientPtr client)
281*4882a593Smuzhiyun {
282*4882a593Smuzhiyun xorg_list_del(&client->ready);
283*4882a593Smuzhiyun }
284*4882a593Smuzhiyun
285*4882a593Smuzhiyun static void
mark_client_grab(ClientPtr grab)286*4882a593Smuzhiyun mark_client_grab(ClientPtr grab)
287*4882a593Smuzhiyun {
288*4882a593Smuzhiyun ClientPtr client, tmp;
289*4882a593Smuzhiyun
290*4882a593Smuzhiyun xorg_list_for_each_entry_safe(client, tmp, &ready_clients, ready) {
291*4882a593Smuzhiyun if (client != grab) {
292*4882a593Smuzhiyun xorg_list_del(&client->ready);
293*4882a593Smuzhiyun xorg_list_append(&client->ready, &saved_ready_clients);
294*4882a593Smuzhiyun }
295*4882a593Smuzhiyun }
296*4882a593Smuzhiyun }
297*4882a593Smuzhiyun
298*4882a593Smuzhiyun static void
mark_client_ungrab(void)299*4882a593Smuzhiyun mark_client_ungrab(void)
300*4882a593Smuzhiyun {
301*4882a593Smuzhiyun ClientPtr client, tmp;
302*4882a593Smuzhiyun
303*4882a593Smuzhiyun xorg_list_for_each_entry_safe(client, tmp, &saved_ready_clients, ready) {
304*4882a593Smuzhiyun xorg_list_del(&client->ready);
305*4882a593Smuzhiyun xorg_list_append(&client->ready, &ready_clients);
306*4882a593Smuzhiyun }
307*4882a593Smuzhiyun }
308*4882a593Smuzhiyun
309*4882a593Smuzhiyun static ClientPtr
SmartScheduleClient(void)310*4882a593Smuzhiyun SmartScheduleClient(void)
311*4882a593Smuzhiyun {
312*4882a593Smuzhiyun ClientPtr pClient, best = NULL;
313*4882a593Smuzhiyun int bestRobin, robin;
314*4882a593Smuzhiyun long now = SmartScheduleTime;
315*4882a593Smuzhiyun long idle;
316*4882a593Smuzhiyun int nready = 0;
317*4882a593Smuzhiyun
318*4882a593Smuzhiyun bestRobin = 0;
319*4882a593Smuzhiyun idle = 2 * SmartScheduleSlice;
320*4882a593Smuzhiyun
321*4882a593Smuzhiyun xorg_list_for_each_entry(pClient, &ready_clients, ready) {
322*4882a593Smuzhiyun nready++;
323*4882a593Smuzhiyun
324*4882a593Smuzhiyun /* Praise clients which haven't run in a while */
325*4882a593Smuzhiyun if ((now - pClient->smart_stop_tick) >= idle) {
326*4882a593Smuzhiyun if (pClient->smart_priority < 0)
327*4882a593Smuzhiyun pClient->smart_priority++;
328*4882a593Smuzhiyun }
329*4882a593Smuzhiyun
330*4882a593Smuzhiyun /* check priority to select best client */
331*4882a593Smuzhiyun robin =
332*4882a593Smuzhiyun (pClient->index -
333*4882a593Smuzhiyun SmartLastIndex[pClient->smart_priority -
334*4882a593Smuzhiyun SMART_MIN_PRIORITY]) & 0xff;
335*4882a593Smuzhiyun
336*4882a593Smuzhiyun /* pick the best client */
337*4882a593Smuzhiyun if (!best ||
338*4882a593Smuzhiyun pClient->priority > best->priority ||
339*4882a593Smuzhiyun (pClient->priority == best->priority &&
340*4882a593Smuzhiyun (pClient->smart_priority > best->smart_priority ||
341*4882a593Smuzhiyun (pClient->smart_priority == best->smart_priority && robin > bestRobin))))
342*4882a593Smuzhiyun {
343*4882a593Smuzhiyun best = pClient;
344*4882a593Smuzhiyun bestRobin = robin;
345*4882a593Smuzhiyun }
346*4882a593Smuzhiyun #ifdef SMART_DEBUG
347*4882a593Smuzhiyun if ((now - SmartLastPrint) >= 5000)
348*4882a593Smuzhiyun fprintf(stderr, " %2d: %3d", pClient->index, pClient->smart_priority);
349*4882a593Smuzhiyun #endif
350*4882a593Smuzhiyun }
351*4882a593Smuzhiyun #ifdef SMART_DEBUG
352*4882a593Smuzhiyun if ((now - SmartLastPrint) >= 5000) {
353*4882a593Smuzhiyun fprintf(stderr, " use %2d\n", best->index);
354*4882a593Smuzhiyun SmartLastPrint = now;
355*4882a593Smuzhiyun }
356*4882a593Smuzhiyun #endif
357*4882a593Smuzhiyun SmartLastIndex[best->smart_priority - SMART_MIN_PRIORITY] = best->index;
358*4882a593Smuzhiyun /*
359*4882a593Smuzhiyun * Set current client pointer
360*4882a593Smuzhiyun */
361*4882a593Smuzhiyun if (SmartLastClient != best) {
362*4882a593Smuzhiyun best->smart_start_tick = now;
363*4882a593Smuzhiyun SmartLastClient = best;
364*4882a593Smuzhiyun }
365*4882a593Smuzhiyun /*
366*4882a593Smuzhiyun * Adjust slice
367*4882a593Smuzhiyun */
368*4882a593Smuzhiyun if (nready == 1 && SmartScheduleLatencyLimited == 0) {
369*4882a593Smuzhiyun /*
370*4882a593Smuzhiyun * If it's been a long time since another client
371*4882a593Smuzhiyun * has run, bump the slice up to get maximal
372*4882a593Smuzhiyun * performance from a single client
373*4882a593Smuzhiyun */
374*4882a593Smuzhiyun if ((now - best->smart_start_tick) > 1000 &&
375*4882a593Smuzhiyun SmartScheduleSlice < SmartScheduleMaxSlice) {
376*4882a593Smuzhiyun SmartScheduleSlice += SmartScheduleInterval;
377*4882a593Smuzhiyun }
378*4882a593Smuzhiyun }
379*4882a593Smuzhiyun else {
380*4882a593Smuzhiyun SmartScheduleSlice = SmartScheduleInterval;
381*4882a593Smuzhiyun }
382*4882a593Smuzhiyun return best;
383*4882a593Smuzhiyun }
384*4882a593Smuzhiyun
385*4882a593Smuzhiyun void
EnableLimitedSchedulingLatency(void)386*4882a593Smuzhiyun EnableLimitedSchedulingLatency(void)
387*4882a593Smuzhiyun {
388*4882a593Smuzhiyun ++SmartScheduleLatencyLimited;
389*4882a593Smuzhiyun SmartScheduleSlice = SmartScheduleInterval;
390*4882a593Smuzhiyun }
391*4882a593Smuzhiyun
392*4882a593Smuzhiyun void
DisableLimitedSchedulingLatency(void)393*4882a593Smuzhiyun DisableLimitedSchedulingLatency(void)
394*4882a593Smuzhiyun {
395*4882a593Smuzhiyun --SmartScheduleLatencyLimited;
396*4882a593Smuzhiyun
397*4882a593Smuzhiyun /* protect against bugs */
398*4882a593Smuzhiyun if (SmartScheduleLatencyLimited < 0)
399*4882a593Smuzhiyun SmartScheduleLatencyLimited = 0;
400*4882a593Smuzhiyun }
401*4882a593Smuzhiyun
402*4882a593Smuzhiyun void
Dispatch(void)403*4882a593Smuzhiyun Dispatch(void)
404*4882a593Smuzhiyun {
405*4882a593Smuzhiyun int result;
406*4882a593Smuzhiyun ClientPtr client;
407*4882a593Smuzhiyun long start_tick;
408*4882a593Smuzhiyun
409*4882a593Smuzhiyun nextFreeClientID = 1;
410*4882a593Smuzhiyun nClients = 0;
411*4882a593Smuzhiyun
412*4882a593Smuzhiyun SmartScheduleSlice = SmartScheduleInterval;
413*4882a593Smuzhiyun init_client_ready();
414*4882a593Smuzhiyun
415*4882a593Smuzhiyun while (!dispatchException) {
416*4882a593Smuzhiyun if (InputCheckPending()) {
417*4882a593Smuzhiyun ProcessInputEvents();
418*4882a593Smuzhiyun FlushIfCriticalOutputPending();
419*4882a593Smuzhiyun }
420*4882a593Smuzhiyun
421*4882a593Smuzhiyun if (!WaitForSomething(clients_are_ready()))
422*4882a593Smuzhiyun continue;
423*4882a593Smuzhiyun
424*4882a593Smuzhiyun /*****************
425*4882a593Smuzhiyun * Handle events in round robin fashion, doing input between
426*4882a593Smuzhiyun * each round
427*4882a593Smuzhiyun *****************/
428*4882a593Smuzhiyun
429*4882a593Smuzhiyun if (!dispatchException && clients_are_ready()) {
430*4882a593Smuzhiyun client = SmartScheduleClient();
431*4882a593Smuzhiyun
432*4882a593Smuzhiyun isItTimeToYield = FALSE;
433*4882a593Smuzhiyun
434*4882a593Smuzhiyun start_tick = SmartScheduleTime;
435*4882a593Smuzhiyun while (!isItTimeToYield) {
436*4882a593Smuzhiyun if (InputCheckPending())
437*4882a593Smuzhiyun ProcessInputEvents();
438*4882a593Smuzhiyun
439*4882a593Smuzhiyun FlushIfCriticalOutputPending();
440*4882a593Smuzhiyun if ((SmartScheduleTime - start_tick) >= SmartScheduleSlice)
441*4882a593Smuzhiyun {
442*4882a593Smuzhiyun /* Penalize clients which consume ticks */
443*4882a593Smuzhiyun if (client->smart_priority > SMART_MIN_PRIORITY)
444*4882a593Smuzhiyun client->smart_priority--;
445*4882a593Smuzhiyun break;
446*4882a593Smuzhiyun }
447*4882a593Smuzhiyun
448*4882a593Smuzhiyun /* now, finally, deal with client requests */
449*4882a593Smuzhiyun result = ReadRequestFromClient(client);
450*4882a593Smuzhiyun if (result <= 0) {
451*4882a593Smuzhiyun if (result < 0)
452*4882a593Smuzhiyun CloseDownClient(client);
453*4882a593Smuzhiyun break;
454*4882a593Smuzhiyun }
455*4882a593Smuzhiyun
456*4882a593Smuzhiyun client->sequence++;
457*4882a593Smuzhiyun client->majorOp = ((xReq *) client->requestBuffer)->reqType;
458*4882a593Smuzhiyun client->minorOp = 0;
459*4882a593Smuzhiyun if (client->majorOp >= EXTENSION_BASE) {
460*4882a593Smuzhiyun ExtensionEntry *ext = GetExtensionEntry(client->majorOp);
461*4882a593Smuzhiyun
462*4882a593Smuzhiyun if (ext)
463*4882a593Smuzhiyun client->minorOp = ext->MinorOpcode(client);
464*4882a593Smuzhiyun }
465*4882a593Smuzhiyun #ifdef XSERVER_DTRACE
466*4882a593Smuzhiyun if (XSERVER_REQUEST_START_ENABLED())
467*4882a593Smuzhiyun XSERVER_REQUEST_START(LookupMajorName(client->majorOp),
468*4882a593Smuzhiyun client->majorOp,
469*4882a593Smuzhiyun ((xReq *) client->requestBuffer)->length,
470*4882a593Smuzhiyun client->index,
471*4882a593Smuzhiyun client->requestBuffer);
472*4882a593Smuzhiyun #endif
473*4882a593Smuzhiyun if (result > (maxBigRequestSize << 2))
474*4882a593Smuzhiyun result = BadLength;
475*4882a593Smuzhiyun else {
476*4882a593Smuzhiyun result = XaceHookDispatch(client, client->majorOp);
477*4882a593Smuzhiyun if (result == Success)
478*4882a593Smuzhiyun result =
479*4882a593Smuzhiyun (*client->requestVector[client->majorOp]) (client);
480*4882a593Smuzhiyun }
481*4882a593Smuzhiyun if (!SmartScheduleSignalEnable)
482*4882a593Smuzhiyun SmartScheduleTime = GetTimeInMillis();
483*4882a593Smuzhiyun
484*4882a593Smuzhiyun #ifdef XSERVER_DTRACE
485*4882a593Smuzhiyun if (XSERVER_REQUEST_DONE_ENABLED())
486*4882a593Smuzhiyun XSERVER_REQUEST_DONE(LookupMajorName(client->majorOp),
487*4882a593Smuzhiyun client->majorOp, client->sequence,
488*4882a593Smuzhiyun client->index, result);
489*4882a593Smuzhiyun #endif
490*4882a593Smuzhiyun
491*4882a593Smuzhiyun if (client->noClientException != Success) {
492*4882a593Smuzhiyun CloseDownClient(client);
493*4882a593Smuzhiyun break;
494*4882a593Smuzhiyun }
495*4882a593Smuzhiyun else if (result != Success) {
496*4882a593Smuzhiyun SendErrorToClient(client, client->majorOp,
497*4882a593Smuzhiyun client->minorOp,
498*4882a593Smuzhiyun client->errorValue, result);
499*4882a593Smuzhiyun break;
500*4882a593Smuzhiyun }
501*4882a593Smuzhiyun }
502*4882a593Smuzhiyun FlushAllOutput();
503*4882a593Smuzhiyun if (client == SmartLastClient)
504*4882a593Smuzhiyun client->smart_stop_tick = SmartScheduleTime;
505*4882a593Smuzhiyun }
506*4882a593Smuzhiyun dispatchException &= ~DE_PRIORITYCHANGE;
507*4882a593Smuzhiyun }
508*4882a593Smuzhiyun #if defined(DDXBEFORERESET)
509*4882a593Smuzhiyun ddxBeforeReset();
510*4882a593Smuzhiyun #endif
511*4882a593Smuzhiyun KillAllClients();
512*4882a593Smuzhiyun dispatchException &= ~DE_RESET;
513*4882a593Smuzhiyun SmartScheduleLatencyLimited = 0;
514*4882a593Smuzhiyun ResetOsBuffers();
515*4882a593Smuzhiyun }
516*4882a593Smuzhiyun
517*4882a593Smuzhiyun static int VendorRelease = VENDOR_RELEASE;
518*4882a593Smuzhiyun static const char *VendorString = VENDOR_NAME;
519*4882a593Smuzhiyun
520*4882a593Smuzhiyun void
SetVendorRelease(int release)521*4882a593Smuzhiyun SetVendorRelease(int release)
522*4882a593Smuzhiyun {
523*4882a593Smuzhiyun VendorRelease = release;
524*4882a593Smuzhiyun }
525*4882a593Smuzhiyun
526*4882a593Smuzhiyun void
SetVendorString(const char * vendor)527*4882a593Smuzhiyun SetVendorString(const char *vendor)
528*4882a593Smuzhiyun {
529*4882a593Smuzhiyun VendorString = vendor;
530*4882a593Smuzhiyun }
531*4882a593Smuzhiyun
532*4882a593Smuzhiyun Bool
CreateConnectionBlock(void)533*4882a593Smuzhiyun CreateConnectionBlock(void)
534*4882a593Smuzhiyun {
535*4882a593Smuzhiyun xConnSetup setup;
536*4882a593Smuzhiyun xWindowRoot root;
537*4882a593Smuzhiyun xDepth depth;
538*4882a593Smuzhiyun xVisualType visual;
539*4882a593Smuzhiyun xPixmapFormat format;
540*4882a593Smuzhiyun unsigned long vid;
541*4882a593Smuzhiyun int i, j, k, lenofblock, sizesofar = 0;
542*4882a593Smuzhiyun char *pBuf;
543*4882a593Smuzhiyun
544*4882a593Smuzhiyun memset(&setup, 0, sizeof(xConnSetup));
545*4882a593Smuzhiyun /* Leave off the ridBase and ridMask, these must be sent with
546*4882a593Smuzhiyun connection */
547*4882a593Smuzhiyun
548*4882a593Smuzhiyun setup.release = VendorRelease;
549*4882a593Smuzhiyun /*
550*4882a593Smuzhiyun * per-server image and bitmap parameters are defined in Xmd.h
551*4882a593Smuzhiyun */
552*4882a593Smuzhiyun setup.imageByteOrder = screenInfo.imageByteOrder;
553*4882a593Smuzhiyun
554*4882a593Smuzhiyun setup.bitmapScanlineUnit = screenInfo.bitmapScanlineUnit;
555*4882a593Smuzhiyun setup.bitmapScanlinePad = screenInfo.bitmapScanlinePad;
556*4882a593Smuzhiyun
557*4882a593Smuzhiyun setup.bitmapBitOrder = screenInfo.bitmapBitOrder;
558*4882a593Smuzhiyun setup.motionBufferSize = NumMotionEvents();
559*4882a593Smuzhiyun setup.numRoots = screenInfo.numScreens;
560*4882a593Smuzhiyun setup.nbytesVendor = strlen(VendorString);
561*4882a593Smuzhiyun setup.numFormats = screenInfo.numPixmapFormats;
562*4882a593Smuzhiyun setup.maxRequestSize = MAX_REQUEST_SIZE;
563*4882a593Smuzhiyun QueryMinMaxKeyCodes(&setup.minKeyCode, &setup.maxKeyCode);
564*4882a593Smuzhiyun
565*4882a593Smuzhiyun lenofblock = sizeof(xConnSetup) +
566*4882a593Smuzhiyun pad_to_int32(setup.nbytesVendor) +
567*4882a593Smuzhiyun (setup.numFormats * sizeof(xPixmapFormat)) +
568*4882a593Smuzhiyun (setup.numRoots * sizeof(xWindowRoot));
569*4882a593Smuzhiyun ConnectionInfo = malloc(lenofblock);
570*4882a593Smuzhiyun if (!ConnectionInfo)
571*4882a593Smuzhiyun return FALSE;
572*4882a593Smuzhiyun
573*4882a593Smuzhiyun memmove(ConnectionInfo, (char *) &setup, sizeof(xConnSetup));
574*4882a593Smuzhiyun sizesofar = sizeof(xConnSetup);
575*4882a593Smuzhiyun pBuf = ConnectionInfo + sizeof(xConnSetup);
576*4882a593Smuzhiyun
577*4882a593Smuzhiyun memmove(pBuf, VendorString, (int) setup.nbytesVendor);
578*4882a593Smuzhiyun sizesofar += setup.nbytesVendor;
579*4882a593Smuzhiyun pBuf += setup.nbytesVendor;
580*4882a593Smuzhiyun i = padding_for_int32(setup.nbytesVendor);
581*4882a593Smuzhiyun sizesofar += i;
582*4882a593Smuzhiyun while (--i >= 0)
583*4882a593Smuzhiyun *pBuf++ = 0;
584*4882a593Smuzhiyun
585*4882a593Smuzhiyun memset(&format, 0, sizeof(xPixmapFormat));
586*4882a593Smuzhiyun for (i = 0; i < screenInfo.numPixmapFormats; i++) {
587*4882a593Smuzhiyun format.depth = screenInfo.formats[i].depth;
588*4882a593Smuzhiyun format.bitsPerPixel = screenInfo.formats[i].bitsPerPixel;
589*4882a593Smuzhiyun format.scanLinePad = screenInfo.formats[i].scanlinePad;
590*4882a593Smuzhiyun memmove(pBuf, (char *) &format, sizeof(xPixmapFormat));
591*4882a593Smuzhiyun pBuf += sizeof(xPixmapFormat);
592*4882a593Smuzhiyun sizesofar += sizeof(xPixmapFormat);
593*4882a593Smuzhiyun }
594*4882a593Smuzhiyun
595*4882a593Smuzhiyun connBlockScreenStart = sizesofar;
596*4882a593Smuzhiyun memset(&depth, 0, sizeof(xDepth));
597*4882a593Smuzhiyun memset(&visual, 0, sizeof(xVisualType));
598*4882a593Smuzhiyun for (i = 0; i < screenInfo.numScreens; i++) {
599*4882a593Smuzhiyun ScreenPtr pScreen;
600*4882a593Smuzhiyun DepthPtr pDepth;
601*4882a593Smuzhiyun VisualPtr pVisual;
602*4882a593Smuzhiyun
603*4882a593Smuzhiyun pScreen = screenInfo.screens[i];
604*4882a593Smuzhiyun root.windowId = pScreen->root->drawable.id;
605*4882a593Smuzhiyun root.defaultColormap = pScreen->defColormap;
606*4882a593Smuzhiyun root.whitePixel = pScreen->whitePixel;
607*4882a593Smuzhiyun root.blackPixel = pScreen->blackPixel;
608*4882a593Smuzhiyun root.currentInputMask = 0; /* filled in when sent */
609*4882a593Smuzhiyun root.pixWidth = pScreen->width;
610*4882a593Smuzhiyun root.pixHeight = pScreen->height;
611*4882a593Smuzhiyun root.mmWidth = pScreen->mmWidth;
612*4882a593Smuzhiyun root.mmHeight = pScreen->mmHeight;
613*4882a593Smuzhiyun root.minInstalledMaps = pScreen->minInstalledCmaps;
614*4882a593Smuzhiyun root.maxInstalledMaps = pScreen->maxInstalledCmaps;
615*4882a593Smuzhiyun root.rootVisualID = pScreen->rootVisual;
616*4882a593Smuzhiyun root.backingStore = pScreen->backingStoreSupport;
617*4882a593Smuzhiyun root.saveUnders = FALSE;
618*4882a593Smuzhiyun root.rootDepth = pScreen->rootDepth;
619*4882a593Smuzhiyun root.nDepths = pScreen->numDepths;
620*4882a593Smuzhiyun memmove(pBuf, (char *) &root, sizeof(xWindowRoot));
621*4882a593Smuzhiyun sizesofar += sizeof(xWindowRoot);
622*4882a593Smuzhiyun pBuf += sizeof(xWindowRoot);
623*4882a593Smuzhiyun
624*4882a593Smuzhiyun pDepth = pScreen->allowedDepths;
625*4882a593Smuzhiyun for (j = 0; j < pScreen->numDepths; j++, pDepth++) {
626*4882a593Smuzhiyun lenofblock += sizeof(xDepth) +
627*4882a593Smuzhiyun (pDepth->numVids * sizeof(xVisualType));
628*4882a593Smuzhiyun pBuf = (char *) realloc(ConnectionInfo, lenofblock);
629*4882a593Smuzhiyun if (!pBuf) {
630*4882a593Smuzhiyun free(ConnectionInfo);
631*4882a593Smuzhiyun return FALSE;
632*4882a593Smuzhiyun }
633*4882a593Smuzhiyun ConnectionInfo = pBuf;
634*4882a593Smuzhiyun pBuf += sizesofar;
635*4882a593Smuzhiyun depth.depth = pDepth->depth;
636*4882a593Smuzhiyun depth.nVisuals = pDepth->numVids;
637*4882a593Smuzhiyun memmove(pBuf, (char *) &depth, sizeof(xDepth));
638*4882a593Smuzhiyun pBuf += sizeof(xDepth);
639*4882a593Smuzhiyun sizesofar += sizeof(xDepth);
640*4882a593Smuzhiyun for (k = 0; k < pDepth->numVids; k++) {
641*4882a593Smuzhiyun vid = pDepth->vids[k];
642*4882a593Smuzhiyun for (pVisual = pScreen->visuals;
643*4882a593Smuzhiyun pVisual->vid != vid; pVisual++);
644*4882a593Smuzhiyun visual.visualID = vid;
645*4882a593Smuzhiyun visual.class = pVisual->class;
646*4882a593Smuzhiyun visual.bitsPerRGB = pVisual->bitsPerRGBValue;
647*4882a593Smuzhiyun visual.colormapEntries = pVisual->ColormapEntries;
648*4882a593Smuzhiyun visual.redMask = pVisual->redMask;
649*4882a593Smuzhiyun visual.greenMask = pVisual->greenMask;
650*4882a593Smuzhiyun visual.blueMask = pVisual->blueMask;
651*4882a593Smuzhiyun memmove(pBuf, (char *) &visual, sizeof(xVisualType));
652*4882a593Smuzhiyun pBuf += sizeof(xVisualType);
653*4882a593Smuzhiyun sizesofar += sizeof(xVisualType);
654*4882a593Smuzhiyun }
655*4882a593Smuzhiyun }
656*4882a593Smuzhiyun }
657*4882a593Smuzhiyun connSetupPrefix.success = xTrue;
658*4882a593Smuzhiyun connSetupPrefix.length = lenofblock / 4;
659*4882a593Smuzhiyun connSetupPrefix.majorVersion = X_PROTOCOL;
660*4882a593Smuzhiyun connSetupPrefix.minorVersion = X_PROTOCOL_REVISION;
661*4882a593Smuzhiyun return TRUE;
662*4882a593Smuzhiyun }
663*4882a593Smuzhiyun
664*4882a593Smuzhiyun int
ProcBadRequest(ClientPtr client)665*4882a593Smuzhiyun ProcBadRequest(ClientPtr client)
666*4882a593Smuzhiyun {
667*4882a593Smuzhiyun return BadRequest;
668*4882a593Smuzhiyun }
669*4882a593Smuzhiyun
670*4882a593Smuzhiyun int
ProcCreateWindow(ClientPtr client)671*4882a593Smuzhiyun ProcCreateWindow(ClientPtr client)
672*4882a593Smuzhiyun {
673*4882a593Smuzhiyun WindowPtr pParent, pWin;
674*4882a593Smuzhiyun
675*4882a593Smuzhiyun REQUEST(xCreateWindowReq);
676*4882a593Smuzhiyun int len, rc;
677*4882a593Smuzhiyun
678*4882a593Smuzhiyun REQUEST_AT_LEAST_SIZE(xCreateWindowReq);
679*4882a593Smuzhiyun
680*4882a593Smuzhiyun LEGAL_NEW_RESOURCE(stuff->wid, client);
681*4882a593Smuzhiyun rc = dixLookupWindow(&pParent, stuff->parent, client, DixAddAccess);
682*4882a593Smuzhiyun if (rc != Success)
683*4882a593Smuzhiyun return rc;
684*4882a593Smuzhiyun len = client->req_len - bytes_to_int32(sizeof(xCreateWindowReq));
685*4882a593Smuzhiyun if (Ones(stuff->mask) != len)
686*4882a593Smuzhiyun return BadLength;
687*4882a593Smuzhiyun if (!stuff->width || !stuff->height) {
688*4882a593Smuzhiyun client->errorValue = 0;
689*4882a593Smuzhiyun return BadValue;
690*4882a593Smuzhiyun }
691*4882a593Smuzhiyun pWin = CreateWindow(stuff->wid, pParent, stuff->x,
692*4882a593Smuzhiyun stuff->y, stuff->width, stuff->height,
693*4882a593Smuzhiyun stuff->borderWidth, stuff->class,
694*4882a593Smuzhiyun stuff->mask, (XID *) &stuff[1],
695*4882a593Smuzhiyun (int) stuff->depth, client, stuff->visual, &rc);
696*4882a593Smuzhiyun if (pWin) {
697*4882a593Smuzhiyun Mask mask = pWin->eventMask;
698*4882a593Smuzhiyun
699*4882a593Smuzhiyun pWin->eventMask = 0; /* subterfuge in case AddResource fails */
700*4882a593Smuzhiyun if (!AddResource(stuff->wid, RT_WINDOW, (void *) pWin))
701*4882a593Smuzhiyun return BadAlloc;
702*4882a593Smuzhiyun pWin->eventMask = mask;
703*4882a593Smuzhiyun }
704*4882a593Smuzhiyun return rc;
705*4882a593Smuzhiyun }
706*4882a593Smuzhiyun
707*4882a593Smuzhiyun int
ProcChangeWindowAttributes(ClientPtr client)708*4882a593Smuzhiyun ProcChangeWindowAttributes(ClientPtr client)
709*4882a593Smuzhiyun {
710*4882a593Smuzhiyun WindowPtr pWin;
711*4882a593Smuzhiyun
712*4882a593Smuzhiyun REQUEST(xChangeWindowAttributesReq);
713*4882a593Smuzhiyun int len, rc;
714*4882a593Smuzhiyun Mask access_mode = 0;
715*4882a593Smuzhiyun
716*4882a593Smuzhiyun REQUEST_AT_LEAST_SIZE(xChangeWindowAttributesReq);
717*4882a593Smuzhiyun access_mode |= (stuff->valueMask & CWEventMask) ? DixReceiveAccess : 0;
718*4882a593Smuzhiyun access_mode |= (stuff->valueMask & ~CWEventMask) ? DixSetAttrAccess : 0;
719*4882a593Smuzhiyun rc = dixLookupWindow(&pWin, stuff->window, client, access_mode);
720*4882a593Smuzhiyun if (rc != Success)
721*4882a593Smuzhiyun return rc;
722*4882a593Smuzhiyun len = client->req_len - bytes_to_int32(sizeof(xChangeWindowAttributesReq));
723*4882a593Smuzhiyun if (len != Ones(stuff->valueMask))
724*4882a593Smuzhiyun return BadLength;
725*4882a593Smuzhiyun return ChangeWindowAttributes(pWin,
726*4882a593Smuzhiyun stuff->valueMask, (XID *) &stuff[1], client);
727*4882a593Smuzhiyun }
728*4882a593Smuzhiyun
729*4882a593Smuzhiyun int
ProcGetWindowAttributes(ClientPtr client)730*4882a593Smuzhiyun ProcGetWindowAttributes(ClientPtr client)
731*4882a593Smuzhiyun {
732*4882a593Smuzhiyun WindowPtr pWin;
733*4882a593Smuzhiyun
734*4882a593Smuzhiyun REQUEST(xResourceReq);
735*4882a593Smuzhiyun xGetWindowAttributesReply wa;
736*4882a593Smuzhiyun int rc;
737*4882a593Smuzhiyun
738*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xResourceReq);
739*4882a593Smuzhiyun rc = dixLookupWindow(&pWin, stuff->id, client, DixGetAttrAccess);
740*4882a593Smuzhiyun if (rc != Success)
741*4882a593Smuzhiyun return rc;
742*4882a593Smuzhiyun memset(&wa, 0, sizeof(xGetWindowAttributesReply));
743*4882a593Smuzhiyun GetWindowAttributes(pWin, client, &wa);
744*4882a593Smuzhiyun WriteReplyToClient(client, sizeof(xGetWindowAttributesReply), &wa);
745*4882a593Smuzhiyun return Success;
746*4882a593Smuzhiyun }
747*4882a593Smuzhiyun
748*4882a593Smuzhiyun int
ProcDestroyWindow(ClientPtr client)749*4882a593Smuzhiyun ProcDestroyWindow(ClientPtr client)
750*4882a593Smuzhiyun {
751*4882a593Smuzhiyun WindowPtr pWin;
752*4882a593Smuzhiyun
753*4882a593Smuzhiyun REQUEST(xResourceReq);
754*4882a593Smuzhiyun int rc;
755*4882a593Smuzhiyun
756*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xResourceReq);
757*4882a593Smuzhiyun rc = dixLookupWindow(&pWin, stuff->id, client, DixDestroyAccess);
758*4882a593Smuzhiyun if (rc != Success)
759*4882a593Smuzhiyun return rc;
760*4882a593Smuzhiyun if (pWin->parent) {
761*4882a593Smuzhiyun rc = dixLookupWindow(&pWin, pWin->parent->drawable.id, client,
762*4882a593Smuzhiyun DixRemoveAccess);
763*4882a593Smuzhiyun if (rc != Success)
764*4882a593Smuzhiyun return rc;
765*4882a593Smuzhiyun FreeResource(stuff->id, RT_NONE);
766*4882a593Smuzhiyun }
767*4882a593Smuzhiyun return Success;
768*4882a593Smuzhiyun }
769*4882a593Smuzhiyun
770*4882a593Smuzhiyun int
ProcDestroySubwindows(ClientPtr client)771*4882a593Smuzhiyun ProcDestroySubwindows(ClientPtr client)
772*4882a593Smuzhiyun {
773*4882a593Smuzhiyun WindowPtr pWin;
774*4882a593Smuzhiyun
775*4882a593Smuzhiyun REQUEST(xResourceReq);
776*4882a593Smuzhiyun int rc;
777*4882a593Smuzhiyun
778*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xResourceReq);
779*4882a593Smuzhiyun rc = dixLookupWindow(&pWin, stuff->id, client, DixRemoveAccess);
780*4882a593Smuzhiyun if (rc != Success)
781*4882a593Smuzhiyun return rc;
782*4882a593Smuzhiyun DestroySubwindows(pWin, client);
783*4882a593Smuzhiyun return Success;
784*4882a593Smuzhiyun }
785*4882a593Smuzhiyun
786*4882a593Smuzhiyun int
ProcChangeSaveSet(ClientPtr client)787*4882a593Smuzhiyun ProcChangeSaveSet(ClientPtr client)
788*4882a593Smuzhiyun {
789*4882a593Smuzhiyun WindowPtr pWin;
790*4882a593Smuzhiyun
791*4882a593Smuzhiyun REQUEST(xChangeSaveSetReq);
792*4882a593Smuzhiyun int rc;
793*4882a593Smuzhiyun
794*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xChangeSaveSetReq);
795*4882a593Smuzhiyun rc = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess);
796*4882a593Smuzhiyun if (rc != Success)
797*4882a593Smuzhiyun return rc;
798*4882a593Smuzhiyun if (client->clientAsMask == (CLIENT_BITS(pWin->drawable.id)))
799*4882a593Smuzhiyun return BadMatch;
800*4882a593Smuzhiyun if ((stuff->mode == SetModeInsert) || (stuff->mode == SetModeDelete))
801*4882a593Smuzhiyun return AlterSaveSetForClient(client, pWin, stuff->mode, FALSE, TRUE);
802*4882a593Smuzhiyun client->errorValue = stuff->mode;
803*4882a593Smuzhiyun return BadValue;
804*4882a593Smuzhiyun }
805*4882a593Smuzhiyun
806*4882a593Smuzhiyun int
ProcReparentWindow(ClientPtr client)807*4882a593Smuzhiyun ProcReparentWindow(ClientPtr client)
808*4882a593Smuzhiyun {
809*4882a593Smuzhiyun WindowPtr pWin, pParent;
810*4882a593Smuzhiyun
811*4882a593Smuzhiyun REQUEST(xReparentWindowReq);
812*4882a593Smuzhiyun int rc;
813*4882a593Smuzhiyun
814*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xReparentWindowReq);
815*4882a593Smuzhiyun rc = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess);
816*4882a593Smuzhiyun if (rc != Success)
817*4882a593Smuzhiyun return rc;
818*4882a593Smuzhiyun rc = dixLookupWindow(&pParent, stuff->parent, client, DixAddAccess);
819*4882a593Smuzhiyun if (rc != Success)
820*4882a593Smuzhiyun return rc;
821*4882a593Smuzhiyun if (!SAME_SCREENS(pWin->drawable, pParent->drawable))
822*4882a593Smuzhiyun return BadMatch;
823*4882a593Smuzhiyun if ((pWin->backgroundState == ParentRelative) &&
824*4882a593Smuzhiyun (pParent->drawable.depth != pWin->drawable.depth))
825*4882a593Smuzhiyun return BadMatch;
826*4882a593Smuzhiyun if ((pWin->drawable.class != InputOnly) &&
827*4882a593Smuzhiyun (pParent->drawable.class == InputOnly))
828*4882a593Smuzhiyun return BadMatch;
829*4882a593Smuzhiyun return ReparentWindow(pWin, pParent,
830*4882a593Smuzhiyun (short) stuff->x, (short) stuff->y, client);
831*4882a593Smuzhiyun }
832*4882a593Smuzhiyun
833*4882a593Smuzhiyun int
ProcMapWindow(ClientPtr client)834*4882a593Smuzhiyun ProcMapWindow(ClientPtr client)
835*4882a593Smuzhiyun {
836*4882a593Smuzhiyun WindowPtr pWin;
837*4882a593Smuzhiyun
838*4882a593Smuzhiyun REQUEST(xResourceReq);
839*4882a593Smuzhiyun int rc;
840*4882a593Smuzhiyun
841*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xResourceReq);
842*4882a593Smuzhiyun rc = dixLookupWindow(&pWin, stuff->id, client, DixShowAccess);
843*4882a593Smuzhiyun if (rc != Success)
844*4882a593Smuzhiyun return rc;
845*4882a593Smuzhiyun MapWindow(pWin, client);
846*4882a593Smuzhiyun /* update cache to say it is mapped */
847*4882a593Smuzhiyun return Success;
848*4882a593Smuzhiyun }
849*4882a593Smuzhiyun
850*4882a593Smuzhiyun int
ProcMapSubwindows(ClientPtr client)851*4882a593Smuzhiyun ProcMapSubwindows(ClientPtr client)
852*4882a593Smuzhiyun {
853*4882a593Smuzhiyun WindowPtr pWin;
854*4882a593Smuzhiyun
855*4882a593Smuzhiyun REQUEST(xResourceReq);
856*4882a593Smuzhiyun int rc;
857*4882a593Smuzhiyun
858*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xResourceReq);
859*4882a593Smuzhiyun rc = dixLookupWindow(&pWin, stuff->id, client, DixListAccess);
860*4882a593Smuzhiyun if (rc != Success)
861*4882a593Smuzhiyun return rc;
862*4882a593Smuzhiyun MapSubwindows(pWin, client);
863*4882a593Smuzhiyun /* update cache to say it is mapped */
864*4882a593Smuzhiyun return Success;
865*4882a593Smuzhiyun }
866*4882a593Smuzhiyun
867*4882a593Smuzhiyun int
ProcUnmapWindow(ClientPtr client)868*4882a593Smuzhiyun ProcUnmapWindow(ClientPtr client)
869*4882a593Smuzhiyun {
870*4882a593Smuzhiyun WindowPtr pWin;
871*4882a593Smuzhiyun
872*4882a593Smuzhiyun REQUEST(xResourceReq);
873*4882a593Smuzhiyun int rc;
874*4882a593Smuzhiyun
875*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xResourceReq);
876*4882a593Smuzhiyun rc = dixLookupWindow(&pWin, stuff->id, client, DixHideAccess);
877*4882a593Smuzhiyun if (rc != Success)
878*4882a593Smuzhiyun return rc;
879*4882a593Smuzhiyun UnmapWindow(pWin, FALSE);
880*4882a593Smuzhiyun /* update cache to say it is mapped */
881*4882a593Smuzhiyun return Success;
882*4882a593Smuzhiyun }
883*4882a593Smuzhiyun
884*4882a593Smuzhiyun int
ProcUnmapSubwindows(ClientPtr client)885*4882a593Smuzhiyun ProcUnmapSubwindows(ClientPtr client)
886*4882a593Smuzhiyun {
887*4882a593Smuzhiyun WindowPtr pWin;
888*4882a593Smuzhiyun
889*4882a593Smuzhiyun REQUEST(xResourceReq);
890*4882a593Smuzhiyun int rc;
891*4882a593Smuzhiyun
892*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xResourceReq);
893*4882a593Smuzhiyun rc = dixLookupWindow(&pWin, stuff->id, client, DixListAccess);
894*4882a593Smuzhiyun if (rc != Success)
895*4882a593Smuzhiyun return rc;
896*4882a593Smuzhiyun UnmapSubwindows(pWin);
897*4882a593Smuzhiyun return Success;
898*4882a593Smuzhiyun }
899*4882a593Smuzhiyun
900*4882a593Smuzhiyun int
ProcConfigureWindow(ClientPtr client)901*4882a593Smuzhiyun ProcConfigureWindow(ClientPtr client)
902*4882a593Smuzhiyun {
903*4882a593Smuzhiyun WindowPtr pWin;
904*4882a593Smuzhiyun
905*4882a593Smuzhiyun REQUEST(xConfigureWindowReq);
906*4882a593Smuzhiyun int len, rc;
907*4882a593Smuzhiyun
908*4882a593Smuzhiyun REQUEST_AT_LEAST_SIZE(xConfigureWindowReq);
909*4882a593Smuzhiyun rc = dixLookupWindow(&pWin, stuff->window, client,
910*4882a593Smuzhiyun DixManageAccess | DixSetAttrAccess);
911*4882a593Smuzhiyun if (rc != Success)
912*4882a593Smuzhiyun return rc;
913*4882a593Smuzhiyun len = client->req_len - bytes_to_int32(sizeof(xConfigureWindowReq));
914*4882a593Smuzhiyun if (Ones((Mask) stuff->mask) != len)
915*4882a593Smuzhiyun return BadLength;
916*4882a593Smuzhiyun return ConfigureWindow(pWin, (Mask) stuff->mask, (XID *) &stuff[1], client);
917*4882a593Smuzhiyun }
918*4882a593Smuzhiyun
919*4882a593Smuzhiyun int
ProcCirculateWindow(ClientPtr client)920*4882a593Smuzhiyun ProcCirculateWindow(ClientPtr client)
921*4882a593Smuzhiyun {
922*4882a593Smuzhiyun WindowPtr pWin;
923*4882a593Smuzhiyun
924*4882a593Smuzhiyun REQUEST(xCirculateWindowReq);
925*4882a593Smuzhiyun int rc;
926*4882a593Smuzhiyun
927*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xCirculateWindowReq);
928*4882a593Smuzhiyun if ((stuff->direction != RaiseLowest) && (stuff->direction != LowerHighest)) {
929*4882a593Smuzhiyun client->errorValue = stuff->direction;
930*4882a593Smuzhiyun return BadValue;
931*4882a593Smuzhiyun }
932*4882a593Smuzhiyun rc = dixLookupWindow(&pWin, stuff->window, client, DixManageAccess);
933*4882a593Smuzhiyun if (rc != Success)
934*4882a593Smuzhiyun return rc;
935*4882a593Smuzhiyun CirculateWindow(pWin, (int) stuff->direction, client);
936*4882a593Smuzhiyun return Success;
937*4882a593Smuzhiyun }
938*4882a593Smuzhiyun
939*4882a593Smuzhiyun static int
GetGeometry(ClientPtr client,xGetGeometryReply * rep)940*4882a593Smuzhiyun GetGeometry(ClientPtr client, xGetGeometryReply * rep)
941*4882a593Smuzhiyun {
942*4882a593Smuzhiyun DrawablePtr pDraw;
943*4882a593Smuzhiyun int rc;
944*4882a593Smuzhiyun
945*4882a593Smuzhiyun REQUEST(xResourceReq);
946*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xResourceReq);
947*4882a593Smuzhiyun
948*4882a593Smuzhiyun rc = dixLookupDrawable(&pDraw, stuff->id, client, M_ANY, DixGetAttrAccess);
949*4882a593Smuzhiyun if (rc != Success)
950*4882a593Smuzhiyun return rc;
951*4882a593Smuzhiyun
952*4882a593Smuzhiyun rep->type = X_Reply;
953*4882a593Smuzhiyun rep->length = 0;
954*4882a593Smuzhiyun rep->sequenceNumber = client->sequence;
955*4882a593Smuzhiyun rep->root = pDraw->pScreen->root->drawable.id;
956*4882a593Smuzhiyun rep->depth = pDraw->depth;
957*4882a593Smuzhiyun rep->width = pDraw->width;
958*4882a593Smuzhiyun rep->height = pDraw->height;
959*4882a593Smuzhiyun
960*4882a593Smuzhiyun if (WindowDrawable(pDraw->type)) {
961*4882a593Smuzhiyun WindowPtr pWin = (WindowPtr) pDraw;
962*4882a593Smuzhiyun
963*4882a593Smuzhiyun rep->x = pWin->origin.x - wBorderWidth(pWin);
964*4882a593Smuzhiyun rep->y = pWin->origin.y - wBorderWidth(pWin);
965*4882a593Smuzhiyun rep->borderWidth = pWin->borderWidth;
966*4882a593Smuzhiyun }
967*4882a593Smuzhiyun else { /* DRAWABLE_PIXMAP */
968*4882a593Smuzhiyun
969*4882a593Smuzhiyun rep->x = rep->y = rep->borderWidth = 0;
970*4882a593Smuzhiyun }
971*4882a593Smuzhiyun
972*4882a593Smuzhiyun return Success;
973*4882a593Smuzhiyun }
974*4882a593Smuzhiyun
975*4882a593Smuzhiyun int
ProcGetGeometry(ClientPtr client)976*4882a593Smuzhiyun ProcGetGeometry(ClientPtr client)
977*4882a593Smuzhiyun {
978*4882a593Smuzhiyun xGetGeometryReply rep = { .type = X_Reply };
979*4882a593Smuzhiyun int status;
980*4882a593Smuzhiyun
981*4882a593Smuzhiyun if ((status = GetGeometry(client, &rep)) != Success)
982*4882a593Smuzhiyun return status;
983*4882a593Smuzhiyun
984*4882a593Smuzhiyun WriteReplyToClient(client, sizeof(xGetGeometryReply), &rep);
985*4882a593Smuzhiyun return Success;
986*4882a593Smuzhiyun }
987*4882a593Smuzhiyun
988*4882a593Smuzhiyun int
ProcQueryTree(ClientPtr client)989*4882a593Smuzhiyun ProcQueryTree(ClientPtr client)
990*4882a593Smuzhiyun {
991*4882a593Smuzhiyun xQueryTreeReply reply;
992*4882a593Smuzhiyun int rc, numChildren = 0;
993*4882a593Smuzhiyun WindowPtr pChild, pWin, pHead;
994*4882a593Smuzhiyun Window *childIDs = (Window *) NULL;
995*4882a593Smuzhiyun
996*4882a593Smuzhiyun REQUEST(xResourceReq);
997*4882a593Smuzhiyun
998*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xResourceReq);
999*4882a593Smuzhiyun rc = dixLookupWindow(&pWin, stuff->id, client, DixListAccess);
1000*4882a593Smuzhiyun if (rc != Success)
1001*4882a593Smuzhiyun return rc;
1002*4882a593Smuzhiyun
1003*4882a593Smuzhiyun reply = (xQueryTreeReply) {
1004*4882a593Smuzhiyun .type = X_Reply,
1005*4882a593Smuzhiyun .sequenceNumber = client->sequence,
1006*4882a593Smuzhiyun .root = pWin->drawable.pScreen->root->drawable.id,
1007*4882a593Smuzhiyun .parent = (pWin->parent) ? pWin->parent->drawable.id : (Window) None
1008*4882a593Smuzhiyun };
1009*4882a593Smuzhiyun pHead = RealChildHead(pWin);
1010*4882a593Smuzhiyun for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
1011*4882a593Smuzhiyun numChildren++;
1012*4882a593Smuzhiyun if (numChildren) {
1013*4882a593Smuzhiyun int curChild = 0;
1014*4882a593Smuzhiyun
1015*4882a593Smuzhiyun childIDs = xallocarray(numChildren, sizeof(Window));
1016*4882a593Smuzhiyun if (!childIDs)
1017*4882a593Smuzhiyun return BadAlloc;
1018*4882a593Smuzhiyun for (pChild = pWin->lastChild; pChild != pHead;
1019*4882a593Smuzhiyun pChild = pChild->prevSib)
1020*4882a593Smuzhiyun childIDs[curChild++] = pChild->drawable.id;
1021*4882a593Smuzhiyun }
1022*4882a593Smuzhiyun
1023*4882a593Smuzhiyun reply.nChildren = numChildren;
1024*4882a593Smuzhiyun reply.length = bytes_to_int32(numChildren * sizeof(Window));
1025*4882a593Smuzhiyun
1026*4882a593Smuzhiyun WriteReplyToClient(client, sizeof(xQueryTreeReply), &reply);
1027*4882a593Smuzhiyun if (numChildren) {
1028*4882a593Smuzhiyun client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
1029*4882a593Smuzhiyun WriteSwappedDataToClient(client, numChildren * sizeof(Window),
1030*4882a593Smuzhiyun childIDs);
1031*4882a593Smuzhiyun free(childIDs);
1032*4882a593Smuzhiyun }
1033*4882a593Smuzhiyun
1034*4882a593Smuzhiyun return Success;
1035*4882a593Smuzhiyun }
1036*4882a593Smuzhiyun
1037*4882a593Smuzhiyun int
ProcInternAtom(ClientPtr client)1038*4882a593Smuzhiyun ProcInternAtom(ClientPtr client)
1039*4882a593Smuzhiyun {
1040*4882a593Smuzhiyun Atom atom;
1041*4882a593Smuzhiyun char *tchar;
1042*4882a593Smuzhiyun
1043*4882a593Smuzhiyun REQUEST(xInternAtomReq);
1044*4882a593Smuzhiyun
1045*4882a593Smuzhiyun REQUEST_FIXED_SIZE(xInternAtomReq, stuff->nbytes);
1046*4882a593Smuzhiyun if ((stuff->onlyIfExists != xTrue) && (stuff->onlyIfExists != xFalse)) {
1047*4882a593Smuzhiyun client->errorValue = stuff->onlyIfExists;
1048*4882a593Smuzhiyun return BadValue;
1049*4882a593Smuzhiyun }
1050*4882a593Smuzhiyun tchar = (char *) &stuff[1];
1051*4882a593Smuzhiyun atom = MakeAtom(tchar, stuff->nbytes, !stuff->onlyIfExists);
1052*4882a593Smuzhiyun if (atom != BAD_RESOURCE) {
1053*4882a593Smuzhiyun xInternAtomReply reply = {
1054*4882a593Smuzhiyun .type = X_Reply,
1055*4882a593Smuzhiyun .sequenceNumber = client->sequence,
1056*4882a593Smuzhiyun .length = 0,
1057*4882a593Smuzhiyun .atom = atom
1058*4882a593Smuzhiyun };
1059*4882a593Smuzhiyun WriteReplyToClient(client, sizeof(xInternAtomReply), &reply);
1060*4882a593Smuzhiyun return Success;
1061*4882a593Smuzhiyun }
1062*4882a593Smuzhiyun else
1063*4882a593Smuzhiyun return BadAlloc;
1064*4882a593Smuzhiyun }
1065*4882a593Smuzhiyun
1066*4882a593Smuzhiyun int
ProcGetAtomName(ClientPtr client)1067*4882a593Smuzhiyun ProcGetAtomName(ClientPtr client)
1068*4882a593Smuzhiyun {
1069*4882a593Smuzhiyun const char *str;
1070*4882a593Smuzhiyun
1071*4882a593Smuzhiyun REQUEST(xResourceReq);
1072*4882a593Smuzhiyun
1073*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xResourceReq);
1074*4882a593Smuzhiyun if ((str = NameForAtom(stuff->id))) {
1075*4882a593Smuzhiyun int len = strlen(str);
1076*4882a593Smuzhiyun xGetAtomNameReply reply = {
1077*4882a593Smuzhiyun .type = X_Reply,
1078*4882a593Smuzhiyun .sequenceNumber = client->sequence,
1079*4882a593Smuzhiyun .length = bytes_to_int32(len),
1080*4882a593Smuzhiyun .nameLength = len
1081*4882a593Smuzhiyun };
1082*4882a593Smuzhiyun
1083*4882a593Smuzhiyun WriteReplyToClient(client, sizeof(xGetAtomNameReply), &reply);
1084*4882a593Smuzhiyun WriteToClient(client, len, str);
1085*4882a593Smuzhiyun return Success;
1086*4882a593Smuzhiyun }
1087*4882a593Smuzhiyun else {
1088*4882a593Smuzhiyun client->errorValue = stuff->id;
1089*4882a593Smuzhiyun return BadAtom;
1090*4882a593Smuzhiyun }
1091*4882a593Smuzhiyun }
1092*4882a593Smuzhiyun
1093*4882a593Smuzhiyun int
ProcGrabServer(ClientPtr client)1094*4882a593Smuzhiyun ProcGrabServer(ClientPtr client)
1095*4882a593Smuzhiyun {
1096*4882a593Smuzhiyun int rc;
1097*4882a593Smuzhiyun
1098*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xReq);
1099*4882a593Smuzhiyun if (grabState != GrabNone && client != grabClient) {
1100*4882a593Smuzhiyun ResetCurrentRequest(client);
1101*4882a593Smuzhiyun client->sequence--;
1102*4882a593Smuzhiyun BITSET(grabWaiters, client->index);
1103*4882a593Smuzhiyun IgnoreClient(client);
1104*4882a593Smuzhiyun return Success;
1105*4882a593Smuzhiyun }
1106*4882a593Smuzhiyun rc = OnlyListenToOneClient(client);
1107*4882a593Smuzhiyun if (rc != Success)
1108*4882a593Smuzhiyun return rc;
1109*4882a593Smuzhiyun grabState = GrabActive;
1110*4882a593Smuzhiyun grabClient = client;
1111*4882a593Smuzhiyun mark_client_grab(client);
1112*4882a593Smuzhiyun
1113*4882a593Smuzhiyun if (ServerGrabCallback) {
1114*4882a593Smuzhiyun ServerGrabInfoRec grabinfo;
1115*4882a593Smuzhiyun
1116*4882a593Smuzhiyun grabinfo.client = client;
1117*4882a593Smuzhiyun grabinfo.grabstate = SERVER_GRABBED;
1118*4882a593Smuzhiyun CallCallbacks(&ServerGrabCallback, (void *) &grabinfo);
1119*4882a593Smuzhiyun }
1120*4882a593Smuzhiyun
1121*4882a593Smuzhiyun return Success;
1122*4882a593Smuzhiyun }
1123*4882a593Smuzhiyun
1124*4882a593Smuzhiyun static void
UngrabServer(ClientPtr client)1125*4882a593Smuzhiyun UngrabServer(ClientPtr client)
1126*4882a593Smuzhiyun {
1127*4882a593Smuzhiyun int i;
1128*4882a593Smuzhiyun
1129*4882a593Smuzhiyun grabState = GrabNone;
1130*4882a593Smuzhiyun ListenToAllClients();
1131*4882a593Smuzhiyun mark_client_ungrab();
1132*4882a593Smuzhiyun for (i = mskcnt; --i >= 0 && !grabWaiters[i];);
1133*4882a593Smuzhiyun if (i >= 0) {
1134*4882a593Smuzhiyun i <<= 5;
1135*4882a593Smuzhiyun while (!GETBIT(grabWaiters, i))
1136*4882a593Smuzhiyun i++;
1137*4882a593Smuzhiyun BITCLEAR(grabWaiters, i);
1138*4882a593Smuzhiyun AttendClient(clients[i]);
1139*4882a593Smuzhiyun }
1140*4882a593Smuzhiyun
1141*4882a593Smuzhiyun if (ServerGrabCallback) {
1142*4882a593Smuzhiyun ServerGrabInfoRec grabinfo;
1143*4882a593Smuzhiyun
1144*4882a593Smuzhiyun grabinfo.client = client;
1145*4882a593Smuzhiyun grabinfo.grabstate = SERVER_UNGRABBED;
1146*4882a593Smuzhiyun CallCallbacks(&ServerGrabCallback, (void *) &grabinfo);
1147*4882a593Smuzhiyun }
1148*4882a593Smuzhiyun }
1149*4882a593Smuzhiyun
1150*4882a593Smuzhiyun int
ProcUngrabServer(ClientPtr client)1151*4882a593Smuzhiyun ProcUngrabServer(ClientPtr client)
1152*4882a593Smuzhiyun {
1153*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xReq);
1154*4882a593Smuzhiyun UngrabServer(client);
1155*4882a593Smuzhiyun return Success;
1156*4882a593Smuzhiyun }
1157*4882a593Smuzhiyun
1158*4882a593Smuzhiyun int
ProcTranslateCoords(ClientPtr client)1159*4882a593Smuzhiyun ProcTranslateCoords(ClientPtr client)
1160*4882a593Smuzhiyun {
1161*4882a593Smuzhiyun REQUEST(xTranslateCoordsReq);
1162*4882a593Smuzhiyun
1163*4882a593Smuzhiyun WindowPtr pWin, pDst;
1164*4882a593Smuzhiyun xTranslateCoordsReply rep;
1165*4882a593Smuzhiyun int rc;
1166*4882a593Smuzhiyun
1167*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xTranslateCoordsReq);
1168*4882a593Smuzhiyun rc = dixLookupWindow(&pWin, stuff->srcWid, client, DixGetAttrAccess);
1169*4882a593Smuzhiyun if (rc != Success)
1170*4882a593Smuzhiyun return rc;
1171*4882a593Smuzhiyun rc = dixLookupWindow(&pDst, stuff->dstWid, client, DixGetAttrAccess);
1172*4882a593Smuzhiyun if (rc != Success)
1173*4882a593Smuzhiyun return rc;
1174*4882a593Smuzhiyun
1175*4882a593Smuzhiyun rep = (xTranslateCoordsReply) {
1176*4882a593Smuzhiyun .type = X_Reply,
1177*4882a593Smuzhiyun .sequenceNumber = client->sequence,
1178*4882a593Smuzhiyun .length = 0
1179*4882a593Smuzhiyun };
1180*4882a593Smuzhiyun if (!SAME_SCREENS(pWin->drawable, pDst->drawable)) {
1181*4882a593Smuzhiyun rep.sameScreen = xFalse;
1182*4882a593Smuzhiyun rep.child = None;
1183*4882a593Smuzhiyun rep.dstX = rep.dstY = 0;
1184*4882a593Smuzhiyun }
1185*4882a593Smuzhiyun else {
1186*4882a593Smuzhiyun INT16 x, y;
1187*4882a593Smuzhiyun
1188*4882a593Smuzhiyun rep.sameScreen = xTrue;
1189*4882a593Smuzhiyun rep.child = None;
1190*4882a593Smuzhiyun /* computing absolute coordinates -- adjust to destination later */
1191*4882a593Smuzhiyun x = pWin->drawable.x + stuff->srcX;
1192*4882a593Smuzhiyun y = pWin->drawable.y + stuff->srcY;
1193*4882a593Smuzhiyun pWin = pDst->firstChild;
1194*4882a593Smuzhiyun while (pWin) {
1195*4882a593Smuzhiyun BoxRec box;
1196*4882a593Smuzhiyun
1197*4882a593Smuzhiyun if ((pWin->mapped) &&
1198*4882a593Smuzhiyun (x >= pWin->drawable.x - wBorderWidth(pWin)) &&
1199*4882a593Smuzhiyun (x < pWin->drawable.x + (int) pWin->drawable.width +
1200*4882a593Smuzhiyun wBorderWidth(pWin)) &&
1201*4882a593Smuzhiyun (y >= pWin->drawable.y - wBorderWidth(pWin)) &&
1202*4882a593Smuzhiyun (y < pWin->drawable.y + (int) pWin->drawable.height +
1203*4882a593Smuzhiyun wBorderWidth(pWin))
1204*4882a593Smuzhiyun /* When a window is shaped, a further check
1205*4882a593Smuzhiyun * is made to see if the point is inside
1206*4882a593Smuzhiyun * borderSize
1207*4882a593Smuzhiyun */
1208*4882a593Smuzhiyun && (!wBoundingShape(pWin) ||
1209*4882a593Smuzhiyun RegionContainsPoint(&pWin->borderSize, x, y, &box))
1210*4882a593Smuzhiyun
1211*4882a593Smuzhiyun && (!wInputShape(pWin) ||
1212*4882a593Smuzhiyun RegionContainsPoint(wInputShape(pWin),
1213*4882a593Smuzhiyun x - pWin->drawable.x,
1214*4882a593Smuzhiyun y - pWin->drawable.y, &box))
1215*4882a593Smuzhiyun ) {
1216*4882a593Smuzhiyun rep.child = pWin->drawable.id;
1217*4882a593Smuzhiyun pWin = (WindowPtr) NULL;
1218*4882a593Smuzhiyun }
1219*4882a593Smuzhiyun else
1220*4882a593Smuzhiyun pWin = pWin->nextSib;
1221*4882a593Smuzhiyun }
1222*4882a593Smuzhiyun /* adjust to destination coordinates */
1223*4882a593Smuzhiyun rep.dstX = x - pDst->drawable.x;
1224*4882a593Smuzhiyun rep.dstY = y - pDst->drawable.y;
1225*4882a593Smuzhiyun }
1226*4882a593Smuzhiyun WriteReplyToClient(client, sizeof(xTranslateCoordsReply), &rep);
1227*4882a593Smuzhiyun return Success;
1228*4882a593Smuzhiyun }
1229*4882a593Smuzhiyun
1230*4882a593Smuzhiyun int
ProcOpenFont(ClientPtr client)1231*4882a593Smuzhiyun ProcOpenFont(ClientPtr client)
1232*4882a593Smuzhiyun {
1233*4882a593Smuzhiyun int err;
1234*4882a593Smuzhiyun
1235*4882a593Smuzhiyun REQUEST(xOpenFontReq);
1236*4882a593Smuzhiyun
1237*4882a593Smuzhiyun REQUEST_FIXED_SIZE(xOpenFontReq, stuff->nbytes);
1238*4882a593Smuzhiyun client->errorValue = stuff->fid;
1239*4882a593Smuzhiyun LEGAL_NEW_RESOURCE(stuff->fid, client);
1240*4882a593Smuzhiyun err = OpenFont(client, stuff->fid, (Mask) 0,
1241*4882a593Smuzhiyun stuff->nbytes, (char *) &stuff[1]);
1242*4882a593Smuzhiyun if (err == Success) {
1243*4882a593Smuzhiyun return Success;
1244*4882a593Smuzhiyun }
1245*4882a593Smuzhiyun else
1246*4882a593Smuzhiyun return err;
1247*4882a593Smuzhiyun }
1248*4882a593Smuzhiyun
1249*4882a593Smuzhiyun int
ProcCloseFont(ClientPtr client)1250*4882a593Smuzhiyun ProcCloseFont(ClientPtr client)
1251*4882a593Smuzhiyun {
1252*4882a593Smuzhiyun FontPtr pFont;
1253*4882a593Smuzhiyun int rc;
1254*4882a593Smuzhiyun
1255*4882a593Smuzhiyun REQUEST(xResourceReq);
1256*4882a593Smuzhiyun
1257*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xResourceReq);
1258*4882a593Smuzhiyun rc = dixLookupResourceByType((void **) &pFont, stuff->id, RT_FONT,
1259*4882a593Smuzhiyun client, DixDestroyAccess);
1260*4882a593Smuzhiyun if (rc == Success) {
1261*4882a593Smuzhiyun FreeResource(stuff->id, RT_NONE);
1262*4882a593Smuzhiyun return Success;
1263*4882a593Smuzhiyun }
1264*4882a593Smuzhiyun else {
1265*4882a593Smuzhiyun client->errorValue = stuff->id;
1266*4882a593Smuzhiyun return rc;
1267*4882a593Smuzhiyun }
1268*4882a593Smuzhiyun }
1269*4882a593Smuzhiyun
1270*4882a593Smuzhiyun int
ProcQueryFont(ClientPtr client)1271*4882a593Smuzhiyun ProcQueryFont(ClientPtr client)
1272*4882a593Smuzhiyun {
1273*4882a593Smuzhiyun xQueryFontReply *reply;
1274*4882a593Smuzhiyun FontPtr pFont;
1275*4882a593Smuzhiyun int rc;
1276*4882a593Smuzhiyun
1277*4882a593Smuzhiyun REQUEST(xResourceReq);
1278*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xResourceReq);
1279*4882a593Smuzhiyun
1280*4882a593Smuzhiyun rc = dixLookupFontable(&pFont, stuff->id, client, DixGetAttrAccess);
1281*4882a593Smuzhiyun if (rc != Success)
1282*4882a593Smuzhiyun return rc;
1283*4882a593Smuzhiyun
1284*4882a593Smuzhiyun {
1285*4882a593Smuzhiyun xCharInfo *pmax = FONTINKMAX(pFont);
1286*4882a593Smuzhiyun xCharInfo *pmin = FONTINKMIN(pFont);
1287*4882a593Smuzhiyun int nprotoxcistructs;
1288*4882a593Smuzhiyun int rlength;
1289*4882a593Smuzhiyun
1290*4882a593Smuzhiyun nprotoxcistructs = (pmax->rightSideBearing == pmin->rightSideBearing &&
1291*4882a593Smuzhiyun pmax->leftSideBearing == pmin->leftSideBearing &&
1292*4882a593Smuzhiyun pmax->descent == pmin->descent &&
1293*4882a593Smuzhiyun pmax->ascent == pmin->ascent &&
1294*4882a593Smuzhiyun pmax->characterWidth == pmin->characterWidth) ?
1295*4882a593Smuzhiyun 0 : N2dChars(pFont);
1296*4882a593Smuzhiyun
1297*4882a593Smuzhiyun rlength = sizeof(xQueryFontReply) +
1298*4882a593Smuzhiyun FONTINFONPROPS(FONTCHARSET(pFont)) * sizeof(xFontProp) +
1299*4882a593Smuzhiyun nprotoxcistructs * sizeof(xCharInfo);
1300*4882a593Smuzhiyun reply = calloc(1, rlength);
1301*4882a593Smuzhiyun if (!reply) {
1302*4882a593Smuzhiyun return BadAlloc;
1303*4882a593Smuzhiyun }
1304*4882a593Smuzhiyun
1305*4882a593Smuzhiyun reply->type = X_Reply;
1306*4882a593Smuzhiyun reply->length = bytes_to_int32(rlength - sizeof(xGenericReply));
1307*4882a593Smuzhiyun reply->sequenceNumber = client->sequence;
1308*4882a593Smuzhiyun QueryFont(pFont, reply, nprotoxcistructs);
1309*4882a593Smuzhiyun
1310*4882a593Smuzhiyun WriteReplyToClient(client, rlength, reply);
1311*4882a593Smuzhiyun free(reply);
1312*4882a593Smuzhiyun return Success;
1313*4882a593Smuzhiyun }
1314*4882a593Smuzhiyun }
1315*4882a593Smuzhiyun
1316*4882a593Smuzhiyun int
ProcQueryTextExtents(ClientPtr client)1317*4882a593Smuzhiyun ProcQueryTextExtents(ClientPtr client)
1318*4882a593Smuzhiyun {
1319*4882a593Smuzhiyun xQueryTextExtentsReply reply;
1320*4882a593Smuzhiyun FontPtr pFont;
1321*4882a593Smuzhiyun ExtentInfoRec info;
1322*4882a593Smuzhiyun unsigned long length;
1323*4882a593Smuzhiyun int rc;
1324*4882a593Smuzhiyun
1325*4882a593Smuzhiyun REQUEST(xQueryTextExtentsReq);
1326*4882a593Smuzhiyun REQUEST_AT_LEAST_SIZE(xQueryTextExtentsReq);
1327*4882a593Smuzhiyun
1328*4882a593Smuzhiyun rc = dixLookupFontable(&pFont, stuff->fid, client, DixGetAttrAccess);
1329*4882a593Smuzhiyun if (rc != Success)
1330*4882a593Smuzhiyun return rc;
1331*4882a593Smuzhiyun
1332*4882a593Smuzhiyun length = client->req_len - bytes_to_int32(sizeof(xQueryTextExtentsReq));
1333*4882a593Smuzhiyun length = length << 1;
1334*4882a593Smuzhiyun if (stuff->oddLength) {
1335*4882a593Smuzhiyun if (length == 0)
1336*4882a593Smuzhiyun return BadLength;
1337*4882a593Smuzhiyun length--;
1338*4882a593Smuzhiyun }
1339*4882a593Smuzhiyun if (!xfont2_query_text_extents(pFont, length, (unsigned char *) &stuff[1], &info))
1340*4882a593Smuzhiyun return BadAlloc;
1341*4882a593Smuzhiyun reply = (xQueryTextExtentsReply) {
1342*4882a593Smuzhiyun .type = X_Reply,
1343*4882a593Smuzhiyun .drawDirection = info.drawDirection,
1344*4882a593Smuzhiyun .sequenceNumber = client->sequence,
1345*4882a593Smuzhiyun .length = 0,
1346*4882a593Smuzhiyun .fontAscent = info.fontAscent,
1347*4882a593Smuzhiyun .fontDescent = info.fontDescent,
1348*4882a593Smuzhiyun .overallAscent = info.overallAscent,
1349*4882a593Smuzhiyun .overallDescent = info.overallDescent,
1350*4882a593Smuzhiyun .overallWidth = info.overallWidth,
1351*4882a593Smuzhiyun .overallLeft = info.overallLeft,
1352*4882a593Smuzhiyun .overallRight = info.overallRight
1353*4882a593Smuzhiyun };
1354*4882a593Smuzhiyun WriteReplyToClient(client, sizeof(xQueryTextExtentsReply), &reply);
1355*4882a593Smuzhiyun return Success;
1356*4882a593Smuzhiyun }
1357*4882a593Smuzhiyun
1358*4882a593Smuzhiyun int
ProcListFonts(ClientPtr client)1359*4882a593Smuzhiyun ProcListFonts(ClientPtr client)
1360*4882a593Smuzhiyun {
1361*4882a593Smuzhiyun REQUEST(xListFontsReq);
1362*4882a593Smuzhiyun
1363*4882a593Smuzhiyun REQUEST_FIXED_SIZE(xListFontsReq, stuff->nbytes);
1364*4882a593Smuzhiyun
1365*4882a593Smuzhiyun return ListFonts(client, (unsigned char *) &stuff[1], stuff->nbytes,
1366*4882a593Smuzhiyun stuff->maxNames);
1367*4882a593Smuzhiyun }
1368*4882a593Smuzhiyun
1369*4882a593Smuzhiyun int
ProcListFontsWithInfo(ClientPtr client)1370*4882a593Smuzhiyun ProcListFontsWithInfo(ClientPtr client)
1371*4882a593Smuzhiyun {
1372*4882a593Smuzhiyun REQUEST(xListFontsWithInfoReq);
1373*4882a593Smuzhiyun
1374*4882a593Smuzhiyun REQUEST_FIXED_SIZE(xListFontsWithInfoReq, stuff->nbytes);
1375*4882a593Smuzhiyun
1376*4882a593Smuzhiyun return StartListFontsWithInfo(client, stuff->nbytes,
1377*4882a593Smuzhiyun (unsigned char *) &stuff[1], stuff->maxNames);
1378*4882a593Smuzhiyun }
1379*4882a593Smuzhiyun
1380*4882a593Smuzhiyun /**
1381*4882a593Smuzhiyun *
1382*4882a593Smuzhiyun * \param value must conform to DeleteType
1383*4882a593Smuzhiyun */
1384*4882a593Smuzhiyun int
dixDestroyPixmap(void * value,XID pid)1385*4882a593Smuzhiyun dixDestroyPixmap(void *value, XID pid)
1386*4882a593Smuzhiyun {
1387*4882a593Smuzhiyun PixmapPtr pPixmap = (PixmapPtr) value;
1388*4882a593Smuzhiyun
1389*4882a593Smuzhiyun return (*pPixmap->drawable.pScreen->DestroyPixmap) (pPixmap);
1390*4882a593Smuzhiyun }
1391*4882a593Smuzhiyun
1392*4882a593Smuzhiyun int
ProcCreatePixmap(ClientPtr client)1393*4882a593Smuzhiyun ProcCreatePixmap(ClientPtr client)
1394*4882a593Smuzhiyun {
1395*4882a593Smuzhiyun PixmapPtr pMap;
1396*4882a593Smuzhiyun DrawablePtr pDraw;
1397*4882a593Smuzhiyun
1398*4882a593Smuzhiyun REQUEST(xCreatePixmapReq);
1399*4882a593Smuzhiyun DepthPtr pDepth;
1400*4882a593Smuzhiyun int i, rc;
1401*4882a593Smuzhiyun
1402*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xCreatePixmapReq);
1403*4882a593Smuzhiyun client->errorValue = stuff->pid;
1404*4882a593Smuzhiyun LEGAL_NEW_RESOURCE(stuff->pid, client);
1405*4882a593Smuzhiyun
1406*4882a593Smuzhiyun rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY,
1407*4882a593Smuzhiyun DixGetAttrAccess);
1408*4882a593Smuzhiyun if (rc != Success)
1409*4882a593Smuzhiyun return rc;
1410*4882a593Smuzhiyun
1411*4882a593Smuzhiyun if (!stuff->width || !stuff->height) {
1412*4882a593Smuzhiyun client->errorValue = 0;
1413*4882a593Smuzhiyun return BadValue;
1414*4882a593Smuzhiyun }
1415*4882a593Smuzhiyun if (stuff->width > 32767 || stuff->height > 32767) {
1416*4882a593Smuzhiyun /* It is allowed to try and allocate a pixmap which is larger than
1417*4882a593Smuzhiyun * 32767 in either dimension. However, all of the framebuffer code
1418*4882a593Smuzhiyun * is buggy and does not reliably draw to such big pixmaps, basically
1419*4882a593Smuzhiyun * because the Region data structure operates with signed shorts
1420*4882a593Smuzhiyun * for the rectangles in it.
1421*4882a593Smuzhiyun *
1422*4882a593Smuzhiyun * Furthermore, several places in the X server computes the
1423*4882a593Smuzhiyun * size in bytes of the pixmap and tries to store it in an
1424*4882a593Smuzhiyun * integer. This integer can overflow and cause the allocated size
1425*4882a593Smuzhiyun * to be much smaller.
1426*4882a593Smuzhiyun *
1427*4882a593Smuzhiyun * So, such big pixmaps are rejected here with a BadAlloc
1428*4882a593Smuzhiyun */
1429*4882a593Smuzhiyun return BadAlloc;
1430*4882a593Smuzhiyun }
1431*4882a593Smuzhiyun if (stuff->depth != 1) {
1432*4882a593Smuzhiyun pDepth = pDraw->pScreen->allowedDepths;
1433*4882a593Smuzhiyun for (i = 0; i < pDraw->pScreen->numDepths; i++, pDepth++)
1434*4882a593Smuzhiyun if (pDepth->depth == stuff->depth)
1435*4882a593Smuzhiyun goto CreatePmap;
1436*4882a593Smuzhiyun client->errorValue = stuff->depth;
1437*4882a593Smuzhiyun return BadValue;
1438*4882a593Smuzhiyun }
1439*4882a593Smuzhiyun CreatePmap:
1440*4882a593Smuzhiyun pMap = (PixmapPtr) (*pDraw->pScreen->CreatePixmap)
1441*4882a593Smuzhiyun (pDraw->pScreen, stuff->width, stuff->height, stuff->depth, 0);
1442*4882a593Smuzhiyun if (pMap) {
1443*4882a593Smuzhiyun pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
1444*4882a593Smuzhiyun pMap->drawable.id = stuff->pid;
1445*4882a593Smuzhiyun /* security creation/labeling check */
1446*4882a593Smuzhiyun rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, RT_PIXMAP,
1447*4882a593Smuzhiyun pMap, RT_NONE, NULL, DixCreateAccess);
1448*4882a593Smuzhiyun if (rc != Success) {
1449*4882a593Smuzhiyun (*pDraw->pScreen->DestroyPixmap) (pMap);
1450*4882a593Smuzhiyun return rc;
1451*4882a593Smuzhiyun }
1452*4882a593Smuzhiyun if (AddResource(stuff->pid, RT_PIXMAP, (void *) pMap))
1453*4882a593Smuzhiyun return Success;
1454*4882a593Smuzhiyun }
1455*4882a593Smuzhiyun return BadAlloc;
1456*4882a593Smuzhiyun }
1457*4882a593Smuzhiyun
1458*4882a593Smuzhiyun int
ProcFreePixmap(ClientPtr client)1459*4882a593Smuzhiyun ProcFreePixmap(ClientPtr client)
1460*4882a593Smuzhiyun {
1461*4882a593Smuzhiyun PixmapPtr pMap;
1462*4882a593Smuzhiyun int rc;
1463*4882a593Smuzhiyun
1464*4882a593Smuzhiyun REQUEST(xResourceReq);
1465*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xResourceReq);
1466*4882a593Smuzhiyun
1467*4882a593Smuzhiyun rc = dixLookupResourceByType((void **) &pMap, stuff->id, RT_PIXMAP,
1468*4882a593Smuzhiyun client, DixDestroyAccess);
1469*4882a593Smuzhiyun if (rc == Success) {
1470*4882a593Smuzhiyun FreeResource(stuff->id, RT_NONE);
1471*4882a593Smuzhiyun return Success;
1472*4882a593Smuzhiyun }
1473*4882a593Smuzhiyun else {
1474*4882a593Smuzhiyun client->errorValue = stuff->id;
1475*4882a593Smuzhiyun return rc;
1476*4882a593Smuzhiyun }
1477*4882a593Smuzhiyun }
1478*4882a593Smuzhiyun
1479*4882a593Smuzhiyun int
ProcCreateGC(ClientPtr client)1480*4882a593Smuzhiyun ProcCreateGC(ClientPtr client)
1481*4882a593Smuzhiyun {
1482*4882a593Smuzhiyun int error, rc;
1483*4882a593Smuzhiyun GC *pGC;
1484*4882a593Smuzhiyun DrawablePtr pDraw;
1485*4882a593Smuzhiyun unsigned len;
1486*4882a593Smuzhiyun
1487*4882a593Smuzhiyun REQUEST(xCreateGCReq);
1488*4882a593Smuzhiyun
1489*4882a593Smuzhiyun REQUEST_AT_LEAST_SIZE(xCreateGCReq);
1490*4882a593Smuzhiyun client->errorValue = stuff->gc;
1491*4882a593Smuzhiyun LEGAL_NEW_RESOURCE(stuff->gc, client);
1492*4882a593Smuzhiyun rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0,
1493*4882a593Smuzhiyun DixGetAttrAccess);
1494*4882a593Smuzhiyun if (rc != Success)
1495*4882a593Smuzhiyun return rc;
1496*4882a593Smuzhiyun
1497*4882a593Smuzhiyun len = client->req_len - bytes_to_int32(sizeof(xCreateGCReq));
1498*4882a593Smuzhiyun if (len != Ones(stuff->mask))
1499*4882a593Smuzhiyun return BadLength;
1500*4882a593Smuzhiyun pGC = (GC *) CreateGC(pDraw, stuff->mask, (XID *) &stuff[1], &error,
1501*4882a593Smuzhiyun stuff->gc, client);
1502*4882a593Smuzhiyun if (error != Success)
1503*4882a593Smuzhiyun return error;
1504*4882a593Smuzhiyun if (!AddResource(stuff->gc, RT_GC, (void *) pGC))
1505*4882a593Smuzhiyun return BadAlloc;
1506*4882a593Smuzhiyun return Success;
1507*4882a593Smuzhiyun }
1508*4882a593Smuzhiyun
1509*4882a593Smuzhiyun int
ProcChangeGC(ClientPtr client)1510*4882a593Smuzhiyun ProcChangeGC(ClientPtr client)
1511*4882a593Smuzhiyun {
1512*4882a593Smuzhiyun GC *pGC;
1513*4882a593Smuzhiyun int result;
1514*4882a593Smuzhiyun unsigned len;
1515*4882a593Smuzhiyun
1516*4882a593Smuzhiyun REQUEST(xChangeGCReq);
1517*4882a593Smuzhiyun REQUEST_AT_LEAST_SIZE(xChangeGCReq);
1518*4882a593Smuzhiyun
1519*4882a593Smuzhiyun result = dixLookupGC(&pGC, stuff->gc, client, DixSetAttrAccess);
1520*4882a593Smuzhiyun if (result != Success)
1521*4882a593Smuzhiyun return result;
1522*4882a593Smuzhiyun
1523*4882a593Smuzhiyun len = client->req_len - bytes_to_int32(sizeof(xChangeGCReq));
1524*4882a593Smuzhiyun if (len != Ones(stuff->mask))
1525*4882a593Smuzhiyun return BadLength;
1526*4882a593Smuzhiyun
1527*4882a593Smuzhiyun return ChangeGCXIDs(client, pGC, stuff->mask, (CARD32 *) &stuff[1]);
1528*4882a593Smuzhiyun }
1529*4882a593Smuzhiyun
1530*4882a593Smuzhiyun int
ProcCopyGC(ClientPtr client)1531*4882a593Smuzhiyun ProcCopyGC(ClientPtr client)
1532*4882a593Smuzhiyun {
1533*4882a593Smuzhiyun GC *dstGC;
1534*4882a593Smuzhiyun GC *pGC;
1535*4882a593Smuzhiyun int result;
1536*4882a593Smuzhiyun
1537*4882a593Smuzhiyun REQUEST(xCopyGCReq);
1538*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xCopyGCReq);
1539*4882a593Smuzhiyun
1540*4882a593Smuzhiyun result = dixLookupGC(&pGC, stuff->srcGC, client, DixGetAttrAccess);
1541*4882a593Smuzhiyun if (result != Success)
1542*4882a593Smuzhiyun return result;
1543*4882a593Smuzhiyun result = dixLookupGC(&dstGC, stuff->dstGC, client, DixSetAttrAccess);
1544*4882a593Smuzhiyun if (result != Success)
1545*4882a593Smuzhiyun return result;
1546*4882a593Smuzhiyun if ((dstGC->pScreen != pGC->pScreen) || (dstGC->depth != pGC->depth))
1547*4882a593Smuzhiyun return BadMatch;
1548*4882a593Smuzhiyun if (stuff->mask & ~GCAllBits) {
1549*4882a593Smuzhiyun client->errorValue = stuff->mask;
1550*4882a593Smuzhiyun return BadValue;
1551*4882a593Smuzhiyun }
1552*4882a593Smuzhiyun return CopyGC(pGC, dstGC, stuff->mask);
1553*4882a593Smuzhiyun }
1554*4882a593Smuzhiyun
1555*4882a593Smuzhiyun int
ProcSetDashes(ClientPtr client)1556*4882a593Smuzhiyun ProcSetDashes(ClientPtr client)
1557*4882a593Smuzhiyun {
1558*4882a593Smuzhiyun GC *pGC;
1559*4882a593Smuzhiyun int result;
1560*4882a593Smuzhiyun
1561*4882a593Smuzhiyun REQUEST(xSetDashesReq);
1562*4882a593Smuzhiyun
1563*4882a593Smuzhiyun REQUEST_FIXED_SIZE(xSetDashesReq, stuff->nDashes);
1564*4882a593Smuzhiyun if (stuff->nDashes == 0) {
1565*4882a593Smuzhiyun client->errorValue = 0;
1566*4882a593Smuzhiyun return BadValue;
1567*4882a593Smuzhiyun }
1568*4882a593Smuzhiyun
1569*4882a593Smuzhiyun result = dixLookupGC(&pGC, stuff->gc, client, DixSetAttrAccess);
1570*4882a593Smuzhiyun if (result != Success)
1571*4882a593Smuzhiyun return result;
1572*4882a593Smuzhiyun
1573*4882a593Smuzhiyun /* If there's an error, either there's no sensible errorValue,
1574*4882a593Smuzhiyun * or there was a dash segment of 0. */
1575*4882a593Smuzhiyun client->errorValue = 0;
1576*4882a593Smuzhiyun return SetDashes(pGC, stuff->dashOffset, stuff->nDashes,
1577*4882a593Smuzhiyun (unsigned char *) &stuff[1]);
1578*4882a593Smuzhiyun }
1579*4882a593Smuzhiyun
1580*4882a593Smuzhiyun int
ProcSetClipRectangles(ClientPtr client)1581*4882a593Smuzhiyun ProcSetClipRectangles(ClientPtr client)
1582*4882a593Smuzhiyun {
1583*4882a593Smuzhiyun int nr, result;
1584*4882a593Smuzhiyun GC *pGC;
1585*4882a593Smuzhiyun
1586*4882a593Smuzhiyun REQUEST(xSetClipRectanglesReq);
1587*4882a593Smuzhiyun
1588*4882a593Smuzhiyun REQUEST_AT_LEAST_SIZE(xSetClipRectanglesReq);
1589*4882a593Smuzhiyun if ((stuff->ordering != Unsorted) && (stuff->ordering != YSorted) &&
1590*4882a593Smuzhiyun (stuff->ordering != YXSorted) && (stuff->ordering != YXBanded)) {
1591*4882a593Smuzhiyun client->errorValue = stuff->ordering;
1592*4882a593Smuzhiyun return BadValue;
1593*4882a593Smuzhiyun }
1594*4882a593Smuzhiyun result = dixLookupGC(&pGC, stuff->gc, client, DixSetAttrAccess);
1595*4882a593Smuzhiyun if (result != Success)
1596*4882a593Smuzhiyun return result;
1597*4882a593Smuzhiyun
1598*4882a593Smuzhiyun nr = (client->req_len << 2) - sizeof(xSetClipRectanglesReq);
1599*4882a593Smuzhiyun if (nr & 4)
1600*4882a593Smuzhiyun return BadLength;
1601*4882a593Smuzhiyun nr >>= 3;
1602*4882a593Smuzhiyun return SetClipRects(pGC, stuff->xOrigin, stuff->yOrigin,
1603*4882a593Smuzhiyun nr, (xRectangle *) &stuff[1], (int) stuff->ordering);
1604*4882a593Smuzhiyun }
1605*4882a593Smuzhiyun
1606*4882a593Smuzhiyun int
ProcFreeGC(ClientPtr client)1607*4882a593Smuzhiyun ProcFreeGC(ClientPtr client)
1608*4882a593Smuzhiyun {
1609*4882a593Smuzhiyun GC *pGC;
1610*4882a593Smuzhiyun int rc;
1611*4882a593Smuzhiyun
1612*4882a593Smuzhiyun REQUEST(xResourceReq);
1613*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xResourceReq);
1614*4882a593Smuzhiyun
1615*4882a593Smuzhiyun rc = dixLookupGC(&pGC, stuff->id, client, DixDestroyAccess);
1616*4882a593Smuzhiyun if (rc != Success)
1617*4882a593Smuzhiyun return rc;
1618*4882a593Smuzhiyun
1619*4882a593Smuzhiyun FreeResource(stuff->id, RT_NONE);
1620*4882a593Smuzhiyun return Success;
1621*4882a593Smuzhiyun }
1622*4882a593Smuzhiyun
1623*4882a593Smuzhiyun int
ProcClearToBackground(ClientPtr client)1624*4882a593Smuzhiyun ProcClearToBackground(ClientPtr client)
1625*4882a593Smuzhiyun {
1626*4882a593Smuzhiyun REQUEST(xClearAreaReq);
1627*4882a593Smuzhiyun WindowPtr pWin;
1628*4882a593Smuzhiyun int rc;
1629*4882a593Smuzhiyun
1630*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xClearAreaReq);
1631*4882a593Smuzhiyun rc = dixLookupWindow(&pWin, stuff->window, client, DixWriteAccess);
1632*4882a593Smuzhiyun if (rc != Success)
1633*4882a593Smuzhiyun return rc;
1634*4882a593Smuzhiyun if (pWin->drawable.class == InputOnly) {
1635*4882a593Smuzhiyun client->errorValue = stuff->window;
1636*4882a593Smuzhiyun return BadMatch;
1637*4882a593Smuzhiyun }
1638*4882a593Smuzhiyun if ((stuff->exposures != xTrue) && (stuff->exposures != xFalse)) {
1639*4882a593Smuzhiyun client->errorValue = stuff->exposures;
1640*4882a593Smuzhiyun return BadValue;
1641*4882a593Smuzhiyun }
1642*4882a593Smuzhiyun (*pWin->drawable.pScreen->ClearToBackground) (pWin, stuff->x, stuff->y,
1643*4882a593Smuzhiyun stuff->width, stuff->height,
1644*4882a593Smuzhiyun (Bool) stuff->exposures);
1645*4882a593Smuzhiyun return Success;
1646*4882a593Smuzhiyun }
1647*4882a593Smuzhiyun
1648*4882a593Smuzhiyun /* send GraphicsExpose events, or a NoExpose event, based on the region */
1649*4882a593Smuzhiyun void
SendGraphicsExpose(ClientPtr client,RegionPtr pRgn,XID drawable,int major,int minor)1650*4882a593Smuzhiyun SendGraphicsExpose(ClientPtr client, RegionPtr pRgn, XID drawable,
1651*4882a593Smuzhiyun int major, int minor)
1652*4882a593Smuzhiyun {
1653*4882a593Smuzhiyun if (pRgn && !RegionNil(pRgn)) {
1654*4882a593Smuzhiyun xEvent *pEvent;
1655*4882a593Smuzhiyun xEvent *pe;
1656*4882a593Smuzhiyun BoxPtr pBox;
1657*4882a593Smuzhiyun int i;
1658*4882a593Smuzhiyun int numRects;
1659*4882a593Smuzhiyun
1660*4882a593Smuzhiyun numRects = RegionNumRects(pRgn);
1661*4882a593Smuzhiyun pBox = RegionRects(pRgn);
1662*4882a593Smuzhiyun if (!(pEvent = calloc(numRects, sizeof(xEvent))))
1663*4882a593Smuzhiyun return;
1664*4882a593Smuzhiyun pe = pEvent;
1665*4882a593Smuzhiyun
1666*4882a593Smuzhiyun for (i = 1; i <= numRects; i++, pe++, pBox++) {
1667*4882a593Smuzhiyun pe->u.u.type = GraphicsExpose;
1668*4882a593Smuzhiyun pe->u.graphicsExposure.drawable = drawable;
1669*4882a593Smuzhiyun pe->u.graphicsExposure.x = pBox->x1;
1670*4882a593Smuzhiyun pe->u.graphicsExposure.y = pBox->y1;
1671*4882a593Smuzhiyun pe->u.graphicsExposure.width = pBox->x2 - pBox->x1;
1672*4882a593Smuzhiyun pe->u.graphicsExposure.height = pBox->y2 - pBox->y1;
1673*4882a593Smuzhiyun pe->u.graphicsExposure.count = numRects - i;
1674*4882a593Smuzhiyun pe->u.graphicsExposure.majorEvent = major;
1675*4882a593Smuzhiyun pe->u.graphicsExposure.minorEvent = minor;
1676*4882a593Smuzhiyun }
1677*4882a593Smuzhiyun /* GraphicsExpose is a "critical event", which TryClientEvents
1678*4882a593Smuzhiyun * handles specially. */
1679*4882a593Smuzhiyun TryClientEvents(client, NULL, pEvent, numRects,
1680*4882a593Smuzhiyun (Mask) 0, NoEventMask, NullGrab);
1681*4882a593Smuzhiyun free(pEvent);
1682*4882a593Smuzhiyun }
1683*4882a593Smuzhiyun else {
1684*4882a593Smuzhiyun xEvent event = {
1685*4882a593Smuzhiyun .u.noExposure.drawable = drawable,
1686*4882a593Smuzhiyun .u.noExposure.majorEvent = major,
1687*4882a593Smuzhiyun .u.noExposure.minorEvent = minor
1688*4882a593Smuzhiyun };
1689*4882a593Smuzhiyun event.u.u.type = NoExpose;
1690*4882a593Smuzhiyun WriteEventsToClient(client, 1, &event);
1691*4882a593Smuzhiyun }
1692*4882a593Smuzhiyun }
1693*4882a593Smuzhiyun
1694*4882a593Smuzhiyun int
ProcCopyArea(ClientPtr client)1695*4882a593Smuzhiyun ProcCopyArea(ClientPtr client)
1696*4882a593Smuzhiyun {
1697*4882a593Smuzhiyun DrawablePtr pDst;
1698*4882a593Smuzhiyun DrawablePtr pSrc;
1699*4882a593Smuzhiyun GC *pGC;
1700*4882a593Smuzhiyun
1701*4882a593Smuzhiyun REQUEST(xCopyAreaReq);
1702*4882a593Smuzhiyun RegionPtr pRgn;
1703*4882a593Smuzhiyun int rc;
1704*4882a593Smuzhiyun
1705*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xCopyAreaReq);
1706*4882a593Smuzhiyun
1707*4882a593Smuzhiyun VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pDst, DixWriteAccess);
1708*4882a593Smuzhiyun if (stuff->dstDrawable != stuff->srcDrawable) {
1709*4882a593Smuzhiyun rc = dixLookupDrawable(&pSrc, stuff->srcDrawable, client, 0,
1710*4882a593Smuzhiyun DixReadAccess);
1711*4882a593Smuzhiyun if (rc != Success)
1712*4882a593Smuzhiyun return rc;
1713*4882a593Smuzhiyun if ((pDst->pScreen != pSrc->pScreen) || (pDst->depth != pSrc->depth)) {
1714*4882a593Smuzhiyun client->errorValue = stuff->dstDrawable;
1715*4882a593Smuzhiyun return BadMatch;
1716*4882a593Smuzhiyun }
1717*4882a593Smuzhiyun }
1718*4882a593Smuzhiyun else
1719*4882a593Smuzhiyun pSrc = pDst;
1720*4882a593Smuzhiyun
1721*4882a593Smuzhiyun pRgn = (*pGC->ops->CopyArea) (pSrc, pDst, pGC, stuff->srcX, stuff->srcY,
1722*4882a593Smuzhiyun stuff->width, stuff->height,
1723*4882a593Smuzhiyun stuff->dstX, stuff->dstY);
1724*4882a593Smuzhiyun if (pGC->graphicsExposures) {
1725*4882a593Smuzhiyun SendGraphicsExpose(client, pRgn, stuff->dstDrawable, X_CopyArea, 0);
1726*4882a593Smuzhiyun if (pRgn)
1727*4882a593Smuzhiyun RegionDestroy(pRgn);
1728*4882a593Smuzhiyun }
1729*4882a593Smuzhiyun
1730*4882a593Smuzhiyun return Success;
1731*4882a593Smuzhiyun }
1732*4882a593Smuzhiyun
1733*4882a593Smuzhiyun int
ProcCopyPlane(ClientPtr client)1734*4882a593Smuzhiyun ProcCopyPlane(ClientPtr client)
1735*4882a593Smuzhiyun {
1736*4882a593Smuzhiyun DrawablePtr psrcDraw, pdstDraw;
1737*4882a593Smuzhiyun GC *pGC;
1738*4882a593Smuzhiyun
1739*4882a593Smuzhiyun REQUEST(xCopyPlaneReq);
1740*4882a593Smuzhiyun RegionPtr pRgn;
1741*4882a593Smuzhiyun int rc;
1742*4882a593Smuzhiyun
1743*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xCopyPlaneReq);
1744*4882a593Smuzhiyun
1745*4882a593Smuzhiyun VALIDATE_DRAWABLE_AND_GC(stuff->dstDrawable, pdstDraw, DixWriteAccess);
1746*4882a593Smuzhiyun if (stuff->dstDrawable != stuff->srcDrawable) {
1747*4882a593Smuzhiyun rc = dixLookupDrawable(&psrcDraw, stuff->srcDrawable, client, 0,
1748*4882a593Smuzhiyun DixReadAccess);
1749*4882a593Smuzhiyun if (rc != Success)
1750*4882a593Smuzhiyun return rc;
1751*4882a593Smuzhiyun
1752*4882a593Smuzhiyun if (pdstDraw->pScreen != psrcDraw->pScreen) {
1753*4882a593Smuzhiyun client->errorValue = stuff->dstDrawable;
1754*4882a593Smuzhiyun return BadMatch;
1755*4882a593Smuzhiyun }
1756*4882a593Smuzhiyun }
1757*4882a593Smuzhiyun else
1758*4882a593Smuzhiyun psrcDraw = pdstDraw;
1759*4882a593Smuzhiyun
1760*4882a593Smuzhiyun /* Check to see if stuff->bitPlane has exactly ONE good bit set */
1761*4882a593Smuzhiyun if (stuff->bitPlane == 0 || (stuff->bitPlane & (stuff->bitPlane - 1)) ||
1762*4882a593Smuzhiyun (stuff->bitPlane > (1L << (psrcDraw->depth - 1)))) {
1763*4882a593Smuzhiyun client->errorValue = stuff->bitPlane;
1764*4882a593Smuzhiyun return BadValue;
1765*4882a593Smuzhiyun }
1766*4882a593Smuzhiyun
1767*4882a593Smuzhiyun pRgn =
1768*4882a593Smuzhiyun (*pGC->ops->CopyPlane) (psrcDraw, pdstDraw, pGC, stuff->srcX,
1769*4882a593Smuzhiyun stuff->srcY, stuff->width, stuff->height,
1770*4882a593Smuzhiyun stuff->dstX, stuff->dstY, stuff->bitPlane);
1771*4882a593Smuzhiyun if (pGC->graphicsExposures) {
1772*4882a593Smuzhiyun SendGraphicsExpose(client, pRgn, stuff->dstDrawable, X_CopyPlane, 0);
1773*4882a593Smuzhiyun if (pRgn)
1774*4882a593Smuzhiyun RegionDestroy(pRgn);
1775*4882a593Smuzhiyun }
1776*4882a593Smuzhiyun return Success;
1777*4882a593Smuzhiyun }
1778*4882a593Smuzhiyun
1779*4882a593Smuzhiyun int
ProcPolyPoint(ClientPtr client)1780*4882a593Smuzhiyun ProcPolyPoint(ClientPtr client)
1781*4882a593Smuzhiyun {
1782*4882a593Smuzhiyun int npoint;
1783*4882a593Smuzhiyun GC *pGC;
1784*4882a593Smuzhiyun DrawablePtr pDraw;
1785*4882a593Smuzhiyun
1786*4882a593Smuzhiyun REQUEST(xPolyPointReq);
1787*4882a593Smuzhiyun
1788*4882a593Smuzhiyun REQUEST_AT_LEAST_SIZE(xPolyPointReq);
1789*4882a593Smuzhiyun if ((stuff->coordMode != CoordModeOrigin) &&
1790*4882a593Smuzhiyun (stuff->coordMode != CoordModePrevious)) {
1791*4882a593Smuzhiyun client->errorValue = stuff->coordMode;
1792*4882a593Smuzhiyun return BadValue;
1793*4882a593Smuzhiyun }
1794*4882a593Smuzhiyun VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
1795*4882a593Smuzhiyun npoint = bytes_to_int32((client->req_len << 2) - sizeof(xPolyPointReq));
1796*4882a593Smuzhiyun if (npoint)
1797*4882a593Smuzhiyun (*pGC->ops->PolyPoint) (pDraw, pGC, stuff->coordMode, npoint,
1798*4882a593Smuzhiyun (xPoint *) &stuff[1]);
1799*4882a593Smuzhiyun return Success;
1800*4882a593Smuzhiyun }
1801*4882a593Smuzhiyun
1802*4882a593Smuzhiyun int
ProcPolyLine(ClientPtr client)1803*4882a593Smuzhiyun ProcPolyLine(ClientPtr client)
1804*4882a593Smuzhiyun {
1805*4882a593Smuzhiyun int npoint;
1806*4882a593Smuzhiyun GC *pGC;
1807*4882a593Smuzhiyun DrawablePtr pDraw;
1808*4882a593Smuzhiyun
1809*4882a593Smuzhiyun REQUEST(xPolyLineReq);
1810*4882a593Smuzhiyun
1811*4882a593Smuzhiyun REQUEST_AT_LEAST_SIZE(xPolyLineReq);
1812*4882a593Smuzhiyun if ((stuff->coordMode != CoordModeOrigin) &&
1813*4882a593Smuzhiyun (stuff->coordMode != CoordModePrevious)) {
1814*4882a593Smuzhiyun client->errorValue = stuff->coordMode;
1815*4882a593Smuzhiyun return BadValue;
1816*4882a593Smuzhiyun }
1817*4882a593Smuzhiyun VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
1818*4882a593Smuzhiyun npoint = bytes_to_int32((client->req_len << 2) - sizeof(xPolyLineReq));
1819*4882a593Smuzhiyun if (npoint > 1)
1820*4882a593Smuzhiyun (*pGC->ops->Polylines) (pDraw, pGC, stuff->coordMode, npoint,
1821*4882a593Smuzhiyun (DDXPointPtr) &stuff[1]);
1822*4882a593Smuzhiyun return Success;
1823*4882a593Smuzhiyun }
1824*4882a593Smuzhiyun
1825*4882a593Smuzhiyun int
ProcPolySegment(ClientPtr client)1826*4882a593Smuzhiyun ProcPolySegment(ClientPtr client)
1827*4882a593Smuzhiyun {
1828*4882a593Smuzhiyun int nsegs;
1829*4882a593Smuzhiyun GC *pGC;
1830*4882a593Smuzhiyun DrawablePtr pDraw;
1831*4882a593Smuzhiyun
1832*4882a593Smuzhiyun REQUEST(xPolySegmentReq);
1833*4882a593Smuzhiyun
1834*4882a593Smuzhiyun REQUEST_AT_LEAST_SIZE(xPolySegmentReq);
1835*4882a593Smuzhiyun VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
1836*4882a593Smuzhiyun nsegs = (client->req_len << 2) - sizeof(xPolySegmentReq);
1837*4882a593Smuzhiyun if (nsegs & 4)
1838*4882a593Smuzhiyun return BadLength;
1839*4882a593Smuzhiyun nsegs >>= 3;
1840*4882a593Smuzhiyun if (nsegs)
1841*4882a593Smuzhiyun (*pGC->ops->PolySegment) (pDraw, pGC, nsegs, (xSegment *) &stuff[1]);
1842*4882a593Smuzhiyun return Success;
1843*4882a593Smuzhiyun }
1844*4882a593Smuzhiyun
1845*4882a593Smuzhiyun int
ProcPolyRectangle(ClientPtr client)1846*4882a593Smuzhiyun ProcPolyRectangle(ClientPtr client)
1847*4882a593Smuzhiyun {
1848*4882a593Smuzhiyun int nrects;
1849*4882a593Smuzhiyun GC *pGC;
1850*4882a593Smuzhiyun DrawablePtr pDraw;
1851*4882a593Smuzhiyun
1852*4882a593Smuzhiyun REQUEST(xPolyRectangleReq);
1853*4882a593Smuzhiyun
1854*4882a593Smuzhiyun REQUEST_AT_LEAST_SIZE(xPolyRectangleReq);
1855*4882a593Smuzhiyun VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
1856*4882a593Smuzhiyun nrects = (client->req_len << 2) - sizeof(xPolyRectangleReq);
1857*4882a593Smuzhiyun if (nrects & 4)
1858*4882a593Smuzhiyun return BadLength;
1859*4882a593Smuzhiyun nrects >>= 3;
1860*4882a593Smuzhiyun if (nrects)
1861*4882a593Smuzhiyun (*pGC->ops->PolyRectangle) (pDraw, pGC,
1862*4882a593Smuzhiyun nrects, (xRectangle *) &stuff[1]);
1863*4882a593Smuzhiyun return Success;
1864*4882a593Smuzhiyun }
1865*4882a593Smuzhiyun
1866*4882a593Smuzhiyun int
ProcPolyArc(ClientPtr client)1867*4882a593Smuzhiyun ProcPolyArc(ClientPtr client)
1868*4882a593Smuzhiyun {
1869*4882a593Smuzhiyun int narcs;
1870*4882a593Smuzhiyun GC *pGC;
1871*4882a593Smuzhiyun DrawablePtr pDraw;
1872*4882a593Smuzhiyun
1873*4882a593Smuzhiyun REQUEST(xPolyArcReq);
1874*4882a593Smuzhiyun
1875*4882a593Smuzhiyun REQUEST_AT_LEAST_SIZE(xPolyArcReq);
1876*4882a593Smuzhiyun VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
1877*4882a593Smuzhiyun narcs = (client->req_len << 2) - sizeof(xPolyArcReq);
1878*4882a593Smuzhiyun if (narcs % sizeof(xArc))
1879*4882a593Smuzhiyun return BadLength;
1880*4882a593Smuzhiyun narcs /= sizeof(xArc);
1881*4882a593Smuzhiyun if (narcs)
1882*4882a593Smuzhiyun (*pGC->ops->PolyArc) (pDraw, pGC, narcs, (xArc *) &stuff[1]);
1883*4882a593Smuzhiyun return Success;
1884*4882a593Smuzhiyun }
1885*4882a593Smuzhiyun
1886*4882a593Smuzhiyun int
ProcFillPoly(ClientPtr client)1887*4882a593Smuzhiyun ProcFillPoly(ClientPtr client)
1888*4882a593Smuzhiyun {
1889*4882a593Smuzhiyun int things;
1890*4882a593Smuzhiyun GC *pGC;
1891*4882a593Smuzhiyun DrawablePtr pDraw;
1892*4882a593Smuzhiyun
1893*4882a593Smuzhiyun REQUEST(xFillPolyReq);
1894*4882a593Smuzhiyun
1895*4882a593Smuzhiyun REQUEST_AT_LEAST_SIZE(xFillPolyReq);
1896*4882a593Smuzhiyun if ((stuff->shape != Complex) && (stuff->shape != Nonconvex) &&
1897*4882a593Smuzhiyun (stuff->shape != Convex)) {
1898*4882a593Smuzhiyun client->errorValue = stuff->shape;
1899*4882a593Smuzhiyun return BadValue;
1900*4882a593Smuzhiyun }
1901*4882a593Smuzhiyun if ((stuff->coordMode != CoordModeOrigin) &&
1902*4882a593Smuzhiyun (stuff->coordMode != CoordModePrevious)) {
1903*4882a593Smuzhiyun client->errorValue = stuff->coordMode;
1904*4882a593Smuzhiyun return BadValue;
1905*4882a593Smuzhiyun }
1906*4882a593Smuzhiyun
1907*4882a593Smuzhiyun VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
1908*4882a593Smuzhiyun things = bytes_to_int32((client->req_len << 2) - sizeof(xFillPolyReq));
1909*4882a593Smuzhiyun if (things)
1910*4882a593Smuzhiyun (*pGC->ops->FillPolygon) (pDraw, pGC, stuff->shape,
1911*4882a593Smuzhiyun stuff->coordMode, things,
1912*4882a593Smuzhiyun (DDXPointPtr) &stuff[1]);
1913*4882a593Smuzhiyun return Success;
1914*4882a593Smuzhiyun }
1915*4882a593Smuzhiyun
1916*4882a593Smuzhiyun int
ProcPolyFillRectangle(ClientPtr client)1917*4882a593Smuzhiyun ProcPolyFillRectangle(ClientPtr client)
1918*4882a593Smuzhiyun {
1919*4882a593Smuzhiyun int things;
1920*4882a593Smuzhiyun GC *pGC;
1921*4882a593Smuzhiyun DrawablePtr pDraw;
1922*4882a593Smuzhiyun
1923*4882a593Smuzhiyun REQUEST(xPolyFillRectangleReq);
1924*4882a593Smuzhiyun
1925*4882a593Smuzhiyun REQUEST_AT_LEAST_SIZE(xPolyFillRectangleReq);
1926*4882a593Smuzhiyun VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
1927*4882a593Smuzhiyun things = (client->req_len << 2) - sizeof(xPolyFillRectangleReq);
1928*4882a593Smuzhiyun if (things & 4)
1929*4882a593Smuzhiyun return BadLength;
1930*4882a593Smuzhiyun things >>= 3;
1931*4882a593Smuzhiyun
1932*4882a593Smuzhiyun if (things)
1933*4882a593Smuzhiyun (*pGC->ops->PolyFillRect) (pDraw, pGC, things,
1934*4882a593Smuzhiyun (xRectangle *) &stuff[1]);
1935*4882a593Smuzhiyun return Success;
1936*4882a593Smuzhiyun }
1937*4882a593Smuzhiyun
1938*4882a593Smuzhiyun int
ProcPolyFillArc(ClientPtr client)1939*4882a593Smuzhiyun ProcPolyFillArc(ClientPtr client)
1940*4882a593Smuzhiyun {
1941*4882a593Smuzhiyun int narcs;
1942*4882a593Smuzhiyun GC *pGC;
1943*4882a593Smuzhiyun DrawablePtr pDraw;
1944*4882a593Smuzhiyun
1945*4882a593Smuzhiyun REQUEST(xPolyFillArcReq);
1946*4882a593Smuzhiyun
1947*4882a593Smuzhiyun REQUEST_AT_LEAST_SIZE(xPolyFillArcReq);
1948*4882a593Smuzhiyun VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
1949*4882a593Smuzhiyun narcs = (client->req_len << 2) - sizeof(xPolyFillArcReq);
1950*4882a593Smuzhiyun if (narcs % sizeof(xArc))
1951*4882a593Smuzhiyun return BadLength;
1952*4882a593Smuzhiyun narcs /= sizeof(xArc);
1953*4882a593Smuzhiyun if (narcs)
1954*4882a593Smuzhiyun (*pGC->ops->PolyFillArc) (pDraw, pGC, narcs, (xArc *) &stuff[1]);
1955*4882a593Smuzhiyun return Success;
1956*4882a593Smuzhiyun }
1957*4882a593Smuzhiyun
1958*4882a593Smuzhiyun #ifdef MATCH_CLIENT_ENDIAN
1959*4882a593Smuzhiyun
1960*4882a593Smuzhiyun int
ServerOrder(void)1961*4882a593Smuzhiyun ServerOrder(void)
1962*4882a593Smuzhiyun {
1963*4882a593Smuzhiyun int whichbyte = 1;
1964*4882a593Smuzhiyun
1965*4882a593Smuzhiyun if (*((char *) &whichbyte))
1966*4882a593Smuzhiyun return LSBFirst;
1967*4882a593Smuzhiyun return MSBFirst;
1968*4882a593Smuzhiyun }
1969*4882a593Smuzhiyun
1970*4882a593Smuzhiyun #define ClientOrder(client) ((client)->swapped ? !ServerOrder() : ServerOrder())
1971*4882a593Smuzhiyun
1972*4882a593Smuzhiyun void
ReformatImage(char * base,int nbytes,int bpp,int order)1973*4882a593Smuzhiyun ReformatImage(char *base, int nbytes, int bpp, int order)
1974*4882a593Smuzhiyun {
1975*4882a593Smuzhiyun switch (bpp) {
1976*4882a593Smuzhiyun case 1: /* yuck */
1977*4882a593Smuzhiyun if (BITMAP_BIT_ORDER != order)
1978*4882a593Smuzhiyun BitOrderInvert((unsigned char *) base, nbytes);
1979*4882a593Smuzhiyun #if IMAGE_BYTE_ORDER != BITMAP_BIT_ORDER && BITMAP_SCANLINE_UNIT != 8
1980*4882a593Smuzhiyun ReformatImage(base, nbytes, BITMAP_SCANLINE_UNIT, order);
1981*4882a593Smuzhiyun #endif
1982*4882a593Smuzhiyun break;
1983*4882a593Smuzhiyun case 4:
1984*4882a593Smuzhiyun break; /* yuck */
1985*4882a593Smuzhiyun case 8:
1986*4882a593Smuzhiyun break;
1987*4882a593Smuzhiyun case 16:
1988*4882a593Smuzhiyun if (IMAGE_BYTE_ORDER != order)
1989*4882a593Smuzhiyun TwoByteSwap((unsigned char *) base, nbytes);
1990*4882a593Smuzhiyun break;
1991*4882a593Smuzhiyun case 32:
1992*4882a593Smuzhiyun if (IMAGE_BYTE_ORDER != order)
1993*4882a593Smuzhiyun FourByteSwap((unsigned char *) base, nbytes);
1994*4882a593Smuzhiyun break;
1995*4882a593Smuzhiyun }
1996*4882a593Smuzhiyun }
1997*4882a593Smuzhiyun #else
1998*4882a593Smuzhiyun #define ReformatImage(b,n,bpp,o)
1999*4882a593Smuzhiyun #endif
2000*4882a593Smuzhiyun
2001*4882a593Smuzhiyun /* 64-bit server notes: the protocol restricts padding of images to
2002*4882a593Smuzhiyun * 8-, 16-, or 32-bits. We would like to have 64-bits for the server
2003*4882a593Smuzhiyun * to use internally. Removes need for internal alignment checking.
2004*4882a593Smuzhiyun * All of the PutImage functions could be changed individually, but
2005*4882a593Smuzhiyun * as currently written, they call other routines which require things
2006*4882a593Smuzhiyun * to be 64-bit padded on scanlines, so we changed things here.
2007*4882a593Smuzhiyun * If an image would be padded differently for 64- versus 32-, then
2008*4882a593Smuzhiyun * copy each scanline to a 64-bit padded scanline.
2009*4882a593Smuzhiyun * Also, we need to make sure that the image is aligned on a 64-bit
2010*4882a593Smuzhiyun * boundary, even if the scanlines are padded to our satisfaction.
2011*4882a593Smuzhiyun */
2012*4882a593Smuzhiyun int
ProcPutImage(ClientPtr client)2013*4882a593Smuzhiyun ProcPutImage(ClientPtr client)
2014*4882a593Smuzhiyun {
2015*4882a593Smuzhiyun GC *pGC;
2016*4882a593Smuzhiyun DrawablePtr pDraw;
2017*4882a593Smuzhiyun long length; /* length of scanline server padded */
2018*4882a593Smuzhiyun long lengthProto; /* length of scanline protocol padded */
2019*4882a593Smuzhiyun char *tmpImage;
2020*4882a593Smuzhiyun
2021*4882a593Smuzhiyun REQUEST(xPutImageReq);
2022*4882a593Smuzhiyun
2023*4882a593Smuzhiyun REQUEST_AT_LEAST_SIZE(xPutImageReq);
2024*4882a593Smuzhiyun VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
2025*4882a593Smuzhiyun if (stuff->format == XYBitmap) {
2026*4882a593Smuzhiyun if ((stuff->depth != 1) ||
2027*4882a593Smuzhiyun (stuff->leftPad >= (unsigned int) screenInfo.bitmapScanlinePad))
2028*4882a593Smuzhiyun return BadMatch;
2029*4882a593Smuzhiyun length = BitmapBytePad(stuff->width + stuff->leftPad);
2030*4882a593Smuzhiyun }
2031*4882a593Smuzhiyun else if (stuff->format == XYPixmap) {
2032*4882a593Smuzhiyun if ((pDraw->depth != stuff->depth) ||
2033*4882a593Smuzhiyun (stuff->leftPad >= (unsigned int) screenInfo.bitmapScanlinePad))
2034*4882a593Smuzhiyun return BadMatch;
2035*4882a593Smuzhiyun length = BitmapBytePad(stuff->width + stuff->leftPad);
2036*4882a593Smuzhiyun length *= stuff->depth;
2037*4882a593Smuzhiyun }
2038*4882a593Smuzhiyun else if (stuff->format == ZPixmap) {
2039*4882a593Smuzhiyun if ((pDraw->depth != stuff->depth) || (stuff->leftPad != 0))
2040*4882a593Smuzhiyun return BadMatch;
2041*4882a593Smuzhiyun length = PixmapBytePad(stuff->width, stuff->depth);
2042*4882a593Smuzhiyun }
2043*4882a593Smuzhiyun else {
2044*4882a593Smuzhiyun client->errorValue = stuff->format;
2045*4882a593Smuzhiyun return BadValue;
2046*4882a593Smuzhiyun }
2047*4882a593Smuzhiyun
2048*4882a593Smuzhiyun tmpImage = (char *) &stuff[1];
2049*4882a593Smuzhiyun lengthProto = length;
2050*4882a593Smuzhiyun
2051*4882a593Smuzhiyun if (stuff->height != 0 && lengthProto >= (INT32_MAX / stuff->height))
2052*4882a593Smuzhiyun return BadLength;
2053*4882a593Smuzhiyun
2054*4882a593Smuzhiyun if ((bytes_to_int32(lengthProto * stuff->height) +
2055*4882a593Smuzhiyun bytes_to_int32(sizeof(xPutImageReq))) != client->req_len)
2056*4882a593Smuzhiyun return BadLength;
2057*4882a593Smuzhiyun
2058*4882a593Smuzhiyun ReformatImage(tmpImage, lengthProto * stuff->height,
2059*4882a593Smuzhiyun stuff->format == ZPixmap ? BitsPerPixel(stuff->depth) : 1,
2060*4882a593Smuzhiyun ClientOrder(client));
2061*4882a593Smuzhiyun
2062*4882a593Smuzhiyun (*pGC->ops->PutImage) (pDraw, pGC, stuff->depth, stuff->dstX, stuff->dstY,
2063*4882a593Smuzhiyun stuff->width, stuff->height,
2064*4882a593Smuzhiyun stuff->leftPad, stuff->format, tmpImage);
2065*4882a593Smuzhiyun
2066*4882a593Smuzhiyun return Success;
2067*4882a593Smuzhiyun }
2068*4882a593Smuzhiyun
2069*4882a593Smuzhiyun static int
DoGetImage(ClientPtr client,int format,Drawable drawable,int x,int y,int width,int height,Mask planemask)2070*4882a593Smuzhiyun DoGetImage(ClientPtr client, int format, Drawable drawable,
2071*4882a593Smuzhiyun int x, int y, int width, int height,
2072*4882a593Smuzhiyun Mask planemask)
2073*4882a593Smuzhiyun {
2074*4882a593Smuzhiyun DrawablePtr pDraw, pBoundingDraw;
2075*4882a593Smuzhiyun int nlines, linesPerBuf, rc;
2076*4882a593Smuzhiyun int linesDone;
2077*4882a593Smuzhiyun
2078*4882a593Smuzhiyun /* coordinates relative to the bounding drawable */
2079*4882a593Smuzhiyun int relx, rely;
2080*4882a593Smuzhiyun long widthBytesLine, length;
2081*4882a593Smuzhiyun Mask plane = 0;
2082*4882a593Smuzhiyun char *pBuf;
2083*4882a593Smuzhiyun xGetImageReply xgi;
2084*4882a593Smuzhiyun RegionPtr pVisibleRegion = NULL;
2085*4882a593Smuzhiyun
2086*4882a593Smuzhiyun if ((format != XYPixmap) && (format != ZPixmap)) {
2087*4882a593Smuzhiyun client->errorValue = format;
2088*4882a593Smuzhiyun return BadValue;
2089*4882a593Smuzhiyun }
2090*4882a593Smuzhiyun rc = dixLookupDrawable(&pDraw, drawable, client, 0, DixReadAccess);
2091*4882a593Smuzhiyun if (rc != Success)
2092*4882a593Smuzhiyun return rc;
2093*4882a593Smuzhiyun
2094*4882a593Smuzhiyun memset(&xgi, 0, sizeof(xGetImageReply));
2095*4882a593Smuzhiyun
2096*4882a593Smuzhiyun relx = x;
2097*4882a593Smuzhiyun rely = y;
2098*4882a593Smuzhiyun
2099*4882a593Smuzhiyun if (pDraw->type == DRAWABLE_WINDOW) {
2100*4882a593Smuzhiyun WindowPtr pWin = (WindowPtr) pDraw;
2101*4882a593Smuzhiyun
2102*4882a593Smuzhiyun /* "If the drawable is a window, the window must be viewable ... or a
2103*4882a593Smuzhiyun * BadMatch error results" */
2104*4882a593Smuzhiyun if (!pWin->viewable)
2105*4882a593Smuzhiyun return BadMatch;
2106*4882a593Smuzhiyun
2107*4882a593Smuzhiyun /* If the drawable is a window, the rectangle must be contained within
2108*4882a593Smuzhiyun * its bounds (including the border). */
2109*4882a593Smuzhiyun if (x < -wBorderWidth(pWin) ||
2110*4882a593Smuzhiyun x + width > wBorderWidth(pWin) + (int) pDraw->width ||
2111*4882a593Smuzhiyun y < -wBorderWidth(pWin) ||
2112*4882a593Smuzhiyun y + height > wBorderWidth(pWin) + (int) pDraw->height)
2113*4882a593Smuzhiyun return BadMatch;
2114*4882a593Smuzhiyun
2115*4882a593Smuzhiyun relx += pDraw->x;
2116*4882a593Smuzhiyun rely += pDraw->y;
2117*4882a593Smuzhiyun
2118*4882a593Smuzhiyun if (pDraw->pScreen->GetWindowPixmap) {
2119*4882a593Smuzhiyun PixmapPtr pPix = (*pDraw->pScreen->GetWindowPixmap) (pWin);
2120*4882a593Smuzhiyun
2121*4882a593Smuzhiyun pBoundingDraw = &pPix->drawable;
2122*4882a593Smuzhiyun #ifdef COMPOSITE
2123*4882a593Smuzhiyun relx -= pPix->screen_x;
2124*4882a593Smuzhiyun rely -= pPix->screen_y;
2125*4882a593Smuzhiyun #endif
2126*4882a593Smuzhiyun }
2127*4882a593Smuzhiyun else {
2128*4882a593Smuzhiyun pBoundingDraw = (DrawablePtr) pDraw->pScreen->root;
2129*4882a593Smuzhiyun }
2130*4882a593Smuzhiyun
2131*4882a593Smuzhiyun xgi.visual = wVisual(pWin);
2132*4882a593Smuzhiyun }
2133*4882a593Smuzhiyun else {
2134*4882a593Smuzhiyun pBoundingDraw = pDraw;
2135*4882a593Smuzhiyun xgi.visual = None;
2136*4882a593Smuzhiyun }
2137*4882a593Smuzhiyun
2138*4882a593Smuzhiyun /* "If the drawable is a pixmap, the given rectangle must be wholly
2139*4882a593Smuzhiyun * contained within the pixmap, or a BadMatch error results. If the
2140*4882a593Smuzhiyun * drawable is a window [...] it must be the case that if there were no
2141*4882a593Smuzhiyun * inferiors or overlapping windows, the specified rectangle of the window
2142*4882a593Smuzhiyun * would be fully visible on the screen and wholly contained within the
2143*4882a593Smuzhiyun * outside edges of the window, or a BadMatch error results."
2144*4882a593Smuzhiyun *
2145*4882a593Smuzhiyun * We relax the window case slightly to mean that the rectangle must exist
2146*4882a593Smuzhiyun * within the bounds of the window's backing pixmap. In particular, this
2147*4882a593Smuzhiyun * means that a GetImage request may succeed or fail with BadMatch depending
2148*4882a593Smuzhiyun * on whether any of its ancestor windows are redirected. */
2149*4882a593Smuzhiyun if (relx < 0 || relx + width > (int) pBoundingDraw->width ||
2150*4882a593Smuzhiyun rely < 0 || rely + height > (int) pBoundingDraw->height)
2151*4882a593Smuzhiyun return BadMatch;
2152*4882a593Smuzhiyun
2153*4882a593Smuzhiyun xgi.type = X_Reply;
2154*4882a593Smuzhiyun xgi.sequenceNumber = client->sequence;
2155*4882a593Smuzhiyun xgi.depth = pDraw->depth;
2156*4882a593Smuzhiyun if (format == ZPixmap) {
2157*4882a593Smuzhiyun widthBytesLine = PixmapBytePad(width, pDraw->depth);
2158*4882a593Smuzhiyun length = widthBytesLine * height;
2159*4882a593Smuzhiyun
2160*4882a593Smuzhiyun }
2161*4882a593Smuzhiyun else {
2162*4882a593Smuzhiyun widthBytesLine = BitmapBytePad(width);
2163*4882a593Smuzhiyun plane = ((Mask) 1) << (pDraw->depth - 1);
2164*4882a593Smuzhiyun /* only planes asked for */
2165*4882a593Smuzhiyun length = widthBytesLine * height *
2166*4882a593Smuzhiyun Ones(planemask & (plane | (plane - 1)));
2167*4882a593Smuzhiyun
2168*4882a593Smuzhiyun }
2169*4882a593Smuzhiyun
2170*4882a593Smuzhiyun xgi.length = length;
2171*4882a593Smuzhiyun
2172*4882a593Smuzhiyun xgi.length = bytes_to_int32(xgi.length);
2173*4882a593Smuzhiyun if (widthBytesLine == 0 || height == 0)
2174*4882a593Smuzhiyun linesPerBuf = 0;
2175*4882a593Smuzhiyun else if (widthBytesLine >= IMAGE_BUFSIZE)
2176*4882a593Smuzhiyun linesPerBuf = 1;
2177*4882a593Smuzhiyun else {
2178*4882a593Smuzhiyun linesPerBuf = IMAGE_BUFSIZE / widthBytesLine;
2179*4882a593Smuzhiyun if (linesPerBuf > height)
2180*4882a593Smuzhiyun linesPerBuf = height;
2181*4882a593Smuzhiyun }
2182*4882a593Smuzhiyun length = linesPerBuf * widthBytesLine;
2183*4882a593Smuzhiyun if (linesPerBuf < height) {
2184*4882a593Smuzhiyun /* we have to make sure intermediate buffers don't need padding */
2185*4882a593Smuzhiyun while ((linesPerBuf > 1) &&
2186*4882a593Smuzhiyun (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD) - 1))) {
2187*4882a593Smuzhiyun linesPerBuf--;
2188*4882a593Smuzhiyun length -= widthBytesLine;
2189*4882a593Smuzhiyun }
2190*4882a593Smuzhiyun while (length & ((1L << LOG2_BYTES_PER_SCANLINE_PAD) - 1)) {
2191*4882a593Smuzhiyun linesPerBuf++;
2192*4882a593Smuzhiyun length += widthBytesLine;
2193*4882a593Smuzhiyun }
2194*4882a593Smuzhiyun }
2195*4882a593Smuzhiyun if (!(pBuf = calloc(1, length)))
2196*4882a593Smuzhiyun return BadAlloc;
2197*4882a593Smuzhiyun WriteReplyToClient(client, sizeof(xGetImageReply), &xgi);
2198*4882a593Smuzhiyun
2199*4882a593Smuzhiyun if (pDraw->type == DRAWABLE_WINDOW) {
2200*4882a593Smuzhiyun pVisibleRegion = &((WindowPtr) pDraw)->borderClip;
2201*4882a593Smuzhiyun pDraw->pScreen->SourceValidate(pDraw, x, y, width, height,
2202*4882a593Smuzhiyun IncludeInferiors);
2203*4882a593Smuzhiyun }
2204*4882a593Smuzhiyun
2205*4882a593Smuzhiyun if (linesPerBuf == 0) {
2206*4882a593Smuzhiyun /* nothing to do */
2207*4882a593Smuzhiyun }
2208*4882a593Smuzhiyun else if (format == ZPixmap) {
2209*4882a593Smuzhiyun linesDone = 0;
2210*4882a593Smuzhiyun while (height - linesDone > 0) {
2211*4882a593Smuzhiyun nlines = min(linesPerBuf, height - linesDone);
2212*4882a593Smuzhiyun (*pDraw->pScreen->GetImage) (pDraw,
2213*4882a593Smuzhiyun x,
2214*4882a593Smuzhiyun y + linesDone,
2215*4882a593Smuzhiyun width,
2216*4882a593Smuzhiyun nlines,
2217*4882a593Smuzhiyun format, planemask, (void *) pBuf);
2218*4882a593Smuzhiyun if (pVisibleRegion)
2219*4882a593Smuzhiyun XaceCensorImage(client, pVisibleRegion, widthBytesLine,
2220*4882a593Smuzhiyun pDraw, x, y + linesDone, width,
2221*4882a593Smuzhiyun nlines, format, pBuf);
2222*4882a593Smuzhiyun
2223*4882a593Smuzhiyun /* Note that this is NOT a call to WriteSwappedDataToClient,
2224*4882a593Smuzhiyun as we do NOT byte swap */
2225*4882a593Smuzhiyun ReformatImage(pBuf, (int) (nlines * widthBytesLine),
2226*4882a593Smuzhiyun BitsPerPixel(pDraw->depth), ClientOrder(client));
2227*4882a593Smuzhiyun
2228*4882a593Smuzhiyun WriteToClient(client, (int) (nlines * widthBytesLine), pBuf);
2229*4882a593Smuzhiyun linesDone += nlines;
2230*4882a593Smuzhiyun }
2231*4882a593Smuzhiyun }
2232*4882a593Smuzhiyun else { /* XYPixmap */
2233*4882a593Smuzhiyun
2234*4882a593Smuzhiyun for (; plane; plane >>= 1) {
2235*4882a593Smuzhiyun if (planemask & plane) {
2236*4882a593Smuzhiyun linesDone = 0;
2237*4882a593Smuzhiyun while (height - linesDone > 0) {
2238*4882a593Smuzhiyun nlines = min(linesPerBuf, height - linesDone);
2239*4882a593Smuzhiyun (*pDraw->pScreen->GetImage) (pDraw,
2240*4882a593Smuzhiyun x,
2241*4882a593Smuzhiyun y + linesDone,
2242*4882a593Smuzhiyun width,
2243*4882a593Smuzhiyun nlines,
2244*4882a593Smuzhiyun format, plane, (void *) pBuf);
2245*4882a593Smuzhiyun if (pVisibleRegion)
2246*4882a593Smuzhiyun XaceCensorImage(client, pVisibleRegion,
2247*4882a593Smuzhiyun widthBytesLine,
2248*4882a593Smuzhiyun pDraw, x, y + linesDone, width,
2249*4882a593Smuzhiyun nlines, format, pBuf);
2250*4882a593Smuzhiyun
2251*4882a593Smuzhiyun /* Note: NOT a call to WriteSwappedDataToClient,
2252*4882a593Smuzhiyun as we do NOT byte swap */
2253*4882a593Smuzhiyun ReformatImage(pBuf, (int) (nlines * widthBytesLine),
2254*4882a593Smuzhiyun 1, ClientOrder(client));
2255*4882a593Smuzhiyun
2256*4882a593Smuzhiyun WriteToClient(client, (int)(nlines * widthBytesLine), pBuf);
2257*4882a593Smuzhiyun linesDone += nlines;
2258*4882a593Smuzhiyun }
2259*4882a593Smuzhiyun }
2260*4882a593Smuzhiyun }
2261*4882a593Smuzhiyun }
2262*4882a593Smuzhiyun free(pBuf);
2263*4882a593Smuzhiyun return Success;
2264*4882a593Smuzhiyun }
2265*4882a593Smuzhiyun
2266*4882a593Smuzhiyun int
ProcGetImage(ClientPtr client)2267*4882a593Smuzhiyun ProcGetImage(ClientPtr client)
2268*4882a593Smuzhiyun {
2269*4882a593Smuzhiyun REQUEST(xGetImageReq);
2270*4882a593Smuzhiyun
2271*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xGetImageReq);
2272*4882a593Smuzhiyun
2273*4882a593Smuzhiyun return DoGetImage(client, stuff->format, stuff->drawable,
2274*4882a593Smuzhiyun stuff->x, stuff->y,
2275*4882a593Smuzhiyun (int) stuff->width, (int) stuff->height,
2276*4882a593Smuzhiyun stuff->planeMask);
2277*4882a593Smuzhiyun }
2278*4882a593Smuzhiyun
2279*4882a593Smuzhiyun int
ProcPolyText(ClientPtr client)2280*4882a593Smuzhiyun ProcPolyText(ClientPtr client)
2281*4882a593Smuzhiyun {
2282*4882a593Smuzhiyun int err;
2283*4882a593Smuzhiyun
2284*4882a593Smuzhiyun REQUEST(xPolyTextReq);
2285*4882a593Smuzhiyun DrawablePtr pDraw;
2286*4882a593Smuzhiyun GC *pGC;
2287*4882a593Smuzhiyun
2288*4882a593Smuzhiyun REQUEST_AT_LEAST_SIZE(xPolyTextReq);
2289*4882a593Smuzhiyun VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
2290*4882a593Smuzhiyun
2291*4882a593Smuzhiyun err = PolyText(client,
2292*4882a593Smuzhiyun pDraw,
2293*4882a593Smuzhiyun pGC,
2294*4882a593Smuzhiyun (unsigned char *) &stuff[1],
2295*4882a593Smuzhiyun ((unsigned char *) stuff) + (client->req_len << 2),
2296*4882a593Smuzhiyun stuff->x, stuff->y, stuff->reqType, stuff->drawable);
2297*4882a593Smuzhiyun
2298*4882a593Smuzhiyun if (err == Success) {
2299*4882a593Smuzhiyun return Success;
2300*4882a593Smuzhiyun }
2301*4882a593Smuzhiyun else
2302*4882a593Smuzhiyun return err;
2303*4882a593Smuzhiyun }
2304*4882a593Smuzhiyun
2305*4882a593Smuzhiyun int
ProcImageText8(ClientPtr client)2306*4882a593Smuzhiyun ProcImageText8(ClientPtr client)
2307*4882a593Smuzhiyun {
2308*4882a593Smuzhiyun int err;
2309*4882a593Smuzhiyun DrawablePtr pDraw;
2310*4882a593Smuzhiyun GC *pGC;
2311*4882a593Smuzhiyun
2312*4882a593Smuzhiyun REQUEST(xImageTextReq);
2313*4882a593Smuzhiyun
2314*4882a593Smuzhiyun REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars);
2315*4882a593Smuzhiyun VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
2316*4882a593Smuzhiyun
2317*4882a593Smuzhiyun err = ImageText(client,
2318*4882a593Smuzhiyun pDraw,
2319*4882a593Smuzhiyun pGC,
2320*4882a593Smuzhiyun stuff->nChars,
2321*4882a593Smuzhiyun (unsigned char *) &stuff[1],
2322*4882a593Smuzhiyun stuff->x, stuff->y, stuff->reqType, stuff->drawable);
2323*4882a593Smuzhiyun
2324*4882a593Smuzhiyun if (err == Success) {
2325*4882a593Smuzhiyun return Success;
2326*4882a593Smuzhiyun }
2327*4882a593Smuzhiyun else
2328*4882a593Smuzhiyun return err;
2329*4882a593Smuzhiyun }
2330*4882a593Smuzhiyun
2331*4882a593Smuzhiyun int
ProcImageText16(ClientPtr client)2332*4882a593Smuzhiyun ProcImageText16(ClientPtr client)
2333*4882a593Smuzhiyun {
2334*4882a593Smuzhiyun int err;
2335*4882a593Smuzhiyun DrawablePtr pDraw;
2336*4882a593Smuzhiyun GC *pGC;
2337*4882a593Smuzhiyun
2338*4882a593Smuzhiyun REQUEST(xImageTextReq);
2339*4882a593Smuzhiyun
2340*4882a593Smuzhiyun REQUEST_FIXED_SIZE(xImageTextReq, stuff->nChars << 1);
2341*4882a593Smuzhiyun VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
2342*4882a593Smuzhiyun
2343*4882a593Smuzhiyun err = ImageText(client,
2344*4882a593Smuzhiyun pDraw,
2345*4882a593Smuzhiyun pGC,
2346*4882a593Smuzhiyun stuff->nChars,
2347*4882a593Smuzhiyun (unsigned char *) &stuff[1],
2348*4882a593Smuzhiyun stuff->x, stuff->y, stuff->reqType, stuff->drawable);
2349*4882a593Smuzhiyun
2350*4882a593Smuzhiyun if (err == Success) {
2351*4882a593Smuzhiyun return Success;
2352*4882a593Smuzhiyun }
2353*4882a593Smuzhiyun else
2354*4882a593Smuzhiyun return err;
2355*4882a593Smuzhiyun }
2356*4882a593Smuzhiyun
2357*4882a593Smuzhiyun int
ProcCreateColormap(ClientPtr client)2358*4882a593Smuzhiyun ProcCreateColormap(ClientPtr client)
2359*4882a593Smuzhiyun {
2360*4882a593Smuzhiyun VisualPtr pVisual;
2361*4882a593Smuzhiyun ColormapPtr pmap;
2362*4882a593Smuzhiyun Colormap mid;
2363*4882a593Smuzhiyun WindowPtr pWin;
2364*4882a593Smuzhiyun ScreenPtr pScreen;
2365*4882a593Smuzhiyun
2366*4882a593Smuzhiyun REQUEST(xCreateColormapReq);
2367*4882a593Smuzhiyun int i, result;
2368*4882a593Smuzhiyun
2369*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xCreateColormapReq);
2370*4882a593Smuzhiyun
2371*4882a593Smuzhiyun if ((stuff->alloc != AllocNone) && (stuff->alloc != AllocAll)) {
2372*4882a593Smuzhiyun client->errorValue = stuff->alloc;
2373*4882a593Smuzhiyun return BadValue;
2374*4882a593Smuzhiyun }
2375*4882a593Smuzhiyun mid = stuff->mid;
2376*4882a593Smuzhiyun LEGAL_NEW_RESOURCE(mid, client);
2377*4882a593Smuzhiyun result = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
2378*4882a593Smuzhiyun if (result != Success)
2379*4882a593Smuzhiyun return result;
2380*4882a593Smuzhiyun
2381*4882a593Smuzhiyun pScreen = pWin->drawable.pScreen;
2382*4882a593Smuzhiyun for (i = 0, pVisual = pScreen->visuals;
2383*4882a593Smuzhiyun i < pScreen->numVisuals; i++, pVisual++) {
2384*4882a593Smuzhiyun if (pVisual->vid != stuff->visual)
2385*4882a593Smuzhiyun continue;
2386*4882a593Smuzhiyun return CreateColormap(mid, pScreen, pVisual, &pmap,
2387*4882a593Smuzhiyun (int) stuff->alloc, client->index);
2388*4882a593Smuzhiyun }
2389*4882a593Smuzhiyun client->errorValue = stuff->visual;
2390*4882a593Smuzhiyun return BadMatch;
2391*4882a593Smuzhiyun }
2392*4882a593Smuzhiyun
2393*4882a593Smuzhiyun int
ProcFreeColormap(ClientPtr client)2394*4882a593Smuzhiyun ProcFreeColormap(ClientPtr client)
2395*4882a593Smuzhiyun {
2396*4882a593Smuzhiyun ColormapPtr pmap;
2397*4882a593Smuzhiyun int rc;
2398*4882a593Smuzhiyun
2399*4882a593Smuzhiyun REQUEST(xResourceReq);
2400*4882a593Smuzhiyun
2401*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xResourceReq);
2402*4882a593Smuzhiyun rc = dixLookupResourceByType((void **) &pmap, stuff->id, RT_COLORMAP,
2403*4882a593Smuzhiyun client, DixDestroyAccess);
2404*4882a593Smuzhiyun if (rc == Success) {
2405*4882a593Smuzhiyun /* Freeing a default colormap is a no-op */
2406*4882a593Smuzhiyun if (!(pmap->flags & IsDefault))
2407*4882a593Smuzhiyun FreeResource(stuff->id, RT_NONE);
2408*4882a593Smuzhiyun return Success;
2409*4882a593Smuzhiyun }
2410*4882a593Smuzhiyun else {
2411*4882a593Smuzhiyun client->errorValue = stuff->id;
2412*4882a593Smuzhiyun return rc;
2413*4882a593Smuzhiyun }
2414*4882a593Smuzhiyun }
2415*4882a593Smuzhiyun
2416*4882a593Smuzhiyun int
ProcCopyColormapAndFree(ClientPtr client)2417*4882a593Smuzhiyun ProcCopyColormapAndFree(ClientPtr client)
2418*4882a593Smuzhiyun {
2419*4882a593Smuzhiyun Colormap mid;
2420*4882a593Smuzhiyun ColormapPtr pSrcMap;
2421*4882a593Smuzhiyun
2422*4882a593Smuzhiyun REQUEST(xCopyColormapAndFreeReq);
2423*4882a593Smuzhiyun int rc;
2424*4882a593Smuzhiyun
2425*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xCopyColormapAndFreeReq);
2426*4882a593Smuzhiyun mid = stuff->mid;
2427*4882a593Smuzhiyun LEGAL_NEW_RESOURCE(mid, client);
2428*4882a593Smuzhiyun rc = dixLookupResourceByType((void **) &pSrcMap, stuff->srcCmap,
2429*4882a593Smuzhiyun RT_COLORMAP, client,
2430*4882a593Smuzhiyun DixReadAccess | DixRemoveAccess);
2431*4882a593Smuzhiyun if (rc == Success)
2432*4882a593Smuzhiyun return CopyColormapAndFree(mid, pSrcMap, client->index);
2433*4882a593Smuzhiyun client->errorValue = stuff->srcCmap;
2434*4882a593Smuzhiyun return rc;
2435*4882a593Smuzhiyun }
2436*4882a593Smuzhiyun
2437*4882a593Smuzhiyun int
ProcInstallColormap(ClientPtr client)2438*4882a593Smuzhiyun ProcInstallColormap(ClientPtr client)
2439*4882a593Smuzhiyun {
2440*4882a593Smuzhiyun ColormapPtr pcmp;
2441*4882a593Smuzhiyun int rc;
2442*4882a593Smuzhiyun
2443*4882a593Smuzhiyun REQUEST(xResourceReq);
2444*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xResourceReq);
2445*4882a593Smuzhiyun
2446*4882a593Smuzhiyun rc = dixLookupResourceByType((void **) &pcmp, stuff->id, RT_COLORMAP,
2447*4882a593Smuzhiyun client, DixInstallAccess);
2448*4882a593Smuzhiyun if (rc != Success)
2449*4882a593Smuzhiyun goto out;
2450*4882a593Smuzhiyun
2451*4882a593Smuzhiyun rc = XaceHook(XACE_SCREEN_ACCESS, client, pcmp->pScreen, DixSetAttrAccess);
2452*4882a593Smuzhiyun if (rc != Success) {
2453*4882a593Smuzhiyun if (rc == BadValue)
2454*4882a593Smuzhiyun rc = BadColor;
2455*4882a593Smuzhiyun goto out;
2456*4882a593Smuzhiyun }
2457*4882a593Smuzhiyun
2458*4882a593Smuzhiyun (*(pcmp->pScreen->InstallColormap)) (pcmp);
2459*4882a593Smuzhiyun return Success;
2460*4882a593Smuzhiyun
2461*4882a593Smuzhiyun out:
2462*4882a593Smuzhiyun client->errorValue = stuff->id;
2463*4882a593Smuzhiyun return rc;
2464*4882a593Smuzhiyun }
2465*4882a593Smuzhiyun
2466*4882a593Smuzhiyun int
ProcUninstallColormap(ClientPtr client)2467*4882a593Smuzhiyun ProcUninstallColormap(ClientPtr client)
2468*4882a593Smuzhiyun {
2469*4882a593Smuzhiyun ColormapPtr pcmp;
2470*4882a593Smuzhiyun int rc;
2471*4882a593Smuzhiyun
2472*4882a593Smuzhiyun REQUEST(xResourceReq);
2473*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xResourceReq);
2474*4882a593Smuzhiyun
2475*4882a593Smuzhiyun rc = dixLookupResourceByType((void **) &pcmp, stuff->id, RT_COLORMAP,
2476*4882a593Smuzhiyun client, DixUninstallAccess);
2477*4882a593Smuzhiyun if (rc != Success)
2478*4882a593Smuzhiyun goto out;
2479*4882a593Smuzhiyun
2480*4882a593Smuzhiyun rc = XaceHook(XACE_SCREEN_ACCESS, client, pcmp->pScreen, DixSetAttrAccess);
2481*4882a593Smuzhiyun if (rc != Success) {
2482*4882a593Smuzhiyun if (rc == BadValue)
2483*4882a593Smuzhiyun rc = BadColor;
2484*4882a593Smuzhiyun goto out;
2485*4882a593Smuzhiyun }
2486*4882a593Smuzhiyun
2487*4882a593Smuzhiyun if (pcmp->mid != pcmp->pScreen->defColormap)
2488*4882a593Smuzhiyun (*(pcmp->pScreen->UninstallColormap)) (pcmp);
2489*4882a593Smuzhiyun return Success;
2490*4882a593Smuzhiyun
2491*4882a593Smuzhiyun out:
2492*4882a593Smuzhiyun client->errorValue = stuff->id;
2493*4882a593Smuzhiyun return rc;
2494*4882a593Smuzhiyun }
2495*4882a593Smuzhiyun
2496*4882a593Smuzhiyun int
ProcListInstalledColormaps(ClientPtr client)2497*4882a593Smuzhiyun ProcListInstalledColormaps(ClientPtr client)
2498*4882a593Smuzhiyun {
2499*4882a593Smuzhiyun xListInstalledColormapsReply *preply;
2500*4882a593Smuzhiyun int nummaps, rc;
2501*4882a593Smuzhiyun WindowPtr pWin;
2502*4882a593Smuzhiyun
2503*4882a593Smuzhiyun REQUEST(xResourceReq);
2504*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xResourceReq);
2505*4882a593Smuzhiyun
2506*4882a593Smuzhiyun rc = dixLookupWindow(&pWin, stuff->id, client, DixGetAttrAccess);
2507*4882a593Smuzhiyun if (rc != Success)
2508*4882a593Smuzhiyun return rc;
2509*4882a593Smuzhiyun
2510*4882a593Smuzhiyun rc = XaceHook(XACE_SCREEN_ACCESS, client, pWin->drawable.pScreen,
2511*4882a593Smuzhiyun DixGetAttrAccess);
2512*4882a593Smuzhiyun if (rc != Success)
2513*4882a593Smuzhiyun return rc;
2514*4882a593Smuzhiyun
2515*4882a593Smuzhiyun preply = malloc(sizeof(xListInstalledColormapsReply) +
2516*4882a593Smuzhiyun pWin->drawable.pScreen->maxInstalledCmaps *
2517*4882a593Smuzhiyun sizeof(Colormap));
2518*4882a593Smuzhiyun if (!preply)
2519*4882a593Smuzhiyun return BadAlloc;
2520*4882a593Smuzhiyun
2521*4882a593Smuzhiyun preply->type = X_Reply;
2522*4882a593Smuzhiyun preply->sequenceNumber = client->sequence;
2523*4882a593Smuzhiyun nummaps = (*pWin->drawable.pScreen->ListInstalledColormaps)
2524*4882a593Smuzhiyun (pWin->drawable.pScreen, (Colormap *) &preply[1]);
2525*4882a593Smuzhiyun preply->nColormaps = nummaps;
2526*4882a593Smuzhiyun preply->length = nummaps;
2527*4882a593Smuzhiyun WriteReplyToClient(client, sizeof(xListInstalledColormapsReply), preply);
2528*4882a593Smuzhiyun client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
2529*4882a593Smuzhiyun WriteSwappedDataToClient(client, nummaps * sizeof(Colormap), &preply[1]);
2530*4882a593Smuzhiyun free(preply);
2531*4882a593Smuzhiyun return Success;
2532*4882a593Smuzhiyun }
2533*4882a593Smuzhiyun
2534*4882a593Smuzhiyun int
ProcAllocColor(ClientPtr client)2535*4882a593Smuzhiyun ProcAllocColor(ClientPtr client)
2536*4882a593Smuzhiyun {
2537*4882a593Smuzhiyun ColormapPtr pmap;
2538*4882a593Smuzhiyun int rc;
2539*4882a593Smuzhiyun
2540*4882a593Smuzhiyun REQUEST(xAllocColorReq);
2541*4882a593Smuzhiyun
2542*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xAllocColorReq);
2543*4882a593Smuzhiyun rc = dixLookupResourceByType((void **) &pmap, stuff->cmap, RT_COLORMAP,
2544*4882a593Smuzhiyun client, DixAddAccess);
2545*4882a593Smuzhiyun if (rc == Success) {
2546*4882a593Smuzhiyun xAllocColorReply acr = {
2547*4882a593Smuzhiyun .type = X_Reply,
2548*4882a593Smuzhiyun .sequenceNumber = client->sequence,
2549*4882a593Smuzhiyun .length = 0,
2550*4882a593Smuzhiyun .red = stuff->red,
2551*4882a593Smuzhiyun .green = stuff->green,
2552*4882a593Smuzhiyun .blue = stuff->blue,
2553*4882a593Smuzhiyun .pixel = 0
2554*4882a593Smuzhiyun };
2555*4882a593Smuzhiyun if ((rc = AllocColor(pmap, &acr.red, &acr.green, &acr.blue,
2556*4882a593Smuzhiyun &acr.pixel, client->index)))
2557*4882a593Smuzhiyun return rc;
2558*4882a593Smuzhiyun #ifdef PANORAMIX
2559*4882a593Smuzhiyun if (noPanoramiXExtension || !pmap->pScreen->myNum)
2560*4882a593Smuzhiyun #endif
2561*4882a593Smuzhiyun WriteReplyToClient(client, sizeof(xAllocColorReply), &acr);
2562*4882a593Smuzhiyun return Success;
2563*4882a593Smuzhiyun
2564*4882a593Smuzhiyun }
2565*4882a593Smuzhiyun else {
2566*4882a593Smuzhiyun client->errorValue = stuff->cmap;
2567*4882a593Smuzhiyun return rc;
2568*4882a593Smuzhiyun }
2569*4882a593Smuzhiyun }
2570*4882a593Smuzhiyun
2571*4882a593Smuzhiyun int
ProcAllocNamedColor(ClientPtr client)2572*4882a593Smuzhiyun ProcAllocNamedColor(ClientPtr client)
2573*4882a593Smuzhiyun {
2574*4882a593Smuzhiyun ColormapPtr pcmp;
2575*4882a593Smuzhiyun int rc;
2576*4882a593Smuzhiyun
2577*4882a593Smuzhiyun REQUEST(xAllocNamedColorReq);
2578*4882a593Smuzhiyun
2579*4882a593Smuzhiyun REQUEST_FIXED_SIZE(xAllocNamedColorReq, stuff->nbytes);
2580*4882a593Smuzhiyun rc = dixLookupResourceByType((void **) &pcmp, stuff->cmap, RT_COLORMAP,
2581*4882a593Smuzhiyun client, DixAddAccess);
2582*4882a593Smuzhiyun if (rc == Success) {
2583*4882a593Smuzhiyun xAllocNamedColorReply ancr = {
2584*4882a593Smuzhiyun .type = X_Reply,
2585*4882a593Smuzhiyun .sequenceNumber = client->sequence,
2586*4882a593Smuzhiyun .length = 0
2587*4882a593Smuzhiyun };
2588*4882a593Smuzhiyun if (OsLookupColor
2589*4882a593Smuzhiyun (pcmp->pScreen->myNum, (char *) &stuff[1], stuff->nbytes,
2590*4882a593Smuzhiyun &ancr.exactRed, &ancr.exactGreen, &ancr.exactBlue)) {
2591*4882a593Smuzhiyun ancr.screenRed = ancr.exactRed;
2592*4882a593Smuzhiyun ancr.screenGreen = ancr.exactGreen;
2593*4882a593Smuzhiyun ancr.screenBlue = ancr.exactBlue;
2594*4882a593Smuzhiyun ancr.pixel = 0;
2595*4882a593Smuzhiyun if ((rc = AllocColor(pcmp,
2596*4882a593Smuzhiyun &ancr.screenRed, &ancr.screenGreen,
2597*4882a593Smuzhiyun &ancr.screenBlue, &ancr.pixel, client->index)))
2598*4882a593Smuzhiyun return rc;
2599*4882a593Smuzhiyun #ifdef PANORAMIX
2600*4882a593Smuzhiyun if (noPanoramiXExtension || !pcmp->pScreen->myNum)
2601*4882a593Smuzhiyun #endif
2602*4882a593Smuzhiyun WriteReplyToClient(client, sizeof(xAllocNamedColorReply),
2603*4882a593Smuzhiyun &ancr);
2604*4882a593Smuzhiyun return Success;
2605*4882a593Smuzhiyun }
2606*4882a593Smuzhiyun else
2607*4882a593Smuzhiyun return BadName;
2608*4882a593Smuzhiyun
2609*4882a593Smuzhiyun }
2610*4882a593Smuzhiyun else {
2611*4882a593Smuzhiyun client->errorValue = stuff->cmap;
2612*4882a593Smuzhiyun return rc;
2613*4882a593Smuzhiyun }
2614*4882a593Smuzhiyun }
2615*4882a593Smuzhiyun
2616*4882a593Smuzhiyun int
ProcAllocColorCells(ClientPtr client)2617*4882a593Smuzhiyun ProcAllocColorCells(ClientPtr client)
2618*4882a593Smuzhiyun {
2619*4882a593Smuzhiyun ColormapPtr pcmp;
2620*4882a593Smuzhiyun int rc;
2621*4882a593Smuzhiyun
2622*4882a593Smuzhiyun REQUEST(xAllocColorCellsReq);
2623*4882a593Smuzhiyun
2624*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xAllocColorCellsReq);
2625*4882a593Smuzhiyun rc = dixLookupResourceByType((void **) &pcmp, stuff->cmap, RT_COLORMAP,
2626*4882a593Smuzhiyun client, DixAddAccess);
2627*4882a593Smuzhiyun if (rc == Success) {
2628*4882a593Smuzhiyun int npixels, nmasks;
2629*4882a593Smuzhiyun long length;
2630*4882a593Smuzhiyun Pixel *ppixels, *pmasks;
2631*4882a593Smuzhiyun
2632*4882a593Smuzhiyun npixels = stuff->colors;
2633*4882a593Smuzhiyun if (!npixels) {
2634*4882a593Smuzhiyun client->errorValue = npixels;
2635*4882a593Smuzhiyun return BadValue;
2636*4882a593Smuzhiyun }
2637*4882a593Smuzhiyun if (stuff->contiguous != xTrue && stuff->contiguous != xFalse) {
2638*4882a593Smuzhiyun client->errorValue = stuff->contiguous;
2639*4882a593Smuzhiyun return BadValue;
2640*4882a593Smuzhiyun }
2641*4882a593Smuzhiyun nmasks = stuff->planes;
2642*4882a593Smuzhiyun length = ((long) npixels + (long) nmasks) * sizeof(Pixel);
2643*4882a593Smuzhiyun ppixels = malloc(length);
2644*4882a593Smuzhiyun if (!ppixels)
2645*4882a593Smuzhiyun return BadAlloc;
2646*4882a593Smuzhiyun pmasks = ppixels + npixels;
2647*4882a593Smuzhiyun
2648*4882a593Smuzhiyun if ((rc = AllocColorCells(client->index, pcmp, npixels, nmasks,
2649*4882a593Smuzhiyun (Bool) stuff->contiguous, ppixels, pmasks))) {
2650*4882a593Smuzhiyun free(ppixels);
2651*4882a593Smuzhiyun return rc;
2652*4882a593Smuzhiyun }
2653*4882a593Smuzhiyun #ifdef PANORAMIX
2654*4882a593Smuzhiyun if (noPanoramiXExtension || !pcmp->pScreen->myNum)
2655*4882a593Smuzhiyun #endif
2656*4882a593Smuzhiyun {
2657*4882a593Smuzhiyun xAllocColorCellsReply accr = {
2658*4882a593Smuzhiyun .type = X_Reply,
2659*4882a593Smuzhiyun .sequenceNumber = client->sequence,
2660*4882a593Smuzhiyun .length = bytes_to_int32(length),
2661*4882a593Smuzhiyun .nPixels = npixels,
2662*4882a593Smuzhiyun .nMasks = nmasks
2663*4882a593Smuzhiyun };
2664*4882a593Smuzhiyun WriteReplyToClient(client, sizeof(xAllocColorCellsReply), &accr);
2665*4882a593Smuzhiyun client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
2666*4882a593Smuzhiyun WriteSwappedDataToClient(client, length, ppixels);
2667*4882a593Smuzhiyun }
2668*4882a593Smuzhiyun free(ppixels);
2669*4882a593Smuzhiyun return Success;
2670*4882a593Smuzhiyun }
2671*4882a593Smuzhiyun else {
2672*4882a593Smuzhiyun client->errorValue = stuff->cmap;
2673*4882a593Smuzhiyun return rc;
2674*4882a593Smuzhiyun }
2675*4882a593Smuzhiyun }
2676*4882a593Smuzhiyun
2677*4882a593Smuzhiyun int
ProcAllocColorPlanes(ClientPtr client)2678*4882a593Smuzhiyun ProcAllocColorPlanes(ClientPtr client)
2679*4882a593Smuzhiyun {
2680*4882a593Smuzhiyun ColormapPtr pcmp;
2681*4882a593Smuzhiyun int rc;
2682*4882a593Smuzhiyun
2683*4882a593Smuzhiyun REQUEST(xAllocColorPlanesReq);
2684*4882a593Smuzhiyun
2685*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xAllocColorPlanesReq);
2686*4882a593Smuzhiyun rc = dixLookupResourceByType((void **) &pcmp, stuff->cmap, RT_COLORMAP,
2687*4882a593Smuzhiyun client, DixAddAccess);
2688*4882a593Smuzhiyun if (rc == Success) {
2689*4882a593Smuzhiyun xAllocColorPlanesReply acpr;
2690*4882a593Smuzhiyun int npixels;
2691*4882a593Smuzhiyun long length;
2692*4882a593Smuzhiyun Pixel *ppixels;
2693*4882a593Smuzhiyun
2694*4882a593Smuzhiyun npixels = stuff->colors;
2695*4882a593Smuzhiyun if (!npixels) {
2696*4882a593Smuzhiyun client->errorValue = npixels;
2697*4882a593Smuzhiyun return BadValue;
2698*4882a593Smuzhiyun }
2699*4882a593Smuzhiyun if (stuff->contiguous != xTrue && stuff->contiguous != xFalse) {
2700*4882a593Smuzhiyun client->errorValue = stuff->contiguous;
2701*4882a593Smuzhiyun return BadValue;
2702*4882a593Smuzhiyun }
2703*4882a593Smuzhiyun acpr = (xAllocColorPlanesReply) {
2704*4882a593Smuzhiyun .type = X_Reply,
2705*4882a593Smuzhiyun .sequenceNumber = client->sequence,
2706*4882a593Smuzhiyun .nPixels = npixels
2707*4882a593Smuzhiyun };
2708*4882a593Smuzhiyun length = (long) npixels *sizeof(Pixel);
2709*4882a593Smuzhiyun
2710*4882a593Smuzhiyun ppixels = malloc(length);
2711*4882a593Smuzhiyun if (!ppixels)
2712*4882a593Smuzhiyun return BadAlloc;
2713*4882a593Smuzhiyun if ((rc = AllocColorPlanes(client->index, pcmp, npixels,
2714*4882a593Smuzhiyun (int) stuff->red, (int) stuff->green,
2715*4882a593Smuzhiyun (int) stuff->blue, (Bool) stuff->contiguous,
2716*4882a593Smuzhiyun ppixels, &acpr.redMask, &acpr.greenMask,
2717*4882a593Smuzhiyun &acpr.blueMask))) {
2718*4882a593Smuzhiyun free(ppixels);
2719*4882a593Smuzhiyun return rc;
2720*4882a593Smuzhiyun }
2721*4882a593Smuzhiyun acpr.length = bytes_to_int32(length);
2722*4882a593Smuzhiyun #ifdef PANORAMIX
2723*4882a593Smuzhiyun if (noPanoramiXExtension || !pcmp->pScreen->myNum)
2724*4882a593Smuzhiyun #endif
2725*4882a593Smuzhiyun {
2726*4882a593Smuzhiyun WriteReplyToClient(client, sizeof(xAllocColorPlanesReply), &acpr);
2727*4882a593Smuzhiyun client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
2728*4882a593Smuzhiyun WriteSwappedDataToClient(client, length, ppixels);
2729*4882a593Smuzhiyun }
2730*4882a593Smuzhiyun free(ppixels);
2731*4882a593Smuzhiyun return Success;
2732*4882a593Smuzhiyun }
2733*4882a593Smuzhiyun else {
2734*4882a593Smuzhiyun client->errorValue = stuff->cmap;
2735*4882a593Smuzhiyun return rc;
2736*4882a593Smuzhiyun }
2737*4882a593Smuzhiyun }
2738*4882a593Smuzhiyun
2739*4882a593Smuzhiyun int
ProcFreeColors(ClientPtr client)2740*4882a593Smuzhiyun ProcFreeColors(ClientPtr client)
2741*4882a593Smuzhiyun {
2742*4882a593Smuzhiyun ColormapPtr pcmp;
2743*4882a593Smuzhiyun int rc;
2744*4882a593Smuzhiyun
2745*4882a593Smuzhiyun REQUEST(xFreeColorsReq);
2746*4882a593Smuzhiyun
2747*4882a593Smuzhiyun REQUEST_AT_LEAST_SIZE(xFreeColorsReq);
2748*4882a593Smuzhiyun rc = dixLookupResourceByType((void **) &pcmp, stuff->cmap, RT_COLORMAP,
2749*4882a593Smuzhiyun client, DixRemoveAccess);
2750*4882a593Smuzhiyun if (rc == Success) {
2751*4882a593Smuzhiyun int count;
2752*4882a593Smuzhiyun
2753*4882a593Smuzhiyun if (pcmp->flags & AllAllocated)
2754*4882a593Smuzhiyun return BadAccess;
2755*4882a593Smuzhiyun count = bytes_to_int32((client->req_len << 2) - sizeof(xFreeColorsReq));
2756*4882a593Smuzhiyun return FreeColors(pcmp, client->index, count,
2757*4882a593Smuzhiyun (Pixel *) &stuff[1], (Pixel) stuff->planeMask);
2758*4882a593Smuzhiyun }
2759*4882a593Smuzhiyun else {
2760*4882a593Smuzhiyun client->errorValue = stuff->cmap;
2761*4882a593Smuzhiyun return rc;
2762*4882a593Smuzhiyun }
2763*4882a593Smuzhiyun }
2764*4882a593Smuzhiyun
2765*4882a593Smuzhiyun int
ProcStoreColors(ClientPtr client)2766*4882a593Smuzhiyun ProcStoreColors(ClientPtr client)
2767*4882a593Smuzhiyun {
2768*4882a593Smuzhiyun ColormapPtr pcmp;
2769*4882a593Smuzhiyun int rc;
2770*4882a593Smuzhiyun
2771*4882a593Smuzhiyun REQUEST(xStoreColorsReq);
2772*4882a593Smuzhiyun
2773*4882a593Smuzhiyun REQUEST_AT_LEAST_SIZE(xStoreColorsReq);
2774*4882a593Smuzhiyun rc = dixLookupResourceByType((void **) &pcmp, stuff->cmap, RT_COLORMAP,
2775*4882a593Smuzhiyun client, DixWriteAccess);
2776*4882a593Smuzhiyun if (rc == Success) {
2777*4882a593Smuzhiyun int count;
2778*4882a593Smuzhiyun
2779*4882a593Smuzhiyun count = (client->req_len << 2) - sizeof(xStoreColorsReq);
2780*4882a593Smuzhiyun if (count % sizeof(xColorItem))
2781*4882a593Smuzhiyun return BadLength;
2782*4882a593Smuzhiyun count /= sizeof(xColorItem);
2783*4882a593Smuzhiyun return StoreColors(pcmp, count, (xColorItem *) &stuff[1], client);
2784*4882a593Smuzhiyun }
2785*4882a593Smuzhiyun else {
2786*4882a593Smuzhiyun client->errorValue = stuff->cmap;
2787*4882a593Smuzhiyun return rc;
2788*4882a593Smuzhiyun }
2789*4882a593Smuzhiyun }
2790*4882a593Smuzhiyun
2791*4882a593Smuzhiyun int
ProcStoreNamedColor(ClientPtr client)2792*4882a593Smuzhiyun ProcStoreNamedColor(ClientPtr client)
2793*4882a593Smuzhiyun {
2794*4882a593Smuzhiyun ColormapPtr pcmp;
2795*4882a593Smuzhiyun int rc;
2796*4882a593Smuzhiyun
2797*4882a593Smuzhiyun REQUEST(xStoreNamedColorReq);
2798*4882a593Smuzhiyun
2799*4882a593Smuzhiyun REQUEST_FIXED_SIZE(xStoreNamedColorReq, stuff->nbytes);
2800*4882a593Smuzhiyun rc = dixLookupResourceByType((void **) &pcmp, stuff->cmap, RT_COLORMAP,
2801*4882a593Smuzhiyun client, DixWriteAccess);
2802*4882a593Smuzhiyun if (rc == Success) {
2803*4882a593Smuzhiyun xColorItem def;
2804*4882a593Smuzhiyun
2805*4882a593Smuzhiyun if (OsLookupColor(pcmp->pScreen->myNum, (char *) &stuff[1],
2806*4882a593Smuzhiyun stuff->nbytes, &def.red, &def.green, &def.blue)) {
2807*4882a593Smuzhiyun def.flags = stuff->flags;
2808*4882a593Smuzhiyun def.pixel = stuff->pixel;
2809*4882a593Smuzhiyun return StoreColors(pcmp, 1, &def, client);
2810*4882a593Smuzhiyun }
2811*4882a593Smuzhiyun return BadName;
2812*4882a593Smuzhiyun }
2813*4882a593Smuzhiyun else {
2814*4882a593Smuzhiyun client->errorValue = stuff->cmap;
2815*4882a593Smuzhiyun return rc;
2816*4882a593Smuzhiyun }
2817*4882a593Smuzhiyun }
2818*4882a593Smuzhiyun
2819*4882a593Smuzhiyun int
ProcQueryColors(ClientPtr client)2820*4882a593Smuzhiyun ProcQueryColors(ClientPtr client)
2821*4882a593Smuzhiyun {
2822*4882a593Smuzhiyun ColormapPtr pcmp;
2823*4882a593Smuzhiyun int rc;
2824*4882a593Smuzhiyun
2825*4882a593Smuzhiyun REQUEST(xQueryColorsReq);
2826*4882a593Smuzhiyun
2827*4882a593Smuzhiyun REQUEST_AT_LEAST_SIZE(xQueryColorsReq);
2828*4882a593Smuzhiyun rc = dixLookupResourceByType((void **) &pcmp, stuff->cmap, RT_COLORMAP,
2829*4882a593Smuzhiyun client, DixReadAccess);
2830*4882a593Smuzhiyun if (rc == Success) {
2831*4882a593Smuzhiyun int count;
2832*4882a593Smuzhiyun xrgb *prgbs;
2833*4882a593Smuzhiyun xQueryColorsReply qcr;
2834*4882a593Smuzhiyun
2835*4882a593Smuzhiyun count =
2836*4882a593Smuzhiyun bytes_to_int32((client->req_len << 2) - sizeof(xQueryColorsReq));
2837*4882a593Smuzhiyun prgbs = calloc(count, sizeof(xrgb));
2838*4882a593Smuzhiyun if (!prgbs && count)
2839*4882a593Smuzhiyun return BadAlloc;
2840*4882a593Smuzhiyun if ((rc =
2841*4882a593Smuzhiyun QueryColors(pcmp, count, (Pixel *) &stuff[1], prgbs, client))) {
2842*4882a593Smuzhiyun free(prgbs);
2843*4882a593Smuzhiyun return rc;
2844*4882a593Smuzhiyun }
2845*4882a593Smuzhiyun qcr = (xQueryColorsReply) {
2846*4882a593Smuzhiyun .type = X_Reply,
2847*4882a593Smuzhiyun .sequenceNumber = client->sequence,
2848*4882a593Smuzhiyun .length = bytes_to_int32(count * sizeof(xrgb)),
2849*4882a593Smuzhiyun .nColors = count
2850*4882a593Smuzhiyun };
2851*4882a593Smuzhiyun WriteReplyToClient(client, sizeof(xQueryColorsReply), &qcr);
2852*4882a593Smuzhiyun if (count) {
2853*4882a593Smuzhiyun client->pSwapReplyFunc = (ReplySwapPtr) SQColorsExtend;
2854*4882a593Smuzhiyun WriteSwappedDataToClient(client, count * sizeof(xrgb), prgbs);
2855*4882a593Smuzhiyun }
2856*4882a593Smuzhiyun free(prgbs);
2857*4882a593Smuzhiyun return Success;
2858*4882a593Smuzhiyun
2859*4882a593Smuzhiyun }
2860*4882a593Smuzhiyun else {
2861*4882a593Smuzhiyun client->errorValue = stuff->cmap;
2862*4882a593Smuzhiyun return rc;
2863*4882a593Smuzhiyun }
2864*4882a593Smuzhiyun }
2865*4882a593Smuzhiyun
2866*4882a593Smuzhiyun int
ProcLookupColor(ClientPtr client)2867*4882a593Smuzhiyun ProcLookupColor(ClientPtr client)
2868*4882a593Smuzhiyun {
2869*4882a593Smuzhiyun ColormapPtr pcmp;
2870*4882a593Smuzhiyun int rc;
2871*4882a593Smuzhiyun
2872*4882a593Smuzhiyun REQUEST(xLookupColorReq);
2873*4882a593Smuzhiyun
2874*4882a593Smuzhiyun REQUEST_FIXED_SIZE(xLookupColorReq, stuff->nbytes);
2875*4882a593Smuzhiyun rc = dixLookupResourceByType((void **) &pcmp, stuff->cmap, RT_COLORMAP,
2876*4882a593Smuzhiyun client, DixReadAccess);
2877*4882a593Smuzhiyun if (rc == Success) {
2878*4882a593Smuzhiyun CARD16 exactRed, exactGreen, exactBlue;
2879*4882a593Smuzhiyun
2880*4882a593Smuzhiyun if (OsLookupColor
2881*4882a593Smuzhiyun (pcmp->pScreen->myNum, (char *) &stuff[1], stuff->nbytes,
2882*4882a593Smuzhiyun &exactRed, &exactGreen, &exactBlue)) {
2883*4882a593Smuzhiyun xLookupColorReply lcr = {
2884*4882a593Smuzhiyun .type = X_Reply,
2885*4882a593Smuzhiyun .sequenceNumber = client->sequence,
2886*4882a593Smuzhiyun .length = 0,
2887*4882a593Smuzhiyun .exactRed = exactRed,
2888*4882a593Smuzhiyun .exactGreen = exactGreen,
2889*4882a593Smuzhiyun .exactBlue = exactBlue,
2890*4882a593Smuzhiyun .screenRed = exactRed,
2891*4882a593Smuzhiyun .screenGreen = exactGreen,
2892*4882a593Smuzhiyun .screenBlue = exactBlue
2893*4882a593Smuzhiyun };
2894*4882a593Smuzhiyun (*pcmp->pScreen->ResolveColor) (&lcr.screenRed,
2895*4882a593Smuzhiyun &lcr.screenGreen,
2896*4882a593Smuzhiyun &lcr.screenBlue, pcmp->pVisual);
2897*4882a593Smuzhiyun WriteReplyToClient(client, sizeof(xLookupColorReply), &lcr);
2898*4882a593Smuzhiyun return Success;
2899*4882a593Smuzhiyun }
2900*4882a593Smuzhiyun return BadName;
2901*4882a593Smuzhiyun }
2902*4882a593Smuzhiyun else {
2903*4882a593Smuzhiyun client->errorValue = stuff->cmap;
2904*4882a593Smuzhiyun return rc;
2905*4882a593Smuzhiyun }
2906*4882a593Smuzhiyun }
2907*4882a593Smuzhiyun
2908*4882a593Smuzhiyun int
ProcCreateCursor(ClientPtr client)2909*4882a593Smuzhiyun ProcCreateCursor(ClientPtr client)
2910*4882a593Smuzhiyun {
2911*4882a593Smuzhiyun CursorPtr pCursor;
2912*4882a593Smuzhiyun PixmapPtr src;
2913*4882a593Smuzhiyun PixmapPtr msk;
2914*4882a593Smuzhiyun unsigned char *srcbits;
2915*4882a593Smuzhiyun unsigned char *mskbits;
2916*4882a593Smuzhiyun unsigned short width, height;
2917*4882a593Smuzhiyun long n;
2918*4882a593Smuzhiyun CursorMetricRec cm;
2919*4882a593Smuzhiyun int rc;
2920*4882a593Smuzhiyun
2921*4882a593Smuzhiyun REQUEST(xCreateCursorReq);
2922*4882a593Smuzhiyun
2923*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xCreateCursorReq);
2924*4882a593Smuzhiyun LEGAL_NEW_RESOURCE(stuff->cid, client);
2925*4882a593Smuzhiyun
2926*4882a593Smuzhiyun rc = dixLookupResourceByType((void **) &src, stuff->source, RT_PIXMAP,
2927*4882a593Smuzhiyun client, DixReadAccess);
2928*4882a593Smuzhiyun if (rc != Success) {
2929*4882a593Smuzhiyun client->errorValue = stuff->source;
2930*4882a593Smuzhiyun return rc;
2931*4882a593Smuzhiyun }
2932*4882a593Smuzhiyun
2933*4882a593Smuzhiyun if (src->drawable.depth != 1)
2934*4882a593Smuzhiyun return (BadMatch);
2935*4882a593Smuzhiyun
2936*4882a593Smuzhiyun /* Find and validate cursor mask pixmap, if one is provided */
2937*4882a593Smuzhiyun if (stuff->mask != None) {
2938*4882a593Smuzhiyun rc = dixLookupResourceByType((void **) &msk, stuff->mask, RT_PIXMAP,
2939*4882a593Smuzhiyun client, DixReadAccess);
2940*4882a593Smuzhiyun if (rc != Success) {
2941*4882a593Smuzhiyun client->errorValue = stuff->mask;
2942*4882a593Smuzhiyun return rc;
2943*4882a593Smuzhiyun }
2944*4882a593Smuzhiyun
2945*4882a593Smuzhiyun if (src->drawable.width != msk->drawable.width
2946*4882a593Smuzhiyun || src->drawable.height != msk->drawable.height
2947*4882a593Smuzhiyun || src->drawable.depth != 1 || msk->drawable.depth != 1)
2948*4882a593Smuzhiyun return BadMatch;
2949*4882a593Smuzhiyun }
2950*4882a593Smuzhiyun else
2951*4882a593Smuzhiyun msk = NULL;
2952*4882a593Smuzhiyun
2953*4882a593Smuzhiyun width = src->drawable.width;
2954*4882a593Smuzhiyun height = src->drawable.height;
2955*4882a593Smuzhiyun
2956*4882a593Smuzhiyun if (stuff->x > width || stuff->y > height)
2957*4882a593Smuzhiyun return BadMatch;
2958*4882a593Smuzhiyun
2959*4882a593Smuzhiyun srcbits = calloc(BitmapBytePad(width), height);
2960*4882a593Smuzhiyun if (!srcbits)
2961*4882a593Smuzhiyun return BadAlloc;
2962*4882a593Smuzhiyun n = BitmapBytePad(width) * height;
2963*4882a593Smuzhiyun mskbits = malloc(n);
2964*4882a593Smuzhiyun if (!mskbits) {
2965*4882a593Smuzhiyun free(srcbits);
2966*4882a593Smuzhiyun return BadAlloc;
2967*4882a593Smuzhiyun }
2968*4882a593Smuzhiyun
2969*4882a593Smuzhiyun (*src->drawable.pScreen->GetImage) ((DrawablePtr) src, 0, 0, width, height,
2970*4882a593Smuzhiyun XYPixmap, 1, (void *) srcbits);
2971*4882a593Smuzhiyun if (msk == (PixmapPtr) NULL) {
2972*4882a593Smuzhiyun unsigned char *bits = mskbits;
2973*4882a593Smuzhiyun
2974*4882a593Smuzhiyun while (--n >= 0)
2975*4882a593Smuzhiyun *bits++ = ~0;
2976*4882a593Smuzhiyun }
2977*4882a593Smuzhiyun else {
2978*4882a593Smuzhiyun /* zeroing the (pad) bits helps some ddx cursor handling */
2979*4882a593Smuzhiyun memset((char *) mskbits, 0, n);
2980*4882a593Smuzhiyun (*msk->drawable.pScreen->GetImage) ((DrawablePtr) msk, 0, 0, width,
2981*4882a593Smuzhiyun height, XYPixmap, 1,
2982*4882a593Smuzhiyun (void *) mskbits);
2983*4882a593Smuzhiyun }
2984*4882a593Smuzhiyun cm.width = width;
2985*4882a593Smuzhiyun cm.height = height;
2986*4882a593Smuzhiyun cm.xhot = stuff->x;
2987*4882a593Smuzhiyun cm.yhot = stuff->y;
2988*4882a593Smuzhiyun rc = AllocARGBCursor(srcbits, mskbits, NULL, &cm,
2989*4882a593Smuzhiyun stuff->foreRed, stuff->foreGreen, stuff->foreBlue,
2990*4882a593Smuzhiyun stuff->backRed, stuff->backGreen, stuff->backBlue,
2991*4882a593Smuzhiyun &pCursor, client, stuff->cid);
2992*4882a593Smuzhiyun
2993*4882a593Smuzhiyun if (rc != Success)
2994*4882a593Smuzhiyun goto bail;
2995*4882a593Smuzhiyun if (!AddResource(stuff->cid, RT_CURSOR, (void *) pCursor)) {
2996*4882a593Smuzhiyun rc = BadAlloc;
2997*4882a593Smuzhiyun goto bail;
2998*4882a593Smuzhiyun }
2999*4882a593Smuzhiyun
3000*4882a593Smuzhiyun return Success;
3001*4882a593Smuzhiyun bail:
3002*4882a593Smuzhiyun free(srcbits);
3003*4882a593Smuzhiyun free(mskbits);
3004*4882a593Smuzhiyun return rc;
3005*4882a593Smuzhiyun }
3006*4882a593Smuzhiyun
3007*4882a593Smuzhiyun int
ProcCreateGlyphCursor(ClientPtr client)3008*4882a593Smuzhiyun ProcCreateGlyphCursor(ClientPtr client)
3009*4882a593Smuzhiyun {
3010*4882a593Smuzhiyun CursorPtr pCursor;
3011*4882a593Smuzhiyun int res;
3012*4882a593Smuzhiyun
3013*4882a593Smuzhiyun REQUEST(xCreateGlyphCursorReq);
3014*4882a593Smuzhiyun
3015*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xCreateGlyphCursorReq);
3016*4882a593Smuzhiyun LEGAL_NEW_RESOURCE(stuff->cid, client);
3017*4882a593Smuzhiyun
3018*4882a593Smuzhiyun res = AllocGlyphCursor(stuff->source, stuff->sourceChar,
3019*4882a593Smuzhiyun stuff->mask, stuff->maskChar,
3020*4882a593Smuzhiyun stuff->foreRed, stuff->foreGreen, stuff->foreBlue,
3021*4882a593Smuzhiyun stuff->backRed, stuff->backGreen, stuff->backBlue,
3022*4882a593Smuzhiyun &pCursor, client, stuff->cid);
3023*4882a593Smuzhiyun if (res != Success)
3024*4882a593Smuzhiyun return res;
3025*4882a593Smuzhiyun if (AddResource(stuff->cid, RT_CURSOR, (void *) pCursor))
3026*4882a593Smuzhiyun return Success;
3027*4882a593Smuzhiyun return BadAlloc;
3028*4882a593Smuzhiyun }
3029*4882a593Smuzhiyun
3030*4882a593Smuzhiyun int
ProcFreeCursor(ClientPtr client)3031*4882a593Smuzhiyun ProcFreeCursor(ClientPtr client)
3032*4882a593Smuzhiyun {
3033*4882a593Smuzhiyun CursorPtr pCursor;
3034*4882a593Smuzhiyun int rc;
3035*4882a593Smuzhiyun
3036*4882a593Smuzhiyun REQUEST(xResourceReq);
3037*4882a593Smuzhiyun
3038*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xResourceReq);
3039*4882a593Smuzhiyun rc = dixLookupResourceByType((void **) &pCursor, stuff->id, RT_CURSOR,
3040*4882a593Smuzhiyun client, DixDestroyAccess);
3041*4882a593Smuzhiyun if (rc == Success) {
3042*4882a593Smuzhiyun FreeResource(stuff->id, RT_NONE);
3043*4882a593Smuzhiyun return Success;
3044*4882a593Smuzhiyun }
3045*4882a593Smuzhiyun else {
3046*4882a593Smuzhiyun client->errorValue = stuff->id;
3047*4882a593Smuzhiyun return rc;
3048*4882a593Smuzhiyun }
3049*4882a593Smuzhiyun }
3050*4882a593Smuzhiyun
3051*4882a593Smuzhiyun int
ProcQueryBestSize(ClientPtr client)3052*4882a593Smuzhiyun ProcQueryBestSize(ClientPtr client)
3053*4882a593Smuzhiyun {
3054*4882a593Smuzhiyun xQueryBestSizeReply reply;
3055*4882a593Smuzhiyun DrawablePtr pDraw;
3056*4882a593Smuzhiyun ScreenPtr pScreen;
3057*4882a593Smuzhiyun int rc;
3058*4882a593Smuzhiyun
3059*4882a593Smuzhiyun REQUEST(xQueryBestSizeReq);
3060*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xQueryBestSizeReq);
3061*4882a593Smuzhiyun
3062*4882a593Smuzhiyun if ((stuff->class != CursorShape) &&
3063*4882a593Smuzhiyun (stuff->class != TileShape) && (stuff->class != StippleShape)) {
3064*4882a593Smuzhiyun client->errorValue = stuff->class;
3065*4882a593Smuzhiyun return BadValue;
3066*4882a593Smuzhiyun }
3067*4882a593Smuzhiyun
3068*4882a593Smuzhiyun rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY,
3069*4882a593Smuzhiyun DixGetAttrAccess);
3070*4882a593Smuzhiyun if (rc != Success)
3071*4882a593Smuzhiyun return rc;
3072*4882a593Smuzhiyun if (stuff->class != CursorShape && pDraw->type == UNDRAWABLE_WINDOW)
3073*4882a593Smuzhiyun return BadMatch;
3074*4882a593Smuzhiyun pScreen = pDraw->pScreen;
3075*4882a593Smuzhiyun rc = XaceHook(XACE_SCREEN_ACCESS, client, pScreen, DixGetAttrAccess);
3076*4882a593Smuzhiyun if (rc != Success)
3077*4882a593Smuzhiyun return rc;
3078*4882a593Smuzhiyun (*pScreen->QueryBestSize) (stuff->class, &stuff->width,
3079*4882a593Smuzhiyun &stuff->height, pScreen);
3080*4882a593Smuzhiyun reply = (xQueryBestSizeReply) {
3081*4882a593Smuzhiyun .type = X_Reply,
3082*4882a593Smuzhiyun .sequenceNumber = client->sequence,
3083*4882a593Smuzhiyun .length = 0,
3084*4882a593Smuzhiyun .width = stuff->width,
3085*4882a593Smuzhiyun .height = stuff->height
3086*4882a593Smuzhiyun };
3087*4882a593Smuzhiyun WriteReplyToClient(client, sizeof(xQueryBestSizeReply), &reply);
3088*4882a593Smuzhiyun return Success;
3089*4882a593Smuzhiyun }
3090*4882a593Smuzhiyun
3091*4882a593Smuzhiyun int
ProcSetScreenSaver(ClientPtr client)3092*4882a593Smuzhiyun ProcSetScreenSaver(ClientPtr client)
3093*4882a593Smuzhiyun {
3094*4882a593Smuzhiyun int rc, i, blankingOption, exposureOption;
3095*4882a593Smuzhiyun
3096*4882a593Smuzhiyun REQUEST(xSetScreenSaverReq);
3097*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xSetScreenSaverReq);
3098*4882a593Smuzhiyun
3099*4882a593Smuzhiyun for (i = 0; i < screenInfo.numScreens; i++) {
3100*4882a593Smuzhiyun rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, screenInfo.screens[i],
3101*4882a593Smuzhiyun DixSetAttrAccess);
3102*4882a593Smuzhiyun if (rc != Success)
3103*4882a593Smuzhiyun return rc;
3104*4882a593Smuzhiyun }
3105*4882a593Smuzhiyun
3106*4882a593Smuzhiyun blankingOption = stuff->preferBlank;
3107*4882a593Smuzhiyun if ((blankingOption != DontPreferBlanking) &&
3108*4882a593Smuzhiyun (blankingOption != PreferBlanking) &&
3109*4882a593Smuzhiyun (blankingOption != DefaultBlanking)) {
3110*4882a593Smuzhiyun client->errorValue = blankingOption;
3111*4882a593Smuzhiyun return BadValue;
3112*4882a593Smuzhiyun }
3113*4882a593Smuzhiyun exposureOption = stuff->allowExpose;
3114*4882a593Smuzhiyun if ((exposureOption != DontAllowExposures) &&
3115*4882a593Smuzhiyun (exposureOption != AllowExposures) &&
3116*4882a593Smuzhiyun (exposureOption != DefaultExposures)) {
3117*4882a593Smuzhiyun client->errorValue = exposureOption;
3118*4882a593Smuzhiyun return BadValue;
3119*4882a593Smuzhiyun }
3120*4882a593Smuzhiyun if (stuff->timeout < -1) {
3121*4882a593Smuzhiyun client->errorValue = stuff->timeout;
3122*4882a593Smuzhiyun return BadValue;
3123*4882a593Smuzhiyun }
3124*4882a593Smuzhiyun if (stuff->interval < -1) {
3125*4882a593Smuzhiyun client->errorValue = stuff->interval;
3126*4882a593Smuzhiyun return BadValue;
3127*4882a593Smuzhiyun }
3128*4882a593Smuzhiyun
3129*4882a593Smuzhiyun if (blankingOption == DefaultBlanking)
3130*4882a593Smuzhiyun ScreenSaverBlanking = defaultScreenSaverBlanking;
3131*4882a593Smuzhiyun else
3132*4882a593Smuzhiyun ScreenSaverBlanking = blankingOption;
3133*4882a593Smuzhiyun if (exposureOption == DefaultExposures)
3134*4882a593Smuzhiyun ScreenSaverAllowExposures = defaultScreenSaverAllowExposures;
3135*4882a593Smuzhiyun else
3136*4882a593Smuzhiyun ScreenSaverAllowExposures = exposureOption;
3137*4882a593Smuzhiyun
3138*4882a593Smuzhiyun if (stuff->timeout >= 0)
3139*4882a593Smuzhiyun ScreenSaverTime = stuff->timeout * MILLI_PER_SECOND;
3140*4882a593Smuzhiyun else
3141*4882a593Smuzhiyun ScreenSaverTime = defaultScreenSaverTime;
3142*4882a593Smuzhiyun if (stuff->interval >= 0)
3143*4882a593Smuzhiyun ScreenSaverInterval = stuff->interval * MILLI_PER_SECOND;
3144*4882a593Smuzhiyun else
3145*4882a593Smuzhiyun ScreenSaverInterval = defaultScreenSaverInterval;
3146*4882a593Smuzhiyun
3147*4882a593Smuzhiyun SetScreenSaverTimer();
3148*4882a593Smuzhiyun return Success;
3149*4882a593Smuzhiyun }
3150*4882a593Smuzhiyun
3151*4882a593Smuzhiyun int
ProcGetScreenSaver(ClientPtr client)3152*4882a593Smuzhiyun ProcGetScreenSaver(ClientPtr client)
3153*4882a593Smuzhiyun {
3154*4882a593Smuzhiyun xGetScreenSaverReply rep;
3155*4882a593Smuzhiyun int rc, i;
3156*4882a593Smuzhiyun
3157*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xReq);
3158*4882a593Smuzhiyun
3159*4882a593Smuzhiyun for (i = 0; i < screenInfo.numScreens; i++) {
3160*4882a593Smuzhiyun rc = XaceHook(XACE_SCREENSAVER_ACCESS, client, screenInfo.screens[i],
3161*4882a593Smuzhiyun DixGetAttrAccess);
3162*4882a593Smuzhiyun if (rc != Success)
3163*4882a593Smuzhiyun return rc;
3164*4882a593Smuzhiyun }
3165*4882a593Smuzhiyun
3166*4882a593Smuzhiyun rep = (xGetScreenSaverReply) {
3167*4882a593Smuzhiyun .type = X_Reply,
3168*4882a593Smuzhiyun .sequenceNumber = client->sequence,
3169*4882a593Smuzhiyun .length = 0,
3170*4882a593Smuzhiyun .timeout = ScreenSaverTime / MILLI_PER_SECOND,
3171*4882a593Smuzhiyun .interval = ScreenSaverInterval / MILLI_PER_SECOND,
3172*4882a593Smuzhiyun .preferBlanking = ScreenSaverBlanking,
3173*4882a593Smuzhiyun .allowExposures = ScreenSaverAllowExposures
3174*4882a593Smuzhiyun };
3175*4882a593Smuzhiyun WriteReplyToClient(client, sizeof(xGetScreenSaverReply), &rep);
3176*4882a593Smuzhiyun return Success;
3177*4882a593Smuzhiyun }
3178*4882a593Smuzhiyun
3179*4882a593Smuzhiyun int
ProcChangeHosts(ClientPtr client)3180*4882a593Smuzhiyun ProcChangeHosts(ClientPtr client)
3181*4882a593Smuzhiyun {
3182*4882a593Smuzhiyun REQUEST(xChangeHostsReq);
3183*4882a593Smuzhiyun
3184*4882a593Smuzhiyun REQUEST_FIXED_SIZE(xChangeHostsReq, stuff->hostLength);
3185*4882a593Smuzhiyun
3186*4882a593Smuzhiyun if (stuff->mode == HostInsert)
3187*4882a593Smuzhiyun return AddHost(client, (int) stuff->hostFamily,
3188*4882a593Smuzhiyun stuff->hostLength, (void *) &stuff[1]);
3189*4882a593Smuzhiyun if (stuff->mode == HostDelete)
3190*4882a593Smuzhiyun return RemoveHost(client, (int) stuff->hostFamily,
3191*4882a593Smuzhiyun stuff->hostLength, (void *) &stuff[1]);
3192*4882a593Smuzhiyun client->errorValue = stuff->mode;
3193*4882a593Smuzhiyun return BadValue;
3194*4882a593Smuzhiyun }
3195*4882a593Smuzhiyun
3196*4882a593Smuzhiyun int
ProcListHosts(ClientPtr client)3197*4882a593Smuzhiyun ProcListHosts(ClientPtr client)
3198*4882a593Smuzhiyun {
3199*4882a593Smuzhiyun xListHostsReply reply;
3200*4882a593Smuzhiyun int len, nHosts, result;
3201*4882a593Smuzhiyun BOOL enabled;
3202*4882a593Smuzhiyun void *pdata;
3203*4882a593Smuzhiyun
3204*4882a593Smuzhiyun /* REQUEST(xListHostsReq); */
3205*4882a593Smuzhiyun
3206*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xListHostsReq);
3207*4882a593Smuzhiyun
3208*4882a593Smuzhiyun /* untrusted clients can't list hosts */
3209*4882a593Smuzhiyun result = XaceHook(XACE_SERVER_ACCESS, client, DixReadAccess);
3210*4882a593Smuzhiyun if (result != Success)
3211*4882a593Smuzhiyun return result;
3212*4882a593Smuzhiyun
3213*4882a593Smuzhiyun result = GetHosts(&pdata, &nHosts, &len, &enabled);
3214*4882a593Smuzhiyun if (result != Success)
3215*4882a593Smuzhiyun return result;
3216*4882a593Smuzhiyun
3217*4882a593Smuzhiyun reply = (xListHostsReply) {
3218*4882a593Smuzhiyun .type = X_Reply,
3219*4882a593Smuzhiyun .enabled = enabled,
3220*4882a593Smuzhiyun .sequenceNumber = client->sequence,
3221*4882a593Smuzhiyun .length = bytes_to_int32(len),
3222*4882a593Smuzhiyun .nHosts = nHosts
3223*4882a593Smuzhiyun };
3224*4882a593Smuzhiyun WriteReplyToClient(client, sizeof(xListHostsReply), &reply);
3225*4882a593Smuzhiyun if (nHosts) {
3226*4882a593Smuzhiyun client->pSwapReplyFunc = (ReplySwapPtr) SLHostsExtend;
3227*4882a593Smuzhiyun WriteSwappedDataToClient(client, len, pdata);
3228*4882a593Smuzhiyun }
3229*4882a593Smuzhiyun free(pdata);
3230*4882a593Smuzhiyun return Success;
3231*4882a593Smuzhiyun }
3232*4882a593Smuzhiyun
3233*4882a593Smuzhiyun int
ProcChangeAccessControl(ClientPtr client)3234*4882a593Smuzhiyun ProcChangeAccessControl(ClientPtr client)
3235*4882a593Smuzhiyun {
3236*4882a593Smuzhiyun REQUEST(xSetAccessControlReq);
3237*4882a593Smuzhiyun
3238*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xSetAccessControlReq);
3239*4882a593Smuzhiyun if ((stuff->mode != EnableAccess) && (stuff->mode != DisableAccess)) {
3240*4882a593Smuzhiyun client->errorValue = stuff->mode;
3241*4882a593Smuzhiyun return BadValue;
3242*4882a593Smuzhiyun }
3243*4882a593Smuzhiyun return ChangeAccessControl(client, stuff->mode == EnableAccess);
3244*4882a593Smuzhiyun }
3245*4882a593Smuzhiyun
3246*4882a593Smuzhiyun /*********************
3247*4882a593Smuzhiyun * CloseDownRetainedResources
3248*4882a593Smuzhiyun *
3249*4882a593Smuzhiyun * Find all clients that are gone and have terminated in RetainTemporary
3250*4882a593Smuzhiyun * and destroy their resources.
3251*4882a593Smuzhiyun *********************/
3252*4882a593Smuzhiyun
3253*4882a593Smuzhiyun static void
CloseDownRetainedResources(void)3254*4882a593Smuzhiyun CloseDownRetainedResources(void)
3255*4882a593Smuzhiyun {
3256*4882a593Smuzhiyun int i;
3257*4882a593Smuzhiyun ClientPtr client;
3258*4882a593Smuzhiyun
3259*4882a593Smuzhiyun for (i = 1; i < currentMaxClients; i++) {
3260*4882a593Smuzhiyun client = clients[i];
3261*4882a593Smuzhiyun if (client && (client->closeDownMode == RetainTemporary)
3262*4882a593Smuzhiyun && (client->clientGone))
3263*4882a593Smuzhiyun CloseDownClient(client);
3264*4882a593Smuzhiyun }
3265*4882a593Smuzhiyun }
3266*4882a593Smuzhiyun
3267*4882a593Smuzhiyun int
ProcKillClient(ClientPtr client)3268*4882a593Smuzhiyun ProcKillClient(ClientPtr client)
3269*4882a593Smuzhiyun {
3270*4882a593Smuzhiyun REQUEST(xResourceReq);
3271*4882a593Smuzhiyun ClientPtr killclient;
3272*4882a593Smuzhiyun int rc;
3273*4882a593Smuzhiyun
3274*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xResourceReq);
3275*4882a593Smuzhiyun if (stuff->id == AllTemporary) {
3276*4882a593Smuzhiyun CloseDownRetainedResources();
3277*4882a593Smuzhiyun return Success;
3278*4882a593Smuzhiyun }
3279*4882a593Smuzhiyun
3280*4882a593Smuzhiyun rc = dixLookupClient(&killclient, stuff->id, client, DixDestroyAccess);
3281*4882a593Smuzhiyun if (rc == Success) {
3282*4882a593Smuzhiyun CloseDownClient(killclient);
3283*4882a593Smuzhiyun if (client == killclient) {
3284*4882a593Smuzhiyun /* force yield and return Success, so that Dispatch()
3285*4882a593Smuzhiyun * doesn't try to touch client
3286*4882a593Smuzhiyun */
3287*4882a593Smuzhiyun isItTimeToYield = TRUE;
3288*4882a593Smuzhiyun }
3289*4882a593Smuzhiyun return Success;
3290*4882a593Smuzhiyun }
3291*4882a593Smuzhiyun else
3292*4882a593Smuzhiyun return rc;
3293*4882a593Smuzhiyun }
3294*4882a593Smuzhiyun
3295*4882a593Smuzhiyun int
ProcSetFontPath(ClientPtr client)3296*4882a593Smuzhiyun ProcSetFontPath(ClientPtr client)
3297*4882a593Smuzhiyun {
3298*4882a593Smuzhiyun unsigned char *ptr;
3299*4882a593Smuzhiyun unsigned long nbytes, total;
3300*4882a593Smuzhiyun long nfonts;
3301*4882a593Smuzhiyun int n;
3302*4882a593Smuzhiyun
3303*4882a593Smuzhiyun REQUEST(xSetFontPathReq);
3304*4882a593Smuzhiyun
3305*4882a593Smuzhiyun REQUEST_AT_LEAST_SIZE(xSetFontPathReq);
3306*4882a593Smuzhiyun
3307*4882a593Smuzhiyun nbytes = (client->req_len << 2) - sizeof(xSetFontPathReq);
3308*4882a593Smuzhiyun total = nbytes;
3309*4882a593Smuzhiyun ptr = (unsigned char *) &stuff[1];
3310*4882a593Smuzhiyun nfonts = stuff->nFonts;
3311*4882a593Smuzhiyun while (--nfonts >= 0) {
3312*4882a593Smuzhiyun if ((total == 0) || (total < (n = (*ptr + 1))))
3313*4882a593Smuzhiyun return BadLength;
3314*4882a593Smuzhiyun total -= n;
3315*4882a593Smuzhiyun ptr += n;
3316*4882a593Smuzhiyun }
3317*4882a593Smuzhiyun if (total >= 4)
3318*4882a593Smuzhiyun return BadLength;
3319*4882a593Smuzhiyun return SetFontPath(client, stuff->nFonts, (unsigned char *) &stuff[1]);
3320*4882a593Smuzhiyun }
3321*4882a593Smuzhiyun
3322*4882a593Smuzhiyun int
ProcGetFontPath(ClientPtr client)3323*4882a593Smuzhiyun ProcGetFontPath(ClientPtr client)
3324*4882a593Smuzhiyun {
3325*4882a593Smuzhiyun xGetFontPathReply reply;
3326*4882a593Smuzhiyun int rc, stringLens, numpaths;
3327*4882a593Smuzhiyun unsigned char *bufferStart;
3328*4882a593Smuzhiyun
3329*4882a593Smuzhiyun /* REQUEST (xReq); */
3330*4882a593Smuzhiyun
3331*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xReq);
3332*4882a593Smuzhiyun rc = GetFontPath(client, &numpaths, &stringLens, &bufferStart);
3333*4882a593Smuzhiyun if (rc != Success)
3334*4882a593Smuzhiyun return rc;
3335*4882a593Smuzhiyun
3336*4882a593Smuzhiyun reply = (xGetFontPathReply) {
3337*4882a593Smuzhiyun .type = X_Reply,
3338*4882a593Smuzhiyun .sequenceNumber = client->sequence,
3339*4882a593Smuzhiyun .length = bytes_to_int32(stringLens + numpaths),
3340*4882a593Smuzhiyun .nPaths = numpaths
3341*4882a593Smuzhiyun };
3342*4882a593Smuzhiyun
3343*4882a593Smuzhiyun WriteReplyToClient(client, sizeof(xGetFontPathReply), &reply);
3344*4882a593Smuzhiyun if (stringLens || numpaths)
3345*4882a593Smuzhiyun WriteToClient(client, stringLens + numpaths, bufferStart);
3346*4882a593Smuzhiyun return Success;
3347*4882a593Smuzhiyun }
3348*4882a593Smuzhiyun
3349*4882a593Smuzhiyun int
ProcChangeCloseDownMode(ClientPtr client)3350*4882a593Smuzhiyun ProcChangeCloseDownMode(ClientPtr client)
3351*4882a593Smuzhiyun {
3352*4882a593Smuzhiyun int rc;
3353*4882a593Smuzhiyun
3354*4882a593Smuzhiyun REQUEST(xSetCloseDownModeReq);
3355*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xSetCloseDownModeReq);
3356*4882a593Smuzhiyun
3357*4882a593Smuzhiyun rc = XaceHook(XACE_CLIENT_ACCESS, client, client, DixManageAccess);
3358*4882a593Smuzhiyun if (rc != Success)
3359*4882a593Smuzhiyun return rc;
3360*4882a593Smuzhiyun
3361*4882a593Smuzhiyun if ((stuff->mode == AllTemporary) ||
3362*4882a593Smuzhiyun (stuff->mode == RetainPermanent) || (stuff->mode == RetainTemporary)) {
3363*4882a593Smuzhiyun client->closeDownMode = stuff->mode;
3364*4882a593Smuzhiyun return Success;
3365*4882a593Smuzhiyun }
3366*4882a593Smuzhiyun else {
3367*4882a593Smuzhiyun client->errorValue = stuff->mode;
3368*4882a593Smuzhiyun return BadValue;
3369*4882a593Smuzhiyun }
3370*4882a593Smuzhiyun }
3371*4882a593Smuzhiyun
3372*4882a593Smuzhiyun int
ProcForceScreenSaver(ClientPtr client)3373*4882a593Smuzhiyun ProcForceScreenSaver(ClientPtr client)
3374*4882a593Smuzhiyun {
3375*4882a593Smuzhiyun int rc;
3376*4882a593Smuzhiyun
3377*4882a593Smuzhiyun REQUEST(xForceScreenSaverReq);
3378*4882a593Smuzhiyun
3379*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xForceScreenSaverReq);
3380*4882a593Smuzhiyun
3381*4882a593Smuzhiyun if ((stuff->mode != ScreenSaverReset) && (stuff->mode != ScreenSaverActive)) {
3382*4882a593Smuzhiyun client->errorValue = stuff->mode;
3383*4882a593Smuzhiyun return BadValue;
3384*4882a593Smuzhiyun }
3385*4882a593Smuzhiyun rc = dixSaveScreens(client, SCREEN_SAVER_FORCER, (int) stuff->mode);
3386*4882a593Smuzhiyun if (rc != Success)
3387*4882a593Smuzhiyun return rc;
3388*4882a593Smuzhiyun return Success;
3389*4882a593Smuzhiyun }
3390*4882a593Smuzhiyun
3391*4882a593Smuzhiyun int
ProcNoOperation(ClientPtr client)3392*4882a593Smuzhiyun ProcNoOperation(ClientPtr client)
3393*4882a593Smuzhiyun {
3394*4882a593Smuzhiyun REQUEST_AT_LEAST_SIZE(xReq);
3395*4882a593Smuzhiyun
3396*4882a593Smuzhiyun /* noop -- don't do anything */
3397*4882a593Smuzhiyun return Success;
3398*4882a593Smuzhiyun }
3399*4882a593Smuzhiyun
3400*4882a593Smuzhiyun /**********************
3401*4882a593Smuzhiyun * CloseDownClient
3402*4882a593Smuzhiyun *
3403*4882a593Smuzhiyun * Client can either mark his resources destroy or retain. If retained and
3404*4882a593Smuzhiyun * then killed again, the client is really destroyed.
3405*4882a593Smuzhiyun *********************/
3406*4882a593Smuzhiyun
3407*4882a593Smuzhiyun char dispatchExceptionAtReset = DE_RESET;
3408*4882a593Smuzhiyun
3409*4882a593Smuzhiyun void
CloseDownClient(ClientPtr client)3410*4882a593Smuzhiyun CloseDownClient(ClientPtr client)
3411*4882a593Smuzhiyun {
3412*4882a593Smuzhiyun Bool really_close_down = client->clientGone ||
3413*4882a593Smuzhiyun client->closeDownMode == DestroyAll;
3414*4882a593Smuzhiyun
3415*4882a593Smuzhiyun if (!client->clientGone) {
3416*4882a593Smuzhiyun /* ungrab server if grabbing client dies */
3417*4882a593Smuzhiyun if (grabState != GrabNone && grabClient == client) {
3418*4882a593Smuzhiyun UngrabServer(client);
3419*4882a593Smuzhiyun }
3420*4882a593Smuzhiyun BITCLEAR(grabWaiters, client->index);
3421*4882a593Smuzhiyun DeleteClientFromAnySelections(client);
3422*4882a593Smuzhiyun ReleaseActiveGrabs(client);
3423*4882a593Smuzhiyun DeleteClientFontStuff(client);
3424*4882a593Smuzhiyun if (!really_close_down) {
3425*4882a593Smuzhiyun /* This frees resources that should never be retained
3426*4882a593Smuzhiyun * no matter what the close down mode is. Actually we
3427*4882a593Smuzhiyun * could do this unconditionally, but it's probably
3428*4882a593Smuzhiyun * better not to traverse all the client's resources
3429*4882a593Smuzhiyun * twice (once here, once a few lines down in
3430*4882a593Smuzhiyun * FreeClientResources) in the common case of
3431*4882a593Smuzhiyun * really_close_down == TRUE.
3432*4882a593Smuzhiyun */
3433*4882a593Smuzhiyun FreeClientNeverRetainResources(client);
3434*4882a593Smuzhiyun client->clientState = ClientStateRetained;
3435*4882a593Smuzhiyun if (ClientStateCallback) {
3436*4882a593Smuzhiyun NewClientInfoRec clientinfo;
3437*4882a593Smuzhiyun
3438*4882a593Smuzhiyun clientinfo.client = client;
3439*4882a593Smuzhiyun clientinfo.prefix = (xConnSetupPrefix *) NULL;
3440*4882a593Smuzhiyun clientinfo.setup = (xConnSetup *) NULL;
3441*4882a593Smuzhiyun CallCallbacks((&ClientStateCallback), (void *) &clientinfo);
3442*4882a593Smuzhiyun }
3443*4882a593Smuzhiyun }
3444*4882a593Smuzhiyun client->clientGone = TRUE; /* so events aren't sent to client */
3445*4882a593Smuzhiyun if (ClientIsAsleep(client))
3446*4882a593Smuzhiyun ClientSignal(client);
3447*4882a593Smuzhiyun ProcessWorkQueueZombies();
3448*4882a593Smuzhiyun CloseDownConnection(client);
3449*4882a593Smuzhiyun output_pending_clear(client);
3450*4882a593Smuzhiyun mark_client_not_ready(client);
3451*4882a593Smuzhiyun
3452*4882a593Smuzhiyun /* If the client made it to the Running stage, nClients has
3453*4882a593Smuzhiyun * been incremented on its behalf, so we need to decrement it
3454*4882a593Smuzhiyun * now. If it hasn't gotten to Running, nClients has *not*
3455*4882a593Smuzhiyun * been incremented, so *don't* decrement it.
3456*4882a593Smuzhiyun */
3457*4882a593Smuzhiyun if (client->clientState != ClientStateInitial) {
3458*4882a593Smuzhiyun --nClients;
3459*4882a593Smuzhiyun }
3460*4882a593Smuzhiyun }
3461*4882a593Smuzhiyun
3462*4882a593Smuzhiyun if (really_close_down) {
3463*4882a593Smuzhiyun if (client->clientState == ClientStateRunning && nClients == 0)
3464*4882a593Smuzhiyun dispatchException |= dispatchExceptionAtReset;
3465*4882a593Smuzhiyun
3466*4882a593Smuzhiyun client->clientState = ClientStateGone;
3467*4882a593Smuzhiyun if (ClientStateCallback) {
3468*4882a593Smuzhiyun NewClientInfoRec clientinfo;
3469*4882a593Smuzhiyun
3470*4882a593Smuzhiyun clientinfo.client = client;
3471*4882a593Smuzhiyun clientinfo.prefix = (xConnSetupPrefix *) NULL;
3472*4882a593Smuzhiyun clientinfo.setup = (xConnSetup *) NULL;
3473*4882a593Smuzhiyun CallCallbacks((&ClientStateCallback), (void *) &clientinfo);
3474*4882a593Smuzhiyun }
3475*4882a593Smuzhiyun TouchListenerGone(client->clientAsMask);
3476*4882a593Smuzhiyun FreeClientResources(client);
3477*4882a593Smuzhiyun /* Disable client ID tracking. This must be done after
3478*4882a593Smuzhiyun * ClientStateCallback. */
3479*4882a593Smuzhiyun ReleaseClientIds(client);
3480*4882a593Smuzhiyun #ifdef XSERVER_DTRACE
3481*4882a593Smuzhiyun XSERVER_CLIENT_DISCONNECT(client->index);
3482*4882a593Smuzhiyun #endif
3483*4882a593Smuzhiyun if (client->index < nextFreeClientID)
3484*4882a593Smuzhiyun nextFreeClientID = client->index;
3485*4882a593Smuzhiyun clients[client->index] = NullClient;
3486*4882a593Smuzhiyun SmartLastClient = NullClient;
3487*4882a593Smuzhiyun dixFreeObjectWithPrivates(client, PRIVATE_CLIENT);
3488*4882a593Smuzhiyun
3489*4882a593Smuzhiyun while (!clients[currentMaxClients - 1])
3490*4882a593Smuzhiyun currentMaxClients--;
3491*4882a593Smuzhiyun }
3492*4882a593Smuzhiyun }
3493*4882a593Smuzhiyun
3494*4882a593Smuzhiyun static void
KillAllClients(void)3495*4882a593Smuzhiyun KillAllClients(void)
3496*4882a593Smuzhiyun {
3497*4882a593Smuzhiyun int i;
3498*4882a593Smuzhiyun
3499*4882a593Smuzhiyun for (i = 1; i < currentMaxClients; i++)
3500*4882a593Smuzhiyun if (clients[i]) {
3501*4882a593Smuzhiyun /* Make sure Retained clients are released. */
3502*4882a593Smuzhiyun clients[i]->closeDownMode = DestroyAll;
3503*4882a593Smuzhiyun CloseDownClient(clients[i]);
3504*4882a593Smuzhiyun }
3505*4882a593Smuzhiyun }
3506*4882a593Smuzhiyun
3507*4882a593Smuzhiyun void
InitClient(ClientPtr client,int i,void * ospriv)3508*4882a593Smuzhiyun InitClient(ClientPtr client, int i, void *ospriv)
3509*4882a593Smuzhiyun {
3510*4882a593Smuzhiyun client->index = i;
3511*4882a593Smuzhiyun xorg_list_init(&client->ready);
3512*4882a593Smuzhiyun xorg_list_init(&client->output_pending);
3513*4882a593Smuzhiyun client->clientAsMask = ((Mask) i) << CLIENTOFFSET;
3514*4882a593Smuzhiyun client->closeDownMode = i ? DestroyAll : RetainPermanent;
3515*4882a593Smuzhiyun client->requestVector = InitialVector;
3516*4882a593Smuzhiyun client->osPrivate = ospriv;
3517*4882a593Smuzhiyun QueryMinMaxKeyCodes(&client->minKC, &client->maxKC);
3518*4882a593Smuzhiyun client->smart_start_tick = SmartScheduleTime;
3519*4882a593Smuzhiyun client->smart_stop_tick = SmartScheduleTime;
3520*4882a593Smuzhiyun client->clientIds = NULL;
3521*4882a593Smuzhiyun }
3522*4882a593Smuzhiyun
3523*4882a593Smuzhiyun /************************
3524*4882a593Smuzhiyun * int NextAvailableClient(ospriv)
3525*4882a593Smuzhiyun *
3526*4882a593Smuzhiyun * OS dependent portion can't assign client id's because of CloseDownModes.
3527*4882a593Smuzhiyun * Returns NULL if there are no free clients.
3528*4882a593Smuzhiyun *************************/
3529*4882a593Smuzhiyun
3530*4882a593Smuzhiyun ClientPtr
NextAvailableClient(void * ospriv)3531*4882a593Smuzhiyun NextAvailableClient(void *ospriv)
3532*4882a593Smuzhiyun {
3533*4882a593Smuzhiyun int i;
3534*4882a593Smuzhiyun ClientPtr client;
3535*4882a593Smuzhiyun xReq data;
3536*4882a593Smuzhiyun
3537*4882a593Smuzhiyun i = nextFreeClientID;
3538*4882a593Smuzhiyun if (i == LimitClients)
3539*4882a593Smuzhiyun return (ClientPtr) NULL;
3540*4882a593Smuzhiyun clients[i] = client =
3541*4882a593Smuzhiyun dixAllocateObjectWithPrivates(ClientRec, PRIVATE_CLIENT);
3542*4882a593Smuzhiyun if (!client)
3543*4882a593Smuzhiyun return (ClientPtr) NULL;
3544*4882a593Smuzhiyun InitClient(client, i, ospriv);
3545*4882a593Smuzhiyun if (!InitClientResources(client)) {
3546*4882a593Smuzhiyun dixFreeObjectWithPrivates(client, PRIVATE_CLIENT);
3547*4882a593Smuzhiyun return (ClientPtr) NULL;
3548*4882a593Smuzhiyun }
3549*4882a593Smuzhiyun data.reqType = 1;
3550*4882a593Smuzhiyun data.length = bytes_to_int32(sz_xReq + sz_xConnClientPrefix);
3551*4882a593Smuzhiyun if (!InsertFakeRequest(client, (char *) &data, sz_xReq)) {
3552*4882a593Smuzhiyun FreeClientResources(client);
3553*4882a593Smuzhiyun dixFreeObjectWithPrivates(client, PRIVATE_CLIENT);
3554*4882a593Smuzhiyun return (ClientPtr) NULL;
3555*4882a593Smuzhiyun }
3556*4882a593Smuzhiyun if (i == currentMaxClients)
3557*4882a593Smuzhiyun currentMaxClients++;
3558*4882a593Smuzhiyun while ((nextFreeClientID < LimitClients) && clients[nextFreeClientID])
3559*4882a593Smuzhiyun nextFreeClientID++;
3560*4882a593Smuzhiyun
3561*4882a593Smuzhiyun /* Enable client ID tracking. This must be done before
3562*4882a593Smuzhiyun * ClientStateCallback. */
3563*4882a593Smuzhiyun ReserveClientIds(client);
3564*4882a593Smuzhiyun
3565*4882a593Smuzhiyun if (ClientStateCallback) {
3566*4882a593Smuzhiyun NewClientInfoRec clientinfo;
3567*4882a593Smuzhiyun
3568*4882a593Smuzhiyun clientinfo.client = client;
3569*4882a593Smuzhiyun clientinfo.prefix = (xConnSetupPrefix *) NULL;
3570*4882a593Smuzhiyun clientinfo.setup = (xConnSetup *) NULL;
3571*4882a593Smuzhiyun CallCallbacks((&ClientStateCallback), (void *) &clientinfo);
3572*4882a593Smuzhiyun }
3573*4882a593Smuzhiyun return client;
3574*4882a593Smuzhiyun }
3575*4882a593Smuzhiyun
3576*4882a593Smuzhiyun int
ProcInitialConnection(ClientPtr client)3577*4882a593Smuzhiyun ProcInitialConnection(ClientPtr client)
3578*4882a593Smuzhiyun {
3579*4882a593Smuzhiyun REQUEST(xReq);
3580*4882a593Smuzhiyun xConnClientPrefix *prefix;
3581*4882a593Smuzhiyun int whichbyte = 1;
3582*4882a593Smuzhiyun char order;
3583*4882a593Smuzhiyun
3584*4882a593Smuzhiyun prefix = (xConnClientPrefix *) ((char *)stuff + sz_xReq);
3585*4882a593Smuzhiyun order = prefix->byteOrder;
3586*4882a593Smuzhiyun if (order != 'l' && order != 'B' && order != 'r' && order != 'R')
3587*4882a593Smuzhiyun return client->noClientException = -1;
3588*4882a593Smuzhiyun if (((*(char *) &whichbyte) && (order == 'B' || order == 'R')) ||
3589*4882a593Smuzhiyun (!(*(char *) &whichbyte) && (order == 'l' || order == 'r'))) {
3590*4882a593Smuzhiyun client->swapped = TRUE;
3591*4882a593Smuzhiyun SwapConnClientPrefix(prefix);
3592*4882a593Smuzhiyun }
3593*4882a593Smuzhiyun stuff->reqType = 2;
3594*4882a593Smuzhiyun stuff->length += bytes_to_int32(prefix->nbytesAuthProto) +
3595*4882a593Smuzhiyun bytes_to_int32(prefix->nbytesAuthString);
3596*4882a593Smuzhiyun if (client->swapped) {
3597*4882a593Smuzhiyun swaps(&stuff->length);
3598*4882a593Smuzhiyun }
3599*4882a593Smuzhiyun if (order == 'r' || order == 'R') {
3600*4882a593Smuzhiyun client->local = FALSE;
3601*4882a593Smuzhiyun }
3602*4882a593Smuzhiyun ResetCurrentRequest(client);
3603*4882a593Smuzhiyun return Success;
3604*4882a593Smuzhiyun }
3605*4882a593Smuzhiyun
3606*4882a593Smuzhiyun static int
SendConnSetup(ClientPtr client,const char * reason)3607*4882a593Smuzhiyun SendConnSetup(ClientPtr client, const char *reason)
3608*4882a593Smuzhiyun {
3609*4882a593Smuzhiyun xWindowRoot *root;
3610*4882a593Smuzhiyun int i;
3611*4882a593Smuzhiyun int numScreens;
3612*4882a593Smuzhiyun char *lConnectionInfo;
3613*4882a593Smuzhiyun xConnSetupPrefix *lconnSetupPrefix;
3614*4882a593Smuzhiyun
3615*4882a593Smuzhiyun if (reason) {
3616*4882a593Smuzhiyun xConnSetupPrefix csp;
3617*4882a593Smuzhiyun
3618*4882a593Smuzhiyun csp.success = xFalse;
3619*4882a593Smuzhiyun csp.lengthReason = strlen(reason);
3620*4882a593Smuzhiyun csp.length = bytes_to_int32(csp.lengthReason);
3621*4882a593Smuzhiyun csp.majorVersion = X_PROTOCOL;
3622*4882a593Smuzhiyun csp.minorVersion = X_PROTOCOL_REVISION;
3623*4882a593Smuzhiyun if (client->swapped)
3624*4882a593Smuzhiyun WriteSConnSetupPrefix(client, &csp);
3625*4882a593Smuzhiyun else
3626*4882a593Smuzhiyun WriteToClient(client, sz_xConnSetupPrefix, &csp);
3627*4882a593Smuzhiyun WriteToClient(client, (int) csp.lengthReason, reason);
3628*4882a593Smuzhiyun return client->noClientException = -1;
3629*4882a593Smuzhiyun }
3630*4882a593Smuzhiyun
3631*4882a593Smuzhiyun numScreens = screenInfo.numScreens;
3632*4882a593Smuzhiyun lConnectionInfo = ConnectionInfo;
3633*4882a593Smuzhiyun lconnSetupPrefix = &connSetupPrefix;
3634*4882a593Smuzhiyun
3635*4882a593Smuzhiyun /* We're about to start speaking X protocol back to the client by
3636*4882a593Smuzhiyun * sending the connection setup info. This means the authorization
3637*4882a593Smuzhiyun * step is complete, and we can count the client as an
3638*4882a593Smuzhiyun * authorized one.
3639*4882a593Smuzhiyun */
3640*4882a593Smuzhiyun nClients++;
3641*4882a593Smuzhiyun
3642*4882a593Smuzhiyun client->requestVector = client->swapped ? SwappedProcVector : ProcVector;
3643*4882a593Smuzhiyun client->sequence = 0;
3644*4882a593Smuzhiyun ((xConnSetup *) lConnectionInfo)->ridBase = client->clientAsMask;
3645*4882a593Smuzhiyun ((xConnSetup *) lConnectionInfo)->ridMask = RESOURCE_ID_MASK;
3646*4882a593Smuzhiyun #ifdef MATCH_CLIENT_ENDIAN
3647*4882a593Smuzhiyun ((xConnSetup *) lConnectionInfo)->imageByteOrder = ClientOrder(client);
3648*4882a593Smuzhiyun ((xConnSetup *) lConnectionInfo)->bitmapBitOrder = ClientOrder(client);
3649*4882a593Smuzhiyun #endif
3650*4882a593Smuzhiyun /* fill in the "currentInputMask" */
3651*4882a593Smuzhiyun root = (xWindowRoot *) (lConnectionInfo + connBlockScreenStart);
3652*4882a593Smuzhiyun #ifdef PANORAMIX
3653*4882a593Smuzhiyun if (noPanoramiXExtension)
3654*4882a593Smuzhiyun numScreens = screenInfo.numScreens;
3655*4882a593Smuzhiyun else
3656*4882a593Smuzhiyun numScreens = ((xConnSetup *) ConnectionInfo)->numRoots;
3657*4882a593Smuzhiyun #endif
3658*4882a593Smuzhiyun
3659*4882a593Smuzhiyun for (i = 0; i < numScreens; i++) {
3660*4882a593Smuzhiyun unsigned int j;
3661*4882a593Smuzhiyun xDepth *pDepth;
3662*4882a593Smuzhiyun WindowPtr pRoot = screenInfo.screens[i]->root;
3663*4882a593Smuzhiyun
3664*4882a593Smuzhiyun root->currentInputMask = pRoot->eventMask | wOtherEventMasks(pRoot);
3665*4882a593Smuzhiyun pDepth = (xDepth *) (root + 1);
3666*4882a593Smuzhiyun for (j = 0; j < root->nDepths; j++) {
3667*4882a593Smuzhiyun pDepth = (xDepth *) (((char *) (pDepth + 1)) +
3668*4882a593Smuzhiyun pDepth->nVisuals * sizeof(xVisualType));
3669*4882a593Smuzhiyun }
3670*4882a593Smuzhiyun root = (xWindowRoot *) pDepth;
3671*4882a593Smuzhiyun }
3672*4882a593Smuzhiyun
3673*4882a593Smuzhiyun if (client->swapped) {
3674*4882a593Smuzhiyun WriteSConnSetupPrefix(client, lconnSetupPrefix);
3675*4882a593Smuzhiyun WriteSConnectionInfo(client,
3676*4882a593Smuzhiyun (unsigned long) (lconnSetupPrefix->length << 2),
3677*4882a593Smuzhiyun lConnectionInfo);
3678*4882a593Smuzhiyun }
3679*4882a593Smuzhiyun else {
3680*4882a593Smuzhiyun WriteToClient(client, sizeof(xConnSetupPrefix), lconnSetupPrefix);
3681*4882a593Smuzhiyun WriteToClient(client, (int) (lconnSetupPrefix->length << 2),
3682*4882a593Smuzhiyun lConnectionInfo);
3683*4882a593Smuzhiyun }
3684*4882a593Smuzhiyun client->clientState = ClientStateRunning;
3685*4882a593Smuzhiyun if (ClientStateCallback) {
3686*4882a593Smuzhiyun NewClientInfoRec clientinfo;
3687*4882a593Smuzhiyun
3688*4882a593Smuzhiyun clientinfo.client = client;
3689*4882a593Smuzhiyun clientinfo.prefix = lconnSetupPrefix;
3690*4882a593Smuzhiyun clientinfo.setup = (xConnSetup *) lConnectionInfo;
3691*4882a593Smuzhiyun CallCallbacks((&ClientStateCallback), (void *) &clientinfo);
3692*4882a593Smuzhiyun }
3693*4882a593Smuzhiyun return Success;
3694*4882a593Smuzhiyun }
3695*4882a593Smuzhiyun
3696*4882a593Smuzhiyun int
ProcEstablishConnection(ClientPtr client)3697*4882a593Smuzhiyun ProcEstablishConnection(ClientPtr client)
3698*4882a593Smuzhiyun {
3699*4882a593Smuzhiyun const char *reason;
3700*4882a593Smuzhiyun char *auth_proto, *auth_string;
3701*4882a593Smuzhiyun xConnClientPrefix *prefix;
3702*4882a593Smuzhiyun
3703*4882a593Smuzhiyun REQUEST(xReq);
3704*4882a593Smuzhiyun
3705*4882a593Smuzhiyun prefix = (xConnClientPrefix *) ((char *) stuff + sz_xReq);
3706*4882a593Smuzhiyun auth_proto = (char *) prefix + sz_xConnClientPrefix;
3707*4882a593Smuzhiyun auth_string = auth_proto + pad_to_int32(prefix->nbytesAuthProto);
3708*4882a593Smuzhiyun
3709*4882a593Smuzhiyun if ((client->req_len << 2) != sz_xReq + sz_xConnClientPrefix +
3710*4882a593Smuzhiyun pad_to_int32(prefix->nbytesAuthProto) +
3711*4882a593Smuzhiyun pad_to_int32(prefix->nbytesAuthString))
3712*4882a593Smuzhiyun reason = "Bad length";
3713*4882a593Smuzhiyun else if ((prefix->majorVersion != X_PROTOCOL) ||
3714*4882a593Smuzhiyun (prefix->minorVersion != X_PROTOCOL_REVISION))
3715*4882a593Smuzhiyun reason = "Protocol version mismatch";
3716*4882a593Smuzhiyun else
3717*4882a593Smuzhiyun reason = ClientAuthorized(client,
3718*4882a593Smuzhiyun (unsigned short) prefix->nbytesAuthProto,
3719*4882a593Smuzhiyun auth_proto,
3720*4882a593Smuzhiyun (unsigned short) prefix->nbytesAuthString,
3721*4882a593Smuzhiyun auth_string);
3722*4882a593Smuzhiyun
3723*4882a593Smuzhiyun return (SendConnSetup(client, reason));
3724*4882a593Smuzhiyun }
3725*4882a593Smuzhiyun
3726*4882a593Smuzhiyun void
SendErrorToClient(ClientPtr client,unsigned majorCode,unsigned minorCode,XID resId,int errorCode)3727*4882a593Smuzhiyun SendErrorToClient(ClientPtr client, unsigned majorCode, unsigned minorCode,
3728*4882a593Smuzhiyun XID resId, int errorCode)
3729*4882a593Smuzhiyun {
3730*4882a593Smuzhiyun xError rep = {
3731*4882a593Smuzhiyun .type = X_Error,
3732*4882a593Smuzhiyun .errorCode = errorCode,
3733*4882a593Smuzhiyun .resourceID = resId,
3734*4882a593Smuzhiyun .minorCode = minorCode,
3735*4882a593Smuzhiyun .majorCode = majorCode
3736*4882a593Smuzhiyun };
3737*4882a593Smuzhiyun
3738*4882a593Smuzhiyun WriteEventsToClient(client, 1, (xEvent *) &rep);
3739*4882a593Smuzhiyun }
3740*4882a593Smuzhiyun
3741*4882a593Smuzhiyun void
MarkClientException(ClientPtr client)3742*4882a593Smuzhiyun MarkClientException(ClientPtr client)
3743*4882a593Smuzhiyun {
3744*4882a593Smuzhiyun client->noClientException = -1;
3745*4882a593Smuzhiyun }
3746*4882a593Smuzhiyun
3747*4882a593Smuzhiyun /*
3748*4882a593Smuzhiyun * This array encodes the answer to the question "what is the log base 2
3749*4882a593Smuzhiyun * of the number of pixels that fit in a scanline pad unit?"
3750*4882a593Smuzhiyun * Note that ~0 is an invalid entry (mostly for the benefit of the reader).
3751*4882a593Smuzhiyun */
3752*4882a593Smuzhiyun static int answer[6][4] = {
3753*4882a593Smuzhiyun /* pad pad pad pad */
3754*4882a593Smuzhiyun /* 8 16 32 64 */
3755*4882a593Smuzhiyun
3756*4882a593Smuzhiyun {3, 4, 5, 6}, /* 1 bit per pixel */
3757*4882a593Smuzhiyun {1, 2, 3, 4}, /* 4 bits per pixel */
3758*4882a593Smuzhiyun {0, 1, 2, 3}, /* 8 bits per pixel */
3759*4882a593Smuzhiyun {~0, 0, 1, 2}, /* 16 bits per pixel */
3760*4882a593Smuzhiyun {~0, ~0, 0, 1}, /* 24 bits per pixel */
3761*4882a593Smuzhiyun {~0, ~0, 0, 1} /* 32 bits per pixel */
3762*4882a593Smuzhiyun };
3763*4882a593Smuzhiyun
3764*4882a593Smuzhiyun /*
3765*4882a593Smuzhiyun * This array gives the answer to the question "what is the first index for
3766*4882a593Smuzhiyun * the answer array above given the number of bits per pixel?"
3767*4882a593Smuzhiyun * Note that ~0 is an invalid entry (mostly for the benefit of the reader).
3768*4882a593Smuzhiyun */
3769*4882a593Smuzhiyun static int indexForBitsPerPixel[33] = {
3770*4882a593Smuzhiyun ~0, 0, ~0, ~0, /* 1 bit per pixel */
3771*4882a593Smuzhiyun 1, ~0, ~0, ~0, /* 4 bits per pixel */
3772*4882a593Smuzhiyun 2, ~0, ~0, ~0, /* 8 bits per pixel */
3773*4882a593Smuzhiyun ~0, ~0, ~0, ~0,
3774*4882a593Smuzhiyun 3, ~0, ~0, ~0, /* 16 bits per pixel */
3775*4882a593Smuzhiyun ~0, ~0, ~0, ~0,
3776*4882a593Smuzhiyun 4, ~0, ~0, ~0, /* 24 bits per pixel */
3777*4882a593Smuzhiyun ~0, ~0, ~0, ~0,
3778*4882a593Smuzhiyun 5 /* 32 bits per pixel */
3779*4882a593Smuzhiyun };
3780*4882a593Smuzhiyun
3781*4882a593Smuzhiyun /*
3782*4882a593Smuzhiyun * This array gives the bytesperPixel value for cases where the number
3783*4882a593Smuzhiyun * of bits per pixel is a multiple of 8 but not a power of 2.
3784*4882a593Smuzhiyun */
3785*4882a593Smuzhiyun static int answerBytesPerPixel[33] = {
3786*4882a593Smuzhiyun ~0, 0, ~0, ~0, /* 1 bit per pixel */
3787*4882a593Smuzhiyun 0, ~0, ~0, ~0, /* 4 bits per pixel */
3788*4882a593Smuzhiyun 0, ~0, ~0, ~0, /* 8 bits per pixel */
3789*4882a593Smuzhiyun ~0, ~0, ~0, ~0,
3790*4882a593Smuzhiyun 0, ~0, ~0, ~0, /* 16 bits per pixel */
3791*4882a593Smuzhiyun ~0, ~0, ~0, ~0,
3792*4882a593Smuzhiyun 3, ~0, ~0, ~0, /* 24 bits per pixel */
3793*4882a593Smuzhiyun ~0, ~0, ~0, ~0,
3794*4882a593Smuzhiyun 0 /* 32 bits per pixel */
3795*4882a593Smuzhiyun };
3796*4882a593Smuzhiyun
3797*4882a593Smuzhiyun /*
3798*4882a593Smuzhiyun * This array gives the answer to the question "what is the second index for
3799*4882a593Smuzhiyun * the answer array above given the number of bits per scanline pad unit?"
3800*4882a593Smuzhiyun * Note that ~0 is an invalid entry (mostly for the benefit of the reader).
3801*4882a593Smuzhiyun */
3802*4882a593Smuzhiyun static int indexForScanlinePad[65] = {
3803*4882a593Smuzhiyun ~0, ~0, ~0, ~0,
3804*4882a593Smuzhiyun ~0, ~0, ~0, ~0,
3805*4882a593Smuzhiyun 0, ~0, ~0, ~0, /* 8 bits per scanline pad unit */
3806*4882a593Smuzhiyun ~0, ~0, ~0, ~0,
3807*4882a593Smuzhiyun 1, ~0, ~0, ~0, /* 16 bits per scanline pad unit */
3808*4882a593Smuzhiyun ~0, ~0, ~0, ~0,
3809*4882a593Smuzhiyun ~0, ~0, ~0, ~0,
3810*4882a593Smuzhiyun ~0, ~0, ~0, ~0,
3811*4882a593Smuzhiyun 2, ~0, ~0, ~0, /* 32 bits per scanline pad unit */
3812*4882a593Smuzhiyun ~0, ~0, ~0, ~0,
3813*4882a593Smuzhiyun ~0, ~0, ~0, ~0,
3814*4882a593Smuzhiyun ~0, ~0, ~0, ~0,
3815*4882a593Smuzhiyun ~0, ~0, ~0, ~0,
3816*4882a593Smuzhiyun ~0, ~0, ~0, ~0,
3817*4882a593Smuzhiyun ~0, ~0, ~0, ~0,
3818*4882a593Smuzhiyun ~0, ~0, ~0, ~0,
3819*4882a593Smuzhiyun 3 /* 64 bits per scanline pad unit */
3820*4882a593Smuzhiyun };
3821*4882a593Smuzhiyun
3822*4882a593Smuzhiyun /*
3823*4882a593Smuzhiyun grow the array of screenRecs if necessary.
3824*4882a593Smuzhiyun call the device-supplied initialization procedure
3825*4882a593Smuzhiyun with its screen number, a pointer to its ScreenRec, argc, and argv.
3826*4882a593Smuzhiyun return the number of successfully installed screens.
3827*4882a593Smuzhiyun
3828*4882a593Smuzhiyun */
3829*4882a593Smuzhiyun
init_screen(ScreenPtr pScreen,int i,Bool gpu)3830*4882a593Smuzhiyun static int init_screen(ScreenPtr pScreen, int i, Bool gpu)
3831*4882a593Smuzhiyun {
3832*4882a593Smuzhiyun int scanlinepad, format, depth, bitsPerPixel, j, k;
3833*4882a593Smuzhiyun
3834*4882a593Smuzhiyun dixInitScreenSpecificPrivates(pScreen);
3835*4882a593Smuzhiyun
3836*4882a593Smuzhiyun if (!dixAllocatePrivates(&pScreen->devPrivates, PRIVATE_SCREEN)) {
3837*4882a593Smuzhiyun return -1;
3838*4882a593Smuzhiyun }
3839*4882a593Smuzhiyun pScreen->myNum = i;
3840*4882a593Smuzhiyun if (gpu) {
3841*4882a593Smuzhiyun pScreen->myNum += GPU_SCREEN_OFFSET;
3842*4882a593Smuzhiyun pScreen->isGPU = TRUE;
3843*4882a593Smuzhiyun }
3844*4882a593Smuzhiyun pScreen->totalPixmapSize = 0; /* computed in CreateScratchPixmapForScreen */
3845*4882a593Smuzhiyun pScreen->ClipNotify = 0; /* for R4 ddx compatibility */
3846*4882a593Smuzhiyun pScreen->CreateScreenResources = 0;
3847*4882a593Smuzhiyun
3848*4882a593Smuzhiyun xorg_list_init(&pScreen->pixmap_dirty_list);
3849*4882a593Smuzhiyun xorg_list_init(&pScreen->slave_list);
3850*4882a593Smuzhiyun
3851*4882a593Smuzhiyun /*
3852*4882a593Smuzhiyun * This loop gets run once for every Screen that gets added,
3853*4882a593Smuzhiyun * but thats ok. If the ddx layer initializes the formats
3854*4882a593Smuzhiyun * one at a time calling AddScreen() after each, then each
3855*4882a593Smuzhiyun * iteration will make it a little more accurate. Worst case
3856*4882a593Smuzhiyun * we do this loop N * numPixmapFormats where N is # of screens.
3857*4882a593Smuzhiyun * Anyway, this must be called after InitOutput and before the
3858*4882a593Smuzhiyun * screen init routine is called.
3859*4882a593Smuzhiyun */
3860*4882a593Smuzhiyun for (format = 0; format < screenInfo.numPixmapFormats; format++) {
3861*4882a593Smuzhiyun depth = screenInfo.formats[format].depth;
3862*4882a593Smuzhiyun bitsPerPixel = screenInfo.formats[format].bitsPerPixel;
3863*4882a593Smuzhiyun scanlinepad = screenInfo.formats[format].scanlinePad;
3864*4882a593Smuzhiyun j = indexForBitsPerPixel[bitsPerPixel];
3865*4882a593Smuzhiyun k = indexForScanlinePad[scanlinepad];
3866*4882a593Smuzhiyun PixmapWidthPaddingInfo[depth].padPixelsLog2 = answer[j][k];
3867*4882a593Smuzhiyun PixmapWidthPaddingInfo[depth].padRoundUp =
3868*4882a593Smuzhiyun (scanlinepad / bitsPerPixel) - 1;
3869*4882a593Smuzhiyun j = indexForBitsPerPixel[8]; /* bits per byte */
3870*4882a593Smuzhiyun PixmapWidthPaddingInfo[depth].padBytesLog2 = answer[j][k];
3871*4882a593Smuzhiyun PixmapWidthPaddingInfo[depth].bitsPerPixel = bitsPerPixel;
3872*4882a593Smuzhiyun if (answerBytesPerPixel[bitsPerPixel]) {
3873*4882a593Smuzhiyun PixmapWidthPaddingInfo[depth].notPower2 = 1;
3874*4882a593Smuzhiyun PixmapWidthPaddingInfo[depth].bytesPerPixel =
3875*4882a593Smuzhiyun answerBytesPerPixel[bitsPerPixel];
3876*4882a593Smuzhiyun }
3877*4882a593Smuzhiyun else {
3878*4882a593Smuzhiyun PixmapWidthPaddingInfo[depth].notPower2 = 0;
3879*4882a593Smuzhiyun }
3880*4882a593Smuzhiyun }
3881*4882a593Smuzhiyun return 0;
3882*4882a593Smuzhiyun }
3883*4882a593Smuzhiyun
3884*4882a593Smuzhiyun int
AddScreen(Bool (* pfnInit)(ScreenPtr,int,char **),int argc,char ** argv)3885*4882a593Smuzhiyun AddScreen(Bool (*pfnInit) (ScreenPtr /*pScreen */ ,
3886*4882a593Smuzhiyun int /*argc */ ,
3887*4882a593Smuzhiyun char ** /*argv */
3888*4882a593Smuzhiyun ), int argc, char **argv)
3889*4882a593Smuzhiyun {
3890*4882a593Smuzhiyun
3891*4882a593Smuzhiyun int i;
3892*4882a593Smuzhiyun ScreenPtr pScreen;
3893*4882a593Smuzhiyun Bool ret;
3894*4882a593Smuzhiyun
3895*4882a593Smuzhiyun i = screenInfo.numScreens;
3896*4882a593Smuzhiyun if (i == MAXSCREENS)
3897*4882a593Smuzhiyun return -1;
3898*4882a593Smuzhiyun
3899*4882a593Smuzhiyun pScreen = (ScreenPtr) calloc(1, sizeof(ScreenRec));
3900*4882a593Smuzhiyun if (!pScreen)
3901*4882a593Smuzhiyun return -1;
3902*4882a593Smuzhiyun
3903*4882a593Smuzhiyun ret = init_screen(pScreen, i, FALSE);
3904*4882a593Smuzhiyun if (ret != 0) {
3905*4882a593Smuzhiyun free(pScreen);
3906*4882a593Smuzhiyun return ret;
3907*4882a593Smuzhiyun }
3908*4882a593Smuzhiyun /* This is where screen specific stuff gets initialized. Load the
3909*4882a593Smuzhiyun screen structure, call the hardware, whatever.
3910*4882a593Smuzhiyun This is also where the default colormap should be allocated and
3911*4882a593Smuzhiyun also pixel values for blackPixel, whitePixel, and the cursor
3912*4882a593Smuzhiyun Note that InitScreen is NOT allowed to modify argc, argv, or
3913*4882a593Smuzhiyun any of the strings pointed to by argv. They may be passed to
3914*4882a593Smuzhiyun multiple screens.
3915*4882a593Smuzhiyun */
3916*4882a593Smuzhiyun screenInfo.screens[i] = pScreen;
3917*4882a593Smuzhiyun screenInfo.numScreens++;
3918*4882a593Smuzhiyun if (!(*pfnInit) (pScreen, argc, argv)) {
3919*4882a593Smuzhiyun dixFreeScreenSpecificPrivates(pScreen);
3920*4882a593Smuzhiyun dixFreePrivates(pScreen->devPrivates, PRIVATE_SCREEN);
3921*4882a593Smuzhiyun free(pScreen);
3922*4882a593Smuzhiyun screenInfo.numScreens--;
3923*4882a593Smuzhiyun return -1;
3924*4882a593Smuzhiyun }
3925*4882a593Smuzhiyun
3926*4882a593Smuzhiyun update_desktop_dimensions();
3927*4882a593Smuzhiyun
3928*4882a593Smuzhiyun dixRegisterScreenPrivateKey(&cursorScreenDevPriv, pScreen, PRIVATE_CURSOR,
3929*4882a593Smuzhiyun 0);
3930*4882a593Smuzhiyun
3931*4882a593Smuzhiyun return i;
3932*4882a593Smuzhiyun }
3933*4882a593Smuzhiyun
3934*4882a593Smuzhiyun int
AddGPUScreen(Bool (* pfnInit)(ScreenPtr,int,char **),int argc,char ** argv)3935*4882a593Smuzhiyun AddGPUScreen(Bool (*pfnInit) (ScreenPtr /*pScreen */ ,
3936*4882a593Smuzhiyun int /*argc */ ,
3937*4882a593Smuzhiyun char ** /*argv */
3938*4882a593Smuzhiyun ),
3939*4882a593Smuzhiyun int argc, char **argv)
3940*4882a593Smuzhiyun {
3941*4882a593Smuzhiyun int i;
3942*4882a593Smuzhiyun ScreenPtr pScreen;
3943*4882a593Smuzhiyun Bool ret;
3944*4882a593Smuzhiyun
3945*4882a593Smuzhiyun i = screenInfo.numGPUScreens;
3946*4882a593Smuzhiyun if (i == MAXGPUSCREENS)
3947*4882a593Smuzhiyun return -1;
3948*4882a593Smuzhiyun
3949*4882a593Smuzhiyun pScreen = (ScreenPtr) calloc(1, sizeof(ScreenRec));
3950*4882a593Smuzhiyun if (!pScreen)
3951*4882a593Smuzhiyun return -1;
3952*4882a593Smuzhiyun
3953*4882a593Smuzhiyun ret = init_screen(pScreen, i, TRUE);
3954*4882a593Smuzhiyun if (ret != 0) {
3955*4882a593Smuzhiyun free(pScreen);
3956*4882a593Smuzhiyun return ret;
3957*4882a593Smuzhiyun }
3958*4882a593Smuzhiyun
3959*4882a593Smuzhiyun /* This is where screen specific stuff gets initialized. Load the
3960*4882a593Smuzhiyun screen structure, call the hardware, whatever.
3961*4882a593Smuzhiyun This is also where the default colormap should be allocated and
3962*4882a593Smuzhiyun also pixel values for blackPixel, whitePixel, and the cursor
3963*4882a593Smuzhiyun Note that InitScreen is NOT allowed to modify argc, argv, or
3964*4882a593Smuzhiyun any of the strings pointed to by argv. They may be passed to
3965*4882a593Smuzhiyun multiple screens.
3966*4882a593Smuzhiyun */
3967*4882a593Smuzhiyun screenInfo.gpuscreens[i] = pScreen;
3968*4882a593Smuzhiyun screenInfo.numGPUScreens++;
3969*4882a593Smuzhiyun if (!(*pfnInit) (pScreen, argc, argv)) {
3970*4882a593Smuzhiyun dixFreePrivates(pScreen->devPrivates, PRIVATE_SCREEN);
3971*4882a593Smuzhiyun free(pScreen);
3972*4882a593Smuzhiyun screenInfo.numGPUScreens--;
3973*4882a593Smuzhiyun return -1;
3974*4882a593Smuzhiyun }
3975*4882a593Smuzhiyun
3976*4882a593Smuzhiyun update_desktop_dimensions();
3977*4882a593Smuzhiyun
3978*4882a593Smuzhiyun /*
3979*4882a593Smuzhiyun * We cannot register the Screen PRIVATE_CURSOR key if cursors are already
3980*4882a593Smuzhiyun * created, because dix/privates.c does not have relocation code for
3981*4882a593Smuzhiyun * PRIVATE_CURSOR. Once this is fixed the if() can be removed and we can
3982*4882a593Smuzhiyun * register the Screen PRIVATE_CURSOR key unconditionally.
3983*4882a593Smuzhiyun */
3984*4882a593Smuzhiyun if (!dixPrivatesCreated(PRIVATE_CURSOR))
3985*4882a593Smuzhiyun dixRegisterScreenPrivateKey(&cursorScreenDevPriv, pScreen,
3986*4882a593Smuzhiyun PRIVATE_CURSOR, 0);
3987*4882a593Smuzhiyun
3988*4882a593Smuzhiyun return i;
3989*4882a593Smuzhiyun }
3990*4882a593Smuzhiyun
3991*4882a593Smuzhiyun void
RemoveGPUScreen(ScreenPtr pScreen)3992*4882a593Smuzhiyun RemoveGPUScreen(ScreenPtr pScreen)
3993*4882a593Smuzhiyun {
3994*4882a593Smuzhiyun int idx, j;
3995*4882a593Smuzhiyun if (!pScreen->isGPU)
3996*4882a593Smuzhiyun return;
3997*4882a593Smuzhiyun
3998*4882a593Smuzhiyun idx = pScreen->myNum - GPU_SCREEN_OFFSET;
3999*4882a593Smuzhiyun for (j = idx; j < screenInfo.numGPUScreens - 1; j++) {
4000*4882a593Smuzhiyun screenInfo.gpuscreens[j] = screenInfo.gpuscreens[j + 1];
4001*4882a593Smuzhiyun screenInfo.gpuscreens[j]->myNum = j + GPU_SCREEN_OFFSET;
4002*4882a593Smuzhiyun }
4003*4882a593Smuzhiyun screenInfo.numGPUScreens--;
4004*4882a593Smuzhiyun
4005*4882a593Smuzhiyun /* this gets freed later in the resource list, but without
4006*4882a593Smuzhiyun * the screen existing it causes crashes - so remove it here */
4007*4882a593Smuzhiyun if (pScreen->defColormap)
4008*4882a593Smuzhiyun FreeResource(pScreen->defColormap, RT_COLORMAP);
4009*4882a593Smuzhiyun free(pScreen);
4010*4882a593Smuzhiyun
4011*4882a593Smuzhiyun }
4012*4882a593Smuzhiyun
4013*4882a593Smuzhiyun void
AttachUnboundGPU(ScreenPtr pScreen,ScreenPtr new)4014*4882a593Smuzhiyun AttachUnboundGPU(ScreenPtr pScreen, ScreenPtr new)
4015*4882a593Smuzhiyun {
4016*4882a593Smuzhiyun assert(new->isGPU);
4017*4882a593Smuzhiyun assert(!new->current_master);
4018*4882a593Smuzhiyun xorg_list_add(&new->slave_head, &pScreen->slave_list);
4019*4882a593Smuzhiyun new->current_master = pScreen;
4020*4882a593Smuzhiyun }
4021*4882a593Smuzhiyun
4022*4882a593Smuzhiyun void
DetachUnboundGPU(ScreenPtr slave)4023*4882a593Smuzhiyun DetachUnboundGPU(ScreenPtr slave)
4024*4882a593Smuzhiyun {
4025*4882a593Smuzhiyun assert(slave->isGPU);
4026*4882a593Smuzhiyun assert(!slave->is_output_slave);
4027*4882a593Smuzhiyun assert(!slave->is_offload_slave);
4028*4882a593Smuzhiyun xorg_list_del(&slave->slave_head);
4029*4882a593Smuzhiyun slave->current_master = NULL;
4030*4882a593Smuzhiyun }
4031*4882a593Smuzhiyun
4032*4882a593Smuzhiyun void
AttachOutputGPU(ScreenPtr pScreen,ScreenPtr new)4033*4882a593Smuzhiyun AttachOutputGPU(ScreenPtr pScreen, ScreenPtr new)
4034*4882a593Smuzhiyun {
4035*4882a593Smuzhiyun assert(new->isGPU);
4036*4882a593Smuzhiyun assert(!new->is_output_slave);
4037*4882a593Smuzhiyun assert(new->current_master == pScreen);
4038*4882a593Smuzhiyun new->is_output_slave = TRUE;
4039*4882a593Smuzhiyun new->current_master->output_slaves++;
4040*4882a593Smuzhiyun }
4041*4882a593Smuzhiyun
4042*4882a593Smuzhiyun void
DetachOutputGPU(ScreenPtr slave)4043*4882a593Smuzhiyun DetachOutputGPU(ScreenPtr slave)
4044*4882a593Smuzhiyun {
4045*4882a593Smuzhiyun assert(slave->isGPU);
4046*4882a593Smuzhiyun assert(slave->is_output_slave);
4047*4882a593Smuzhiyun slave->current_master->output_slaves--;
4048*4882a593Smuzhiyun slave->is_output_slave = FALSE;
4049*4882a593Smuzhiyun }
4050*4882a593Smuzhiyun
4051*4882a593Smuzhiyun void
AttachOffloadGPU(ScreenPtr pScreen,ScreenPtr new)4052*4882a593Smuzhiyun AttachOffloadGPU(ScreenPtr pScreen, ScreenPtr new)
4053*4882a593Smuzhiyun {
4054*4882a593Smuzhiyun assert(new->isGPU);
4055*4882a593Smuzhiyun assert(!new->is_offload_slave);
4056*4882a593Smuzhiyun assert(new->current_master == pScreen);
4057*4882a593Smuzhiyun new->is_offload_slave = TRUE;
4058*4882a593Smuzhiyun }
4059*4882a593Smuzhiyun
4060*4882a593Smuzhiyun void
DetachOffloadGPU(ScreenPtr slave)4061*4882a593Smuzhiyun DetachOffloadGPU(ScreenPtr slave)
4062*4882a593Smuzhiyun {
4063*4882a593Smuzhiyun assert(slave->isGPU);
4064*4882a593Smuzhiyun assert(slave->is_offload_slave);
4065*4882a593Smuzhiyun slave->is_offload_slave = FALSE;
4066*4882a593Smuzhiyun }
4067*4882a593Smuzhiyun
4068