"Fossies" - the Fresh Open Source Software Archive

Member "xorg-server-1.20.5/hw/xquartz/applewm.c" (30 May 2019, 19664 Bytes) of package /linux/misc/xorg-server-1.20.5.tar.bz2:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) C and C++ source code syntax highlighting (style: standard) with prefixed line numbers and code folding option. Alternatively you can here view or download the uninterpreted source code file. For more information about "applewm.c" see the Fossies "Dox" file reference documentation.

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