783 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			783 lines
		
	
	
		
			20 KiB
		
	
	
	
		
			C
		
	
	
	
| 
 | |
| #define NEED_REPLIES
 | |
| #define NEED_EVENTS
 | |
| #ifdef HAVE_DIX_CONFIG_H
 | |
| #include <dix-config.h>
 | |
| #endif
 | |
| 
 | |
| #include <string.h>
 | |
| 
 | |
| #include <X11/X.h>
 | |
| #include <X11/Xproto.h>
 | |
| #include "misc.h"
 | |
| #include "os.h"
 | |
| #include "dixstruct.h"
 | |
| #include "resource.h"
 | |
| #include "scrnintstr.h"
 | |
| #include "extnsionst.h"
 | |
| #include "servermd.h"
 | |
| #include <X11/Xfuncproto.h>
 | |
| #include "xvdix.h"
 | |
| #include <X11/extensions/XvMC.h>
 | |
| #include <X11/extensions/Xvproto.h>
 | |
| #include <X11/extensions/XvMCproto.h>
 | |
| #include "xvmcext.h"
 | |
| 
 | |
| #ifdef HAS_XVMCSHM
 | |
| #include <sys/ipc.h>
 | |
| #include <sys/types.h>
 | |
| #include <sys/shm.h>
 | |
| #endif /* HAS_XVMCSHM */
 | |
|    
 | |
| 
 | |
| 
 | |
| #define DR_CLIENT_DRIVER_NAME_SIZE 48
 | |
| #define DR_BUSID_SIZE 48
 | |
| 
 | |
| static int XvMCScreenKeyIndex;
 | |
| static DevPrivateKey XvMCScreenKey;
 | |
| 
 | |
| unsigned long XvMCGeneration = 0;
 | |
| 
 | |
| int XvMCReqCode;
 | |
| int XvMCEventBase;
 | |
| int XvMCErrorBase;
 | |
| 
 | |
| unsigned long XvMCRTContext;
 | |
| unsigned long XvMCRTSurface;
 | |
| unsigned long XvMCRTSubpicture;
 | |
| 
 | |
| typedef struct {
 | |
|    int num_adaptors;
 | |
|    XvMCAdaptorPtr adaptors;
 | |
|    CloseScreenProcPtr	CloseScreen;
 | |
|    char clientDriverName[DR_CLIENT_DRIVER_NAME_SIZE];
 | |
|    char busID[DR_BUSID_SIZE];
 | |
|    int major;
 | |
|    int minor;
 | |
|    int patchLevel;
 | |
| } XvMCScreenRec, *XvMCScreenPtr; 
 | |
| 
 | |
| #define XVMC_GET_PRIVATE(pScreen) \
 | |
|     (XvMCScreenPtr)(dixLookupPrivate(&(pScreen)->devPrivates, XvMCScreenKey))
 | |
| 
 | |
| 
 | |
| static int
 | |
| XvMCDestroyContextRes(pointer data, XID id)
 | |
| {
 | |
|    XvMCContextPtr pContext = (XvMCContextPtr)data;
 | |
|    
 | |
|    pContext->refcnt--;
 | |
| 
 | |
|    if(!pContext->refcnt) {
 | |
|   	 XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen);
 | |
| 	(*pScreenPriv->adaptors[pContext->adapt_num].DestroyContext)(pContext);
 | |
| 	xfree(pContext);
 | |
|    }	   
 | |
| 
 | |
|    return Success;
 | |
| }
 | |
| 
 | |
| static int
 | |
| XvMCDestroySurfaceRes(pointer data, XID id)
 | |
| {
 | |
|    XvMCSurfacePtr pSurface = (XvMCSurfacePtr)data;
 | |
|    XvMCContextPtr pContext = pSurface->context;
 | |
|    XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen);
 | |
| 
 | |
|    (*pScreenPriv->adaptors[pContext->adapt_num].DestroySurface)(pSurface); 
 | |
