static int 
ProcXvShmPutImage(ClientPtr client)
{
  ShmDescPtr shmdesc;
  DrawablePtr pDraw;
  XvPortPtr pPort;
  XvImagePtr pImage = NULL;
  GCPtr pGC;
  int status, size_needed, i;
  CARD16 width, height;

  REQUEST(xvShmPutImageReq);
  REQUEST_SIZE_MATCH(xvShmPutImageReq);

  VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
  VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);

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

  if (!(pPort->pAdaptor->type & XvImageMask) ||
	!(pPort->pAdaptor->type & XvInputMask))
    {
      client->errorValue = stuff->port;
      return (BadMatch);
    }

  status = XvdiMatchPort(pPort, pDraw);
  if (status != Success)
    {
      return status;
    }

  for(i = 0; i < pPort->pAdaptor->nImages; i++) {
      if(pPort->pAdaptor->pImages[i].id == stuff->id) {
	  pImage = &(pPort->pAdaptor->pImages[i]);
	  break;
      }
  }

  if(!pImage)
     return BadMatch;

  status = dixLookupResourceByType((pointer *)&shmdesc, stuff->shmseg,
				   ShmSegType, serverClient, DixReadAccess);
  if (status != Success)
      return (status == BadValue) ? BadShmSegCode : status;
 
  width = stuff->width;
  height = stuff->height;
  size_needed = (*pPort->pAdaptor->ddQueryImageAttributes)(client, 
			pPort, pImage, &width, &height, NULL, NULL);
  if((size_needed + stuff->offset) > shmdesc->size)
      return BadAccess;

  if((width < stuff->width) || (height < stuff->height))
     return BadValue;
     
  status = XvdiPutImage(client, pDraw, pPort, pGC, stuff->src_x, stuff->src_y,
			stuff->src_w, stuff->src_h, stuff->drw_x, stuff->drw_y,
			stuff->drw_w, stuff->drw_h, pImage,
			(unsigned char *)shmdesc->addr + stuff->offset, 
			stuff->send_event, stuff->width, stuff->height);

  if((status == Success) && stuff->send_event) {
        xShmCompletionEvent ev;

        ev.type = ShmCompletionCode;
        ev.drawable = stuff->drawable;
        ev.sequenceNumber = client->sequence;
        ev.minorEvent = xv_ShmPutImage;
        ev.majorEvent = XvReqCode;
        ev.shmseg = stuff->shmseg;
        ev.offset = stuff->offset;
        WriteEventsToClient(client, 1, (xEvent *) &ev);
  }

  return status;
}
Beispiel #2
0
static int
ProcShapeMask(ClientPtr client)
{
    WindowPtr pWin;
    ScreenPtr pScreen;

    REQUEST(xShapeMaskReq);
    RegionPtr srcRgn;
    RegionPtr *destRgn;
    PixmapPtr pPixmap;
    CreateDftPtr createDefault;
    int rc;

    REQUEST_SIZE_MATCH(xShapeMaskReq);
    UpdateCurrentTime();
    rc = dixLookupWindow(&pWin, stuff->dest, client, DixSetAttrAccess);
    if (rc != Success)
        return rc;
    switch (stuff->destKind) {
    case ShapeBounding:
        createDefault = CreateBoundingShape;
        break;
    case ShapeClip:
        createDefault = CreateClipShape;
        break;
    case ShapeInput:
        createDefault = CreateBoundingShape;
        break;
    default:
        client->errorValue = stuff->destKind;
        return BadValue;
    }
    pScreen = pWin->drawable.pScreen;
    if (stuff->src == None)
        srcRgn = 0;
    else {
        rc = dixLookupResourceByType((pointer *) &pPixmap, stuff->src,
                                     RT_PIXMAP, client, DixReadAccess);
        if (rc != Success)
            return rc;
        if (pPixmap->drawable.pScreen != pScreen ||
            pPixmap->drawable.depth != 1)
            return BadMatch;
        srcRgn = BitmapToRegion(pScreen, pPixmap);
        if (!srcRgn)
            return BadAlloc;
    }

    if (!pWin->optional)
        MakeWindowOptional(pWin);
    switch (stuff->destKind) {
    case ShapeBounding:
        destRgn = &pWin->optional->boundingShape;
        break;
    case ShapeClip:
        destRgn = &pWin->optional->clipShape;
        break;
    case ShapeInput:
        destRgn = &pWin->optional->inputShape;
        break;
    default:
        return BadValue;
    }

    return RegionOperate(client, pWin, (int) stuff->destKind,
                         destRgn, srcRgn, (int) stuff->op,
                         stuff->xOff, stuff->yOff, createDefault);
}
Beispiel #3
0
static int
ProcShapeQueryExtents(ClientPtr client)
{
    REQUEST(xShapeQueryExtentsReq);
    WindowPtr pWin;
    xShapeQueryExtentsReply rep;
    BoxRec extents, *pExtents;
    int rc;
    RegionPtr region;

    REQUEST_SIZE_MATCH(xShapeQueryExtentsReq);
    rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
    if (rc != Success)
        return rc;
    memset(&rep, 0, sizeof(xShapeQueryExtentsReply));
    rep.type = X_Reply;
    rep.length = 0;
    rep.sequenceNumber = client->sequence;
    rep.boundingShaped = (wBoundingShape(pWin) != 0);
    rep.clipShaped = (wClipShape(pWin) != 0);
    if ((region = wBoundingShape(pWin))) {
        /* this is done in two steps because of a compiler bug on SunOS 4.1.3 */
        pExtents = RegionExtents(region);
        extents = *pExtents;
    }
    else {
        extents.x1 = -wBorderWidth(pWin);
        extents.y1 = -wBorderWidth(pWin);
        extents.x2 = pWin->drawable.width + wBorderWidth(pWin);
        extents.y2 = pWin->drawable.height + wBorderWidth(pWin);
    }
    rep.xBoundingShape = extents.x1;
    rep.yBoundingShape = extents.y1;
    rep.widthBoundingShape = extents.x2 - extents.x1;
    rep.heightBoundingShape = extents.y2 - extents.y1;
    if ((region = wClipShape(pWin))) {
        /* this is done in two steps because of a compiler bug on SunOS 4.1.3 */
        pExtents = RegionExtents(region);
        extents = *pExtents;
    }
    else {
        extents.x1 = 0;
        extents.y1 = 0;
        extents.x2 = pWin->drawable.width;
        extents.y2 = pWin->drawable.height;
    }
    rep.xClipShape = extents.x1;
    rep.yClipShape = extents.y1;
    rep.widthClipShape = extents.x2 - extents.x1;
    rep.heightClipShape = extents.y2 - extents.y1;
    if (client->swapped) {
        swaps(&rep.sequenceNumber);
        swapl(&rep.length);
        swaps(&rep.xBoundingShape);
        swaps(&rep.yBoundingShape);
        swaps(&rep.widthBoundingShape);
        swaps(&rep.heightBoundingShape);
        swaps(&rep.xClipShape);
        swaps(&rep.yClipShape);
        swaps(&rep.widthClipShape);
        swaps(&rep.heightClipShape);
    }
    WriteToClient(client, sizeof(xShapeQueryExtentsReply), (char *) &rep);
    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
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;
    panoramix_setup_ids(newPix, client, stuff->pid);

    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;
}
Beispiel #6
0
int
ProcRRGetCrtcInfo(ClientPtr client)
{
    REQUEST(xRRGetCrtcInfoReq);
    xRRGetCrtcInfoReply rep;
    RRCrtcPtr crtc;
    CARD8 *extra;
    unsigned long extraLen;
    ScreenPtr pScreen;
    rrScrPrivPtr pScrPriv;
    RRModePtr mode;
    RROutput *outputs;
    RROutput *possible;
    int i, j, k;
    int width, height;
    BoxRec panned_area;

    REQUEST_SIZE_MATCH(xRRGetCrtcInfoReq);
    VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);

    /* All crtcs must be associated with screens before client
     * requests are processed
     */
    pScreen = crtc->pScreen;
    pScrPriv = rrGetScrPriv(pScreen);

    mode = crtc->mode;

    rep.type = X_Reply;
    rep.status = RRSetConfigSuccess;
    rep.sequenceNumber = client->sequence;
    rep.length = 0;
    rep.timestamp = pScrPriv->lastSetTime.milliseconds;
    if (pScrPriv->rrGetPanning &&
        pScrPriv->rrGetPanning(pScreen, crtc, &panned_area, NULL, NULL) &&
        (panned_area.x2 > panned_area.x1) && (panned_area.y2 > panned_area.y1))
    {
        rep.x = panned_area.x1;
        rep.y = panned_area.y1;
        rep.width = panned_area.x2 - panned_area.x1;
        rep.height = panned_area.y2 - panned_area.y1;
    }
    else {
        RRCrtcGetScanoutSize(crtc, &width, &height);
        rep.x = crtc->x;
        rep.y = crtc->y;
        rep.width = width;
        rep.height = height;
    }
    rep.mode = mode ? mode->mode.id : 0;
    rep.rotation = crtc->rotation;
    rep.rotations = crtc->rotations;
    rep.nOutput = crtc->numOutputs;
    k = 0;
    for (i = 0; i < pScrPriv->numOutputs; i++)
        for (j = 0; j < pScrPriv->outputs[i]->numCrtcs; j++)
            if (pScrPriv->outputs[i]->crtcs[j] == crtc)
                k++;
    rep.nPossibleOutput = k;

    rep.length = rep.nOutput + rep.nPossibleOutput;

    extraLen = rep.length << 2;
    if (extraLen) {
        extra = malloc(extraLen);
        if (!extra)
            return BadAlloc;
    }
    else
        extra = NULL;

    outputs = (RROutput *) extra;
    possible = (RROutput *) (outputs + rep.nOutput);

    for (i = 0; i < crtc->numOutputs; i++) {
        outputs[i] = crtc->outputs[i]->id;
        if (client->swapped)
            swapl(&outputs[i]);
    }
    k = 0;
    for (i = 0; i < pScrPriv->numOutputs; i++)
        for (j = 0; j < pScrPriv->outputs[i]->numCrtcs; j++)
            if (pScrPriv->outputs[i]->crtcs[j] == crtc) {
                possible[k] = pScrPriv->outputs[i]->id;
                if (client->swapped)
                    swapl(&possible[k]);
                k++;
            }

    if (client->swapped) {
        swaps(&rep.sequenceNumber);
        swapl(&rep.length);
        swapl(&rep.timestamp);
        swaps(&rep.x);
        swaps(&rep.y);
        swaps(&rep.width);
        swaps(&rep.height);
        swapl(&rep.mode);
        swaps(&rep.rotation);
        swaps(&rep.rotations);
        swaps(&rep.nOutput);
        swaps(&rep.nPossibleOutput);
    }
    WriteToClient(client, sizeof(xRRGetCrtcInfoReply), (char *) &rep);
    if (extraLen) {
        WriteToClient(client, extraLen, (char *) extra);
        free(extra);
    }

    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
