don't crash when hostX reports an error.

* hw/kdrive/ephyr/ephyrhostvideo.c,h:
          (ephyrHostXVLogXErrorEvent): add this to
          log X error events. Heavily copied from libx11
          (ephyrHostXVErrorHandler): new x error handler that
          logs the error but does not exits.
          (ephyrHostXVInit): add this to be called at the beginning
          of xvideo lifetime. It sets an xerror handler that does not
          exit.
        * hw/kdrive/ephyr/ephyrvideo.c:
          (ephyrXVPrivIsAttrValueValid): this validates an attribute
          value.
          (ephyrSetPortAttribute): before setting an attribute,
          validate the new value so that we don't send a buggy
          request to host X.
        * hw/kdrive/ephyr/*.c: fix case in ephyrvideo code.
        * hw/kdrive/ephyr/ephyr.c: fix a typo
This commit is contained in:
Dodji Seketeli 2007-08-04 01:13:38 +02:00
parent 207714b60d
commit 1de89239bd
4 changed files with 308 additions and 108 deletions

View File

@ -610,7 +610,7 @@ ephyrInitScreen (ScreenPtr pScreen)
if (!ephyrInitVideo (pScreen)) {
EPHYR_LOG_ERROR ("failed to initialize xvideo\n") ;
} else {
EPHYR_LOG_ERROR ("initialized xvideo okay\n") ;
EPHYR_LOG ("initialized xvideo okay\n") ;
}
#endif /*XV*/
return TRUE;

View File

