コード例 #1
0
ファイル: ephyrglxext.c プロジェクト: balagopalraj/clearlinux
static int
ephyrGLXMakeCurrentReal(__GLXclientState * a_cl, GLXDrawable write,
                        GLXDrawable read, GLXContextTag ctx,
                        GLXContextTag old_ctx, Bool a_do_swap)
{
    int res = BadImplementation;
    xGLXMakeCurrentReply reply;
    DrawablePtr drawableR = NULL, drawableW = NULL;
    GLXContextTag new_ctx = 0;

    EPHYR_LOG("enter\n");
    res = dixLookupDrawable(&drawableW, write, a_cl->client, 0, DixReadAccess);
    EPHYR_RETURN_VAL_IF_FAIL(drawableW, BadValue);
    EPHYR_RETURN_VAL_IF_FAIL(drawableW->pScreen, BadValue);
    EPHYR_LOG("screen nummber requested:%d\n", drawableW->pScreen->myNum);

    if (read != write) {
        res = dixLookupDrawable(&drawableR, read, a_cl->client, 0,
                                DixReadAccess);
        EPHYR_RETURN_VAL_IF_FAIL(drawableR, BadValue);
        EPHYR_RETURN_VAL_IF_FAIL(drawableR->pScreen, BadValue);
    }
    else {
        drawableR = drawableW;
    }

    if (!ephyrHostGLXMakeCurrent(hostx_get_window(drawableW->pScreen->myNum),
                                 hostx_get_window(drawableR->pScreen->myNum),
                                 ctx, old_ctx, (int *) &new_ctx)) {
        EPHYR_LOG_ERROR("ephyrHostGLXMakeCurrent() failed\n");
        goto out;
    }
    reply = (xGLXMakeCurrentReply) {
        .type = X_Reply,
        .sequenceNumber = a_cl->client->sequence,
        .length = 0,
        .contextTag = new_ctx
    };
    if (a_do_swap) {
        __GLX_DECLARE_SWAP_VARIABLES;
        __GLX_SWAP_SHORT(&reply.sequenceNumber);
        __GLX_SWAP_INT(&reply.length);
        __GLX_SWAP_INT(&reply.contextTag);
    }
    WriteToClient(a_cl->client, sz_xGLXMakeCurrentReply, &reply);

    res = Success;
 out:
    EPHYR_LOG("leave\n");
    return res;
}

int
ephyrGLXMakeCurrent(__GLXclientState * a_cl, GLbyte * a_pc)
{
    xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) a_pc;
    return ephyrGLXMakeCurrentReal(a_cl, req->drawable, req->drawable,
                                   req->context, req->oldContextTag, FALSE);
}
コード例 #2
0
ファイル: xf86dri.c プロジェクト: mcr/xorg-xvnc4
static int
ProcXF86DRIDestroyDrawable(
    register ClientPtr client
)
{
    REQUEST(xXF86DRIDestroyDrawableReq);
    DrawablePtr pDrawable;
    REQUEST_SIZE_MATCH(xXF86DRIDestroyDrawableReq);
    int rc;

    if (stuff->screen >= screenInfo.numScreens) {
	client->errorValue = stuff->screen;
	return BadValue;
    }

    rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
			   DixReadAccess);
    if (rc != Success)
	return rc;

    if (!DRIDestroyDrawable(screenInfo.screens[stuff->screen], client,
			    pDrawable)) {
	return BadValue;
    }

    return (client->noClientException);
}
コード例 #3
0
ファイル: xf86dri.c プロジェクト: mcr/xorg-xvnc4
static int
ProcXF86DRICreateDrawable(
    ClientPtr client
)
{
    xXF86DRICreateDrawableReply	rep;
    DrawablePtr pDrawable;
    int rc;

    REQUEST(xXF86DRICreateDrawableReq);
    REQUEST_SIZE_MATCH(xXF86DRICreateDrawableReq);
    if (stuff->screen >= screenInfo.numScreens) {
	client->errorValue = stuff->screen;
	return BadValue;
    }

    rep.type = X_Reply;
    rep.length = 0;
    rep.sequenceNumber = client->sequence;

    rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
			   DixReadAccess);
    if (rc != Success)
	return rc;

    if (!DRICreateDrawable(screenInfo.screens[stuff->screen], client,
			   pDrawable, (drm_drawable_t *)&rep.hHWDrawable)) {
	return BadValue;
    }

    WriteToClient(client, sizeof(xXF86DRICreateDrawableReply), (char *)&rep);
    return (client->noClientException);
}
コード例 #4
0
ファイル: dixutils.c プロジェクト: 4eremuxa/xserver
int
dixLookupWindow(WindowPtr *pWin, XID id, ClientPtr client, Mask access)
{
    int rc;
    rc = dixLookupDrawable((DrawablePtr*)pWin, id, client, M_WINDOW, access);
    return (rc == BadDrawable) ? BadWindow : rc;
}
コード例 #5
0
ファイル: xvdisp.c プロジェクト: aosm/X11server
static int
ProcXvStopVideo(ClientPtr client)
{
  int status, rc;
  DrawablePtr pDraw;
  XvPortPtr pPort;
  REQUEST(xvStopVideoReq);
  REQUEST_SIZE_MATCH(xvStopVideoReq);

  if(!(pPort = LOOKUP_PORT(stuff->port, client) ))
    {
      client->errorValue = stuff->port;
      return (_XvBadPort);
    }

  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
    {
      client->errorValue = stuff->port;
      return (status);
    }

  rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, DixWriteAccess);
  if (rc != Success)
    return rc;

  return XVCALL(diStopVideo)(client, pPort, pDraw);
}
コード例 #6
0
static int
proc_dri3_fd_from_fence(ClientPtr client)
{
    REQUEST(xDRI3FDFromFenceReq);
    xDRI3FDFromFenceReply rep = {
        .type = X_Reply,
        .nfd = 1,
        .sequenceNumber = client->sequence,
        .length = 0,
    };
    DrawablePtr drawable;
    int fd;
    int status;
    SyncFence *fence;

    REQUEST_SIZE_MATCH(xDRI3FDFromFenceReq);

    status = dixLookupDrawable(&drawable, stuff->drawable, client, M_ANY, DixGetAttrAccess);
    if (status != Success)
        return status;
    status = SyncVerifyFence(&fence, stuff->fence, client, DixWriteAccess);
    if (status != Success)
        return status;

    fd = SyncFDFromFence(client, drawable, fence);
    if (fd < 0)
        return BadMatch;

    if (client->swapped) {
        swaps(&rep.sequenceNumber);
        swapl(&rep.length);
    }
    if (WriteFdToClient(client, fd, FALSE) < 0)
        return BadAlloc;

    WriteToClient(client, sizeof(rep), &rep);

    return client->noClientException;
}