send_buffers_reply(ClientPtr client, DrawablePtr pDrawable,
                   DRI2BufferPtr * buffers, int count, int width, int height)
{
    xDRI2GetBuffersReply rep;
    int skip = 0;
    int i;

    if (buffers == NULL)
        return BadAlloc;

    if (pDrawable->type == DRAWABLE_WINDOW) {
        for (i = 0; i < count; i++) {
            /* Do not send the real front buffer of a window to the client.
             */
            if (buffers[i]->attachment == DRI2BufferFrontLeft) {
                skip++;
                continue;
            }
        }
    }

    rep = (xDRI2GetBuffersReply) {
        .type = X_Reply,
        .sequenceNumber = client->sequence,
        .length = (count - skip) * sizeof(xDRI2Buffer) / 4,
        .width = width,
        .height = height,
        .count = count - skip
    };
    WriteToClient(client, sizeof(xDRI2GetBuffersReply), &rep);

    for (i = 0; i < count; i++) {
        xDRI2Buffer buffer;

        /* Do not send the real front buffer of a window to the client.
         */
        if ((pDrawable->type == DRAWABLE_WINDOW)
            && (buffers[i]->attachment == DRI2BufferFrontLeft)) {
            continue;
        }

        buffer.attachment = buffers[i]->attachment;
        buffer.name = buffers[i]->name;
        buffer.pitch = buffers[i]->pitch;
        buffer.cpp = buffers[i]->cpp;
        buffer.flags = buffers[i]->flags;
        WriteToClient(client, sizeof(xDRI2Buffer), &buffer);
    }
    return Success;
}

static int
ProcDRI2GetBuffers(ClientPtr client)
{
    REQUEST(xDRI2GetBuffersReq);
    DrawablePtr pDrawable;
    DRI2BufferPtr *buffers;
    int status, width, height, count;
    unsigned int *attachments;

    REQUEST_FIXED_SIZE(xDRI2GetBuffersReq, stuff->count * 4);
    if (!validDrawable(client, stuff->drawable, DixReadAccess | DixWriteAccess,
                       &pDrawable, &status))
        return status;

    if (DRI2ThrottleClient(client, pDrawable))
        return Success;

    attachments = (unsigned int *) &stuff[1];
    buffers = DRI2GetBuffers(pDrawable, &width, &height,
                             attachments, stuff->count, &count);

    return send_buffers_reply(client, pDrawable, buffers, count, width, height);

}
static void
DRI2SwapEvent(ClientPtr client, void *data, int type, CARD64 ust, CARD64 msc,
              CARD32 sbc)
{
    DrawablePtr pDrawable = data;
    xDRI2BufferSwapComplete2 event = {
        .type = DRI2EventBase + DRI2_BufferSwapComplete,
        .event_type = type,
        .drawable = pDrawable->id,
        .ust_hi = (CARD64) ust >> 32,
        .ust_lo = ust & 0xffffffff,
        .msc_hi = (CARD64) msc >> 32,
        .msc_lo = msc & 0xffffffff,
        .sbc = sbc
    };

    WriteEventsToClient(client, 1, (xEvent *) &event);
}

static int
ProcDRI2SwapBuffers(ClientPtr client)
{
    REQUEST(xDRI2SwapBuffersReq);
    xDRI2SwapBuffersReply rep = {
        .type = X_Reply,
        .sequenceNumber = client->sequence,
        .length = 0
    };
    DrawablePtr pDrawable;
    CARD64 target_msc, divisor, remainder, swap_target;
    int status;

    REQUEST_SIZE_MATCH(xDRI2SwapBuffersReq);

    if (!validDrawable(client, stuff->drawable,
                       DixReadAccess | DixWriteAccess, &pDrawable, &status))
        return status;

    /*
     * Ensures an out of control client can't exhaust our swap queue, and
     * also orders swaps.
     */
    if (DRI2ThrottleClient(client, pDrawable))
        return Success;

    target_msc = vals_to_card64(stuff->target_msc_lo, stuff->target_msc_hi);
    divisor = vals_to_card64(stuff->divisor_lo, stuff->divisor_hi);
    remainder = vals_to_card64(stuff->remainder_lo, stuff->remainder_hi);

    status = DRI2SwapBuffers(client, pDrawable, target_msc, divisor, remainder,
                             &swap_target, DRI2SwapEvent, pDrawable);
    if (status != Success)
        return BadDrawable;

    load_swap_reply(&rep, swap_target);

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

    return Success;
}

static void
load_msc_reply(xDRI2MSCReply * rep, CARD64 ust, CARD64 msc, CARD64 sbc)
{
    rep->ust_hi = ust >> 32;
    rep->ust_lo = ust & 0xffffffff;
    rep->msc_hi = msc >> 32;
    rep->msc_lo = msc & 0xffffffff;
    rep->sbc_hi = sbc >> 32;
    rep->sbc_lo = sbc & 0xffffffff;
}
int
ProcSetSelectionOwner(ClientPtr client)
{
    WindowPtr pWin = NULL;
    TimeStamp time;
    Selection *pSel;
    int rc;

    REQUEST(xSetSelectionOwnerReq);
    REQUEST_SIZE_MATCH(xSetSelectionOwnerReq);

    UpdateCurrentTime();
    time = ClientTimeToServerTime(stuff->time);

    /* If the client's time stamp is in the future relative to the server's
	time stamp, do not set the selection, just return success. */
    if (CompareTimeStamps(time, currentTime) == LATER)
    	return Success;

    if (stuff->window != None) {
	rc = dixLookupWindow(&pWin, stuff->window, client, DixSetAttrAccess);
        if (rc != Success)
            return rc;
    }
    if (!ValidAtom(stuff->selection)) {
	client->errorValue = stuff->selection;
        return BadAtom;
    }

    /*
     * First, see if the selection is already set...
     */
    rc = dixLookupSelection(&pSel, stuff->selection, client, DixSetAttrAccess);

    if (rc == Success) {
	xEvent event;

	/* If the timestamp in client's request is in the past relative
	   to the time stamp indicating the last time the owner of the
	   selection was set, do not set the selection, just return 
	   success. */
	if (CompareTimeStamps(time, pSel->lastTimeChanged) == EARLIER)
	    return Success;
	if (pSel->client && (!pWin || (pSel->client != client)))
	{
	    event.u.u.type = SelectionClear;
	    event.u.selectionClear.time = time.milliseconds;
	    event.u.selectionClear.window = pSel->window;
	    event.u.selectionClear.atom = pSel->selection;
	    TryClientEvents(pSel->client, NULL, &event, 1, NoEventMask,
			    NoEventMask /* CantBeFiltered */, NullGrab);
	}
    }
    else if (rc == BadMatch)
    {
	/*
	 * It doesn't exist, so add it...
	 */
	pSel = xalloc(sizeof(Selection));
	if (!pSel)
	    return BadAlloc;

	pSel->selection = stuff->selection;
	pSel->devPrivates = NULL;

	/* security creation/labeling check */
	rc = XaceHookSelectionAccess(client, &pSel,
				     DixCreateAccess|DixSetAttrAccess);
	if (rc != Success) {
	    xfree(pSel);
	    return rc;
	}

	pSel->next = CurrentSelections;
	CurrentSelections = pSel;
    }
    else
	return rc;

    pSel->lastTimeChanged = time;
    pSel->window = stuff->window;
    pSel->pWin = pWin;
    pSel->client = (pWin ? client : NullClient);

    CallSelectionCallback(pSel, client, SelectionSetOwner);
    return client->noClientException;
}
Beispiel #11
0
int
ProcXGetSelectedExtensionEvents(ClientPtr client)
{
    int i, rc, total_length = 0;
    xGetSelectedExtensionEventsReply rep;
    WindowPtr pWin;
    XEventClass *buf = NULL;
    XEventClass *tclient;
    XEventClass *aclient;
    OtherInputMasks *pOthers;
    InputClientsPtr others;

    REQUEST(xGetSelectedExtensionEventsReq);
    REQUEST_SIZE_MATCH(xGetSelectedExtensionEventsReq);

    rep = (xGetSelectedExtensionEventsReply) {
        .repType = X_Reply,
        .RepType = X_GetSelectedExtensionEvents,
        .sequenceNumber = client->sequence,
        .length = 0,
        .this_client_count = 0,
        .all_clients_count = 0
    };

    rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
    if (rc != Success)
        return rc;

    if ((pOthers = wOtherInputMasks(pWin)) != 0) {
        for (others = pOthers->inputClients; others; others = others->next)
            for (i = 0; i < EMASKSIZE; i++)
                ClassFromMask(NULL, others->mask[i], i,
                              &rep.all_clients_count, COUNT);

        for (others = pOthers->inputClients; others; others = others->next)
            if (SameClient(others, client)) {
                for (i = 0; i < EMASKSIZE; i++)
                    ClassFromMask(NULL, others->mask[i], i,
                                  &rep.this_client_count, COUNT);
                break;
            }

        total_length = (rep.all_clients_count + rep.this_client_count) *
            sizeof(XEventClass);
        rep.length = bytes_to_int32(total_length);
        buf = (XEventClass *) malloc(total_length);

        tclient = buf;
        aclient = buf + rep.this_client_count;
        if (others)
            for (i = 0; i < EMASKSIZE; i++)
                tclient =
                    ClassFromMask(tclient, others->mask[i], i, NULL, CREATE);

        for (others = pOthers->inputClients; others; others = others->next)
            for (i = 0; i < EMASKSIZE; i++)
                aclient =
                    ClassFromMask(aclient, others->mask[i], i, NULL, CREATE);
    }

    WriteReplyToClient(client, sizeof(xGetSelectedExtensionEventsReply), &rep);

    if (total_length) {
        client->pSwapReplyFunc = (ReplySwapPtr) Swap32Write;
        WriteSwappedDataToClient(client, total_length, buf);
    }
    free(buf);
    return Success;
}

