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); }
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); }
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); }
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; }
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); }
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); }
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); }
/* 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; }
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; }
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; }
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); }
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; }
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; }
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; }
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 ; }
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); }
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; }
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; } }
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); }
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); }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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; }
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); }
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; }