int (*proc_dri3_vector[DRI3NumberRequests]) (ClientPtr) = {
    proc_dri3_query_version,            /* 0 */
    proc_dri3_open,                     /* 1 */
    proc_dri3_pixmap_from_buffer,       /* 2 */
    proc_dri3_buffer_from_pixmap,       /* 3 */
    proc_dri3_fence_from_fd,            /* 4 */
    proc_dri3_fd_from_fence,            /* 5 */
};

int
proc_dri3_dispatch(ClientPtr client)
{
    REQUEST(xReq);
    if (!client->local)
        return BadMatch;
    if (stuff->data >= DRI3NumberRequests || !proc_dri3_vector[stuff->data])
        return BadRequest;
    return (*proc_dri3_vector[stuff->data]) (client);
}
コード例 #7
0
static void
nouveau_dri2_flip_event_handler(unsigned int frame, unsigned int tv_sec,
				unsigned int tv_usec, void *event_data)
{
	struct nouveau_dri2_vblank_state *flip = event_data;
	DrawablePtr draw;
	ScreenPtr screen;
	ScrnInfoPtr scrn;
	int status;

	status = dixLookupDrawable(&draw, flip->draw, serverClient,
				   M_ANY, DixWriteAccess);
	if (status != Success) {
		free(flip);
		return;
	}

	screen = draw->pScreen;
	scrn = xf86ScreenToScrn(screen);

	/* We assume our flips arrive in order, so we don't check the frame */
	switch (flip->action) {
	case SWAP:
		/* Check for too small vblank count of pageflip completion,
		 * taking wraparound into account. This usually means some
		 * defective kms pageflip completion, causing wrong (msc, ust)
		 * return values and possible visual corruption.
		 * Skip test for frame == 0, as this is a valid constant value
		 * reported by all Linux kernels at least up to Linux 3.0.
		 */
		if ((frame != 0) &&
		    (frame < flip->frame) && (flip->frame - frame < 5)) {
			xf86DrvMsg(scrn->scrnIndex, X_WARNING,
				   "%s: Pageflip has impossible msc %d < target_msc %d\n",
				   __func__, frame, flip->frame);
			/* All-Zero values signal failure of (msc, ust)
			 * timestamping to client.
			 */
			frame = tv_sec = tv_usec = 0;
		}

		DRI2SwapComplete(flip->client, draw, frame, tv_sec, tv_usec,
				 DRI2_FLIP_COMPLETE, flip->func,
				 flip->data);
		break;
	default:
		xf86DrvMsg(scrn->scrnIndex, X_WARNING,
			   "%s: unknown vblank event received\n", __func__);
		/* Unknown type */
		break;
	}

	free(flip);
}
コード例 #8
0
ファイル: deprecated.c プロジェクト: Agnarr/xserver
/* replaced by dixLookupDrawable */
pointer
SecurityLookupDrawable(XID id, ClientPtr client, Mask access_mode)
{
    DrawablePtr pDraw;
    int i = dixLookupDrawable(&pDraw, id, client, M_DRAWABLE, access_mode);
    static int warn = 1;
    if (warn > 0 && --warn)
	ErrorF("Warning: LookupDrawable()/SecurityLookupDrawable() "
	       "are deprecated.  Please convert your driver/module "
	       "to use dixLookupDrawable().\n");
    return (i == Success) ? pDraw : NULL;
}
コード例 #9
0
static int
ProcAppleDRICreatePixmap(ClientPtr client)
{
    REQUEST(xAppleDRICreatePixmapReq);
    DrawablePtr pDrawable;
    int rc;
    char path[PATH_MAX];
    xAppleDRICreatePixmapReply rep;
    int width, height, pitch, bpp;
    void *ptr;

    REQUEST_SIZE_MATCH(xAppleDRICreatePixmapReq);

    rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
                           DixReadAccess);

    if(rc != Success)
        return rc;
    
    if(!DRICreatePixmap(screenInfo.screens[stuff->screen],
                              (Drawable)stuff->drawable,
                              pDrawable,
			      path, PATH_MAX)) {
        return BadValue;
    }

    if(!DRIGetPixmapData(pDrawable, &width, &height,
			 &pitch, &bpp, &ptr)) {
	return BadValue;
    } 
	
    rep.stringLength = strlen(path) + 1;
		
    /* No need for swapping, because this only runs if LocalClient is true. */
    rep.type = X_Reply;
    rep.length = sizeof(rep) + rep.stringLength;
    rep.sequenceNumber = client->sequence;
    rep.width = width;
    rep.height = height;
    rep.pitch = pitch;
    rep.bpp = bpp;
    rep.size = pitch * height;

    if(sizeof(rep) != sz_xAppleDRICreatePixmapReply)
	ErrorF("error sizeof(rep) is %zu\n", sizeof(rep)); 
    
    WriteReplyToClient(client, sizeof(rep), &rep);
    (void)WriteToClient(client, rep.stringLength, path);

    return Success;
}
コード例 #10
0
ファイル: dri2ext.c プロジェクト: aosm/X11server
static Bool
validDrawable(ClientPtr client, XID drawable, Mask access_mode,
	      DrawablePtr *pDrawable, int *status)
{
    *status = dixLookupDrawable(pDrawable, drawable, client,
				M_DRAWABLE_WINDOW | M_DRAWABLE_PIXMAP,
				access_mode);
    if (*status != Success) {
	client->errorValue = drawable;
	return FALSE;
    }

    return TRUE;
}
コード例 #11
0
ファイル: xvdisp.c プロジェクト: eriytt/xserver-xsdl
static int
ProcXvSelectVideoNotify(ClientPtr client)
{
  DrawablePtr pDraw;
  int rc;
  REQUEST(xvSelectVideoNotifyReq);
  REQUEST_SIZE_MATCH(xvSelectVideoNotifyReq);

  rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, DixReceiveAccess);
  if (rc != Success)
    return rc;

  return XvdiSelectVideoNotify(client, pDraw, stuff->onoff);
}
コード例 #12
0
ファイル: dixutils.c プロジェクト: timon37/xwayland
int
dixLookupWindow(WindowPtr *pWin, XID id, ClientPtr client, Mask access)
{
    int rc;
    rc = dixLookupDrawable((DrawablePtr*)pWin, id, client, M_WINDOW, access);
    /* dixLookupDrawable returns BadMatch iff id is a valid Drawable
       but is not a Window. Users of dixLookupWindow expect a BadWindow
       error in this case; they don't care that it's a valid non-Window XID */
    if (rc == BadMatch)
	rc = BadWindow;
    /* Similarly, users of dixLookupWindow don't want BadDrawable. */
    if (rc == BadDrawable)
	rc = BadWindow;
    return rc;
}
コード例 #13
0
ファイル: appledri.c プロジェクト: csulmone/X11
static int
ProcAppleDRICreateSurface(ClientPtr client)
{
    xAppleDRICreateSurfaceReply rep;
    DrawablePtr pDrawable;
    xp_surface_id sid;
    unsigned int key[2];
    int rc;

    REQUEST(xAppleDRICreateSurfaceReq);
    REQUEST_SIZE_MATCH(xAppleDRICreateSurfaceReq);
    rep.type = X_Reply;
    rep.length = 0;
    rep.sequenceNumber = client->sequence;

    rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
                           DixReadAccess);
    if (rc != Success)
        return rc;

    rep.key_0 = rep.key_1 = rep.uid = 0;

    if (!DRICreateSurface(screenInfo.screens[stuff->screen],
                          (Drawable)stuff->drawable, pDrawable,
                          stuff->client_id, &sid, key,
                          surface_notify,
                          x_cvt_uint_to_vptr(client->index))) {
        return BadValue;
    }

    rep.key_0 = key[0];
    rep.key_1 = key[1];
    rep.uid = sid;

    if (client->swapped) {
        swaps(&rep.sequenceNumber);
        swapl(&rep.length);
        swapl(&rep.key_0);
        swapl(&rep.key_1);
        swapl(&rep.uid);
    }

    WriteToClient(client, sizeof(xAppleDRICreateSurfaceReply), (char *)&rep);
    return Success;
}
コード例 #14
0
ファイル: appledri.c プロジェクト: csulmone/X11
static int
ProcAppleDRIDestroyPixmap(ClientPtr client)
{
    DrawablePtr pDrawable;
    int rc;
    REQUEST(xAppleDRIDestroyPixmapReq);
    REQUEST_SIZE_MATCH(xAppleDRIDestroyPixmapReq);

    rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
                           DixReadAccess);

    if (rc != Success)
        return rc;

    DRIDestroyPixmap(pDrawable);

    return Success;
}
コード例 #15
0
ファイル: ephyrglxext.c プロジェクト: 4eremuxa/xserver
static int
ephyrGLXMakeCurrentReal (__GLXclientState *a_cl, GLbyte *a_pc, Bool a_do_swap)
{
    int res=BadImplementation;
    xGLXMakeCurrentReq *req = (xGLXMakeCurrentReq *) a_pc;
    xGLXMakeCurrentReply reply ;
    DrawablePtr drawable=NULL;
    int rc=0;

    EPHYR_LOG ("enter\n") ;
    rc = dixLookupDrawable (&drawable,
                            req->drawable,
                            a_cl->client,
                            0,
                            DixReadAccess);
    EPHYR_RETURN_VAL_IF_FAIL (drawable, BadValue) ;
    EPHYR_RETURN_VAL_IF_FAIL (drawable->pScreen, BadValue) ;
    EPHYR_LOG ("screen nummber requested:%d\n",
               drawable->pScreen->myNum) ;

    memset (&reply, 0, sizeof (reply)) ;
    if (!ephyrHostGLXMakeCurrent (hostx_get_window (drawable->pScreen->myNum),
                                  req->context,
                                  req->oldContextTag,
                                  (int*)&reply.contextTag)) {
        EPHYR_LOG_ERROR ("ephyrHostGLXMakeCurrent() failed\n") ;
        goto out;
    }
    reply.length = 0;
    reply.type = X_Reply;
    reply.sequenceNumber = a_cl->client->sequence;
    if (a_do_swap) {
        __GLX_DECLARE_SWAP_VARIABLES;
        __GLX_SWAP_SHORT(&reply.sequenceNumber);
        __GLX_SWAP_INT(&reply.length);
        __GLX_SWAP_INT(&reply.contextTag);
    }
    WriteToClient(a_cl->client, sz_xGLXMakeCurrentReply, (char *)&reply);

    res = Success ;
out:
    EPHYR_LOG ("leave\n") ;
    return res ;
}
コード例 #16
0
void
vivante_dri2_vblank(int fd, unsigned frame, unsigned tv_sec, unsigned tv_usec,
	void *event)
{
	struct vivante_dri_wait *wait = event;
	DrawablePtr draw;

	if (!wait->drawable_id)
		goto out;

	if (dixLookupDrawable(&draw, wait->drawable_id, serverClient, M_ANY,
			      DixWriteAccess) != Success)
		goto out;

	switch (wait->type) {
	case DRI2_FLIP:
		if (can_exchange(draw, wait->front, wait->back) &&
		    vivante_dri2_ScheduleFlip(draw, wait))
			return;
		/* FALLTHROUGH */

	case DRI2_SWAP:
		vivante_dri2_blit(wait->client, draw, wait->front, wait->back,
				  frame, tv_sec, tv_usec,
				  wait->client ? wait->event_func : NULL,
				  wait->event_data);
		break;

	case DRI2_WAITMSC:
		if (wait->client)
			DRI2WaitMSCComplete(wait->client, draw, frame, tv_sec, tv_usec);
		break;

	default:
		xf86DrvMsg(xf86ScreenToScrn(draw->pScreen)->scrnIndex,
			   X_WARNING, "%s: unknown vblank event received\n",
			   __FUNCTION__);
		break;
	}

 out:
	del_wait_info(wait);
}
コード例 #17
0
ファイル: appledri.c プロジェクト: csulmone/X11
static int
ProcAppleDRIDestroySurface(register ClientPtr client)
{
    int rc;
    REQUEST(xAppleDRIDestroySurfaceReq);
    DrawablePtr pDrawable;
    REQUEST_SIZE_MATCH(xAppleDRIDestroySurfaceReq);

    rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
                           DixReadAccess);
    if (rc != Success)
        return rc;

    if (!DRIDestroySurface(screenInfo.screens[stuff->screen],
                           (Drawable)stuff->drawable,
                           pDrawable, NULL, NULL)) {
        return BadValue;
    }

    return Success;
}
コード例 #18
0
static void
nouveau_dri2_vblank_handler(void *priv, uint64_t name, uint64_t ust, uint32_t frame)
{
	struct dri2_vblank *event = priv;
	struct nouveau_dri2_vblank_state *s = event->s;
	uint32_t tv_sec  = ust / 1000000;
	uint32_t tv_usec = ust % 1000000;
	DrawablePtr draw;
	int ret;

	ret = dixLookupDrawable(&draw, s->draw, serverClient,
				M_ANY, DixWriteAccess);
	if (ret) {
		free(s);
		return;
	}

	switch (s->action) {
	case SWAP:
		nouveau_dri2_finish_swap(draw, frame, tv_sec, tv_usec, s);
#if DRI2INFOREC_VERSION >= 6
		/* Restore real swap limit on drawable, now that it is safe. */
		ScrnInfoPtr scrn = xf86ScreenToScrn(draw->pScreen);
		DRI2SwapLimit(draw, NVPTR(scrn)->swap_limit);
#endif
		break;

	case WAIT:
		DRI2WaitMSCComplete(s->client, draw, frame, tv_sec, tv_usec);
		free(s);
		break;

	case BLIT:
		DRI2SwapComplete(s->client, draw, frame, tv_sec, tv_usec,
				 DRI2_BLIT_COMPLETE, s->func, s->data);
		free(s);
		break;
	}
}
コード例 #19
0
ファイル: xselinux_ext.c プロジェクト: 4eremuxa/xserver
static int
ProcSELinuxGetDrawableContext(ClientPtr client)
{
    DrawablePtr pDraw;
    PrivateRec **privatePtr;
    SELinuxObjectRec *obj;
    int rc;

    REQUEST(SELinuxGetContextReq);
    REQUEST_SIZE_MATCH(SELinuxGetContextReq);

    rc = dixLookupDrawable(&pDraw, stuff->id, client, 0, DixGetAttrAccess);
    if (rc != Success)
	return rc;

    if (pDraw->type == DRAWABLE_PIXMAP)
	privatePtr = &((PixmapPtr)pDraw)->devPrivates;
    else
	privatePtr = &((WindowPtr)pDraw)->devPrivates;

    obj = dixLookupPrivate(privatePtr, objectKey);
    return SELinuxSendContextReply(client, obj->sid);
}
コード例 #20
0
ファイル: xvdisp.c プロジェクト: eriytt/xserver-xsdl
static int
ProcXvStopVideo(ClientPtr client)
{
  int status, rc;
  DrawablePtr pDraw;
  XvPortPtr pPort;
  REQUEST(xvStopVideoReq);
  REQUEST_SIZE_MATCH(xvStopVideoReq);

  VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);

  if ((status = _AllocatePort(stuff->port, pPort)) != Success)
    {
      client->errorValue = stuff->port;
      return status;
    }

  rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0, DixWriteAccess);
  if (rc != Success)
    return rc;

  return XvdiStopVideo(client, pPort, pDraw);
}
コード例 #21
0
static int
ProcDamageAdd (ClientPtr client)
{
    REQUEST(xDamageAddReq);
    DrawablePtr	    pDrawable;
    RegionPtr	    pRegion;
    int		    rc;

    REQUEST_SIZE_MATCH(xDamageAddReq);
    VERIFY_REGION(pRegion, stuff->region, client, DixWriteAccess);
    rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
			   DixWriteAccess);
    if (rc != Success)
	return rc;

    /* The region is relative to the drawable origin, so translate it out to
     * screen coordinates like damage expects.
     */
    RegionTranslate(pRegion, pDrawable->x, pDrawable->y);
    DamageDamageRegion(pDrawable, pRegion);
    RegionTranslate(pRegion, -pDrawable->x, -pDrawable->y);

    return Success;
}
コード例 #22
0
ファイル: shm.c プロジェクト: Agnarr/xserver
static int
ProcPanoramiXShmCreatePixmap(ClientPtr client)
{
    ScreenPtr pScreen = NULL;
    PixmapPtr pMap = NULL;
    DrawablePtr pDraw;
    DepthPtr pDepth;
    int i, j, result, rc;
    ShmDescPtr shmdesc;
    REQUEST(xShmCreatePixmapReq);
    unsigned int width, height, depth;
    unsigned long size;
    PanoramiXRes *newPix;

    REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
    client->errorValue = stuff->pid;
    if (!sharedPixmaps)
	return BadImplementation;
    LEGAL_NEW_RESOURCE(stuff->pid, client);
    rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY,
			   DixGetAttrAccess);
    if (rc != Success)
	return rc;

    VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);

    width = stuff->width;
    height = stuff->height;
    depth = stuff->depth;
    if (!width || !height || !depth)
    {
	client->errorValue = 0;
        return BadValue;
    }
    if (width > 32767 || height > 32767)
        return BadAlloc;

    if (stuff->depth != 1)
    {
        pDepth = pDraw->pScreen->allowedDepths;
        for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++)
	   if (pDepth->depth == stuff->depth)
               goto CreatePmap;
	client->errorValue = stuff->depth;
        return BadValue;
    }