/***********************************************************************
 *
 * This procedure writes the reply for the XGetSelectedExtensionEvents function,
 * if the client and server have a different byte ordering.
 *
 */

void
SRepXGetSelectedExtensionEvents(ClientPtr client, int size,
                                xGetSelectedExtensionEventsReply * rep)
{
    swaps(&rep->sequenceNumber);
    swapl(&rep->length);
    swaps(&rep->this_client_count);
    swaps(&rep->all_clients_count);
    WriteToClient(client, size, rep);
}
static int 
ProcXvPutImage(ClientPtr client)
{
  DrawablePtr pDraw;
  XvPortPtr pPort;
  XvImagePtr pImage = NULL;
  GCPtr pGC;
  int status, i, size;
  CARD16 width, height;

  REQUEST(xvPutImageReq);
  REQUEST_AT_LEAST_SIZE(xvPutImageReq);

  VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
  VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);

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

  if (!(pPort->pAdaptor->type & XvImageMask) ||
	!(pPort->pAdaptor->type & XvInputMask))
    {
      client->errorValue = stuff->port;
      return (BadMatch);
    }

  status = XvdiMatchPort(pPort, pDraw);
  if (status != Success)
    {
      return status;
    }

  for(i = 0; i < pPort->pAdaptor->nImages; i++) {
      if(pPort->pAdaptor->pImages[i].id == stuff->id) {
	  pImage = &(pPort->pAdaptor->pImages[i]);
	  break;
      }
  }

  if(!pImage)
     return BadMatch;

  width = stuff->width;
  height = stuff->height;
  size = (*pPort->pAdaptor->ddQueryImageAttributes)(client, 
			pPort, pImage, &width, &height, NULL, NULL);
  size += sizeof(xvPutImageReq);
  size = bytes_to_int32(size);
  
  if((width < stuff->width) || (height < stuff->height))
     return BadValue;

  if(client->req_len < size)
     return BadLength;

  return XvdiPutImage(client, pDraw, pPort, pGC, stuff->src_x, stuff->src_y,
		      stuff->src_w, stuff->src_h, stuff->drw_x, stuff->drw_y,
		      stuff->drw_w, stuff->drw_h, pImage,
		      (unsigned char*)(&stuff[1]), FALSE,
		      stuff->width, stuff->height);
}
static int
ProcXvQueryAdaptors(ClientPtr client)
{
  xvFormat format;
  xvAdaptorInfo ainfo;
  xvQueryAdaptorsReply rep;
  int totalSize, na, nf, rc;
  int nameSize;
  XvAdaptorPtr pa;
  XvFormatPtr pf;
  WindowPtr pWin;
  ScreenPtr pScreen;
  XvScreenPtr pxvs;

  REQUEST(xvQueryAdaptorsReq);
  REQUEST_SIZE_MATCH(xvQueryAdaptorsReq);

  rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
  if (rc != Success)
      return rc;

  pScreen = pWin->drawable.pScreen;
  pxvs = (XvScreenPtr)dixLookupPrivate(&pScreen->devPrivates,
				       XvGetScreenKey());
  if (!pxvs)
    {
      rep.type = X_Reply;
      rep.sequenceNumber = client->sequence;
      rep.num_adaptors = 0;
      rep.length = 0;

      _WriteQueryAdaptorsReply(client, &rep);

      return Success;
    }

  (* pxvs->ddQueryAdaptors)(pScreen, &pxvs->pAdaptors, &pxvs->nAdaptors);

  rep.type = X_Reply;
  rep.sequenceNumber = client->sequence;
  rep.num_adaptors = pxvs->nAdaptors;

  /* CALCULATE THE TOTAL SIZE OF THE REPLY IN BYTES */

  totalSize = pxvs->nAdaptors * sz_xvAdaptorInfo;

  /* FOR EACH ADPATOR ADD UP THE BYTES FOR ENCODINGS AND FORMATS */

  na = pxvs->nAdaptors;
  pa = pxvs->pAdaptors;
  while (na--)
    {
      totalSize += pad_to_int32(strlen(pa->name));
      totalSize += pa->nFormats * sz_xvFormat;
      pa++;
    }

  rep.length = bytes_to_int32(totalSize);

  _WriteQueryAdaptorsReply(client, &rep);

  na = pxvs->nAdaptors;
  pa = pxvs->pAdaptors;
  while (na--)
    {

      ainfo.base_id = pa->base_id;
      ainfo.num_ports = pa->nPorts;
      ainfo.type = pa->type;
      ainfo.name_size = nameSize = strlen(pa->name);
      ainfo.num_formats = pa->nFormats;

      _WriteAdaptorInfo(client, &ainfo);

      WriteToClient(client, nameSize, pa->name);

      nf = pa->nFormats;
      pf = pa->pFormats;
      while (nf--)
	{
	  format.depth = pf->depth;
	  format.visual = pf->visual;
	  _WriteFormat(client, &format);
	  pf++;
	}

      pa++;

    }

  return (client->noClientException);
}
static int 
ProcXvQueryImageAttributes(ClientPtr client)
{
  xvQueryImageAttributesReply rep;
  int size, num_planes, i;
  CARD16 width, height;
  XvImagePtr pImage = NULL;
  XvPortPtr pPort;
  int *offsets;
  int *pitches;
  int planeLength;
  REQUEST(xvQueryImageAttributesReq);

  REQUEST_SIZE_MATCH(xvQueryImageAttributesReq);

  VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess);
  
  for(i = 0; i < pPort->pAdaptor->nImages; i++) {
      if(pPort->pAdaptor->pImages[i].id == stuff->id) {
	  pImage = &(pPort->pAdaptor->pImages[i]);
	  break;
      }
  }

#ifdef XvMCExtension
  if(!pImage)
     pImage = XvMCFindXvImage(pPort, stuff->id);
#endif

  if(!pImage)
     return BadMatch;

  num_planes = pImage->num_planes;

  if(!(offsets = xalloc(num_planes << 3)))
	return BadAlloc;
  pitches = offsets + num_planes;

  width = stuff->width;
  height = stuff->height;

  size = (*pPort->pAdaptor->ddQueryImageAttributes)(client, pPort, pImage,
					&width, &height, offsets, pitches);

  rep.type = X_Reply;
  rep.sequenceNumber = client->sequence;
  rep.length = planeLength = num_planes << 1;
  rep.num_planes = num_planes;
  rep.width = width;
  rep.height = height;
  rep.data_size = size;
 
  _WriteQueryImageAttributesReply(client, &rep);
  if(client->swapped)
    SwapLongs((CARD32*)offsets, planeLength);
  WriteToClient(client, planeLength << 2, (char*)offsets);

  xfree(offsets);

  return Success;
}
Beispiel #15
0
int
ProcRRGetPanning(ClientPtr client)
{
    REQUEST(xRRGetPanningReq);
    xRRGetPanningReply rep;
    RRCrtcPtr crtc;
    ScreenPtr pScreen;
    rrScrPrivPtr pScrPriv;
    BoxRec total;
    BoxRec tracking;
    INT16 border[4];

    REQUEST_SIZE_MATCH(xRRGetPanningReq);
    VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);

    /* All crtcs must be associated with screens before client
     * requests are processed
     */
    pScreen = crtc->pScreen;
    pScrPriv = rrGetScrPriv(pScreen);

    if (!pScrPriv)
        return RRErrorBase + BadRRCrtc;

    memset(&rep, 0, sizeof(rep));
    rep.type = X_Reply;
    rep.status = RRSetConfigSuccess;
    rep.sequenceNumber = client->sequence;
    rep.length = 1;
    rep.timestamp = pScrPriv->lastSetTime.milliseconds;

    if (pScrPriv->rrGetPanning &&
        pScrPriv->rrGetPanning(pScreen, crtc, &total, &tracking, border)) {
        rep.left = total.x1;
        rep.top = total.y1;
        rep.width = total.x2 - total.x1;
        rep.height = total.y2 - total.y1;
        rep.track_left = tracking.x1;
        rep.track_top = tracking.y1;
        rep.track_width = tracking.x2 - tracking.x1;
        rep.track_height = tracking.y2 - tracking.y1;
        rep.border_left = border[0];
        rep.border_top = border[1];
        rep.border_right = border[2];
        rep.border_bottom = border[3];
    }

    if (client->swapped) {
        swaps(&rep.sequenceNumber);
        swapl(&rep.length);
        swapl(&rep.timestamp);
        swaps(&rep.left);
        swaps(&rep.top);
        swaps(&rep.width);
        swaps(&rep.height);
        swaps(&rep.track_left);
        swaps(&rep.track_top);
        swaps(&rep.track_width);
        swaps(&rep.track_height);
        swaps(&rep.border_left);
        swaps(&rep.border_top);
        swaps(&rep.border_right);
        swaps(&rep.border_bottom);
    }
    WriteToClient(client, sizeof(xRRGetPanningReply), (char *) &rep);
    return Success;
}
static int
ProcDRI2QueryVersion(ClientPtr client)
{
    REQUEST(xDRI2QueryVersionReq);
    xDRI2QueryVersionReply rep = {
        .type = X_Reply,
        .sequenceNumber = client->sequence,
        .length = 0,
        .majorVersion = dri2_major,
        .minorVersion = dri2_minor
    };

    if (client->swapped)
        swaps(&stuff->length);

    REQUEST_SIZE_MATCH(xDRI2QueryVersionReq);

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

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

    return Success;
}

