aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/dix/dispatch.c
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/dix/dispatch.c')
-rw-r--r--xorg-server/dix/dispatch.c579
1 files changed, 454 insertions, 125 deletions
diff --git a/xorg-server/dix/dispatch.c b/xorg-server/dix/dispatch.c
index 7e16589da..414bd0404 100644
--- a/xorg-server/dix/dispatch.c
+++ b/xorg-server/dix/dispatch.c
@@ -107,6 +107,7 @@ Equipment Corporation.
#ifdef HAVE_DIX_CONFIG_H
#include <dix-config.h>
+#include <version-config.h>
#endif
#ifdef PANORAMIX_DEBUG
@@ -130,19 +131,11 @@ int ProcInitialConnection();
#include "dispatch.h"
#include "swaprep.h"
#include "swapreq.h"
-#ifdef PANORAMIX
-#include "panoramiX.h"
-#include "panoramiXsrv.h"
-#endif
#include "privates.h"
#include "xace.h"
-#ifdef XKB
-#ifndef XKB_IN_SERVER
-#define XKB_IN_SERVER
-#endif
#include "inputstr.h"
-#include <xkbsrv.h>
-#endif
+#include "xkbsrv.h"
+#include "site.h"
#ifdef XSERVER_DTRACE
#include "registry.h"
@@ -159,7 +152,9 @@ typedef const char *string;
#define BITCLEAR(buf, i) MASKWORD(buf, i) &= ~BITMASK(i)
#define GETBIT(buf, i) (MASKWORD(buf, i) & BITMASK(i))
-extern xConnSetupPrefix connSetupPrefix;
+xConnSetupPrefix connSetupPrefix;
+
+PaddingInfo PixmapWidthPaddingInfo[33];
static ClientPtr grabClient;
#define GrabNone 0
@@ -167,9 +162,9 @@ static ClientPtr grabClient;
#define GrabKickout 2
static int grabState = GrabNone;
static long grabWaiters[mskcnt];
-_X_EXPORT CallbackListPtr ServerGrabCallback = NULL;
+CallbackListPtr ServerGrabCallback = NULL;
HWEventQueuePtr checkForInput[2];
-extern int connBlockScreenStart;
+int connBlockScreenStart;
static void KillAllClients(void);
@@ -177,15 +172,15 @@ static int nextFreeClientID; /* always MIN free client ID */
static int nClients; /* number of authorized clients */
-_X_EXPORT CallbackListPtr ClientStateCallback;
+CallbackListPtr ClientStateCallback;
/* dispatchException & isItTimeToYield must be declared volatile since they
* are modified by signal handlers - otherwise optimizer may assume it doesn't
* need to actually check value in memory when used and may miss changes from
* signal handlers.
*/
-_X_EXPORT volatile char dispatchException = 0;
-_X_EXPORT volatile char isItTimeToYield;
+volatile char dispatchException = 0;
+volatile char isItTimeToYield;
/* Various of the DIX function interfaces were not designed to allow
* the client->errorValue to be set on BadValue and other errors.
@@ -204,7 +199,7 @@ SetInputCheck(HWEventQueuePtr c0, HWEventQueuePtr c1)
checkForInput[1] = c1;
}
-_X_EXPORT void
+void
UpdateCurrentTime(void)
{
TimeStamp systime;
@@ -223,7 +218,7 @@ UpdateCurrentTime(void)
}
/* Like UpdateCurrentTime, but can't call ProcessInputEvents */
-_X_EXPORT void
+void
UpdateCurrentTimeIf(void)
{
TimeStamp systime;
@@ -242,12 +237,12 @@ UpdateCurrentTimeIf(void)
#define SMART_SCHEDULE_DEFAULT_INTERVAL 20 /* ms */
#define SMART_SCHEDULE_MAX_SLICE 200 /* ms */
-Bool SmartScheduleDisable = FALSE;
-long SmartScheduleSlice = SMART_SCHEDULE_DEFAULT_INTERVAL;
-long SmartScheduleInterval = SMART_SCHEDULE_DEFAULT_INTERVAL;
-long SmartScheduleMaxSlice = SMART_SCHEDULE_MAX_SLICE;
-long SmartScheduleTime;
-int SmartScheduleLatencyLimited = 0;
+Bool SmartScheduleDisable = FALSE;
+long SmartScheduleSlice = SMART_SCHEDULE_DEFAULT_INTERVAL;
+long SmartScheduleInterval = SMART_SCHEDULE_DEFAULT_INTERVAL;
+long SmartScheduleMaxSlice = SMART_SCHEDULE_MAX_SLICE;
+long SmartScheduleTime;
+int SmartScheduleLatencyLimited = 0;
static ClientPtr SmartLastClient;
static int SmartLastIndex[SMART_MAX_PRIORITY-SMART_MIN_PRIORITY+1];
@@ -370,7 +365,7 @@ Dispatch(void)
nextFreeClientID = 1;
nClients = 0;
- clientReady = (int *) xalloc(sizeof(int) * MaxClients);
+ clientReady = xalloc(sizeof(int) * MaxClients);
if (!clientReady)
return;
@@ -437,12 +432,6 @@ Dispatch(void)
}
client->sequence++;
-#ifdef DEBUG
- if (client->requestLogIndex == MAX_REQUEST_LOG)
- client->requestLogIndex = 0;
- client->requestLog[client->requestLogIndex] = MAJOROP;
- client->requestLogIndex++;
-#endif
#ifdef XSERVER_DTRACE
XSERVER_REQUEST_START(LookupMajorName(MAJOROP), MAJOROP,
((xReq *)client->requestBuffer)->length,
@@ -490,7 +479,167 @@ Dispatch(void)
#undef MAJOROP
-_X_EXPORT int
+static int VendorRelease = VENDOR_RELEASE;
+static char *VendorString = VENDOR_NAME;
+
+static const int padlength[4] = {0, 3, 2, 1};
+
+void
+SetVendorRelease(int release)
+{
+ VendorRelease = release;
+}
+
+void
+SetVendorString(char *string)
+{
+ VendorString = string;
+}
+
+Bool
+CreateConnectionBlock(void)
+{
+ xConnSetup setup;
+ xWindowRoot root;
+ xDepth depth;
+ xVisualType visual;
+ xPixmapFormat format;
+ unsigned long vid;
+ int i, j, k,
+ lenofblock,
+ sizesofar = 0;
+ char *pBuf;
+
+
+ memset(&setup, 0, sizeof(xConnSetup));
+ /* Leave off the ridBase and ridMask, these must be sent with
+ connection */
+
+ setup.release = VendorRelease;
+ /*
+ * per-server image and bitmap parameters are defined in Xmd.h
+ */
+ setup.imageByteOrder = screenInfo.imageByteOrder;
+
+ setup.bitmapScanlineUnit = screenInfo.bitmapScanlineUnit;
+ setup.bitmapScanlinePad = screenInfo.bitmapScanlinePad;
+
+ setup.bitmapBitOrder = screenInfo.bitmapBitOrder;
+ setup.motionBufferSize = NumMotionEvents();
+ setup.numRoots = screenInfo.numScreens;
+ setup.nbytesVendor = strlen(VendorString);
+ setup.numFormats = screenInfo.numPixmapFormats;
+ setup.maxRequestSize = MAX_REQUEST_SIZE;
+ QueryMinMaxKeyCodes(&setup.minKeyCode, &setup.maxKeyCode);
+
+ lenofblock = sizeof(xConnSetup) +
+ pad_to_int32(setup.nbytesVendor) +
+ (setup.numFormats * sizeof(xPixmapFormat)) +
+ (setup.numRoots * sizeof(xWindowRoot));
+ ConnectionInfo = xalloc(lenofblock);
+ if (!ConnectionInfo)
+ return FALSE;
+
+ memmove(ConnectionInfo, (char *)&setup, sizeof(xConnSetup));
+ sizesofar = sizeof(xConnSetup);
+ pBuf = ConnectionInfo + sizeof(xConnSetup);
+
+ memmove(pBuf, VendorString, (int)setup.nbytesVendor);
+ sizesofar += setup.nbytesVendor;
+ pBuf += setup.nbytesVendor;
+ i = padlength[setup.nbytesVendor & 3];
+ sizesofar += i;
+ while (--i >= 0)
+ *pBuf++ = 0;
+
+ memset(&format, 0, sizeof(xPixmapFormat));
+ for (i=0; i<screenInfo.numPixmapFormats; i++)
+ {
+ format.depth = screenInfo.formats[i].depth;
+ format.bitsPerPixel = screenInfo.formats[i].bitsPerPixel;
+ format.scanLinePad = screenInfo.formats[i].scanlinePad;
+ memmove(pBuf, (char *)&format, sizeof(xPixmapFormat));
+ pBuf += sizeof(xPixmapFormat);
+ sizesofar += sizeof(xPixmapFormat);
+ }
+
+ connBlockScreenStart = sizesofar;
+ memset(&depth, 0, sizeof(xDepth));
+ memset(&visual, 0, sizeof(xVisualType));
+ for (i=0; i<screenInfo.numScreens; i++)
+ {
+ ScreenPtr pScreen;
+ DepthPtr pDepth;
+ VisualPtr pVisual;
+
+ pScreen = screenInfo.screens[i];
+ root.windowId = WindowTable[i]->drawable.id;
+ root.defaultColormap = pScreen->defColormap;
+ root.whitePixel = pScreen->whitePixel;
+ root.blackPixel = pScreen->blackPixel;
+ root.currentInputMask = 0; /* filled in when sent */
+ root.pixWidth = pScreen->width;
+ root.pixHeight = pScreen->height;
+ root.mmWidth = pScreen->mmWidth;
+ root.mmHeight = pScreen->mmHeight;
+ root.minInstalledMaps = pScreen->minInstalledCmaps;
+ root.maxInstalledMaps = pScreen->maxInstalledCmaps;
+ root.rootVisualID = pScreen->rootVisual;
+ root.backingStore = pScreen->backingStoreSupport;
+ root.saveUnders = FALSE;
+ root.rootDepth = pScreen->rootDepth;
+ root.nDepths = pScreen->numDepths;
+ memmove(pBuf, (char *)&root, sizeof(xWindowRoot));
+ sizesofar += sizeof(xWindowRoot);
+ pBuf += sizeof(xWindowRoot);
+
+ pDepth = pScreen->allowedDepths;
+ for(j = 0; j < pScreen->numDepths; j++, pDepth++)
+ {
+ lenofblock += sizeof(xDepth) +
+ (pDepth->numVids * sizeof(xVisualType));
+ pBuf = (char *)xrealloc(ConnectionInfo, lenofblock);
+ if (!pBuf)
+ {
+ xfree(ConnectionInfo);
+ return FALSE;
+ }
+ ConnectionInfo = pBuf;
+ pBuf += sizesofar;
+ depth.depth = pDepth->depth;
+ depth.nVisuals = pDepth->numVids;
+ memmove(pBuf, (char *)&depth, sizeof(xDepth));
+ pBuf += sizeof(xDepth);
+ sizesofar += sizeof(xDepth);
+ for(k = 0; k < pDepth->numVids; k++)
+ {
+ vid = pDepth->vids[k];
+ for (pVisual = pScreen->visuals;
+ pVisual->vid != vid;
+ pVisual++)
+ ;
+ visual.visualID = vid;
+ visual.class = pVisual->class;
+ visual.bitsPerRGB = pVisual->bitsPerRGBValue;
+ visual.colormapEntries = pVisual->ColormapEntries;
+ visual.redMask = pVisual->redMask;
+ visual.greenMask = pVisual->greenMask;
+ visual.blueMask = pVisual->blueMask;
+ memmove(pBuf, (char *)&visual, sizeof(xVisualType));
+ pBuf += sizeof(xVisualType);
+ sizesofar += sizeof(xVisualType);
+ }
+ }
+ }
+ connSetupPrefix.success = xTrue;
+ connSetupPrefix.length = lenofblock/4;
+ connSetupPrefix.majorVersion = X_PROTOCOL;
+ connSetupPrefix.minorVersion = X_PROTOCOL_REVISION;
+ return TRUE;
+}
+
+
+int
ProcBadRequest(ClientPtr client)
{
return (BadRequest);
@@ -509,7 +658,7 @@ ProcCreateWindow(ClientPtr client)
rc = dixLookupWindow(&pParent, stuff->parent, client, DixAddAccess);
if (rc != Success)
return rc;
- len = client->req_len - (sizeof(xCreateWindowReq) >> 2);
+ len = client->req_len - bytes_to_int32(sizeof(xCreateWindowReq));
if (Ones(stuff->mask) != len)
return BadLength;
if (!stuff->width || !stuff->height)
@@ -552,7 +701,7 @@ ProcChangeWindowAttributes(ClientPtr client)
rc = dixLookupWindow(&pWin, stuff->window, client, access_mode);
if (rc != Success)
return rc;
- len = client->req_len - (sizeof(xChangeWindowAttributesReq) >> 2);
+ len = client->req_len - bytes_to_int32(sizeof(xChangeWindowAttributesReq));
if (len != Ones(stuff->valueMask))
return BadLength;
result = ChangeWindowAttributes(pWin,
@@ -577,6 +726,7 @@ ProcGetWindowAttributes(ClientPtr client)
rc = dixLookupWindow(&pWin, stuff->id, client, DixGetAttrAccess);
if (rc != Success)
return rc;
+ memset(&wa, 0, sizeof(xGetWindowAttributesReply));
GetWindowAttributes(pWin, client, &wa);
WriteReplyToClient(client, sizeof(xGetWindowAttributesReply), &wa);
return(client->noClientException);
@@ -755,7 +905,7 @@ ProcConfigureWindow(ClientPtr client)
DixManageAccess|DixSetAttrAccess);
if (rc != Success)
return rc;
- len = client->req_len - (sizeof(xConfigureWindowReq) >> 2);
+ len = client->req_len - bytes_to_int32(sizeof(xConfigureWindowReq));
if (Ones((Mask)stuff->mask) != len)
return BadLength;
result = ConfigureWindow(pWin, (Mask)stuff->mask, (XID *) &stuff[1],
@@ -838,6 +988,7 @@ ProcGetGeometry(ClientPtr client)
xGetGeometryReply rep;
int status;
+ memset(&rep, 0, sizeof(xGetGeometryReply));
if ((status = GetGeometry(client, &rep)) != Success)
return status;
@@ -859,6 +1010,7 @@ ProcQueryTree(ClientPtr client)
rc = dixLookupWindow(&pWin, stuff->id, client, DixListAccess);
if (rc != Success)
return rc;
+ memset(&reply, 0, sizeof(xQueryTreeReply));
reply.type = X_Reply;
reply.root = WindowTable[pWin->drawable.pScreen->myNum]->drawable.id;
reply.sequenceNumber = client->sequence;
@@ -873,7 +1025,7 @@ ProcQueryTree(ClientPtr client)
{
int curChild = 0;
- childIDs = (Window *) xalloc(numChildren * sizeof(Window));
+ childIDs = xalloc(numChildren * sizeof(Window));
if (!childIDs)
return BadAlloc;
for (pChild = pWin->lastChild; pChild != pHead; pChild = pChild->prevSib)
@@ -881,7 +1033,7 @@ ProcQueryTree(ClientPtr client)
}
reply.nChildren = numChildren;
- reply.length = (numChildren * sizeof(Window)) >> 2;
+ reply.length = bytes_to_int32(numChildren * sizeof(Window));
WriteReplyToClient(client, sizeof(xQueryTreeReply), &reply);
if (numChildren)
@@ -912,6 +1064,7 @@ ProcInternAtom(ClientPtr client)
if (atom != BAD_RESOURCE)
{
xInternAtomReply reply;
+ memset(&reply, 0, sizeof(xInternAtomReply));
reply.type = X_Reply;
reply.length = 0;
reply.sequenceNumber = client->sequence;
@@ -926,7 +1079,7 @@ ProcInternAtom(ClientPtr client)
int
ProcGetAtomName(ClientPtr client)
{
- char *str;
+ const char *str;
xGetAtomNameReply reply;
int len;
REQUEST(xResourceReq);
@@ -935,8 +1088,9 @@ ProcGetAtomName(ClientPtr client)
if ( (str = NameForAtom(stuff->id)) )
{
len = strlen(str);
+ memset(&reply, 0, sizeof(xGetAtomNameReply));
reply.type = X_Reply;
- reply.length = (len + 3) >> 2;
+ reply.length = bytes_to_int32(len);
reply.sequenceNumber = client->sequence;
reply.nameLength = len;
WriteReplyToClient(client, sizeof(xGetAtomNameReply), &reply);
@@ -1031,6 +1185,7 @@ ProcTranslateCoords(ClientPtr client)
rc = dixLookupWindow(&pDst, stuff->dstWid, client, DixGetAttrAccess);
if (rc != Success)
return rc;
+ memset(&rep, 0, sizeof(xTranslateCoordsReply));
rep.type = X_Reply;
rep.length = 0;
rep.sequenceNumber = client->sequence;
@@ -1111,12 +1266,13 @@ int
ProcCloseFont(ClientPtr client)
{
FontPtr pFont;
+ int rc;
REQUEST(xResourceReq);
REQUEST_SIZE_MATCH(xResourceReq);
- pFont = (FontPtr)SecurityLookupIDByType(client, stuff->id, RT_FONT,
- DixDestroyAccess);
- if ( pFont != (FontPtr)NULL) /* id was valid */
+ rc = dixLookupResourceByType((pointer *)&pFont, stuff->id, RT_FONT,
+ client, DixDestroyAccess);
+ if (rc == Success)
{
FreeResource(stuff->id, RT_NONE);
return(client->noClientException);
@@ -1124,7 +1280,7 @@ ProcCloseFont(ClientPtr client)
else
{
client->errorValue = stuff->id;
- return (BadFont);
+ return (rc == BadValue) ? BadFont : rc;
}
}
@@ -1167,14 +1323,14 @@ ProcQueryFont(ClientPtr client)
rlength = sizeof(xQueryFontReply) +
FONTINFONPROPS(FONTCHARSET(pFont)) * sizeof(xFontProp) +
nprotoxcistructs * sizeof(xCharInfo);
- reply = (xQueryFontReply *)xalloc(rlength);
+ reply = xcalloc(1, rlength);
if(!reply)
{
return(BadAlloc);
}
reply->type = X_Reply;
- reply->length = (rlength - sizeof(xGenericReply)) >> 2;
+ reply->length = bytes_to_int32(rlength - sizeof(xGenericReply));
reply->sequenceNumber = client->sequence;
QueryFont( pFont, reply, nprotoxcistructs);
@@ -1208,7 +1364,7 @@ ProcQueryTextExtents(ClientPtr client)
if (rc != Success)
return (rc == BadValue) ? BadFont: rc;
- length = client->req_len - (sizeof(xQueryTextExtentsReq) >> 2);
+ length = client->req_len - bytes_to_int32(sizeof(xQueryTextExtentsReq));
length = length << 1;
if (stuff->oddLength)
{
@@ -1376,7 +1532,7 @@ ProcCreateGC(ClientPtr client)
if (rc != Success)
return rc;
- len = client->req_len - (sizeof(xCreateGCReq) >> 2);
+ len = client->req_len - bytes_to_int32(sizeof(xCreateGCReq));
if (len != Ones(stuff->mask))
return BadLength;
pGC = (GC *)CreateGC(pDraw, stuff->mask, (XID *) &stuff[1], &error,
@@ -1401,7 +1557,7 @@ ProcChangeGC(ClientPtr client)
if (result != Success)
return result;
- len = client->req_len - (sizeof(xChangeGCReq) >> 2);
+ len = client->req_len - bytes_to_int32(sizeof(xChangeGCReq));
if (len != Ones(stuff->mask))
return BadLength;
@@ -1651,7 +1807,7 @@ ProcPolyPoint(ClientPtr client)
return BadValue;
}
VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
- npoint = ((client->req_len << 2) - sizeof(xPolyPointReq)) >> 2;
+ npoint = bytes_to_int32((client->req_len << 2) - sizeof(xPolyPointReq));
if (npoint)
(*pGC->ops->PolyPoint)(pDraw, pGC, stuff->coordMode, npoint,
(xPoint *) &stuff[1]);
@@ -1674,7 +1830,7 @@ ProcPolyLine(ClientPtr client)
return BadValue;
}
VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
- npoint = ((client->req_len << 2) - sizeof(xPolyLineReq)) >> 2;
+ npoint = bytes_to_int32((client->req_len << 2) - sizeof(xPolyLineReq));
if (npoint > 1)
(*pGC->ops->Polylines)(pDraw, pGC, stuff->coordMode, npoint,
(DDXPointPtr) &stuff[1]);
@@ -1762,7 +1918,7 @@ ProcFillPoly(ClientPtr client)
}
VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
- things = ((client->req_len << 2) - sizeof(xFillPolyReq)) >> 2;
+ things = bytes_to_int32((client->req_len << 2) - sizeof(xFillPolyReq));
if (things)
(*pGC->ops->FillPolygon) (pDraw, pGC, stuff->shape,
stuff->coordMode, things,
@@ -1906,8 +2062,8 @@ ProcPutImage(ClientPtr client)
tmpImage = (char *)&stuff[1];
lengthProto = length;
- if (((((lengthProto * stuff->height) + (unsigned)3) >> 2) +
- (sizeof(xPutImageReq) >> 2)) != client->req_len)
+ if ((bytes_to_int32(lengthProto * stuff->height) +
+ bytes_to_int32(sizeof(xPutImageReq))) != client->req_len)
return BadLength;
ReformatImage (tmpImage, lengthProto * stuff->height,
@@ -1926,9 +2082,11 @@ DoGetImage(ClientPtr client, int format, Drawable drawable,
int x, int y, int width, int height,
Mask planemask, xGetImageReply **im_return)
{
- DrawablePtr pDraw;
+ DrawablePtr pDraw, pBoundingDraw;
int nlines, linesPerBuf, rc;
- int linesDone;
+ int linesDone;
+ /* coordinates relative to the bounding drawable */
+ int relx, rely;
long widthBytesLine, length;
Mask plane = 0;
char *pBuf;
@@ -1944,35 +2102,60 @@ DoGetImage(ClientPtr client, int format, Drawable drawable,
if (rc != Success)
return rc;
+ memset(&xgi, 0, sizeof(xGetImageReply));
+
+ relx = x;
+ rely = y;
+
if(pDraw->type == DRAWABLE_WINDOW)
{
- if( /* check for being viewable */
- !((WindowPtr) pDraw)->realized ||
- /* check for being on screen */
- pDraw->x + x < 0 ||
- pDraw->x + x + width > pDraw->pScreen->width ||
- pDraw->y + y < 0 ||
- pDraw->y + y + height > pDraw->pScreen->height ||
- /* check for being inside of border */
- x < - wBorderWidth((WindowPtr)pDraw) ||
- x + width > wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width ||
- y < -wBorderWidth((WindowPtr)pDraw) ||
- y + height > wBorderWidth ((WindowPtr)pDraw) + (int)pDraw->height
- )
- return(BadMatch);
- xgi.visual = wVisual (((WindowPtr) pDraw));
+ WindowPtr pWin = (WindowPtr)pDraw;
+
+ /* "If the drawable is a window, the window must be viewable ... or a
+ * BadMatch error results" */
+ if (!pWin->viewable)
+ return BadMatch;
+
+ relx += pDraw->x;
+ rely += pDraw->y;
+
+ if (pDraw->pScreen->GetWindowPixmap) {
+ PixmapPtr pPix = (*pDraw->pScreen->GetWindowPixmap) (pWin);
+
+ pBoundingDraw = &pPix->drawable;
+#ifdef COMPOSITE
+ relx -= pPix->screen_x;
+ rely -= pPix->screen_y;
+#endif
+ }
+ else
+ {
+ pBoundingDraw = (DrawablePtr)WindowTable[pDraw->pScreen->myNum];
+ }
+
+ xgi.visual = wVisual (pWin);
}
else
{
- if(x < 0 ||
- x+width > (int)pDraw->width ||
- y < 0 ||
- y+height > (int)pDraw->height
- )
- return(BadMatch);
+ pBoundingDraw = pDraw;
xgi.visual = None;
}
+ /* "If the drawable is a pixmap, the given rectangle must be wholly
+ * contained within the pixmap, or a BadMatch error results. If the
+ * drawable is a window [...] it must be the case that if there were no
+ * inferiors or overlapping windows, the specified rectangle of the window
+ * would be fully visible on the screen and wholly contained within the
+ * outside edges of the window, or a BadMatch error results."
+ *
+ * We relax the window case slightly to mean that the rectangle must exist
+ * within the bounds of the window's backing pixmap. In particular, this
+ * means that a GetImage request may succeed or fail with BadMatch depending
+ * on whether any of its ancestor windows are redirected. */
+ if(relx < 0 || relx + width > (int)pBoundingDraw->width ||
+ rely < 0 || rely + height > (int)pBoundingDraw->height)
+ return BadMatch;
+
xgi.type = X_Reply;
xgi.sequenceNumber = client->sequence;
xgi.depth = pDraw->depth;
@@ -1995,7 +2178,7 @@ DoGetImage(ClientPtr client, int format, Drawable drawable,
xgi.length = length;
if (im_return) {
- pBuf = (char *)xalloc(sz_xGetImageReply + length);
+ pBuf = xcalloc(1, sz_xGetImageReply + length);
if (!pBuf)
return (BadAlloc);
if (widthBytesLine == 0)
@@ -2006,7 +2189,7 @@ DoGetImage(ClientPtr client, int format, Drawable drawable,
*(xGetImageReply *)pBuf = xgi;
pBuf += sz_xGetImageReply;
} else {
- xgi.length = (xgi.length + 3) >> 2;
+ xgi.length = bytes_to_int32(xgi.length);
if (widthBytesLine == 0 || height == 0)
linesPerBuf = 0;
else if (widthBytesLine >= IMAGE_BUFSIZE)
@@ -2033,7 +2216,7 @@ DoGetImage(ClientPtr client, int format, Drawable drawable,
length += widthBytesLine;
}
}
- if(!(pBuf = (char *) xalloc(length)))
+ if(!(pBuf = xcalloc(1, length)))
return (BadAlloc);
WriteReplyToClient(client, sizeof (xGetImageReply), &xgi);
}
@@ -2405,8 +2588,7 @@ ProcListInstalledColormaps(ClientPtr client)
if (rc != Success)
goto out;
- preply = (xListInstalledColormapsReply *)
- xalloc(sizeof(xListInstalledColormapsReply) +
+ preply = xalloc(sizeof(xListInstalledColormapsReply) +
pWin->drawable.pScreen->maxInstalledCmaps *
sizeof(Colormap));
if(!preply)
@@ -2550,7 +2732,7 @@ ProcAllocColorCells (ClientPtr client)
}
nmasks = stuff->planes;
length = ((long)npixels + (long)nmasks) * sizeof(Pixel);
- ppixels = (Pixel *)xalloc(length);
+ ppixels = xalloc(length);
if(!ppixels)
return(BadAlloc);
pmasks = ppixels + npixels;
@@ -2569,7 +2751,7 @@ ProcAllocColorCells (ClientPtr client)
#endif
{
accr.type = X_Reply;
- accr.length = length >> 2;
+ accr.length = bytes_to_int32(length);
accr.sequenceNumber = client->sequence;
accr.nPixels = npixels;
accr.nMasks = nmasks;
@@ -2619,7 +2801,7 @@ ProcAllocColorPlanes(ClientPtr client)
acpr.sequenceNumber = client->sequence;
acpr.nPixels = npixels;
length = (long)npixels * sizeof(Pixel);
- ppixels = (Pixel *)xalloc(length);
+ ppixels = xalloc(length);
if(!ppixels)
return(BadAlloc);
if( (rc = AllocColorPlanes(client->index, pcmp, npixels,
@@ -2633,7 +2815,7 @@ ProcAllocColorPlanes(ClientPtr client)
else
return rc;
}
- acpr.length = length >> 2;
+ acpr.length = bytes_to_int32(length);
#ifdef PANORAMIX
if (noPanoramiXExtension || !pcmp->pScreen->myNum)
#endif
@@ -2668,7 +2850,7 @@ ProcFreeColors(ClientPtr client)
if(pcmp->flags & AllAllocated)
return(BadAccess);
- count = ((client->req_len << 2)- sizeof(xFreeColorsReq)) >> 2;
+ count = bytes_to_int32((client->req_len << 2) - sizeof(xFreeColorsReq));
rc = FreeColors(pcmp, client->index, count,
(Pixel *)&stuff[1], (Pixel)stuff->planeMask);
if (client->noClientException != Success)
@@ -2771,8 +2953,8 @@ ProcQueryColors(ClientPtr client)
xrgb *prgbs;
xQueryColorsReply qcr;
- count = ((client->req_len << 2) - sizeof(xQueryColorsReq)) >> 2;
- prgbs = (xrgb *)xalloc(count * sizeof(xrgb));
+ count = bytes_to_int32((client->req_len << 2) - sizeof(xQueryColorsReq));
+ prgbs = xcalloc(1, count * sizeof(xrgb));
if(!prgbs && count)
return(BadAlloc);
if( (rc = QueryColors(pcmp, count, (Pixel *)&stuff[1], prgbs)) )
@@ -2786,8 +2968,9 @@ ProcQueryColors(ClientPtr client)
return rc;
}
}
+ memset(&qcr, 0, sizeof(xQueryColorsReply));
qcr.type = X_Reply;
- qcr.length = (count * sizeof(xrgb)) >> 2;
+ qcr.length = bytes_to_int32(count * sizeof(xrgb));
qcr.sequenceNumber = client->sequence;
qcr.nColors = count;
WriteReplyToClient(client, sizeof(xQueryColorsReply), &qcr);
@@ -3013,6 +3196,7 @@ ProcQueryBestSize (ClientPtr client)
return rc;
(* pScreen->QueryBestSize)(stuff->class, &stuff->width,
&stuff->height, pScreen);
+ memset(&reply, 0, sizeof(xQueryBestSizeReply));
reply.type = X_Reply;
reply.length = 0;
reply.sequenceNumber = client->sequence;
@@ -3156,7 +3340,7 @@ ProcListHosts(ClientPtr client)
reply.type = X_Reply;
reply.sequenceNumber = client->sequence;
reply.nHosts = nHosts;
- reply.length = len >> 2;
+ reply.length = bytes_to_int32(len);
WriteReplyToClient(client, sizeof(xListHostsReply), &reply);
if (nHosts)
{
@@ -3289,7 +3473,7 @@ ProcGetFontPath(ClientPtr client)
reply.type = X_Reply;
reply.sequenceNumber = client->sequence;
- reply.length = (stringLens + numpaths + 3) >> 2;
+ reply.length = bytes_to_int32(stringLens + numpaths);
reply.nPaths = numpaths;
WriteReplyToClient(client, sizeof(xGetFontPathReply), &reply);
@@ -3480,41 +3664,16 @@ KillAllClients(void)
void InitClient(ClientPtr client, int i, pointer ospriv)
{
+ memset(client, 0, sizeof(*client));
client->index = i;
- client->sequence = 0;
client->clientAsMask = ((Mask)i) << CLIENTOFFSET;
- client->clientGone = FALSE;
client->closeDownMode = i ? DestroyAll : RetainPermanent;
- client->numSaved = 0;
- client->saveSet = (SaveSetElt *)NULL;
- client->noClientException = Success;
-#ifdef DEBUG
- client->requestLogIndex = 0;
-#endif
client->requestVector = InitialVector;
client->osPrivate = ospriv;
- client->swapped = FALSE;
- client->big_requests = FALSE;
- client->priority = 0;
- client->clientState = ClientStateInitial;
- client->devPrivates = NULL;
-#ifdef XKB
- if (!noXkbExtension) {
- client->xkbClientFlags = 0;
- client->mapNotifyMask = 0;
- client->newKeyboardNotifyMask = 0;
- client->vMinor = client->vMajor = 0;
- QueryMinMaxKeyCodes(&client->minKC,&client->maxKC);
- }
-#endif
- client->replyBytesRemaining = 0;
- client->fontResFunc = NULL;
- client->smart_priority = 0;
+ QueryMinMaxKeyCodes(&client->minKC,&client->maxKC);
client->smart_start_tick = SmartScheduleTime;
client->smart_stop_tick = SmartScheduleTime;
client->smart_check_tick = SmartScheduleTime;
-
- client->clientPtr = NULL;
}
/************************
@@ -3533,7 +3692,7 @@ ClientPtr NextAvailableClient(pointer ospriv)
i = nextFreeClientID;
if (i == MAXCLIENTS)
return (ClientPtr)NULL;
- clients[i] = client = (ClientPtr)xalloc(sizeof(ClientRec));
+ clients[i] = client = xalloc(sizeof(ClientRec));
if (!client)
return (ClientPtr)NULL;
InitClient(client, i, ospriv);
@@ -3543,7 +3702,7 @@ ClientPtr NextAvailableClient(pointer ospriv)
return (ClientPtr)NULL;
}
data.reqType = 1;
- data.length = (sz_xReq + sz_xConnClientPrefix) >> 2;
+ data.length = bytes_to_int32(sz_xReq + sz_xConnClientPrefix);
if (!InsertFakeRequest(client, (char *)&data, sz_xReq))
{
FreeClientResources(client);
@@ -3583,8 +3742,8 @@ ProcInitialConnection(ClientPtr client)
SwapConnClientPrefix(prefix);
}
stuff->reqType = 2;
- stuff->length += ((prefix->nbytesAuthProto + (unsigned)3) >> 2) +
- ((prefix->nbytesAuthString + (unsigned)3) >> 2);
+ stuff->length += bytes_to_int32(prefix->nbytesAuthProto) +
+ bytes_to_int32(prefix->nbytesAuthString);
if (client->swapped)
{
swaps(&stuff->length, whichbyte);
@@ -3608,7 +3767,7 @@ SendConnSetup(ClientPtr client, char *reason)
csp.success = xFalse;
csp.lengthReason = strlen(reason);
- csp.length = (csp.lengthReason + (unsigned)3) >> 2;
+ csp.length = bytes_to_int32(csp.lengthReason);
csp.majorVersion = X_PROTOCOL;
csp.minorVersion = X_PROTOCOL_REVISION;
if (client->swapped)
@@ -3699,7 +3858,7 @@ ProcEstablishConnection(ClientPtr client)
prefix = (xConnClientPrefix *)((char *)stuff + sz_xReq);
auth_proto = (char *)prefix + sz_xConnClientPrefix;
- auth_string = auth_proto + ((prefix->nbytesAuthProto + 3) & ~3);
+ auth_string = auth_proto + pad_to_int32(prefix->nbytesAuthProto);
if ((prefix->majorVersion != X_PROTOCOL) ||
(prefix->minorVersion != X_PROTOCOL_REVISION))
reason = "Protocol version mismatch";
@@ -3724,12 +3883,13 @@ ProcEstablishConnection(ClientPtr client)
return(client->noClientException);
}
-_X_EXPORT void
+void
SendErrorToClient(ClientPtr client, unsigned majorCode, unsigned minorCode,
XID resId, int errorCode)
{
xError rep;
+ memset(&rep, 0, sizeof(xError));
rep.type = X_Error;
rep.sequenceNumber = client->sequence;
rep.errorCode = errorCode;
@@ -3745,3 +3905,172 @@ MarkClientException(ClientPtr client)
{
client->noClientException = -1;
}
+
+/*
+ * This array encodes the answer to the question "what is the log base 2
+ * of the number of pixels that fit in a scanline pad unit?"
+ * Note that ~0 is an invalid entry (mostly for the benefit of the reader).
+ */
+static int answer[6][4] = {
+ /* pad pad pad pad*/
+ /* 8 16 32 64 */
+
+ { 3, 4, 5 , 6 }, /* 1 bit per pixel */
+ { 1, 2, 3 , 4 }, /* 4 bits per pixel */
+ { 0, 1, 2 , 3 }, /* 8 bits per pixel */
+ { ~0, 0, 1 , 2 }, /* 16 bits per pixel */
+ { ~0, ~0, 0 , 1 }, /* 24 bits per pixel */
+ { ~0, ~0, 0 , 1 } /* 32 bits per pixel */
+};
+
+/*
+ * This array gives the answer to the question "what is the first index for
+ * the answer array above given the number of bits per pixel?"
+ * Note that ~0 is an invalid entry (mostly for the benefit of the reader).
+ */
+static int indexForBitsPerPixel[ 33 ] = {
+ ~0, 0, ~0, ~0, /* 1 bit per pixel */
+ 1, ~0, ~0, ~0, /* 4 bits per pixel */
+ 2, ~0, ~0, ~0, /* 8 bits per pixel */
+ ~0,~0, ~0, ~0,
+ 3, ~0, ~0, ~0, /* 16 bits per pixel */
+ ~0,~0, ~0, ~0,
+ 4, ~0, ~0, ~0, /* 24 bits per pixel */
+ ~0,~0, ~0, ~0,
+ 5 /* 32 bits per pixel */
+};
+
+/*
+ * This array gives the bytesperPixel value for cases where the number
+ * of bits per pixel is a multiple of 8 but not a power of 2.
+ */
+static int answerBytesPerPixel[ 33 ] = {
+ ~0, 0, ~0, ~0, /* 1 bit per pixel */
+ 0, ~0, ~0, ~0, /* 4 bits per pixel */
+ 0, ~0, ~0, ~0, /* 8 bits per pixel */
+ ~0,~0, ~0, ~0,
+ 0, ~0, ~0, ~0, /* 16 bits per pixel */
+ ~0,~0, ~0, ~0,
+ 3, ~0, ~0, ~0, /* 24 bits per pixel */
+ ~0,~0, ~0, ~0,
+ 0 /* 32 bits per pixel */
+};
+
+/*
+ * This array gives the answer to the question "what is the second index for
+ * the answer array above given the number of bits per scanline pad unit?"
+ * Note that ~0 is an invalid entry (mostly for the benefit of the reader).
+ */
+static int indexForScanlinePad[ 65 ] = {
+ ~0, ~0, ~0, ~0,
+ ~0, ~0, ~0, ~0,
+ 0, ~0, ~0, ~0, /* 8 bits per scanline pad unit */
+ ~0, ~0, ~0, ~0,
+ 1, ~0, ~0, ~0, /* 16 bits per scanline pad unit */
+ ~0, ~0, ~0, ~0,
+ ~0, ~0, ~0, ~0,
+ ~0, ~0, ~0, ~0,
+ 2, ~0, ~0, ~0, /* 32 bits per scanline pad unit */
+ ~0, ~0, ~0, ~0,
+ ~0, ~0, ~0, ~0,
+ ~0, ~0, ~0, ~0,
+ ~0, ~0, ~0, ~0,
+ ~0, ~0, ~0, ~0,
+ ~0, ~0, ~0, ~0,
+ ~0, ~0, ~0, ~0,
+ 3 /* 64 bits per scanline pad unit */
+};
+
+/*
+ grow the array of screenRecs if necessary.
+ call the device-supplied initialization procedure
+with its screen number, a pointer to its ScreenRec, argc, and argv.
+ return the number of successfully installed screens.
+
+*/
+
+int
+AddScreen(
+ Bool (* pfnInit)(
+ int /*index*/,
+ ScreenPtr /*pScreen*/,
+ int /*argc*/,
+ char ** /*argv*/
+ ),
+ int argc,
+ char **argv)
+{
+
+ int i;
+ int scanlinepad, format, depth, bitsPerPixel, j, k;
+ ScreenPtr pScreen;
+
+ i = screenInfo.numScreens;
+ if (i == MAXSCREENS)
+ return -1;
+
+ pScreen = (ScreenPtr) xcalloc(1, sizeof(ScreenRec));
+ if (!pScreen)
+ return -1;
+
+ pScreen->devPrivates = NULL;
+ pScreen->myNum = i;
+ pScreen->totalPixmapSize = BitmapBytePad(sizeof(PixmapRec)*8);
+ pScreen->ClipNotify = 0; /* for R4 ddx compatibility */
+ pScreen->CreateScreenResources = 0;
+
+ /*
+ * This loop gets run once for every Screen that gets added,
+ * but thats ok. If the ddx layer initializes the formats
+ * one at a time calling AddScreen() after each, then each
+ * iteration will make it a little more accurate. Worst case
+ * we do this loop N * numPixmapFormats where N is # of screens.
+ * Anyway, this must be called after InitOutput and before the
+ * screen init routine is called.
+ */
+ for (format=0; format<screenInfo.numPixmapFormats; format++)
+ {
+ depth = screenInfo.formats[format].depth;
+ bitsPerPixel = screenInfo.formats[format].bitsPerPixel;
+ scanlinepad = screenInfo.formats[format].scanlinePad;
+ j = indexForBitsPerPixel[ bitsPerPixel ];
+ k = indexForScanlinePad[ scanlinepad ];
+ PixmapWidthPaddingInfo[ depth ].padPixelsLog2 = answer[j][k];
+ PixmapWidthPaddingInfo[ depth ].padRoundUp =
+ (scanlinepad/bitsPerPixel) - 1;
+ j = indexForBitsPerPixel[ 8 ]; /* bits per byte */
+ PixmapWidthPaddingInfo[ depth ].padBytesLog2 = answer[j][k];
+ PixmapWidthPaddingInfo[ depth ].bitsPerPixel = bitsPerPixel;
+ if (answerBytesPerPixel[bitsPerPixel])
+ {
+ PixmapWidthPaddingInfo[ depth ].notPower2 = 1;
+ PixmapWidthPaddingInfo[ depth ].bytesPerPixel =
+ answerBytesPerPixel[bitsPerPixel];
+ }
+ else
+ {
+ PixmapWidthPaddingInfo[ depth ].notPower2 = 0;
+ }
+ }
+
+ /* This is where screen specific stuff gets initialized. Load the
+ screen structure, call the hardware, whatever.
+ This is also where the default colormap should be allocated and
+ also pixel values for blackPixel, whitePixel, and the cursor
+ Note that InitScreen is NOT allowed to modify argc, argv, or
+ any of the strings pointed to by argv. They may be passed to
+ multiple screens.
+ */
+ pScreen->rgf = ~0L; /* there are no scratch GCs yet*/
+ WindowTable[i] = NullWindow;
+ screenInfo.screens[i] = pScreen;
+ screenInfo.numScreens++;
+ if (!(*pfnInit)(i, pScreen, argc, argv))
+ {
+ dixFreePrivates(pScreen->devPrivates);
+ xfree(pScreen);
+ screenInfo.numScreens--;
+ return -1;
+ }
+ return i;
+}