/************************************************************ Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts, and the Massachusetts Institute of Technology, Cambridge, Massachusetts. All Rights Reserved Permission to use, copy, modify, and distribute this software and its documentation for any purpose and without fee is hereby granted, provided that the above copyright notice appear in all copies and that both that copyright notice and this permission notice appear in supporting documentation, and that the names of Digital or MIT not be used in advertising or publicity pertaining to distribution of the software without specific, written prior permission. DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ********************************************************/ #include "X.h" #define NEED←REPLIES #define NEED←EVENTS #include "Xproto.h" #include "Xprotostr.h" #include "windowstr.h" #include "fontstruct.h" #include "dixfontstr.h" #include "gcstruct.h" #include "osstruct.h" #include "resource.h" #include "selection.h" #include "colormapst.h" #include "dixstruct.h" #include "extension.h" #include "input.h" #include "cursorstr.h" #include "scrnintstr.h" #include "opaque.h" extern void ProcessInputEvents(); extern WindowRec WindowTable[]; extern xConnSetupPrefix connSetupPrefix; extern char *ConnectionInfo; extern char *SwappedConnInfo; extern void ValidateGC(); Selection *CurrentSelections = (Selection *)NULL; int NumCurrentSelections = 0; extern long ScreenSaverTime; extern long ScreenSaverInterval; extern int ScreenSaverBlanking; extern int ScreenSaverAllowExposures; ClientPtr onlyClient; Bool grabbingClient = FALSE; long *checkForInput[2]; extern Bool clientsDoomed; extern int (* ProcVector[256]) (); extern int (* SwappedProcVector[256]) (); extern void (* EventSwapVector[128]) (); extern void (* ReplySwapVector[256]) (); extern void KillAllClients(); /* buffers for clients. legal values below */ int nextFreeClientID=1; /* 0 is for the server */ int nClients = 0; /* number active clients */ #define SAME←SCREENS(a, b) (\ (a.pScreen == b.pScreen)) #define VALIDATE(pGC, pDraw, rt) {\ if (pGC->serialNumber != pDraw->serialNumber)\ {\ ValidateGC(pDraw, pGC);\ } \ } #define LEGAL←NEW←RESOURCE(id)\ if ((LookupID(id, RT←ANY, RC←CORE) != 0) || (id & SERVER←BIT) \ || (client->clientAsMask != CLIENT←BITS(id)))\ return(BadIDChoice) #define LOOKUP←DRAWABLE(did, client)\ ((client->lastDrawableID == did) ? \ (DrawablePtr)client->lastDrawable : (DrawablePtr)LookupDrawable(did, client)) #define VERIFY←GC(pGC, rid, client)\ if (client->lastGCID == rid)\ {\ pGC = (GC *) client->lastGC;\ }\ else\ {\ pGC = (GC *)LookupID(rid, RT←GC, RC←CORE);\ if (!pGC)\ {\ client->errorValue = rid;\ return (BadGC);\ }\ } #define VALIDATE←DRAWABLE←AND←GC(drawID, pDraw, pGC, client)\ if ((client->lastDrawableID != drawID) || (client->lastGCID != stuff->gc))\ {\ if (client->lastDrawableID != drawID)\ {\ pDraw = (DrawablePtr)LookupID(drawID, RT←DRAWABLE, RC←CORE);\ if (!pDraw)\ {\ client->errorValue = drawID; \ return (BadDrawable);\ }\ if ((pDraw->type == DRAWABLE←WINDOW) || \ (pDraw->type == DRAWABLE←PIXMAP))\ {\ client->lastDrawable = (pointer)pDraw;\ client->lastDrawableID = drawID;\ }\ else\ {\ client->errorValue = drawID;\ return (BadDrawable);\ }\ }\ else\ pDraw = (DrawablePtr)client->lastDrawable;\ if (client->lastGCID != stuff->gc)\ {\ pGC = (GC *)LookupID(stuff->gc, RT←GC, RC←CORE);\ if (!pGC)\ {\ client->errorValue = stuff->gc;\ return (BadGC);\ }\ client->lastGC = (pointer)pGC;\ client->lastGCID = stuff->gc;\ }\ else\ pGC = (GC *) client->lastGC;\ if ((pGC->depth != pDraw->depth) || (pGC->pScreen != pDraw->pScreen))\ {\ client->errorValue = stuff->gc;\ client->lastGCID = -1;\ return (BadMatch);\ }\ }\ else\ {\ pGC = (GC *) client->lastGC;\ pDraw = (DrawablePtr)client->lastDrawable;\ }\ if (pGC->serialNumber != pDraw->serialNumber)\ { \ ValidateGC(pDraw, pGC);\ } void SetInputCheck(c0, c1) long *c0, *c1; { checkForInput[0] = c0; checkForInput[1] = c1; } void InitSelections() { int i; if (NumCurrentSelections == 0) { CurrentSelections = (Selection *)Xalloc(5 * sizeof(Selection)); NumCurrentSelections = 5; } for (i = 0; i< NumCurrentSelections; i++) CurrentSelections[i].window = None; } void FlushClientCaches(id) long id; { int i; register ClientPtr client; for (i=0; i<currentMaxClients; i++) { if (client == clients[i]) { if (client->lastDrawableID == id) client->lastDrawableID = -1; else if (client->lastGCID == id) client->lastGCID = -1; } } } Dispatch() { ClientPtr *clientReady; /* mask of request ready clients */ ClientPtr *newClients; /* mask of new clients */ int result; int i; xReq *request = 0; int ErrorStatus; ClientPtr client; int nready, nnew; currentMaxClients = 10; clients = (ClientPtr *)Xalloc(currentMaxClients * sizeof(ClientPtr)); for (i=1; i<currentMaxClients; i++) clients[i] = NullClient; clients[0] = serverClient; nextFreeClientID = 1; InitSelections(); nClients = 0; clientsDoomed = FALSE; clientReady = (ClientPtr *) ALLOCATE←LOCAL((int)(sizeof(ClientPtr) * MaxClients)); newClients = (ClientPtr *)ALLOCATE←LOCAL((int)(sizeof(ClientPtr) * MaxClients)); while (1) { StartOver: if (*checkForInput[0] != *checkForInput[1]) ProcessInputEvents(); WaitForSomething(clientReady, &nready, newClients, &nnew); /***************** * Establish any new connections *****************/ while (nnew--) { client = newClients[nnew]; InitClientResources(client); SendConnectionSetupInfo(client); nClients++; } /***************** * Handle events in round robin fashion, doing input between * each round *****************/ while ((nready--) > 0) { client = clientReady[nready]; if (! client) { ErrorF( "HORRIBLE ERROR, unused client %d\n", nready); continue; } isItTimeToYield = FALSE; requestingClient = client; while (! isItTimeToYield) { if (*checkForInput[0] != *checkForInput[1]) ProcessInputEvents(); /* now, finally, deal with client requests */ request = (xReq *)ReadRequestFromClient( client, &result, (pointer)request); if (result < 0) { CloseDownClient(client); isItTimeToYield = TRUE; continue; } else if (result == 0) { ErrorF( "Blocked read in dispatcher\n"); ErrorF( "reqType %d %d\n", (request ? request->reqType : -1), nready); if (nready > 0) continue; else goto StartOver; } client->sequence++; client->requestBuffer = (pointer)request; ErrorStatus = (* (client->swapped ? SwappedProcVector : ProcVector)[request->reqType])(client); if (ErrorStatus != Success) { if (client->noClientException != Success) CloseDownClient(client); else Oops(client, (char)request->reqType, 0, ErrorStatus); isItTimeToYield = TRUE; continue; } } } /* Not an error, we just need to know to restart */ if((nClients == -1) || clientsDoomed) break; /* so that DEALLOCATE←LOCALs happen */ } if (clientsDoomed) KillAllClients(); DEALLOCATE←LOCAL(newClients); DEALLOCATE←LOCAL(clientReady); Xfree(clients); } int ProcBadRequest(client) ClientPtr client; { return (BadRequest); } extern int Ones(); int ProcCreateWindow(client) register ClientPtr client; { register WindowPtr pParent, pWin; REQUEST(xCreateWindowReq); int result; int len; REQUEST←AT←LEAST←SIZE(xCreateWindowReq); LEGAL←NEW←RESOURCE(stuff->wid); if (!(pParent = (WindowPtr)LookupWindow(stuff->parent, client))) return BadWindow; len = stuff->length - (sizeof(xCreateWindowReq) >> 2); if (Ones(stuff->mask) != len) return BadLength; if (!stuff->width || !stuff->height) return BadValue; pWin = CreateWindow(stuff->wid, pParent, stuff->x, stuff->y, stuff->width, stuff->height, stuff->borderWidth, stuff->class, stuff->mask, (long *) &stuff[1], stuff->depth, client, stuff->visual, &result); if (pWin) AddResource(stuff->wid, RT←WINDOW, (pointer)pWin, DeleteWindow, RC←CORE); if (client->noClientException != Success) return(client->noClientException); else return(result); } int ProcChangeWindowAttributes(client) register ClientPtr client; { register WindowPtr pWin; REQUEST(xChangeWindowAttributesReq); register int result; int len; REQUEST←AT←LEAST←SIZE(xChangeWindowAttributesReq); pWin = (WindowPtr)LookupWindow(stuff->window, client); if (!pWin) return(BadWindow); len = stuff->length - (sizeof(xChangeWindowAttributesReq) >> 2); if (len != Ones(stuff->valueMask)) return BadLength; client->lastDrawableID = -1; result = ChangeWindowAttributes(pWin, (unsigned long)stuff->valueMask, (long *) &stuff[1], client); if (client->noClientException != Success) return(client->noClientException); else return(result); } int ProcGetWindowAttributes(client) register ClientPtr client; { register WindowPtr pWin; REQUEST(xResourceReq); REQUEST←SIZE←MATCH(xResourceReq); pWin = (WindowPtr)LookupWindow(stuff->id, client); if (!pWin) return(BadWindow); GetWindowAttributes(pWin, client); return(client->noClientException); } int ProcDestroyWindow(client) register ClientPtr client; { register WindowPtr pWin; REQUEST(xResourceReq); REQUEST←SIZE←MATCH(xResourceReq); pWin = (WindowPtr)LookupWindow(stuff->id, client); if (!pWin) return(BadWindow); FreeResource(stuff->id, RC←NONE); return(client->noClientException); } int ProcDestroySubwindows(client) register ClientPtr client; { register WindowPtr pWin; REQUEST(xResourceReq); REQUEST←SIZE←MATCH(xResourceReq); pWin = (WindowPtr)LookupWindow(stuff->id, client); if (!pWin) return(BadWindow); DestroySubwindows(pWin, client); return(client->noClientException); } int ProcChangeSaveSet(client) register ClientPtr client; { register WindowPtr pWin; REQUEST(xChangeSaveSetReq); register result; REQUEST←SIZE←MATCH(xChangeSaveSetReq); pWin = (WindowPtr)LookupWindow(stuff->window, client); if (!pWin) return(BadWindow); if (client->clientAsMask == (CLIENT←ID(pWin->wid))) return BadMatch; if ((stuff->mode == SetModeInsert) || (stuff->mode == SetModeDelete)) { result = AlterSaveSetForClient(client, (pointer)pWin, (char)stuff->mode); if (client->noClientException != Success) return(client->noClientException); else return(result); } else return( BadValue ); } int ProcReparentWindow(client) register ClientPtr client; { register WindowPtr pWin, pParent; REQUEST(xReparentWindowReq); register int result; REQUEST←SIZE←MATCH(xReparentWindowReq); pWin = (WindowPtr)LookupWindow(stuff->window, client); if (!pWin) return(BadWindow); pParent = (WindowPtr)LookupWindow(stuff->parent, client); if (!pParent) return(BadWindow); if (SAME←SCREENS(pWin->drawable, pParent->drawable)) { if ((pWin->backgroundTile == (PixmapPtr)ParentRelative) && (pParent->drawable.depth != pWin->drawable.depth)) return BadMatch; result = ReparentWindow(pWin, pParent, (short)stuff->x, (short)stuff->y, client); if (client->noClientException != Success) return(client->noClientException); else return(result); } else return (BadMatch); } int ProcMapWindow(client) register ClientPtr client; { register WindowPtr pWin; REQUEST(xResourceReq); REQUEST←SIZE←MATCH(xResourceReq); pWin = (WindowPtr)LookupWindow(stuff->id, client); if (!pWin) return(BadWindow); MapWindow(pWin, HANDLE←EXPOSURES, BITS←DISCARDED, SEND←NOTIFICATION, client); /* update cache to say it is mapped */ return(client->noClientException); } int ProcMapSubwindows(client) register ClientPtr client; { register WindowPtr pWin; REQUEST(xResourceReq); REQUEST←SIZE←MATCH(xResourceReq); pWin = (WindowPtr)LookupWindow( stuff->id, client); if (!pWin) return(BadWindow); MapSubwindows(pWin, HANDLE←EXPOSURES, client); /* update cache to say it is mapped */ return(client->noClientException); } int ProcUnmapWindow(client) register ClientPtr client; { register WindowPtr pWin; REQUEST(xResourceReq); REQUEST←SIZE←MATCH(xResourceReq); pWin = (WindowPtr)LookupWindow( stuff->id, client); if (!pWin) return(BadWindow); UnmapWindow(pWin, HANDLE←EXPOSURES, SEND←NOTIFICATION, FALSE); /* update cache to say it is mapped */ return(client->noClientException); } int ProcUnmapSubwindows(client) register ClientPtr client; { register WindowPtr pWin; REQUEST(xResourceReq); REQUEST←SIZE←MATCH(xResourceReq); pWin = (WindowPtr)LookupWindow( stuff->id, client); if (!pWin) return(BadWindow); UnmapSubwindows(pWin, HANDLE←EXPOSURES); return(client->noClientException); } int ProcConfigureWindow(client) register ClientPtr client; { register WindowPtr pWin; REQUEST(xConfigureWindowReq); register int result; int len; REQUEST←AT←LEAST←SIZE(xConfigureWindowReq); pWin = (WindowPtr)LookupWindow( stuff->window, client); if (!pWin) return(BadWindow); len = stuff->length - (sizeof(xConfigureWindowReq) >> 2); if (Ones((long)stuff->mask) != len) return BadLength; result = ConfigureWindow(pWin, (unsigned long)stuff->mask, (long *) &stuff[1], client); if (client->noClientException != Success) return(client->noClientException); else return(result); } int ProcCirculateWindow(client) register ClientPtr client; { register WindowPtr pWin; REQUEST(xCirculateWindowReq); REQUEST←SIZE←MATCH(xCirculateWindowReq); if ((stuff->direction != RaiseLowest) && (stuff->direction != LowerHighest)) return BadValue; pWin = (WindowPtr)LookupWindow(stuff->window, client); if (!pWin) return(BadWindow); CirculateWindow(pWin, (int)stuff->direction, client); return(client->noClientException); } int ProcGetGeometry(client) register ClientPtr client; { xGetGeometryReply rep; register DrawablePtr pDraw; REQUEST(xResourceReq); REQUEST←SIZE←MATCH(xResourceReq); if (!(pDraw = LOOKUP←DRAWABLE(stuff->id, client))) return (BadDrawable); rep.type = X←Reply; rep.length = 0; rep.sequenceNumber = client->sequence; rep.root = WindowTable[pDraw->pScreen->myNum].wid; rep.depth = pDraw->depth; if (pDraw->type == DRAWABLE←PIXMAP) { PixmapPtr pPixmap = (PixmapPtr)pDraw; rep.x = rep.y = rep.borderWidth = 0; rep.width = pPixmap->width; rep.height = pPixmap->height; } else { register WindowPtr pWin = (WindowPtr)pDraw; rep.x = pWin->clientWinSize.x - pWin->borderWidth; rep.y = pWin->clientWinSize.y - pWin->borderWidth; rep.borderWidth = pWin->borderWidth; rep.width = pWin->clientWinSize.width; rep.height = pWin->clientWinSize.height; } WriteReplyToClient(client, sizeof(xGetGeometryReply), &rep); return(client->noClientException); } int ProcQueryTree(client) register ClientPtr client; { xQueryTreeReply reply; int numChildren = 0; register WindowPtr pChild, pWin; Window *childIDs = (Window *)NULL; REQUEST(xResourceReq); REQUEST←SIZE←MATCH(xResourceReq); pWin = (WindowPtr)LookupWindow(stuff->id, client); if (!pWin) return(BadWindow); reply.type = X←Reply; reply.root = WindowTable[pWin->drawable.pScreen->myNum].wid; reply.sequenceNumber = client->sequence; if (pWin->parent) reply.parent = pWin->parent->wid; else reply.parent = (Window)None; if (pChild = pWin->lastChild) { int csize = 10; childIDs = (Window *) Xalloc(csize * sizeof(Window)); while (pChild) { *childIDs = pChild->wid; childIDs++; numChildren++; if (numChildren > csize) { csize *= 2; childIDs = (Window *) Xrealloc(childIDs, sizeof(Window) * csize); childIDs += numChildren; } pChild = pChild->prevSib; } reply.nChildren = numChildren; reply.length = (numChildren * sizeof(Window)) >> 2; WriteReplyToClient(client, sizeof(xQueryTreeReply), &reply); if (numChildren) { childIDs -= numChildren; WriteReplyToClient(client, numChildren * sizeof(Window), childIDs); Xfree(childIDs); } } else { reply.nChildren = 0; reply.length = 0; WriteReplyToClient(client, sizeof(xQueryTreeReply), &reply); } return(client->noClientException); } int ProcInternAtom(client) register ClientPtr client; { Atom atom; char *tchar; REQUEST(xInternAtomReq); REQUEST←AT←LEAST←SIZE(xInternAtomReq); tchar = (char *) &stuff[1]; atom = MakeAtom(tchar, (int)stuff->nbytes, !stuff->onlyIfExists); if (atom || stuff->onlyIfExists) { xInternAtomReply reply; reply.type = X←Reply; reply.length = 0; reply.sequenceNumber = client->sequence; reply.atom = (atom ? atom : None); WriteReplyToClient(client, sizeof(xInternAtomReply), &reply); return(client->noClientException); } else return (BadAlloc); } int ProcGetAtomName(client) register ClientPtr client; { char *str; xGetAtomNameReply reply; int len; REQUEST(xResourceReq); REQUEST←SIZE←MATCH(xResourceReq); if (str = (char *)NameForAtom(stuff->id)) { len = strlen(str); reply.type = X←Reply; reply.length = (len + 3) >> 2; reply.sequenceNumber = client->sequence; reply.nameLength = len; WriteReplyToClient(client, sizeof(xGetAtomNameReply), &reply); WriteReplyToClient(client, len, str); return(client->noClientException); } else { client->errorValue = stuff->id; return (BadAtom); } } int ProcDeleteProperty(client) register ClientPtr client; { WindowPtr pWin; REQUEST(xDeletePropertyReq); int result; REQUEST←SIZE←MATCH(xDeletePropertyReq); pWin = (WindowPtr)LookupWindow(stuff->window, client); if (!pWin) return(BadWindow); if (ValidAtom(stuff->property)) { result = DeleteProperty(pWin, (ATOM) stuff->property); if (client->noClientException != Success) return(client->noClientException); else return(result); } else return (BadAtom); } int ProcSetSelectionOwner(client) register ClientPtr client; { WindowPtr pWin; REQUEST(xSetSelectionOwnerReq); REQUEST←SIZE←MATCH(xSetSelectionOwnerReq); if (stuff->window != None) { pWin = (WindowPtr)LookupWindow(stuff->window, client); if (!pWin) return(BadWindow); } else pWin = (WindowPtr)None; if (ValidAtom(stuff->selection)) { int i = 0; /* * First, see if the selection is already set... */ while ((i < NumCurrentSelections) && CurrentSelections[i].selection != stuff->selection) i++; if (i < NumCurrentSelections) { xEvent event; if (CurrentSelections[i].pWin != (WindowPtr)None) { event.u.u.type = SelectionClear; event.u.selectionClear.time = 0; event.u.selectionClear.window = CurrentSelections[i].window; event.u.selectionClear.atom = CurrentSelections[i].selection; DeliverEvents(CurrentSelections[i].pWin, &event, 1, (long)0); } CurrentSelections[i].selection = stuff->selection; CurrentSelections[i].window = stuff->window; CurrentSelections[i].pWin = pWin; return (client->noClientException); } /* * It doesn't exist, so add it... */ i = 0; while ((i < NumCurrentSelections) && CurrentSelections[i].window != 0) i++; if (i == NumCurrentSelections) /* there's no room, grow array */ { NumCurrentSelections += 5; CurrentSelections = (Selection *)Xrealloc(CurrentSelections, NumCurrentSelections * sizeof(Selection)); } CurrentSelections[i].selection = stuff->selection; CurrentSelections[i].window = stuff->window; CurrentSelections[i].pWin = pWin; return (client->noClientException); } else return (BadAtom); } int ProcGetSelectionOwner(client) register ClientPtr client; { REQUEST(xResourceReq); REQUEST←SIZE←MATCH(xResourceReq); if (ValidAtom(stuff->id)) { int i; xGetSelectionOwnerReply reply; i = 0; while ((i < NumCurrentSelections) && CurrentSelections[i].selection != stuff->id) i++; reply.type = X←Reply; reply.length = 0; reply.sequenceNumber = client->sequence; if (i < NumCurrentSelections) reply.owner = CurrentSelections[i].window; else reply.owner = None; WriteReplyToClient(client, sizeof(xGetSelectionOwnerReply), &reply); return(client->noClientException); } else return (BadAtom); } int ProcConvertSelection(client) register ClientPtr client; { Bool paramsOkay = TRUE; xEvent event; WindowPtr pWin; REQUEST(xConvertSelectionReq); REQUEST←SIZE←MATCH(xConvertSelectionReq); pWin = (WindowPtr)LookupWindow(stuff->requestor, client); if (!pWin) return(BadWindow); paramsOkay = (ValidAtom(stuff->selection) && ValidAtom(stuff->target)); if (stuff->property != None) paramsOkay &= ValidAtom(stuff->property); if (paramsOkay) { int i; i = 0; while ((i < NumCurrentSelections) && CurrentSelections[i].selection != stuff->selection) i++; if ((i < NumCurrentSelections) && (CurrentSelections[i].window != None)) { event.u.u.type = SelectionRequest; event.u.selectionRequest.time = 0; event.u.selectionRequest.owner = CurrentSelections[i].window; event.u.selectionRequest.requestor = stuff->requestor; event.u.selectionRequest.selection = stuff->selection; event.u.selectionRequest.target = stuff->target; event.u.selectionRequest.property = stuff->property; DeliverEvents(CurrentSelections[i].pWin, &event, 1, (long)0); } else /* didn't find so send SelectionNotify */ { event.u.u.type = SelectionNotify; event.u.selectionNotify.time = 0; event.u.selectionNotify.requestor = stuff->requestor; event.u.selectionNotify.selection = stuff->selection; event.u.selectionNotify.target = stuff->target; event.u.selectionNotify.property = None; DeliverEvents(pWin, &event, 1, (long)0); } return (client->noClientException); } else return (BadAtom); } int ProcGrabServer(client) register ClientPtr client; { OnlyListenToOneClient(client); grabbingClient = TRUE; onlyClient = client; return(client->noClientException); } int ProcUngrabServer(client) register ClientPtr client; { REQUEST(xReq); REQUEST←SIZE←MATCH(xReq); grabbingClient = FALSE; ListenToAllClients(); return(client->noClientException); } int ProcTranslateCoords(client) register ClientPtr client; { REQUEST(xTranslateCoordsReq); register WindowPtr pWin, pDst; xTranslateCoordsReply rep; REQUEST←SIZE←MATCH(xTranslateCoordsReq); pWin = (WindowPtr)LookupWindow(stuff->srcWid, client); if (!pWin) return(BadWindow); pDst = (WindowPtr)LookupWindow(stuff->dstWid, client); if (!pDst) return(BadWindow); rep.type = X←Reply; rep.length = 0; rep.sequenceNumber = client->sequence; if (!SAME←SCREENS(pWin->drawable, pDst->drawable)) { rep.sameScreen = xFalse; rep.child = None; rep.dstX = rep.dstY = 0; } else { INT16 x, y; rep.sameScreen = xTrue; rep.child = None; x = pWin->absCorner.x + stuff->srcX - pDst->absCorner.x; y = pWin->absCorner.y + stuff->srcY - pDst->absCorner.y; pWin = pDst->firstChild; while (pWin) { if ((pWin->mapped) && (x >= pWin->absCorner.x - pWin->borderWidth) && (x < pWin->absCorner.x + pWin->clientWinSize.width + pWin->borderWidth) && (y >= pWin->absCorner.y - pWin->borderWidth) && (y < pWin->absCorner.y + pWin->clientWinSize.height + pWin->borderWidth)) { rep.child = pWin->wid; pWin = (WindowPtr) NULL; } else pWin = pWin->nextSib; } rep.dstX = x; rep.dstY = y; } WriteReplyToClient(client, sizeof(xTranslateCoordsReply), &rep); return(client->noClientException); } int ProcOpenFont(client) register ClientPtr client; { FontPtr pFont; REQUEST(xOpenFontReq); REQUEST←AT←LEAST←SIZE(xOpenFontReq); client->errorValue = stuff->fid; LEGAL←NEW←RESOURCE(stuff->fid); if ( pFont = OpenFont( (int)stuff->nbytes, (char *)&stuff[1])) { AddResource( stuff->fid, RT←FONT, (pointer)pFont, CloseFont,RC←CORE); return(client->noClientException); } else return (BadName); } int ProcCloseFont(client) register ClientPtr client; { FontPtr pFont; REQUEST(xResourceReq); REQUEST←SIZE←MATCH(xResourceReq); pFont = (FontPtr)LookupID(stuff->id, RT←FONT, RC←CORE); if ( pFont != (FontPtr)NULL) /* id was valid */ { FreeResource( stuff->id, RC←NONE); return(client->noClientException); } else return (BadFont); } int ProcQueryFont(client) register ClientPtr client; { xQueryFontReply *reply; FontPtr pFont; register GC *pGC; REQUEST(xResourceReq); REQUEST←SIZE←MATCH(xResourceReq); client->errorValue = stuff->id; /* EITHER font or gc */ pFont = (FontPtr)LookupID(stuff->id, RT←FONT, RC←CORE); if (!pFont) { VERIFY←GC(pGC, stuff->id, client); if (!pGC) return(BadGC); pFont = pGC->font; } { CharInfoPtr pmax = &pFont->pFI->maxbounds; CharInfoPtr pmin = &pFont->pFI->minbounds; int nprotoxcistructs; int rlength; nprotoxcistructs = ( pmax->metrics.rightSideBearing == pmin->metrics.rightSideBearing && pmax->metrics.leftSideBearing == pmin->metrics.leftSideBearing && pmax->metrics.descent == pmin->metrics.descent && pmax->metrics.ascent == pmin->metrics.ascent && pmax->metrics.characterWidth == pmin->metrics.characterWidth) ? 0 : n2dChars(pFont->pFI); rlength = sizeof(xQueryFontReply) + pFont->pFI->nProps * sizeof(xFontProp) + nprotoxcistructs * sizeof(xCharInfo); reply = (xQueryFontReply *)ALLOCATE←LOCAL(rlength); if(!reply) { return(client->noClientException = BadAlloc); } reply->type = X←Reply; reply->length = (rlength - sizeof(xGenericReply)) >> 2; reply->sequenceNumber = client->sequence; QueryFont( pFont, reply, nprotoxcistructs); WriteReplyToClient(client, rlength, reply); DEALLOCATE←LOCAL(reply); return(client->noClientException); } } int ProcQueryTextExtents(client) register ClientPtr client; { REQUEST(xQueryTextExtentsReq); xQueryTextExtentsReply reply; FontPtr pFont; GC *pGC; ExtentInfoRec info; short length; REQUEST←AT←LEAST←SIZE(xQueryTextExtentsReq); pFont = (FontPtr)LookupID( stuff->fid, RT←FONT, RC←CORE); if (!pFont) { pGC = (GC *)LookupID( stuff->fid, RT←GC, RC←CORE); if (!pGC) return(BadFont); pFont = pGC->font; } length = stuff->length - (sizeof(xQueryTextExtentsReq) >> 2); length = length << 1; if (stuff->oddLength) length--; QueryTextExtents(pFont, (unsigned int)length, (unsigned short *)&stuff[1], &info); reply.type = X←Reply; reply.length = 0; reply.sequenceNumber = client->sequence; reply.drawDirection = info.drawDirection; reply.fontAscent = info.fontAscent; reply.fontDescent = info.fontDescent; reply.overallAscent = info.overallAscent; reply.overallDescent = info.overallDescent; reply.overallWidth = info.overallWidth; reply.overallLeft = info.overallLeft; reply.overallRight = info.overallRight; WriteReplyToClient(client, sizeof(xQueryTextExtentsReply), &reply); return(client->noClientException); } int ProcListFonts(client) register ClientPtr client; { xListFontsReply reply; FontPathPtr fpr; int stringLens, i; char *bufptr, *bufferStart; REQUEST(xListFontsReq); REQUEST←AT←LEAST←SIZE(xListFontsReq); fpr = ExpandFontNamePattern( (int)stuff->nbytes, (char *) &stuff[1], (int)stuff->maxNames); stringLens = 0; for (i=0; i<fpr->npaths; i++) stringLens += fpr->length[i]; reply.type = X←Reply; reply.length = (stringLens + fpr->npaths + 3) >> 2; reply.nFonts = fpr->npaths; reply.sequenceNumber = client->sequence; bufptr = bufferStart = (char *)ALLOCATE←LOCAL((int)reply.length << 2); if(!bufptr) return(client->noClientException = BadAlloc); /* since WriteToClient long word aligns things, copy to temp buffer and write all at once */ for (i=0; i<fpr->npaths; i++) { *bufptr++ = fpr->length[i]; bcopy(fpr->paths[i], bufptr, fpr->length[i]); bufptr += fpr->length[i]; } WriteReplyToClient(client, sizeof(xListFontsReply), &reply); WriteReplyToClient(client, reply.length << 2, bufferStart); FreeFontRecord(fpr); DEALLOCATE←LOCAL(bufferStart); return(client->noClientException); } int ProcListFontsWithInfo(client) register ClientPtr client; { xListFontsWithInfoReply reply; FontDataRec fdr; FontPathPtr fpr; int stringLens, i; char *bufptr, *bufferStart; REQUEST(xListFontsWithInfoReq); REQUEST←AT←LEAST←SIZE(xListFontsWithInfoReq); fpr = ExpandFontNamePattern( (int)stuff->nbytes, (char *)&stuff[1], (int)stuff->maxNames); fdr.nfonts = fpr->npaths; fdr.pFI = (FontInfoPtr)ALLOCATE←LOCAL(sizeof(FontInfoRec) * fdr.nfonts); fdr.pFP = (DIXFontProp **)ALLOCATE←LOCAL(sizeof(DIXFontProp) * fdr.nfonts); if(!fdr.pFI || !fdr.pFP) { DEALLOCATE←LOCAL(fdr.pFP); DEALLOCATE←LOCAL(fdr.pFI); return(client->noClientException = BadAlloc); } DescribeFontList(fpr, &fdr); stringLens = 0; for (i=0; i<fpr->npaths; i++) stringLens += fpr->length[i]; reply.type = X←Reply; reply.length = (stringLens + fpr->npaths + 3) >> 2; reply.nFonts = fpr->npaths; reply.sequenceNumber = client->sequence; if(!(bufptr = bufferStart = (char *)ALLOCATE←LOCAL((int)reply.length << 2))) return(client->noClientException = BadAlloc); /* since WriteToClient long word aligns things, copy to temp buffer and write all at once */ for (i=0; i<fpr->npaths; i++) { *bufptr++ = fpr->length[i]; bcopy(fpr->paths[i], bufptr, fpr->length[i]); bufptr += fpr->length[i]; } WriteReplyToClient(client, sizeof(xListFontsWithInfoReply), &reply); WriteReplyToClient(client, reply.length << 2, bufferStart); FreeFontRecord(fpr); DEALLOCATE←LOCAL(bufferStart); DEALLOCATE←LOCAL(fdr.pFP); DEALLOCATE←LOCAL(fdr.pFI); return(client->noClientException); } int ProcCreatePixmap(client) register ClientPtr client; { PixmapPtr pMap; register DrawablePtr pDraw; REQUEST(xCreatePixmapReq); DepthPtr pDepth; register int i; REQUEST←AT←LEAST←SIZE(xCreatePixmapReq); client->errorValue = stuff->pid; LEGAL←NEW←RESOURCE(stuff->pid); if (!(pDraw = LOOKUP←DRAWABLE(stuff->drawable, client))) return (BadDrawable); if (!stuff->width || !stuff->height) return BadValue; if (stuff->depth != 1) { pDepth = pDraw->pScreen->allowedDepths; for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++) if (pDepth->depth == stuff->depth) goto CreatePmap; return BadValue; } CreatePmap: pMap = (PixmapPtr)(*pDraw->pScreen->CreatePixmap) (pDraw->pScreen, stuff->width, stuff->height, stuff->depth); if (pMap) { pMap->drawable.serialNumber = NEXT←SERIAL←NUMBER; AddResource( stuff->pid, RT←PIXMAP, (pointer)pMap, pDraw->pScreen->DestroyPixmap, RC←CORE); return(client->noClientException); } else return (BadAlloc); } int ProcFreePixmap(client) register ClientPtr client; { PixmapPtr pMap; REQUEST(xResourceReq); REQUEST←SIZE←MATCH(xResourceReq); pMap = (PixmapPtr)LookupID(stuff->id, RT←PIXMAP, RC←CORE); if (pMap) { FreeResource(stuff->id, RC←NONE); return(client->noClientException); } else { client->errorValue = stuff->id; return (BadPixmap); } }