1013 lines
		
	
	
		
			30 KiB
		
	
	
	
		
			C
		
	
	
	
			
		
		
	
	
			1013 lines
		
	
	
		
			30 KiB
		
	
	
	
		
			C
		
	
	
	
/*
 | 
						|
 * Xephyr - A kdrive X server thats runs in a host X window.
 | 
						|
 *          Authored by Matthew Allum <mallum@openedhand.com>
 | 
						|
 * 
 | 
						|
 * Copyright © 2007 OpenedHand Ltd 
 | 
						|
 *
 | 
						|
 * Permission to use, copy, modify, distribute, and sell this software and its
 | 
						|
 * documentation for any purpose is hereby granted without fee, provided that
 | 
						|
 * the above copyright notice appear in all copies and that both that
 | 
						|
 * copyright notice and this permission notice appear in supporting
 | 
						|
 * documentation, and that the name of OpenedHand Ltd not be used in
 | 
						|
 * advertising or publicity pertaining to distribution of the software without
 | 
						|
 * specific, written prior permission. OpenedHand Ltd makes no
 | 
						|
 * representations about the suitability of this software for any purpose.  It
 | 
						|
 * is provided "as is" without express or implied warranty.
 | 
						|
 *
 | 
						|
 * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
 | 
						|
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
 | 
						|
 * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
 | 
						|
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
 | 
						|
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
 | 
						|
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
 | 
						|
 * PERFORMANCE OF THIS SOFTWARE.
 | 
						|
 *
 | 
						|
 * Authors:
 | 
						|
 *    Dodji Seketeli <dodji@openedhand.com>
 | 
						|
 */
 | 
						|
#ifdef HAVE_CONFIG_H
 | 
						|
#include <kdrive-config.h>
 | 
						|
#endif
 | 
						|
/*
 | 
						|
 * including some server headers (like kdrive-config.h)
 | 
						|
 * might define the macro _XSERVER64
 | 
						|
 * on 64 bits machines. That macro must _NOT_ be defined for Xlib
 | 
						|
 * client code, otherwise bad things happen.
 | 
						|
 * So let's undef that macro if necessary.
 | 
						|
 */
 | 
						|
#ifdef _XSERVER64
 | 
						|
#undef _XSERVER64
 | 
						|
#endif
 | 
						|
#include <X11/Xutil.h>
 | 
						|
#include <X11/Xlibint.h>
 | 
						|
#include <X11/extensions/Xvlib.h>
 | 
						|
#include <X11/extensions/Xvproto.h>
 | 
						|
#include <X11/extensions/Xext.h>
 | 
						|
#include <X11/extensions/extutil.h>
 | 
						|
#define _HAVE_XALLOC_DECLS
 | 
						|
 | 
						|
#include "hostx.h"
 | 
						|
#include "ephyrhostvideo.h"
 | 
						|
#include "ephyrlog.h"
 | 
						|
 | 
						|
#ifndef TRUE
 | 
						|
#define TRUE 1
 | 
						|
#endif /*TRUE*/
 | 
						|
 | 
						|
#ifndef FALSE
 | 
						|
#define FALSE 0
 | 
						|
#endif /*FALSE*/
 | 
						|
 | 
						|
static XExtensionInfo _xv_info_data;
 | 
						|
static XExtensionInfo *xv_info = &_xv_info_data;
 | 
						|
static char *xv_extension_name = XvName;
 | 
						|
static char *xv_error_string(Display *dpy, int code, XExtCodes *codes,
 | 
						|
                             char * buf, int n);
 | 
						|
static int xv_close_display(Display *dpy, XExtCodes *codes);
 | 
						|
static Bool xv_wire_to_event(Display *dpy, XEvent *host, xEvent *wire);
 | 
						|
 | 
						|