CreatePmap:
    size = PixmapBytePad(width, depth) * height;
    if (sizeof(size) == 4 && BitsPerPixel(depth) > 8) {
        if (size < width * height)
            return BadAlloc;
    }
    /* thankfully, offset is unsigned */
    if (stuff->offset + size < size)
	return BadAlloc;

    VERIFY_SHMSIZE(shmdesc, stuff->offset, size, client);

    if(!(newPix = malloc(sizeof(PanoramiXRes))))
	return BadAlloc;

    newPix->type = XRT_PIXMAP;
    newPix->u.pix.shared = TRUE;
    newPix->info[0].id = stuff->pid;
    for(j = 1; j < PanoramiXNumScreens; j++)
	newPix->info[j].id = FakeClientID(client->index);

    result = Success;

    FOR_NSCREENS(j) {
	ShmScrPrivateRec *screen_priv;
	pScreen = screenInfo.screens[j];

	screen_priv = ShmGetScreenPriv(pScreen);
	pMap = (*screen_priv->shmFuncs->CreatePixmap)(pScreen,
				stuff->width, stuff->height, stuff->depth,
				shmdesc->addr + stuff->offset);

	if (pMap) {
	    dixSetPrivate(&pMap->devPrivates, shmPixmapPrivateKey, shmdesc);
            shmdesc->refcnt++;
	    pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
	    pMap->drawable.id = newPix->info[j].id;
	    if (!AddResource(newPix->info[j].id, RT_PIXMAP, (pointer)pMap)) {
		(*pScreen->DestroyPixmap)(pMap);
		result = BadAlloc;
		break;
	    }
	} else {
	   result = BadAlloc;
	   break;
	}
    }

    if(result == BadAlloc) {
	while(j--) {
	    (*pScreen->DestroyPixmap)(pMap);
	    FreeResource(newPix->info[j].id, RT_NONE);
	}
	free(newPix);
    } else 
	AddResource(stuff->pid, XRT_PIXMAP, newPix);

    return result;
}
コード例 #23
0
ファイル: shm.c プロジェクト: Agnarr/xserver
static int 
ProcPanoramiXShmGetImage(ClientPtr client)
{
    PanoramiXRes	*draw;
    DrawablePtr 	*drawables;
    DrawablePtr 	pDraw;
    xShmGetImageReply	xgi;
    ShmDescPtr		shmdesc;
    int         	i, x, y, w, h, format, rc;
    Mask		plane = 0, planemask;
    long		lenPer = 0, length, widthBytesLine;
    Bool		isRoot;

    REQUEST(xShmGetImageReq);

    REQUEST_SIZE_MATCH(xShmGetImageReq);

    if ((stuff->format != XYPixmap) && (stuff->format != ZPixmap)) {
	client->errorValue = stuff->format;
        return BadValue;
    }

    rc = dixLookupResourceByClass((pointer *)&draw, stuff->drawable,
				  XRC_DRAWABLE, client, DixWriteAccess);
    if (rc != Success)
	return (rc == BadValue) ? BadDrawable : rc;

    if (draw->type == XRT_PIXMAP)
	return ProcShmGetImage(client);

    rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0,
			   DixReadAccess);
    if (rc != Success)
	return rc;

    VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);

    x = stuff->x;
    y = stuff->y;
    w = stuff->width;
    h = stuff->height;
    format = stuff->format;
    planemask = stuff->planeMask;

    isRoot = (draw->type == XRT_WINDOW) && draw->u.win.root;

    if(isRoot) {
      if( /* check for being onscreen */
	x < 0 || x + w > PanoramiXPixWidth ||
	y < 0 || y + h > PanoramiXPixHeight )
	    return BadMatch;
    } else {
      if( /* check for being onscreen */
	screenInfo.screens[0]->x + pDraw->x + x < 0 ||
	screenInfo.screens[0]->x + pDraw->x + x + w > PanoramiXPixWidth ||
	screenInfo.screens[0]->y + pDraw->y + y < 0 ||
	screenInfo.screens[0]->y + pDraw->y + y + h > PanoramiXPixHeight ||
	 /* check for being inside of border */
       	x < - wBorderWidth((WindowPtr)pDraw) ||
	x + w > wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width ||
	y < -wBorderWidth((WindowPtr)pDraw) ||
	y + h > wBorderWidth ((WindowPtr)pDraw) + (int)pDraw->height)
	    return BadMatch;
    }

    drawables = calloc(PanoramiXNumScreens, sizeof(DrawablePtr));
    if(!drawables)
	return BadAlloc;

    drawables[0] = pDraw;
    for(i = 1; i < PanoramiXNumScreens; i++) {
	rc = dixLookupDrawable(drawables+i, draw->info[i].id, client, 0, 
			       DixReadAccess);
	if (rc != Success)
	{
	    free(drawables);
	    return rc;
	}
    }

    xgi.visual = wVisual(((WindowPtr)pDraw));
    xgi.type = X_Reply;
    xgi.length = 0;
    xgi.sequenceNumber = client->sequence;
    xgi.depth = pDraw->depth;

    if(format == ZPixmap) {
	widthBytesLine = PixmapBytePad(w, pDraw->depth);
	length = widthBytesLine * h;
    } else {
	widthBytesLine = PixmapBytePad(w, 1);
	lenPer = widthBytesLine * h;
	plane = ((Mask)1) << (pDraw->depth - 1);
	length = lenPer * Ones(planemask & (plane | (plane - 1)));
    }

    VERIFY_SHMSIZE(shmdesc, stuff->offset, length, client);
    xgi.size = length;

    if (length == 0) {/* nothing to do */ }
    else if (format == ZPixmap) {
	    XineramaGetImageData(drawables, x, y, w, h, format, planemask,
					shmdesc->addr + stuff->offset,
					widthBytesLine, isRoot);
    } else {

	length = stuff->offset;
        for (; plane; plane >>= 1) {
	    if (planemask & plane) {
		XineramaGetImageData(drawables, x, y, w, h, 
				     format, plane, shmdesc->addr + length,
				     widthBytesLine, isRoot);
		length += lenPer;
	    }
	}
    }
    free(drawables);
    
    if (client->swapped) {
	int n;
    	swaps(&xgi.sequenceNumber, n);
    	swapl(&xgi.length, n);
	swapl(&xgi.visual, n);
	swapl(&xgi.size, n);
    }
    WriteToClient(client, sizeof(xShmGetImageReply), (char *)&xgi);

    return Success;
}
コード例 #24
0
ファイル: shm.c プロジェクト: Agnarr/xserver
static int
ProcShmGetImage(ClientPtr client)
{
    DrawablePtr		pDraw;
    long		lenPer = 0, length;
    Mask		plane = 0;
    xShmGetImageReply	xgi;
    ShmDescPtr		shmdesc;
    int			n, rc;

    REQUEST(xShmGetImageReq);

    REQUEST_SIZE_MATCH(xShmGetImageReq);
    if ((stuff->format != XYPixmap) && (stuff->format != ZPixmap))
    {
	client->errorValue = stuff->format;
        return BadValue;
    }
    rc = dixLookupDrawable(&pDraw, stuff->drawable, client, 0,
			   DixReadAccess);
    if (rc != Success)
	return rc;
    VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
    if (pDraw->type == DRAWABLE_WINDOW)
    {
      if( /* check for being viewable */
	 !((WindowPtr) pDraw)->realized ||
	  /* check for being on screen */
         pDraw->x + stuff->x < 0 ||
         pDraw->x + stuff->x + (int)stuff->width > pDraw->pScreen->width ||
         pDraw->y + stuff->y < 0 ||
         pDraw->y + stuff->y + (int)stuff->height > pDraw->pScreen->height ||
          /* check for being inside of border */
         stuff->x < - wBorderWidth((WindowPtr)pDraw) ||
         stuff->x + (int)stuff->width >
		wBorderWidth((WindowPtr)pDraw) + (int)pDraw->width ||
         stuff->y < -wBorderWidth((WindowPtr)pDraw) ||
         stuff->y + (int)stuff->height >
		wBorderWidth((WindowPtr)pDraw) + (int)pDraw->height
        )
	    return BadMatch;
	xgi.visual = wVisual(((WindowPtr)pDraw));
    }
    else
    {
	if (stuff->x < 0 ||
	    stuff->x+(int)stuff->width > pDraw->width ||
	    stuff->y < 0 ||
	    stuff->y+(int)stuff->height > pDraw->height
	    )
	    return BadMatch;
	xgi.visual = None;
    }
    xgi.type = X_Reply;
    xgi.length = 0;
    xgi.sequenceNumber = client->sequence;
    xgi.depth = pDraw->depth;
    if(stuff->format == ZPixmap)
    {
	length = PixmapBytePad(stuff->width, pDraw->depth) * stuff->height;
    }
    else
    {
	lenPer = PixmapBytePad(stuff->width, 1) * stuff->height;
	plane = ((Mask)1) << (pDraw->depth - 1);
	/* only planes asked for */
	length = lenPer * Ones(stuff->planeMask & (plane | (plane - 1)));
    }

    VERIFY_SHMSIZE(shmdesc, stuff->offset, length, client);
    xgi.size = length;

    if (length == 0)
    {
	/* nothing to do */
    }
    else if (stuff->format == ZPixmap)
    {
	(*pDraw->pScreen->GetImage)(pDraw, stuff->x, stuff->y,
				    stuff->width, stuff->height,
				    stuff->format, stuff->planeMask,
				    shmdesc->addr + stuff->offset);
    }
    else
    {

	length = stuff->offset;
        for (; plane; plane >>= 1)
	{
	    if (stuff->planeMask & plane)
	    {
		(*pDraw->pScreen->GetImage)(pDraw,
					    stuff->x, stuff->y,
					    stuff->width, stuff->height,
					    stuff->format, plane,
					    shmdesc->addr + length);
		length += lenPer;
	    }
	}
    }

    if (client->swapped) {
	swaps(&xgi.sequenceNumber, n);
	swapl(&xgi.length, n);
	swapl(&xgi.visual, n);
	swapl(&xgi.size, n);
    }
    WriteToClient(client, sizeof(xShmGetImageReply), (char *)&xgi);

    return Success;
}
コード例 #25
0
ファイル: shm.c プロジェクト: Agnarr/xserver
static int
ProcShmCreatePixmap(ClientPtr client)
{
    PixmapPtr pMap;
    DrawablePtr pDraw;
    DepthPtr pDepth;
    int i, rc;
    ShmDescPtr shmdesc;
    ShmScrPrivateRec *screen_priv;
    REQUEST(xShmCreatePixmapReq);
    unsigned int width, height, depth;
    unsigned long size;

    REQUEST_SIZE_MATCH(xShmCreatePixmapReq);
    client->errorValue = stuff->pid;
    if (!sharedPixmaps)
	return BadImplementation;
    LEGAL_NEW_RESOURCE(stuff->pid, client);
    rc = dixLookupDrawable(&pDraw, stuff->drawable, client, M_ANY,
			   DixGetAttrAccess);
    if (rc != Success)
	return rc;

    VERIFY_SHMPTR(stuff->shmseg, stuff->offset, TRUE, shmdesc, client);
    
    width = stuff->width;
    height = stuff->height;
    depth = stuff->depth;
    if (!width || !height || !depth)
    {
	client->errorValue = 0;
        return BadValue;
    }
    if (width > 32767 || height > 32767)
	return BadAlloc;

    if (stuff->depth != 1)
    {
        pDepth = pDraw->pScreen->allowedDepths;
        for (i=0; i<pDraw->pScreen->numDepths; i++, pDepth++)
	   if (pDepth->depth == stuff->depth)
               goto CreatePmap;
	client->errorValue = stuff->depth;
        return BadValue;
    }

CreatePmap:
    size = PixmapBytePad(width, depth) * height;
    if (sizeof(size) == 4 && BitsPerPixel(depth) > 8) {
	if (size < width * height)
	    return BadAlloc;
    }
    /* thankfully, offset is unsigned */
    if (stuff->offset + size < size)
	return BadAlloc;

    VERIFY_SHMSIZE(shmdesc, stuff->offset, size, client);
    screen_priv = ShmGetScreenPriv(pDraw->pScreen);
    pMap = (*screen_priv->shmFuncs->CreatePixmap)(
			    pDraw->pScreen, stuff->width,
			    stuff->height, stuff->depth,
			    shmdesc->addr + stuff->offset);
    if (pMap)
    {
	rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pid, RT_PIXMAP,
		      pMap, RT_NONE, NULL, DixCreateAccess);
	if (rc != Success) {
	    pDraw->pScreen->DestroyPixmap(pMap);
	    return rc;
	}
	dixSetPrivate(&pMap->devPrivates, shmPixmapPrivateKey, shmdesc);
	shmdesc->refcnt++;
	pMap->drawable.serialNumber = NEXT_SERIAL_NUMBER;
	pMap->drawable.id = stuff->pid;
	if (AddResource(stuff->pid, RT_PIXMAP, (pointer)pMap))
	{
	    return Success;
	}
	pDraw->pScreen->DestroyPixmap(pMap);
    }
    return BadAlloc;
}
コード例 #26
0
static int
proc_dri3_query_version(ClientPtr client)
{
    REQUEST(xDRI3QueryVersionReq);
    xDRI3QueryVersionReply rep = {
        .type = X_Reply,
        .sequenceNumber = client->sequence,
        .length = 0,
        .majorVersion = SERVER_DRI3_MAJOR_VERSION,
        .minorVersion = SERVER_DRI3_MINOR_VERSION
    };

    REQUEST_SIZE_MATCH(xDRI3QueryVersionReq);
    (void) stuff;
    if (client->swapped) {
        swaps(&rep.sequenceNumber);
        swapl(&rep.length);
        swapl(&rep.majorVersion);
        swapl(&rep.minorVersion);
    }
    WriteToClient(client, sizeof(rep), &rep);
    return Success;
}