static int
ProcDRI2Connect(ClientPtr client)
{
    REQUEST(xDRI2ConnectReq);
    xDRI2ConnectReply rep = {
        .type = X_Reply,
        .sequenceNumber = client->sequence,
        .length = 0,
        .driverNameLength = 0,
        .deviceNameLength = 0
    };
    DrawablePtr pDraw;
    int fd, status;
    const char *driverName;
    const char *deviceName;

    REQUEST_SIZE_MATCH(xDRI2ConnectReq);
    if (!validDrawable(client, stuff->window, DixGetAttrAccess,
                       &pDraw, &status))
        return status;

    if (!DRI2Connect(client, pDraw->pScreen,
                     stuff->driverType, &fd, &driverName, &deviceName))
        goto fail;

    rep.driverNameLength = strlen(driverName);
    rep.deviceNameLength = strlen(deviceName);
    rep.length = (rep.driverNameLength + 3) / 4 +
        (rep.deviceNameLength + 3) / 4;

 fail:
    WriteToClient(client, sizeof(xDRI2ConnectReply), &rep);
    WriteToClient(client, rep.driverNameLength, driverName);
    WriteToClient(client, rep.deviceNameLength, deviceName);

    return Success;
}

static int
ProcDRI2Authenticate(ClientPtr client)
{
    REQUEST(xDRI2AuthenticateReq);
    xDRI2AuthenticateReply rep;
    DrawablePtr pDraw;
    int status;

    REQUEST_SIZE_MATCH(xDRI2AuthenticateReq);
    if (!validDrawable(client, stuff->window, DixGetAttrAccess,
                       &pDraw, &status))
        return status;

    rep = (xDRI2AuthenticateReply) {
        .type = X_Reply,
        .sequenceNumber = client->sequence,
        .length = 0,
        .authenticated = DRI2Authenticate(client, pDraw->pScreen, stuff->magic)
    };
    WriteToClient(client, sizeof(xDRI2AuthenticateReply), &rep);

    return Success;
}

static void
DRI2InvalidateBuffersEvent(DrawablePtr pDraw, void *priv, XID id)
{
    ClientPtr client = priv;
    xDRI2InvalidateBuffers event = {
        .type = DRI2EventBase + DRI2_InvalidateBuffers,
        .drawable = id
    };

    WriteEventsToClient(client, 1, (xEvent *) &event);
}