|    xfree(pSurface);
 | |
| 
 | |
|    XvMCDestroyContextRes((pointer)pContext, pContext->context_id);
 | |
| 
 | |
|    return Success;
 | |
| }
 | |
| 
 | |
| 
 | |
| static int
 | |
| XvMCDestroySubpictureRes(pointer data, XID id)
 | |
| {
 | |
|    XvMCSubpicturePtr pSubpict = (XvMCSubpicturePtr)data;
 | |
|    XvMCContextPtr pContext = pSubpict->context;
 | |
|    XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen);
 | |
| 
 | |
|    (*pScreenPriv->adaptors[pContext->adapt_num].DestroySubpicture)(pSubpict); 
 | |
|    xfree(pSubpict);
 | |
| 
 | |
|    XvMCDestroyContextRes((pointer)pContext, pContext->context_id);
 | |
| 
 | |
|    return Success;
 | |
| }
 | |
| 
 | |
| static int 
 | |
| ProcXvMCQueryVersion(ClientPtr client)
 | |
| {
 | |
|     xvmcQueryVersionReply rep;
 | |
|     /* REQUEST(xvmcQueryVersionReq); */
 | |
|     REQUEST_SIZE_MATCH(xvmcQueryVersionReq);
 | |
|     rep.type = X_Reply;
 | |
|     rep.sequenceNumber = client->sequence;
 | |
|     rep.length = 0;
 | |
|     rep.major = XvMCVersion;
 | |
|     rep.minor = XvMCRevision;
 | |
|     WriteToClient(client, sizeof(xvmcQueryVersionReply), (char*)&rep);
 | |
|     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);
 | |
| 
 | |
|     if(!(pPort = LOOKUP_PORT(stuff->port, client))) {
 | |
|         client->errorValue = stuff->port;
 | |
|         return _XvBadPort;
 | |
|     }
 | |
| 
 | |
