diff options
Diffstat (limited to 'xorg-server/dix')
-rw-r--r-- | xorg-server/dix/cursor.c | 4 | ||||
-rw-r--r-- | xorg-server/dix/dispatch.c | 47 | ||||
-rw-r--r-- | xorg-server/dix/dixfonts.c | 1 | ||||
-rw-r--r-- | xorg-server/dix/dixutils.c | 8 | ||||
-rw-r--r-- | xorg-server/dix/events.c | 26 | ||||
-rw-r--r-- | xorg-server/dix/gc.c | 2316 | ||||
-rw-r--r-- | xorg-server/dix/inpututils.c | 1 | ||||
-rw-r--r-- | xorg-server/dix/resource.c | 101 | ||||
-rw-r--r-- | xorg-server/dix/selection.c | 12 | ||||
-rw-r--r-- | xorg-server/dix/window.c | 8 |
10 files changed, 1283 insertions, 1241 deletions
diff --git a/xorg-server/dix/cursor.c b/xorg-server/dix/cursor.c index 01d08bd6e..c8253bba0 100644 --- a/xorg-server/dix/cursor.c +++ b/xorg-server/dix/cursor.c @@ -316,14 +316,14 @@ AllocGlyphCursor(Font source, unsigned sourceChar, Font mask, unsigned maskChar, if (rc != Success)
{
client->errorValue = source;
- return (rc == BadValue) ? BadFont : rc;
+ return rc;
}
rc = dixLookupResourceByType((pointer *)&maskfont, mask, RT_FONT, client,
DixUseAccess);
if (rc != Success && mask != None)
{
client->errorValue = mask;
- return (rc == BadValue) ? BadFont : rc;
+ return rc;
}
if (sourcefont != maskfont)
pShare = (GlyphSharePtr)NULL;
diff --git a/xorg-server/dix/dispatch.c b/xorg-server/dix/dispatch.c index fa11155cc..181fafa77 100644 --- a/xorg-server/dix/dispatch.c +++ b/xorg-server/dix/dispatch.c @@ -1240,7 +1240,7 @@ ProcCloseFont(ClientPtr client) else
{
client->errorValue = stuff->id;
- return (rc == BadValue) ? BadFont : rc;
+ return rc;
}
}
@@ -1453,7 +1453,7 @@ ProcFreePixmap(ClientPtr client) else
{
client->errorValue = stuff->id;
- return (rc == BadValue) ? BadPixmap : rc;
+ return rc;
}
}
@@ -2407,7 +2407,7 @@ ProcFreeColormap(ClientPtr client) else
{
client->errorValue = stuff->id;
- return (rc == BadValue) ? BadColor : rc;
+ return rc;
}
}
@@ -2428,7 +2428,7 @@ ProcCopyColormapAndFree(ClientPtr client) if (rc == Success)
return CopyColormapAndFree(mid, pSrcMap, client->index);
client->errorValue = stuff->srcCmap;
- return (rc == BadValue) ? BadColor : rc;
+ return rc;
}
int
@@ -2445,15 +2445,18 @@ ProcInstallColormap(ClientPtr client) goto out;
rc = XaceHook(XACE_SCREEN_ACCESS, client, pcmp->pScreen, DixSetAttrAccess);
- if (rc != Success)
+ if (rc != Success) {
+ if (rc == BadValue)
+ rc = BadColor;
goto out;
+ }
(*(pcmp->pScreen->InstallColormap)) (pcmp);
return Success;
out:
client->errorValue = stuff->id;
- return (rc == BadValue) ? BadColor : rc;
+ return rc;
}
int
@@ -2470,8 +2473,11 @@ ProcUninstallColormap(ClientPtr client) goto out;
rc = XaceHook(XACE_SCREEN_ACCESS, client, pcmp->pScreen, DixSetAttrAccess);
- if (rc != Success)
+ if (rc != Success) {
+ if (rc == BadValue)
+ rc = BadColor;
goto out;
+ }
if(pcmp->mid != pcmp->pScreen->defColormap)
(*(pcmp->pScreen->UninstallColormap)) (pcmp);
@@ -2479,7 +2485,7 @@ ProcUninstallColormap(ClientPtr client) out:
client->errorValue = stuff->id;
- return (rc == BadValue) ? BadColor : rc;
+ return rc;
}
int
@@ -2552,7 +2558,7 @@ ProcAllocColor (ClientPtr client) else
{
client->errorValue = stuff->cmap;
- return (rc == BadValue) ? BadColor : rc;
+ return rc;
}
}
@@ -2598,7 +2604,7 @@ ProcAllocNamedColor (ClientPtr client) else
{
client->errorValue = stuff->cmap;
- return (rc == BadValue) ? BadColor : rc;
+ return rc;
}
}
@@ -2662,7 +2668,7 @@ ProcAllocColorCells (ClientPtr client) else
{
client->errorValue = stuff->cmap;
- return (rc == BadValue) ? BadColor : rc;
+ return rc;
}
}
@@ -2724,7 +2730,7 @@ ProcAllocColorPlanes(ClientPtr client) else
{
client->errorValue = stuff->cmap;
- return (rc == BadValue) ? BadColor : rc;
+ return rc;
}
}
@@ -2751,7 +2757,7 @@ ProcFreeColors(ClientPtr client) else
{
client->errorValue = stuff->cmap;
- return (rc == BadValue) ? BadColor : rc;
+ return rc;
}
}
@@ -2778,7 +2784,7 @@ ProcStoreColors (ClientPtr client) else
{
client->errorValue = stuff->cmap;
- return (rc == BadValue) ? BadColor : rc;
+ return rc;
}
}
@@ -2808,7 +2814,7 @@ ProcStoreNamedColor (ClientPtr client) else
{
client->errorValue = stuff->cmap;
- return (rc == BadValue) ? BadColor : rc;
+ return rc;
}
}
@@ -2855,7 +2861,7 @@ ProcQueryColors(ClientPtr client) else
{
client->errorValue = stuff->cmap;
- return (rc == BadValue) ? BadColor : rc;
+ return rc;
}
}
@@ -2894,7 +2900,7 @@ ProcLookupColor(ClientPtr client) else
{
client->errorValue = stuff->cmap;
- return (rc == BadValue) ? BadColor : rc;
+ return rc;
}
}
@@ -2920,7 +2926,7 @@ ProcCreateCursor (ClientPtr client) DixReadAccess);
if (rc != Success) {
client->errorValue = stuff->source;
- return (rc == BadValue) ? BadPixmap : rc;
+ return rc;
}
rc = dixLookupResourceByType((pointer *)&msk, stuff->mask, RT_PIXMAP, client,
@@ -2930,7 +2936,7 @@ ProcCreateCursor (ClientPtr client) if (stuff->mask != None)
{
client->errorValue = stuff->mask;
- return (rc == BadValue) ? BadPixmap : rc;
+ return rc;
}
}
else if ( src->drawable.width != msk->drawable.width
@@ -3031,7 +3037,7 @@ ProcFreeCursor (ClientPtr client) else
{
client->errorValue = stuff->id;
- return (rc == BadValue) ? BadCursor : rc;
+ return rc;
}
}
@@ -3741,7 +3747,6 @@ SendErrorToClient(ClientPtr client, unsigned majorCode, unsigned minorCode, memset(&rep, 0, sizeof(xError));
rep.type = X_Error;
- rep.sequenceNumber = client->sequence;
rep.errorCode = errorCode;
rep.majorCode = majorCode;
rep.minorCode = minorCode;
diff --git a/xorg-server/dix/dixfonts.c b/xorg-server/dix/dixfonts.c index 77bb52fb3..239431e2a 100644 --- a/xorg-server/dix/dixfonts.c +++ b/xorg-server/dix/dixfonts.c @@ -1238,7 +1238,6 @@ doPolyText(ClientPtr client, PTclosurePtr c) client, DixUseAccess);
if (err != Success)
{
- err = (err == BadValue) ? BadFont : err;
/* restore pFont and fid for step 4 (described below) */
pFont = oldpFont;
fid = oldfid;
diff --git a/xorg-server/dix/dixutils.c b/xorg-server/dix/dixutils.c index 9d5eb78eb..6b6b41d0d 100644 --- a/xorg-server/dix/dixutils.c +++ b/xorg-server/dix/dixutils.c @@ -231,9 +231,7 @@ dixLookupWindow(WindowPtr *pWin, XID id, ClientPtr client, Mask access) int
dixLookupGC(GCPtr *pGC, XID id, ClientPtr client, Mask access)
{
- int rc;
- rc = dixLookupResourceByType((pointer *)pGC, id, RT_GC, client, access);
- return (rc == BadValue) ? BadGC : rc;
+ return dixLookupResourceByType((pointer *)pGC, id, RT_GC, client, access);
}
int
@@ -243,10 +241,10 @@ dixLookupFontable(FontPtr *pFont, XID id, ClientPtr client, Mask access) GC *pGC;
client->errorValue = id; /* EITHER font or gc */
rc = dixLookupResourceByType((pointer *) pFont, id, RT_FONT, client, access);
- if (rc != BadValue)
+ if (rc != BadFont)
return rc;
rc = dixLookupResourceByType((pointer *) &pGC, id, RT_GC, client, access);
- if (rc == BadValue)
+ if (rc == BadGC)
return BadFont;
if (rc == Success)
*pFont = pGC->font;
diff --git a/xorg-server/dix/events.c b/xorg-server/dix/events.c index a537730a9..d68eeee62 100644 --- a/xorg-server/dix/events.c +++ b/xorg-server/dix/events.c @@ -1841,7 +1841,6 @@ int TryClientEvents (ClientPtr client, DeviceIntPtr dev, xEvent *pEvents,
int count, Mask mask, Mask filter, GrabPtr grab)
{
- int i;
int type;
#ifdef DEBUG_EVENTS
@@ -1908,7 +1907,6 @@ TryClientEvents (ClientPtr client, DeviceIntPtr dev, xEvent *pEvents, {
xEvent release = *pEvents;
release.u.u.type = KeyRelease;
- release.u.u.sequenceNumber = client->sequence;
WriteEventsToClient(client, 1, &release);
#ifdef DEBUG_EVENTS
ErrorF(" (plus fake core release for repeat)");
@@ -1929,7 +1927,6 @@ TryClientEvents (ClientPtr client, DeviceIntPtr dev, xEvent *pEvents, {
deviceKeyButtonPointer release = *(deviceKeyButtonPointer *)pEvents;
release.type = DeviceKeyRelease;
- release.sequenceNumber = client->sequence;
#ifdef DEBUG_EVENTS
ErrorF(" (plus fake xi1 release for repeat)");
#endif
@@ -1943,14 +1940,6 @@ TryClientEvents (ClientPtr client, DeviceIntPtr dev, xEvent *pEvents, }
}
- type &= 0177;
- if (type != KeymapNotify)
- {
- /* all extension events must have a sequence number */
- for (i = 0; i < count; i++)
- pEvents[i].u.u.sequenceNumber = client->sequence;
- }
-
if (BitIsOn(criticalEvents, type))
{
if (client->smart_priority < SMART_MAX_PRIORITY)
@@ -4708,7 +4697,7 @@ ProcChangeActivePointerGrab(ClientPtr client) if (rc != Success)
{
client->errorValue = stuff->cursor;
- return (rc == BadValue) ? BadCursor : rc;
+ return rc;
}
}
@@ -4831,7 +4820,7 @@ GrabDevice(ClientPtr client, DeviceIntPtr dev, if (rc != Success)
{
client->errorValue = curs;
- return (rc == BadValue) ? BadCursor : rc;
+ return rc;
}
access_mode |= DixForceAccess;
}
@@ -5356,7 +5345,7 @@ ProcGrabButton(ClientPtr client) if (rc != Success)
{
client->errorValue = stuff->cursor;
- return (rc == BadValue) ? BadCursor : rc;
+ return rc;
}
access_mode |= DixForceAccess;
}
@@ -5619,7 +5608,7 @@ ProcRecolorCursor(ClientPtr client) if (rc != Success)
{
client->errorValue = stuff->cursor;
- return (rc == BadValue) ? BadCursor : rc;
+ return rc;
}
pCursor->foreRed = stuff->foreRed;
@@ -5669,6 +5658,13 @@ WriteEventsToClient(ClientPtr pClient, int count, xEvent *events) int i,
eventlength = sizeof(xEvent);
+ if (!pClient || pClient == serverClient || pClient->clientGone)
+ return;
+
+ for (i = 0; i < count; i++)
+ if ((events[i].u.u.type & 0x7f) != KeymapNotify)
+ events[i].u.u.sequenceNumber = pClient->sequence;
+
/* Let XKB rewrite the state, as it depends on client preferences. */
XkbFilterEvents(pClient, count, events);
diff --git a/xorg-server/dix/gc.c b/xorg-server/dix/gc.c index 6281f25cd..c93b04496 100644 --- a/xorg-server/dix/gc.c +++ b/xorg-server/dix/gc.c @@ -1,1159 +1,1157 @@ -/*********************************************************** - -Copyright 1987, 1998 The Open Group - -Permission to use, copy, modify, distribute, and sell this software and its -documentation for any purpose is hereby granted without fee, provided that -the above copyright notice appear in all copies and that both that -copyright notice and this permission notice appear in supporting -documentation. - -The above copyright notice and this permission notice shall be included in -all copies or substantial portions of the Software. - -THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR -IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, -FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE -OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN -AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN -CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. - -Except as contained in this notice, the name of The Open Group shall not be -used in advertising or otherwise to promote the sale, use or other dealings -in this Software without prior written authorization from The Open Group. - - -Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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. - -******************************************************************/ - - -#ifdef HAVE_DIX_CONFIG_H -#include <dix-config.h> -#endif - -#include <X11/X.h> -#include <X11/Xmd.h> -#include <X11/Xproto.h> -#include "misc.h" -#include "resource.h" -#include "gcstruct.h" -#include "pixmapstr.h" -#include "dixfontstr.h" -#include "scrnintstr.h" -#include "region.h" -#include "dixstruct.h" - -#include "privates.h" -#include "dix.h" -#include "xace.h" -#include <assert.h> - -extern FontPtr defaultFont; - -static Bool CreateDefaultTile(GCPtr pGC); - -static unsigned char DefaultDash[2] = {4, 4}; - -void -ValidateGC(DrawablePtr pDraw, GC *pGC) -{ - (*pGC->funcs->ValidateGC) (pGC, pGC->stateChanges, pDraw); - pGC->stateChanges = 0; - pGC->serialNumber = pDraw->serialNumber; -} - - -/* - * ChangeGC/ChangeGCXIDs: - * - * The client performing the gc change must be passed so that access - * checks can be performed on any tiles, stipples, or fonts that are - * specified. ddxen can call this too; they should normally pass - * NullClient for the client since any access checking should have - * already been done at a higher level. - * - * If you have any XIDs, you must use ChangeGCXIDs: - * - * CARD32 v[2]; - * v[0] = FillTiled; - * v[1] = pid; - * ChangeGCXIDs(client, pGC, GCFillStyle|GCTile, v); - * - * However, if you need to pass a pointer to a pixmap or font, you must - * use ChangeGC: - * - * ChangeGCVal v[2]; - * v[0].val = FillTiled; - * v[1].ptr = pPixmap; - * ChangeGC(client, pGC, GCFillStyle|GCTile, v); - * - * If you have neither XIDs nor pointers, you can use either function, - * but ChangeGC will do less work. - * - * ChangeGCVal v[2]; - * v[0].val = foreground; - * v[1].val = background; - * ChangeGC(client, pGC, GCForeground|GCBackground, v); - */ - -#define NEXTVAL(_type, _var) { \ - _var = (_type)(pUnion->val); pUnion++; \ - } - -#define NEXT_PTR(_type, _var) { \ - _var = (_type)pUnion->ptr; pUnion++; } - -int -ChangeGC(ClientPtr client, GC *pGC, BITS32 mask, ChangeGCValPtr pUnion) -{ - BITS32 index2; - int error = 0; - PixmapPtr pPixmap; - BITS32 maskQ; - - assert(pUnion); - pGC->serialNumber |= GC_CHANGE_SERIAL_BIT; - - maskQ = mask; /* save these for when we walk the GCque */ - while (mask && !error) - { - index2 = (BITS32) lowbit (mask); - mask &= ~index2; - pGC->stateChanges |= index2; - switch (index2) - { - case GCFunction: - { - CARD8 newalu; - NEXTVAL(CARD8, newalu); - if (newalu <= GXset) - pGC->alu = newalu; - else - { - if (client) - client->errorValue = newalu; - error = BadValue; - } - break; - } - case GCPlaneMask: - NEXTVAL(unsigned long, pGC->planemask); - break; - case GCForeground: - NEXTVAL(unsigned long, pGC->fgPixel); - /* - * this is for CreateGC - */ - if (!pGC->tileIsPixel && !pGC->tile.pixmap) - { - pGC->tileIsPixel = TRUE; - pGC->tile.pixel = pGC->fgPixel; - } - break; - case GCBackground: - NEXTVAL(unsigned long, pGC->bgPixel); - break; - case GCLineWidth: /* ??? line width is a CARD16 */ - NEXTVAL(CARD16, pGC->lineWidth); - break; - case GCLineStyle: - { - unsigned int newlinestyle; - NEXTVAL(unsigned int, newlinestyle); - if (newlinestyle <= LineDoubleDash) - pGC->lineStyle = newlinestyle; - else - { - if (client) - client->errorValue = newlinestyle; - error = BadValue; - } - break; - } - case GCCapStyle: - { - unsigned int newcapstyle; - NEXTVAL(unsigned int, newcapstyle); - if (newcapstyle <= CapProjecting) - pGC->capStyle = newcapstyle; - else - { - if (client) - client->errorValue = newcapstyle; - error = BadValue; - } - break; - } - case GCJoinStyle: - { - unsigned int newjoinstyle; - NEXTVAL(unsigned int, newjoinstyle); - if (newjoinstyle <= JoinBevel) - pGC->joinStyle = newjoinstyle; - else - { - if (client) - client->errorValue = newjoinstyle; - error = BadValue; - } - break; - } - case GCFillStyle: - { - unsigned int newfillstyle; - NEXTVAL(unsigned int, newfillstyle); - if (newfillstyle <= FillOpaqueStippled) - pGC->fillStyle = newfillstyle; - else - { - if (client) - client->errorValue = newfillstyle; - error = BadValue; - } - break; - } - case GCFillRule: - { - unsigned int newfillrule; - NEXTVAL(unsigned int, newfillrule); - if (newfillrule <= WindingRule) - pGC->fillRule = newfillrule; - else - { - if (client) - client->errorValue = newfillrule; - error = BadValue; - } - break; - } - case GCTile: - NEXT_PTR(PixmapPtr, pPixmap); - if ((pPixmap->drawable.depth != pGC->depth) || - (pPixmap->drawable.pScreen != pGC->pScreen)) - { - error = BadMatch; - } - else - { - pPixmap->refcnt++; - if (!pGC->tileIsPixel) - (* pGC->pScreen->DestroyPixmap)(pGC->tile.pixmap); - pGC->tileIsPixel = FALSE; - pGC->tile.pixmap = pPixmap; - } - break; - case GCStipple: - NEXT_PTR(PixmapPtr, pPixmap); - if ((pPixmap->drawable.depth != 1) || - (pPixmap->drawable.pScreen != pGC->pScreen)) - { - error = BadMatch; - } - else - { - pPixmap->refcnt++; - if (pGC->stipple) - (* pGC->pScreen->DestroyPixmap)(pGC->stipple); - pGC->stipple = pPixmap; - } - break; - case GCTileStipXOrigin: - NEXTVAL(INT16, pGC->patOrg.x); - break; - case GCTileStipYOrigin: - NEXTVAL(INT16, pGC->patOrg.y); - break; - case GCFont: - { - FontPtr pFont; - NEXT_PTR(FontPtr, pFont); - pFont->refcnt++; - if (pGC->font) - CloseFont(pGC->font, (Font)0); - pGC->font = pFont; - break; - } - case GCSubwindowMode: - { - unsigned int newclipmode; - NEXTVAL(unsigned int, newclipmode); - if (newclipmode <= IncludeInferiors) - pGC->subWindowMode = newclipmode; - else - { - if (client) - client->errorValue = newclipmode; - error = BadValue; - } - break; - } - case GCGraphicsExposures: - { - unsigned int newge; - NEXTVAL(unsigned int, newge); - if (newge <= xTrue) - pGC->graphicsExposures = newge; - else - { - if (client) - client->errorValue = newge; - error = BadValue; - } - break; - } - case GCClipXOrigin: - NEXTVAL(INT16, pGC->clipOrg.x); - break; - case GCClipYOrigin: - NEXTVAL(INT16, pGC->clipOrg.y); - break; - case GCClipMask: - NEXT_PTR(PixmapPtr, pPixmap); - if (pPixmap) - { - if ((pPixmap->drawable.depth != 1) || - (pPixmap->drawable.pScreen != pGC->pScreen)) - { - error = BadMatch; - break; - } - pPixmap->refcnt++; - } - (*pGC->funcs->ChangeClip)(pGC, pPixmap ? CT_PIXMAP : CT_NONE, - (pointer)pPixmap, 0); - break; - case GCDashOffset: - NEXTVAL(INT16, pGC->dashOffset); - break; - case GCDashList: - { - CARD8 newdash; - NEXTVAL(CARD8, newdash); - if (newdash == 4) - { - if (pGC->dash != DefaultDash) - { - free(pGC->dash); - pGC->numInDashList = 2; - pGC->dash = DefaultDash; - } - } - else if (newdash != 0) - { - unsigned char *dash; - - dash = malloc(2 * sizeof(unsigned char)); - if (dash) - { - if (pGC->dash != DefaultDash) - free(pGC->dash); - pGC->numInDashList = 2; - pGC->dash = dash; - dash[0] = newdash; - dash[1] = newdash; - } - else - error = BadAlloc; - } - else - { - if (client) - client->errorValue = newdash; - error = BadValue; - } - break; - } - case GCArcMode: - { - unsigned int newarcmode; - NEXTVAL(unsigned int, newarcmode); - if (newarcmode <= ArcPieSlice) - pGC->arcMode = newarcmode; - else - { - if (client) - client->errorValue = newarcmode; - error = BadValue; - } - break; - } - default: - if (client) - client->errorValue = maskQ; - error = BadValue; - break; - } - } /* end while mask && !error */ - - if (pGC->fillStyle == FillTiled && pGC->tileIsPixel) - { - if (!CreateDefaultTile (pGC)) - { - pGC->fillStyle = FillSolid; - error = BadAlloc; - } - } - (*pGC->funcs->ChangeGC)(pGC, maskQ); - return error; -} - -#undef NEXTVAL -#undef NEXT_PTR - -static const struct { - BITS32 mask; - RESTYPE type; - Mask access_mode; -} xidfields[] = { - { GCTile, RT_PIXMAP, DixReadAccess }, - { GCStipple, RT_PIXMAP, DixReadAccess }, - { GCFont, RT_FONT, DixUseAccess }, - { GCClipMask, RT_PIXMAP, DixReadAccess }, -}; - -int -ChangeGCXIDs(ClientPtr client, GC *pGC, BITS32 mask, CARD32 *pC32) -{ - ChangeGCVal vals[GCLastBit + 1]; - int i; - if (mask & ~GCAllBits) - { - client->errorValue = mask; - return BadValue; - } - for (i = Ones(mask); i--; ) - vals[i].val = pC32[i]; - for (i = 0; i < sizeof(xidfields) / sizeof(*xidfields); ++i) - { - int offset, rc; - if (!(mask & xidfields[i].mask)) - continue; - offset = Ones(mask & (xidfields[i].mask - 1)); - if (xidfields[i].mask == GCClipMask && vals[offset].val == None) - { - vals[offset].ptr = NullPixmap; - continue; - } - rc = dixLookupResourceByType(&vals[offset].ptr, vals[offset].val, - xidfields[i].type, client, xidfields[i].access_mode); - if (rc != Success) - { - client->errorValue = vals[offset].val; - if (rc == BadValue) - rc = (xidfields[i].type == RT_PIXMAP) ? BadPixmap : BadFont; - return rc; - } - } - return ChangeGC(client, pGC, mask, vals); -} - -/* CreateGC(pDrawable, mask, pval, pStatus) - creates a default GC for the given drawable, using mask to fill - in any non-default values. - Returns a pointer to the new GC on success, NULL otherwise. - returns status of non-default fields in pStatus -BUG: - should check for failure to create default tile - -*/ -GCPtr -CreateGC(DrawablePtr pDrawable, BITS32 mask, XID *pval, int *pStatus, - XID gcid, ClientPtr client) -{ - GCPtr pGC; - - pGC = malloc(sizeof(GC)); - if (!pGC) - { - *pStatus = BadAlloc; - return (GCPtr)NULL; - } - - pGC->pScreen = pDrawable->pScreen; - pGC->depth = pDrawable->depth; - pGC->alu = GXcopy; /* dst <- src */ - pGC->planemask = ~0; - pGC->serialNumber = GC_CHANGE_SERIAL_BIT; - pGC->funcs = 0; - pGC->devPrivates = NULL; - pGC->fgPixel = 0; - pGC->bgPixel = 1; - pGC->lineWidth = 0; - pGC->lineStyle = LineSolid; - pGC->capStyle = CapButt; - pGC->joinStyle = JoinMiter; - pGC->fillStyle = FillSolid; - pGC->fillRule = EvenOddRule; - pGC->arcMode = ArcPieSlice; - pGC->tile.pixel = 0; - pGC->tile.pixmap = NullPixmap; - if (mask & GCForeground) - { - /* - * magic special case -- ChangeGC checks for this condition - * and snags the Foreground value to create a pseudo default-tile - */ - pGC->tileIsPixel = FALSE; - } - else - { - pGC->tileIsPixel = TRUE; - } - - pGC->patOrg.x = 0; - pGC->patOrg.y = 0; - pGC->subWindowMode = ClipByChildren; - pGC->graphicsExposures = TRUE; - pGC->clipOrg.x = 0; - pGC->clipOrg.y = 0; - pGC->clientClipType = CT_NONE; - pGC->clientClip = (pointer)NULL; - pGC->numInDashList = 2; - pGC->dash = DefaultDash; - pGC->dashOffset = 0; - pGC->lastWinOrg.x = 0; - pGC->lastWinOrg.y = 0; - - /* use the default font and stipple */ - pGC->font = defaultFont; - defaultFont->refcnt++; - pGC->stipple = pGC->pScreen->PixmapPerDepth[0]; - pGC->stipple->refcnt++; - - /* security creation/labeling check */ - *pStatus = XaceHook(XACE_RESOURCE_ACCESS, client, gcid, RT_GC, pGC, - RT_NONE, NULL, DixCreateAccess|DixSetAttrAccess); - if (*pStatus != Success) - goto out; - - pGC->stateChanges = GCAllBits; - if (!(*pGC->pScreen->CreateGC)(pGC)) - *pStatus = BadAlloc; - else if (mask) - *pStatus = ChangeGCXIDs(client, pGC, mask, pval); - else - *pStatus = Success; - -out: - if (*pStatus != Success) - { - if (!pGC->tileIsPixel && !pGC->tile.pixmap) - pGC->tileIsPixel = TRUE; /* undo special case */ - FreeGC(pGC, (XID)0); - pGC = (GCPtr)NULL; - } - - return (pGC); -} - -static Bool -CreateDefaultTile (GCPtr pGC) -{ - ChangeGCVal tmpval[3]; - PixmapPtr pTile; - GCPtr pgcScratch; - xRectangle rect; - CARD16 w, h; - - w = 1; - h = 1; - (*pGC->pScreen->QueryBestSize)(TileShape, &w, &h, pGC->pScreen); - pTile = (PixmapPtr) - (*pGC->pScreen->CreatePixmap)(pGC->pScreen, - w, h, pGC->depth, 0); - pgcScratch = GetScratchGC(pGC->depth, pGC->pScreen); - if (!pTile || !pgcScratch) - { - if (pTile) - (*pTile->drawable.pScreen->DestroyPixmap)(pTile); - if (pgcScratch) - FreeScratchGC(pgcScratch); - return FALSE; - } - tmpval[0].val = GXcopy; - tmpval[1].val = pGC->tile.pixel; - tmpval[2].val = FillSolid; - (void)ChangeGC(NullClient, pgcScratch, GCFunction | GCForeground | GCFillStyle, tmpval); - ValidateGC((DrawablePtr)pTile, pgcScratch); - rect.x = 0; - rect.y = 0; - rect.width = w; - rect.height = h; - (*pgcScratch->ops->PolyFillRect)((DrawablePtr)pTile, pgcScratch, 1, &rect); - /* Always remember to free the scratch graphics context after use. */ - FreeScratchGC(pgcScratch); - - pGC->tileIsPixel = FALSE; - pGC->tile.pixmap = pTile; - return TRUE; -} - -int -CopyGC(GC *pgcSrc, GC *pgcDst, BITS32 mask) -{ - BITS32 index2; - BITS32 maskQ; - int error = 0; - - if (pgcSrc == pgcDst) - return Success; - pgcDst->serialNumber |= GC_CHANGE_SERIAL_BIT; - pgcDst->stateChanges |= mask; - maskQ = mask; - while (mask) - { - index2 = (BITS32) lowbit (mask); - mask &= ~index2; - switch (index2) - { - case GCFunction: - pgcDst->alu = pgcSrc->alu; - break; - case GCPlaneMask: - pgcDst->planemask = pgcSrc->planemask; - break; - case GCForeground: - pgcDst->fgPixel = pgcSrc->fgPixel; - break; - case GCBackground: - pgcDst->bgPixel = pgcSrc->bgPixel; - break; - case GCLineWidth: - pgcDst->lineWidth = pgcSrc->lineWidth; - break; - case GCLineStyle: - pgcDst->lineStyle = pgcSrc->lineStyle; - break; - case GCCapStyle: - pgcDst->capStyle = pgcSrc->capStyle; - break; - case GCJoinStyle: - pgcDst->joinStyle = pgcSrc->joinStyle; - break; - case GCFillStyle: - pgcDst->fillStyle = pgcSrc->fillStyle; - break; - case GCFillRule: - pgcDst->fillRule = pgcSrc->fillRule; - break; - case GCTile: - { - if (EqualPixUnion(pgcDst->tileIsPixel, - pgcDst->tile, - pgcSrc->tileIsPixel, - pgcSrc->tile)) - { - break; - } - if (!pgcDst->tileIsPixel) - (* pgcDst->pScreen->DestroyPixmap)(pgcDst->tile.pixmap); - pgcDst->tileIsPixel = pgcSrc->tileIsPixel; - pgcDst->tile = pgcSrc->tile; - if (!pgcDst->tileIsPixel) - pgcDst->tile.pixmap->refcnt++; - break; - } - case GCStipple: - { - if (pgcDst->stipple == pgcSrc->stipple) - break; - if (pgcDst->stipple) - (* pgcDst->pScreen->DestroyPixmap)(pgcDst->stipple); - pgcDst->stipple = pgcSrc->stipple; - if (pgcDst->stipple) - pgcDst->stipple->refcnt ++; - break; - } - case GCTileStipXOrigin: - pgcDst->patOrg.x = pgcSrc->patOrg.x; - break; - case GCTileStipYOrigin: - pgcDst->patOrg.y = pgcSrc->patOrg.y; - break; - case GCFont: - if (pgcDst->font == pgcSrc->font) - break; - if (pgcDst->font) - CloseFont(pgcDst->font, (Font)0); - if ((pgcDst->font = pgcSrc->font) != NullFont) - (pgcDst->font)->refcnt++; - break; - case GCSubwindowMode: - pgcDst->subWindowMode = pgcSrc->subWindowMode; - break; - case GCGraphicsExposures: - pgcDst->graphicsExposures = pgcSrc->graphicsExposures; - break; - case GCClipXOrigin: - pgcDst->clipOrg.x = pgcSrc->clipOrg.x; - break; - case GCClipYOrigin: - pgcDst->clipOrg.y = pgcSrc->clipOrg.y; - break; - case GCClipMask: - (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc); - break; - case GCDashOffset: - pgcDst->dashOffset = pgcSrc->dashOffset; - break; - case GCDashList: - if (pgcSrc->dash == DefaultDash) - { - if (pgcDst->dash != DefaultDash) - { - free(pgcDst->dash); - pgcDst->numInDashList = pgcSrc->numInDashList; - pgcDst->dash = pgcSrc->dash; - } - } - else - { - unsigned char *dash; - unsigned int i; - - dash = malloc(pgcSrc->numInDashList * sizeof(unsigned char)); - if (dash) - { - if (pgcDst->dash != DefaultDash) - free(pgcDst->dash); - pgcDst->numInDashList = pgcSrc->numInDashList; - pgcDst->dash = dash; - for (i=0; i<pgcSrc->numInDashList; i++) - dash[i] = pgcSrc->dash[i]; - } - else - error = BadAlloc; - } - break; - case GCArcMode: - pgcDst->arcMode = pgcSrc->arcMode; - break; - default: - FatalError ("CopyGC: Unhandled mask!\n"); - } - } - if (pgcDst->fillStyle == FillTiled && pgcDst->tileIsPixel) - { - if (!CreateDefaultTile (pgcDst)) - { - pgcDst->fillStyle = FillSolid; - error = BadAlloc; - } - } - (*pgcDst->funcs->CopyGC) (pgcSrc, maskQ, pgcDst); - return error; -} - -/** - * does the diX part of freeing the characteristics in the GC. - * - * \param value must conform to DeleteType - */ -int -FreeGC(pointer value, XID gid) -{ - GCPtr pGC = (GCPtr)value; - - CloseFont(pGC->font, (Font)0); - (* pGC->funcs->DestroyClip)(pGC); - - if (!pGC->tileIsPixel) - (* pGC->pScreen->DestroyPixmap)(pGC->tile.pixmap); - if (pGC->stipple) - (* pGC->pScreen->DestroyPixmap)(pGC->stipple); - - (*pGC->funcs->DestroyGC) (pGC); - if (pGC->dash != DefaultDash) - free(pGC->dash); - dixFreePrivates(pGC->devPrivates); - free(pGC); - return(Success); -} - -/* CreateScratchGC(pScreen, depth) - like CreateGC, but doesn't do the default tile or stipple, -since we can't create them without already having a GC. any code -using the tile or stipple has to set them explicitly anyway, -since the state of the scratch gc is unknown. This is OK -because ChangeGC() has to be able to deal with NULL tiles and -stipples anyway (in case the CreateGC() call has provided a -value for them -- we can't set the default tile until the -client-supplied attributes are installed, since the fgPixel -is what fills the default tile. (maybe this comment should -go with CreateGC() or ChangeGC().) -*/ - -GCPtr -CreateScratchGC(ScreenPtr pScreen, unsigned depth) -{ - GCPtr pGC; - - pGC = malloc(sizeof(GC)); - if (!pGC) - return (GCPtr)NULL; - - pGC->pScreen = pScreen; - pGC->depth = depth; - pGC->alu = GXcopy; /* dst <- src */ - pGC->planemask = ~0; - pGC->serialNumber = 0; - pGC->devPrivates = NULL; - pGC->fgPixel = 0; - pGC->bgPixel = 1; - pGC->lineWidth = 0; - pGC->lineStyle = LineSolid; - pGC->capStyle = CapButt; - pGC->joinStyle = JoinMiter; - pGC->fillStyle = FillSolid; - pGC->fillRule = EvenOddRule; - pGC->arcMode = ArcPieSlice; - pGC->font = defaultFont; - if ( pGC->font) /* necessary, because open of default font could fail */ - pGC->font->refcnt++; - pGC->tileIsPixel = TRUE; - pGC->tile.pixel = 0; - pGC->tile.pixmap = NullPixmap; - pGC->stipple = NullPixmap; - pGC->patOrg.x = 0; - pGC->patOrg.y = 0; - pGC->subWindowMode = ClipByChildren; - pGC->graphicsExposures = TRUE; - pGC->clipOrg.x = 0; - pGC->clipOrg.y = 0; - pGC->clientClipType = CT_NONE; - pGC->dashOffset = 0; - pGC->numInDashList = 2; - pGC->dash = DefaultDash; - pGC->lastWinOrg.x = 0; - pGC->lastWinOrg.y = 0; - - pGC->stateChanges = GCAllBits; - if (!(*pScreen->CreateGC)(pGC)) - { - FreeGC(pGC, (XID)0); - pGC = (GCPtr)NULL; - } - return pGC; -} - -void -FreeGCperDepth(int screenNum) -{ - int i; - ScreenPtr pScreen; - GCPtr *ppGC; - - pScreen = screenInfo.screens[screenNum]; - ppGC = pScreen->GCperDepth; - - for (i = 0; i <= pScreen->numDepths; i++) - (void)FreeGC(ppGC[i], (XID)0); - pScreen->rgf = ~0L; -} - - -Bool -CreateGCperDepth(int screenNum) -{ - int i; - ScreenPtr pScreen; - DepthPtr pDepth; - GCPtr *ppGC; - - pScreen = screenInfo.screens[screenNum]; - pScreen->rgf = 0; - ppGC = pScreen->GCperDepth; - /* do depth 1 separately because it's not included in list */ - if (!(ppGC[0] = CreateScratchGC(pScreen, 1))) - return FALSE; - ppGC[0]->graphicsExposures = FALSE; - /* Make sure we don't overflow GCperDepth[] */ - if( pScreen->numDepths > MAXFORMATS ) - return FALSE; - - pDepth = pScreen->allowedDepths; - for (i=0; i<pScreen->numDepths; i++, pDepth++) - { - if (!(ppGC[i+1] = CreateScratchGC(pScreen, pDepth->depth))) - { - for (; i >= 0; i--) - (void)FreeGC(ppGC[i], (XID)0); - return FALSE; - } - ppGC[i+1]->graphicsExposures = FALSE; - } - return TRUE; -} - -Bool -CreateDefaultStipple(int screenNum) -{ - ScreenPtr pScreen; - ChangeGCVal tmpval[3]; - xRectangle rect; - CARD16 w, h; - GCPtr pgcScratch; - - pScreen = screenInfo.screens[screenNum]; - - w = 16; - h = 16; - (* pScreen->QueryBestSize)(StippleShape, &w, &h, pScreen); - if (!(pScreen->PixmapPerDepth[0] = - (*pScreen->CreatePixmap)(pScreen, w, h, 1, 0))) - return FALSE; - /* fill stipple with 1 */ - tmpval[0].val = GXcopy; - tmpval[1].val = 1; - tmpval[2].val = FillSolid; - pgcScratch = GetScratchGC(1, pScreen); - if (!pgcScratch) - { - (*pScreen->DestroyPixmap)(pScreen->PixmapPerDepth[0]); - return FALSE; - } - (void)ChangeGC(NullClient, pgcScratch, GCFunction|GCForeground|GCFillStyle, tmpval); - ValidateGC((DrawablePtr)pScreen->PixmapPerDepth[0], pgcScratch); - rect.x = 0; - rect.y = 0; - rect.width = w; - rect.height = h; - (*pgcScratch->ops->PolyFillRect)((DrawablePtr)pScreen->PixmapPerDepth[0], - pgcScratch, 1, &rect); - FreeScratchGC(pgcScratch); - return TRUE; -} - -void -FreeDefaultStipple(int screenNum) -{ - ScreenPtr pScreen = screenInfo.screens[screenNum]; - (*pScreen->DestroyPixmap)(pScreen->PixmapPerDepth[0]); -} - -int -SetDashes(GCPtr pGC, unsigned offset, unsigned ndash, unsigned char *pdash) -{ - long i; - unsigned char *p, *indash; - BITS32 maskQ = 0; - - i = ndash; - p = pdash; - while (i--) - { - if (!*p++) - { - /* dash segment must be > 0 */ - return BadValue; - } - } - - if (ndash & 1) - p = malloc(2 * ndash * sizeof(unsigned char)); - else - p = malloc(ndash * sizeof(unsigned char)); - if (!p) - return BadAlloc; - - pGC->serialNumber |= GC_CHANGE_SERIAL_BIT; - if (offset != pGC->dashOffset) - { - pGC->dashOffset = offset; - pGC->stateChanges |= GCDashOffset; - maskQ |= GCDashOffset; - } - - if (pGC->dash != DefaultDash) - free(pGC->dash); - pGC->numInDashList = ndash; - pGC->dash = p; - if (ndash & 1) - { - pGC->numInDashList += ndash; - indash = pdash; - i = ndash; - while (i--) - *p++ = *indash++; - } - while(ndash--) - *p++ = *pdash++; - pGC->stateChanges |= GCDashList; - maskQ |= GCDashList; - - if (pGC->funcs->ChangeGC) - (*pGC->funcs->ChangeGC) (pGC, maskQ); - return Success; -} - -int -VerifyRectOrder(int nrects, xRectangle *prects, int ordering) -{ - xRectangle *prectP, *prectN; - int i; - - switch(ordering) - { - case Unsorted: - return CT_UNSORTED; - case YSorted: - if(nrects > 1) - { - for(i = 1, prectP = prects, prectN = prects + 1; - i < nrects; - i++, prectP++, prectN++) - if(prectN->y < prectP->y) - return -1; - } - return CT_YSORTED; - case YXSorted: - if(nrects > 1) - { - for(i = 1, prectP = prects, prectN = prects + 1; - i < nrects; - i++, prectP++, prectN++) - if((prectN->y < prectP->y) || - ( (prectN->y == prectP->y) && - (prectN->x < prectP->x) ) ) - return -1; - } - return CT_YXSORTED; - case YXBanded: - if(nrects > 1) - { - for(i = 1, prectP = prects, prectN = prects + 1; - i < nrects; - i++, prectP++, prectN++) - if((prectN->y != prectP->y && - prectN->y < prectP->y + (int) prectP->height) || - ((prectN->y == prectP->y) && - (prectN->height != prectP->height || - prectN->x < prectP->x + (int) prectP->width))) - return -1; - } - return CT_YXBANDED; - } - return -1; -} - -int -SetClipRects(GCPtr pGC, int xOrigin, int yOrigin, int nrects, - xRectangle *prects, int ordering) -{ - int newct, size; - xRectangle *prectsNew; - - newct = VerifyRectOrder(nrects, prects, ordering); - if (newct < 0) - return(BadMatch); - size = nrects * sizeof(xRectangle); - prectsNew = malloc(size); - if (!prectsNew && size) - return BadAlloc; - - pGC->serialNumber |= GC_CHANGE_SERIAL_BIT; - pGC->clipOrg.x = xOrigin; - pGC->stateChanges |= GCClipXOrigin; - - pGC->clipOrg.y = yOrigin; - pGC->stateChanges |= GCClipYOrigin; - - if (size) - memmove((char *)prectsNew, (char *)prects, size); - (*pGC->funcs->ChangeClip)(pGC, newct, (pointer)prectsNew, nrects); - if (pGC->funcs->ChangeGC) - (*pGC->funcs->ChangeGC) (pGC, GCClipXOrigin|GCClipYOrigin|GCClipMask); - return Success; -} - - -/* - sets reasonable defaults - if we can get a pre-allocated one, use it and mark it as used. - if we can't, create one out of whole cloth (The Velveteen GC -- if - you use it often enough it will become real.) -*/ -GCPtr -GetScratchGC(unsigned depth, ScreenPtr pScreen) -{ - int i; - GCPtr pGC; - - for (i=0; i<=pScreen->numDepths; i++) - if ( pScreen->GCperDepth[i]->depth == depth && - !(pScreen->rgf & (1L << (i+1))) - ) - { - pScreen->rgf |= (1L << (i+1)); - pGC = (pScreen->GCperDepth[i]); - - pGC->alu = GXcopy; - pGC->planemask = ~0; - pGC->serialNumber = 0; - pGC->fgPixel = 0; - pGC->bgPixel = 1; - pGC->lineWidth = 0; - pGC->lineStyle = LineSolid; - pGC->capStyle = CapButt; - pGC->joinStyle = JoinMiter; - pGC->fillStyle = FillSolid; - pGC->fillRule = EvenOddRule; - pGC->arcMode = ArcChord; - pGC->patOrg.x = 0; - pGC->patOrg.y = 0; - pGC->subWindowMode = ClipByChildren; - pGC->graphicsExposures = FALSE; - pGC->clipOrg.x = 0; - pGC->clipOrg.y = 0; - if (pGC->clientClipType != CT_NONE) - (*pGC->funcs->ChangeClip) (pGC, CT_NONE, NULL, 0); - pGC->stateChanges = GCAllBits; - return pGC; - } - /* if we make it this far, need to roll our own */ - pGC = CreateScratchGC(pScreen, depth); - if (pGC) - pGC->graphicsExposures = FALSE; - return pGC; -} - -/* - if the gc to free is in the table of pre-existing ones, -mark it as available. - if not, free it for real -*/ -void -FreeScratchGC(GCPtr pGC) -{ - ScreenPtr pScreen = pGC->pScreen; - int i; - - for (i=0; i<=pScreen->numDepths; i++) - { - if ( pScreen->GCperDepth[i] == pGC) - { - pScreen->rgf &= ~(1L << (i+1)); - return; - } - } - (void)FreeGC(pGC, (GContext)0); -} +/***********************************************************
+
+Copyright 1987, 1998 The Open Group
+
+Permission to use, copy, modify, distribute, and sell this software and its
+documentation for any purpose is hereby granted without fee, provided that
+the above copyright notice appear in all copies and that both that
+copyright notice and this permission notice appear in supporting
+documentation.
+
+The above copyright notice and this permission notice shall be included in
+all copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN
+AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
+CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+
+Except as contained in this notice, the name of The Open Group shall not be
+used in advertising or otherwise to promote the sale, use or other dealings
+in this Software without prior written authorization from The Open Group.
+
+
+Copyright 1987 by Digital Equipment Corporation, Maynard, 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 name of Digital 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.
+
+******************************************************************/
+
+
+#ifdef HAVE_DIX_CONFIG_H
+#include <dix-config.h>
+#endif
+
+#include <X11/X.h>
+#include <X11/Xmd.h>
+#include <X11/Xproto.h>
+#include "misc.h"
+#include "resource.h"
+#include "gcstruct.h"
+#include "pixmapstr.h"
+#include "dixfontstr.h"
+#include "scrnintstr.h"
+#include "region.h"
+#include "dixstruct.h"
+
+#include "privates.h"
+#include "dix.h"
+#include "xace.h"
+#include <assert.h>
+
+extern FontPtr defaultFont;
+
+static Bool CreateDefaultTile(GCPtr pGC);
+
+static unsigned char DefaultDash[2] = {4, 4};
+
+void
+ValidateGC(DrawablePtr pDraw, GC *pGC)
+{
+ (*pGC->funcs->ValidateGC) (pGC, pGC->stateChanges, pDraw);
+ pGC->stateChanges = 0;
+ pGC->serialNumber = pDraw->serialNumber;
+}
+
+
+/*
+ * ChangeGC/ChangeGCXIDs:
+ *
+ * The client performing the gc change must be passed so that access
+ * checks can be performed on any tiles, stipples, or fonts that are
+ * specified. ddxen can call this too; they should normally pass
+ * NullClient for the client since any access checking should have
+ * already been done at a higher level.
+ *
+ * If you have any XIDs, you must use ChangeGCXIDs:
+ *
+ * CARD32 v[2];
+ * v[0] = FillTiled;
+ * v[1] = pid;
+ * ChangeGCXIDs(client, pGC, GCFillStyle|GCTile, v);
+ *
+ * However, if you need to pass a pointer to a pixmap or font, you must
+ * use ChangeGC:
+ *
+ * ChangeGCVal v[2];
+ * v[0].val = FillTiled;
+ * v[1].ptr = pPixmap;
+ * ChangeGC(client, pGC, GCFillStyle|GCTile, v);
+ *
+ * If you have neither XIDs nor pointers, you can use either function,
+ * but ChangeGC will do less work.
+ *
+ * ChangeGCVal v[2];
+ * v[0].val = foreground;
+ * v[1].val = background;
+ * ChangeGC(client, pGC, GCForeground|GCBackground, v);
+ */
+
+#define NEXTVAL(_type, _var) { \
+ _var = (_type)(pUnion->val); pUnion++; \
+ }
+
+#define NEXT_PTR(_type, _var) { \
+ _var = (_type)pUnion->ptr; pUnion++; }
+
+int
+ChangeGC(ClientPtr client, GC *pGC, BITS32 mask, ChangeGCValPtr pUnion)
+{
+ BITS32 index2;
+ int error = 0;
+ PixmapPtr pPixmap;
+ BITS32 maskQ;
+
+ assert(pUnion);
+ pGC->serialNumber |= GC_CHANGE_SERIAL_BIT;
+
+ maskQ = mask; /* save these for when we walk the GCque */
+ while (mask && !error)
+ {
+ index2 = (BITS32) lowbit (mask);
+ mask &= ~index2;
+ pGC->stateChanges |= index2;
+ switch (index2)
+ {
+ case GCFunction:
+ {
+ CARD8 newalu;
+ NEXTVAL(CARD8, newalu);
+ if (newalu <= GXset)
+ pGC->alu = newalu;
+ else
+ {
+ if (client)
+ client->errorValue = newalu;
+ error = BadValue;
+ }
+ break;
+ }
+ case GCPlaneMask:
+ NEXTVAL(unsigned long, pGC->planemask);
+ break;
+ case GCForeground:
+ NEXTVAL(unsigned long, pGC->fgPixel);
+ /*
+ * this is for CreateGC
+ */
+ if (!pGC->tileIsPixel && !pGC->tile.pixmap)
+ {
+ pGC->tileIsPixel = TRUE;
+ pGC->tile.pixel = pGC->fgPixel;
+ }
+ break;
+ case GCBackground:
+ NEXTVAL(unsigned long, pGC->bgPixel);
+ break;
+ case GCLineWidth: /* ??? line width is a CARD16 */
+ NEXTVAL(CARD16, pGC->lineWidth);
+ break;
+ case GCLineStyle:
+ {
+ unsigned int newlinestyle;
+ NEXTVAL(unsigned int, newlinestyle);
+ if (newlinestyle <= LineDoubleDash)
+ pGC->lineStyle = newlinestyle;
+ else
+ {
+ if (client)
+ client->errorValue = newlinestyle;
+ error = BadValue;
+ }
+ break;
+ }
+ case GCCapStyle:
+ {
+ unsigned int newcapstyle;
+ NEXTVAL(unsigned int, newcapstyle);
+ if (newcapstyle <= CapProjecting)
+ pGC->capStyle = newcapstyle;
+ else
+ {
+ if (client)
+ client->errorValue = newcapstyle;
+ error = BadValue;
+ }
+ break;
+ }
+ case GCJoinStyle:
+ {
+ unsigned int newjoinstyle;
+ NEXTVAL(unsigned int, newjoinstyle);
+ if (newjoinstyle <= JoinBevel)
+ pGC->joinStyle = newjoinstyle;
+ else
+ {
+ if (client)
+ client->errorValue = newjoinstyle;
+ error = BadValue;
+ }
+ break;
+ }
+ case GCFillStyle:
+ {
+ unsigned int newfillstyle;
+ NEXTVAL(unsigned int, newfillstyle);
+ if (newfillstyle <= FillOpaqueStippled)
+ pGC->fillStyle = newfillstyle;
+ else
+ {
+ if (client)
+ client->errorValue = newfillstyle;
+ error = BadValue;
+ }
+ break;
+ }
+ case GCFillRule:
+ {
+ unsigned int newfillrule;
+ NEXTVAL(unsigned int, newfillrule);
+ if (newfillrule <= WindingRule)
+ pGC->fillRule = newfillrule;
+ else
+ {
+ if (client)
+ client->errorValue = newfillrule;
+ error = BadValue;
+ }
+ break;
+ }
+ case GCTile:
+ NEXT_PTR(PixmapPtr, pPixmap);
+ if ((pPixmap->drawable.depth != pGC->depth) ||
+ (pPixmap->drawable.pScreen != pGC->pScreen))
+ {
+ error = BadMatch;
+ }
+ else
+ {
+ pPixmap->refcnt++;
+ if (!pGC->tileIsPixel)
+ (* pGC->pScreen->DestroyPixmap)(pGC->tile.pixmap);
+ pGC->tileIsPixel = FALSE;
+ pGC->tile.pixmap = pPixmap;
+ }
+ break;
+ case GCStipple:
+ NEXT_PTR(PixmapPtr, pPixmap);
+ if ((pPixmap->drawable.depth != 1) ||
+ (pPixmap->drawable.pScreen != pGC->pScreen))
+ {
+ error = BadMatch;
+ }
+ else
+ {
+ pPixmap->refcnt++;
+ if (pGC->stipple)
+ (* pGC->pScreen->DestroyPixmap)(pGC->stipple);
+ pGC->stipple = pPixmap;
+ }
+ break;
+ case GCTileStipXOrigin:
+ NEXTVAL(INT16, pGC->patOrg.x);
+ break;
+ case GCTileStipYOrigin:
+ NEXTVAL(INT16, pGC->patOrg.y);
+ break;
+ case GCFont:
+ {
+ FontPtr pFont;
+ NEXT_PTR(FontPtr, pFont);
+ pFont->refcnt++;
+ if (pGC->font)
+ CloseFont(pGC->font, (Font)0);
+ pGC->font = pFont;
+ break;
+ }
+ case GCSubwindowMode:
+ {
+ unsigned int newclipmode;
+ NEXTVAL(unsigned int, newclipmode);
+ if (newclipmode <= IncludeInferiors)
+ pGC->subWindowMode = newclipmode;
+ else
+ {
+ if (client)
+ client->errorValue = newclipmode;
+ error = BadValue;
+ }
+ break;
+ }
+ case GCGraphicsExposures:
+ {
+ unsigned int newge;
+ NEXTVAL(unsigned int, newge);
+ if (newge <= xTrue)
+ pGC->graphicsExposures = newge;
+ else
+ {
+ if (client)
+ client->errorValue = newge;
+ error = BadValue;
+ }
+ break;
+ }
+ case GCClipXOrigin:
+ NEXTVAL(INT16, pGC->clipOrg.x);
+ break;
+ case GCClipYOrigin:
+ NEXTVAL(INT16, pGC->clipOrg.y);
+ break;
+ case GCClipMask:
+ NEXT_PTR(PixmapPtr, pPixmap);
+ if (pPixmap)
+ {
+ if ((pPixmap->drawable.depth != 1) ||
+ (pPixmap->drawable.pScreen != pGC->pScreen))
+ {
+ error = BadMatch;
+ break;
+ }
+ pPixmap->refcnt++;
+ }
+ (*pGC->funcs->ChangeClip)(pGC, pPixmap ? CT_PIXMAP : CT_NONE,
+ (pointer)pPixmap, 0);
+ break;
+ case GCDashOffset:
+ NEXTVAL(INT16, pGC->dashOffset);
+ break;
+ case GCDashList:
+ {
+ CARD8 newdash;
+ NEXTVAL(CARD8, newdash);
+ if (newdash == 4)
+ {
+ if (pGC->dash != DefaultDash)
+ {
+ free(pGC->dash);
+ pGC->numInDashList = 2;
+ pGC->dash = DefaultDash;
+ }
+ }
+ else if (newdash != 0)
+ {
+ unsigned char *dash;
+
+ dash = malloc(2 * sizeof(unsigned char));
+ if (dash)
+ {
+ if (pGC->dash != DefaultDash)
+ free(pGC->dash);
+ pGC->numInDashList = 2;
+ pGC->dash = dash;
+ dash[0] = newdash;
+ dash[1] = newdash;
+ }
+ else
+ error = BadAlloc;
+ }
+ else
+ {
+ if (client)
+ client->errorValue = newdash;
+ error = BadValue;
+ }
+ break;
+ }
+ case GCArcMode:
+ {
+ unsigned int newarcmode;
+ NEXTVAL(unsigned int, newarcmode);
+ if (newarcmode <= ArcPieSlice)
+ pGC->arcMode = newarcmode;
+ else
+ {
+ if (client)
+ client->errorValue = newarcmode;
+ error = BadValue;
+ }
+ break;
+ }
+ default:
+ if (client)
+ client->errorValue = maskQ;
+ error = BadValue;
+ break;
+ }
+ } /* end while mask && !error */
+
+ if (pGC->fillStyle == FillTiled && pGC->tileIsPixel)
+ {
+ if (!CreateDefaultTile (pGC))
+ {
+ pGC->fillStyle = FillSolid;
+ error = BadAlloc;
+ }
+ }
+ (*pGC->funcs->ChangeGC)(pGC, maskQ);
+ return error;
+}
+
+#undef NEXTVAL
+#undef NEXT_PTR
+
+static const struct {
+ BITS32 mask;
+ RESTYPE type;
+ Mask access_mode;
+} xidfields[] = {
+ { GCTile, RT_PIXMAP, DixReadAccess },
+ { GCStipple, RT_PIXMAP, DixReadAccess },
+ { GCFont, RT_FONT, DixUseAccess },
+ { GCClipMask, RT_PIXMAP, DixReadAccess },
+};
+
+int
+ChangeGCXIDs(ClientPtr client, GC *pGC, BITS32 mask, CARD32 *pC32)
+{
+ ChangeGCVal vals[GCLastBit + 1];
+ int i;
+ if (mask & ~GCAllBits)
+ {
+ client->errorValue = mask;
+ return BadValue;
+ }
+ for (i = Ones(mask); i--; )
+ vals[i].val = pC32[i];
+ for (i = 0; i < sizeof(xidfields) / sizeof(*xidfields); ++i)
+ {
+ int offset, rc;
+ if (!(mask & xidfields[i].mask))
+ continue;
+ offset = Ones(mask & (xidfields[i].mask - 1));
+ if (xidfields[i].mask == GCClipMask && vals[offset].val == None)
+ {
+ vals[offset].ptr = NullPixmap;
+ continue;
+ }
+ rc = dixLookupResourceByType(&vals[offset].ptr, vals[offset].val,
+ xidfields[i].type, client, xidfields[i].access_mode);
+ if (rc != Success)
+ {
+ client->errorValue = vals[offset].val;
+ return rc;
+ }
+ }
+ return ChangeGC(client, pGC, mask, vals);
+}
+
+/* CreateGC(pDrawable, mask, pval, pStatus)
+ creates a default GC for the given drawable, using mask to fill
+ in any non-default values.
+ Returns a pointer to the new GC on success, NULL otherwise.
+ returns status of non-default fields in pStatus
+BUG:
+ should check for failure to create default tile
+
+*/
+GCPtr
+CreateGC(DrawablePtr pDrawable, BITS32 mask, XID *pval, int *pStatus,
+ XID gcid, ClientPtr client)
+{
+ GCPtr pGC;
+
+ pGC = malloc(sizeof(GC));
+ if (!pGC)
+ {
+ *pStatus = BadAlloc;
+ return (GCPtr)NULL;
+ }
+
+ pGC->pScreen = pDrawable->pScreen;
+ pGC->depth = pDrawable->depth;
+ pGC->alu = GXcopy; /* dst <- src */
+ pGC->planemask = ~0;
+ pGC->serialNumber = GC_CHANGE_SERIAL_BIT;
+ pGC->funcs = 0;
+ pGC->devPrivates = NULL;
+ pGC->fgPixel = 0;
+ pGC->bgPixel = 1;
+ pGC->lineWidth = 0;
+ pGC->lineStyle = LineSolid;
+ pGC->capStyle = CapButt;
+ pGC->joinStyle = JoinMiter;
+ pGC->fillStyle = FillSolid;
+ pGC->fillRule = EvenOddRule;
+ pGC->arcMode = ArcPieSlice;
+ pGC->tile.pixel = 0;
+ pGC->tile.pixmap = NullPixmap;
+ if (mask & GCForeground)
+ {
+ /*
+ * magic special case -- ChangeGC checks for this condition
+ * and snags the Foreground value to create a pseudo default-tile
+ */
+ pGC->tileIsPixel = FALSE;
+ }
+ else
+ {
+ pGC->tileIsPixel = TRUE;
+ }
+
+ pGC->patOrg.x = 0;
+ pGC->patOrg.y = 0;
+ pGC->subWindowMode = ClipByChildren;
+ pGC->graphicsExposures = TRUE;
+ pGC->clipOrg.x = 0;
+ pGC->clipOrg.y = 0;
+ pGC->clientClipType = CT_NONE;
+ pGC->clientClip = (pointer)NULL;
+ pGC->numInDashList = 2;
+ pGC->dash = DefaultDash;
+ pGC->dashOffset = 0;
+ pGC->lastWinOrg.x = 0;
+ pGC->lastWinOrg.y = 0;
+
+ /* use the default font and stipple */
+ pGC->font = defaultFont;
+ defaultFont->refcnt++;
+ pGC->stipple = pGC->pScreen->PixmapPerDepth[0];
+ pGC->stipple->refcnt++;
+
+ /* security creation/labeling check */
+ *pStatus = XaceHook(XACE_RESOURCE_ACCESS, client, gcid, RT_GC, pGC,
+ RT_NONE, NULL, DixCreateAccess|DixSetAttrAccess);
+ if (*pStatus != Success)
+ goto out;
+
+ pGC->stateChanges = GCAllBits;
+ if (!(*pGC->pScreen->CreateGC)(pGC))
+ *pStatus = BadAlloc;
+ else if (mask)
+ *pStatus = ChangeGCXIDs(client, pGC, mask, pval);
+ else
+ *pStatus = Success;
+
+out:
+ if (*pStatus != Success)
+ {
+ if (!pGC->tileIsPixel && !pGC->tile.pixmap)
+ pGC->tileIsPixel = TRUE; /* undo special case */
+ FreeGC(pGC, (XID)0);
+ pGC = (GCPtr)NULL;
+ }
+
+ return (pGC);
+}
+
+static Bool
+CreateDefaultTile (GCPtr pGC)
+{
+ ChangeGCVal tmpval[3];
+ PixmapPtr pTile;
+ GCPtr pgcScratch;
+ xRectangle rect;
+ CARD16 w, h;
+
+ w = 1;
+ h = 1;
+ (*pGC->pScreen->QueryBestSize)(TileShape, &w, &h, pGC->pScreen);
+ pTile = (PixmapPtr)
+ (*pGC->pScreen->CreatePixmap)(pGC->pScreen,
+ w, h, pGC->depth, 0);
+ pgcScratch = GetScratchGC(pGC->depth, pGC->pScreen);
+ if (!pTile || !pgcScratch)
+ {
+ if (pTile)
+ (*pTile->drawable.pScreen->DestroyPixmap)(pTile);
+ if (pgcScratch)
+ FreeScratchGC(pgcScratch);
+ return FALSE;
+ }
+ tmpval[0].val = GXcopy;
+ tmpval[1].val = pGC->tile.pixel;
+ tmpval[2].val = FillSolid;
+ (void)ChangeGC(NullClient, pgcScratch, GCFunction | GCForeground | GCFillStyle, tmpval);
+ ValidateGC((DrawablePtr)pTile, pgcScratch);
+ rect.x = 0;
+ rect.y = 0;
+ rect.width = w;
+ rect.height = h;
+ (*pgcScratch->ops->PolyFillRect)((DrawablePtr)pTile, pgcScratch, 1, &rect);
+ /* Always remember to free the scratch graphics context after use. */
+ FreeScratchGC(pgcScratch);
+
+ pGC->tileIsPixel = FALSE;
+ pGC->tile.pixmap = pTile;
+ return TRUE;
+}
+
+int
+CopyGC(GC *pgcSrc, GC *pgcDst, BITS32 mask)
+{
+ BITS32 index2;
+ BITS32 maskQ;
+ int error = 0;
+
+ if (pgcSrc == pgcDst)
+ return Success;
+ pgcDst->serialNumber |= GC_CHANGE_SERIAL_BIT;
+ pgcDst->stateChanges |= mask;
+ maskQ = mask;
+ while (mask)
+ {
+ index2 = (BITS32) lowbit (mask);
+ mask &= ~index2;
+ switch (index2)
+ {
+ case GCFunction:
+ pgcDst->alu = pgcSrc->alu;
+ break;
+ case GCPlaneMask:
+ pgcDst->planemask = pgcSrc->planemask;
+ break;
+ case GCForeground:
+ pgcDst->fgPixel = pgcSrc->fgPixel;
+ break;
+ case GCBackground:
+ pgcDst->bgPixel = pgcSrc->bgPixel;
+ break;
+ case GCLineWidth:
+ pgcDst->lineWidth = pgcSrc->lineWidth;
+ break;
+ case GCLineStyle:
+ pgcDst->lineStyle = pgcSrc->lineStyle;
+ break;
+ case GCCapStyle:
+ pgcDst->capStyle = pgcSrc->capStyle;
+ break;
+ case GCJoinStyle:
+ pgcDst->joinStyle = pgcSrc->joinStyle;
+ break;
+ case GCFillStyle:
+ pgcDst->fillStyle = pgcSrc->fillStyle;
+ break;
+ case GCFillRule:
+ pgcDst->fillRule = pgcSrc->fillRule;
+ break;
+ case GCTile:
+ {
+ if (EqualPixUnion(pgcDst->tileIsPixel,
+ pgcDst->tile,
+ pgcSrc->tileIsPixel,
+ pgcSrc->tile))
+ {
+ break;
+ }
+ if (!pgcDst->tileIsPixel)
+ (* pgcDst->pScreen->DestroyPixmap)(pgcDst->tile.pixmap);
+ pgcDst->tileIsPixel = pgcSrc->tileIsPixel;
+ pgcDst->tile = pgcSrc->tile;
+ if (!pgcDst->tileIsPixel)
+ pgcDst->tile.pixmap->refcnt++;
+ break;
+ }
+ case GCStipple:
+ {
+ if (pgcDst->stipple == pgcSrc->stipple)
+ break;
+ if (pgcDst->stipple)
+ (* pgcDst->pScreen->DestroyPixmap)(pgcDst->stipple);
+ pgcDst->stipple = pgcSrc->stipple;
+ if (pgcDst->stipple)
+ pgcDst->stipple->refcnt ++;
+ break;
+ }
+ case GCTileStipXOrigin:
+ pgcDst->patOrg.x = pgcSrc->patOrg.x;
+ break;
+ case GCTileStipYOrigin:
+ pgcDst->patOrg.y = pgcSrc->patOrg.y;
+ break;
+ case GCFont:
+ if (pgcDst->font == pgcSrc->font)
+ break;
+ if (pgcDst->font)
+ CloseFont(pgcDst->font, (Font)0);
+ if ((pgcDst->font = pgcSrc->font) != NullFont)
+ (pgcDst->font)->refcnt++;
+ break;
+ case GCSubwindowMode:
+ pgcDst->subWindowMode = pgcSrc->subWindowMode;
+ break;
+ case GCGraphicsExposures:
+ pgcDst->graphicsExposures = pgcSrc->graphicsExposures;
+ break;
+ case GCClipXOrigin:
+ pgcDst->clipOrg.x = pgcSrc->clipOrg.x;
+ break;
+ case GCClipYOrigin:
+ pgcDst->clipOrg.y = pgcSrc->clipOrg.y;
+ break;
+ case GCClipMask:
+ (* pgcDst->funcs->CopyClip)(pgcDst, pgcSrc);
+ break;
+ case GCDashOffset:
+ pgcDst->dashOffset = pgcSrc->dashOffset;
+ break;
+ case GCDashList:
+ if (pgcSrc->dash == DefaultDash)
+ {
+ if (pgcDst->dash != DefaultDash)
+ {
+ free(pgcDst->dash);
+ pgcDst->numInDashList = pgcSrc->numInDashList;
+ pgcDst->dash = pgcSrc->dash;
+ }
+ }
+ else
+ {
+ unsigned char *dash;
+ unsigned int i;
+
+ dash = malloc(pgcSrc->numInDashList * sizeof(unsigned char));
+ if (dash)
+ {
+ if (pgcDst->dash != DefaultDash)
+ free(pgcDst->dash);
+ pgcDst->numInDashList = pgcSrc->numInDashList;
+ pgcDst->dash = dash;
+ for (i=0; i<pgcSrc->numInDashList; i++)
+ dash[i] = pgcSrc->dash[i];
+ }
+ else
+ error = BadAlloc;
+ }
+ break;
+ case GCArcMode:
+ pgcDst->arcMode = pgcSrc->arcMode;
+ break;
+ default:
+ FatalError ("CopyGC: Unhandled mask!\n");
+ }
+ }
+ if (pgcDst->fillStyle == FillTiled && pgcDst->tileIsPixel)
+ {
+ if (!CreateDefaultTile (pgcDst))
+ {
+ pgcDst->fillStyle = FillSolid;
+ error = BadAlloc;
+ }
+ }
+ (*pgcDst->funcs->CopyGC) (pgcSrc, maskQ, pgcDst);
+ return error;
+}
+
+/**
+ * does the diX part of freeing the characteristics in the GC.
+ *
+ * \param value must conform to DeleteType
+ */
+int
+FreeGC(pointer value, XID gid)
+{
+ GCPtr pGC = (GCPtr)value;
+
+ CloseFont(pGC->font, (Font)0);
+ (* pGC->funcs->DestroyClip)(pGC);
+
+ if (!pGC->tileIsPixel)
+ (* pGC->pScreen->DestroyPixmap)(pGC->tile.pixmap);
+ if (pGC->stipple)
+ (* pGC->pScreen->DestroyPixmap)(pGC->stipple);
+
+ (*pGC->funcs->DestroyGC) (pGC);
+ if (pGC->dash != DefaultDash)
+ free(pGC->dash);
+ dixFreePrivates(pGC->devPrivates);
+ free(pGC);
+ return(Success);
+}
+
+/* CreateScratchGC(pScreen, depth)
+ like CreateGC, but doesn't do the default tile or stipple,
+since we can't create them without already having a GC. any code
+using the tile or stipple has to set them explicitly anyway,
+since the state of the scratch gc is unknown. This is OK
+because ChangeGC() has to be able to deal with NULL tiles and
+stipples anyway (in case the CreateGC() call has provided a
+value for them -- we can't set the default tile until the
+client-supplied attributes are installed, since the fgPixel
+is what fills the default tile. (maybe this comment should
+go with CreateGC() or ChangeGC().)
+*/
+
+GCPtr
+CreateScratchGC(ScreenPtr pScreen, unsigned depth)
+{
+ GCPtr pGC;
+
+ pGC = malloc(sizeof(GC));
+ if (!pGC)
+ return (GCPtr)NULL;
+
+ pGC->pScreen = pScreen;
+ pGC->depth = depth;
+ pGC->alu = GXcopy; /* dst <- src */
+ pGC->planemask = ~0;
+ pGC->serialNumber = 0;
+ pGC->devPrivates = NULL;
+ pGC->fgPixel = 0;
+ pGC->bgPixel = 1;
+ pGC->lineWidth = 0;
+ pGC->lineStyle = LineSolid;
+ pGC->capStyle = CapButt;
+ pGC->joinStyle = JoinMiter;
+ pGC->fillStyle = FillSolid;
+ pGC->fillRule = EvenOddRule;
+ pGC->arcMode = ArcPieSlice;
+ pGC->font = defaultFont;
+ if ( pGC->font) /* necessary, because open of default font could fail */
+ pGC->font->refcnt++;
+ pGC->tileIsPixel = TRUE;
+ pGC->tile.pixel = 0;
+ pGC->tile.pixmap = NullPixmap;
+ pGC->stipple = NullPixmap;
+ pGC->patOrg.x = 0;
+ pGC->patOrg.y = 0;
+ pGC->subWindowMode = ClipByChildren;
+ pGC->graphicsExposures = TRUE;
+ pGC->clipOrg.x = 0;
+ pGC->clipOrg.y = 0;
+ pGC->clientClipType = CT_NONE;
+ pGC->dashOffset = 0;
+ pGC->numInDashList = 2;
+ pGC->dash = DefaultDash;
+ pGC->lastWinOrg.x = 0;
+ pGC->lastWinOrg.y = 0;
+
+ pGC->stateChanges = GCAllBits;
+ if (!(*pScreen->CreateGC)(pGC))
+ {
+ FreeGC(pGC, (XID)0);
+ pGC = (GCPtr)NULL;
+ }
+ return pGC;
+}
+
+void
+FreeGCperDepth(int screenNum)
+{
+ int i;
+ ScreenPtr pScreen;
+ GCPtr *ppGC;
+
+ pScreen = screenInfo.screens[screenNum];
+ ppGC = pScreen->GCperDepth;
+
+ for (i = 0; i <= pScreen->numDepths; i++)
+ (void)FreeGC(ppGC[i], (XID)0);
+ pScreen->rgf = ~0L;
+}
+
+
+Bool
+CreateGCperDepth(int screenNum)
+{
+ int i;
+ ScreenPtr pScreen;
+ DepthPtr pDepth;
+ GCPtr *ppGC;
+
+ pScreen = screenInfo.screens[screenNum];
+ pScreen->rgf = 0;
+ ppGC = pScreen->GCperDepth;
+ /* do depth 1 separately because it's not included in list */
+ if (!(ppGC[0] = CreateScratchGC(pScreen, 1)))
+ return FALSE;
+ ppGC[0]->graphicsExposures = FALSE;
+ /* Make sure we don't overflow GCperDepth[] */
+ if( pScreen->numDepths > MAXFORMATS )
+ return FALSE;
+
+ pDepth = pScreen->allowedDepths;
+ for (i=0; i<pScreen->numDepths; i++, pDepth++)
+ {
+ if (!(ppGC[i+1] = CreateScratchGC(pScreen, pDepth->depth)))
+ {
+ for (; i >= 0; i--)
+ (void)FreeGC(ppGC[i], (XID)0);
+ return FALSE;
+ }
+ ppGC[i+1]->graphicsExposures = FALSE;
+ }
+ return TRUE;
+}
+
+Bool
+CreateDefaultStipple(int screenNum)
+{
+ ScreenPtr pScreen;
+ ChangeGCVal tmpval[3];
+ xRectangle rect;
+ CARD16 w, h;
+ GCPtr pgcScratch;
+
+ pScreen = screenInfo.screens[screenNum];
+
+ w = 16;
+ h = 16;
+ (* pScreen->QueryBestSize)(StippleShape, &w, &h, pScreen);
+ if (!(pScreen->PixmapPerDepth[0] =
+ (*pScreen->CreatePixmap)(pScreen, w, h, 1, 0)))
+ return FALSE;
+ /* fill stipple with 1 */
+ tmpval[0].val = GXcopy;
+ tmpval[1].val = 1;
+ tmpval[2].val = FillSolid;
+ pgcScratch = GetScratchGC(1, pScreen);
+ if (!pgcScratch)
+ {
+ (*pScreen->DestroyPixmap)(pScreen->PixmapPerDepth[0]);
+ return FALSE;
+ }
+ (void)ChangeGC(NullClient, pgcScratch, GCFunction|GCForeground|GCFillStyle, tmpval);
+ ValidateGC((DrawablePtr)pScreen->PixmapPerDepth[0], pgcScratch);
+ rect.x = 0;
+ rect.y = 0;
+ rect.width = w;
+ rect.height = h;
+ (*pgcScratch->ops->PolyFillRect)((DrawablePtr)pScreen->PixmapPerDepth[0],
+ pgcScratch, 1, &rect);
+ FreeScratchGC(pgcScratch);
+ return TRUE;
+}
+
+void
+FreeDefaultStipple(int screenNum)
+{
+ ScreenPtr pScreen = screenInfo.screens[screenNum];
+ (*pScreen->DestroyPixmap)(pScreen->PixmapPerDepth[0]);
+}
+
+int
+SetDashes(GCPtr pGC, unsigned offset, unsigned ndash, unsigned char *pdash)
+{
+ long i;
+ unsigned char *p, *indash;
+ BITS32 maskQ = 0;
+
+ i = ndash;
+ p = pdash;
+ while (i--)
+ {
+ if (!*p++)
+ {
+ /* dash segment must be > 0 */
+ return BadValue;
+ }
+ }
+
+ if (ndash & 1)
+ p = malloc(2 * ndash * sizeof(unsigned char));
+ else
+ p = malloc(ndash * sizeof(unsigned char));
+ if (!p)
+ return BadAlloc;
+
+ pGC->serialNumber |= GC_CHANGE_SERIAL_BIT;
+ if (offset != pGC->dashOffset)
+ {
+ pGC->dashOffset = offset;
+ pGC->stateChanges |= GCDashOffset;
+ maskQ |= GCDashOffset;
+ }
+
+ if (pGC->dash != DefaultDash)
+ free(pGC->dash);
+ pGC->numInDashList = ndash;
+ pGC->dash = p;
+ if (ndash & 1)
+ {
+ pGC->numInDashList += ndash;
+ indash = pdash;
+ i = ndash;
+ while (i--)
+ *p++ = *indash++;
+ }
+ while(ndash--)
+ *p++ = *pdash++;
+ pGC->stateChanges |= GCDashList;
+ maskQ |= GCDashList;
+
+ if (pGC->funcs->ChangeGC)
+ (*pGC->funcs->ChangeGC) (pGC, maskQ);
+ return Success;
+}
+
+int
+VerifyRectOrder(int nrects, xRectangle *prects, int ordering)
+{
+ xRectangle *prectP, *prectN;
+ int i;
+
+ switch(ordering)
+ {
+ case Unsorted:
+ return CT_UNSORTED;
+ case YSorted:
+ if(nrects > 1)
+ {
+ for(i = 1, prectP = prects, prectN = prects + 1;
+ i < nrects;
+ i++, prectP++, prectN++)
+ if(prectN->y < prectP->y)
+ return -1;
+ }
+ return CT_YSORTED;
+ case YXSorted:
+ if(nrects > 1)
+ {
+ for(i = 1, prectP = prects, prectN = prects + 1;
+ i < nrects;
+ i++, prectP++, prectN++)
+ if((prectN->y < prectP->y) ||
+ ( (prectN->y == prectP->y) &&
+ (prectN->x < prectP->x) ) )
+ return -1;
+ }
+ return CT_YXSORTED;
+ case YXBanded:
+ if(nrects > 1)
+ {
+ for(i = 1, prectP = prects, prectN = prects + 1;
+ i < nrects;
+ i++, prectP++, prectN++)
+ if((prectN->y != prectP->y &&
+ prectN->y < prectP->y + (int) prectP->height) ||
+ ((prectN->y == prectP->y) &&
+ (prectN->height != prectP->height ||
+ prectN->x < prectP->x + (int) prectP->width)))
+ return -1;
+ }
+ return CT_YXBANDED;
+ }
+ return -1;
+}
+
+int
+SetClipRects(GCPtr pGC, int xOrigin, int yOrigin, int nrects,
+ xRectangle *prects, int ordering)
+{
+ int newct, size;
+ xRectangle *prectsNew;
+
+ newct = VerifyRectOrder(nrects, prects, ordering);
+ if (newct < 0)
+ return(BadMatch);
+ size = nrects * sizeof(xRectangle);
+ prectsNew = malloc(size);
+ if (!prectsNew && size)
+ return BadAlloc;
+
+ pGC->serialNumber |= GC_CHANGE_SERIAL_BIT;
+ pGC->clipOrg.x = xOrigin;
+ pGC->stateChanges |= GCClipXOrigin;
+
+ pGC->clipOrg.y = yOrigin;
+ pGC->stateChanges |= GCClipYOrigin;
+
+ if (size)
+ memmove((char *)prectsNew, (char *)prects, size);
+ (*pGC->funcs->ChangeClip)(pGC, newct, (pointer)prectsNew, nrects);
+ if (pGC->funcs->ChangeGC)
+ (*pGC->funcs->ChangeGC) (pGC, GCClipXOrigin|GCClipYOrigin|GCClipMask);
+ return Success;
+}
+
+
+/*
+ sets reasonable defaults
+ if we can get a pre-allocated one, use it and mark it as used.
+ if we can't, create one out of whole cloth (The Velveteen GC -- if
+ you use it often enough it will become real.)
+*/
+GCPtr
+GetScratchGC(unsigned depth, ScreenPtr pScreen)
+{
+ int i;
+ GCPtr pGC;
+
+ for (i=0; i<=pScreen->numDepths; i++)
+ if ( pScreen->GCperDepth[i]->depth == depth &&
+ !(pScreen->rgf & (1L << (i+1)))
+ )
+ {
+ pScreen->rgf |= (1L << (i+1));
+ pGC = (pScreen->GCperDepth[i]);
+
+ pGC->alu = GXcopy;
+ pGC->planemask = ~0;
+ pGC->serialNumber = 0;
+ pGC->fgPixel = 0;
+ pGC->bgPixel = 1;
+ pGC->lineWidth = 0;
+ pGC->lineStyle = LineSolid;
+ pGC->capStyle = CapButt;
+ pGC->joinStyle = JoinMiter;
+ pGC->fillStyle = FillSolid;
+ pGC->fillRule = EvenOddRule;
+ pGC->arcMode = ArcChord;
+ pGC->patOrg.x = 0;
+ pGC->patOrg.y = 0;
+ pGC->subWindowMode = ClipByChildren;
+ pGC->graphicsExposures = FALSE;
+ pGC->clipOrg.x = 0;
+ pGC->clipOrg.y = 0;
+ if (pGC->clientClipType != CT_NONE)
+ (*pGC->funcs->ChangeClip) (pGC, CT_NONE, NULL, 0);
+ pGC->stateChanges = GCAllBits;
+ return pGC;
+ }
+ /* if we make it this far, need to roll our own */
+ pGC = CreateScratchGC(pScreen, depth);
+ if (pGC)
+ pGC->graphicsExposures = FALSE;
+ return pGC;
+}
+
+/*
+ if the gc to free is in the table of pre-existing ones,
+mark it as available.
+ if not, free it for real
+*/
+void
+FreeScratchGC(GCPtr pGC)
+{
+ ScreenPtr pScreen = pGC->pScreen;
+ int i;
+
+ for (i=0; i<=pScreen->numDepths; i++)
+ {
+ if ( pScreen->GCperDepth[i] == pGC)
+ {
+ pScreen->rgf &= ~(1L << (i+1));
+ return;
+ }
+ }
+ (void)FreeGC(pGC, (GContext)0);
+}
diff --git a/xorg-server/dix/inpututils.c b/xorg-server/dix/inpututils.c index 55c27e80f..d2d36bd95 100644 --- a/xorg-server/dix/inpututils.c +++ b/xorg-server/dix/inpututils.c @@ -88,7 +88,6 @@ do_butmap_change(DeviceIntPtr dev, CARD8 *map, int len, ClientPtr client) if (!XIShouldNotify(clients[i], dev))
continue;
- core_mn.u.u.sequenceNumber = clients[i]->sequence;
WriteEventsToClient(clients[i], 1, &core_mn);
}
diff --git a/xorg-server/dix/resource.c b/xorg-server/dix/resource.c index 00b3368a0..1d33c9aad 100644 --- a/xorg-server/dix/resource.c +++ b/xorg-server/dix/resource.c @@ -183,7 +183,54 @@ RESTYPE lastResourceType; static RESTYPE lastResourceClass;
RESTYPE TypeMask;
-static DeleteType *DeleteFuncs = (DeleteType *)NULL;
+struct ResourceType {
+ DeleteType deleteFunc;
+ int errorValue;
+};
+
+static struct ResourceType *resourceTypes;
+static const struct ResourceType predefTypes[] = {
+ [RT_NONE & (RC_LASTPREDEF - 1)] = {
+ .deleteFunc = (DeleteType)NoopDDA,
+ .errorValue = BadValue,
+ },
+ [RT_WINDOW & (RC_LASTPREDEF - 1)] = {
+ .deleteFunc = DeleteWindow,
+ .errorValue = BadWindow,
+ },
+ [RT_PIXMAP & (RC_LASTPREDEF - 1)] = {
+ .deleteFunc = dixDestroyPixmap,
+ .errorValue = BadPixmap,
+ },
+ [RT_GC & (RC_LASTPREDEF - 1)] = {
+ .deleteFunc = FreeGC,
+ .errorValue = BadGC,
+ },
+ [RT_FONT & (RC_LASTPREDEF - 1)] = {
+ .deleteFunc = CloseFont,
+ .errorValue = BadFont,
+ },
+ [RT_CURSOR & (RC_LASTPREDEF - 1)] = {
+ .deleteFunc = FreeCursor,
+ .errorValue = BadCursor,
+ },
+ [RT_COLORMAP & (RC_LASTPREDEF - 1)] = {
+ .deleteFunc = FreeColormap,
+ .errorValue = BadColor,
+ },
+ [RT_CMAPENTRY & (RC_LASTPREDEF - 1)] = {
+ .deleteFunc = FreeClientPixels,
+ .errorValue = BadColor,
+ },
+ [RT_OTHERCLIENT & (RC_LASTPREDEF - 1)] = {
+ .deleteFunc = OtherClientGone,
+ .errorValue = BadValue,
+ },
+ [RT_PASSIVEGRAB & (RC_LASTPREDEF - 1)] = {
+ .deleteFunc = DeletePassiveGrab,
+ .errorValue = BadValue,
+ },
+};
CallbackListPtr ResourceStateCallback;
@@ -200,20 +247,20 @@ RESTYPE CreateNewResourceType(DeleteType deleteFunc, char *name)
{
RESTYPE next = lastResourceType + 1;
- DeleteType *funcs;
+ struct ResourceType *types;
if (next & lastResourceClass)
return 0;
- funcs = (DeleteType *)realloc(DeleteFuncs,
- (next + 1) * sizeof(DeleteType));
- if (!funcs)
+ types = realloc(resourceTypes, (next + 1) * sizeof(*resourceTypes));
+ if (!types)
return 0;
if (!dixRegisterPrivateOffset(next, -1))
return 0;
lastResourceType = next;
- DeleteFuncs = funcs;
- DeleteFuncs[next] = deleteFunc;
+ resourceTypes = types;
+ resourceTypes[next].deleteFunc = deleteFunc;
+ resourceTypes[next].errorValue = BadValue;
/* Called even if name is NULL, to remove any previous entry */
RegisterResourceName(next, name);
@@ -221,6 +268,12 @@ CreateNewResourceType(DeleteType deleteFunc, char *name) return next;
}
+void
+SetResourceTypeErrorValue(RESTYPE type, int errorValue)
+{
+ resourceTypes[type & TypeMask].errorValue = errorValue;
+}
+
RESTYPE
CreateNewResourceClass(void)
{
@@ -251,21 +304,11 @@ InitClientResources(ClientPtr client) lastResourceType = RT_LASTPREDEF;
lastResourceClass = RC_LASTPREDEF;
TypeMask = RC_LASTPREDEF - 1;
- if (DeleteFuncs)
- free(DeleteFuncs);
- DeleteFuncs = malloc((lastResourceType + 1) * sizeof(DeleteType));
- if (!DeleteFuncs)
+ free(resourceTypes);
+ resourceTypes = malloc(sizeof(predefTypes));
+ if (!resourceTypes)
return FALSE;
- DeleteFuncs[RT_NONE & TypeMask] = (DeleteType)NoopDDA;
- DeleteFuncs[RT_WINDOW & TypeMask] = DeleteWindow;
- DeleteFuncs[RT_PIXMAP & TypeMask] = dixDestroyPixmap;
- DeleteFuncs[RT_GC & TypeMask] = FreeGC;
- DeleteFuncs[RT_FONT & TypeMask] = CloseFont;
- DeleteFuncs[RT_CURSOR & TypeMask] = FreeCursor;
- DeleteFuncs[RT_COLORMAP & TypeMask] = FreeColormap;
- DeleteFuncs[RT_CMAPENTRY & TypeMask] = FreeClientPixels;
- DeleteFuncs[RT_OTHERCLIENT & TypeMask] = OtherClientGone;
- DeleteFuncs[RT_PASSIVEGRAB & TypeMask] = DeletePassiveGrab;
+ memcpy(resourceTypes, predefTypes, sizeof(predefTypes));
}
clientTable[i = client->index].resources =
malloc(INITBUCKETS*sizeof(ResourcePtr));
@@ -462,7 +505,7 @@ AddResource(XID id, RESTYPE type, pointer value) res = malloc(sizeof(ResourceRec));
if (!res)
{
- (*DeleteFuncs[type & TypeMask])(value, id);
+ (*resourceTypes[type & TypeMask].deleteFunc)(value, id);
return FALSE;
}
res->next = *head;
@@ -557,7 +600,7 @@ FreeResource(XID id, RESTYPE skipDeleteFuncType) CallResourceStateCallback(ResourceStateFreeing, res);
if (rtype != skipDeleteFuncType)
- (*DeleteFuncs[rtype & TypeMask])(res->value, res->id);
+ (*resourceTypes[rtype & TypeMask].deleteFunc)(res->value, res->id);
free(res);
if (*eltptr != elements)
prev = head; /* prev may no longer be valid */
@@ -594,7 +637,7 @@ FreeResourceByType(XID id, RESTYPE type, Bool skipFree) CallResourceStateCallback(ResourceStateFreeing, res);
if (!skipFree)
- (*DeleteFuncs[type & TypeMask])(res->value, res->id);
+ (*resourceTypes[type & TypeMask].deleteFunc)(res->value, res->id);
free(res);
break;
}
@@ -761,7 +804,7 @@ FreeClientNeverRetainResources(ClientPtr client) CallResourceStateCallback(ResourceStateFreeing, this);
elements = *eltptr;
- (*DeleteFuncs[rtype & TypeMask])(this->value, this->id);
+ (*resourceTypes[rtype & TypeMask].deleteFunc)(this->value, this->id);
free(this);
if (*eltptr != elements)
prev = &resources[j]; /* prev may no longer be valid */
@@ -815,7 +858,7 @@ FreeClientResources(ClientPtr client) CallResourceStateCallback(ResourceStateFreeing, this);
- (*DeleteFuncs[rtype & TypeMask])(this->value, this->id);
+ (*resourceTypes[rtype & TypeMask].deleteFunc)(this->value, this->id);
free(this);
}
}
@@ -873,6 +916,8 @@ dixLookupResourceByType(pointer *result, XID id, RESTYPE rtype, ResourcePtr res = NULL;
*result = NULL;
+ if ((rtype & TypeMask) > lastResourceType)
+ return BadImplementation;
if ((cid < MAXCLIENTS) && clientTable[cid].buckets) {
res = clientTable[cid].resources[Hash(cid, id)];
@@ -882,12 +927,14 @@ dixLookupResourceByType(pointer *result, XID id, RESTYPE rtype, break;
}
if (!res)
- return BadValue;
+ return resourceTypes[rtype & TypeMask].errorValue;
if (client) {
client->errorValue = id;
cid = XaceHook(XACE_RESOURCE_ACCESS, client, id, res->type,
res->value, RT_NONE, NULL, mode);
+ if (cid == BadValue)
+ return resourceTypes[rtype & TypeMask].errorValue;
if (cid != Success)
return cid;
}
diff --git a/xorg-server/dix/selection.c b/xorg-server/dix/selection.c index 947fc8d18..8763a2d5a 100644 --- a/xorg-server/dix/selection.c +++ b/xorg-server/dix/selection.c @@ -189,8 +189,7 @@ ProcSetSelectionOwner(ClientPtr client) event.u.selectionClear.time = time.milliseconds;
event.u.selectionClear.window = pSel->window;
event.u.selectionClear.atom = pSel->selection;
- TryClientEvents(pSel->client, NULL, &event, 1, NoEventMask,
- NoEventMask /* CantBeFiltered */, NullGrab);
+ WriteEventsToClient(pSel->client, 1, &event);
}
}
else if (rc == BadMatch)
@@ -296,9 +295,11 @@ ProcConvertSelection(ClientPtr client) event.u.selectionRequest.selection = stuff->selection;
event.u.selectionRequest.target = stuff->target;
event.u.selectionRequest.property = stuff->property;
- if (TryClientEvents(pSel->client, NULL, &event, 1, NoEventMask,
- NoEventMask /* CantBeFiltered */, NullGrab))
+ if (pSel->client && pSel->client != serverClient && !pSel->client->clientGone)
+ {
+ WriteEventsToClient(pSel->client, 1, &event);
return Success;
+ }
}
event.u.u.type = SelectionNotify;
@@ -307,7 +308,6 @@ ProcConvertSelection(ClientPtr client) event.u.selectionNotify.selection = stuff->selection;
event.u.selectionNotify.target = stuff->target;
event.u.selectionNotify.property = None;
- TryClientEvents(client, NULL, &event, 1, NoEventMask,
- NoEventMask /* CantBeFiltered */, NullGrab);
+ WriteEventsToClient(client, 1, &event);
return Success;
}
diff --git a/xorg-server/dix/window.c b/xorg-server/dix/window.c index 6a12c9d05..5109885e9 100644 --- a/xorg-server/dix/window.c +++ b/xorg-server/dix/window.c @@ -1056,7 +1056,7 @@ ChangeWindowAttributes(WindowPtr pWin, Mask vmask, XID *vlist, ClientPtr client) }
else
{
- error = (rc == BadValue) ? BadPixmap : rc;
+ error = rc;
client->errorValue = pixID;
goto PatchUp;
}
@@ -1116,7 +1116,7 @@ ChangeWindowAttributes(WindowPtr pWin, Mask vmask, XID *vlist, ClientPtr client) }
else
{
- error = (rc == BadValue) ? BadPixmap : rc;
+ error = rc;
client->errorValue = pixID;
goto PatchUp;
}
@@ -1264,7 +1264,7 @@ ChangeWindowAttributes(WindowPtr pWin, Mask vmask, XID *vlist, ClientPtr client) client, DixUseAccess);
if (rc != Success)
{
- error = (rc == BadValue) ? BadColor : rc;
+ error = rc;
client->errorValue = cmap;
goto PatchUp;
}
@@ -1340,7 +1340,7 @@ ChangeWindowAttributes(WindowPtr pWin, Mask vmask, XID *vlist, ClientPtr client) RT_CURSOR, client, DixUseAccess);
if (rc != Success)
{
- error = (rc == BadValue) ? BadCursor : rc;
+ error = rc;
client->errorValue = cursorID;
goto PatchUp;
}
|