static int ProcXvQueryBestSize(ClientPtr client) { int status; unsigned int actual_width, actual_height; XvPortPtr pPort; xvQueryBestSizeReply rep; REQUEST(xvQueryBestSizeReq); REQUEST_SIZE_MATCH(xvQueryBestSizeReq); VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess); if ((status = _AllocatePort(stuff->port, pPort)) != Success) { client->errorValue = stuff->port; return status; } rep.type = X_Reply; rep.sequenceNumber = client->sequence; rep.length = 0; (* pPort->pAdaptor->ddQueryBestSize)(client, pPort, stuff->motion, stuff->vid_w, stuff->vid_h, stuff->drw_w, stuff->drw_h, &actual_width, &actual_height); rep.actual_width = actual_width; rep.actual_height = actual_height; _WriteQueryBestSizeReply(client, &rep); return Success; }
static int ProcXvSetPortAttribute(ClientPtr client) { int status; XvPortPtr pPort; REQUEST(xvSetPortAttributeReq); REQUEST_SIZE_MATCH(xvSetPortAttributeReq); VALIDATE_XV_PORT(stuff->port, pPort, DixSetAttrAccess); if ((status = _AllocatePort(stuff->port, pPort)) != Success) { client->errorValue = stuff->port; return status; } if (!ValidAtom(stuff->attribute)) { client->errorValue = stuff->attribute; return BadAtom; } status = XvdiSetPortAttribute(client, pPort, stuff->attribute, stuff->value); if (status == BadMatch) client->errorValue = stuff->attribute; else client->errorValue = stuff->value; return status; }
static int ProcXvGrabPort(ClientPtr client) { int result, status; XvPortPtr pPort; xvGrabPortReply rep; REQUEST(xvGrabPortReq); REQUEST_SIZE_MATCH(xvGrabPortReq); VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess); if ((status = _AllocatePort(stuff->port, pPort)) != Success) { client->errorValue = stuff->port; return status; } status = XvdiGrabPort(client, pPort, stuff->time, &result); if (status != Success) { return status; } rep.type = X_Reply; rep.sequenceNumber = client->sequence; rep.length = 0; rep.result = result; _WriteGrabPortReply(client, &rep); return Success; }
static int ProcXvQueryEncodings(ClientPtr client) { xvEncodingInfo einfo; xvQueryEncodingsReply rep; int totalSize; int nameSize; XvPortPtr pPort; int ne; XvEncodingPtr pe; int status; REQUEST(xvQueryEncodingsReq); REQUEST_SIZE_MATCH(xvQueryEncodingsReq); VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess); if ((status = _AllocatePort(stuff->port, pPort)) != Success) { client->errorValue = stuff->port; return status; } rep.type = X_Reply; rep.sequenceNumber = client->sequence; rep.num_encodings = pPort->pAdaptor->nEncodings; /* FOR EACH ENCODING ADD UP THE BYTES FOR ENCODING NAMES */ ne = pPort->pAdaptor->nEncodings; pe = pPort->pAdaptor->pEncodings; totalSize = ne * sz_xvEncodingInfo; while (ne--) { totalSize += pad_to_int32(strlen(pe->name)); pe++; } rep.length = bytes_to_int32(totalSize); _WriteQueryEncodingsReply(client, &rep); ne = pPort->pAdaptor->nEncodings; pe = pPort->pAdaptor->pEncodings; while (ne--) { einfo.encoding = pe->id; einfo.name_size = nameSize = strlen(pe->name); einfo.width = pe->width; einfo.height = pe->height; einfo.rate.numerator = pe->rate.numerator; einfo.rate.denominator = pe->rate.denominator; _WriteEncodingInfo(client, &einfo); WriteToClient(client, nameSize, pe->name); pe++; } return Success; }
static int ProcXvQueryPortAttributes(ClientPtr client) { int status, size, i; XvPortPtr pPort; XvAttributePtr pAtt; xvQueryPortAttributesReply rep; xvAttributeInfo Info; REQUEST(xvQueryPortAttributesReq); REQUEST_SIZE_MATCH(xvQueryPortAttributesReq); VALIDATE_XV_PORT(stuff->port, pPort, DixGetAttrAccess); if ((status = _AllocatePort(stuff->port, pPort)) != Success) { client->errorValue = stuff->port; return status; } rep.type = X_Reply; rep.sequenceNumber = client->sequence; rep.num_attributes = pPort->pAdaptor->nAttributes; rep.text_size = 0; for(i = 0, pAtt = pPort->pAdaptor->pAttributes; i < pPort->pAdaptor->nAttributes; i++, pAtt++) { rep.text_size += pad_to_int32(strlen(pAtt->name) + 1); } rep.length = (pPort->pAdaptor->nAttributes * sz_xvAttributeInfo) + rep.text_size; rep.length >>= 2; _WriteQueryPortAttributesReply(client, &rep); for(i = 0, pAtt = pPort->pAdaptor->pAttributes; i < pPort->pAdaptor->nAttributes; i++, pAtt++) { size = strlen(pAtt->name) + 1; /* pass the NULL */ Info.flags = pAtt->flags; Info.min = pAtt->min_value; Info.max = pAtt->max_value; Info.size = pad_to_int32(size); _WriteAttributeInfo(client, &Info); WriteToClient(client, size, pAtt->name); } return Success; }
static int ProcXvListImageFormats(ClientPtr client) { XvPortPtr pPort; XvImagePtr pImage; int i; xvListImageFormatsReply rep; xvImageFormatInfo info; REQUEST(xvListImageFormatsReq); REQUEST_SIZE_MATCH(xvListImageFormatsReq); VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess); rep.type = X_Reply; rep.sequenceNumber = client->sequence; rep.num_formats = pPort->pAdaptor->nImages; rep.length = bytes_to_int32(pPort->pAdaptor->nImages * sz_xvImageFormatInfo); _WriteListImageFormatsReply(client, &rep); pImage = pPort->pAdaptor->pImages; for(i = 0; i < pPort->pAdaptor->nImages; i++, pImage++) { info.id = pImage->id; info.type = pImage->type; info.byte_order = pImage->byte_order; memcpy(&info.guid, pImage->guid, 16); info.bpp = pImage->bits_per_pixel; info.num_planes = pImage->num_planes; info.depth = pImage->depth; info.red_mask = pImage->red_mask; info.green_mask = pImage->green_mask; info.blue_mask = pImage->blue_mask; info.format = pImage->format; info.y_sample_bits = pImage->y_sample_bits; info.u_sample_bits = pImage->u_sample_bits; info.v_sample_bits = pImage->v_sample_bits; info.horz_y_period = pImage->horz_y_period; info.horz_u_period = pImage->horz_u_period; info.horz_v_period = pImage->horz_v_period; info.vert_y_period = pImage->vert_y_period; info.vert_u_period = pImage->vert_u_period; info.vert_v_period = pImage->vert_v_period; memcpy(&info.comp_order, pImage->component_order, 32); info.scanline_order = pImage->scanline_order; _WriteImageFormatInfo(client, &info); } return Success; }
static int ProcXvMCListSurfaceTypes(ClientPtr client) { XvPortPtr pPort; int i; XvMCScreenPtr pScreenPriv; xvmcListSurfaceTypesReply rep; xvmcSurfaceInfo info; XvMCAdaptorPtr adaptor = NULL; XvMCSurfaceInfoPtr surface; REQUEST(xvmcListSurfaceTypesReq); REQUEST_SIZE_MATCH(xvmcListSurfaceTypesReq); VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess); if(XvMCInUse) { /* any adaptors at all */ ScreenPtr pScreen = pPort->pAdaptor->pScreen; if((pScreenPriv = XVMC_GET_PRIVATE(pScreen))) { /* any this screen */ for(i = 0; i < pScreenPriv->num_adaptors; i++) { if(pPort->pAdaptor == pScreenPriv->adaptors[i].xv_adaptor) { adaptor = &(pScreenPriv->adaptors[i]); break; } } } } rep.type = X_Reply; rep.sequenceNumber = client->sequence; rep.num = (adaptor) ? adaptor->num_surfaces : 0; rep.length = bytes_to_int32(rep.num * sizeof(xvmcSurfaceInfo)); WriteToClient(client, sizeof(xvmcListSurfaceTypesReply), (char*)&rep); for(i = 0; i < rep.num; i++) { surface = adaptor->surfaces[i]; info.surface_type_id = surface->surface_type_id; info.chroma_format = surface->chroma_format; info.max_width = surface->max_width; info.max_height = surface->max_height; info.subpicture_max_width = surface->subpicture_max_width; info.subpicture_max_height = surface->subpicture_max_height; info.mc_type = surface->mc_type; info.flags = surface->flags; WriteToClient(client, sizeof(xvmcSurfaceInfo), (char*)&info); } return Success; }
static int ProcXvUngrabPort(ClientPtr client) { int status; XvPortPtr pPort; REQUEST(xvGrabPortReq); REQUEST_SIZE_MATCH(xvGrabPortReq); VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess); if ((status = _AllocatePort(stuff->port, pPort)) != Success) { client->errorValue = stuff->port; return status; } return XvdiUngrabPort(client, pPort, stuff->time); }
static int ProcXvSelectPortNotify(ClientPtr client) { int status; XvPortPtr pPort; REQUEST(xvSelectPortNotifyReq); REQUEST_SIZE_MATCH(xvSelectPortNotifyReq); VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess); if ((status = _AllocatePort(stuff->port, pPort)) != Success) { client->errorValue = stuff->port; return status; } return XvdiSelectPortNotify(client, pPort, stuff->onoff); }
static int ProcXvGetPortAttribute(ClientPtr client) { INT32 value; int status; XvPortPtr pPort; xvGetPortAttributeReply rep; REQUEST(xvGetPortAttributeReq); REQUEST_SIZE_MATCH(xvGetPortAttributeReq); VALIDATE_XV_PORT(stuff->port, pPort, DixGetAttrAccess); if ((status = _AllocatePort(stuff->port, pPort)) != Success) { client->errorValue = stuff->port; return status; } if (!ValidAtom(stuff->attribute)) { client->errorValue = stuff->attribute; return BadAtom; } status = XvdiGetPortAttribute(client, pPort, stuff->attribute, &value); if (status != Success) { client->errorValue = stuff->attribute; return status; } rep.type = X_Reply; rep.sequenceNumber = client->sequence; rep.length = 0; rep.value = value; _WriteGetPortAttributeReply(client, &rep); return Success; }
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 ProcXvGetStill(ClientPtr client) { DrawablePtr pDraw; XvPortPtr pPort; GCPtr pGC; int status; REQUEST(xvGetStillReq); REQUEST_SIZE_MATCH(xvGetStillReq); VALIDATE_DRAWABLE_AND_GC(stuff->drawable, pDraw, DixReadAccess); VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess); if ((status = _AllocatePort(stuff->port, pPort)) != Success) { client->errorValue = stuff->port; return status; } if (!(pPort->pAdaptor->type & XvOutputMask) || !(pPort->pAdaptor->type & XvStillMask)) { client->errorValue = stuff->port; return BadMatch; } status = XvdiMatchPort(pPort, pDraw); if (status != Success) { return status; } return XvdiGetStill(client, pDraw, pPort, pGC, stuff->vid_x, stuff->vid_y, stuff->vid_w, stuff->vid_h, stuff->drw_x, stuff->drw_y, stuff->drw_w, stuff->drw_h); }
static int ProcXvMCCreateContext(ClientPtr client) { XvPortPtr pPort; CARD32 *data = NULL; int dwords = 0; int i, result, adapt_num = -1; ScreenPtr pScreen; XvMCContextPtr pContext; XvMCScreenPtr pScreenPriv; XvMCAdaptorPtr adaptor = NULL; XvMCSurfaceInfoPtr surface = NULL; xvmcCreateContextReply rep; REQUEST(xvmcCreateContextReq); REQUEST_SIZE_MATCH(xvmcCreateContextReq); VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess); pScreen = pPort->pAdaptor->pScreen; if(!XvMCInUse) /* no XvMC adaptors */ return BadMatch; if(!(pScreenPriv = XVMC_GET_PRIVATE(pScreen))) /* none this screen */ return BadMatch; for(i = 0; i < pScreenPriv->num_adaptors; i++) { if(pPort->pAdaptor == pScreenPriv->adaptors[i].xv_adaptor) { adaptor = &(pScreenPriv->adaptors[i]); adapt_num = i; break; } } if(adapt_num < 0) /* none this port */ return BadMatch; for(i = 0; i < adaptor->num_surfaces; i++) { if(adaptor->surfaces[i]->surface_type_id == stuff->surface_type_id) { surface = adaptor->surfaces[i]; break; } } /* adaptor doesn't support this suface_type_id */ if(!surface) return BadMatch; if((stuff->width > surface->max_width) || (stuff->height > surface->max_height)) return BadValue; if(!(pContext = malloc(sizeof(XvMCContextRec)))) { return BadAlloc; } pContext->pScreen = pScreen; pContext->adapt_num = adapt_num; pContext->context_id = stuff->context_id; pContext->surface_type_id = stuff->surface_type_id; pContext->width = stuff->width; pContext->height = stuff->height; pContext->flags = stuff->flags; pContext->refcnt = 1; result = (*adaptor->CreateContext)(pPort, pContext, &dwords, &data); if(result != Success) { free(pContext); return result; } rep.type = X_Reply; rep.sequenceNumber = client->sequence; rep.width_actual = pContext->width; rep.height_actual = pContext->height; rep.flags_return = pContext->flags; rep.length = dwords; WriteToClient(client, sizeof(xvmcCreateContextReply), (char*)&rep); if(dwords) WriteToClient(client, dwords << 2, (char*)data); AddResource(pContext->context_id, XvMCRTContext, pContext); free(data); return Success; }
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 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 = malloc(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); free(offsets); return Success; }
static int ProcXvMCListSubpictureTypes(ClientPtr client) { XvPortPtr pPort; xvmcListSubpictureTypesReply rep; XvMCScreenPtr pScreenPriv; ScreenPtr pScreen; XvMCAdaptorPtr adaptor = NULL; XvMCSurfaceInfoPtr surface = NULL; xvImageFormatInfo info; XvImagePtr pImage; int i, j; REQUEST(xvmcListSubpictureTypesReq); REQUEST_SIZE_MATCH(xvmcListSubpictureTypesReq); VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess); pScreen = pPort->pAdaptor->pScreen; if(XvMCScreenKey == NULL) /* No XvMC adaptors */ return BadMatch; if(!(pScreenPriv = XVMC_GET_PRIVATE(pScreen))) return BadMatch; /* None this screen */ for(i = 0; i < pScreenPriv->num_adaptors; i++) { if(pPort->pAdaptor == pScreenPriv->adaptors[i].xv_adaptor) { adaptor = &(pScreenPriv->adaptors[i]); break; } } if(!adaptor) return BadMatch; for(i = 0; i < adaptor->num_surfaces; i++) { if(adaptor->surfaces[i]->surface_type_id == stuff->surface_type_id) { surface = adaptor->surfaces[i]; break; } } if(!surface) return BadMatch; rep.type = X_Reply; rep.sequenceNumber = client->sequence; rep.num = 0; if(surface->compatible_subpictures) rep.num = surface->compatible_subpictures->num_xvimages; rep.length = bytes_to_int32(rep.num * sizeof(xvImageFormatInfo)); WriteToClient(client, sizeof(xvmcListSubpictureTypesReply), (char*)&rep); for(i = 0; i < rep.num; i++) { pImage = NULL; for(j = 0; j < adaptor->num_subpictures; j++) { if(surface->compatible_subpictures->xvimage_ids[i] == adaptor->subpictures[j]->id) { pImage = adaptor->subpictures[j]; break; } } if(!pImage) return BadImplementation; info.id = pImage->id; info.type = pImage->type; info.byte_order = pImage->byte_order; memcpy(&info.guid, pImage->guid, 16); info.bpp = pImage->bits_per_pixel; info.num_planes = pImage->num_planes; info.depth = pImage->depth; info.red_mask = pImage->red_mask; info.green_mask = pImage->green_mask; info.blue_mask = pImage->blue_mask; info.format = pImage->format; info.y_sample_bits = pImage->y_sample_bits; info.u_sample_bits = pImage->u_sample_bits; info.v_sample_bits = pImage->v_sample_bits; info.horz_y_period = pImage->horz_y_period; info.horz_u_period = pImage->horz_u_period; info.horz_v_period = pImage->horz_v_period; info.vert_y_period = pImage->vert_y_period; info.vert_u_period = pImage->vert_u_period; info.vert_v_period = pImage->vert_v_period; memcpy(&info.comp_order, pImage->component_order, 32); info.scanline_order = pImage->scanline_order; WriteToClient(client, sizeof(xvImageFormatInfo), (char*)&info); } return Success; }
static int ProcXvMCGetDRInfo(ClientPtr client) { xvmcGetDRInfoReply rep; XvPortPtr pPort; ScreenPtr pScreen; XvMCScreenPtr pScreenPriv; #ifdef HAS_XVMCSHM volatile CARD32 *patternP; #endif REQUEST(xvmcGetDRInfoReq); REQUEST_SIZE_MATCH(xvmcGetDRInfoReq); VALIDATE_XV_PORT(stuff->port, pPort, DixReadAccess); pScreen = pPort->pAdaptor->pScreen; pScreenPriv = XVMC_GET_PRIVATE(pScreen); rep.type = X_Reply; rep.sequenceNumber = client->sequence; rep.major = pScreenPriv->major; rep.minor = pScreenPriv->minor; rep.patchLevel = pScreenPriv->patchLevel; rep.nameLen = bytes_to_int32(strlen(pScreenPriv->clientDriverName) + 1); rep.busIDLen = bytes_to_int32(strlen(pScreenPriv->busID) + 1); rep.length = rep.nameLen + rep.busIDLen; rep.nameLen <<=2; rep.busIDLen <<=2; /* * Read back to the client what she has put in the shared memory * segment she prepared for us. */ rep.isLocal = 1; #ifdef HAS_XVMCSHM patternP = (CARD32 *)shmat( stuff->shmKey, NULL, SHM_RDONLY ); if ( -1 != (long) patternP) { volatile CARD32 *patternC = patternP; int i; CARD32 magic = stuff->magic; rep.isLocal = 1; i = 1024 / sizeof(CARD32); while ( i-- ) { if (*patternC++ != magic) { rep.isLocal = 0; break; } magic = ~magic; } shmdt( (char *)patternP ); } #endif /* HAS_XVMCSHM */ WriteToClient(client, sizeof(xvmcGetDRInfoReply), (char*)&rep); if (rep.length) { WriteToClient(client, rep.nameLen, pScreenPriv->clientDriverName); WriteToClient(client, rep.busIDLen, pScreenPriv->busID); } return Success; }
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; 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.minorEvent = xv_ShmPutImage; ev.majorEvent = XvReqCode; ev.shmseg = stuff->shmseg; ev.offset = stuff->offset; WriteEventsToClient(client, 1, (xEvent *) &ev); } return status; }