int
dri3_send_open_reply(ClientPtr client, int fd)
{
    xDRI3OpenReply rep = {
        .type = X_Reply,
        .nfd = 1,
        .sequenceNumber = client->sequence,
        .length = 0,
    };

    if (client->swapped) {
        swaps(&rep.sequenceNumber);
        swapl(&rep.length);
    }

    if (WriteFdToClient(client, fd, TRUE) < 0) {
        close(fd);
        return BadAlloc;
    }

    WriteToClient(client, sizeof (rep), &rep);

    return Success;
}

static int
proc_dri3_open(ClientPtr client)
{
    REQUEST(xDRI3OpenReq);
    RRProviderPtr provider;
    DrawablePtr drawable;
    ScreenPtr screen;
    int fd;
    int status;

    REQUEST_SIZE_MATCH(xDRI3OpenReq);

    status = dixLookupDrawable(&drawable, stuff->drawable, client, 0, DixReadAccess);
    if (status != Success)
        return status;

    if (stuff->provider == None)
        provider = NULL;
    else if (!RRProviderType) {
        return BadMatch;
    } else {
        VERIFY_RR_PROVIDER(stuff->provider, provider, DixReadAccess);
        if (drawable->pScreen != provider->pScreen)
            return BadMatch;
    }
    screen = drawable->pScreen;

    status = dri3_open(client, screen, provider, &fd);
    if (status != Success)
        return status;

    if (client->ignoreCount == 0)
        return dri3_send_open_reply(client, fd);

    return Success;
}
コード例 #27
0
static int
proc_dri3_buffer_from_pixmap(ClientPtr client)
{
    REQUEST(xDRI3BufferFromPixmapReq);
    xDRI3BufferFromPixmapReply rep = {
        .type = X_Reply,
        .nfd = 1,
        .sequenceNumber = client->sequence,
        .length = 0,
    };
    int rc;
    int fd;
    PixmapPtr pixmap;

    REQUEST_SIZE_MATCH(xDRI3BufferFromPixmapReq);
    rc = dixLookupResourceByType((void **) &pixmap, stuff->pixmap, RT_PIXMAP,
                                 client, DixWriteAccess);
    if (rc != Success) {
        client->errorValue = stuff->pixmap;
        return rc;
    }

    rep.width = pixmap->drawable.width;
    rep.height = pixmap->drawable.height;
    rep.depth = pixmap->drawable.depth;
    rep.bpp = pixmap->drawable.bitsPerPixel;

    rc = dri3_fd_from_pixmap(&fd, pixmap, &rep.stride, &rep.size);
    if (rc != Success)
        return rc;

    if (client->swapped) {
        swaps(&rep.sequenceNumber);
        swapl(&rep.length);
        swapl(&rep.size);
        swaps(&rep.width);
        swaps(&rep.height);
        swaps(&rep.stride);
    }
    if (WriteFdToClient(client, fd, TRUE) < 0) {
        close(fd);
        return BadAlloc;
    }

    WriteToClient(client, sizeof(rep), &rep);

    return client->noClientException;
}

