1706f2543Smrg/*
2706f2543Smrg * Xephyr - A kdrive X server thats runs in a host X window.
3706f2543Smrg *          Authored by Matthew Allum <mallum@openedhand.com>
4706f2543Smrg *
5706f2543Smrg * Copyright © 2007 OpenedHand Ltd
6706f2543Smrg *
7706f2543Smrg * Permission to use, copy, modify, distribute, and sell this software and its
8706f2543Smrg * documentation for any purpose is hereby granted without fee, provided that
9706f2543Smrg * the above copyright notice appear in all copies and that both that
10706f2543Smrg * copyright notice and this permission notice appear in supporting
11706f2543Smrg * documentation, and that the name of OpenedHand Ltd not be used in
12706f2543Smrg * advertising or publicity pertaining to distribution of the software without
13706f2543Smrg * specific, written prior permission. OpenedHand Ltd makes no
14706f2543Smrg * representations about the suitability of this software for any purpose.  It
15706f2543Smrg * is provided "as is" without express or implied warranty.
16706f2543Smrg *
17706f2543Smrg * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
18706f2543Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
19706f2543Smrg * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR
20706f2543Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
21706f2543Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
22706f2543Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
23706f2543Smrg * PERFORMANCE OF THIS SOFTWARE.
24706f2543Smrg *
25706f2543Smrg * Authors:
26706f2543Smrg *    Dodji Seketeli <dodji@openedhand.com>
27706f2543Smrg */
28706f2543Smrg#ifdef HAVE_CONFIG_H
29706f2543Smrg#include <kdrive-config.h>
30706f2543Smrg#endif
31706f2543Smrg/*
32706f2543Smrg * including some server headers (like kdrive-config.h)
33706f2543Smrg * might define the macro _XSERVER64
34706f2543Smrg * on 64 bits machines. That macro must _NOT_ be defined for Xlib
35706f2543Smrg * client code, otherwise bad things happen.
36706f2543Smrg * So let's undef that macro if necessary.
37706f2543Smrg */
38706f2543Smrg#ifdef _XSERVER64
39706f2543Smrg#undef _XSERVER64
40706f2543Smrg#endif
41706f2543Smrg#include <X11/Xutil.h>
42706f2543Smrg#include <X11/Xlibint.h>
43706f2543Smrg#include <X11/extensions/Xvlib.h>
44706f2543Smrg#include <X11/extensions/Xvproto.h>
45706f2543Smrg#include <X11/extensions/Xext.h>
46706f2543Smrg#include <X11/extensions/extutil.h>
47706f2543Smrg#define _HAVE_XALLOC_DECLS
48706f2543Smrg
49706f2543Smrg#include "hostx.h"
50706f2543Smrg#include "ephyrhostvideo.h"
51706f2543Smrg#include "ephyrlog.h"
52706f2543Smrg
53706f2543Smrg#ifndef TRUE
54706f2543Smrg#define TRUE 1
55706f2543Smrg#endif /*TRUE*/
56706f2543Smrg
57706f2543Smrg#ifndef FALSE
58706f2543Smrg#define FALSE 0
59706f2543Smrg#endif /*FALSE*/
60706f2543Smrg
61706f2543Smrgstatic XExtensionInfo _xv_info_data;
62706f2543Smrgstatic XExtensionInfo *xv_info = &_xv_info_data;
63706f2543Smrgstatic char *xv_extension_name = XvName;
64706f2543Smrgstatic char *xv_error_string(Display *dpy, int code, XExtCodes *codes,
65706f2543Smrg                             char * buf, int n);
66706f2543Smrgstatic int xv_close_display(Display *dpy, XExtCodes *codes);
67706f2543Smrgstatic Bool xv_wire_to_event(Display *dpy, XEvent *host, xEvent *wire);
68706f2543Smrg
69706f2543Smrgstatic XExtensionHooks xv_extension_hooks = {
70706f2543Smrg    NULL,                               /* create_gc */
71706f2543Smrg    NULL,                               /* copy_gc */
72706f2543Smrg    NULL,                               /* flush_gc */
73706f2543Smrg    NULL,                               /* free_gc */
74706f2543Smrg    NULL,                               /* create_font */
75706f2543Smrg    NULL,                               /* free_font */
76706f2543Smrg    xv_close_display,                   /* close_display */
77706f2543Smrg    xv_wire_to_event,                   /* wire_to_event */
78706f2543Smrg    NULL,                               /* event_to_wire */
79706f2543Smrg    NULL,                               /* error */
80706f2543Smrg    xv_error_string                     /* error_string */
81706f2543Smrg};
82706f2543Smrg
83706f2543Smrg
84706f2543Smrgstatic char *xv_error_list[] =
85706f2543Smrg{
86706f2543Smrg   "BadPort",       /* XvBadPort     */
87706f2543Smrg   "BadEncoding",   /* XvBadEncoding */
88706f2543Smrg   "BadControl"     /* XvBadControl  */
89706f2543Smrg};
90706f2543Smrg
91706f2543Smrg
92706f2543Smrg#define XvCheckExtension(dpy, i, val) \
93706f2543Smrg  XextCheckExtension(dpy, i, xv_extension_name, val)
94706f2543Smrg#define XvGetReq(name, req) \
95706f2543Smrg        WORD64ALIGN\
96706f2543Smrg        if ((dpy->bufptr + SIZEOF(xv##name##Req)) > dpy->bufmax)\
97706f2543Smrg                _XFlush(dpy);\
98706f2543Smrg        req = (xv##name##Req *)(dpy->last_req = dpy->bufptr);\
99706f2543Smrg        req->reqType = info->codes->major_opcode;\
100706f2543Smrg        req->xvReqType = xv_##name; \
101706f2543Smrg        req->length = (SIZEOF(xv##name##Req))>>2;\
102706f2543Smrg        dpy->bufptr += SIZEOF(xv##name##Req);\
103706f2543Smrg        dpy->request++
104706f2543Smrg
105706f2543Smrgstatic XEXT_GENERATE_CLOSE_DISPLAY (xv_close_display, xv_info)
106706f2543Smrg
107706f2543Smrg
108706f2543Smrgstatic XEXT_GENERATE_FIND_DISPLAY (xv_find_display, xv_info,
109706f2543Smrg                                   xv_extension_name,
110706f2543Smrg                                   &xv_extension_hooks,
111706f2543Smrg                                   XvNumEvents, NULL)
112706f2543Smrg
113706f2543Smrgstatic XEXT_GENERATE_ERROR_STRING (xv_error_string, xv_extension_name,
114706f2543Smrg                                   XvNumErrors, xv_error_list)
115706f2543Smrg
116706f2543Smrgstruct _EphyrHostXVAdaptorArray {
117706f2543Smrg    XvAdaptorInfo *adaptors ;
118706f2543Smrg    unsigned int nb_adaptors ;
119706f2543Smrg};
120706f2543Smrg
121706f2543Smrg/*heavily copied from libx11*/
122706f2543Smrg#define BUFSIZE 2048
123706f2543Smrgstatic void
124706f2543SmrgephyrHostXVLogXErrorEvent (Display *a_display,
125706f2543Smrg                           XErrorEvent *a_err_event,
126706f2543Smrg                           FILE *a_fp)
127706f2543Smrg{
128706f2543Smrg    char buffer[BUFSIZ];
129706f2543Smrg    char mesg[BUFSIZ];
130706f2543Smrg    char number[32];
131706f2543Smrg    const char *mtype = "XlibMessage";
132706f2543Smrg    register _XExtension *ext = (_XExtension *)NULL;
133706f2543Smrg    _XExtension *bext = (_XExtension *)NULL;
134706f2543Smrg    Display *dpy = a_display ;
135706f2543Smrg
136706f2543Smrg    XGetErrorText(dpy, a_err_event->error_code, buffer, BUFSIZ);
137706f2543Smrg    XGetErrorDatabaseText(dpy, mtype, "XError", "X Error", mesg, BUFSIZ);
138706f2543Smrg    (void) fprintf(a_fp, "%s:  %s\n  ", mesg, buffer);
139706f2543Smrg    XGetErrorDatabaseText(dpy, mtype, "MajorCode", "Request Major code %d",
140706f2543Smrg            mesg, BUFSIZ);
141706f2543Smrg    (void) fprintf(a_fp, mesg, a_err_event->request_code);
142706f2543Smrg    if (a_err_event->request_code < 128) {
143706f2543Smrg        sprintf(number, "%d", a_err_event->request_code);
144706f2543Smrg        XGetErrorDatabaseText(dpy, "XRequest", number, "", buffer, BUFSIZ);
145706f2543Smrg    } else {
146706f2543Smrg        for (ext = dpy->ext_procs;
147706f2543Smrg                ext && (ext->codes.major_opcode != a_err_event->request_code);
148706f2543Smrg                ext = ext->next)
149706f2543Smrg            ;
150706f2543Smrg        if (ext)
151706f2543Smrg            strcpy(buffer, ext->name);
152706f2543Smrg        else
153706f2543Smrg            buffer[0] = '\0';
154706f2543Smrg    }
155706f2543Smrg    (void) fprintf(a_fp, " (%s)\n", buffer);
156706f2543Smrg    if (a_err_event->request_code >= 128) {
157706f2543Smrg        XGetErrorDatabaseText(dpy, mtype, "MinorCode", "Request Minor code %d",
158706f2543Smrg                mesg, BUFSIZ);
159706f2543Smrg        fputs("  ", a_fp);
160706f2543Smrg        (void) fprintf(a_fp, mesg, a_err_event->minor_code);
161706f2543Smrg        if (ext) {
162706f2543Smrg            sprintf(mesg, "%s.%d", ext->name, a_err_event->minor_code);
163706f2543Smrg            XGetErrorDatabaseText(dpy, "XRequest", mesg, "", buffer, BUFSIZ);
164706f2543Smrg            (void) fprintf(a_fp, " (%s)", buffer);
165706f2543Smrg        }
166706f2543Smrg        fputs("\n", a_fp);
167706f2543Smrg    }
168706f2543Smrg    if (a_err_event->error_code >= 128) {
169706f2543Smrg        /* kludge, try to find the extension that caused it */
170706f2543Smrg        buffer[0] = '\0';
171706f2543Smrg        for (ext = dpy->ext_procs; ext; ext = ext->next) {
172706f2543Smrg            if (ext->error_string)
173706f2543Smrg                (*ext->error_string)(dpy, a_err_event->error_code, &ext->codes,
174706f2543Smrg                        buffer, BUFSIZ);
175706f2543Smrg            if (buffer[0]) {
176706f2543Smrg                bext = ext;
177706f2543Smrg                break;
178706f2543Smrg            }
179706f2543Smrg            if (ext->codes.first_error &&
180706f2543Smrg                    ext->codes.first_error < (int)a_err_event->error_code &&
181706f2543Smrg                    (!bext || ext->codes.first_error > bext->codes.first_error))
182706f2543Smrg                bext = ext;
183706f2543Smrg        }
184706f2543Smrg        if (bext)
185706f2543Smrg            sprintf(buffer, "%s.%d", bext->name,
186706f2543Smrg                    a_err_event->error_code - bext->codes.first_error);
187706f2543Smrg        else
188706f2543Smrg            strcpy(buffer, "Value");
189706f2543Smrg        XGetErrorDatabaseText(dpy, mtype, buffer, "", mesg, BUFSIZ);
190706f2543Smrg        if (mesg[0]) {
191706f2543Smrg            fputs("  ", a_fp);
192706f2543Smrg            (void) fprintf(a_fp, mesg, a_err_event->resourceid);
193706f2543Smrg            fputs("\n", a_fp);
194706f2543Smrg        }
195706f2543Smrg        /* let extensions try to print the values */
196706f2543Smrg        for (ext = dpy->ext_procs; ext; ext = ext->next) {
197706f2543Smrg            if (ext->error_values)
198706f2543Smrg                (*ext->error_values)(dpy, a_err_event, a_fp);
199706f2543Smrg        }
200706f2543Smrg    } else if ((a_err_event->error_code == BadWindow) ||
201706f2543Smrg            (a_err_event->error_code == BadPixmap) ||
202706f2543Smrg            (a_err_event->error_code == BadCursor) ||
203706f2543Smrg            (a_err_event->error_code == BadFont) ||
204706f2543Smrg            (a_err_event->error_code == BadDrawable) ||
205706f2543Smrg            (a_err_event->error_code == BadColor) ||
206706f2543Smrg            (a_err_event->error_code == BadGC) ||
207706f2543Smrg            (a_err_event->error_code == BadIDChoice) ||
208706f2543Smrg            (a_err_event->error_code == BadValue) ||
209706f2543Smrg            (a_err_event->error_code == BadAtom)) {
210706f2543Smrg        if (a_err_event->error_code == BadValue)
211706f2543Smrg            XGetErrorDatabaseText(dpy, mtype, "Value", "Value 0x%x",
212706f2543Smrg                    mesg, BUFSIZ);
213706f2543Smrg        else if (a_err_event->error_code == BadAtom)
214706f2543Smrg            XGetErrorDatabaseText(dpy, mtype, "AtomID", "AtomID 0x%x",
215706f2543Smrg                    mesg, BUFSIZ);
216706f2543Smrg        else
217706f2543Smrg            XGetErrorDatabaseText(dpy, mtype, "ResourceID", "ResourceID 0x%x",
218706f2543Smrg                    mesg, BUFSIZ);
219706f2543Smrg        fputs("  ", a_fp);
220706f2543Smrg        (void) fprintf(a_fp, mesg, a_err_event->resourceid);
221706f2543Smrg        fputs("\n", a_fp);
222706f2543Smrg    }
223706f2543Smrg    XGetErrorDatabaseText(dpy, mtype, "ErrorSerial", "Error Serial #%d",
224706f2543Smrg            mesg, BUFSIZ);
225706f2543Smrg    fputs("  ", a_fp);
226706f2543Smrg    (void) fprintf(a_fp, mesg, a_err_event->serial);
227706f2543Smrg    XGetErrorDatabaseText(dpy, mtype, "CurrentSerial", "Current Serial #%d",
228706f2543Smrg            mesg, BUFSIZ);
229706f2543Smrg    fputs("\n  ", a_fp);
230706f2543Smrg    (void) fprintf(a_fp, mesg, dpy->request);
231706f2543Smrg    fputs("\n", a_fp);
232706f2543Smrg}
233706f2543Smrg
234706f2543Smrgstatic int
235706f2543SmrgephyrHostXVErrorHandler (Display *a_display,
236706f2543Smrg                         XErrorEvent *a_error_event)
237706f2543Smrg{
238706f2543Smrg    EPHYR_LOG_ERROR ("got an error from the host xserver:\n") ;
239706f2543Smrg    ephyrHostXVLogXErrorEvent (a_display, a_error_event, stderr) ;
240706f2543Smrg    return Success ;
241706f2543Smrg}
242706f2543Smrg
243706f2543Smrgvoid
244706f2543SmrgephyrHostXVInit (void)
245706f2543Smrg{
246706f2543Smrg    static Bool s_initialized ;
247706f2543Smrg
248706f2543Smrg    if (s_initialized)
249706f2543Smrg        return ;
250706f2543Smrg    XSetErrorHandler (ephyrHostXVErrorHandler) ;
251706f2543Smrg    s_initialized = TRUE ;
252706f2543Smrg}
253706f2543Smrg
254706f2543SmrgBool
255706f2543SmrgephyrHostXVQueryAdaptors (EphyrHostXVAdaptorArray **a_adaptors)
256706f2543Smrg{
257706f2543Smrg    EphyrHostXVAdaptorArray *result=NULL ;
258706f2543Smrg    int ret=0 ;
259706f2543Smrg    Bool is_ok=FALSE ;
260706f2543Smrg
261706f2543Smrg    EPHYR_RETURN_VAL_IF_FAIL (a_adaptors, FALSE) ;
262706f2543Smrg
263706f2543Smrg    EPHYR_LOG ("enter\n") ;
264706f2543Smrg
265706f2543Smrg    result = calloc (1, sizeof (EphyrHostXVAdaptorArray)) ;
266706f2543Smrg    if (!result)
267706f2543Smrg        goto out ;
268706f2543Smrg
269706f2543Smrg    ret = XvQueryAdaptors (hostx_get_display (),
270706f2543Smrg                           DefaultRootWindow (hostx_get_display ()),
271706f2543Smrg                           &result->nb_adaptors,
272706f2543Smrg                           &result->adaptors) ;
273706f2543Smrg    if (ret != Success) {
274706f2543Smrg        EPHYR_LOG_ERROR ("failed to query host adaptors: %d\n", ret) ;
275706f2543Smrg        goto out ;
276706f2543Smrg    }
277706f2543Smrg    *a_adaptors = result ;
278706f2543Smrg    is_ok = TRUE ;
279706f2543Smrg
280706f2543Smrgout:
281706f2543Smrg    EPHYR_LOG ("leave\n") ;
282706f2543Smrg    return is_ok ;
283706f2543Smrg}
284706f2543Smrg
285706f2543Smrgvoid
286706f2543SmrgephyrHostXVAdaptorArrayDelete (EphyrHostXVAdaptorArray *a_adaptors)
287706f2543Smrg{
288706f2543Smrg    if (!a_adaptors)
289706f2543Smrg        return ;
290706f2543Smrg    if (a_adaptors->adaptors) {
291706f2543Smrg        XvFreeAdaptorInfo (a_adaptors->adaptors) ;
292706f2543Smrg        a_adaptors->adaptors = NULL ;
293706f2543Smrg        a_adaptors->nb_adaptors = 0 ;
294706f2543Smrg    }
295706f2543Smrg    XFree (a_adaptors) ;
296706f2543Smrg}
297706f2543Smrg
298706f2543Smrgint
299706f2543SmrgephyrHostXVAdaptorArrayGetSize (const EphyrHostXVAdaptorArray *a_this)
300706f2543Smrg{
301706f2543Smrg    EPHYR_RETURN_VAL_IF_FAIL (a_this, -1) ;
302706f2543Smrg    return a_this->nb_adaptors ;
303706f2543Smrg}
304706f2543Smrg
305706f2543SmrgEphyrHostXVAdaptor*
306706f2543SmrgephyrHostXVAdaptorArrayAt (const EphyrHostXVAdaptorArray *a_this,
307706f2543Smrg                           int a_index)
308706f2543Smrg{
309706f2543Smrg    EPHYR_RETURN_VAL_IF_FAIL (a_this, NULL) ;
310706f2543Smrg
311706f2543Smrg    if (a_index >= a_this->nb_adaptors)
312706f2543Smrg        return NULL ;
313706f2543Smrg    return (EphyrHostXVAdaptor*)&a_this->adaptors[a_index] ;
314706f2543Smrg}
315706f2543Smrg
316706f2543Smrgchar
317706f2543SmrgephyrHostXVAdaptorGetType (const EphyrHostXVAdaptor *a_this)
318706f2543Smrg{
319706f2543Smrg    EPHYR_RETURN_VAL_IF_FAIL (a_this, -1) ;
320706f2543Smrg    return ((XvAdaptorInfo*)a_this)->type ;
321706f2543Smrg}
322706f2543Smrg
323706f2543Smrgconst char*
324706f2543SmrgephyrHostXVAdaptorGetName (const EphyrHostXVAdaptor *a_this)
325706f2543Smrg{
326706f2543Smrg    EPHYR_RETURN_VAL_IF_FAIL (a_this, NULL) ;
327706f2543Smrg
328706f2543Smrg    return ((XvAdaptorInfo*)a_this)->name ;
329706f2543Smrg}
330706f2543Smrg
331706f2543SmrgEphyrHostVideoFormat*
332706f2543SmrgephyrHostXVAdaptorGetVideoFormats (const EphyrHostXVAdaptor *a_this,
333706f2543Smrg                                   int *a_nb_formats)
334706f2543Smrg{
335706f2543Smrg    EphyrHostVideoFormat *formats=NULL ;
336706f2543Smrg    int nb_formats=0, i=0 ;
337706f2543Smrg    XVisualInfo *visual_info, visual_info_template ;
338706f2543Smrg    int nb_visual_info ;
339706f2543Smrg
340706f2543Smrg    EPHYR_RETURN_VAL_IF_FAIL (a_this, NULL) ;
341706f2543Smrg
342706f2543Smrg    nb_formats = ((XvAdaptorInfo*)a_this)->num_formats ;
343706f2543Smrg    formats = calloc (nb_formats, sizeof (EphyrHostVideoFormat)) ;
344706f2543Smrg    for (i=0; i < nb_formats; i++) {
345706f2543Smrg        memset (&visual_info_template, 0, sizeof (visual_info_template)) ;
346706f2543Smrg        visual_info_template.visualid =
347706f2543Smrg                            ((XvAdaptorInfo*)a_this)->formats[i].visual_id;
348706f2543Smrg        visual_info = XGetVisualInfo (hostx_get_display (),
349706f2543Smrg                                      VisualIDMask,
350706f2543Smrg                                      &visual_info_template,
351706f2543Smrg                                      &nb_visual_info) ;
352706f2543Smrg        formats[i].depth = ((XvAdaptorInfo*)a_this)->formats[i].depth ;
353706f2543Smrg        formats[i].visual_class = visual_info->class ;
354706f2543Smrg        XFree (visual_info) ;
355706f2543Smrg    }
356706f2543Smrg    if (a_nb_formats)
357706f2543Smrg        *a_nb_formats = nb_formats ;
358706f2543Smrg    return formats ;
359706f2543Smrg}
360706f2543Smrg
361706f2543Smrgint
362706f2543SmrgephyrHostXVAdaptorGetNbPorts (const EphyrHostXVAdaptor *a_this)
363706f2543Smrg{
364706f2543Smrg    EPHYR_RETURN_VAL_IF_FAIL (a_this, -1) ;
365706f2543Smrg
366706f2543Smrg    return ((XvAdaptorInfo*)a_this)->num_ports ;
367706f2543Smrg}
368706f2543Smrg
369706f2543Smrgint
370706f2543SmrgephyrHostXVAdaptorGetFirstPortID (const EphyrHostXVAdaptor *a_this)
371706f2543Smrg{
372706f2543Smrg    EPHYR_RETURN_VAL_IF_FAIL (a_this, -1) ;
373706f2543Smrg
374706f2543Smrg    return ((XvAdaptorInfo*)a_this)->base_id ;
375706f2543Smrg}
376706f2543Smrg
377706f2543SmrgBool
378706f2543SmrgephyrHostXVAdaptorHasPutVideo (const EphyrHostXVAdaptor *a_this,
379706f2543Smrg                               Bool *a_result)
380706f2543Smrg{
381706f2543Smrg    EPHYR_RETURN_VAL_IF_FAIL (a_this && a_result, FALSE) ;
382706f2543Smrg
383706f2543Smrg    if ((((XvAdaptorInfo*)a_this)->type & (XvVideoMask | XvInputMask)) ==
384706f2543Smrg		    (XvVideoMask | XvInputMask))
385706f2543Smrg        *a_result = TRUE ;
386706f2543Smrg    else
387706f2543Smrg        *a_result = FALSE ;
388706f2543Smrg    return TRUE ;
389706f2543Smrg}
390706f2543Smrg
391706f2543SmrgBool
392706f2543SmrgephyrHostXVAdaptorHasGetVideo (const EphyrHostXVAdaptor *a_this,
393706f2543Smrg                               Bool *a_result)
394706f2543Smrg{
395706f2543Smrg    if ((((XvAdaptorInfo*)a_this)->type & (XvVideoMask | XvOutputMask)) ==
396706f2543Smrg		    (XvVideoMask | XvOutputMask))
397706f2543Smrg        *a_result = TRUE ;
398706f2543Smrg    else
399706f2543Smrg        *a_result = FALSE ;
400706f2543Smrg    return TRUE ;
401706f2543Smrg}
402706f2543Smrg
403706f2543SmrgBool
404706f2543SmrgephyrHostXVAdaptorHasPutStill (const EphyrHostXVAdaptor *a_this,
405706f2543Smrg                               Bool *a_result)
406706f2543Smrg{
407706f2543Smrg    EPHYR_RETURN_VAL_IF_FAIL (a_this && a_result, FALSE) ;
408706f2543Smrg
409706f2543Smrg    if ((((XvAdaptorInfo*)a_this)->type & (XvStillMask | XvInputMask)) ==
410706f2543Smrg		    (XvStillMask | XvInputMask))
411706f2543Smrg        *a_result = TRUE ;
412706f2543Smrg    else
413706f2543Smrg        *a_result = FALSE ;
414706f2543Smrg    return TRUE ;
415706f2543Smrg}
416706f2543Smrg
417706f2543SmrgBool
418706f2543SmrgephyrHostXVAdaptorHasGetStill (const EphyrHostXVAdaptor *a_this,
419706f2543Smrg                               Bool *a_result)
420706f2543Smrg{
421706f2543Smrg    EPHYR_RETURN_VAL_IF_FAIL (a_this && a_result, FALSE) ;
422706f2543Smrg
423706f2543Smrg    if ((((XvAdaptorInfo*)a_this)->type & (XvStillMask | XvOutputMask)) ==
424706f2543Smrg		    (XvStillMask | XvOutputMask))
425706f2543Smrg        *a_result = TRUE ;
426706f2543Smrg    else
427706f2543Smrg        *a_result = FALSE ;
428706f2543Smrg    return TRUE ;
429706f2543Smrg}
430706f2543Smrg
431706f2543SmrgBool
432706f2543SmrgephyrHostXVAdaptorHasPutImage (const EphyrHostXVAdaptor *a_this,
433706f2543Smrg                               Bool *a_result)
434706f2543Smrg{
435706f2543Smrg    EPHYR_RETURN_VAL_IF_FAIL (a_this && a_result, FALSE) ;
436706f2543Smrg
437706f2543Smrg    if ((((XvAdaptorInfo*)a_this)->type & (XvImageMask | XvInputMask)) ==
438706f2543Smrg		    (XvImageMask | XvInputMask))
439706f2543Smrg        *a_result = TRUE ;
440706f2543Smrg    else
441706f2543Smrg        *a_result = FALSE ;
442706f2543Smrg    return TRUE ;
443706f2543Smrg}
444706f2543Smrg
445706f2543SmrgBool
446706f2543SmrgephyrHostXVQueryEncodings (int a_port_id,
447706f2543Smrg                           EphyrHostEncoding **a_encodings,
448706f2543Smrg                           unsigned int *a_num_encodings)
449706f2543Smrg{
450706f2543Smrg    EphyrHostEncoding *encodings=NULL ;
451706f2543Smrg    XvEncodingInfo *encoding_info=NULL ;
452706f2543Smrg    unsigned int num_encodings=0, i;
453706f2543Smrg    int ret=0 ;
454706f2543Smrg
455706f2543Smrg    EPHYR_RETURN_VAL_IF_FAIL (a_encodings && a_num_encodings, FALSE) ;
456706f2543Smrg
457706f2543Smrg    ret = XvQueryEncodings (hostx_get_display (),
458706f2543Smrg                            a_port_id,
459706f2543Smrg                            &num_encodings,
460706f2543Smrg                            &encoding_info) ;
461706f2543Smrg    if (num_encodings && encoding_info) {
462706f2543Smrg        encodings = calloc (num_encodings, sizeof (EphyrHostEncoding)) ;
463706f2543Smrg        for (i=0; i<num_encodings; i++) {
464706f2543Smrg            encodings[i].id = encoding_info[i].encoding_id ;
465706f2543Smrg            encodings[i].name = strdup (encoding_info[i].name) ;
466706f2543Smrg            encodings[i].width = encoding_info[i].width ;
467706f2543Smrg            encodings[i].height = encoding_info[i].height ;
468706f2543Smrg            encodings[i].rate.numerator = encoding_info[i].rate.numerator ;
469706f2543Smrg            encodings[i].rate.denominator = encoding_info[i].rate.denominator ;
470706f2543Smrg        }
471706f2543Smrg    }
472706f2543Smrg    if (encoding_info) {
473706f2543Smrg        XvFreeEncodingInfo (encoding_info) ;
474706f2543Smrg        encoding_info = NULL ;
475706f2543Smrg    }
476706f2543Smrg    *a_encodings = encodings ;
477706f2543Smrg    *a_num_encodings = num_encodings ;
478706f2543Smrg
479706f2543Smrg    if (ret != Success)
480706f2543Smrg        return FALSE ;
481706f2543Smrg    return TRUE ;
482706f2543Smrg}
483706f2543Smrg
484706f2543Smrgvoid
485706f2543SmrgephyrHostEncodingsDelete (EphyrHostEncoding *a_encodings,
486706f2543Smrg                          int a_num_encodings)
487706f2543Smrg{
488706f2543Smrg    int i=0 ;
489706f2543Smrg
490706f2543Smrg    if (!a_encodings)
491706f2543Smrg        return ;
492706f2543Smrg    for (i=0; i < a_num_encodings; i++) {
493706f2543Smrg        free(a_encodings[i].name) ;
494706f2543Smrg        a_encodings[i].name = NULL ;
495706f2543Smrg    }
496706f2543Smrg    free(a_encodings) ;
497706f2543Smrg}
498706f2543Smrg
499706f2543Smrgvoid
500706f2543SmrgephyrHostAttributesDelete (EphyrHostAttribute *a_attributes)
501706f2543Smrg{
502706f2543Smrg    if (!a_attributes)
503706f2543Smrg        return ;
504706f2543Smrg    XFree (a_attributes) ;
505706f2543Smrg}
506706f2543Smrg
507706f2543SmrgBool
508706f2543SmrgephyrHostXVQueryPortAttributes (int a_port_id,
509706f2543Smrg                                EphyrHostAttribute **a_attributes,
510706f2543Smrg                                int *a_num_attributes)
511706f2543Smrg{
512706f2543Smrg    EPHYR_RETURN_VAL_IF_FAIL (a_attributes && a_num_attributes, FALSE) ;
513706f2543Smrg
514706f2543Smrg    *a_attributes =
515706f2543Smrg        (EphyrHostAttribute*)XvQueryPortAttributes (hostx_get_display (),
516706f2543Smrg                                                    a_port_id,
517706f2543Smrg                                                    a_num_attributes);
518706f2543Smrg
519706f2543Smrg    return TRUE ;
520706f2543Smrg}
521706f2543Smrg
522706f2543SmrgBool
523706f2543SmrgephyrHostXVQueryImageFormats (int a_port_id,
524706f2543Smrg                              EphyrHostImageFormat **a_formats,
525706f2543Smrg                              int *a_num_format)
526706f2543Smrg{
527706f2543Smrg    XvImageFormatValues *result=NULL ;
528706f2543Smrg
529706f2543Smrg    EPHYR_RETURN_VAL_IF_FAIL (a_formats && a_num_format, FALSE) ;
530706f2543Smrg
531706f2543Smrg    result = XvListImageFormats (hostx_get_display (),
532706f2543Smrg                                 a_port_id,
533706f2543Smrg                                 a_num_format) ;
534706f2543Smrg    *a_formats = (EphyrHostImageFormat*) result ;
535706f2543Smrg    return TRUE ;
536706f2543Smrg
537706f2543Smrg}
538706f2543Smrg
539706f2543SmrgBool
540706f2543SmrgephyrHostXVSetPortAttribute (int a_port_id,
541706f2543Smrg                             int a_atom,
542706f2543Smrg                             int a_attr_value)
543706f2543Smrg{
544706f2543Smrg    int res=Success ;
545706f2543Smrg
546706f2543Smrg    EPHYR_LOG ("atom,name,value: (%d,%s,%d)\n",
547706f2543Smrg               a_atom,
548706f2543Smrg               XGetAtomName (hostx_get_display (), a_atom),
549706f2543Smrg               a_attr_value) ;
550706f2543Smrg
551706f2543Smrg    res = XvSetPortAttribute (hostx_get_display (),
552706f2543Smrg                              a_port_id,
553706f2543Smrg                              a_atom,
554706f2543Smrg                              a_attr_value) ;
555706f2543Smrg    if (res != Success) {
556706f2543Smrg        EPHYR_LOG_ERROR ("XvSetPortAttribute() failed: %d\n", res) ;
557706f2543Smrg        return FALSE ;
558706f2543Smrg    }
559706f2543Smrg    XFlush (hostx_get_display ()) ;
560706f2543Smrg    EPHYR_LOG ("leave\n") ;
561706f2543Smrg
562706f2543Smrg    return TRUE ;
563706f2543Smrg}
564706f2543Smrg
565706f2543SmrgBool
566706f2543SmrgephyrHostXVGetPortAttribute (int a_port_id,
567706f2543Smrg                             int a_atom,
568706f2543Smrg                             int *a_attr_value)
569706f2543Smrg{
570706f2543Smrg    int res=Success ;
571706f2543Smrg    Bool ret=FALSE ;
572706f2543Smrg
573706f2543Smrg    EPHYR_RETURN_VAL_IF_FAIL (a_attr_value, FALSE) ;
574706f2543Smrg
575706f2543Smrg    EPHYR_LOG ("enter, a_port_id: %d, a_atomid: %d, attr_name: %s\n",
576706f2543Smrg               a_port_id, a_atom, XGetAtomName (hostx_get_display (), a_atom)) ;
577706f2543Smrg
578706f2543Smrg    res = XvGetPortAttribute (hostx_get_display (),
579706f2543Smrg                              a_port_id,
580706f2543Smrg                              a_atom,
581706f2543Smrg                              a_attr_value) ;
582706f2543Smrg    if (res != Success) {
583706f2543Smrg        EPHYR_LOG_ERROR ("XvGetPortAttribute() failed: %d \n", res) ;
584706f2543Smrg        goto out ;
585706f2543Smrg    }
586706f2543Smrg    EPHYR_LOG ("atom,value: (%d, %d)\n", a_atom, *a_attr_value) ;
587706f2543Smrg
588706f2543Smrg    ret = TRUE ;
589706f2543Smrg
590706f2543Smrgout:
591706f2543Smrg    EPHYR_LOG ("leave\n") ;
592706f2543Smrg    return ret ;
593706f2543Smrg}
594706f2543Smrg
595706f2543SmrgBool
596706f2543SmrgephyrHostXVQueryBestSize (int a_port_id,
597706f2543Smrg                          Bool a_motion,
598706f2543Smrg                          unsigned int a_frame_w,
599706f2543Smrg                          unsigned int a_frame_h,
600706f2543Smrg                          unsigned int a_drw_w,
601706f2543Smrg                          unsigned int a_drw_h,
602706f2543Smrg                          unsigned int *a_actual_w,
603706f2543Smrg                          unsigned int *a_actual_h)
604706f2543Smrg{
605706f2543Smrg    int res=0 ;
606706f2543Smrg    Bool is_ok=FALSE ;
607706f2543Smrg
608706f2543Smrg    EPHYR_RETURN_VAL_IF_FAIL (a_actual_w && a_actual_h, FALSE) ;
609706f2543Smrg
610706f2543Smrg    EPHYR_LOG ("enter: frame (%dx%d), drw (%dx%d)\n",
611706f2543Smrg               a_frame_w, a_frame_h,
612706f2543Smrg               a_drw_w, a_drw_h) ;
613706f2543Smrg
614706f2543Smrg    res = XvQueryBestSize (hostx_get_display (),
615706f2543Smrg                           a_port_id,
616706f2543Smrg                           a_motion,
617706f2543Smrg                           a_frame_w, a_frame_h,
618706f2543Smrg                           a_drw_w, a_drw_h,
619706f2543Smrg                           a_actual_w, a_actual_h) ;
620706f2543Smrg    if (res != Success) {
621706f2543Smrg        EPHYR_LOG_ERROR ("XvQueryBestSize() failed: %d\n", res) ;
622706f2543Smrg        goto out ;
623706f2543Smrg    }
624706f2543Smrg    XSync (hostx_get_display (), FALSE) ;
625706f2543Smrg
626706f2543Smrg    EPHYR_LOG ("actual (%dx%d)\n", *a_actual_w, *a_actual_h) ;
627706f2543Smrg    is_ok = TRUE ;
628706f2543Smrg
629706f2543Smrgout:
630706f2543Smrg    EPHYR_LOG ("leave\n") ;
631706f2543Smrg    return is_ok ;
632706f2543Smrg}
633706f2543Smrg
634706f2543Smrgstatic Bool
635706f2543Smrgxv_wire_to_event(Display *dpy, XEvent *host, xEvent *wire)
636706f2543Smrg{
637706f2543Smrg    XExtDisplayInfo *info = xv_find_display (dpy);
638706f2543Smrg    XvEvent *re    = (XvEvent *)host;
639706f2543Smrg    xvEvent *event = (xvEvent *)wire;
640706f2543Smrg
641706f2543Smrg    XvCheckExtension(dpy, info, False);
642706f2543Smrg
643706f2543Smrg    switch ((event->u.u.type & 0x7F) - info->codes->first_event) {
644706f2543Smrg        case XvVideoNotify:
645706f2543Smrg            re->xvvideo.type = event->u.u.type & 0x7f;
646706f2543Smrg            re->xvvideo.serial =
647706f2543Smrg            _XSetLastRequestRead(dpy, (xGenericReply *)event);
648706f2543Smrg            re->xvvideo.send_event = ((event->u.u.type & 0x80) != 0);
649706f2543Smrg            re->xvvideo.display = dpy;
650706f2543Smrg            re->xvvideo.time = event->u.videoNotify.time;
651706f2543Smrg            re->xvvideo.reason = event->u.videoNotify.reason;
652706f2543Smrg            re->xvvideo.drawable = event->u.videoNotify.drawable;
653706f2543Smrg            re->xvvideo.port_id = event->u.videoNotify.port;
654706f2543Smrg            break;
655706f2543Smrg        case XvPortNotify:
656706f2543Smrg            re->xvport.type = event->u.u.type & 0x7f;
657706f2543Smrg            re->xvport.serial =
658706f2543Smrg            _XSetLastRequestRead(dpy, (xGenericReply *)event);
659706f2543Smrg            re->xvport.send_event = ((event->u.u.type & 0x80) != 0);
660706f2543Smrg            re->xvport.display = dpy;
661706f2543Smrg            re->xvport.time = event->u.portNotify.time;
662706f2543Smrg            re->xvport.port_id = event->u.portNotify.port;
663706f2543Smrg            re->xvport.attribute = event->u.portNotify.attribute;
664706f2543Smrg            re->xvport.value = event->u.portNotify.value;
665706f2543Smrg            break;
666706f2543Smrg        default:
667706f2543Smrg            return False;
668706f2543Smrg    }
669706f2543Smrg
670706f2543Smrg    return True ;
671706f2543Smrg}
672706f2543Smrg
673706f2543SmrgBool
674706f2543SmrgephyrHostXVQueryImageAttributes (int a_port_id,
675706f2543Smrg                                 int a_image_id /*image fourcc code*/,
676706f2543Smrg                                 unsigned short *a_width,
677706f2543Smrg                                 unsigned short *a_height,
678706f2543Smrg                                 int *a_image_size,
679706f2543Smrg                                 int *a_pitches,
680706f2543Smrg                                 int *a_offsets)
681706f2543Smrg{
682706f2543Smrg    Display *dpy = hostx_get_display () ;
683706f2543Smrg    Bool ret=FALSE ;
684706f2543Smrg    XExtDisplayInfo *info = xv_find_display (dpy);
685706f2543Smrg    xvQueryImageAttributesReq *req=NULL;
686706f2543Smrg    xvQueryImageAttributesReply rep;
687706f2543Smrg
688706f2543Smrg    EPHYR_RETURN_VAL_IF_FAIL (a_width, FALSE) ;
689706f2543Smrg    EPHYR_RETURN_VAL_IF_FAIL (a_height, FALSE) ;
690706f2543Smrg    EPHYR_RETURN_VAL_IF_FAIL (a_image_size, FALSE) ;
691706f2543Smrg
692706f2543Smrg    XvCheckExtension (dpy, info, FALSE);
693706f2543Smrg
694706f2543Smrg    LockDisplay (dpy);
695706f2543Smrg
696706f2543Smrg    XvGetReq (QueryImageAttributes, req);
697706f2543Smrg    req->id = a_image_id;
698706f2543Smrg    req->port = a_port_id;
699706f2543Smrg    req->width = *a_width;
700706f2543Smrg    req->height = *a_height;
701706f2543Smrg    /*
702706f2543Smrg     * read the reply
703706f2543Smrg     */
704706f2543Smrg    if (!_XReply (dpy, (xReply *)&rep, 0, xFalse)) {
705706f2543Smrg        EPHYR_LOG_ERROR ("QeryImageAttribute req failed\n") ;
706706f2543Smrg        goto out ;
707706f2543Smrg    }
708706f2543Smrg    if (a_pitches && a_offsets) {
709706f2543Smrg        _XRead (dpy,
710706f2543Smrg                (char*)a_pitches,
711706f2543Smrg                rep.num_planes << 2);
712706f2543Smrg        _XRead (dpy,
713706f2543Smrg                (char*)a_offsets,
714706f2543Smrg                rep.num_planes << 2);
715706f2543Smrg    } else {
716706f2543Smrg        _XEatData(dpy, rep.length << 2);
717706f2543Smrg    }
718706f2543Smrg    *a_width = rep.width ;
719706f2543Smrg    *a_height = rep.height ;
720706f2543Smrg    *a_image_size = rep.data_size ;
721706f2543Smrg
722706f2543Smrg    ret = TRUE ;
723706f2543Smrg
724706f2543Smrgout:
725706f2543Smrg    UnlockDisplay (dpy) ;
726706f2543Smrg    SyncHandle ();
727706f2543Smrg    return ret ;
728706f2543Smrg}
729706f2543Smrg
730706f2543SmrgBool
731706f2543SmrgephyrHostGetAtom (const char* a_name,
732706f2543Smrg                  Bool a_create_if_not_exists,
733706f2543Smrg                  int *a_atom)
734706f2543Smrg{
735706f2543Smrg    int atom=None ;
736706f2543Smrg
737706f2543Smrg    EPHYR_RETURN_VAL_IF_FAIL (a_atom, FALSE) ;
738706f2543Smrg
739706f2543Smrg    atom = XInternAtom (hostx_get_display (), a_name, a_create_if_not_exists);
740706f2543Smrg    if (atom == None) {
741706f2543Smrg        return FALSE ;
742706f2543Smrg    }
743706f2543Smrg    *a_atom = atom ;
744706f2543Smrg    return TRUE ;
745706f2543Smrg}
746706f2543Smrg
747706f2543Smrgchar*
748706f2543SmrgephyrHostGetAtomName (int a_atom)
749706f2543Smrg{
750706f2543Smrg    return XGetAtomName (hostx_get_display (), a_atom) ;
751706f2543Smrg}
752706f2543Smrg
753706f2543Smrgvoid
754706f2543SmrgephyrHostFree (void *a_pointer)
755706f2543Smrg{
756706f2543Smrg    if (a_pointer)
757706f2543Smrg        XFree (a_pointer) ;
758706f2543Smrg}
759706f2543Smrg
760706f2543SmrgBool
761706f2543SmrgephyrHostXVPutImage (int a_screen_num,
762706f2543Smrg                     int a_port_id,
763706f2543Smrg                     int a_image_id,
764706f2543Smrg                     int a_drw_x,
765706f2543Smrg                     int a_drw_y,
766706f2543Smrg                     int a_drw_w,
767706f2543Smrg                     int a_drw_h,
768706f2543Smrg                     int a_src_x,
769706f2543Smrg                     int a_src_y,
770706f2543Smrg                     int a_src_w,
771706f2543Smrg                     int a_src_h,
772706f2543Smrg                     int a_image_width,
773706f2543Smrg                     int a_image_height,
774706f2543Smrg                     unsigned char *a_buf,
775706f2543Smrg                     EphyrHostBox *a_clip_rects,
776706f2543Smrg                     int a_clip_rect_nums )
777706f2543Smrg{
778706f2543Smrg    Bool is_ok=TRUE ;
779706f2543Smrg    XvImage *xv_image=NULL ;
780706f2543Smrg    GC gc=0 ;
781706f2543Smrg    XGCValues gc_values;
782706f2543Smrg    Display *dpy = hostx_get_display () ;
783706f2543Smrg    XRectangle *rects=NULL ;
784706f2543Smrg    int res = 0 ;
785706f2543Smrg
786706f2543Smrg    EPHYR_RETURN_VAL_IF_FAIL (a_buf, FALSE) ;
787706f2543Smrg
788706f2543Smrg    EPHYR_LOG ("enter, num_clip_rects: %d\n", a_clip_rect_nums) ;
789706f2543Smrg
790706f2543Smrg    memset (&gc_values, 0, sizeof (gc_values)) ;
791706f2543Smrg    gc = XCreateGC (dpy, hostx_get_window (a_screen_num), 0L, &gc_values);
792706f2543Smrg    if (!gc) {
793706f2543Smrg        EPHYR_LOG_ERROR ("failed to create gc \n") ;
794706f2543Smrg        goto out ;
795706f2543Smrg    }
796706f2543Smrg    xv_image = (XvImage*) XvCreateImage (hostx_get_display (),
797706f2543Smrg                                         a_port_id, a_image_id,
798706f2543Smrg                                         NULL, a_image_width, a_image_height) ;
799706f2543Smrg    if (!xv_image) {
800706f2543Smrg        EPHYR_LOG_ERROR ("failed to create image\n") ;
801706f2543Smrg        goto out ;
802706f2543Smrg    }
803706f2543Smrg    xv_image->data = (char*)a_buf ;
804706f2543Smrg    if (a_clip_rect_nums) {
805706f2543Smrg        int i=0 ;
806706f2543Smrg        rects = calloc (a_clip_rect_nums, sizeof (XRectangle)) ;
807706f2543Smrg        for (i=0; i < a_clip_rect_nums; i++) {
808706f2543Smrg            rects[i].x = a_clip_rects[i].x1 ;
809706f2543Smrg            rects[i].y = a_clip_rects[i].y1 ;
810706f2543Smrg            rects[i].width = a_clip_rects[i].x2 - a_clip_rects[i].x1;
811706f2543Smrg            rects[i].height = a_clip_rects[i].y2 - a_clip_rects[i].y1;
812706f2543Smrg            EPHYR_LOG ("(x,y,w,h): (%d,%d,%d,%d)\n",
813706f2543Smrg                       rects[i].x, rects[i].y,
814706f2543Smrg                       rects[i].width, rects[i].height) ;
815706f2543Smrg        }
816706f2543Smrg        XSetClipRectangles (dpy, gc, 0, 0, rects, a_clip_rect_nums, YXBanded) ;
817706f2543Smrg        /*this always returns 1*/
818706f2543Smrg    }
819706f2543Smrg    res = XvPutImage (dpy, a_port_id,
820706f2543Smrg                      hostx_get_window (a_screen_num),
821706f2543Smrg                      gc, xv_image,
822706f2543Smrg                      a_src_x, a_src_y, a_src_w, a_src_h,
823706f2543Smrg                      a_drw_x, a_drw_y, a_drw_w, a_drw_h) ;
824706f2543Smrg    if (res != Success) {
825706f2543Smrg        EPHYR_LOG_ERROR ("XvPutImage() failed: %d\n", res) ;
826706f2543Smrg        goto out ;
827706f2543Smrg    }
828706f2543Smrg    is_ok = TRUE ;
829706f2543Smrg
830706f2543Smrgout:
831706f2543Smrg    if (xv_image) {
832706f2543Smrg        XFree (xv_image) ;
833706f2543Smrg        xv_image = NULL ;
834706f2543Smrg    }
835706f2543Smrg    if (gc) {
836706f2543Smrg        XFreeGC (dpy, gc) ;
837706f2543Smrg        gc = NULL ;
838706f2543Smrg    }
839706f2543Smrg    free(rects);
840706f2543Smrg    rects = NULL;
841706f2543Smrg    EPHYR_LOG ("leave\n") ;
842706f2543Smrg    return is_ok ;
843706f2543Smrg}
844706f2543Smrg
845706f2543SmrgBool
846706f2543SmrgephyrHostXVPutVideo (int a_screen_num, int a_port_id,
847706f2543Smrg                     int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
848706f2543Smrg                     int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h)
849706f2543Smrg{
850706f2543Smrg    Bool is_ok=FALSE ;
851706f2543Smrg    int res=FALSE ;
852706f2543Smrg    GC gc=0 ;
853706f2543Smrg    XGCValues gc_values;
854706f2543Smrg    Display *dpy=hostx_get_display () ;
855706f2543Smrg
856706f2543Smrg    EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
857706f2543Smrg
858706f2543Smrg    gc = XCreateGC (dpy, hostx_get_window (a_screen_num), 0L, &gc_values);
859706f2543Smrg    if (!gc) {
860706f2543Smrg        EPHYR_LOG_ERROR ("failed to create gc \n") ;
861706f2543Smrg        goto out ;
862706f2543Smrg    }
863706f2543Smrg    res = XvPutVideo (dpy, a_port_id, hostx_get_window (a_screen_num), gc,
864706f2543Smrg                      a_vid_x, a_vid_y, a_vid_w, a_vid_h,
865706f2543Smrg                      a_drw_x, a_drw_y, a_drw_w, a_drw_h) ;
866706f2543Smrg
867706f2543Smrg    if (res != Success) {
868706f2543Smrg        EPHYR_LOG_ERROR ("XvPutVideo() failed: %d\n", res) ;
869706f2543Smrg        goto out ;
870706f2543Smrg    }
871706f2543Smrg
872706f2543Smrg    is_ok = TRUE ;
873706f2543Smrg
874706f2543Smrgout:
875706f2543Smrg    if (gc) {
876706f2543Smrg        XFreeGC (dpy, gc) ;
877706f2543Smrg        gc = NULL ;
878706f2543Smrg    }
879706f2543Smrg    return is_ok ;
880706f2543Smrg}
881706f2543Smrg
882706f2543SmrgBool
883706f2543SmrgephyrHostXVGetVideo (int a_screen_num, int a_port_id,
884706f2543Smrg                     int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
885706f2543Smrg                     int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h)
886706f2543Smrg{
887706f2543Smrg    Bool is_ok=FALSE ;
888706f2543Smrg    int res=FALSE ;
889706f2543Smrg    GC gc=0 ;
890706f2543Smrg    XGCValues gc_values;
891706f2543Smrg    Display *dpy=hostx_get_display () ;
892706f2543Smrg
893706f2543Smrg    EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
894706f2543Smrg
895706f2543Smrg    gc = XCreateGC (dpy, hostx_get_window (a_screen_num), 0L, &gc_values);
896706f2543Smrg    if (!gc) {
897706f2543Smrg        EPHYR_LOG_ERROR ("failed to create gc \n") ;
898706f2543Smrg        goto out ;
899706f2543Smrg    }
900706f2543Smrg    res = XvGetVideo (dpy, a_port_id, hostx_get_window (a_screen_num), gc,
901706f2543Smrg                      a_vid_x, a_vid_y, a_vid_w, a_vid_h,
902706f2543Smrg                      a_drw_x, a_drw_y, a_drw_w, a_drw_h) ;
903706f2543Smrg
904706f2543Smrg    if (res != Success) {
905706f2543Smrg        EPHYR_LOG_ERROR ("XvGetVideo() failed: %d\n", res) ;
906706f2543Smrg        goto out ;
907706f2543Smrg    }
908706f2543Smrg
909706f2543Smrg    is_ok = TRUE ;
910706f2543Smrg
911706f2543Smrgout:
912706f2543Smrg    if (gc) {
913706f2543Smrg        XFreeGC (dpy, gc) ;
914706f2543Smrg        gc = NULL ;
915706f2543Smrg    }
916706f2543Smrg    return is_ok ;
917706f2543Smrg}
918706f2543Smrg
919706f2543SmrgBool
920706f2543SmrgephyrHostXVPutStill (int a_screen_num, int a_port_id,
921706f2543Smrg                     int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
922706f2543Smrg                     int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h)
923706f2543Smrg{
924706f2543Smrg    Bool is_ok=FALSE ;
925706f2543Smrg    int res=FALSE ;
926706f2543Smrg    GC gc=0 ;
927706f2543Smrg    XGCValues gc_values;
928706f2543Smrg    Display *dpy=hostx_get_display () ;
929706f2543Smrg
930706f2543Smrg    EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
931706f2543Smrg
932706f2543Smrg    gc = XCreateGC (dpy, hostx_get_window (a_screen_num), 0L, &gc_values);
933706f2543Smrg    if (!gc) {
934706f2543Smrg        EPHYR_LOG_ERROR ("failed to create gc \n") ;
935706f2543Smrg        goto out ;
936706f2543Smrg    }
937706f2543Smrg    res = XvPutStill (dpy, a_port_id, hostx_get_window (a_screen_num), gc,
938706f2543Smrg                      a_vid_x, a_vid_y, a_vid_w, a_vid_h,
939706f2543Smrg                      a_drw_x, a_drw_y, a_drw_w, a_drw_h) ;
940706f2543Smrg
941706f2543Smrg    if (res != Success) {
942706f2543Smrg        EPHYR_LOG_ERROR ("XvPutStill() failed: %d\n", res) ;
943706f2543Smrg        goto out ;
944706f2543Smrg    }
945706f2543Smrg
946706f2543Smrg    is_ok = TRUE ;
947706f2543Smrg
948706f2543Smrgout:
949706f2543Smrg    if (gc) {
950706f2543Smrg        XFreeGC (dpy, gc) ;
951706f2543Smrg        gc = NULL ;
952706f2543Smrg    }
953706f2543Smrg    return is_ok ;
954706f2543Smrg}
955706f2543Smrg
956706f2543SmrgBool
957706f2543SmrgephyrHostXVGetStill (int a_screen_num, int a_port_id,
958706f2543Smrg                     int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
959706f2543Smrg                     int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h)
960706f2543Smrg{
961706f2543Smrg    Bool is_ok=FALSE ;
962706f2543Smrg    int res=FALSE ;
963706f2543Smrg    GC gc=0 ;
964706f2543Smrg    XGCValues gc_values;
965706f2543Smrg    Display *dpy=hostx_get_display () ;
966706f2543Smrg
967706f2543Smrg    EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
968706f2543Smrg
969706f2543Smrg    gc = XCreateGC (dpy, hostx_get_window (a_screen_num), 0L, &gc_values);
970706f2543Smrg    if (!gc) {
971706f2543Smrg        EPHYR_LOG_ERROR ("failed to create gc \n") ;
972706f2543Smrg        goto out ;
973706f2543Smrg    }
974706f2543Smrg    res = XvGetStill (dpy, a_port_id, hostx_get_window (a_screen_num), gc,
975706f2543Smrg                      a_vid_x, a_vid_y, a_vid_w, a_vid_h,
976706f2543Smrg                      a_drw_x, a_drw_y, a_drw_w, a_drw_h) ;
977706f2543Smrg
978706f2543Smrg    if (res != Success) {
979706f2543Smrg        EPHYR_LOG_ERROR ("XvGetStill() failed: %d\n", res) ;
980706f2543Smrg        goto out ;
981706f2543Smrg    }
982706f2543Smrg
983706f2543Smrg    is_ok = TRUE ;
984706f2543Smrg
985706f2543Smrgout:
986706f2543Smrg    if (gc) {
987706f2543Smrg        XFreeGC (dpy, gc) ;
988706f2543Smrg        gc = NULL ;
989706f2543Smrg    }
990706f2543Smrg    return is_ok ;
991706f2543Smrg}
992706f2543Smrg
993706f2543SmrgBool
994706f2543SmrgephyrHostXVStopVideo (int a_screen_num, int a_port_id)
995706f2543Smrg{
996706f2543Smrg    int ret=0 ;
997706f2543Smrg    Bool is_ok=FALSE ;
998706f2543Smrg    Display *dpy = hostx_get_display () ;
999706f2543Smrg
1000706f2543Smrg    EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
1001706f2543Smrg
1002706f2543Smrg    EPHYR_LOG ("enter\n") ;
1003706f2543Smrg
1004706f2543Smrg    ret = XvStopVideo (dpy, a_port_id, hostx_get_window (a_screen_num)) ;
1005706f2543Smrg    if (ret != Success) {
1006706f2543Smrg        EPHYR_LOG_ERROR ("XvStopVideo() failed: %d \n", ret) ;
1007706f2543Smrg        goto out ;
1008706f2543Smrg    }
1009706f2543Smrg    is_ok = TRUE ;
1010706f2543Smrg
1011706f2543Smrgout:
1012706f2543Smrg    EPHYR_LOG ("leave\n") ;
1013706f2543Smrg    return is_ok ;
1014706f2543Smrg}
1015706f2543Smrg
1016