xserver-multidpi/hw/kdrive/ephyr/ephyrhostvideo.c
Keith Packard 9838b7032e Introduce a consistent coding style
This is strictly the application of the script 'x-indent-all.sh'
from util/modular. Compared to the patch that Daniel posted in
January, I've added a few indent flags:

	-bap
	-psl
	-T PrivatePtr
	-T pmWait
	-T _XFUNCPROTOBEGIN
	-T _XFUNCPROTOEND
	-T _X_EXPORT

The typedefs were needed to make the output of sdksyms.sh match the
previous output, otherwise, the code is formatted badly enough that
sdksyms.sh generates incorrect output.

The generated code was compared with the previous version and found to
be essentially identical -- "assert" line numbers and BUILD_TIME were
the only differences found.

The comparison was done with this script:

dir1=$1
dir2=$2

for dir in $dir1 $dir2; do
	(cd $dir && find . -name '*.o' | while read file; do
		dir=`dirname $file`
		base=`basename $file .o`
		dump=$dir/$base.dump
		objdump -d $file > $dump
	done)
done

find $dir1 -name '*.dump' | while read dump; do
	otherdump=`echo $dump | sed "s;$dir1;$dir2;"`
	diff -u $dump $otherdump
done

Signed-off-by: Keith Packard <keithp@keithp.com>
Acked-by: Daniel Stone <daniel@fooishbar.org>
Acked-by: Alan Coopersmith <alan.coopersmith@oracle.com>
2012-03-21 13:54:42 -07:00

976 lines
29 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) {
snprintf(number, sizeof(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) {
snprintf(mesg, sizeof(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)
snprintf(buffer, sizeof(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 = calloc(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 = calloc(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)) ==
(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)) ==
(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)) ==
(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)) ==
(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)) ==
(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 = calloc(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++) {
free(a_encodings[i].name);
a_encodings[i].name = NULL;
}
free(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;
}
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;
}