|     if(XvMCScreenKey) { /* 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 = rep.num * sizeof(xvmcSurfaceInfo) >> 2;
 | |
|  
 | |
|     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 
 | |
| 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);
 | |
| 
 | |
|     if(!(pPort = LOOKUP_PORT(stuff->port, client))) {
 | |
| 	client->errorValue = stuff->port;
 | |
| 	return _XvBadPort;
 | |
|     }
 | |
| 
 | |
|     pScreen = pPort->pAdaptor->pScreen;
 | |
| 
 | |
|     if(XvMCScreenKey == NULL) /* 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 = xalloc(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) {
 | |
| 	xfree(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);
 | |
| 
 | |
|     if(data)
 | |
| 	xfree(data);
 | |
| 
 | |
|     return Success;
 | |
| }
 | |
| 
 | |
| static int 
 | |
| ProcXvMCDestroyContext(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xvmcDestroyContextReq);
 | |
|     REQUEST_SIZE_MATCH(xvmcDestroyContextReq);
 | |
| 
 | |
|     if(!LookupIDByType(stuff->context_id, XvMCRTContext))
 | |
| 	return (XvMCBadContext + XvMCErrorBase);
 | |
| 
 | |
|     FreeResource(stuff->context_id, RT_NONE); 
 | |
| 
 | |
|     return Success;
 | |
| }
 | |
| 
 | |
| static int 
 | |
| ProcXvMCCreateSurface(ClientPtr client)
 | |
| {
 | |
|     CARD32 *data = NULL;
 | |
|     int dwords = 0;
 | |
|     int result;
 | |
|     XvMCContextPtr pContext;
 | |
|     XvMCSurfacePtr pSurface;
 | |
|     XvMCScreenPtr pScreenPriv;
 | |
|     xvmcCreateSurfaceReply rep;
 | |
|     REQUEST(xvmcCreateSurfaceReq);
 | |
|     REQUEST_SIZE_MATCH(xvmcCreateSurfaceReq);
 | |
| 
 | |
|     if(!(pContext = LookupIDByType(stuff->context_id, XvMCRTContext)))
 | |
|         return (XvMCBadContext + XvMCErrorBase);
 | |
| 
 | |
|     pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen);
 | |
| 
 | |
|     if(!(pSurface = xalloc(sizeof(XvMCSurfaceRec)))) 
 | |
|         return BadAlloc;
 | |
| 
 | |
|     pSurface->surface_id = stuff->surface_id;
 | |
|     pSurface->surface_type_id = pContext->surface_type_id;
 | |
|     pSurface->context = pContext;
 | |
| 
 | |
|     result = (*pScreenPriv->adaptors[pContext->adapt_num].CreateSurface)(
 | |
|                 pSurface, &dwords, &data);
 | |
| 
 | |
|     if(result != Success) {
 | |
|         xfree(pSurface);
 | |
|         return result;
 | |
|     }
 | |
| 
 | |
|     rep.type = X_Reply;
 | |
|     rep.sequenceNumber = client->sequence;
 | |
|     rep.length = dwords;
 | |
| 
 | |
|     WriteToClient(client, sizeof(xvmcCreateSurfaceReply), (char*)&rep);
 | |
|     if(dwords)
 | |
|       WriteToClient(client, dwords << 2, (char*)data);
 | |
|     AddResource(pSurface->surface_id, XvMCRTSurface, pSurface);
 | |
| 
 | |
|     if(data)
 | |
|         xfree(data);
 | |
| 
 | |
|     pContext->refcnt++;
 | |
| 
 | |
|     return Success;
 | |
| }
 | |
| 
 | |
| static int 
 | |
| ProcXvMCDestroySurface(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xvmcDestroySurfaceReq);
 | |
|     REQUEST_SIZE_MATCH(xvmcDestroySurfaceReq);
 | |
| 
 | |
|     if(!LookupIDByType(stuff->surface_id, XvMCRTSurface))
 | |
|         return (XvMCBadSurface + XvMCErrorBase);
 | |
| 
 | |
|     FreeResource(stuff->surface_id, RT_NONE);
 | |
| 
 | |
|     return Success;
 | |
| }
 | |
| 
 | |
| static int 
 | |
| ProcXvMCCreateSubpicture(ClientPtr client)
 | |
| {
 | |
|     Bool image_supported = FALSE;
 | |
|     CARD32 *data = NULL;
 | |
|     int i, result, dwords = 0;
 | |
|     XvMCContextPtr pContext;
 | |
|     XvMCSubpicturePtr pSubpicture;
 | |
|     XvMCScreenPtr pScreenPriv;
 | |
|     xvmcCreateSubpictureReply rep;
 | |
|     XvMCAdaptorPtr adaptor;
 | |
|     XvMCSurfaceInfoPtr surface = NULL;
 | |
|     REQUEST(xvmcCreateSubpictureReq);
 | |
|     REQUEST_SIZE_MATCH(xvmcCreateSubpictureReq);
 | |
| 
 | |
|     if(!(pContext = LookupIDByType(stuff->context_id, XvMCRTContext)))
 | |
|         return (XvMCBadContext + XvMCErrorBase);
 | |
| 
 | |
|     pScreenPriv = XVMC_GET_PRIVATE(pContext->pScreen);
 | |
| 
 | |
|     adaptor = &(pScreenPriv->adaptors[pContext->adapt_num]); 
 | |
| 
 | |
|     /* find which surface this context supports */
 | |
|     for(i = 0; i < adaptor->num_surfaces; i++) {
 | |
| 	if(adaptor->surfaces[i]->surface_type_id == pContext->surface_type_id){
 | |
| 	   surface = adaptor->surfaces[i];
 | |
| 	   break;
 | |
| 	}
 | |
|     } 
 | |
| 
 | |
|     if(!surface) return BadMatch;
 | |
| 
 | |
|     /* make sure this surface supports that xvimage format */
 | |
|     if(!surface->compatible_subpictures) return BadMatch;
 | |
| 
 | |
|     for(i = 0; i < surface->compatible_subpictures->num_xvimages; i++) {
 | |
|       if(surface->compatible_subpictures->xvimage_ids[i] == stuff->xvimage_id) {
 | |
| 	   image_supported = TRUE;
 | |
| 	   break;
 | |
|       }
 | |
|     }
 | |
| 
 | |
|     if(!image_supported) return BadMatch;
 | |
| 
 | |
|     /* make sure the size is OK */
 | |
|     if((stuff->width > surface->subpicture_max_width) ||
 | |
|        (stuff->height > surface->subpicture_max_height))
 | |
| 	return BadValue;
 | |
| 
 | |
|     if(!(pSubpicture = xalloc(sizeof(XvMCSubpictureRec))))
 | |
|         return BadAlloc;
 | |
| 
 | |
|     pSubpicture->subpicture_id = stuff->subpicture_id;
 | |
|     pSubpicture->xvimage_id = stuff->xvimage_id;
 | |
|     pSubpicture->width = stuff->width;
 | |
|     pSubpicture->height = stuff->height;
 | |
|     pSubpicture->num_palette_entries = 0; /* overwritten by DDX */
 | |
|     pSubpicture->entry_bytes = 0;         /* overwritten by DDX */
 | |
|     pSubpicture->component_order[0] = 0;  /* overwritten by DDX */
 | |
|     pSubpicture->component_order[1] = 0;
 | |
|     pSubpicture->component_order[2] = 0;
 | |
|     pSubpicture->component_order[3] = 0;
 | |
|     pSubpicture->context = pContext;
 | |
|    
 | |
|     result = (*pScreenPriv->adaptors[pContext->adapt_num].CreateSubpicture)(
 | |
|                 pSubpicture, &dwords, &data);
 | |
| 
 | |
|     if(result != Success) {
 | |
|         xfree(pSubpicture);
 | |
|         return result;
 | |
|     }
 | |
| 
 | |
|     rep.type = X_Reply;
 | |
|     rep.sequenceNumber = client->sequence;
 | |
|     rep.width_actual = pSubpicture->width;
 | |
|     rep.height_actual = pSubpicture->height;
 | |
|     rep.num_palette_entries = pSubpicture->num_palette_entries;
 | |
|     rep.entry_bytes = pSubpicture->entry_bytes;
 | |
|     rep.component_order[0] = pSubpicture->component_order[0];
 | |
|     rep.component_order[1] = pSubpicture->component_order[1];
 | |
|     rep.component_order[2] = pSubpicture->component_order[2];
 | |
|     rep.component_order[3] = pSubpicture->component_order[3];
 | |
|     rep.length = dwords;
 | |
| 
 | |
|     WriteToClient(client, sizeof(xvmcCreateSubpictureReply), (char*)&rep);
 | |
|     if(dwords)
 | |
|       WriteToClient(client, dwords << 2, (char*)data);
 | |
|     AddResource(pSubpicture->subpicture_id, XvMCRTSubpicture, pSubpicture);
 | |
| 
 | |
|     if(data)
 | |
|         xfree(data);
 | |
| 
 | |
|     pContext->refcnt++;
 | |
| 
 | |
|     return Success;
 | |
| }
 | |
