1*4882a593Smuzhiyun /*
2*4882a593Smuzhiyun * Copyright (c) 2003 Torrey T. Lyons. All Rights Reserved.
3*4882a593Smuzhiyun * Copyright (c) 2002-2012 Apple Inc. All rights reserved.
4*4882a593Smuzhiyun *
5*4882a593Smuzhiyun * Permission is hereby granted, free of charge, to any person
6*4882a593Smuzhiyun * obtaining a copy of this software and associated documentation files
7*4882a593Smuzhiyun * (the "Software"), to deal in the Software without restriction,
8*4882a593Smuzhiyun * including without limitation the rights to use, copy, modify, merge,
9*4882a593Smuzhiyun * publish, distribute, sublicense, and/or sell copies of the Software,
10*4882a593Smuzhiyun * and to permit persons to whom the Software is furnished to do so,
11*4882a593Smuzhiyun * subject to the following conditions:
12*4882a593Smuzhiyun *
13*4882a593Smuzhiyun * The above copyright notice and this permission notice shall be
14*4882a593Smuzhiyun * included in all copies or substantial portions of the Software.
15*4882a593Smuzhiyun *
16*4882a593Smuzhiyun * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
17*4882a593Smuzhiyun * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
18*4882a593Smuzhiyun * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
19*4882a593Smuzhiyun * NONINFRINGEMENT. IN NO EVENT SHALL THE ABOVE LISTED COPYRIGHT
20*4882a593Smuzhiyun * HOLDER(S) BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
21*4882a593Smuzhiyun * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
22*4882a593Smuzhiyun * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
23*4882a593Smuzhiyun * DEALINGS IN THE SOFTWARE.
24*4882a593Smuzhiyun *
25*4882a593Smuzhiyun * Except as contained in this notice, the name(s) of the above
26*4882a593Smuzhiyun * copyright holders shall not be used in advertising or otherwise to
27*4882a593Smuzhiyun * promote the sale, use or other dealings in this Software without
28*4882a593Smuzhiyun * prior written authorization.
29*4882a593Smuzhiyun */
30*4882a593Smuzhiyun
31*4882a593Smuzhiyun #include "sanitizedCarbon.h"
32*4882a593Smuzhiyun
33*4882a593Smuzhiyun #ifdef HAVE_DIX_CONFIG_H
34*4882a593Smuzhiyun #include <dix-config.h>
35*4882a593Smuzhiyun #endif
36*4882a593Smuzhiyun
37*4882a593Smuzhiyun #include "quartz.h"
38*4882a593Smuzhiyun
39*4882a593Smuzhiyun #include "misc.h"
40*4882a593Smuzhiyun #include "dixstruct.h"
41*4882a593Smuzhiyun #include "globals.h"
42*4882a593Smuzhiyun #include "extnsionst.h"
43*4882a593Smuzhiyun #include "colormapst.h"
44*4882a593Smuzhiyun #include "cursorstr.h"
45*4882a593Smuzhiyun #include "scrnintstr.h"
46*4882a593Smuzhiyun #include "windowstr.h"
47*4882a593Smuzhiyun #include "servermd.h"
48*4882a593Smuzhiyun #include "swaprep.h"
49*4882a593Smuzhiyun #include "propertyst.h"
50*4882a593Smuzhiyun #include <X11/Xatom.h>
51*4882a593Smuzhiyun #include "darwin.h"
52*4882a593Smuzhiyun #define _APPLEWM_SERVER_
53*4882a593Smuzhiyun #include <X11/extensions/applewmproto.h>
54*4882a593Smuzhiyun #include "applewmExt.h"
55*4882a593Smuzhiyun #include "X11Application.h"
56*4882a593Smuzhiyun #include "protocol-versions.h"
57*4882a593Smuzhiyun
58*4882a593Smuzhiyun #define DEFINE_ATOM_HELPER(func, atom_name) \
59*4882a593Smuzhiyun static Atom func(void) { \
60*4882a593Smuzhiyun static int generation; \
61*4882a593Smuzhiyun static Atom atom; \
62*4882a593Smuzhiyun if (generation != serverGeneration) { \
63*4882a593Smuzhiyun generation = serverGeneration; \
64*4882a593Smuzhiyun atom = MakeAtom(atom_name, strlen(atom_name), TRUE); \
65*4882a593Smuzhiyun } \
66*4882a593Smuzhiyun return atom; \
67*4882a593Smuzhiyun }
68*4882a593Smuzhiyun
69*4882a593Smuzhiyun DEFINE_ATOM_HELPER(xa_native_screen_origin, "_NATIVE_SCREEN_ORIGIN")
70*4882a593Smuzhiyun DEFINE_ATOM_HELPER(xa_apple_no_order_in, "_APPLE_NO_ORDER_IN")
71*4882a593Smuzhiyun
72*4882a593Smuzhiyun static AppleWMProcsPtr appleWMProcs;
73*4882a593Smuzhiyun
74*4882a593Smuzhiyun static int WMErrorBase;
75*4882a593Smuzhiyun
76*4882a593Smuzhiyun static unsigned char WMReqCode = 0;
77*4882a593Smuzhiyun static int WMEventBase = 0;
78*4882a593Smuzhiyun
79*4882a593Smuzhiyun static RESTYPE ClientType, EventType; /* resource types for event masks */
80*4882a593Smuzhiyun static XID eventResource;
81*4882a593Smuzhiyun
82*4882a593Smuzhiyun /* Currently selected events */
83*4882a593Smuzhiyun static unsigned int eventMask = 0;
84*4882a593Smuzhiyun
85*4882a593Smuzhiyun static int
86*4882a593Smuzhiyun WMFreeClient(void *data, XID id);
87*4882a593Smuzhiyun static int
88*4882a593Smuzhiyun WMFreeEvents(void *data, XID id);
89*4882a593Smuzhiyun static void
90*4882a593Smuzhiyun SNotifyEvent(xAppleWMNotifyEvent *from, xAppleWMNotifyEvent *to);
91*4882a593Smuzhiyun
92*4882a593Smuzhiyun typedef struct _WMEvent *WMEventPtr;
93*4882a593Smuzhiyun typedef struct _WMEvent {
94*4882a593Smuzhiyun WMEventPtr next;
95*4882a593Smuzhiyun ClientPtr client;
96*4882a593Smuzhiyun XID clientResource;
97*4882a593Smuzhiyun unsigned int mask;
98*4882a593Smuzhiyun } WMEventRec;
99*4882a593Smuzhiyun
100*4882a593Smuzhiyun static inline BoxRec
make_box(int x,int y,int w,int h)101*4882a593Smuzhiyun make_box(int x, int y, int w, int h)
102*4882a593Smuzhiyun {
103*4882a593Smuzhiyun BoxRec r;
104*4882a593Smuzhiyun r.x1 = x;
105*4882a593Smuzhiyun r.y1 = y;
106*4882a593Smuzhiyun r.x2 = x + w;
107*4882a593Smuzhiyun r.y2 = y + h;
108*4882a593Smuzhiyun return r;
109*4882a593Smuzhiyun }
110*4882a593Smuzhiyun
111*4882a593Smuzhiyun /* Updates the _NATIVE_SCREEN_ORIGIN property on the given root window. */
112*4882a593Smuzhiyun void
AppleWMSetScreenOrigin(WindowPtr pWin)113*4882a593Smuzhiyun AppleWMSetScreenOrigin(WindowPtr pWin)
114*4882a593Smuzhiyun {
115*4882a593Smuzhiyun int32_t data[2];
116*4882a593Smuzhiyun
117*4882a593Smuzhiyun data[0] = pWin->drawable.pScreen->x + darwinMainScreenX;
118*4882a593Smuzhiyun data[1] = pWin->drawable.pScreen->y + darwinMainScreenY;
119*4882a593Smuzhiyun
120*4882a593Smuzhiyun dixChangeWindowProperty(serverClient, pWin, xa_native_screen_origin(),
121*4882a593Smuzhiyun XA_INTEGER, 32, PropModeReplace, 2, data, TRUE);
122*4882a593Smuzhiyun }
123*4882a593Smuzhiyun
124*4882a593Smuzhiyun /* Window managers can set the _APPLE_NO_ORDER_IN property on windows
125*4882a593Smuzhiyun that are being genie-restored from the Dock. We want them to
126*4882a593Smuzhiyun be mapped but remain ordered-out until the animation
127*4882a593Smuzhiyun completes (when the Dock will order them in). */
128*4882a593Smuzhiyun Bool
AppleWMDoReorderWindow(WindowPtr pWin)129*4882a593Smuzhiyun AppleWMDoReorderWindow(WindowPtr pWin)
130*4882a593Smuzhiyun {
131*4882a593Smuzhiyun Atom atom;
132*4882a593Smuzhiyun PropertyPtr prop;
133*4882a593Smuzhiyun int rc;
134*4882a593Smuzhiyun
135*4882a593Smuzhiyun atom = xa_apple_no_order_in();
136*4882a593Smuzhiyun rc = dixLookupProperty(&prop, pWin, atom, serverClient, DixReadAccess);
137*4882a593Smuzhiyun
138*4882a593Smuzhiyun if (Success == rc && prop->type == atom)
139*4882a593Smuzhiyun return 0;
140*4882a593Smuzhiyun
141*4882a593Smuzhiyun return 1;
142*4882a593Smuzhiyun }
143*4882a593Smuzhiyun
144*4882a593Smuzhiyun static int
ProcAppleWMQueryVersion(register ClientPtr client)145*4882a593Smuzhiyun ProcAppleWMQueryVersion(register ClientPtr client)
146*4882a593Smuzhiyun {
147*4882a593Smuzhiyun xAppleWMQueryVersionReply rep;
148*4882a593Smuzhiyun
149*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xAppleWMQueryVersionReq);
150*4882a593Smuzhiyun rep.type = X_Reply;
151*4882a593Smuzhiyun rep.length = 0;
152*4882a593Smuzhiyun rep.sequenceNumber = client->sequence;
153*4882a593Smuzhiyun rep.majorVersion = SERVER_APPLEWM_MAJOR_VERSION;
154*4882a593Smuzhiyun rep.minorVersion = SERVER_APPLEWM_MINOR_VERSION;
155*4882a593Smuzhiyun rep.patchVersion = SERVER_APPLEWM_PATCH_VERSION;
156*4882a593Smuzhiyun if (client->swapped) {
157*4882a593Smuzhiyun swaps(&rep.sequenceNumber);
158*4882a593Smuzhiyun swapl(&rep.length);
159*4882a593Smuzhiyun }
160*4882a593Smuzhiyun WriteToClient(client, sizeof(xAppleWMQueryVersionReply),&rep);
161*4882a593Smuzhiyun return Success;
162*4882a593Smuzhiyun }
163*4882a593Smuzhiyun
164*4882a593Smuzhiyun /* events */
165*4882a593Smuzhiyun
166*4882a593Smuzhiyun static inline void
updateEventMask(WMEventPtr * pHead)167*4882a593Smuzhiyun updateEventMask(WMEventPtr *pHead)
168*4882a593Smuzhiyun {
169*4882a593Smuzhiyun WMEventPtr pCur;
170*4882a593Smuzhiyun
171*4882a593Smuzhiyun eventMask = 0;
172*4882a593Smuzhiyun for (pCur = *pHead; pCur != NULL; pCur = pCur->next)
173*4882a593Smuzhiyun eventMask |= pCur->mask;
174*4882a593Smuzhiyun }
175*4882a593Smuzhiyun
176*4882a593Smuzhiyun /*ARGSUSED*/
177*4882a593Smuzhiyun static int
WMFreeClient(void * data,XID id)178*4882a593Smuzhiyun WMFreeClient(void *data, XID id)
179*4882a593Smuzhiyun {
180*4882a593Smuzhiyun WMEventPtr pEvent;
181*4882a593Smuzhiyun WMEventPtr *pHead, pCur, pPrev;
182*4882a593Smuzhiyun int i;
183*4882a593Smuzhiyun
184*4882a593Smuzhiyun pEvent = (WMEventPtr)data;
185*4882a593Smuzhiyun i = dixLookupResourceByType(
186*4882a593Smuzhiyun (void **)&pHead, eventResource, EventType, serverClient,
187*4882a593Smuzhiyun DixReadAccess |
188*4882a593Smuzhiyun DixWriteAccess | DixDestroyAccess);
189*4882a593Smuzhiyun if (i == Success && pHead) {
190*4882a593Smuzhiyun pPrev = 0;
191*4882a593Smuzhiyun for (pCur = *pHead; pCur && pCur != pEvent; pCur = pCur->next)
192*4882a593Smuzhiyun pPrev = pCur;
193*4882a593Smuzhiyun if (pCur) {
194*4882a593Smuzhiyun if (pPrev)
195*4882a593Smuzhiyun pPrev->next = pEvent->next;
196*4882a593Smuzhiyun else
197*4882a593Smuzhiyun *pHead = pEvent->next;
198*4882a593Smuzhiyun }
199*4882a593Smuzhiyun updateEventMask(pHead);
200*4882a593Smuzhiyun }
201*4882a593Smuzhiyun free((void *)pEvent);
202*4882a593Smuzhiyun return 1;
203*4882a593Smuzhiyun }
204*4882a593Smuzhiyun
205*4882a593Smuzhiyun /*ARGSUSED*/
206*4882a593Smuzhiyun static int
WMFreeEvents(void * data,XID id)207*4882a593Smuzhiyun WMFreeEvents(void *data, XID id)
208*4882a593Smuzhiyun {
209*4882a593Smuzhiyun WMEventPtr *pHead, pCur, pNext;
210*4882a593Smuzhiyun
211*4882a593Smuzhiyun pHead = (WMEventPtr *)data;
212*4882a593Smuzhiyun for (pCur = *pHead; pCur; pCur = pNext) {
213*4882a593Smuzhiyun pNext = pCur->next;
214*4882a593Smuzhiyun FreeResource(pCur->clientResource, ClientType);
215*4882a593Smuzhiyun free((void *)pCur);
216*4882a593Smuzhiyun }
217*4882a593Smuzhiyun free((void *)pHead);
218*4882a593Smuzhiyun eventMask = 0;
219*4882a593Smuzhiyun return 1;
220*4882a593Smuzhiyun }
221*4882a593Smuzhiyun
222*4882a593Smuzhiyun static int
ProcAppleWMSelectInput(register ClientPtr client)223*4882a593Smuzhiyun ProcAppleWMSelectInput(register ClientPtr client)
224*4882a593Smuzhiyun {
225*4882a593Smuzhiyun REQUEST(xAppleWMSelectInputReq);
226*4882a593Smuzhiyun WMEventPtr pEvent, pNewEvent, *pHead;
227*4882a593Smuzhiyun XID clientResource;
228*4882a593Smuzhiyun int i;
229*4882a593Smuzhiyun
230*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xAppleWMSelectInputReq);
231*4882a593Smuzhiyun i =
232*4882a593Smuzhiyun dixLookupResourceByType((void **)&pHead, eventResource, EventType,
233*4882a593Smuzhiyun client,
234*4882a593Smuzhiyun DixWriteAccess);
235*4882a593Smuzhiyun if (stuff->mask != 0) {
236*4882a593Smuzhiyun if (i == Success && pHead) {
237*4882a593Smuzhiyun /* check for existing entry. */
238*4882a593Smuzhiyun for (pEvent = *pHead; pEvent; pEvent = pEvent->next) {
239*4882a593Smuzhiyun if (pEvent->client == client) {
240*4882a593Smuzhiyun pEvent->mask = stuff->mask;
241*4882a593Smuzhiyun updateEventMask(pHead);
242*4882a593Smuzhiyun return Success;
243*4882a593Smuzhiyun }
244*4882a593Smuzhiyun }
245*4882a593Smuzhiyun }
246*4882a593Smuzhiyun
247*4882a593Smuzhiyun /* build the entry */
248*4882a593Smuzhiyun pNewEvent = (WMEventPtr)malloc(sizeof(WMEventRec));
249*4882a593Smuzhiyun if (!pNewEvent)
250*4882a593Smuzhiyun return BadAlloc;
251*4882a593Smuzhiyun pNewEvent->next = 0;
252*4882a593Smuzhiyun pNewEvent->client = client;
253*4882a593Smuzhiyun pNewEvent->mask = stuff->mask;
254*4882a593Smuzhiyun /*
255*4882a593Smuzhiyun * add a resource that will be deleted when
256*4882a593Smuzhiyun * the client goes away
257*4882a593Smuzhiyun */
258*4882a593Smuzhiyun clientResource = FakeClientID(client->index);
259*4882a593Smuzhiyun pNewEvent->clientResource = clientResource;
260*4882a593Smuzhiyun if (!AddResource(clientResource, ClientType, (void *)pNewEvent))
261*4882a593Smuzhiyun return BadAlloc;
262*4882a593Smuzhiyun /*
263*4882a593Smuzhiyun * create a resource to contain a pointer to the list
264*4882a593Smuzhiyun * of clients selecting input. This must be indirect as
265*4882a593Smuzhiyun * the list may be arbitrarily rearranged which cannot be
266*4882a593Smuzhiyun * done through the resource database.
267*4882a593Smuzhiyun */
268*4882a593Smuzhiyun if (i != Success || !pHead) {
269*4882a593Smuzhiyun pHead = (WMEventPtr *)malloc(sizeof(WMEventPtr));
270*4882a593Smuzhiyun if (!pHead ||
271*4882a593Smuzhiyun !AddResource(eventResource, EventType, (void *)pHead)) {
272*4882a593Smuzhiyun FreeResource(clientResource, RT_NONE);
273*4882a593Smuzhiyun return BadAlloc;
274*4882a593Smuzhiyun }
275*4882a593Smuzhiyun *pHead = 0;
276*4882a593Smuzhiyun }
277*4882a593Smuzhiyun pNewEvent->next = *pHead;
278*4882a593Smuzhiyun *pHead = pNewEvent;
279*4882a593Smuzhiyun updateEventMask(pHead);
280*4882a593Smuzhiyun }
281*4882a593Smuzhiyun else if (stuff->mask == 0) {
282*4882a593Smuzhiyun /* delete the interest */
283*4882a593Smuzhiyun if (i == Success && pHead) {
284*4882a593Smuzhiyun pNewEvent = 0;
285*4882a593Smuzhiyun for (pEvent = *pHead; pEvent; pEvent = pEvent->next) {
286*4882a593Smuzhiyun if (pEvent->client == client)
287*4882a593Smuzhiyun break;
288*4882a593Smuzhiyun pNewEvent = pEvent;
289*4882a593Smuzhiyun }
290*4882a593Smuzhiyun if (pEvent) {
291*4882a593Smuzhiyun FreeResource(pEvent->clientResource, ClientType);
292*4882a593Smuzhiyun if (pNewEvent)
293*4882a593Smuzhiyun pNewEvent->next = pEvent->next;
294*4882a593Smuzhiyun else
295*4882a593Smuzhiyun *pHead = pEvent->next;
296*4882a593Smuzhiyun free(pEvent);
297*4882a593Smuzhiyun updateEventMask(pHead);
298*4882a593Smuzhiyun }
299*4882a593Smuzhiyun }
300*4882a593Smuzhiyun }
301*4882a593Smuzhiyun else {
302*4882a593Smuzhiyun client->errorValue = stuff->mask;
303*4882a593Smuzhiyun return BadValue;
304*4882a593Smuzhiyun }
305*4882a593Smuzhiyun return Success;
306*4882a593Smuzhiyun }
307*4882a593Smuzhiyun
308*4882a593Smuzhiyun /*
309*4882a593Smuzhiyun * deliver the event
310*4882a593Smuzhiyun */
311*4882a593Smuzhiyun
312*4882a593Smuzhiyun void
AppleWMSendEvent(int type,unsigned int mask,int which,int arg)313*4882a593Smuzhiyun AppleWMSendEvent(int type, unsigned int mask, int which, int arg)
314*4882a593Smuzhiyun {
315*4882a593Smuzhiyun WMEventPtr *pHead, pEvent;
316*4882a593Smuzhiyun xAppleWMNotifyEvent se;
317*4882a593Smuzhiyun int i;
318*4882a593Smuzhiyun
319*4882a593Smuzhiyun i =
320*4882a593Smuzhiyun dixLookupResourceByType((void **)&pHead, eventResource, EventType,
321*4882a593Smuzhiyun serverClient,
322*4882a593Smuzhiyun DixReadAccess);
323*4882a593Smuzhiyun if (i != Success || !pHead)
324*4882a593Smuzhiyun return;
325*4882a593Smuzhiyun for (pEvent = *pHead; pEvent; pEvent = pEvent->next) {
326*4882a593Smuzhiyun if ((pEvent->mask & mask) == 0)
327*4882a593Smuzhiyun continue;
328*4882a593Smuzhiyun se.type = type + WMEventBase;
329*4882a593Smuzhiyun se.kind = which;
330*4882a593Smuzhiyun se.arg = arg;
331*4882a593Smuzhiyun se.time = currentTime.milliseconds;
332*4882a593Smuzhiyun WriteEventsToClient(pEvent->client, 1, (xEvent *)&se);
333*4882a593Smuzhiyun }
334*4882a593Smuzhiyun }
335*4882a593Smuzhiyun
336*4882a593Smuzhiyun /* Safe to call from any thread. */
337*4882a593Smuzhiyun unsigned int
AppleWMSelectedEvents(void)338*4882a593Smuzhiyun AppleWMSelectedEvents(void)
339*4882a593Smuzhiyun {
340*4882a593Smuzhiyun return eventMask;
341*4882a593Smuzhiyun }
342*4882a593Smuzhiyun
343*4882a593Smuzhiyun /* general utility functions */
344*4882a593Smuzhiyun
345*4882a593Smuzhiyun static int
ProcAppleWMDisableUpdate(register ClientPtr client)346*4882a593Smuzhiyun ProcAppleWMDisableUpdate(register ClientPtr client)
347*4882a593Smuzhiyun {
348*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xAppleWMDisableUpdateReq);
349*4882a593Smuzhiyun
350*4882a593Smuzhiyun appleWMProcs->DisableUpdate();
351*4882a593Smuzhiyun
352*4882a593Smuzhiyun return Success;
353*4882a593Smuzhiyun }
354*4882a593Smuzhiyun
355*4882a593Smuzhiyun static int
ProcAppleWMReenableUpdate(register ClientPtr client)356*4882a593Smuzhiyun ProcAppleWMReenableUpdate(register ClientPtr client)
357*4882a593Smuzhiyun {
358*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xAppleWMReenableUpdateReq);
359*4882a593Smuzhiyun
360*4882a593Smuzhiyun appleWMProcs->EnableUpdate();
361*4882a593Smuzhiyun
362*4882a593Smuzhiyun return Success;
363*4882a593Smuzhiyun }
364*4882a593Smuzhiyun
365*4882a593Smuzhiyun /* window functions */
366*4882a593Smuzhiyun
367*4882a593Smuzhiyun static int
ProcAppleWMSetWindowMenu(register ClientPtr client)368*4882a593Smuzhiyun ProcAppleWMSetWindowMenu(register ClientPtr client)
369*4882a593Smuzhiyun {
370*4882a593Smuzhiyun const char *bytes, **items;
371*4882a593Smuzhiyun char *shortcuts;
372*4882a593Smuzhiyun int max_len, nitems, i, j;
373*4882a593Smuzhiyun REQUEST(xAppleWMSetWindowMenuReq);
374*4882a593Smuzhiyun
375*4882a593Smuzhiyun REQUEST_AT_LEAST_SIZE(xAppleWMSetWindowMenuReq);
376*4882a593Smuzhiyun
377*4882a593Smuzhiyun nitems = stuff->nitems;
378*4882a593Smuzhiyun items = malloc(sizeof(char *) * nitems);
379*4882a593Smuzhiyun shortcuts = malloc(sizeof(char) * nitems);
380*4882a593Smuzhiyun
381*4882a593Smuzhiyun if (!items || !shortcuts) {
382*4882a593Smuzhiyun free(items);
383*4882a593Smuzhiyun free(shortcuts);
384*4882a593Smuzhiyun
385*4882a593Smuzhiyun return BadAlloc;
386*4882a593Smuzhiyun }
387*4882a593Smuzhiyun
388*4882a593Smuzhiyun max_len = (stuff->length << 2) - sizeof(xAppleWMSetWindowMenuReq);
389*4882a593Smuzhiyun bytes = (char *)&stuff[1];
390*4882a593Smuzhiyun
391*4882a593Smuzhiyun for (i = j = 0; i < max_len && j < nitems;) {
392*4882a593Smuzhiyun shortcuts[j] = bytes[i++];
393*4882a593Smuzhiyun items[j++] = bytes + i;
394*4882a593Smuzhiyun
395*4882a593Smuzhiyun while (i < max_len)
396*4882a593Smuzhiyun {
397*4882a593Smuzhiyun if (bytes[i++] == 0)
398*4882a593Smuzhiyun break;
399*4882a593Smuzhiyun }
400*4882a593Smuzhiyun }
401*4882a593Smuzhiyun
402*4882a593Smuzhiyun /* Check if we bailed out of the above loop due to a request that was too long */
403*4882a593Smuzhiyun if (j < nitems) {
404*4882a593Smuzhiyun free(items);
405*4882a593Smuzhiyun free(shortcuts);
406*4882a593Smuzhiyun
407*4882a593Smuzhiyun return BadRequest;
408*4882a593Smuzhiyun }
409*4882a593Smuzhiyun
410*4882a593Smuzhiyun X11ApplicationSetWindowMenu(nitems, items, shortcuts);
411*4882a593Smuzhiyun free(items);
412*4882a593Smuzhiyun free(shortcuts);
413*4882a593Smuzhiyun
414*4882a593Smuzhiyun return Success;
415*4882a593Smuzhiyun }
416*4882a593Smuzhiyun
417*4882a593Smuzhiyun static int
ProcAppleWMSetWindowMenuCheck(register ClientPtr client)418*4882a593Smuzhiyun ProcAppleWMSetWindowMenuCheck(register ClientPtr client)
419*4882a593Smuzhiyun {
420*4882a593Smuzhiyun REQUEST(xAppleWMSetWindowMenuCheckReq);
421*4882a593Smuzhiyun
422*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xAppleWMSetWindowMenuCheckReq);
423*4882a593Smuzhiyun X11ApplicationSetWindowMenuCheck(stuff->index);
424*4882a593Smuzhiyun return Success;
425*4882a593Smuzhiyun }
426*4882a593Smuzhiyun
427*4882a593Smuzhiyun static int
ProcAppleWMSetFrontProcess(register ClientPtr client)428*4882a593Smuzhiyun ProcAppleWMSetFrontProcess(register ClientPtr client)
429*4882a593Smuzhiyun {
430*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xAppleWMSetFrontProcessReq);
431*4882a593Smuzhiyun
432*4882a593Smuzhiyun X11ApplicationSetFrontProcess();
433*4882a593Smuzhiyun return Success;
434*4882a593Smuzhiyun }
435*4882a593Smuzhiyun
436*4882a593Smuzhiyun static int
ProcAppleWMSetWindowLevel(register ClientPtr client)437*4882a593Smuzhiyun ProcAppleWMSetWindowLevel(register ClientPtr client)
438*4882a593Smuzhiyun {
439*4882a593Smuzhiyun REQUEST(xAppleWMSetWindowLevelReq);
440*4882a593Smuzhiyun WindowPtr pWin;
441*4882a593Smuzhiyun int err;
442*4882a593Smuzhiyun
443*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xAppleWMSetWindowLevelReq);
444*4882a593Smuzhiyun
445*4882a593Smuzhiyun if (Success != dixLookupWindow(&pWin, stuff->window, client,
446*4882a593Smuzhiyun DixReadAccess))
447*4882a593Smuzhiyun return BadValue;
448*4882a593Smuzhiyun
449*4882a593Smuzhiyun if (stuff->level >= AppleWMNumWindowLevels) {
450*4882a593Smuzhiyun return BadValue;
451*4882a593Smuzhiyun }
452*4882a593Smuzhiyun
453*4882a593Smuzhiyun err = appleWMProcs->SetWindowLevel(pWin, stuff->level);
454*4882a593Smuzhiyun if (err != Success) {
455*4882a593Smuzhiyun return err;
456*4882a593Smuzhiyun }
457*4882a593Smuzhiyun
458*4882a593Smuzhiyun return Success;
459*4882a593Smuzhiyun }
460*4882a593Smuzhiyun
461*4882a593Smuzhiyun static int
ProcAppleWMSendPSN(register ClientPtr client)462*4882a593Smuzhiyun ProcAppleWMSendPSN(register ClientPtr client)
463*4882a593Smuzhiyun {
464*4882a593Smuzhiyun REQUEST(xAppleWMSendPSNReq);
465*4882a593Smuzhiyun int err;
466*4882a593Smuzhiyun
467*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xAppleWMSendPSNReq);
468*4882a593Smuzhiyun
469*4882a593Smuzhiyun if (!appleWMProcs->SendPSN)
470*4882a593Smuzhiyun return BadRequest;
471*4882a593Smuzhiyun
472*4882a593Smuzhiyun err = appleWMProcs->SendPSN(stuff->psn_hi, stuff->psn_lo);
473*4882a593Smuzhiyun if (err != Success) {
474*4882a593Smuzhiyun return err;
475*4882a593Smuzhiyun }
476*4882a593Smuzhiyun
477*4882a593Smuzhiyun return Success;
478*4882a593Smuzhiyun }
479*4882a593Smuzhiyun
480*4882a593Smuzhiyun static int
ProcAppleWMAttachTransient(register ClientPtr client)481*4882a593Smuzhiyun ProcAppleWMAttachTransient(register ClientPtr client)
482*4882a593Smuzhiyun {
483*4882a593Smuzhiyun WindowPtr pWinChild, pWinParent;
484*4882a593Smuzhiyun REQUEST(xAppleWMAttachTransientReq);
485*4882a593Smuzhiyun int err;
486*4882a593Smuzhiyun
487*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xAppleWMAttachTransientReq);
488*4882a593Smuzhiyun
489*4882a593Smuzhiyun if (!appleWMProcs->AttachTransient)
490*4882a593Smuzhiyun return BadRequest;
491*4882a593Smuzhiyun
492*4882a593Smuzhiyun if (Success !=
493*4882a593Smuzhiyun dixLookupWindow(&pWinChild, stuff->child, client, DixReadAccess))
494*4882a593Smuzhiyun return BadValue;
495*4882a593Smuzhiyun
496*4882a593Smuzhiyun if (stuff->parent) {
497*4882a593Smuzhiyun if (Success !=
498*4882a593Smuzhiyun dixLookupWindow(&pWinParent, stuff->parent, client, DixReadAccess))
499*4882a593Smuzhiyun return BadValue;
500*4882a593Smuzhiyun }
501*4882a593Smuzhiyun else {
502*4882a593Smuzhiyun pWinParent = NULL;
503*4882a593Smuzhiyun }
504*4882a593Smuzhiyun
505*4882a593Smuzhiyun err = appleWMProcs->AttachTransient(pWinChild, pWinParent);
506*4882a593Smuzhiyun if (err != Success) {
507*4882a593Smuzhiyun return err;
508*4882a593Smuzhiyun }
509*4882a593Smuzhiyun
510*4882a593Smuzhiyun return Success;
511*4882a593Smuzhiyun }
512*4882a593Smuzhiyun
513*4882a593Smuzhiyun static int
ProcAppleWMSetCanQuit(register ClientPtr client)514*4882a593Smuzhiyun ProcAppleWMSetCanQuit(register ClientPtr client)
515*4882a593Smuzhiyun {
516*4882a593Smuzhiyun REQUEST(xAppleWMSetCanQuitReq);
517*4882a593Smuzhiyun
518*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xAppleWMSetCanQuitReq);
519*4882a593Smuzhiyun
520*4882a593Smuzhiyun X11ApplicationSetCanQuit(stuff->state);
521*4882a593Smuzhiyun return Success;
522*4882a593Smuzhiyun }
523*4882a593Smuzhiyun
524*4882a593Smuzhiyun /* frame functions */
525*4882a593Smuzhiyun
526*4882a593Smuzhiyun static int
ProcAppleWMFrameGetRect(register ClientPtr client)527*4882a593Smuzhiyun ProcAppleWMFrameGetRect(register ClientPtr client)
528*4882a593Smuzhiyun {
529*4882a593Smuzhiyun xAppleWMFrameGetRectReply rep;
530*4882a593Smuzhiyun BoxRec ir, or, rr;
531*4882a593Smuzhiyun REQUEST(xAppleWMFrameGetRectReq);
532*4882a593Smuzhiyun
533*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xAppleWMFrameGetRectReq);
534*4882a593Smuzhiyun rep.type = X_Reply;
535*4882a593Smuzhiyun rep.length = 0;
536*4882a593Smuzhiyun rep.sequenceNumber = client->sequence;
537*4882a593Smuzhiyun
538*4882a593Smuzhiyun ir = make_box(stuff->ix, stuff->iy, stuff->iw, stuff->ih);
539*4882a593Smuzhiyun or = make_box(stuff->ox, stuff->oy, stuff->ow, stuff->oh);
540*4882a593Smuzhiyun
541*4882a593Smuzhiyun if (appleWMProcs->FrameGetRect(stuff->frame_rect,
542*4882a593Smuzhiyun stuff->frame_class,
543*4882a593Smuzhiyun &or, &ir, &rr) != Success) {
544*4882a593Smuzhiyun return BadValue;
545*4882a593Smuzhiyun }
546*4882a593Smuzhiyun
547*4882a593Smuzhiyun rep.x = rr.x1;
548*4882a593Smuzhiyun rep.y = rr.y1;
549*4882a593Smuzhiyun rep.w = rr.x2 - rr.x1;
550*4882a593Smuzhiyun rep.h = rr.y2 - rr.y1;
551*4882a593Smuzhiyun
552*4882a593Smuzhiyun WriteToClient(client, sizeof(xAppleWMFrameGetRectReply),&rep);
553*4882a593Smuzhiyun return Success;
554*4882a593Smuzhiyun }
555*4882a593Smuzhiyun
556*4882a593Smuzhiyun static int
ProcAppleWMFrameHitTest(register ClientPtr client)557*4882a593Smuzhiyun ProcAppleWMFrameHitTest(register ClientPtr client)
558*4882a593Smuzhiyun {
559*4882a593Smuzhiyun xAppleWMFrameHitTestReply rep;
560*4882a593Smuzhiyun BoxRec ir, or;
561*4882a593Smuzhiyun int ret;
562*4882a593Smuzhiyun REQUEST(xAppleWMFrameHitTestReq);
563*4882a593Smuzhiyun
564*4882a593Smuzhiyun REQUEST_SIZE_MATCH(xAppleWMFrameHitTestReq);
565*4882a593Smuzhiyun rep.type = X_Reply;
566*4882a593Smuzhiyun rep.length = 0;
567*4882a593Smuzhiyun rep.sequenceNumber = client->sequence;
568*4882a593Smuzhiyun
569*4882a593Smuzhiyun ir = make_box(stuff->ix, stuff->iy, stuff->iw, stuff->ih);
570*4882a593Smuzhiyun or = make_box(stuff->ox, stuff->oy, stuff->ow, stuff->oh);
571*4882a593Smuzhiyun
572*4882a593Smuzhiyun if (appleWMProcs->FrameHitTest(stuff->frame_class, stuff->px,
573*4882a593Smuzhiyun stuff->py, &or, &ir, &ret) != Success) {
574*4882a593Smuzhiyun return BadValue;
575*4882a593Smuzhiyun }
576*4882a593Smuzhiyun
577*4882a593Smuzhiyun rep.ret = ret;
578*4882a593Smuzhiyun
579*4882a593Smuzhiyun WriteToClient(client, sizeof(xAppleWMFrameHitTestReply),&rep);
580*4882a593Smuzhiyun return Success;
581*4882a593Smuzhiyun }
582*4882a593Smuzhiyun
583*4882a593Smuzhiyun static int
ProcAppleWMFrameDraw(register ClientPtr client)584*4882a593Smuzhiyun ProcAppleWMFrameDraw(register ClientPtr client)
585*4882a593Smuzhiyun {
586*4882a593Smuzhiyun BoxRec ir, or;
587*4882a593Smuzhiyun unsigned int title_length, title_max;
588*4882a593Smuzhiyun unsigned char *title_bytes;
589*4882a593Smuzhiyun REQUEST(xAppleWMFrameDrawReq);
590*4882a593Smuzhiyun WindowPtr pWin;
591*4882a593Smuzhiyun
592*4882a593Smuzhiyun REQUEST_AT_LEAST_SIZE(xAppleWMFrameDrawReq);
593*4882a593Smuzhiyun
594*4882a593Smuzhiyun if (Success != dixLookupWindow(&pWin, stuff->window, client,
595*4882a593Smuzhiyun DixReadAccess))
596*4882a593Smuzhiyun return BadValue;
597*4882a593Smuzhiyun
598*4882a593Smuzhiyun ir = make_box(stuff->ix, stuff->iy, stuff->iw, stuff->ih);
599*4882a593Smuzhiyun or = make_box(stuff->ox, stuff->oy, stuff->ow, stuff->oh);
600*4882a593Smuzhiyun
601*4882a593Smuzhiyun title_length = stuff->title_length;
602*4882a593Smuzhiyun title_max = (stuff->length << 2) - sizeof(xAppleWMFrameDrawReq);
603*4882a593Smuzhiyun
604*4882a593Smuzhiyun if (title_max < title_length)
605*4882a593Smuzhiyun return BadValue;
606*4882a593Smuzhiyun
607*4882a593Smuzhiyun title_bytes = (unsigned char *)&stuff[1];
608*4882a593Smuzhiyun
609*4882a593Smuzhiyun errno = appleWMProcs->FrameDraw(pWin, stuff->frame_class,
610*4882a593Smuzhiyun stuff->frame_attr, &or, &ir,
611*4882a593Smuzhiyun title_length, title_bytes);
612*4882a593Smuzhiyun if (errno != Success) {
613*4882a593Smuzhiyun return errno;
614*4882a593Smuzhiyun }
615*4882a593Smuzhiyun
616*4882a593Smuzhiyun return Success;
617*4882a593Smuzhiyun }
618*4882a593Smuzhiyun
619*4882a593Smuzhiyun /* dispatch */
620*4882a593Smuzhiyun
621*4882a593Smuzhiyun static int
ProcAppleWMDispatch(register ClientPtr client)622*4882a593Smuzhiyun ProcAppleWMDispatch(register ClientPtr client)
623*4882a593Smuzhiyun {
624*4882a593Smuzhiyun REQUEST(xReq);
625*4882a593Smuzhiyun
626*4882a593Smuzhiyun switch (stuff->data) {
627*4882a593Smuzhiyun case X_AppleWMQueryVersion:
628*4882a593Smuzhiyun return ProcAppleWMQueryVersion(client);
629*4882a593Smuzhiyun }
630*4882a593Smuzhiyun
631*4882a593Smuzhiyun if (!client->local)
632*4882a593Smuzhiyun return WMErrorBase + AppleWMClientNotLocal;
633*4882a593Smuzhiyun
634*4882a593Smuzhiyun switch (stuff->data) {
635*4882a593Smuzhiyun case X_AppleWMSelectInput:
636*4882a593Smuzhiyun return ProcAppleWMSelectInput(client);
637*4882a593Smuzhiyun
638*4882a593Smuzhiyun case X_AppleWMDisableUpdate:
639*4882a593Smuzhiyun return ProcAppleWMDisableUpdate(client);
640*4882a593Smuzhiyun
641*4882a593Smuzhiyun case X_AppleWMReenableUpdate:
642*4882a593Smuzhiyun return ProcAppleWMReenableUpdate(client);
643*4882a593Smuzhiyun
644*4882a593Smuzhiyun case X_AppleWMSetWindowMenu:
645*4882a593Smuzhiyun return ProcAppleWMSetWindowMenu(client);
646*4882a593Smuzhiyun
647*4882a593Smuzhiyun case X_AppleWMSetWindowMenuCheck:
648*4882a593Smuzhiyun return ProcAppleWMSetWindowMenuCheck(client);
649*4882a593Smuzhiyun
650*4882a593Smuzhiyun case X_AppleWMSetFrontProcess:
651*4882a593Smuzhiyun return ProcAppleWMSetFrontProcess(client);
652*4882a593Smuzhiyun
653*4882a593Smuzhiyun case X_AppleWMSetWindowLevel:
654*4882a593Smuzhiyun return ProcAppleWMSetWindowLevel(client);
655*4882a593Smuzhiyun
656*4882a593Smuzhiyun case X_AppleWMSetCanQuit:
657*4882a593Smuzhiyun return ProcAppleWMSetCanQuit(client);
658*4882a593Smuzhiyun
659*4882a593Smuzhiyun case X_AppleWMFrameGetRect:
660*4882a593Smuzhiyun return ProcAppleWMFrameGetRect(client);
661*4882a593Smuzhiyun
662*4882a593Smuzhiyun case X_AppleWMFrameHitTest:
663*4882a593Smuzhiyun return ProcAppleWMFrameHitTest(client);
664*4882a593Smuzhiyun
665*4882a593Smuzhiyun case X_AppleWMFrameDraw:
666*4882a593Smuzhiyun return ProcAppleWMFrameDraw(client);
667*4882a593Smuzhiyun
668*4882a593Smuzhiyun case X_AppleWMSendPSN:
669*4882a593Smuzhiyun return ProcAppleWMSendPSN(client);
670*4882a593Smuzhiyun
671*4882a593Smuzhiyun case X_AppleWMAttachTransient:
672*4882a593Smuzhiyun return ProcAppleWMAttachTransient(client);
673*4882a593Smuzhiyun
674*4882a593Smuzhiyun default:
675*4882a593Smuzhiyun return BadRequest;
676*4882a593Smuzhiyun }
677*4882a593Smuzhiyun }
678*4882a593Smuzhiyun
679*4882a593Smuzhiyun static void
SNotifyEvent(xAppleWMNotifyEvent * from,xAppleWMNotifyEvent * to)680*4882a593Smuzhiyun SNotifyEvent(xAppleWMNotifyEvent *from, xAppleWMNotifyEvent *to)
681*4882a593Smuzhiyun {
682*4882a593Smuzhiyun to->type = from->type;
683*4882a593Smuzhiyun to->kind = from->kind;
684*4882a593Smuzhiyun cpswaps(from->sequenceNumber, to->sequenceNumber);
685*4882a593Smuzhiyun cpswapl(from->time, to->time);
686*4882a593Smuzhiyun cpswapl(from->arg, to->arg);
687*4882a593Smuzhiyun }
688*4882a593Smuzhiyun
689*4882a593Smuzhiyun static int
SProcAppleWMQueryVersion(register ClientPtr client)690*4882a593Smuzhiyun SProcAppleWMQueryVersion(register ClientPtr client)
691*4882a593Smuzhiyun {
692*4882a593Smuzhiyun REQUEST(xAppleWMQueryVersionReq);
693*4882a593Smuzhiyun swaps(&stuff->length);
694*4882a593Smuzhiyun return ProcAppleWMQueryVersion(client);
695*4882a593Smuzhiyun }
696*4882a593Smuzhiyun
697*4882a593Smuzhiyun static int
SProcAppleWMDispatch(register ClientPtr client)698*4882a593Smuzhiyun SProcAppleWMDispatch(register ClientPtr client)
699*4882a593Smuzhiyun {
700*4882a593Smuzhiyun REQUEST(xReq);
701*4882a593Smuzhiyun
702*4882a593Smuzhiyun /* It is bound to be non-local when there is byte swapping */
703*4882a593Smuzhiyun if (!client->local)
704*4882a593Smuzhiyun return WMErrorBase + AppleWMClientNotLocal;
705*4882a593Smuzhiyun
706*4882a593Smuzhiyun /* only local clients are allowed WM access */
707*4882a593Smuzhiyun switch (stuff->data) {
708*4882a593Smuzhiyun case X_AppleWMQueryVersion:
709*4882a593Smuzhiyun return SProcAppleWMQueryVersion(client);
710*4882a593Smuzhiyun
711*4882a593Smuzhiyun default:
712*4882a593Smuzhiyun return BadRequest;
713*4882a593Smuzhiyun }
714*4882a593Smuzhiyun }
715*4882a593Smuzhiyun
716*4882a593Smuzhiyun void
AppleWMExtensionInit(AppleWMProcsPtr procsPtr)717*4882a593Smuzhiyun AppleWMExtensionInit(AppleWMProcsPtr procsPtr)
718*4882a593Smuzhiyun {
719*4882a593Smuzhiyun ExtensionEntry* extEntry;
720*4882a593Smuzhiyun
721*4882a593Smuzhiyun ClientType = CreateNewResourceType(WMFreeClient, "WMClient");
722*4882a593Smuzhiyun EventType = CreateNewResourceType(WMFreeEvents, "WMEvent");
723*4882a593Smuzhiyun eventResource = FakeClientID(0);
724*4882a593Smuzhiyun
725*4882a593Smuzhiyun if (ClientType && EventType &&
726*4882a593Smuzhiyun (extEntry = AddExtension(APPLEWMNAME,
727*4882a593Smuzhiyun AppleWMNumberEvents,
728*4882a593Smuzhiyun AppleWMNumberErrors,
729*4882a593Smuzhiyun ProcAppleWMDispatch,
730*4882a593Smuzhiyun SProcAppleWMDispatch,
731*4882a593Smuzhiyun NULL,
732*4882a593Smuzhiyun StandardMinorOpcode))) {
733*4882a593Smuzhiyun size_t i;
734*4882a593Smuzhiyun WMReqCode = (unsigned char)extEntry->base;
735*4882a593Smuzhiyun WMErrorBase = extEntry->errorBase;
736*4882a593Smuzhiyun WMEventBase = extEntry->eventBase;
737*4882a593Smuzhiyun for (i = 0; i < AppleWMNumberEvents; i++)
738*4882a593Smuzhiyun EventSwapVector[WMEventBase + i] = (EventSwapPtr)SNotifyEvent;
739*4882a593Smuzhiyun appleWMProcs = procsPtr;
740*4882a593Smuzhiyun }
741*4882a593Smuzhiyun }
742