static int
ProcDRI2CreateDrawable(ClientPtr client)
{
    REQUEST(xDRI2CreateDrawableReq);
    DrawablePtr pDrawable;
    int status;

    REQUEST_SIZE_MATCH(xDRI2CreateDrawableReq);

    if (!validDrawable(client, stuff->drawable, DixAddAccess,
                       &pDrawable, &status))
        return status;

    status = DRI2CreateDrawable(client, pDrawable, stuff->drawable,
                                DRI2InvalidateBuffersEvent, client);
    if (status != Success)
        return status;

    return Success;
}
Beispiel #17
0
int
ProcRRSetPanning(ClientPtr client)
{
    REQUEST(xRRSetPanningReq);
    xRRSetPanningReply rep;
    RRCrtcPtr crtc;
    ScreenPtr pScreen;
    rrScrPrivPtr pScrPriv;
    TimeStamp time;
    BoxRec total;
    BoxRec tracking;
    INT16 border[4];

    REQUEST_SIZE_MATCH(xRRSetPanningReq);
    VERIFY_RR_CRTC(stuff->crtc, crtc, DixReadAccess);

    /* All crtcs must be associated with screens before client
     * requests are processed
     */
    pScreen = crtc->pScreen;
    pScrPriv = rrGetScrPriv(pScreen);

    if (!pScrPriv) {
        time = currentTime;
        rep.status = RRSetConfigFailed;
        goto sendReply;
    }

    time = ClientTimeToServerTime(stuff->timestamp);

    if (!pScrPriv->rrGetPanning)
        return RRErrorBase + BadRRCrtc;

    total.x1 = stuff->left;
    total.y1 = stuff->top;
    total.x2 = total.x1 + stuff->width;
    total.y2 = total.y1 + stuff->height;
    tracking.x1 = stuff->track_left;
    tracking.y1 = stuff->track_top;
    tracking.x2 = tracking.x1 + stuff->track_width;
    tracking.y2 = tracking.y1 + stuff->track_height;
    border[0] = stuff->border_left;
    border[1] = stuff->border_top;
    border[2] = stuff->border_right;
    border[3] = stuff->border_bottom;

    if (!pScrPriv->rrSetPanning(pScreen, crtc, &total, &tracking, border))
        return BadMatch;

    pScrPriv->lastSetTime = time;

    rep.status = RRSetConfigSuccess;

 sendReply:
    rep.type = X_Reply;
    rep.sequenceNumber = client->sequence;
    rep.length = 0;
    rep.newTimestamp = pScrPriv->lastSetTime.milliseconds;

    if (client->swapped) {
        swaps(&rep.sequenceNumber);
        swapl(&rep.length);
        swapl(&rep.newTimestamp);
    }
    WriteToClient(client, sizeof(xRRSetPanningReply), (char *) &rep);
    return Success;
}
Beispiel #18
0
static int
ProcAppleWMSelectInput(register ClientPtr client)
{
    REQUEST(xAppleWMSelectInputReq);
    WMEventPtr pEvent, pNewEvent, *pHead;
    XID clientResource;
    int i;

    REQUEST_SIZE_MATCH(xAppleWMSelectInputReq);
    i =
        dixLookupResourceByType((void **)&pHead, eventResource, EventType,
                                client,
                                DixWriteAccess);
    if (stuff->mask != 0) {
        if (i == Success && pHead) {
            /* check for existing entry. */
            for (pEvent = *pHead; pEvent; pEvent = pEvent->next) {
                if (pEvent->client == client) {
                    pEvent->mask = stuff->mask;
                    updateEventMask(pHead);
                    return Success;
                }
            }
        }

        /* build the entry */
        pNewEvent = (WMEventPtr)malloc(sizeof(WMEventRec));
        if (!pNewEvent)
            return BadAlloc;
        pNewEvent->next = 0;
        pNewEvent->client = client;
        pNewEvent->mask = stuff->mask;
        /*
         * add a resource that will be deleted when
         * the client goes away
         */
        clientResource = FakeClientID(client->index);
        pNewEvent->clientResource = clientResource;
        if (!AddResource(clientResource, ClientType, (void *)pNewEvent))
            return BadAlloc;
        /*
         * create a resource to contain a pointer to the list
         * of clients selecting input.  This must be indirect as
         * the list may be arbitrarily rearranged which cannot be
         * done through the resource database.
         */
        if (i != Success || !pHead) {
            pHead = (WMEventPtr *)malloc(sizeof(WMEventPtr));
            if (!pHead ||
                !AddResource(eventResource, EventType, (void *)pHead)) {
                FreeResource(clientResource, RT_NONE);
                return BadAlloc;
            }
            *pHead = 0;
        }
        pNewEvent->next = *pHead;
        *pHead = pNewEvent;
        updateEventMask(pHead);
    }
    else if (stuff->mask == 0) {
        /* delete the interest */
        if (i == Success && pHead) {
            pNewEvent = 0;
            for (pEvent = *pHead; pEvent; pEvent = pEvent->next) {
                if (pEvent->client == client)
                    break;
                pNewEvent = pEvent;
            }
            if (pEvent) {
                FreeResource(pEvent->clientResource, ClientType);
                if (pNewEvent)
                    pNewEvent->next = pEvent->next;
                else
                    *pHead = pEvent->next;
                free(pEvent);
                updateEventMask(pHead);
            }
        }
    }
    else {
        client->errorValue = stuff->mask;
        return BadValue;
    }
    return Success;
}
Beispiel #19
0
int
ProcRRSetCrtcConfig(ClientPtr client)
{
    REQUEST(xRRSetCrtcConfigReq);
    xRRSetCrtcConfigReply rep;
    ScreenPtr pScreen;
    rrScrPrivPtr pScrPriv;
    RRCrtcPtr crtc;
    RRModePtr mode;
    int numOutputs;
    RROutputPtr *outputs = NULL;
    RROutput *outputIds;
    TimeStamp configTime;
    TimeStamp time;
    Rotation rotation;
    int rc, i, j;

    REQUEST_AT_LEAST_SIZE(xRRSetCrtcConfigReq);
    numOutputs = (stuff->length - bytes_to_int32(SIZEOF(xRRSetCrtcConfigReq)));

    VERIFY_RR_CRTC(stuff->crtc, crtc, DixSetAttrAccess);

    if (stuff->mode == None) {
        mode = NULL;
        if (numOutputs > 0)
            return BadMatch;
    }
    else {
        VERIFY_RR_MODE(stuff->mode, mode, DixSetAttrAccess);
        if (numOutputs == 0)
            return BadMatch;
    }
    if (numOutputs) {
        outputs = malloc(numOutputs * sizeof(RROutputPtr));
        if (!outputs)
            return BadAlloc;
    }
    else
        outputs = NULL;

    outputIds = (RROutput *) (stuff + 1);
    for (i = 0; i < numOutputs; i++) {
        rc = dixLookupResourceByType((pointer *) (outputs + i), outputIds[i],
                                     RROutputType, client, DixSetAttrAccess);
        if (rc != Success) {
            free(outputs);
            return rc;
        }
        /* validate crtc for this output */
        for (j = 0; j < outputs[i]->numCrtcs; j++)
            if (outputs[i]->crtcs[j] == crtc)
                break;
        if (j == outputs[i]->numCrtcs) {
            free(outputs);
            return BadMatch;
        }
        /* validate mode for this output */
        for (j = 0; j < outputs[i]->numModes + outputs[i]->numUserModes; j++) {
            RRModePtr m = (j < outputs[i]->numModes ?
                           outputs[i]->modes[j] :
                           outputs[i]->userModes[j - outputs[i]->numModes]);
            if (m == mode)
                break;
        }
        if (j == outputs[i]->numModes + outputs[i]->numUserModes) {
            free(outputs);
            return BadMatch;
        }
    }
    /* validate clones */
    for (i = 0; i < numOutputs; i++) {
        for (j = 0; j < numOutputs; j++) {
            int k;

            if (i == j)
                continue;
            for (k = 0; k < outputs[i]->numClones; k++) {
                if (outputs[i]->clones[k] == outputs[j])
                    break;
            }
            if (k == outputs[i]->numClones) {
                free(outputs);
                return BadMatch;
            }
        }
    }

    pScreen = crtc->pScreen;
    pScrPriv = rrGetScrPriv(pScreen);

    time = ClientTimeToServerTime(stuff->timestamp);
    configTime = ClientTimeToServerTime(stuff->configTimestamp);

    if (!pScrPriv) {
        time = currentTime;
        rep.status = RRSetConfigFailed;
        goto sendReply;
    }

    /*
     * Validate requested rotation
     */
    rotation = (Rotation) stuff->rotation;

    /* test the rotation bits only! */
    switch (rotation & 0xf) {
    case RR_Rotate_0:
    case RR_Rotate_90:
    case RR_Rotate_180:
    case RR_Rotate_270:
        break;
    default:
        /*
         * Invalid rotation
         */
        client->errorValue = stuff->rotation;
        free(outputs);
        return BadValue;
    }

    if (mode) {
        if ((~crtc->rotations) & rotation) {
            /*
             * requested rotation or reflection not supported by screen
             */
            client->errorValue = stuff->rotation;
            free(outputs);
            return BadMatch;
        }

#ifdef RANDR_12_INTERFACE
        /*
         * Check screen size bounds if the DDX provides a 1.2 interface
         * for setting screen size. Else, assume the CrtcSet sets
         * the size along with the mode. If the driver supports transforms,
         * then it must allow crtcs to display a subset of the screen, so
         * only do this check for drivers without transform support.
         */
        if (pScrPriv->rrScreenSetSize && !crtc->transforms) {
            int source_width;
            int source_height;
            PictTransform transform;
            struct pixman_f_transform f_transform, f_inverse;

            RRTransformCompute(stuff->x, stuff->y,
                               mode->mode.width, mode->mode.height,
                               rotation,
                               &crtc->client_pending_transform,
                               &transform, &f_transform, &f_inverse);

            RRModeGetScanoutSize(mode, &transform, &source_width,
                                 &source_height);
            if (stuff->x + source_width > pScreen->width) {
                client->errorValue = stuff->x;
                free(outputs);
                return BadValue;
            }

            if (stuff->y + source_height > pScreen->height) {
                client->errorValue = stuff->y;
                free(outputs);
                return BadValue;
            }
        }
#endif
    }

    if (!RRCrtcSet(crtc, mode, stuff->x, stuff->y,
                   rotation, numOutputs, outputs)) {
        rep.status = RRSetConfigFailed;
        goto sendReply;
    }
    rep.status = RRSetConfigSuccess;
    pScrPriv->lastSetTime = time;

 sendReply:
    free(outputs);

    rep.type = X_Reply;
    /* rep.status has already been filled in */
    rep.length = 0;
    rep.sequenceNumber = client->sequence;
    rep.newTimestamp = pScrPriv->lastSetTime.milliseconds;

    if (client->swapped) {
        swaps(&rep.sequenceNumber);
        swapl(&rep.length);
        swapl(&rep.newTimestamp);
    }
    WriteToClient(client, sizeof(xRRSetCrtcConfigReply), (char *) &rep);

    return Success;
}
Beispiel #20
0
uchar usbFunctionWrite(uchar *data, uchar len)
{
    uchar i;
    uchar counter;
    uint8_t temp;

    if(len > bytesRemaining)                // if this is the last incomplete chunk
        len = bytesRemaining;               // limit to the amount we can store
    bytesRemaining -= len;
    for(i = 0; i < len; i++)
        buffer[currentPosition++] = data[i];

    if(bytesRemaining == 0) {
        switch(buffer[0]) {
        case CMD_READ_EEDATA:
            RESPONSE(read_eedata)->addr = REQUEST(read_eedata)->addr;
            RESPONSE(read_eedata)->value = eeprom_read_byte((uint8_t*)(uint16_t)REQUEST(read_eedata)->addr);

            buffer_len = sizeof(usb_response_read_eedata_t);
            break;
        case CMD_WRITE_EEDATA:
            RESPONSE(write_eedata)->result = 1;
            eeprom_write_byte((uint8_t*)(uint16_t)REQUEST(write_eedata)->addr, REQUEST(write_eedata)->value);
            buffer_len = sizeof(usb_response_write_eedata_t);
            break;
        case CMD_READ_VERSION:
            RESPONSE(read_version)->version_major = FIRMWARE_MAJOR;
            RESPONSE(read_version)->version_minor = FIRMWARE_MINOR;
            buffer_len = sizeof(usb_response_read_version_t);;
            break;
        case CMD_BOARD_TYPE:
            RESPONSE(board_type)->board_type = BOARD_TYPE_I2C;
            temp = eeprom_read_byte((uint8_t*)1);
            if((temp == 0) || (temp == 255))
                temp = 9;

            RESPONSE(board_type)->serial = temp;  // read from EEPROM address 1

#ifdef __AVR_ATmega88__
            RESPONSE(board_type)->proc_type = PROCESSOR_TYPE_A88;
#elif defined __AVR_ATmega168__
            RESPONSE(board_type)->proc_type = PROCESSOR_TYPE_A168;
#else
#warn "UNKNOWN PROC TYPE!"
            RESPONSE(board_type)->proc_type = PROCESSOR_TYPE_UNKNOWN;
#endif

            RESPONSE(board_type)->mhz = F_CPU/1000000;
            buffer_len = sizeof(usb_response_board_type_t);
            break;
        case CMD_BD_POWER_STATE:
            buffer_len = 0;
            break;
        case CMD_BD_POWER_INFO:
            buffer_len = 0;
            break;
        case CMD_I2C_READ:
            counter = REQUEST(i2c_read)->read_len;
            RESPONSE(i2c_read)->result = counter;
            buffer_len = REQUEST(i2c_read)->read_len + 1;

            if((i2cMasterSendNI(REQUEST(i2c_read)->device << 1, 1, &(REQUEST(i2c_read)->address)) == I2C_OK) &&
               (i2cMasterReceiveNI(REQUEST(i2c_read)->device << 1, counter, (u08*)&(RESPONSE(i2c_read)->data)) == I2C_OK)) {
                RESPONSE(i2c_read)->result = 1;
            } else {
                RESPONSE(i2c_read)->result = 0;
                *RESPONSE(i2c_read)->data = I2C_E_NODEV;
            }

            break;

        case CMD_I2C_WRITE:
            buffer_len = sizeof(usb_response_i2c_write_t);

            counter = REQUEST(i2c_write)->len - 2;
            RESPONSE(i2c_write)->result = counter;

            if(i2cMasterSendNI(REQUEST(i2c_write)->device << 1, counter + 1, &(REQUEST(i2c_write)->address)) == I2C_OK) {
                RESPONSE(i2c_write)->result = 1;
            } else {
                RESPONSE(i2c_write)->result = 0;
                RESPONSE(i2c_write)->extended_result = I2C_E_NODEV;
            }
            break;

        case CMD_RESET:
            break;
        }
    }

    return bytesRemaining == 0;             // return 1 if we have all data
}
static int
ProcShmPutImage(ClientPtr client)
{
    GCPtr pGC;
    DrawablePtr pDraw;
    long length;
    ShmDescPtr shmdesc;
    REQUEST(xShmPutImageReq);

    REQUEST_SIZE_MATCH(xShmPutImageReq);
    VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixWriteAccess);
    VERIFY_SHMPTR(stuff->shmseg, stuff->offset, FALSE, shmdesc, client);
    if ((stuff->sendEvent != xTrue) && (stuff->sendEvent != xFalse))
	return BadValue;
    if (stuff->format == XYBitmap)
    {
        if (stuff->depth != 1)
            return BadMatch;
        length = PixmapBytePad(stuff->totalWidth, 1);
    }
    else if (stuff->format == XYPixmap)
    {
        if (pDraw->depth != stuff->depth)
            return BadMatch;
        length = PixmapBytePad(stuff->totalWidth, 1);
	length *= stuff->depth;
    }
    else if (stuff->format == ZPixmap)
    {
        if (pDraw->depth != stuff->depth)
            return BadMatch;
        length = PixmapBytePad(stuff->totalWidth, stuff->depth);
    }
    else
    {
	client->errorValue = stuff->format;
        return BadValue;
    }

    /*
     * There's a potential integer overflow in this check:
     * VERIFY_SHMSIZE(shmdesc, stuff->offset, length * stuff->totalHeight,
     *                client);
     * the version below ought to avoid it
     */
    if (stuff->totalHeight != 0 &&
	length > (shmdesc->size - stuff->offset)/stuff->totalHeight) {
	client->errorValue = stuff->totalWidth;
	return BadValue;
    }
    if (stuff->srcX > stuff->totalWidth)
    {
	client->errorValue = stuff->srcX;
	return BadValue;
    }
    if (stuff->srcY > stuff->totalHeight)
    {
	client->errorValue = stuff->srcY;
	return BadValue;
    }
    if ((stuff->srcX + stuff->srcWidth) > stuff->totalWidth)
    {
	client->errorValue = stuff->srcWidth;
	return BadValue;
    }
    if ((stuff->srcY + stuff->srcHeight) > stuff->totalHeight)
    {
	client->errorValue = stuff->srcHeight;
	return BadValue;
    }

    if ((((stuff->format == ZPixmap) && (stuff->srcX == 0)) ||
	 ((stuff->format != ZPixmap) &&
	  (stuff->srcX < screenInfo.bitmapScanlinePad) &&
	  ((stuff->format == XYBitmap) ||
	   ((stuff->srcY == 0) &&
	    (stuff->srcHeight == stuff->totalHeight))))) &&
	((stuff->srcX + stuff->srcWidth) == stuff->totalWidth))
	(*pGC->ops->PutImage) (pDraw, pGC, stuff->depth,
			       stuff->dstX, stuff->dstY,
			       stuff->totalWidth, stuff->srcHeight,
			       stuff->srcX, stuff->format,
			       shmdesc->addr + stuff->offset +
			       (stuff->srcY * length));
    else
	doShmPutImage(pDraw, pGC, stuff->depth, stuff->format,
		      stuff->totalWidth, stuff->totalHeight,
		      stuff->srcX, stuff->srcY,
		      stuff->srcWidth, stuff->srcHeight,
		      stuff->dstX, stuff->dstY,
                      shmdesc->addr + stuff->offset);

    if (stuff->sendEvent)
    {
	xShmCompletionEvent ev;

	ev.type = ShmCompletionCode;
	ev.drawable = stuff->drawable;
	ev.minorEvent = X_ShmPutImage;
	ev.majorEvent = ShmReqCode;
	ev.shmseg = stuff->shmseg;
	ev.offset = stuff->offset;
	WriteEventsToClient(client, 1, (xEvent *) &ev);
    }

    return Success;
}
Beispiel #22
0
static int
ProcShapeGetRectangles(ClientPtr client)
{
    REQUEST(xShapeGetRectanglesReq);
    WindowPtr pWin;
    xShapeGetRectanglesReply rep;
    xRectangle *rects;
    int nrects, i, rc;
    RegionPtr region;

    REQUEST_SIZE_MATCH(xShapeGetRectanglesReq);
    rc = dixLookupWindow(&pWin, stuff->window, client, DixGetAttrAccess);
    if (rc != Success)
        return rc;
    switch (stuff->kind) {
    case ShapeBounding:
        region = wBoundingShape(pWin);
        break;
    case ShapeClip:
        region = wClipShape(pWin);
        break;
    case ShapeInput:
        region = wInputShape(pWin);
        break;
    default:
        client->errorValue = stuff->kind;
        return BadValue;
    }
    if (!region) {
        nrects = 1;
        rects = malloc(sizeof(xRectangle));
        if (!rects)
            return BadAlloc;
        switch (stuff->kind) {
        case ShapeBounding:
            rects->x = -(int) wBorderWidth(pWin);
            rects->y = -(int) wBorderWidth(pWin);
            rects->width = pWin->drawable.width + wBorderWidth(pWin);
            rects->height = pWin->drawable.height + wBorderWidth(pWin);
            break;
        case ShapeClip:
            rects->x = 0;
            rects->y = 0;
            rects->width = pWin->drawable.width;
            rects->height = pWin->drawable.height;
            break;
        case ShapeInput:
            rects->x = -(int) wBorderWidth(pWin);
            rects->y = -(int) wBorderWidth(pWin);
            rects->width = pWin->drawable.width + wBorderWidth(pWin);
            rects->height = pWin->drawable.height + wBorderWidth(pWin);
            break;
        }
    }
    else {
        BoxPtr box;

        nrects = RegionNumRects(region);
        box = RegionRects(region);
        rects = malloc(nrects * sizeof(xRectangle));
        if (!rects && nrects)
            return BadAlloc;
        for (i = 0; i < nrects; i++, box++) {
            rects[i].x = box->x1;
            rects[i].y = box->y1;
            rects[i].width = box->x2 - box->x1;
            rects[i].height = box->y2 - box->y1;
        }
    }

    rep.type = X_Reply;
    rep.ordering = YXBanded;
    rep.sequenceNumber = client->sequence;
    rep.length = bytes_to_int32(nrects * sizeof(xRectangle));
    rep.nrects = nrects;

    if (client->swapped) {
        swaps(&rep.sequenceNumber);
        swapl(&rep.length);
        swapl(&rep.nrects);
        SwapShorts((short *) rects, (unsigned long) nrects * 4);
    }
    WriteToClient(client, sizeof(rep), &rep);
    WriteToClient(client, nrects * sizeof(xRectangle), rects);
    free(rects);
    return Success;
}
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_NSCREENS_FORWARD_SKIP(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;
}
Beispiel #24
0
static int
proc_present_query_version(ClientPtr client)
{
    REQUEST(xPresentQueryVersionReq);
    xPresentQueryVersionReply rep = {
        .type = X_Reply,
        .sequenceNumber = client->sequence,
        .length = 0,
        .majorVersion = SERVER_PRESENT_MAJOR_VERSION,
        .minorVersion = SERVER_PRESENT_MINOR_VERSION
    };

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

#define VERIFY_FENCE_OR_NONE(fence_ptr, fence_id, client, access) do {  \
        if ((fence_id) == None)                                         \
            (fence_ptr) = NULL;                                         \
        else {                                                          \
            int __rc__ = SyncVerifyFence(&fence_ptr, fence_id, client, access); \
            if (__rc__ != Success)                                      \
                return __rc__;                                          \
        }                                                               \
    } while (0)