| 
 | |
| static int 
 | |
| ProcXvMCDestroySubpicture(ClientPtr client)
 | |
| {
 | |
|     REQUEST(xvmcDestroySubpictureReq);
 | |
|     REQUEST_SIZE_MATCH(xvmcDestroySubpictureReq);
 | |
| 
 | |
|     if(!LookupIDByType(stuff->subpicture_id, XvMCRTSubpicture))
 | |
|         return (XvMCBadSubpicture + XvMCErrorBase);
 | |
| 
 | |
|     FreeResource(stuff->subpicture_id, RT_NONE);
 | |
| 
 | |
|     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);
 | |
| 
 | |
|     if(!(pPort = LOOKUP_PORT(stuff->port, client))) {
 | |
|         client->errorValue = stuff->port;
 | |
|         return _XvBadPort;
 | |
|     }
 | |
| 
 | |
|     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 = rep.num * sizeof(xvImageFormatInfo) >> 2;
 | |
| 
 | |
|     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);
 | |
| 
 | |
| 
 | |
|     if(!(pPort = LOOKUP_PORT(stuff->port, client))) {
 | |
| 	client->errorValue = stuff->port;
 | |
| 	return _XvBadPort;
 | |
|     }
 | |
| 
 | |
|     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 = (strlen(pScreenPriv->clientDriverName) + 4) >> 2;
 | |