static XExtensionHooks xv_extension_hooks = {
 | 
						|
    NULL,                               /* create_gc */
 | 
						|
    NULL,                               /* copy_gc */
 | 
						|
    NULL,                               /* flush_gc */
 | 
						|
    NULL,                               /* free_gc */
 | 
						|
    NULL,                               /* create_font */
 | 
						|
    NULL,                               /* free_font */
 | 
						|
    xv_close_display,                   /* close_display */
 | 
						|
    xv_wire_to_event,                   /* wire_to_event */
 | 
						|
    NULL,                               /* event_to_wire */
 | 
						|
    NULL,                               /* error */
 | 
						|
    xv_error_string                     /* error_string */
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
static char *xv_error_list[] =
 | 
						|
{
 | 
						|
   "BadPort",       /* XvBadPort     */
 | 
						|
   "BadEncoding",   /* XvBadEncoding */
 | 
						|
   "BadControl"     /* XvBadControl  */
 | 
						|
};
 | 
						|
 | 
						|
 | 
						|
#define XvCheckExtension(dpy, i, val) \
 | 
						|
  XextCheckExtension(dpy, i, xv_extension_name, val)
 | 
						|
#define XvGetReq(name, req) \
 | 
						|
        WORD64ALIGN\
 | 
						|
        if ((dpy->bufptr + SIZEOF(xv##name##Req)) > dpy->bufmax)\
 | 
						|
                _XFlush(dpy);\
 | 
						|
        req = (xv##name##Req *)(dpy->last_req = dpy->bufptr);\
 | 
						|
        req->reqType = info->codes->major_opcode;\
 | 
						|
        req->xvReqType = xv_##name; \
 | 
						|
        req->length = (SIZEOF(xv##name##Req))>>2;\
 | 
						|
        dpy->bufptr += SIZEOF(xv##name##Req);\
 | 
						|
        dpy->request++
 | 
						|
 | 
						|
static XEXT_GENERATE_CLOSE_DISPLAY (xv_close_display, xv_info)
 | 
						|
 | 
						|
 | 
						|
static XEXT_GENERATE_FIND_DISPLAY (xv_find_display, xv_info,
 | 
						|
                                   xv_extension_name,
 | 
						|
                                   &xv_extension_hooks,
 | 
						|
                                   XvNumEvents, NULL)
 | 
						|
 | 
						|
static XEXT_GENERATE_ERROR_STRING (xv_error_string, xv_extension_name,
 | 
						|
                                   XvNumErrors, xv_error_list)
 | 
						|
 | 
						|
struct _EphyrHostXVAdaptorArray {
 | 
						|
    XvAdaptorInfo *adaptors ;
 | 
						|
    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)
 | 
						|
{
 | 
						|
    EphyrHostXVAdaptorArray *result=NULL ;
 | 
						|
    int ret=0 ;
 | 
						|
    Bool is_ok=FALSE ;
 | 
						|
 | 
						|
    EPHYR_RETURN_VAL_IF_FAIL (a_adaptors, FALSE) ;
 | 
						|
 | 
						|
    EPHYR_LOG ("enter\n") ;
 | 
						|
 | 
						|
    result = Xcalloc (1, sizeof (EphyrHostXVAdaptorArray)) ;
 | 
						|
    if (!result)
 | 
						|
        goto out ;
 | 
						|
 | 
						|
    ret = XvQueryAdaptors (hostx_get_display (),
 | 
						|
                           DefaultRootWindow (hostx_get_display ()),
 | 
						|
                           &result->nb_adaptors,
 | 
						|
                           &result->adaptors) ;
 | 
						|
    if (ret != Success) {
 | 
						|
        EPHYR_LOG_ERROR ("failed to query host adaptors: %d\n", ret) ;
 | 
						|
        goto out ;
 | 
						|
    }
 | 
						|
    *a_adaptors = result ;
 | 
						|
    is_ok = TRUE ;
 | 
						|
 | 
						|
out:
 | 
						|
    EPHYR_LOG ("leave\n") ;
 | 
						|
    return is_ok ;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
ephyrHostXVAdaptorArrayDelete (EphyrHostXVAdaptorArray *a_adaptors)
 | 
						|
{
 | 
						|
    if (!a_adaptors)
 | 
						|
        return ;
 | 
						|
    if (a_adaptors->adaptors) {
 | 
						|
        XvFreeAdaptorInfo (a_adaptors->adaptors) ;
 | 
						|
        a_adaptors->adaptors = NULL ;
 | 
						|
        a_adaptors->nb_adaptors = 0 ;
 | 
						|
    }
 | 
						|
    XFree (a_adaptors) ;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ephyrHostXVAdaptorArrayGetSize (const EphyrHostXVAdaptorArray *a_this)
 | 
						|
{
 | 
						|
    EPHYR_RETURN_VAL_IF_FAIL (a_this, -1) ;
 | 
						|
    return a_this->nb_adaptors ;
 | 
						|
}
 | 
						|
 | 
						|
EphyrHostXVAdaptor*
 | 
						|
ephyrHostXVAdaptorArrayAt (const EphyrHostXVAdaptorArray *a_this,
 | 
						|
                           int a_index)
 | 
						|
{
 | 
						|
    EPHYR_RETURN_VAL_IF_FAIL (a_this, NULL) ;
 | 
						|
 | 
						|
    if (a_index >= a_this->nb_adaptors)
 | 
						|
        return NULL ;
 | 
						|
    return (EphyrHostXVAdaptor*)&a_this->adaptors[a_index] ;
 | 
						|
}
 | 
						|
 | 
						|
char
 | 
						|
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)
 | 
						|
{
 | 
						|
    EPHYR_RETURN_VAL_IF_FAIL (a_this, NULL) ;
 | 
						|
 | 
						|
    return ((XvAdaptorInfo*)a_this)->name ;
 | 
						|
}
 | 
						|
 | 
						|
EphyrHostVideoFormat*
 | 
						|
ephyrHostXVAdaptorGetVideoFormats (const EphyrHostXVAdaptor *a_this,
 | 
						|
                                   int *a_nb_formats)
 | 
						|
{
 | 
						|
    EphyrHostVideoFormat *formats=NULL ;
 | 
						|
    int nb_formats=0, i=0 ;
 | 
						|
    XVisualInfo *visual_info, visual_info_template ;
 | 
						|
    int nb_visual_info ;
 | 
						|
 | 
						|
    EPHYR_RETURN_VAL_IF_FAIL (a_this, NULL) ;
 | 
						|
 | 
						|
    nb_formats = ((XvAdaptorInfo*)a_this)->num_formats ;
 | 
						|
    formats = Xcalloc (nb_formats, sizeof (EphyrHostVideoFormat)) ;
 | 
						|
    for (i=0; i < nb_formats; i++) {
 | 
						|
        memset (&visual_info_template, 0, sizeof (visual_info_template)) ;
 | 
						|
        visual_info_template.visualid =
 | 
						|
                            ((XvAdaptorInfo*)a_this)->formats[i].visual_id;
 | 
						|
        visual_info = XGetVisualInfo (hostx_get_display (),
 | 
						|
                                      VisualIDMask,
 | 
						|
                                      &visual_info_template,
 | 
						|
                                      &nb_visual_info) ;
 | 
						|
        formats[i].depth = ((XvAdaptorInfo*)a_this)->formats[i].depth ;
 | 
						|
        formats[i].visual_class = visual_info->class ;
 | 
						|
        XFree (visual_info) ;
 | 
						|
    }
 | 
						|
    if (a_nb_formats)
 | 
						|
        *a_nb_formats = nb_formats ;
 | 
						|
    return formats ;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ephyrHostXVAdaptorGetNbPorts (const EphyrHostXVAdaptor *a_this)
 | 
						|
{
 | 
						|
    EPHYR_RETURN_VAL_IF_FAIL (a_this, -1) ;
 | 
						|
 | 
						|
    return ((XvAdaptorInfo*)a_this)->num_ports ;
 | 
						|
}
 | 
						|
 | 
						|
int
 | 
						|
ephyrHostXVAdaptorGetFirstPortID (const EphyrHostXVAdaptor *a_this)
 | 
						|
{
 | 
						|
    EPHYR_RETURN_VAL_IF_FAIL (a_this, -1) ;
 | 
						|
 | 
						|
    return ((XvAdaptorInfo*)a_this)->base_id ;
 | 
						|
}
 | 
						|
 | 
						|
Bool
 | 
						|
ephyrHostXVAdaptorHasPutVideo (const EphyrHostXVAdaptor *a_this,
 | 
						|
                               Bool *a_result)
 | 
						|
{
 | 
						|
    EPHYR_RETURN_VAL_IF_FAIL (a_this && a_result, FALSE) ;
 | 
						|
 | 
						|
    if (((XvAdaptorInfo*)a_this)->type & XvVideoMask & XvInputMask)
 | 
						|
        *a_result = TRUE ;
 | 
						|
    else
 | 
						|
        *a_result = FALSE ;
 | 
						|
    return TRUE ;
 | 
						|
}
 | 
						|
 | 
						|
Bool
 | 
						|
ephyrHostXVAdaptorHasGetVideo (const EphyrHostXVAdaptor *a_this,
 | 
						|
                               Bool *a_result)
 | 
						|
{
 | 
						|
    if (((XvAdaptorInfo*)a_this)->type & XvVideoMask & XvOutputMask)
 | 
						|
        *a_result = TRUE ;
 | 
						|
    else
 | 
						|
        *a_result = FALSE ;
 | 
						|
    return TRUE ;
 | 
						|
}
 | 
						|
 | 
						|
Bool
 | 
						|
ephyrHostXVAdaptorHasPutStill (const EphyrHostXVAdaptor *a_this,
 | 
						|
                               Bool *a_result)
 | 
						|
{
 | 
						|
    EPHYR_RETURN_VAL_IF_FAIL (a_this && a_result, FALSE) ;
 | 
						|
 | 
						|
    if (((XvAdaptorInfo*)a_this)->type & XvStillMask && XvInputMask)
 | 
						|
        *a_result = TRUE ;
 | 
						|
    else
 | 
						|
        *a_result = FALSE ;
 | 
						|
    return TRUE ;
 | 
						|
}
 | 
						|
 | 
						|
Bool
 | 
						|
ephyrHostXVAdaptorHasGetStill (const EphyrHostXVAdaptor *a_this,
 | 
						|
                               Bool *a_result)
 | 
						|
{
 | 
						|
    EPHYR_RETURN_VAL_IF_FAIL (a_this && a_result, FALSE) ;
 | 
						|
 | 
						|
    if (((XvAdaptorInfo*)a_this)->type & XvStillMask && XvOutputMask)
 | 
						|
        *a_result = TRUE ;
 | 
						|
    else
 | 
						|
        *a_result = FALSE ;
 | 
						|
    return TRUE ;
 | 
						|
}
 | 
						|
 | 
						|
Bool
 | 
						|
ephyrHostXVAdaptorHasPutImage (const EphyrHostXVAdaptor *a_this,
 | 
						|
                               Bool *a_result)
 | 
						|
{
 | 
						|
    EPHYR_RETURN_VAL_IF_FAIL (a_this && a_result, FALSE) ;
 | 
						|
 | 
						|
    if (((XvAdaptorInfo*)a_this)->type & XvImageMask && XvInputMask)
 | 
						|
        *a_result = TRUE ;
 | 
						|
    else
 | 
						|
        *a_result = FALSE ;
 | 
						|
    return TRUE ;
 | 
						|
}
 | 
						|
 | 
						|
Bool
 | 
						|
ephyrHostXVQueryEncodings (int a_port_id,
 | 
						|
                           EphyrHostEncoding **a_encodings,
 | 
						|
                           unsigned int *a_num_encodings)
 | 
						|
{
 | 
						|
    EphyrHostEncoding *encodings=NULL ;
 | 
						|
    XvEncodingInfo *encoding_info=NULL ;
 | 
						|
    unsigned int num_encodings=0, i;
 | 
						|
    int ret=0 ;
 | 
						|
 | 
						|
    EPHYR_RETURN_VAL_IF_FAIL (a_encodings && a_num_encodings, FALSE) ;
 | 
						|
 | 
						|
    ret = XvQueryEncodings (hostx_get_display (),
 | 
						|
                            a_port_id,
 | 
						|
                            &num_encodings,
 | 
						|
                            &encoding_info) ;
 | 
						|
    if (num_encodings && encoding_info) {
 | 
						|
        encodings = Xcalloc (num_encodings, sizeof (EphyrHostEncoding)) ;
 | 
						|
        for (i=0; i<num_encodings; i++) {
 | 
						|
            encodings[i].id = encoding_info[i].encoding_id ;
 | 
						|
            encodings[i].name = strdup (encoding_info[i].name) ;
 | 
						|
            encodings[i].width = encoding_info[i].width ;
 | 
						|
            encodings[i].height = encoding_info[i].height ;
 | 
						|
            encodings[i].rate.numerator = encoding_info[i].rate.numerator ;
 | 
						|
            encodings[i].rate.denominator = encoding_info[i].rate.denominator ;
 | 
						|
        }
 | 
						|
    }
 | 
						|
    if (encoding_info) {
 | 
						|
        XvFreeEncodingInfo (encoding_info) ;
 | 
						|
        encoding_info = NULL ;
 | 
						|
    }
 | 
						|
    *a_encodings = encodings ;
 | 
						|
    *a_num_encodings = num_encodings ;
 | 
						|
 | 
						|
    if (ret != Success)
 | 
						|
        return FALSE ;
 | 
						|
    return TRUE ;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
ephyrHostEncodingsDelete (EphyrHostEncoding *a_encodings,
 | 
						|
                          int a_num_encodings)
 | 
						|
{
 | 
						|
    int i=0 ;
 | 
						|
 | 
						|
    if (!a_encodings)
 | 
						|
        return ;
 | 
						|
    for (i=0; i < a_num_encodings; i++) {
 | 
						|
        xfree (a_encodings[i].name) ;
 | 
						|
        a_encodings[i].name = NULL ;
 | 
						|
    }
 | 
						|
    xfree (a_encodings) ;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
ephyrHostAttributesDelete (EphyrHostAttribute *a_attributes)
 | 
						|
{
 | 
						|
    if (!a_attributes)
 | 
						|
        return ;
 | 
						|
    XFree (a_attributes) ;
 | 
						|
}
 | 
						|
 | 
						|
Bool
 | 
						|
ephyrHostXVQueryPortAttributes (int a_port_id,
 | 
						|
                                EphyrHostAttribute **a_attributes,
 | 
						|
                                int *a_num_attributes)
 | 
						|
{
 | 
						|
    EPHYR_RETURN_VAL_IF_FAIL (a_attributes && a_num_attributes, FALSE) ;
 | 
						|
 | 
						|
    *a_attributes =
 | 
						|
        (EphyrHostAttribute*)XvQueryPortAttributes (hostx_get_display (),
 | 
						|
                                                    a_port_id,
 | 
						|
                                                    a_num_attributes);
 | 
						|
 | 
						|
    return TRUE ;
 | 
						|
}
 | 
						|
 | 
						|
Bool
 | 
						|
ephyrHostXVQueryImageFormats (int a_port_id,
 | 
						|
                              EphyrHostImageFormat **a_formats,
 | 
						|
                              int *a_num_format)
 | 
						|
{
 | 
						|
    XvImageFormatValues *result=NULL ;
 | 
						|
 | 
						|
    EPHYR_RETURN_VAL_IF_FAIL (a_formats && a_num_format, FALSE) ;
 | 
						|
 | 
						|
    result = XvListImageFormats (hostx_get_display (),
 | 
						|
                                 a_port_id,
 | 
						|
                                 a_num_format) ;
 | 
						|
    *a_formats = (EphyrHostImageFormat*) result ;
 | 
						|
    return TRUE ;
 | 
						|
 | 
						|
}
 | 
						|
 | 
						|
Bool
 | 
						|
ephyrHostXVSetPortAttribute (int a_port_id,
 | 
						|
                             int a_atom,
 | 
						|
                             int a_attr_value)
 | 
						|
{
 | 
						|
    int res=Success ;
 | 
						|
 | 
						|
    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,
 | 
						|
                              a_atom,
 | 
						|
                              a_attr_value) ;
 | 
						|
    if (res != Success) {
 | 
						|
        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,
 | 
						|
                             int a_atom,
 | 
						|
                             int *a_attr_value)
 | 
						|
{
 | 
						|
    int res=Success ;
 | 
						|
    Bool ret=FALSE ;
 | 
						|
 | 
						|
    EPHYR_RETURN_VAL_IF_FAIL (a_attr_value, FALSE) ;
 | 
						|
 | 
						|
    EPHYR_LOG ("enter, a_port_id: %d, a_atomid: %d, attr_name: %s\n",
 | 
						|
               a_port_id, a_atom, XGetAtomName (hostx_get_display (), a_atom)) ;
 | 
						|
 | 
						|
    res = XvGetPortAttribute (hostx_get_display (),
 | 
						|
                              a_port_id,
 | 
						|
                              a_atom,
 | 
						|
                              a_attr_value) ;
 | 
						|
    if (res != Success) {
 | 
						|
        EPHYR_LOG_ERROR ("XvGetPortAttribute() failed: %d \n", res) ;
 | 
						|
        goto out ;
 | 
						|
    }
 | 
						|
    EPHYR_LOG ("atom,value: (%d, %d)\n", a_atom, *a_attr_value) ;
 | 
						|
 | 
						|
    ret = TRUE ;
 | 
						|
 | 
						|
out:
 | 
						|
    EPHYR_LOG ("leave\n") ;
 | 
						|
    return ret ;
 | 
						|
}
 | 
						|
 | 
						|
Bool
 | 
						|
ephyrHostXVQueryBestSize (int a_port_id,
 | 
						|
                          Bool a_motion,
 | 
						|
                          unsigned int a_frame_w,
 | 
						|
                          unsigned int a_frame_h,
 | 
						|
                          unsigned int a_drw_w,
 | 
						|
                          unsigned int a_drw_h,
 | 
						|
                          unsigned int *a_actual_w,
 | 
						|
                          unsigned int *a_actual_h)
 | 
						|
{
 | 
						|
    int res=0 ;
 | 
						|
    Bool is_ok=FALSE ;
 | 
						|
 | 
						|
    EPHYR_RETURN_VAL_IF_FAIL (a_actual_w && a_actual_h, FALSE) ;
 | 
						|
 | 
						|
    EPHYR_LOG ("enter: frame (%dx%d), drw (%dx%d)\n",
 | 
						|
               a_frame_w, a_frame_h,
 | 
						|
               a_drw_w, a_drw_h) ;
 | 
						|
 | 
						|
    res = XvQueryBestSize (hostx_get_display (),
 | 
						|
                           a_port_id,
 | 
						|
                           a_motion,
 | 
						|
                           a_frame_w, a_frame_h,
 | 
						|
                           a_drw_w, a_drw_h,
 | 
						|
                           a_actual_w, a_actual_h) ;
 | 
						|
    if (res != Success) {
 | 
						|
        EPHYR_LOG_ERROR ("XvQueryBestSize() failed: %d\n", res) ;
 | 
						|
        goto out ;
 | 
						|
    }
 | 
						|
    XSync (hostx_get_display (), FALSE) ;
 | 
						|
 | 
						|
    EPHYR_LOG ("actual (%dx%d)\n", *a_actual_w, *a_actual_h) ;
 | 
						|
    is_ok = TRUE ;
 | 
						|
 | 
						|
out:
 | 
						|
    EPHYR_LOG ("leave\n") ;
 | 
						|
    return is_ok ;
 | 
						|
}
 | 
						|
 | 
						|
static Bool
 | 
						|
xv_wire_to_event(Display *dpy, XEvent *host, xEvent *wire)
 | 
						|
{
 | 
						|
    XExtDisplayInfo *info = xv_find_display (dpy);
 | 
						|
    XvEvent *re    = (XvEvent *)host;
 | 
						|
    xvEvent *event = (xvEvent *)wire;
 | 
						|
 | 
						|
    XvCheckExtension(dpy, info, False);
 | 
						|
 | 
						|
    switch ((event->u.u.type & 0x7F) - info->codes->first_event) {
 | 
						|
        case XvVideoNotify:
 | 
						|
            re->xvvideo.type = event->u.u.type & 0x7f;
 | 
						|
            re->xvvideo.serial =
 | 
						|
            _XSetLastRequestRead(dpy, (xGenericReply *)event);
 | 
						|
            re->xvvideo.send_event = ((event->u.u.type & 0x80) != 0);
 | 
						|
            re->xvvideo.display = dpy;
 | 
						|
            re->xvvideo.time = event->u.videoNotify.time;
 | 
						|
            re->xvvideo.reason = event->u.videoNotify.reason;
 | 
						|
            re->xvvideo.drawable = event->u.videoNotify.drawable;
 | 
						|
            re->xvvideo.port_id = event->u.videoNotify.port;
 | 
						|
            break;
 | 
						|
        case XvPortNotify:
 | 
						|
            re->xvport.type = event->u.u.type & 0x7f;
 | 
						|
            re->xvport.serial =
 | 
						|
            _XSetLastRequestRead(dpy, (xGenericReply *)event);
 | 
						|
            re->xvport.send_event = ((event->u.u.type & 0x80) != 0);
 | 
						|
            re->xvport.display = dpy;
 | 
						|
            re->xvport.time = event->u.portNotify.time;
 | 
						|
            re->xvport.port_id = event->u.portNotify.port;
 | 
						|
            re->xvport.attribute = event->u.portNotify.attribute;
 | 
						|
            re->xvport.value = event->u.portNotify.value;
 | 
						|
            break;
 | 
						|
        default:
 | 
						|
            return False;
 | 
						|
    }
 | 
						|
 | 
						|
    return True ;
 | 
						|
}
 | 
						|
 | 
						|
Bool
 | 
						|
ephyrHostXVQueryImageAttributes (int a_port_id,
 | 
						|
                                 int a_image_id /*image fourcc code*/,
 | 
						|
                                 unsigned short *a_width,
 | 
						|
                                 unsigned short *a_height,
 | 
						|
                                 int *a_image_size,
 | 
						|
                                 int *a_pitches,
 | 
						|
                                 int *a_offsets)
 | 
						|
{
 | 
						|
    Display *dpy = hostx_get_display () ;
 | 
						|
    Bool ret=FALSE ;
 | 
						|
    XExtDisplayInfo *info = xv_find_display (dpy);
 | 
						|
    xvQueryImageAttributesReq *req=NULL;
 | 
						|
    xvQueryImageAttributesReply rep;
 | 
						|
 | 
						|
    EPHYR_RETURN_VAL_IF_FAIL (a_width, FALSE) ;
 | 
						|
    EPHYR_RETURN_VAL_IF_FAIL (a_height, FALSE) ;
 | 
						|
    EPHYR_RETURN_VAL_IF_FAIL (a_image_size, FALSE) ;
 | 
						|
 | 
						|
    XvCheckExtension (dpy, info, FALSE);
 | 
						|
 | 
						|
    LockDisplay (dpy);
 | 
						|
 | 
						|
    XvGetReq (QueryImageAttributes, req);
 | 
						|
    req->id = a_image_id;
 | 
						|
    req->port = a_port_id;
 | 
						|
    req->width = *a_width;
 | 
						|
    req->height = *a_height;
 | 
						|
    /*
 | 
						|
     * read the reply
 | 
						|
     */
 | 
						|
    if (!_XReply (dpy, (xReply *)&rep, 0, xFalse)) {
 | 
						|
        EPHYR_LOG_ERROR ("QeryImageAttribute req failed\n") ;
 | 
						|
        goto out ;
 | 
						|
    }
 | 
						|
    if (a_pitches && a_offsets) {
 | 
						|
        _XRead (dpy,
 | 
						|
                (char*)a_pitches,
 | 
						|
                rep.num_planes << 2);
 | 
						|
        _XRead (dpy,
 | 
						|
                (char*)a_offsets,
 | 
						|
                rep.num_planes << 2);
 | 
						|
    } else {
 | 
						|
        _XEatData(dpy, rep.length << 2);
 | 
						|
    }
 | 
						|
    *a_width = rep.width ;
 | 
						|
    *a_height = rep.height ;
 | 
						|
    *a_image_size = rep.data_size ;
 | 
						|
 | 
						|
    ret = TRUE ;
 | 
						|
 | 
						|
out:
 | 
						|
    UnlockDisplay (dpy) ;
 | 
						|
    SyncHandle ();
 | 
						|
    return ret ;
 | 
						|
}
 | 
						|
 | 
						|
Bool
 | 
						|
ephyrHostGetAtom (const char* a_name,
 | 
						|
                  Bool a_create_if_not_exists,
 | 
						|
                  int *a_atom)
 | 
						|
{
 | 
						|
    int atom=None ;
 | 
						|
 | 
						|
    EPHYR_RETURN_VAL_IF_FAIL (a_atom, FALSE) ;
 | 
						|
 | 
						|
    atom = XInternAtom (hostx_get_display (), a_name, a_create_if_not_exists);
 | 
						|
    if (atom == None) {
 | 
						|
        return FALSE ;
 | 
						|
    }
 | 
						|
    *a_atom = atom ;
 | 
						|
    return TRUE ;
 | 
						|
}
 | 
						|
 | 
						|
char*
 | 
						|
ephyrHostGetAtomName (int a_atom)
 | 
						|
{
 | 
						|
    return XGetAtomName (hostx_get_display (), a_atom) ;
 | 
						|
}
 | 
						|
 | 
						|
void
 | 
						|
ephyrHostFree (void *a_pointer)
 | 
						|
{
 | 
						|
    if (a_pointer)
 | 
						|
        XFree (a_pointer) ;
 | 
						|
}
 | 
						|
 | 
						|
Bool
 | 
						|
ephyrHostXVPutImage (int a_screen_num,
 | 
						|
                     int a_port_id,
 | 
						|
                     int a_image_id,
 | 
						|
                     int a_drw_x,
 | 
						|
                     int a_drw_y,
 | 
						|
                     int a_drw_w,
 | 
						|
                     int a_drw_h,
 | 
						|
                     int a_src_x,
 | 
						|
                     int a_src_y,
 | 
						|
                     int a_src_w,
 | 
						|
                     int a_src_h,
 | 
						|
                     int a_image_width,
 | 
						|
                     int a_image_height,
 | 
						|
                     unsigned char *a_buf,
 | 
						|
                     EphyrHostBox *a_clip_rects,
 | 
						|
                     int a_clip_rect_nums )
 | 
						|
{
 | 
						|
    Bool is_ok=TRUE ;
 | 
						|
    XvImage *xv_image=NULL ;
 | 
						|
    GC gc=0 ;
 | 
						|
    XGCValues gc_values;
 | 
						|
    Display *dpy = hostx_get_display () ;
 | 
						|
    XRectangle *rects=NULL ;
 | 
						|
    int res = 0 ;
 | 
						|
 | 
						|
    EPHYR_RETURN_VAL_IF_FAIL (a_buf, FALSE) ;
 | 
						|
 | 
						|
    EPHYR_LOG ("enter, num_clip_rects: %d\n", a_clip_rect_nums) ;
 | 
						|
 | 
						|
    memset (&gc_values, 0, sizeof (gc_values)) ;
 | 
						|
    gc = XCreateGC (dpy, hostx_get_window (a_screen_num), 0L, &gc_values);
 | 
						|
    if (!gc) {
 | 
						|
        EPHYR_LOG_ERROR ("failed to create gc \n") ;
 | 
						|
        goto out ;
 | 
						|
    }
 | 
						|
    xv_image = (XvImage*) XvCreateImage (hostx_get_display (),
 | 
						|
                                         a_port_id, a_image_id,
 | 
						|
                                         NULL, a_image_width, a_image_height) ;
 | 
						|
    if (!xv_image) {
 | 
						|
        EPHYR_LOG_ERROR ("failed to create image\n") ;
 | 
						|
        goto out ;
 | 
						|
    }
 | 
						|
    xv_image->data = (char*)a_buf ;
 | 
						|
    if (a_clip_rect_nums) {
 | 
						|
        int i=0 ;
 | 
						|
        rects = calloc (a_clip_rect_nums, sizeof (XRectangle)) ;
 | 
						|
        for (i=0; i < a_clip_rect_nums; i++) {
 | 
						|
            rects[i].x = a_clip_rects[i].x1 ;
 | 
						|
            rects[i].y = a_clip_rects[i].y1 ;
 | 
						|
            rects[i].width = a_clip_rects[i].x2 - a_clip_rects[i].x1;
 | 
						|
            rects[i].height = a_clip_rects[i].y2 - a_clip_rects[i].y1;
 | 
						|
            EPHYR_LOG ("(x,y,w,h): (%d,%d,%d,%d)\n",
 | 
						|
                       rects[i].x, rects[i].y,
 | 
						|
                       rects[i].width, rects[i].height) ;
 | 
						|
        }
 | 
						|
        XSetClipRectangles (dpy, gc, 0, 0, rects, a_clip_rect_nums, YXBanded) ;
 | 
						|
        /*this always returns 1*/
 | 
						|
    }
 | 
						|
    res = XvPutImage (dpy, a_port_id,
 | 
						|
                      hostx_get_window (a_screen_num),
 | 
						|
                      gc, xv_image,
 | 
						|
                      a_src_x, a_src_y, a_src_w, a_src_h,
 | 
						|
                      a_drw_x, a_drw_y, a_drw_w, a_drw_h) ;
 | 
						|
    if (res != Success) {
 | 
						|
        EPHYR_LOG_ERROR ("XvPutImage() failed: %d\n", res) ;
 | 
						|
        goto out ;
 | 
						|
    }
 | 
						|
    is_ok = TRUE ;
 | 
						|
 | 
						|
out:
 | 
						|
    if (xv_image) {
 | 
						|
        XFree (xv_image) ;
 | 
						|
        xv_image = NULL ;
 | 
						|
    }
 | 
						|
    if (gc) {
 | 
						|
        XFreeGC (dpy, gc) ;
 | 
						|
        gc = NULL ;
 | 
						|
    }
 | 
						|
    if (rects) {
 | 
						|
        free (rects) ;
 | 
						|
        rects = NULL ;
 | 
						|
    }
 | 
						|
    EPHYR_LOG ("leave\n") ;
 | 
						|
    return is_ok ;
 | 
						|
}
 | 
						|
 | 
						|
Bool
 | 
						|
ephyrHostXVPutVideo (int a_screen_num, int a_port_id,
 | 
						|
                     int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
 | 
						|
                     int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h)
 | 
						|
{
 | 
						|
    Bool is_ok=FALSE ;
 | 
						|
    int res=FALSE ;
 | 
						|
    GC gc=0 ;
 | 
						|
    XGCValues gc_values;
 | 
						|
    Display *dpy=hostx_get_display () ;
 | 
						|
 | 
						|
    EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
 | 
						|
 | 
						|
    gc = XCreateGC (dpy, hostx_get_window (a_screen_num), 0L, &gc_values);
 | 
						|
    if (!gc) {
 | 
						|
        EPHYR_LOG_ERROR ("failed to create gc \n") ;
 | 
						|
        goto out ;
 | 
						|
    }
 | 
						|
    res = XvPutVideo (dpy, a_port_id, hostx_get_window (a_screen_num), gc,
 | 
						|
                      a_vid_x, a_vid_y, a_vid_w, a_vid_h,
 | 
						|
                      a_drw_x, a_drw_y, a_drw_w, a_drw_h) ;
 | 
						|
 | 
						|
    if (res != Success) {
 | 
						|
        EPHYR_LOG_ERROR ("XvPutVideo() failed: %d\n", res) ;
 | 
						|
        goto out ;
 | 
						|
    }
 | 
						|
 | 
						|
    is_ok = TRUE ;
 | 
						|
 | 
						|
out:
 | 
						|
    if (gc) {
 | 
						|
        XFreeGC (dpy, gc) ;
 | 
						|
        gc = NULL ;
 | 
						|
    }
 | 
						|
    return is_ok ;
 | 
						|
}
 | 
						|
 | 
						|
Bool
 | 
						|
ephyrHostXVGetVideo (int a_screen_num, int a_port_id,
 | 
						|
                     int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
 | 
						|
                     int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h)
 | 
						|
{
 | 
						|
    Bool is_ok=FALSE ;
 | 
						|
    int res=FALSE ;
 | 
						|
    GC gc=0 ;
 | 
						|
    XGCValues gc_values;
 | 
						|
    Display *dpy=hostx_get_display () ;
 | 
						|
 | 
						|
    EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
 | 
						|
 | 
						|
    gc = XCreateGC (dpy, hostx_get_window (a_screen_num), 0L, &gc_values);
 | 
						|
    if (!gc) {
 | 
						|
        EPHYR_LOG_ERROR ("failed to create gc \n") ;
 | 
						|
        goto out ;
 | 
						|
    }
 | 
						|
    res = XvGetVideo (dpy, a_port_id, hostx_get_window (a_screen_num), gc,
 | 
						|
                      a_vid_x, a_vid_y, a_vid_w, a_vid_h,
 | 
						|
                      a_drw_x, a_drw_y, a_drw_w, a_drw_h) ;
 | 
						|
 | 
						|
    if (res != Success) {
 | 
						|
        EPHYR_LOG_ERROR ("XvGetVideo() failed: %d\n", res) ;
 | 
						|
        goto out ;
 | 
						|
    }
 | 
						|
 | 
						|
    is_ok = TRUE ;
 | 
						|
 | 
						|
out:
 | 
						|
    if (gc) {
 | 
						|
        XFreeGC (dpy, gc) ;
 | 
						|
        gc = NULL ;
 | 
						|
    }
 | 
						|
    return is_ok ;
 | 
						|
}
 | 
						|
 | 
						|
Bool
 | 
						|
ephyrHostXVPutStill (int a_screen_num, int a_port_id,
 | 
						|
                     int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
 | 
						|
                     int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h)
 | 
						|
{
 | 
						|
    Bool is_ok=FALSE ;
 | 
						|
    int res=FALSE ;
 | 
						|
    GC gc=0 ;
 | 
						|
    XGCValues gc_values;
 | 
						|
    Display *dpy=hostx_get_display () ;
 | 
						|
 | 
						|
    EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
 | 
						|
 | 
						|
    gc = XCreateGC (dpy, hostx_get_window (a_screen_num), 0L, &gc_values);
 | 
						|
    if (!gc) {
 | 
						|
        EPHYR_LOG_ERROR ("failed to create gc \n") ;
 | 
						|
        goto out ;
 | 
						|
    }
 | 
						|
    res = XvPutStill (dpy, a_port_id, hostx_get_window (a_screen_num), gc,
 | 
						|
                      a_vid_x, a_vid_y, a_vid_w, a_vid_h,
 | 
						|
                      a_drw_x, a_drw_y, a_drw_w, a_drw_h) ;
 | 
						|
 | 
						|
    if (res != Success) {
 | 
						|
        EPHYR_LOG_ERROR ("XvPutStill() failed: %d\n", res) ;
 | 
						|
        goto out ;
 | 
						|
    }
 | 
						|
 | 
						|
    is_ok = TRUE ;
 | 
						|
 | 
						|
out:
 | 
						|
    if (gc) {
 | 
						|
        XFreeGC (dpy, gc) ;
 | 
						|
        gc = NULL ;
 | 
						|
    }
 | 
						|
    return is_ok ;
 | 
						|
}
 | 
						|
 | 
						|
Bool
 | 
						|
ephyrHostXVGetStill (int a_screen_num, int a_port_id,
 | 
						|
                     int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
 | 
						|
                     int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h)
 | 
						|
{
 | 
						|
    Bool is_ok=FALSE ;
 | 
						|
    int res=FALSE ;
 | 
						|
    GC gc=0 ;
 | 
						|
    XGCValues gc_values;
 | 
						|
    Display *dpy=hostx_get_display () ;
 | 
						|
 | 
						|
    EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
 | 
						|
 | 
						|
    gc = XCreateGC (dpy, hostx_get_window (a_screen_num), 0L, &gc_values);
 | 
						|
    if (!gc) {
 | 
						|
        EPHYR_LOG_ERROR ("failed to create gc \n") ;
 | 
						|
        goto out ;
 | 
						|
    }
 | 
						|
    res = XvGetStill (dpy, a_port_id, hostx_get_window (a_screen_num), gc,
 | 
						|
                      a_vid_x, a_vid_y, a_vid_w, a_vid_h,
 | 
						|
                      a_drw_x, a_drw_y, a_drw_w, a_drw_h) ;
 | 
						|
 | 
						|
    if (res != Success) {
 | 
						|
        EPHYR_LOG_ERROR ("XvGetStill() failed: %d\n", res) ;
 | 
						|
        goto out ;
 | 
						|
    }
 | 
						|
 | 
						|
    is_ok = TRUE ;
 | 
						|
 | 
						|
out:
 | 
						|
    if (gc) {
 | 
						|
        XFreeGC (dpy, gc) ;
 | 
						|
        gc = NULL ;
 | 
						|
    }
 | 
						|
    return is_ok ;
 | 
						|
}
 | 
						|
 | 
						|
Bool
 | 
						|
ephyrHostXVStopVideo (int a_screen_num, int a_port_id)
 | 
						|
{
 | 
						|
    int ret=0 ;
 | 
						|
    Bool is_ok=FALSE ;
 | 
						|
    Display *dpy = hostx_get_display () ;
 | 
						|
 | 
						|
    EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
 | 
						|
 | 
						|
    EPHYR_LOG ("enter\n") ;
 | 
						|
 | 
						|
    ret = XvStopVideo (dpy, a_port_id, hostx_get_window (a_screen_num)) ;
 | 
						|
    if (ret != Success) {
 | 
						|
        EPHYR_LOG_ERROR ("XvStopVideo() failed: %d \n", ret) ;
 | 
						|
        goto out ;
 | 
						|
    }
 | 
						|
    is_ok = TRUE ;
 | 
						|
 | 
						|
out:
 | 
						|
    EPHYR_LOG ("leave\n") ;
 | 
						|
    return is_ok ;
 | 
						|
}
 | 
						|
 |