#define VERIFY_CRTC_OR_NONE(crtc_ptr, crtc_id, client, access) do {     \
        if ((crtc_id) == None)                                          \
            (crtc_ptr) = NULL;                                          \
        else {                                                          \
            VERIFY_RR_CRTC(crtc_id, crtc_ptr, access);                  \
        }                                                               \
    } while (0)

static int
proc_present_pixmap(ClientPtr client)
{
    REQUEST(xPresentPixmapReq);
    WindowPtr           window;
    PixmapPtr           pixmap;
    RegionPtr           valid = NULL;
    RegionPtr           update = NULL;
    SyncFence           *wait_fence;
    SyncFence           *idle_fence;
    RRCrtcPtr           target_crtc;
    int                 ret;
    int                 nnotifies;
    present_notify_ptr  notifies = NULL;

    REQUEST_AT_LEAST_SIZE(xPresentPixmapReq);
    ret = dixLookupWindow(&window, stuff->window, client, DixWriteAccess);
    if (ret != Success)
        return ret;
    ret = dixLookupResourceByType((void **) &pixmap, stuff->pixmap, RT_PIXMAP, client, DixReadAccess);
    if (ret != Success)
        return ret;

    if (window->drawable.depth != pixmap->drawable.depth)
        return BadMatch;

    VERIFY_REGION_OR_NONE(valid, stuff->valid, client, DixReadAccess);
    VERIFY_REGION_OR_NONE(update, stuff->update, client, DixReadAccess);

    VERIFY_CRTC_OR_NONE(target_crtc, stuff->target_crtc, client, DixReadAccess);

    VERIFY_FENCE_OR_NONE(wait_fence, stuff->wait_fence, client, DixReadAccess);
    VERIFY_FENCE_OR_NONE(idle_fence, stuff->idle_fence, client, DixWriteAccess);

    if (stuff->options & ~(PresentAllOptions)) {
        client->errorValue = stuff->options;
        return BadValue;
    }

    /*
     * Check to see if remainder is sane
     */
    if (stuff->divisor == 0) {
        if (stuff->remainder != 0) {
            client->errorValue = (CARD32) stuff->remainder;
            return BadValue;
        }
    } else {
        if (stuff->remainder >= stuff->divisor) {
            client->errorValue = (CARD32) stuff->remainder;
            return BadValue;
        }
    }

    nnotifies = (client->req_len << 2) - sizeof (xPresentPixmapReq);
    if (nnotifies % sizeof (xPresentNotify))
        return BadLength;

    nnotifies /= sizeof (xPresentNotify);
    if (nnotifies) {
        ret = present_create_notifies(client, nnotifies, (xPresentNotify *) (stuff + 1), &notifies);
        if (ret != Success)
            return ret;
    }

    ret = present_pixmap(window, pixmap, stuff->serial, valid, update,
                         stuff->x_off, stuff->y_off, target_crtc,
                         wait_fence, idle_fence, stuff->options,
                         stuff->target_msc, stuff->divisor, stuff->remainder, notifies, nnotifies);
    if (ret != Success)
        present_destroy_notifies(notifies, nnotifies);
    return ret;
}
Beispiel #25
0
static int
ProcShapeRectangles(ClientPtr client)
{
    WindowPtr pWin;

    REQUEST(xShapeRectanglesReq);
    xRectangle *prects;
    int nrects, ctype, rc;
    RegionPtr srcRgn;
    RegionPtr *destRgn;
    CreateDftPtr createDefault;

    REQUEST_AT_LEAST_SIZE(xShapeRectanglesReq);
    UpdateCurrentTime();
    rc = dixLookupWindow(&pWin, stuff->dest, client, DixSetAttrAccess);
    if (rc != Success)
        return rc;
    switch (stuff->destKind) {
    case ShapeBounding:
        createDefault = CreateBoundingShape;
        break;
    case ShapeClip:
        createDefault = CreateClipShape;
        break;
    case ShapeInput:
        createDefault = CreateBoundingShape;
        break;
    default:
        client->errorValue = stuff->destKind;
        return BadValue;
    }
    if ((stuff->ordering != Unsorted) && (stuff->ordering != YSorted) &&
        (stuff->ordering != YXSorted) && (stuff->ordering != YXBanded)) {
        client->errorValue = stuff->ordering;
        return BadValue;
    }
    nrects = ((stuff->length << 2) - sizeof(xShapeRectanglesReq));
    if (nrects & 4)
        return BadLength;
    nrects >>= 3;
    prects = (xRectangle *) &stuff[1];
    ctype = VerifyRectOrder(nrects, prects, (int) stuff->ordering);
    if (ctype < 0)
        return BadMatch;
    srcRgn = RegionFromRects(nrects, prects, ctype);

    if (!pWin->optional)
        MakeWindowOptional(pWin);
    switch (stuff->destKind) {
    case ShapeBounding:
        destRgn = &pWin->optional->boundingShape;
        break;
    case ShapeClip:
        destRgn = &pWin->optional->clipShape;
        break;
    case ShapeInput:
        destRgn = &pWin->optional->inputShape;
        break;
    default:
        return BadValue;
    }

    return RegionOperate(client, pWin, (int) stuff->destKind,
                         destRgn, srcRgn, (int) stuff->op,
                         stuff->xOff, stuff->yOff, createDefault);
}
int
ProcXIQueryDevice(ClientPtr client)
{
    xXIQueryDeviceReply rep;
    DeviceIntPtr dev = NULL;
    int rc = Success;
    int i = 0, len = 0;
    char *info, *ptr;
    Bool *skip = NULL;

    REQUEST(xXIQueryDeviceReq);
    REQUEST_SIZE_MATCH(xXIQueryDeviceReq);

    if (stuff->deviceid != XIAllDevices && stuff->deviceid != XIAllMasterDevices)
    {
        rc = dixLookupDevice(&dev, stuff->deviceid, client, DixGetAttrAccess);
        if (rc != Success)
        {
            client->errorValue = stuff->deviceid;
            return rc;
        }
        len += SizeDeviceInfo(dev);
    }
    else
    {
        skip = calloc(sizeof(Bool), inputInfo.numDevices);
        if (!skip)
            return BadAlloc;

        for (dev = inputInfo.devices; dev; dev = dev->next, i++)
        {
            skip[i] = ShouldSkipDevice(client, stuff->deviceid, dev);
            if (!skip[i])
                len += SizeDeviceInfo(dev);
        }

        for (dev = inputInfo.off_devices; dev; dev = dev->next, i++)
        {
            skip[i] = ShouldSkipDevice(client, stuff->deviceid, dev);
            if (!skip[i])
                len += SizeDeviceInfo(dev);
        }
    }

    info = calloc(1, len);
    if (!info) {
        free(skip);
        return BadAlloc;
    }

    memset(&rep, 0, sizeof(xXIQueryDeviceReply));
    rep.repType = X_Reply;
    rep.RepType = X_XIQueryDevice;
    rep.sequenceNumber = client->sequence;
    rep.length = len/4;
    rep.num_devices = 0;

    ptr = info;
    if (dev)
    {
        len = ListDeviceInfo(client, dev, (xXIDeviceInfo*)info);
        if (client->swapped)
            SwapDeviceInfo(dev, (xXIDeviceInfo*)info);
        info += len;
        rep.num_devices = 1;
    } else
    {
        i = 0;
        for (dev = inputInfo.devices; dev; dev = dev->next, i++)
        {
            if (!skip[i])
            {
                len = ListDeviceInfo(client, dev, (xXIDeviceInfo*)info);
                if (client->swapped)
                    SwapDeviceInfo(dev, (xXIDeviceInfo*)info);
                info += len;
                rep.num_devices++;
            }
        }

        for (dev = inputInfo.off_devices; dev; dev = dev->next, i++)
        {
            if (!skip[i])
            {
                len = ListDeviceInfo(client, dev, (xXIDeviceInfo*)info);
                if (client->swapped)
                    SwapDeviceInfo(dev, (xXIDeviceInfo*)info);
                info += len;
                rep.num_devices++;
            }
        }
    }

    WriteReplyToClient(client, sizeof(xXIQueryDeviceReply), &rep);
    WriteToClient(client, rep.length * 4, ptr);
    free(ptr);
    free(skip);
    return rc;
}
Beispiel #27
0
static int
ProcShapeCombine(ClientPtr client)
{
    WindowPtr pSrcWin, pDestWin;

    REQUEST(xShapeCombineReq);
    RegionPtr srcRgn;
    RegionPtr *destRgn;
    CreateDftPtr createDefault;
    CreateDftPtr createSrc;
    RegionPtr tmp;
    int rc;

    REQUEST_SIZE_MATCH(xShapeCombineReq);
    UpdateCurrentTime();
    rc = dixLookupWindow(&pDestWin, stuff->dest, client, DixSetAttrAccess);
    if (rc != Success)
        return rc;
    if (!pDestWin->optional)
        MakeWindowOptional(pDestWin);
    switch (stuff->destKind) {
    case ShapeBounding:
        createDefault = CreateBoundingShape;
        break;
    case ShapeClip:
        createDefault = CreateClipShape;
        break;
    case ShapeInput:
        createDefault = CreateBoundingShape;
        break;
    default:
        client->errorValue = stuff->destKind;
        return BadValue;
    }

    rc = dixLookupWindow(&pSrcWin, stuff->src, client, DixGetAttrAccess);
    if (rc != Success)
        return rc;
    switch (stuff->srcKind) {
    case ShapeBounding:
        srcRgn = wBoundingShape(pSrcWin);
        createSrc = CreateBoundingShape;
        break;
    case ShapeClip:
        srcRgn = wClipShape(pSrcWin);
        createSrc = CreateClipShape;
        break;
    case ShapeInput:
        srcRgn = wInputShape(pSrcWin);
        createSrc = CreateBoundingShape;
        break;
    default:
        client->errorValue = stuff->srcKind;
        return BadValue;
    }
    if (pSrcWin->drawable.pScreen != pDestWin->drawable.pScreen) {
        return BadMatch;
    }

    if (srcRgn) {
        tmp = RegionCreate((BoxPtr) 0, 0);
        RegionCopy(tmp, srcRgn);
        srcRgn = tmp;
    }
    else
        srcRgn = (*createSrc) (pSrcWin);

    if (!pDestWin->optional)
        MakeWindowOptional(pDestWin);
    switch (stuff->destKind) {
    case ShapeBounding:
        destRgn = &pDestWin->optional->boundingShape;
        break;
    case ShapeClip:
        destRgn = &pDestWin->optional->clipShape;
        break;
    case ShapeInput:
        destRgn = &pDestWin->optional->inputShape;
        break;
    default:
        return BadValue;
    }

    return RegionOperate(client, pDestWin, (int) stuff->destKind,
                         destRgn, srcRgn, (int) stuff->op,
                         stuff->xOff, stuff->yOff, createDefault);
}
Beispiel #28
0
/** Composite glyphs on each screen into the requested picture.  If
 *  either the src or dest picture has not been allocated due to lazy
 *  window creation, this request will gracefully return. */