|     rep.busIDLen = (strlen(pScreenPriv->busID) + 4) >> 2;
 | |
| 
 | |
|     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;
 | |
| }
 | |
| 
 | |
| 
 | |
| int (*ProcXvMCVector[xvmcNumRequest])(ClientPtr) = {
 | |
|   ProcXvMCQueryVersion,
 | |
|   ProcXvMCListSurfaceTypes,
 | |
|   ProcXvMCCreateContext,
 | |
|   ProcXvMCDestroyContext,
 | |
|   ProcXvMCCreateSurface,
 | |
|   ProcXvMCDestroySurface,
 | |
|   ProcXvMCCreateSubpicture,
 | |
|   ProcXvMCDestroySubpicture,
 | |
|   ProcXvMCListSubpictureTypes,
 | |
|   ProcXvMCGetDRInfo
 | |
| };
 | |
| 
 | |
| static int
 | |
| ProcXvMCDispatch (ClientPtr client)
 | |
| {
 | |
|     REQUEST(xReq);
 | |
|     
 | |
|     if(stuff->data < xvmcNumRequest)
 | |
| 	return (*ProcXvMCVector[stuff->data])(client);
 | |
|     else
 | |
| 	return BadRequest;
 | |
| }
 | |
| 
 | |
| static int
 | |
| SProcXvMCDispatch (ClientPtr client)
 | |
| {
 | |
|     /* We only support local */
 | |
|     return BadImplementation;
 | |
| }
 | |
| 
 | |
| void
 | |
| XvMCExtensionInit(void)
 | |
| {
 | |
|    ExtensionEntry *extEntry;
 | |
| 
 | |
|    if(XvMCScreenKey == NULL) /* nobody supports it */
 | |
| 	return; 
 | |
| 
 | |
|    if(!(XvMCRTContext = CreateNewResourceType(XvMCDestroyContextRes)))
 | |
| 	return;
 | |
| 
 | |
|    if(!(XvMCRTSurface = CreateNewResourceType(XvMCDestroySurfaceRes)))
 | |
| 	return;
 | |
| 
 | |
|    if(!(XvMCRTSubpicture = CreateNewResourceType(XvMCDestroySubpictureRes)))
 | |
| 	return;
 | |
| 
 | |
|    extEntry = AddExtension(XvMCName, XvMCNumEvents, XvMCNumErrors, 
 | |
|                               ProcXvMCDispatch, SProcXvMCDispatch,
 | |
|                               NULL, StandardMinorOpcode);
 | |
| 
 | |
|    if(!extEntry) return;
 | |
|   
 | |
|    XvMCReqCode = extEntry->base;
 | |
|    XvMCEventBase = extEntry->eventBase;
 | |
|    XvMCErrorBase = extEntry->errorBase;
 | |
| }
 | |
| 
 | |
| static Bool
 | |
| XvMCCloseScreen (int i, ScreenPtr pScreen)
 | |
| {
 | |
|     XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pScreen);
 | |
| 
 | |
|     pScreen->CloseScreen = pScreenPriv->CloseScreen;
 | |
| 
 | |
|     xfree(pScreenPriv);
 | |
| 
 | |
|     return (*pScreen->CloseScreen)(i, pScreen);
 | |
