1 /* $XFree86: xc/programs/Xserver/GL/dri/xf86dri.c,v 1.10 2000/12/07 20:26:14 dawes Exp $ */
2 /**************************************************************************
4 Copyright 1998-1999 Precision Insight, Inc., Cedar Park, Texas.
5 Copyright 2000 VA Linux Systems, Inc.
6 Copyright (c) 2002 Apple Computer, Inc.
9 Permission is hereby granted, free of charge, to any person obtaining a
10 copy of this software and associated documentation files (the
11 "Software"), to deal in the Software without restriction, including
12 without limitation the rights to use, copy, modify, merge, publish,
13 distribute, sub license, and/or sell copies of the Software, and to
14 permit persons to whom the Software is furnished to do so, subject to
15 the following conditions:
17 The above copyright notice and this permission notice (including the
18 next paragraph) shall be included in all copies or substantial portions
21 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
22 OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
23 MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT.
24 IN NO EVENT SHALL PRECISION INSIGHT AND/OR ITS SUPPLIERS BE LIABLE FOR
25 ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
26 TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
27 SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 **************************************************************************/
36 #include "dixstruct.h"
37 #include "extnsionst.h"
38 #include "colormapst.h"
39 #include "cursorstr.h"
40 #include "scrnintstr.h"
42 #define _APPLEWM_SERVER_
43 #include "applewmstr.h"
45 #include "rootless-common.h"
46 #include "X11Application.h"
48 static int WMErrorBase;
50 static DISPATCH_PROC(ProcAppleWMDispatch);
51 static DISPATCH_PROC(SProcAppleWMDispatch);
53 static void AppleWMResetProc(ExtensionEntry* extEntry);
55 static unsigned char WMReqCode = 0;
56 static int WMEventBase = 0;
58 static RESTYPE ClientType, EventType; /* resource types for event masks */
59 static XID eventResource;
61 /* Currently selected events */
62 static unsigned int eventMask = 0;
64 extern void AppleWMExtensionInit(void);
66 static int WMFreeClient (pointer data, XID id);
67 static int WMFreeEvents (pointer data, XID id);
68 static void SNotifyEvent(xAppleWMNotifyEvent *from, xAppleWMNotifyEvent *to);
70 typedef struct _WMEvent *WMEventPtr;
71 typedef struct _WMEvent {
79 make_box (int x, int y, int w, int h)
90 AppleWMExtensionInit(void)
92 ExtensionEntry* extEntry;
94 ClientType = CreateNewResourceType(WMFreeClient);
95 EventType = CreateNewResourceType(WMFreeEvents);
96 eventResource = FakeClientID(0);
98 if (ClientType && EventType &&
99 (extEntry = AddExtension(APPLEWMNAME,
103 SProcAppleWMDispatch,
105 StandardMinorOpcode))) {
106 WMReqCode = (unsigned char)extEntry->base;
107 WMErrorBase = extEntry->errorBase;
108 WMEventBase = extEntry->eventBase;
109 EventSwapVector[WMEventBase] = (EventSwapPtr) SNotifyEvent;
116 ExtensionEntry* extEntry
122 ProcAppleWMQueryVersion(
123 register ClientPtr client
126 xAppleWMQueryVersionReply rep;
129 REQUEST_SIZE_MATCH(xAppleWMQueryVersionReq);
132 rep.sequenceNumber = client->sequence;
133 rep.majorVersion = APPLE_WM_MAJOR_VERSION;
134 rep.minorVersion = APPLE_WM_MINOR_VERSION;
135 rep.patchVersion = APPLE_WM_PATCH_VERSION;
136 if (client->swapped) {
137 swaps(&rep.sequenceNumber, n);
138 swapl(&rep.length, n);
140 WriteToClient(client, sizeof(xAppleWMQueryVersionReply), (char *)&rep);
141 return (client->noClientException);
148 updateEventMask (WMEventPtr *pHead)
153 for (pCur = *pHead; pCur != NULL; pCur = pCur->next)
154 eventMask |= pCur->mask;
159 WMFreeClient (data, id)
164 WMEventPtr *pHead, pCur, pPrev;
166 pEvent = (WMEventPtr) data;
167 pHead = (WMEventPtr *) LookupIDByType(eventResource, EventType);
170 for (pCur = *pHead; pCur && pCur != pEvent; pCur=pCur->next)
175 pPrev->next = pEvent->next;
177 *pHead = pEvent->next;
179 updateEventMask (pHead);
181 xfree ((pointer) pEvent);
187 WMFreeEvents (data, id)
191 WMEventPtr *pHead, pCur, pNext;
193 pHead = (WMEventPtr *) data;
194 for (pCur = *pHead; pCur; pCur = pNext) {
196 FreeResource (pCur->clientResource, ClientType);
197 xfree ((pointer) pCur);
199 xfree ((pointer) pHead);
205 ProcAppleWMSelectInput (client)
206 register ClientPtr client;
208 REQUEST(xAppleWMSelectInputReq);
209 WMEventPtr pEvent, pNewEvent, *pHead;
212 REQUEST_SIZE_MATCH (xAppleWMSelectInputReq);
213 pHead = (WMEventPtr *)SecurityLookupIDByType(client,
214 eventResource, EventType, SecurityWriteAccess);
215 if (stuff->mask != 0) {
217 /* check for existing entry. */
218 for (pEvent = *pHead; pEvent; pEvent = pEvent->next)
220 if (pEvent->client == client)
222 pEvent->mask = stuff->mask;
223 updateEventMask (pHead);
229 /* build the entry */
230 pNewEvent = (WMEventPtr) xalloc (sizeof (WMEventRec));
234 pNewEvent->client = client;
235 pNewEvent->mask = stuff->mask;
237 * add a resource that will be deleted when
238 * the client goes away
240 clientResource = FakeClientID (client->index);
241 pNewEvent->clientResource = clientResource;
242 if (!AddResource (clientResource, ClientType, (pointer)pNewEvent))
245 * create a resource to contain a pointer to the list
246 * of clients selecting input. This must be indirect as
247 * the list may be arbitrarily rearranged which cannot be
248 * done through the resource database.
252 pHead = (WMEventPtr *) xalloc (sizeof (WMEventPtr));
254 !AddResource (eventResource, EventType, (pointer)pHead))
256 FreeResource (clientResource, RT_NONE);
261 pNewEvent->next = *pHead;
263 updateEventMask (pHead);
264 } else if (stuff->mask == 0) {
265 /* delete the interest */
268 for (pEvent = *pHead; pEvent; pEvent = pEvent->next) {
269 if (pEvent->client == client)
274 FreeResource (pEvent->clientResource, ClientType);
276 pNewEvent->next = pEvent->next;
278 *pHead = pEvent->next;
280 updateEventMask (pHead);
284 client->errorValue = stuff->mask;
295 AppleWMSendEvent (type, mask, which, arg)
296 int type, which, arg;
299 WMEventPtr *pHead, pEvent;
301 xAppleWMNotifyEvent se;
303 pHead = (WMEventPtr *) LookupIDByType(eventResource, EventType);
306 for (pEvent = *pHead; pEvent; pEvent = pEvent->next) {
307 client = pEvent->client;
308 if ((pEvent->mask & mask) == 0
309 || client == serverClient || client->clientGone)
313 se.type = type + WMEventBase;
316 se.sequenceNumber = client->sequence;
317 se.time = currentTime.milliseconds;
318 WriteEventsToClient (client, 1, (xEvent *) &se);
322 /* Safe to call from any thread. */
324 AppleWMSelectedEvents (void)
330 /* general utility functions */
333 ProcAppleWMDisableUpdate(
334 register ClientPtr client
337 REQUEST_SIZE_MATCH(xAppleWMDisableUpdateReq);
339 xp_disable_update ();
341 return (client->noClientException);
345 ProcAppleWMReenableUpdate(
346 register ClientPtr client
349 REQUEST_SIZE_MATCH(xAppleWMReenableUpdateReq);
351 xp_reenable_update ();
353 return (client->noClientException);
357 /* window functions */
360 ProcAppleWMSetWindowMenu(
361 register ClientPtr client
364 const char *bytes, **items;
366 int max_len, nitems, i, j;
367 REQUEST(xAppleWMSetWindowMenuReq);
369 REQUEST_AT_LEAST_SIZE(xAppleWMSetWindowMenuReq);
371 nitems = stuff->nitems;
372 items = alloca (sizeof (char *) * nitems);
373 shortcuts = alloca (sizeof (char) * nitems);
375 max_len = (stuff->length << 2) - sizeof(xAppleWMSetWindowMenuReq);
376 bytes = (char *) &stuff[1];
378 for (i = j = 0; i < max_len && j < nitems;)
380 shortcuts[j] = bytes[i++];
381 items[j++] = bytes + i;
390 X11ApplicationSetWindowMenu (nitems, items, shortcuts);
392 return (client->noClientException);
396 ProcAppleWMSetWindowMenuCheck(
397 register ClientPtr client
400 REQUEST(xAppleWMSetWindowMenuCheckReq);
402 REQUEST_SIZE_MATCH(xAppleWMSetWindowMenuCheckReq);
404 X11ApplicationSetWindowMenuCheck (stuff->index);
406 return (client->noClientException);
410 ProcAppleWMSetFrontProcess(
411 register ClientPtr client
414 REQUEST_SIZE_MATCH(xAppleWMSetFrontProcessReq);
416 X11ApplicationSetFrontProcess ();
418 return (client->noClientException);
422 ProcAppleWMSetWindowLevel(
423 register ClientPtr client
426 REQUEST(xAppleWMSetWindowLevelReq);
429 REQUEST_SIZE_MATCH(xAppleWMSetWindowLevelReq);
431 if (!(pWin = SecurityLookupWindow((Drawable)stuff->window,
432 client, SecurityReadAccess))) {
436 if (stuff->level < 0 || stuff->level >= AppleWMNumWindowLevels) {
440 RootlessSetWindowLevel (pWin, stuff->level);
442 return (client->noClientException);
446 ProcAppleWMSetCanQuit(
447 register ClientPtr client
450 REQUEST(xAppleWMSetCanQuitReq);
452 REQUEST_SIZE_MATCH(xAppleWMSetCanQuitReq);
454 X11ApplicationSetCanQuit (stuff->state);
456 return (client->noClientException);
460 /* frame functions */
463 ProcAppleWMFrameGetRect(
464 register ClientPtr client
467 xAppleWMFrameGetRectReply rep;
469 REQUEST(xAppleWMFrameGetRectReq);
471 REQUEST_SIZE_MATCH(xAppleWMFrameGetRectReq);
474 rep.sequenceNumber = client->sequence;
476 ir = make_box (stuff->ix, stuff->iy, stuff->iw, stuff->ih);
477 or = make_box (stuff->ox, stuff->oy, stuff->ow, stuff->oh);
479 if (xp_frame_get_rect (stuff->frame_rect,
481 &or, &ir, &rr) != Success) {
487 rep.w = rr.x2 - rr.x1;
488 rep.h = rr.y2 - rr.y1;
490 WriteToClient(client, sizeof(xAppleWMFrameGetRectReply), (char *)&rep);
491 return (client->noClientException);
495 ProcAppleWMFrameHitTest(
496 register ClientPtr client
499 xAppleWMFrameHitTestReply rep;
502 REQUEST(xAppleWMFrameHitTestReq);
504 REQUEST_SIZE_MATCH(xAppleWMFrameHitTestReq);
507 rep.sequenceNumber = client->sequence;
509 ir = make_box (stuff->ix, stuff->iy, stuff->iw, stuff->ih);
510 or = make_box (stuff->ox, stuff->oy, stuff->ow, stuff->oh);
512 if (xp_frame_hit_test (stuff->frame_class, stuff->px,
513 stuff->py, &or, &ir, &ret) != Success)
520 WriteToClient(client, sizeof(xAppleWMFrameHitTestReply), (char *)&rep);
521 return (client->noClientException);
525 ProcAppleWMFrameDraw(
526 register ClientPtr client
530 unsigned int title_length, title_max;
531 unsigned char *title_bytes;
532 REQUEST(xAppleWMFrameDrawReq);
536 REQUEST_AT_LEAST_SIZE(xAppleWMFrameDrawReq);
538 if (!(pWin = SecurityLookupWindow((Drawable)stuff->window,
539 client, SecurityReadAccess))) {
543 ir = make_box (stuff->ix, stuff->iy, stuff->iw, stuff->ih);
544 or = make_box (stuff->ox, stuff->oy, stuff->ow, stuff->oh);
546 title_length = stuff->title_length;
547 title_max = (stuff->length << 2) - sizeof(xAppleWMFrameDrawReq);
549 if (title_max < title_length)
552 title_bytes = (unsigned char *) &stuff[1];
554 wid = RootlessGetPhysicalWindow (pWin, FALSE);
558 if (xp_frame_draw (wid, stuff->frame_class,
559 stuff->frame_attr, &or, &ir,
560 title_length, title_bytes) != Success) {
564 return (client->noClientException);
571 ProcAppleWMDispatch (
572 register ClientPtr client
579 case X_AppleWMQueryVersion:
580 return ProcAppleWMQueryVersion(client);
583 if (!LocalClient(client))
584 return WMErrorBase + AppleWMClientNotLocal;
588 case X_AppleWMSelectInput:
589 return ProcAppleWMSelectInput(client);
590 case X_AppleWMDisableUpdate:
591 return ProcAppleWMDisableUpdate(client);
592 case X_AppleWMReenableUpdate:
593 return ProcAppleWMReenableUpdate(client);
594 case X_AppleWMSetWindowMenu:
595 return ProcAppleWMSetWindowMenu(client);
596 case X_AppleWMSetWindowMenuCheck:
597 return ProcAppleWMSetWindowMenuCheck(client);
598 case X_AppleWMSetFrontProcess:
599 return ProcAppleWMSetFrontProcess(client);
600 case X_AppleWMSetWindowLevel:
601 return ProcAppleWMSetWindowLevel(client);
602 case X_AppleWMSetCanQuit:
603 return ProcAppleWMSetCanQuit(client);
604 case X_AppleWMFrameGetRect:
605 return ProcAppleWMFrameGetRect(client);
606 case X_AppleWMFrameHitTest:
607 return ProcAppleWMFrameHitTest(client);
608 case X_AppleWMFrameDraw:
609 return ProcAppleWMFrameDraw(client);
616 SNotifyEvent(from, to)
617 xAppleWMNotifyEvent *from, *to;
619 to->type = from->type;
620 to->kind = from->kind;
621 cpswaps (from->sequenceNumber, to->sequenceNumber);
622 cpswapl (from->time, to->time);
623 cpswapl (from->arg, to->arg);
627 SProcAppleWMQueryVersion(
628 register ClientPtr client
632 REQUEST(xAppleWMQueryVersionReq);
633 swaps(&stuff->length, n);
634 return ProcAppleWMQueryVersion(client);
638 SProcAppleWMDispatch (
639 register ClientPtr client
644 /* It is bound to be non-local when there is byte swapping */
645 if (!LocalClient(client))
646 return WMErrorBase + AppleWMClientNotLocal;
648 /* only local clients are allowed WM access */
651 case X_AppleWMQueryVersion:
652 return SProcAppleWMQueryVersion(client);