static int dmxProcRenderCompositeGlyphs(ClientPtr client)
{
    int  ret;
    REQUEST(xRenderCompositeGlyphsReq);

    ret = dmxSaveRenderVector[stuff->renderReqType](client);

    /* For the following to work with PanoramiX, it assumes that Render
     * wraps the ProcRenderVector after dmxRenderInit has been called.
     */
    if (ret == Success) {
	PicturePtr         pSrc;
	dmxPictPrivPtr     pSrcPriv;
	PicturePtr         pDst;
	dmxPictPrivPtr     pDstPriv;
	PictFormatPtr      pFmt;
	XRenderPictFormat *pFormat;
	int                size;

	int                scrnNum;
	DMXScreenInfo     *dmxScreen;

	CARD8             *buffer;
	CARD8             *end;
	int                space;

	int                nglyph;
	char              *glyphs;
	char              *curGlyph;

	xGlyphElt         *elt;
	int                nelt;
	XGlyphElt8        *elts;
	XGlyphElt8        *curElt;

	GlyphSetPtr        glyphSet;
	dmxGlyphPrivPtr    glyphPriv;

	pSrc = SecurityLookupIDByType(client, stuff->src, PictureType,
				      DixReadAccess);
	pSrcPriv = DMX_GET_PICT_PRIV(pSrc);
	if (!pSrcPriv->pict)
	    return ret;

	pDst = SecurityLookupIDByType(client, stuff->dst, PictureType,
				      DixWriteAccess);
	pDstPriv = DMX_GET_PICT_PRIV(pDst);
	if (!pDstPriv->pict)
	    return ret;

	scrnNum = pDst->pDrawable->pScreen->myNum;
	dmxScreen = &dmxScreens[scrnNum];

	/* Note: If the back-end display has been detached, then it
	 * should not be possible to reach here since the pSrcPriv->pict
	 * and pDstPriv->pict will have already been set to 0.
	 */
	if (!dmxScreen->beDisplay)
	    return ret;

	if (stuff->maskFormat)
	    pFmt = SecurityLookupIDByType(client, stuff->maskFormat,
					  PictFormatType, DixReadAccess);
	else
	    pFmt = NULL;

	pFormat = dmxFindFormat(dmxScreen, pFmt);

	switch (stuff->renderReqType) {
	case X_RenderCompositeGlyphs8:  size = sizeof(CARD8);  break;
	case X_RenderCompositeGlyphs16: size = sizeof(CARD16); break;
	case X_RenderCompositeGlyphs32: size = sizeof(CARD32); break;
        default:                        return BadPictOp; /* Can't happen */
	}

	buffer = (CARD8 *)(stuff + 1);
	end = (CARD8 *)stuff + (stuff->length << 2);
	nelt = 0;
	nglyph = 0;
	while (buffer + sizeof(xGlyphElt) < end) {
	    elt = (xGlyphElt *)buffer;
	    buffer += sizeof(xGlyphElt);

	    if (elt->len == 0xff) {
		buffer += 4;
	    } else {
		nelt++;
		nglyph += elt->len;
		space = size * elt->len;
		if (space & 3) space += 4 - (space & 3);
		buffer += space;
	    }
	}

	/* The following only works for Render version > 0.2 */

	/* All of the XGlyphElt* structure sizes are identical */
	elts = xalloc(nelt * sizeof(XGlyphElt8));
	if (!elts)
	    return BadAlloc;

	glyphs = xalloc(nglyph * size);
	if (!glyphs) {
	    xfree(elts);
	    return BadAlloc;
	}

	buffer = (CARD8 *)(stuff + 1);
	end = (CARD8 *)stuff + (stuff->length << 2);
	curGlyph = glyphs;
	curElt = elts;

	glyphSet = SecurityLookupIDByType(client, stuff->glyphset,
					  GlyphSetType, DixReadAccess);
	glyphPriv = DMX_GET_GLYPH_PRIV(glyphSet);

	while (buffer + sizeof(xGlyphElt) < end) {
	    elt = (xGlyphElt *)buffer;
	    buffer += sizeof(xGlyphElt);

	    if (elt->len == 0xff) {
		glyphSet = SecurityLookupIDByType(client,
						  *((CARD32 *)buffer),
						  GlyphSetType,
						  DixReadAccess);
		glyphPriv = DMX_GET_GLYPH_PRIV(glyphSet);
		buffer += 4;
	    } else {
		curElt->glyphset = glyphPriv->glyphSets[scrnNum];
		curElt->xOff = elt->deltax;
		curElt->yOff = elt->deltay;
		curElt->nchars = elt->len;
		curElt->chars = curGlyph;

		memcpy(curGlyph, buffer, size*elt->len);
		curGlyph += size * elt->len;

		curElt++;

		space = size * elt->len;
		if (space & 3) space += 4 - (space & 3);
		buffer += space;
	    }
	}

	switch (stuff->renderReqType) {
	case X_RenderCompositeGlyphs8:
	    XRenderCompositeText8(dmxScreen->beDisplay, stuff->op,
				  pSrcPriv->pict, pDstPriv->pict,
				  pFormat,
				  stuff->xSrc, stuff->ySrc,
				  0, 0, elts, nelt);
	    break;
	case X_RenderCompositeGlyphs16:
	    XRenderCompositeText16(dmxScreen->beDisplay, stuff->op,
				   pSrcPriv->pict, pDstPriv->pict,
				   pFormat,
				   stuff->xSrc, stuff->ySrc,
				   0, 0, (XGlyphElt16 *)elts, nelt);
	    break;
	case X_RenderCompositeGlyphs32:
	    XRenderCompositeText32(dmxScreen->beDisplay, stuff->op,
				   pSrcPriv->pict, pDstPriv->pict,
				   pFormat,
				   stuff->xSrc, stuff->ySrc,
				   0, 0, (XGlyphElt32 *)elts, nelt);
	    break;
	}

	dmxSync(dmxScreen, FALSE);

	xfree(elts);
	xfree(glyphs);
    }

    return ret;
}
Beispiel #29
0
static int
ProcShapeSelectInput(ClientPtr client)
{
    REQUEST(xShapeSelectInputReq);
    WindowPtr pWin;
    ShapeEventPtr pShapeEvent, pNewShapeEvent, *pHead;
    XID clientResource;
    int rc;

    REQUEST_SIZE_MATCH(xShapeSelectInputReq);
    rc = dixLookupWindow(&pWin, stuff->window, client, DixReceiveAccess);
    if (rc != Success)
        return rc;
    rc = dixLookupResourceByType((pointer *) &pHead, pWin->drawable.id,
                                 ShapeEventType, client, DixWriteAccess);
    if (rc != Success && rc != BadValue)
        return rc;

    switch (stuff->enable) {
    case xTrue:
        if (pHead) {

            /* check for existing entry. */
            for (pShapeEvent = *pHead;
                 pShapeEvent; pShapeEvent = pShapeEvent->next) {
                if (pShapeEvent->client == client)
                    return Success;
            }
        }

        /* build the entry */
        pNewShapeEvent = malloc(sizeof(ShapeEventRec));
        if (!pNewShapeEvent)
            return BadAlloc;
        pNewShapeEvent->next = 0;
        pNewShapeEvent->client = client;
        pNewShapeEvent->window = pWin;
        /*
         * add a resource that will be deleted when
         * the client goes away
         */
        clientResource = FakeClientID(client->index);
        pNewShapeEvent->clientResource = clientResource;
        if (!AddResource(clientResource, ClientType, (pointer) pNewShapeEvent))
            return BadAlloc;
        /*
         * create a resource to contain a pointer to the list
         * of clients selecting input.  This must be indirect as
         * the list may be arbitrarily rearranged which cannot be
         * done through the resource database.
         */
        if (!pHead) {
            pHead = malloc(sizeof(ShapeEventPtr));
            if (!pHead ||
                !AddResource(pWin->drawable.id, ShapeEventType,
                             (pointer) pHead)) {
                FreeResource(clientResource, RT_NONE);
                return BadAlloc;
            }
            *pHead = 0;
        }
        pNewShapeEvent->next = *pHead;
        *pHead = pNewShapeEvent;
        break;
    case xFalse:
        /* delete the interest */
        if (pHead) {
            pNewShapeEvent = 0;
            for (pShapeEvent = *pHead; pShapeEvent;
                 pShapeEvent = pShapeEvent->next) {
                if (pShapeEvent->client == client)
                    break;
                pNewShapeEvent = pShapeEvent;
            }
            if (pShapeEvent) {
                FreeResource(pShapeEvent->clientResource, ClientType);
                if (pNewShapeEvent)
                    pNewShapeEvent->next = pShapeEvent->next;
                else
                    *pHead = pShapeEvent->next;
                free(pShapeEvent);
            }
        }
        break;
    default:
        client->errorValue = stuff->enable;
        return BadValue;
    }
    return Success;
}
Beispiel #30
0
int
winProcSetSelectionOwner(ClientPtr client)
{
    int i;
    DrawablePtr pDrawable;
    WindowPtr pWindow = None;
    Bool fOwnedToNotOwned = FALSE;
    static Window s_iOwners[CLIP_NUM_SELECTIONS] = { None };
    static unsigned long s_ulServerGeneration = 0;

    REQUEST(xSetSelectionOwnerReq);

    REQUEST_SIZE_MATCH(xSetSelectionOwnerReq);

    winDebug("winProcSetSelectionOwner - Hello.\n");

    /* Watch for server reset */
    if (s_ulServerGeneration != serverGeneration) {
        /* Save new generation number */
        s_ulServerGeneration = serverGeneration;

        /* Initialize static variables */
        for (i = 0; i < CLIP_NUM_SELECTIONS; ++i)
            s_iOwners[i] = None;
    }

    /* Abort if clipboard not completely initialized yet */
    if (!g_fClipboardStarted) {
        /* ErrorF ("winProcSetSelectionOwner - Clipboard not yet started, "
           "aborting.\n"); */
        goto winProcSetSelectionOwner_Done;
    }

    /* Grab window if we have one */
    if (None != stuff->window) {
        /* Grab the Window from the request */
        int rc =
            dixLookupWindow(&pWindow, stuff->window, client, DixReadAccess);
        if (rc != Success) {
            ErrorF("winProcSetSelectionOwner - Found BadWindow, aborting.\n");
            goto winProcSetSelectionOwner_Done;
        }
    }

    /* Now we either have a valid window or None */

    /* Save selection owners for monitored selections, ignore other selections */
    if (XA_PRIMARY == stuff->selection) {
        /* Look for owned -> not owned transition */
        if (None == stuff->window && None != s_iOwners[CLIP_OWN_PRIMARY]) {
            fOwnedToNotOwned = TRUE;

            winDebug("winProcSetSelectionOwner - PRIMARY - Going from "
                     "owned to not owned.\n");

            /* Adjust last owned selection */
            if (None != s_iOwners[CLIP_OWN_CLIPBOARD])
                g_atomLastOwnedSelection = MakeAtom("CLIPBOARD", 9, TRUE);
            else
                g_atomLastOwnedSelection = None;
        }

        /* Save new selection owner or None */
        s_iOwners[CLIP_OWN_PRIMARY] = stuff->window;

        winDebug("winProcSetSelectionOwner - PRIMARY - Now owned by: %d\n",
                 stuff->window);
    }
    else if (MakeAtom("CLIPBOARD", 9, TRUE) == stuff->selection) {
        /* Look for owned -> not owned transition */
        if (None == stuff->window && None != s_iOwners[CLIP_OWN_CLIPBOARD]) {
            fOwnedToNotOwned = TRUE;

            winDebug("winProcSetSelectionOwner - CLIPBOARD - Going from "
                     "owned to not owned.\n");

            /* Adjust last owned selection */
            if (None != s_iOwners[CLIP_OWN_PRIMARY])
                g_atomLastOwnedSelection = XA_PRIMARY;
            else
                g_atomLastOwnedSelection = None;
        }

        /* Save new selection owner or None */
        s_iOwners[CLIP_OWN_CLIPBOARD] = stuff->window;

        winDebug("winProcSetSelectionOwner - CLIPBOARD - Now owned by: %d\n",
                 stuff->window);

    }
    else
        goto winProcSetSelectionOwner_Done;

    /*
     * At this point, if one of the selections is still owned by the
     * clipboard manager then it should be marked as unowned since
     * we will be taking ownership of the Win32 clipboard.
     */
    if (g_iClipboardWindow == s_iOwners[CLIP_OWN_PRIMARY])
        s_iOwners[CLIP_OWN_PRIMARY] = None;
    if (g_iClipboardWindow == s_iOwners[CLIP_OWN_CLIPBOARD])
        s_iOwners[CLIP_OWN_CLIPBOARD] = None;

    /*
     * Handle case when selection is being disowned,
     * WM_DRAWCLIPBOARD did not do the disowning,
     * both monitored selections are no longer owned,
     * an owned to not owned transition was detected,
     * and we currently own the Win32 clipboard.
     */
    if (stuff->window == None
            && s_iOwners[CLIP_OWN_PRIMARY] == None
            && s_iOwners[CLIP_OWN_CLIPBOARD] == None
            && fOwnedToNotOwned
            && g_hwndClipboard != NULL && g_hwndClipboard == GetClipboardOwner()) {
        winDebug("winProcSetSelectionOwner - We currently own the "
                 "clipboard and neither the PRIMARY nor the CLIPBOARD "
                 "selections are owned, releasing ownership of Win32 "
                 "clipboard.\n");

        /* Release ownership of the Windows clipboard */
        OpenClipboard(NULL);
        EmptyClipboard();
        CloseClipboard();

        goto winProcSetSelectionOwner_Done;
    }

    /* Abort if no window at this point */
    if (None == stuff->window) {
        winDebug("winProcSetSelectionOwner - No window, returning.\n");
        goto winProcSetSelectionOwner_Done;
    }

    /* Abort if invalid selection */
    if (!ValidAtom(stuff->selection)) {
        ErrorF("winProcSetSelectionOwner - Found BadAtom, aborting.\n");
        goto winProcSetSelectionOwner_Done;
    }

    /* Cast Window to Drawable */
    pDrawable = (DrawablePtr) pWindow;

    /* Abort if clipboard manager is owning the selection */
    if (pDrawable->id == g_iClipboardWindow) {
        winDebug("winProcSetSelectionOwner - We changed ownership, "
                 "aborting.\n");
        goto winProcSetSelectionOwner_Done;
    }

    /* Abort if root window is taking ownership */
    if (pDrawable->id == 0) {
        ErrorF("winProcSetSelectionOwner - Root window taking ownership, "
               "aborting\n");
        goto winProcSetSelectionOwner_Done;
    }

    /* Close clipboard if we have it open already */
    if (GetOpenClipboardWindow() == g_hwndClipboard) {
        CloseClipboard();
    }

    /* Access the Windows clipboard */
    if (!OpenClipboard(g_hwndClipboard)) {
        ErrorF("winProcSetSelectionOwner - OpenClipboard () failed: %08x\n",
               (int) GetLastError());
        goto winProcSetSelectionOwner_Done;
    }

    /* Take ownership of the Windows clipboard */
    if (!EmptyClipboard()) {
        ErrorF("winProcSetSelectionOwner - EmptyClipboard () failed: %08x\n",
               (int) GetLastError());
        goto winProcSetSelectionOwner_Done;
    }

    /* Advertise regular text and unicode */
    SetClipboardData(CF_UNICODETEXT, NULL);
    SetClipboardData(CF_TEXT, NULL);

    /* Save handle to last owned selection */
    g_atomLastOwnedSelection = stuff->selection;

    /* Release the clipboard */
    if (!CloseClipboard()) {
        ErrorF("winProcSetSelectionOwner - CloseClipboard () failed: "
               "%08x\n", (int) GetLastError());
        goto winProcSetSelectionOwner_Done;
    }

winProcSetSelectionOwner_Done:
    return (*winProcSetSelectionOwnerOrig) (client);
}