@ -108,8 +108,141 @@ struct _EphyrHostXVAdaptorArray {
unsigned int nb_adaptors ;
};
/*heavily copied from libx11*/
#define BUFSIZE 2048
static void
ephyrHostXVLogXErrorEvent (Display *a_display,
XErrorEvent *a_err_event,
FILE *a_fp)
{
char buffer[BUFSIZ];
char mesg[BUFSIZ];
char number[32];
const char *mtype = "XlibMessage";
register _XExtension *ext = (_XExtension *)NULL;
_XExtension *bext = (_XExtension *)NULL;
Display *dpy = a_display ;
XGetErrorText(dpy, a_err_event->error_code, buffer, BUFSIZ);
XGetErrorDatabaseText(dpy, mtype, "XError", "X Error", mesg, BUFSIZ);
(void) fprintf(a_fp, "%s: %s\n ", mesg, buffer);
XGetErrorDatabaseText(dpy, mtype, "MajorCode", "Request Major code %d",
mesg, BUFSIZ);
(void) fprintf(a_fp, mesg, a_err_event->request_code);
if (a_err_event->request_code < 128) {
sprintf(number, "%d", a_err_event->request_code);
XGetErrorDatabaseText(dpy, "XRequest", number, "", buffer, BUFSIZ);
} else {
for (ext = dpy->ext_procs;
ext && (ext->codes.major_opcode != a_err_event->request_code);
ext = ext->next)
;
if (ext)
strcpy(buffer, ext->name);
else
buffer[0] = '\0';
}
(void) fprintf(a_fp, " (%s)\n", buffer);
if (a_err_event->request_code >= 128) {
XGetErrorDatabaseText(dpy, mtype, "MinorCode", "Request Minor code %d",
mesg, BUFSIZ);
fputs(" ", a_fp);
(void) fprintf(a_fp, mesg, a_err_event->minor_code);
if (ext) {
sprintf(mesg, "%s.%d", ext->name, a_err_event->minor_code);
XGetErrorDatabaseText(dpy, "XRequest", mesg, "", buffer, BUFSIZ);
(void) fprintf(a_fp, " (%s)", buffer);
}
fputs("\n", a_fp);
}
if (a_err_event->error_code >= 128) {
/* kludge, try to find the extension that caused it */
buffer[0] = '\0';
for (ext = dpy->ext_procs; ext; ext = ext->next) {
if (ext->error_string)
(*ext->error_string)(dpy, a_err_event->error_code, &ext->codes,
buffer, BUFSIZ);
if (buffer[0]) {
bext = ext;
break;
}
if (ext->codes.first_error &&
ext->codes.first_error < (int)a_err_event->error_code &&
(!bext || ext->codes.first_error > bext->codes.first_error))
bext = ext;
}
if (bext)
sprintf(buffer, "%s.%d", bext->name,
a_err_event->error_code - bext->codes.first_error);
else
strcpy(buffer, "Value");
XGetErrorDatabaseText(dpy, mtype, buffer, "", mesg, BUFSIZ);
if (mesg[0]) {
fputs(" ", a_fp);
(void) fprintf(a_fp, mesg, a_err_event->resourceid);
fputs("\n", a_fp);
}
/* let extensions try to print the values */
for (ext = dpy->ext_procs; ext; ext = ext->next) {
if (ext->error_values)
(*ext->error_values)(dpy, a_err_event, a_fp);
}
} else if ((a_err_event->error_code == BadWindow) ||
(a_err_event->error_code == BadPixmap) ||
(a_err_event->error_code == BadCursor) ||
(a_err_event->error_code == BadFont) ||
(a_err_event->error_code == BadDrawable) ||
(a_err_event->error_code == BadColor) ||
(a_err_event->error_code == BadGC) ||
(a_err_event->error_code == BadIDChoice) ||
(a_err_event->error_code == BadValue) ||
(a_err_event->error_code == BadAtom)) {
if (a_err_event->error_code == BadValue)
XGetErrorDatabaseText(dpy, mtype, "Value", "Value 0x%x",
mesg, BUFSIZ);
else if (a_err_event->error_code == BadAtom)
XGetErrorDatabaseText(dpy, mtype, "AtomID", "AtomID 0x%x",
mesg, BUFSIZ);
else
XGetErrorDatabaseText(dpy, mtype, "ResourceID", "ResourceID 0x%x",
mesg, BUFSIZ);
fputs(" ", a_fp);
(void) fprintf(a_fp, mesg, a_err_event->resourceid);
fputs("\n", a_fp);
}
XGetErrorDatabaseText(dpy, mtype, "ErrorSerial", "Error Serial #%d",
mesg, BUFSIZ);
fputs(" ", a_fp);
(void) fprintf(a_fp, mesg, a_err_event->serial);
XGetErrorDatabaseText(dpy, mtype, "CurrentSerial", "Current Serial #%d",
mesg, BUFSIZ);
fputs("\n ", a_fp);
(void) fprintf(a_fp, mesg, dpy->request);
fputs("\n", a_fp);
}
static int
ephyrHostXVErrorHandler (Display *a_display,
XErrorEvent *a_error_event)
{
EPHYR_LOG_ERROR ("got an error from the host xserver:\n") ;
ephyrHostXVLogXErrorEvent (a_display, a_error_event, stderr) ;
return Success ;
}
void
ephyrHostXVInit (void)
{
static Bool s_initialized ;
if (s_initialized)
return ;
XSetErrorHandler (ephyrHostXVErrorHandler) ;
s_initialized = TRUE ;
}
Bool
EphyrHostXVQueryAdaptors (EphyrHostXVAdaptorArray **a_adaptors)
ephyrHostXVQueryAdaptors (EphyrHostXVAdaptorArray **a_adaptors)
{
EphyrHostXVAdaptorArray *result=NULL ;
int ret=0 ;
@ -140,7 +273,7 @@ out:
}
void
EphyrHostXVAdaptorArrayDelete (EphyrHostXVAdaptorArray *a_adaptors)
ephyrHostXVAdaptorArrayDelete (EphyrHostXVAdaptorArray *a_adaptors)
{
if (!a_adaptors)
return ;
@ -153,14 +286,14 @@ EphyrHostXVAdaptorArrayDelete (EphyrHostXVAdaptorArray *a_adaptors)
}
int
EphyrHostXVAdaptorArrayGetSize (const EphyrHostXVAdaptorArray *a_this)
ephyrHostXVAdaptorArrayGetSize (const EphyrHostXVAdaptorArray *a_this)
{
EPHYR_RETURN_VAL_IF_FAIL (a_this, -1) ;
return a_this->nb_adaptors ;
}
EphyrHostXVAdaptor*
EphyrHostXVAdaptorArrayAt (const EphyrHostXVAdaptorArray *a_this,
ephyrHostXVAdaptorArrayAt (const EphyrHostXVAdaptorArray *a_this,
int a_index)
{
EPHYR_RETURN_VAL_IF_FAIL (a_this, NULL) ;
@ -171,14 +304,14 @@ EphyrHostXVAdaptorArrayAt (const EphyrHostXVAdaptorArray *a_this,
}
char
EphyrHostXVAdaptorGetType (const EphyrHostXVAdaptor *a_this)
ephyrHostXVAdaptorGetType (const EphyrHostXVAdaptor *a_this)
{
EPHYR_RETURN_VAL_IF_FAIL (a_this, -1) ;
return ((XvAdaptorInfo*)a_this)->type ;
}
const char*
EphyrHostXVAdaptorGetName (const EphyrHostXVAdaptor *a_this)
ephyrHostXVAdaptorGetName (const EphyrHostXVAdaptor *a_this)
{
EPHYR_RETURN_VAL_IF_FAIL (a_this, NULL) ;
@ -186,7 +319,7 @@ EphyrHostXVAdaptorGetName (const EphyrHostXVAdaptor *a_this)
}
EphyrHostVideoFormat*
EphyrHostXVAdaptorGetVideoFormats (const EphyrHostXVAdaptor *a_this,
ephyrHostXVAdaptorGetVideoFormats (const EphyrHostXVAdaptor *a_this,
int *a_nb_formats)
{
EphyrHostVideoFormat *formats=NULL ;
@ -216,7 +349,7 @@ EphyrHostXVAdaptorGetVideoFormats (const EphyrHostXVAdaptor *a_this,
}
int
EphyrHostXVAdaptorGetNbPorts (const EphyrHostXVAdaptor *a_this)
ephyrHostXVAdaptorGetNbPorts (const EphyrHostXVAdaptor *a_this)
{
EPHYR_RETURN_VAL_IF_FAIL (a_this, -1) ;
@ -224,7 +357,7 @@ EphyrHostXVAdaptorGetNbPorts (const EphyrHostXVAdaptor *a_this)
}
int
EphyrHostXVAdaptorGetFirstPortID (const EphyrHostXVAdaptor *a_this)
ephyrHostXVAdaptorGetFirstPortID (const EphyrHostXVAdaptor *a_this)
{
EPHYR_RETURN_VAL_IF_FAIL (a_this, -1) ;
@ -232,7 +365,7 @@ EphyrHostXVAdaptorGetFirstPortID (const EphyrHostXVAdaptor *a_this)
}
Bool
EphyrHostXVQueryEncodings (int a_port_id,
ephyrHostXVQueryEncodings (int a_port_id,
EphyrHostEncoding **a_encodings,
unsigned int *a_num_encodings)
{
@ -271,7 +404,7 @@ EphyrHostXVQueryEncodings (int a_port_id,
}
void
EphyrHostEncodingsDelete (EphyrHostEncoding *a_encodings,
ephyrHostEncodingsDelete (EphyrHostEncoding *a_encodings,
int a_num_encodings)
{
int i=0 ;
@ -288,7 +421,7 @@ EphyrHostEncodingsDelete (EphyrHostEncoding *a_encodings,
}
void
EphyrHostAttributesDelete (EphyrHostAttribute *a_attributes)
ephyrHostAttributesDelete (EphyrHostAttribute *a_attributes)
{
if (!a_attributes)
return ;
@ -296,7 +429,7 @@ EphyrHostAttributesDelete (EphyrHostAttribute *a_attributes)
}
Bool
EphyrHostXVQueryPortAttributes (int a_port_id,
ephyrHostXVQueryPortAttributes (int a_port_id,
EphyrHostAttribute **a_attributes,
int *a_num_attributes)
{
@ -311,7 +444,7 @@ EphyrHostXVQueryPortAttributes (int a_port_id,
}
Bool
EphyrHostXVQueryImageFormats (int a_port_id,
ephyrHostXVQueryImageFormats (int a_port_id,
EphyrHostImageFormat **a_formats,
int *a_num_format)
{
@ -328,13 +461,16 @@ EphyrHostXVQueryImageFormats (int a_port_id,
}
Bool
EphyrHostXVSetPortAttribute (int a_port_id,
ephyrHostXVSetPortAttribute (int a_port_id,
int a_atom,
int a_attr_value)
{
int res=Success ;
EPHYR_LOG ("atom,value: (%d, %d)\n", a_atom, a_attr_value) ;
EPHYR_LOG ("atom,name,value: (%d,%s,%d)\n",
a_atom,
XGetAtomName (hostx_get_display (), a_atom),
a_attr_value) ;
res = XvSetPortAttribute (hostx_get_display (),
a_port_id,
@ -344,13 +480,14 @@ EphyrHostXVSetPortAttribute (int a_port_id,
EPHYR_LOG_ERROR ("XvSetPortAttribute() failed: %d\n", res) ;
return FALSE ;
}
XFlush (hostx_get_display ()) ;
EPHYR_LOG ("leave\n") ;
return TRUE ;
}
Bool
EphyrHostXVGetPortAttribute (int a_port_id,
ephyrHostXVGetPortAttribute (int a_port_id,
int a_atom,
int *a_attr_value)
{
@ -380,7 +517,7 @@ out:
}
Bool
EphyrHostXVQueryBestSize (int a_port_id,
ephyrHostXVQueryBestSize (int a_port_id,
Bool a_motion,
unsigned int a_frame_w,
unsigned int a_frame_h,
@ -458,7 +595,7 @@ xv_wire_to_event(Display *dpy, XEvent *host, xEvent *wire)
}
Bool
EphyrHostXVQueryImageAttributes (int a_port_id,
ephyrHostXVQueryImageAttributes (int a_port_id,
int a_image_id /*image fourcc code*/,
unsigned short *a_width,
unsigned short *a_height,
@ -515,7 +652,7 @@ out:
}
Bool
EphyrHostGetAtom (const char* a_name,
ephyrHostGetAtom (const char* a_name,
Bool a_create_if_not_exists,
int *a_atom)
{
@ -532,20 +669,20 @@ EphyrHostGetAtom (const char* a_name,
}
char*
EphyrHostGetAtomName (int a_atom)
ephyrHostGetAtomName (int a_atom)
{
return XGetAtomName (hostx_get_display (), a_atom) ;
}
void
EphyrHostFree (void *a_pointer)
ephyrHostFree (void *a_pointer)
{
if (a_pointer)
XFree (a_pointer) ;
}
Bool
EphyrHostXVPutImage (int a_port_id,
ephyrHostXVPutImage (int a_port_id,
int a_image_id,
int a_drw_x,
int a_drw_y,

View File

@ -84,67 +84,69 @@ typedef struct _EphyrHostImageFormat {
int scanline_order; /* XvTopToBottom, XvBottomToTop */
} EphyrHostImageFormat ;
void EphyrHostFree (void *a_pointer) ;
void ephyrHostXVInit (void) ;
void ephyrHostFree (void *a_pointer) ;
/*
* host adaptor array
*/
Bool EphyrHostXVQueryAdaptors (EphyrHostXVAdaptorArray **a_adaptors) ;
void EphyrHostXVAdaptorArrayDelete (EphyrHostXVAdaptorArray *a_adaptors) ;
int EphyrHostXVAdaptorArrayGetSize (const EphyrHostXVAdaptorArray *a_this) ;
EphyrHostXVAdaptor* EphyrHostXVAdaptorArrayAt (const EphyrHostXVAdaptorArray *a_this,
Bool ephyrHostXVQueryAdaptors (EphyrHostXVAdaptorArray **a_adaptors) ;
void ephyrHostXVAdaptorArrayDelete (EphyrHostXVAdaptorArray *a_adaptors) ;
int ephyrHostXVAdaptorArrayGetSize (const EphyrHostXVAdaptorArray *a_this) ;
EphyrHostXVAdaptor* ephyrHostXVAdaptorArrayAt (const EphyrHostXVAdaptorArray *a_this,
int a_index) ;
/*
* host adaptor
*/
char EphyrHostXVAdaptorGetType (const EphyrHostXVAdaptor *a_this) ;
const char* EphyrHostXVAdaptorGetName (const EphyrHostXVAdaptor *a_this) ;
EphyrHostVideoFormat* EphyrHostXVAdaptorGetVideoFormats
char ephyrHostXVAdaptorGetType (const EphyrHostXVAdaptor *a_this) ;
const char* ephyrHostXVAdaptorGetName (const EphyrHostXVAdaptor *a_this) ;
EphyrHostVideoFormat* ephyrHostXVAdaptorGetVideoFormats
(const EphyrHostXVAdaptor *a_this,
int *a_nb_formats) ;
int EphyrHostXVAdaptorGetNbPorts (const EphyrHostXVAdaptor *a_this) ;
int EphyrHostXVAdaptorGetFirstPortID (const EphyrHostXVAdaptor *a_this) ;
int ephyrHostXVAdaptorGetNbPorts (const EphyrHostXVAdaptor *a_this) ;
int ephyrHostXVAdaptorGetFirstPortID (const EphyrHostXVAdaptor *a_this) ;
/*
* encoding
*/
Bool EphyrHostXVQueryEncodings (int a_port_id,
Bool ephyrHostXVQueryEncodings (int a_port_id,
EphyrHostEncoding **a_encodings,
unsigned int *a_num_encodings) ;
void EphyrHostEncodingsDelete (EphyrHostEncoding *a_encodings,
void ephyrHostEncodingsDelete (EphyrHostEncoding *a_encodings,
int a_num_encodings) ;
/*
* attribute
*/
Bool EphyrHostXVQueryPortAttributes (int a_port_id,
Bool ephyrHostXVQueryPortAttributes (int a_port_id,
EphyrHostAttribute **a_attributes,
int *a_num_attributes) ;
void EphyrHostAttributesDelete (EphyrHostAttribute *a_attributes) ;
void ephyrHostAttributesDelete (EphyrHostAttribute *a_attributes) ;
/*
* image format
*/
Bool EphyrHostXVQueryImageFormats (int a_port_id,
Bool ephyrHostXVQueryImageFormats (int a_port_id,
EphyrHostImageFormat **a_formats,
int *a_num_format) ;
/*
* Port Attribute Get/Set
*/
Bool EphyrHostXVSetPortAttribute (int a_port_id,
Bool ephyrHostXVSetPortAttribute (int a_port_id,
int a_atom,
int a_attr_value) ;
Bool EphyrHostXVGetPortAttribute (int a_port_id,
Bool ephyrHostXVGetPortAttribute (int a_port_id,
int a_atom,
int *a_attr_value) ;
/*
*size query
*/
Bool EphyrHostXVQueryBestSize (int a_port_id,
Bool ephyrHostXVQueryBestSize (int a_port_id,
Bool a_motion,
unsigned int a_frame_w,
unsigned int a_frame_h,
@ -153,7 +155,7 @@ Bool EphyrHostXVQueryBestSize (int a_port_id,
unsigned int *a_actual_w,
unsigned int *a_actual_h) ;
Bool EphyrHostXVQueryImageAttributes (int a_port_id,
Bool ephyrHostXVQueryImageAttributes (int a_port_id,
int a_image_id /*image fourcc code*/,
unsigned short *a_width,
unsigned short *a_height,
@ -163,16 +165,16 @@ Bool EphyrHostXVQueryImageAttributes (int a_port_id,
/*
* atom
*/
Bool EphyrHostGetAtom (const char* a_name,
Bool ephyrHostGetAtom (const char* a_name,
Bool a_create_if_not_exists,
int *a_atom) ;
char* EphyrHostGetAtomName (int a_atom) ;
char* ephyrHostGetAtomName (int a_atom) ;
/*
*PutImage
* (ignore clipping for now)
*/
Bool EphyrHostXVPutImage (int a_port_id,
Bool ephyrHostXVPutImage (int a_port_id,
int a_image_id,
int a_drw_x,
int a_drw_y,

View File

@ -47,6 +47,7 @@ typedef struct _EphyrXVPriv EphyrXVPriv ;
struct _EphyrPortPriv {
int port_number ;
KdVideoAdaptorPtr current_adaptor ;
EphyrXVPriv *xv_priv;
};
typedef struct _EphyrPortPriv EphyrPortPriv ;
@ -55,31 +56,38 @@ static Bool DoSimpleClip (BoxPtr a_dst_drw,
BoxPtr a_clipper,
BoxPtr a_result) ;
static Bool EphyrLocalAtomToHost (int a_local_atom, int *a_host_atom) ;
static Bool ephyrLocalAtomToHost (int a_local_atom, int *a_host_atom) ;
static Bool EphyrHostAtomToLocal (int a_host_atom, int *a_local_atom) ;
static Bool ephyrHostAtomToLocal (int a_host_atom, int *a_local_atom) ;
static EphyrXVPriv* EphyrXVPrivNew (void) ;
static void EphyrXVPrivDelete (EphyrXVPriv *a_this) ;
static Bool EphyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this) ;
static Bool EphyrXVPrivSetAdaptorsHooks (EphyrXVPriv *a_this) ;
static Bool EphyrXVPrivRegisterAdaptors (EphyrXVPriv *a_this,
static EphyrXVPriv* ephyrXVPrivNew (void) ;
static void ephyrXVPrivDelete (EphyrXVPriv *a_this) ;
static Bool ephyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this) ;
static Bool ephyrXVPrivSetAdaptorsHooks (EphyrXVPriv *a_this) ;
static Bool ephyrXVPrivRegisterAdaptors (EphyrXVPriv *a_this,
ScreenPtr a_screen) ;
static void EphyrStopVideo (KdScreenInfo *a_info,
static Bool ephyrXVPrivIsAttrValueValid (KdAttributePtr a_attrs,
int a_attrs_len,
const char *a_attr_name,
int a_attr_value,
Bool *a_is_valid) ;
static void ephyrStopVideo (KdScreenInfo *a_info,
pointer a_xv_priv,
Bool a_exit);
static int EphyrSetPortAttribute (KdScreenInfo *a_info,
static int ephyrSetPortAttribute (KdScreenInfo *a_info,
Atom a_attr_name,
int a_attr_value,
pointer a_port_priv);
static int EphyrGetPortAttribute (KdScreenInfo *a_screen_info,
static int ephyrGetPortAttribute (KdScreenInfo *a_screen_info,
Atom a_attr_name,
int *a_attr_value,
pointer a_port_priv);
static void EphyrQueryBestSize (KdScreenInfo *a_info,
static void ephyrQueryBestSize (KdScreenInfo *a_info,
Bool a_motion,
short a_src_w,
short a_src_h,
@ -89,7 +97,7 @@ static void EphyrQueryBestSize (KdScreenInfo *a_info,
unsigned int *a_prefered_h,
pointer a_port_priv);
static int EphyrPutImage (KdScreenInfo *a_info,
static int ephyrPutImage (KdScreenInfo *a_info,
DrawablePtr a_drawable,
short a_src_x,
short a_src_y,
@ -107,7 +115,7 @@ static int EphyrPutImage (KdScreenInfo *a_info,
RegionPtr a_clipping_region,
pointer a_port_priv);
static int EphyrQueryImageAttributes (KdScreenInfo *a_info,
static int ephyrQueryImageAttributes (KdScreenInfo *a_info,
int a_id,
unsigned short *a_w,
unsigned short *a_h,
@ -165,7 +173,7 @@ DoSimpleClip (BoxPtr a_dst_box,
}
static Bool
EphyrLocalAtomToHost (int a_local_atom, int *a_host_atom)
ephyrLocalAtomToHost (int a_local_atom, int *a_host_atom)
{
char *atom_name=NULL;
int host_atom=None ;
@ -180,7 +188,7 @@ EphyrLocalAtomToHost (int a_local_atom, int *a_host_atom)
if (!atom_name)
return FALSE ;
if (!EphyrHostGetAtom (atom_name, FALSE, &host_atom) || host_atom == None) {
if (!ephyrHostGetAtom (atom_name, FALSE, &host_atom) || host_atom == None) {
EPHYR_LOG_ERROR ("no atom for string %s defined in host X\n",
atom_name) ;
return FALSE ;
@ -190,7 +198,7 @@ EphyrLocalAtomToHost (int a_local_atom, int *a_host_atom)
}
static Bool
EphyrHostAtomToLocal (int a_host_atom, int *a_local_atom)
ephyrHostAtomToLocal (int a_host_atom, int *a_local_atom)
{
Bool is_ok=FALSE ;
char *atom_name=NULL ;
@ -198,7 +206,7 @@ EphyrHostAtomToLocal (int a_host_atom, int *a_local_atom)
EPHYR_RETURN_VAL_IF_FAIL (a_local_atom, FALSE) ;
atom_name = EphyrHostGetAtomName (a_host_atom) ;
atom_name = ephyrHostGetAtomName (a_host_atom) ;
if (!atom_name)
goto out ;
@ -211,7 +219,7 @@ EphyrHostAtomToLocal (int a_host_atom, int *a_local_atom)
out:
if (atom_name) {
EphyrHostFree (atom_name) ;
ephyrHostFree (atom_name) ;
}
return is_ok ;
}
@ -234,13 +242,13 @@ ephyrInitVideo (ScreenPtr pScreen)
return FALSE ;
}
xv_priv = EphyrXVPrivNew () ;
xv_priv = ephyrXVPrivNew () ;
if (!xv_priv) {
EPHYR_LOG_ERROR ("failed to create xv_priv\n") ;
return FALSE ;
}
if (!EphyrXVPrivRegisterAdaptors (xv_priv, pScreen)) {
if (!ephyrXVPrivRegisterAdaptors (xv_priv, pScreen)) {
EPHYR_LOG_ERROR ("failed to register adaptors\n") ;
return FALSE ;
}
@ -248,7 +256,7 @@ ephyrInitVideo (ScreenPtr pScreen)
}
static EphyrXVPriv*
EphyrXVPrivNew (void)
ephyrXVPrivNew (void)
{
EphyrXVPriv *xv_priv=NULL ;
@ -259,11 +267,14 @@ EphyrXVPrivNew (void)
EPHYR_LOG_ERROR ("failed to create EphyrXVPriv\n") ;
goto error ;
}
if (!EphyrXVPrivQueryHostAdaptors (xv_priv)) {
ephyrHostXVInit () ;
if (!ephyrXVPrivQueryHostAdaptors (xv_priv)) {
EPHYR_LOG_ERROR ("failed to query the host x for xv properties\n") ;
goto error ;
}
if (!EphyrXVPrivSetAdaptorsHooks (xv_priv)) {
if (!ephyrXVPrivSetAdaptorsHooks (xv_priv)) {
EPHYR_LOG_ERROR ("failed to set xv_priv hooks\n") ;
goto error ;
}
@ -273,21 +284,21 @@ EphyrXVPrivNew (void)
error:
if (xv_priv) {
EphyrXVPrivDelete (xv_priv) ;
ephyrXVPrivDelete (xv_priv) ;
xv_priv = NULL ;
}
return NULL ;
}
static void
EphyrXVPrivDelete (EphyrXVPriv *a_this)
ephyrXVPrivDelete (EphyrXVPriv *a_this)
{
EPHYR_LOG ("enter\n") ;
if (!a_this)
return ;
if (a_this->host_adaptors) {
EphyrHostXVAdaptorArrayDelete (a_this->host_adaptors) ;
ephyrHostXVAdaptorArrayDelete (a_this->host_adaptors) ;
a_this->host_adaptors = NULL ;
}
if (a_this->adaptors) {
@ -343,7 +354,7 @@ portAttributesDup (EphyrHostAttribute *a_encodings,
}
static Bool
EphyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this)
ephyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this)
{
EphyrHostXVAdaptor *cur_host_adaptor=NULL ;
EphyrHostVideoFormat *video_formats=NULL ;
@ -359,13 +370,13 @@ EphyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this)
EPHYR_LOG ("enter\n") ;
if (!EphyrHostXVQueryAdaptors (&a_this->host_adaptors)) {
if (!ephyrHostXVQueryAdaptors (&a_this->host_adaptors)) {
EPHYR_LOG_ERROR ("failed to query host adaptors\n") ;
goto out ;
}
if (a_this->host_adaptors)
a_this->num_adaptors =
EphyrHostXVAdaptorArrayGetSize (a_this->host_adaptors) ;
ephyrHostXVAdaptorArrayGetSize (a_this->host_adaptors) ;
if (a_this->num_adaptors < 0) {
EPHYR_LOG_ERROR ("failed to get number of host adaptors\n") ;
goto out ;
@ -385,20 +396,20 @@ EphyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this)
for (i=0; i < a_this->num_adaptors; i++) {
int j=0 ;
cur_host_adaptor =
EphyrHostXVAdaptorArrayAt (a_this->host_adaptors, i) ;
ephyrHostXVAdaptorArrayAt (a_this->host_adaptors, i) ;
if (!cur_host_adaptor)
continue ;
a_this->adaptors[i].type =
EphyrHostXVAdaptorGetType (cur_host_adaptor) ;
ephyrHostXVAdaptorGetType (cur_host_adaptor) ;
a_this->adaptors[i].type |= XvWindowMask ;
a_this->adaptors[i].flags =
VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
if (EphyrHostXVAdaptorGetName (cur_host_adaptor))
if (ephyrHostXVAdaptorGetName (cur_host_adaptor))
a_this->adaptors[i].name =
strdup (EphyrHostXVAdaptorGetName (cur_host_adaptor)) ;
strdup (ephyrHostXVAdaptorGetName (cur_host_adaptor)) ;
else
a_this->adaptors[i].name = strdup ("Xephyr Video Overlay");
base_port_id = EphyrHostXVAdaptorGetFirstPortID (cur_host_adaptor) ;
base_port_id = ephyrHostXVAdaptorGetFirstPortID (cur_host_adaptor) ;
if (base_port_id < 0) {
EPHYR_LOG_ERROR ("failed to get port id for adaptor %d\n", i) ;
continue ;
@ -406,7 +417,7 @@ EphyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this)
if (!s_base_port_id)
s_base_port_id = base_port_id ;
if (!EphyrHostXVQueryEncodings (base_port_id,
if (!ephyrHostXVQueryEncodings (base_port_id,
&encodings,
&num_encodings)) {
EPHYR_LOG_ERROR ("failed to get encodings for port port id %d,"
@ -418,12 +429,12 @@ EphyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this)
a_this->adaptors[i].pEncodings =
videoEncodingDup (encodings, num_encodings) ;
video_formats = (EphyrHostVideoFormat*)
EphyrHostXVAdaptorGetVideoFormats (cur_host_adaptor,
ephyrHostXVAdaptorGetVideoFormats (cur_host_adaptor,
&num_video_formats);
a_this->adaptors[i].pFormats = (KdVideoFormatPtr) video_formats ;
a_this->adaptors[i].nFormats = num_video_formats ;
a_this->adaptors[i].nPorts =
EphyrHostXVAdaptorGetNbPorts (cur_host_adaptor) ;
ephyrHostXVAdaptorGetNbPorts (cur_host_adaptor) ;
a_this->adaptors[i].pPortPrivates =
xcalloc (a_this->adaptors[i].nPorts,
sizeof (DevUnion) + sizeof (EphyrPortPriv)) ;
@ -433,10 +444,11 @@ EphyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this)
(EphyrPortPriv*)
&a_this->adaptors[i].pPortPrivates[port_priv_offset + j];
port_priv->port_number = base_port_id + j;
port_priv->current_adaptor = &a_this->adaptors[i] ;
port_priv->xv_priv = a_this ;
a_this->adaptors[i].pPortPrivates[j].ptr = port_priv;
}
if (!EphyrHostXVQueryPortAttributes (base_port_id,
if (!ephyrHostXVQueryPortAttributes (base_port_id,
&attributes,
&num_attributes)) {
EPHYR_LOG_ERROR ("failed to get port attribute "
@ -446,7 +458,7 @@ EphyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this)
a_this->adaptors[i].pAttributes =
portAttributesDup (attributes, num_attributes);
a_this->adaptors[i].nAttributes = num_attributes ;
if (!EphyrHostXVQueryImageFormats (base_port_id,
if (!ephyrHostXVQueryImageFormats (base_port_id,
&image_formats,
&num_formats)) {
EPHYR_LOG_ERROR ("failed to get image formats "
@ -460,11 +472,11 @@ EphyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this)
out:
if (encodings) {
EphyrHostEncodingsDelete (encodings, num_encodings) ;
ephyrHostEncodingsDelete (encodings, num_encodings) ;
encodings = NULL ;
}
if (attributes) {
EphyrHostAttributesDelete (attributes) ;
ephyrHostAttributesDelete (attributes) ;
attributes = NULL ;
}
EPHYR_LOG ("leave\n") ;
@ -472,7 +484,7 @@ out:
}
static Bool
EphyrXVPrivSetAdaptorsHooks (EphyrXVPriv *a_this)
ephyrXVPrivSetAdaptorsHooks (EphyrXVPriv *a_this)
{
int i=0 ;
@ -481,19 +493,19 @@ EphyrXVPrivSetAdaptorsHooks (EphyrXVPriv *a_this)
EPHYR_LOG ("enter\n") ;
for (i=0; i < a_this->num_adaptors; i++) {
a_this->adaptors[i].StopVideo = EphyrStopVideo ;
a_this->adaptors[i].SetPortAttribute = EphyrSetPortAttribute ;
a_this->adaptors[i].GetPortAttribute = EphyrGetPortAttribute ;
a_this->adaptors[i].QueryBestSize = EphyrQueryBestSize ;
a_this->adaptors[i].PutImage = EphyrPutImage;
a_this->adaptors[i].QueryImageAttributes = EphyrQueryImageAttributes ;
a_this->adaptors[i].StopVideo = ephyrStopVideo ;
a_this->adaptors[i].SetPortAttribute = ephyrSetPortAttribute ;
a_this->adaptors[i].GetPortAttribute = ephyrGetPortAttribute ;
a_this->adaptors[i].QueryBestSize = ephyrQueryBestSize ;
a_this->adaptors[i].PutImage = ephyrPutImage;
a_this->adaptors[i].QueryImageAttributes = ephyrQueryImageAttributes ;
}
EPHYR_LOG ("leave\n") ;
return TRUE ;
}
static Bool
EphyrXVPrivRegisterAdaptors (EphyrXVPriv *a_this,
ephyrXVPrivRegisterAdaptors (EphyrXVPriv *a_this,
ScreenPtr a_screen)
{
KdScreenPriv(a_screen);
@ -540,23 +552,55 @@ out:
return is_ok ;
}
static Bool
ephyrXVPrivIsAttrValueValid (KdAttributePtr a_attrs,
int a_attrs_len,
const char *a_attr_name,
int a_attr_value,
Bool *a_is_valid)
{
int i=0 ;
EPHYR_RETURN_VAL_IF_FAIL (a_attrs && a_attr_name && a_is_valid,
FALSE) ;
for (i=0; i < a_attrs_len; i++) {
if (a_attrs[i].name && strcmp (a_attrs[i].name, a_attr_name))
continue ;
if (a_attrs[i].min_value > a_attr_value ||
a_attrs[i].max_value < a_attr_value) {
*a_is_valid = FALSE ;
} else {
*a_is_valid = TRUE ;
}
return TRUE ;
}
return FALSE ;
}
static void
EphyrStopVideo (KdScreenInfo *a_info, pointer a_port_priv, Bool a_exit)
ephyrStopVideo (KdScreenInfo *a_info, pointer a_port_priv, Bool a_exit)
{
EPHYR_LOG ("enter\n") ;
EPHYR_LOG ("leave\n") ;
}
static int
EphyrSetPortAttribute (KdScreenInfo *a_info,
ephyrSetPortAttribute (KdScreenInfo *a_info,
Atom a_attr_name,
int a_attr_value,
pointer a_port_priv)
{
int res=Success, host_atom=0 ;
EphyrPortPriv *port_priv = a_port_priv ;
Bool is_attr_valid=FALSE ;
EPHYR_RETURN_VAL_IF_FAIL (port_priv, BadMatch) ;
EPHYR_RETURN_VAL_IF_FAIL (port_priv->current_adaptor, BadMatch) ;
EPHYR_RETURN_VAL_IF_FAIL (port_priv->current_adaptor->pAttributes,
BadMatch) ;
EPHYR_RETURN_VAL_IF_FAIL (port_priv->current_adaptor->nAttributes,
BadMatch) ;
EPHYR_RETURN_VAL_IF_FAIL (ValidAtom (a_attr_name), BadMatch) ;
EPHYR_LOG ("enter, portnum:%d, atomid:%d, attr_name:%s, attr_val:%d\n",
@ -565,13 +609,30 @@ EphyrSetPortAttribute (KdScreenInfo *a_info,
NameForAtom (a_attr_name),
a_attr_value) ;
if (!EphyrLocalAtomToHost (a_attr_name, &host_atom)) {
if (!ephyrLocalAtomToHost (a_attr_name, &host_atom)) {
EPHYR_LOG_ERROR ("failed to convert local atom to host atom\n") ;
res = BadMatch ;
goto out ;
}
if (!EphyrHostXVSetPortAttribute (port_priv->port_number,
if (!ephyrXVPrivIsAttrValueValid (port_priv->current_adaptor->pAttributes,
port_priv->current_adaptor->nAttributes,
NameForAtom (a_attr_name),
a_attr_value,
&is_attr_valid)) {
EPHYR_LOG_ERROR ("failed to validate attribute %s\n",
NameForAtom (a_attr_name)) ;
res = BadMatch ;
goto out ;
}
if (!is_attr_valid) {
EPHYR_LOG_ERROR ("attribute %s is not valid\n",
NameForAtom (a_attr_name)) ;
res = BadMatch ;
goto out ;
}
if (!ephyrHostXVSetPortAttribute (port_priv->port_number,
host_atom,
a_attr_value)) {
EPHYR_LOG_ERROR ("failed to set port attribute\n") ;
@ -586,7 +647,7 @@ out:
}
static int
EphyrGetPortAttribute (KdScreenInfo *a_screen_info,
ephyrGetPortAttribute (KdScreenInfo *a_screen_info,
Atom a_attr_name,
int *a_attr_value,
pointer a_port_priv)
@ -602,13 +663,13 @@ EphyrGetPortAttribute (KdScreenInfo *a_screen_info,
(int)a_attr_name,
NameForAtom (a_attr_name)) ;
if (!EphyrLocalAtomToHost (a_attr_name, &host_atom)) {
if (!ephyrLocalAtomToHost (a_attr_name, &host_atom)) {
EPHYR_LOG_ERROR ("failed to convert local atom to host atom\n") ;
res = BadMatch ;
goto out ;
}
if (!EphyrHostXVGetPortAttribute (port_priv->port_number,
if (!ephyrHostXVGetPortAttribute (port_priv->port_number,
host_atom,
a_attr_value)) {
EPHYR_LOG_ERROR ("failed to get port attribute\n") ;
@ -623,7 +684,7 @@ out:
}
static void
EphyrQueryBestSize (KdScreenInfo *a_info,
ephyrQueryBestSize (KdScreenInfo *a_info,
Bool a_motion,
short a_src_w,
short a_src_h,
@ -639,7 +700,7 @@ EphyrQueryBestSize (KdScreenInfo *a_info,
EPHYR_RETURN_IF_FAIL (port_priv) ;
EPHYR_LOG ("enter\n") ;
res = EphyrHostXVQueryBestSize (port_priv->port_number,
res = ephyrHostXVQueryBestSize (port_priv->port_number,
a_motion,
a_src_w, a_src_h,
a_drw_w, a_drw_h,
@ -652,7 +713,7 @@ EphyrQueryBestSize (KdScreenInfo *a_info,
static int
EphyrPutImage (KdScreenInfo *a_info,
ephyrPutImage (KdScreenInfo *a_info,
DrawablePtr a_drawable,
short a_src_x,
short a_src_y,
@ -696,7 +757,7 @@ EphyrPutImage (KdScreenInfo *a_info,
drw_w = clipped_area.x2 - clipped_area.x1 ;
drw_h = clipped_area.y2 - clipped_area.y1 ;
if (!EphyrHostXVPutImage (port_priv->port_number,
if (!ephyrHostXVPutImage (port_priv->port_number,
a_id,
drw_x, drw_y, drw_w, drw_h,
a_src_x, a_src_y, a_src_w, a_src_h,
@ -713,7 +774,7 @@ out:
}
static int
EphyrQueryImageAttributes (KdScreenInfo *a_info,
ephyrQueryImageAttributes (KdScreenInfo *a_info,
int a_id,
unsigned short *a_w,
unsigned short *a_h,
@ -727,7 +788,7 @@ EphyrQueryImageAttributes (KdScreenInfo *a_info,
EPHYR_LOG ("enter: dim (%dx%d), pitches: %#x, offsets: %#x\n",
*a_w, *a_h, (unsigned int)a_pitches, (unsigned int)a_offsets) ;
if (!EphyrHostXVQueryImageAttributes (s_base_port_id,
if (!ephyrHostXVQueryImageAttributes (s_base_port_id,
a_id,
a_w, a_h,
&image_size,