xserver

xserver with xephyr scale patch
git clone https://git.neptards.moe/u3shit/xserver.git
Log | Files | Refs | README | LICENSE

applewm.c (19658B)


      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 "quartz.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 }