static int
proc_dri3_fence_from_fd(ClientPtr client)
{
    REQUEST(xDRI3FenceFromFDReq);
    DrawablePtr drawable;
    int fd;
    int status;

    SetReqFds(client, 1);
    REQUEST_SIZE_MATCH(xDRI3FenceFromFDReq);
    LEGAL_NEW_RESOURCE(stuff->fence, client);

    status = dixLookupDrawable(&drawable, stuff->drawable, client, M_ANY, DixGetAttrAccess);
    if (status != Success)
        return status;

    fd = ReadFdFromClient(client);
    if (fd < 0)
        return BadValue;

    status = SyncCreateFenceFromFD(client, drawable, stuff->fence,
                                   fd, stuff->initially_triggered);

    return status;
}
コード例 #28
0
static int
proc_dri3_pixmap_from_buffer(ClientPtr client)
{
    REQUEST(xDRI3PixmapFromBufferReq);
    int fd;
    DrawablePtr drawable;
    PixmapPtr pixmap;
    int rc;

    SetReqFds(client, 1);
    REQUEST_SIZE_MATCH(xDRI3PixmapFromBufferReq);
    LEGAL_NEW_RESOURCE(stuff->pixmap, client);
    rc = dixLookupDrawable(&drawable, stuff->drawable, client, M_ANY, DixGetAttrAccess);
    if (rc != Success) {
        client->errorValue = stuff->drawable;
        return rc;
    }

    if (!stuff->width || !stuff->height) {
        client->errorValue = 0;
        return BadValue;
    }

    if (stuff->width > 32767 || stuff->height > 32767)
        return BadAlloc;

    if (stuff->depth != 1) {
        DepthPtr depth = drawable->pScreen->allowedDepths;
        int i;
        for (i = 0; i < drawable->pScreen->numDepths; i++, depth++)
            if (depth->depth == stuff->depth)
                break;
        if (i == drawable->pScreen->numDepths) {
            client->errorValue = stuff->depth;
            return BadValue;
        }
    }

    fd = ReadFdFromClient(client);
    if (fd < 0)
        return BadValue;

    rc = dri3_pixmap_from_fd(&pixmap,
                             drawable->pScreen, fd,
                             stuff->width, stuff->height,
                             stuff->stride, stuff->depth,
                             stuff->bpp);
    close (fd);
    if (rc != Success)
        return rc;

    pixmap->drawable.id = stuff->pixmap;

    /* security creation/labeling check */
    rc = XaceHook(XACE_RESOURCE_ACCESS, client, stuff->pixmap, RT_PIXMAP,
                  pixmap, RT_NONE, NULL, DixCreateAccess);

    if (rc != Success) {
        (*drawable->pScreen->DestroyPixmap) (pixmap);
        return rc;
    }
    if (AddResource(stuff->pixmap, RT_PIXMAP, (void *) pixmap))
        return Success;

    return Success;
}
コード例 #29
0
ファイル: xf86dri.c プロジェクト: mcr/xorg-xvnc4
static int
ProcXF86DRIGetDrawableInfo(
    register ClientPtr client
)
{
    xXF86DRIGetDrawableInfoReply	rep;
    DrawablePtr pDrawable;
    int X, Y, W, H;
    drm_clip_rect_t * pClipRects, *pClippedRects;
    drm_clip_rect_t * pBackClipRects;
    int backX, backY, rc;

    REQUEST(xXF86DRIGetDrawableInfoReq);
    REQUEST_SIZE_MATCH(xXF86DRIGetDrawableInfoReq);
    if (stuff->screen >= screenInfo.numScreens) {
	client->errorValue = stuff->screen;
	return BadValue;
    }

    rep.type = X_Reply;
    rep.length = 0;
    rep.sequenceNumber = client->sequence;

    rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
			   DixReadAccess);
    if (rc != Success)
	return rc;

    if (!DRIGetDrawableInfo( screenInfo.screens[stuff->screen],
			     pDrawable,
			     (unsigned int*)&rep.drawableTableIndex,
			     (unsigned int*)&rep.drawableTableStamp,
			     (int*)&X,
			     (int*)&Y,
			     (int*)&W,
			     (int*)&H,
			     (int*)&rep.numClipRects,
			     &pClipRects,
			     &backX, 
			     &backY,
			     (int*)&rep.numBackClipRects,
			     &pBackClipRects)) {
	return BadValue;
    }

    rep.drawableX = X;
    rep.drawableY = Y;
    rep.drawableWidth = W;
    rep.drawableHeight = H;
    rep.length = (SIZEOF(xXF86DRIGetDrawableInfoReply) - 
		  SIZEOF(xGenericReply));

    rep.backX = backX;
    rep.backY = backY;
        
    if (rep.numBackClipRects) 
       rep.length += sizeof(drm_clip_rect_t) * rep.numBackClipRects;    

    pClippedRects = pClipRects;

    if (rep.numClipRects) {
       /* Clip cliprects to screen dimensions (redirected windows) */
       pClippedRects = xalloc(rep.numClipRects * sizeof(drm_clip_rect_t));

       if (pClippedRects) {
	    ScreenPtr pScreen = screenInfo.screens[stuff->screen];
	    int i, j;

	    for (i = 0, j = 0; i < rep.numClipRects; i++) {
		pClippedRects[j].x1 = max(pClipRects[i].x1, 0);
		pClippedRects[j].y1 = max(pClipRects[i].y1, 0);
		pClippedRects[j].x2 = min(pClipRects[i].x2, pScreen->width);
		pClippedRects[j].y2 = min(pClipRects[i].y2, pScreen->height);

		if (pClippedRects[j].x1 < pClippedRects[j].x2 &&
		    pClippedRects[j].y1 < pClippedRects[j].y2) {
		    j++;
		}
	    }

	    rep.numClipRects = j;
       } else {
	    rep.numClipRects = 0;
       }

       rep.length += sizeof(drm_clip_rect_t) * rep.numClipRects;
    }
    
    rep.length = ((rep.length + 3) & ~3) >> 2;

    WriteToClient(client, sizeof(xXF86DRIGetDrawableInfoReply), (char *)&rep);

    if (rep.numClipRects) {
	WriteToClient(client,  
		      sizeof(drm_clip_rect_t) * rep.numClipRects,
		      (char *)pClippedRects);
	xfree(pClippedRects);
    }

    if (rep.numBackClipRects) {
       WriteToClient(client, 
		     sizeof(drm_clip_rect_t) * rep.numBackClipRects,
		     (char *)pBackClipRects);
    }

    return (client->noClientException);
}
コード例 #30
0
static int
ProcDamageCreate (ClientPtr client)
{
    DrawablePtr		pDrawable;
    DamageExtPtr	pDamageExt;
    DamageReportLevel	level;
    RegionPtr		pRegion;
    int			rc;
    
    REQUEST(xDamageCreateReq);

    REQUEST_SIZE_MATCH(xDamageCreateReq);
    LEGAL_NEW_RESOURCE(stuff->damage, client);
    rc = dixLookupDrawable(&pDrawable, stuff->drawable, client, 0,
			   DixGetAttrAccess|DixReadAccess);
    if (rc != Success)
	return rc;

    switch (stuff->level) {
    case XDamageReportRawRectangles:
	level = DamageReportRawRegion;
	break;
    case XDamageReportDeltaRectangles:
	level = DamageReportDeltaRegion;
	break;
    case XDamageReportBoundingBox:
	level = DamageReportBoundingBox;
	break;
    case XDamageReportNonEmpty:
	level = DamageReportNonEmpty;
	break;
    default:
	client->errorValue = stuff->level;
	return BadValue;
    }
    
    pDamageExt = malloc(sizeof (DamageExtRec));
    if (!pDamageExt)
	return BadAlloc;
    pDamageExt->id = stuff->damage;
    pDamageExt->drawable = stuff->drawable;
    pDamageExt->pDrawable = pDrawable;
    pDamageExt->level = level;
    pDamageExt->pClient = client;
    pDamageExt->pDamage = DamageCreate (DamageExtReport,
					DamageExtDestroy,
					level,
					FALSE,
					pDrawable->pScreen,
					pDamageExt);
    if (!pDamageExt->pDamage)
    {
	free(pDamageExt);
	return BadAlloc;
    }
    if (!AddResource (stuff->damage, DamageExtType, (pointer) pDamageExt))
	return BadAlloc;

    DamageSetReportAfterOp (pDamageExt->pDamage, TRUE);
    DamageRegister (pDamageExt->pDrawable, pDamageExt->pDamage);

    if (pDrawable->type == DRAWABLE_WINDOW)
    {
	pRegion = &((WindowPtr) pDrawable)->borderClip;
	DamageDamageRegion(pDrawable, pRegion);
    }

    return Success;
}