| }
 | |
| 
 | |
| 
 | |
| int
 | |
| XvMCScreenInit(ScreenPtr pScreen, int num, XvMCAdaptorPtr pAdapt)
 | |
| {
 | |
|    XvMCScreenPtr pScreenPriv;
 | |
| 
 | |
|    XvMCScreenKey = &XvMCScreenKeyIndex;
 | |
| 
 | |
|    if(!(pScreenPriv = (XvMCScreenPtr)xalloc(sizeof(XvMCScreenRec))))
 | |
| 	return BadAlloc;
 | |
| 
 | |
|    dixSetPrivate(&pScreen->devPrivates, XvMCScreenKey, pScreenPriv);
 | |
| 
 | |
|    pScreenPriv->CloseScreen = pScreen->CloseScreen;
 | |
|    pScreen->CloseScreen = XvMCCloseScreen;
 | |
| 
 | |
|    pScreenPriv->num_adaptors = num;
 | |
|    pScreenPriv->adaptors = pAdapt;
 | |
|    pScreenPriv->clientDriverName[0] = 0;
 | |
|    pScreenPriv->busID[0] = 0;
 | |
|    pScreenPriv->major = 0;
 | |
|    pScreenPriv->minor = 0;
 | |
|    pScreenPriv->patchLevel = 0;
 | |
| 
 | |
|    return Success;
 | |
| }
 | |
| 
 | |
| XvImagePtr XvMCFindXvImage(XvPortPtr pPort, CARD32 id)
 | |
| {
 | |
|     XvImagePtr pImage = NULL;
 | |
|     ScreenPtr pScreen = pPort->pAdaptor->pScreen;
 | |
|     XvMCScreenPtr pScreenPriv;
 | |
|     XvMCAdaptorPtr adaptor = NULL;
 | |
|     int i;
 | |
| 
 | |
|     if(XvMCScreenKey == NULL) return NULL;
 | |
| 
 | |
|     if(!(pScreenPriv = XVMC_GET_PRIVATE(pScreen))) 
 | |
|         return NULL;
 | |
| 
 | |
|     for(i = 0; i < pScreenPriv->num_adaptors; i++) {
 | |
|        if(pPort->pAdaptor == pScreenPriv->adaptors[i].xv_adaptor) {
 | |
|           adaptor = &(pScreenPriv->adaptors[i]);
 | |
|           break;
 | |
|        }
 | |
|     }
 | |
| 
 | |
|     if(!adaptor) return NULL;
 | |
| 
 | |
|     for(i = 0; i < adaptor->num_subpictures; i++) {
 | |
|         if(adaptor->subpictures[i]->id == id) {
 | |
|             pImage = adaptor->subpictures[i];
 | |
|             break;
 | |
|         }
 | |
|     }
 | |
| 
 | |
|     return pImage;
 | |
| }
 | |
| 
 | |
| int
 | |
| xf86XvMCRegisterDRInfo(ScreenPtr pScreen, char *name,
 | |
| 		       char *busID, int major, int minor,
 | |
| 		       int patchLevel)
 | |
| {
 | |
|     XvMCScreenPtr pScreenPriv = XVMC_GET_PRIVATE(pScreen);
 | |
|     strncpy(pScreenPriv->clientDriverName, name,
 | |
| 	    DR_CLIENT_DRIVER_NAME_SIZE);
 | |
|     strncpy(pScreenPriv->busID, busID, DR_BUSID_SIZE);
 | |
|     pScreenPriv->major = major;
 | |
|     pScreenPriv->minor = minor;
 | |
|     pScreenPriv->patchLevel = patchLevel;
 | |
|     pScreenPriv->clientDriverName[DR_CLIENT_DRIVER_NAME_SIZE-1] = 0;
 | |
|     pScreenPriv->busID[DR_BUSID_SIZE-1] = 0;
 | |
|     return Success;
 | |
| }
 | |
| 
 |