aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/hw/kdrive/ephyr/ephyrvideo.c
diff options
context:
space:
mode:
authormarha <marha@users.sourceforge.net>2010-05-16 20:50:58 +0000
committermarha <marha@users.sourceforge.net>2010-05-16 20:50:58 +0000
commit1c94119ae26b94a60bb2c2b33494ed43c3b8a52f (patch)
treecfe0c736c95314edac7d9f1065be9c13026ed0c1 /xorg-server/hw/kdrive/ephyr/ephyrvideo.c
parent6b29aa4559aeb6f795caee047561654bfa0a1954 (diff)
downloadvcxsrv-1c94119ae26b94a60bb2c2b33494ed43c3b8a52f.tar.gz
vcxsrv-1c94119ae26b94a60bb2c2b33494ed43c3b8a52f.tar.bz2
vcxsrv-1c94119ae26b94a60bb2c2b33494ed43c3b8a52f.zip
svn merge -r588:HEAD ^/branches/released .
Diffstat (limited to 'xorg-server/hw/kdrive/ephyr/ephyrvideo.c')
-rw-r--r--xorg-server/hw/kdrive/ephyr/ephyrvideo.c2546
1 files changed, 1273 insertions, 1273 deletions
diff --git a/xorg-server/hw/kdrive/ephyr/ephyrvideo.c b/xorg-server/hw/kdrive/ephyr/ephyrvideo.c
index 6624ab98a..14213c966 100644
--- a/xorg-server/hw/kdrive/ephyr/ephyrvideo.c
+++ b/xorg-server/hw/kdrive/ephyr/ephyrvideo.c
@@ -1,1273 +1,1273 @@
-/*
- * 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
-#include <string.h>
-#include <X11/extensions/Xv.h>
-#include "ephyrlog.h"
-#include "kdrive.h"
-#include "kxv.h"
-#include "ephyr.h"
-#include "hostx.h"
-#include "ephyrhostvideo.h"
-
-struct _EphyrXVPriv {
- EphyrHostXVAdaptorArray *host_adaptors ;
- KdVideoAdaptorPtr adaptors ;
- int num_adaptors ;
-};
-typedef struct _EphyrXVPriv EphyrXVPriv ;
-
-struct _EphyrPortPriv {
- int port_number ;
- KdVideoAdaptorPtr current_adaptor ;
- EphyrXVPriv *xv_priv;
- unsigned char *image_buf ;
- int image_buf_size ;
- int image_id ;
- int drw_x, drw_y, drw_w, drw_h ;
- int src_x, src_y, src_w, src_h ;
- int image_width, image_height ;
-};
-typedef struct _EphyrPortPriv EphyrPortPriv ;
-
-static Bool DoSimpleClip (BoxPtr a_dst_drw,
- BoxPtr a_clipper,
- BoxPtr a_result) ;
-
-static Bool ephyrLocalAtomToHost (int a_local_atom, int *a_host_atom) ;
-
-/*
-static Bool ephyrHostAtomToLocal (int a_host_atom, int *a_local_atom) ;
-*/
-
-static EphyrXVPriv* ephyrXVPrivNew (void) ;
-static void ephyrXVPrivDelete (EphyrXVPriv *a_this) ;
-static Bool ephyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this) ;
-static Bool ephyrXVPrivSetAdaptorsHooks (EphyrXVPriv *a_this) ;
-static Bool ephyrXVPrivRegisterAdaptors (EphyrXVPriv *a_this,
- ScreenPtr a_screen) ;
-
-static Bool ephyrXVPrivIsAttrValueValid (KdAttributePtr a_attrs,
- int a_attrs_len,
- const char *a_attr_name,
- int a_attr_value,
- Bool *a_is_valid) ;
-
-static Bool ephyrXVPrivGetImageBufSize (int a_port_id,
- int a_image_id,
- unsigned short a_width,
- unsigned short a_height,
- int *a_size) ;
-
-static Bool ephyrXVPrivSaveImageToPortPriv (EphyrPortPriv *a_port_priv,
- const unsigned char *a_image,
- int a_image_len) ;
-
-static void ephyrStopVideo (KdScreenInfo *a_info,
- pointer a_xv_priv,
- Bool a_exit);
-
-static int ephyrSetPortAttribute (KdScreenInfo *a_info,
- Atom a_attr_name,
- int a_attr_value,
- pointer a_port_priv);
-
-static int ephyrGetPortAttribute (KdScreenInfo *a_screen_info,
- Atom a_attr_name,
- int *a_attr_value,
- pointer a_port_priv);
-
-static void ephyrQueryBestSize (KdScreenInfo *a_info,
- Bool a_motion,
- short a_src_w,
- short a_src_h,
- short a_drw_w,
- short a_drw_h,
- unsigned int *a_prefered_w,
- unsigned int *a_prefered_h,
- pointer a_port_priv);
-
-static int ephyrPutImage (KdScreenInfo *a_info,
- DrawablePtr a_drawable,
- short a_src_x,
- short a_src_y,
- short a_drw_x,
- short a_drw_y,
- short a_src_w,
- short a_src_h,
- short a_drw_w,
- short a_drw_h,
- int a_id,
- unsigned char *a_buf,
- short a_width,
- short a_height,
- Bool a_sync,
- RegionPtr a_clipping_region,
- pointer a_port_priv);
-
-static int ephyrReputImage (KdScreenInfo *a_info,
- DrawablePtr a_drawable,
- short a_drw_x,
- short a_drw_y,
- RegionPtr a_clipping_region,
- pointer a_port_priv) ;
-
-static int ephyrPutVideo (KdScreenInfo *a_info,
- DrawablePtr a_drawable,
- short a_vid_x, short a_vid_y,
- short a_drw_x, short a_drw_y,
- short a_vid_w, short a_vid_h,
- short a_drw_w, short a_drw_h,
- RegionPtr a_clip_region,
- pointer a_port_priv) ;
-
-static int ephyrGetVideo (KdScreenInfo *a_info,
- DrawablePtr a_drawable,
- short a_vid_x, short a_vid_y,
- short a_drw_x, short a_drw_y,
- short a_vid_w, short a_vid_h,
- short a_drw_w, short a_drw_h,
- RegionPtr a_clip_region,
- pointer a_port_priv) ;
-
-static int ephyrPutStill (KdScreenInfo *a_info,
- DrawablePtr a_drawable,
- short a_vid_x, short a_vid_y,
- short a_drw_x, short a_drw_y,
- short a_vid_w, short a_vid_h,
- short a_drw_w, short a_drw_h,
- RegionPtr a_clip_region,
- pointer a_port_priv) ;
-
-static int ephyrGetStill (KdScreenInfo *a_info,
- DrawablePtr a_drawable,
- short a_vid_x, short a_vid_y,
- short a_drw_x, short a_drw_y,
- short a_vid_w, short a_vid_h,
- short a_drw_w, short a_drw_h,
- RegionPtr a_clip_region,
- pointer a_port_priv) ;
-
-static int ephyrQueryImageAttributes (KdScreenInfo *a_info,
- int a_id,
- unsigned short *a_w,
- unsigned short *a_h,
- int *a_pitches,
- int *a_offsets);
-static int s_base_port_id ;
-
-/**************
- * <helpers>
- * ************/
-
-static Bool
-DoSimpleClip (BoxPtr a_dst_box,
- BoxPtr a_clipper,
- BoxPtr a_result)
-{
- BoxRec dstClippedBox ;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_dst_box && a_clipper && a_result, FALSE) ;
-
- /*
- * setup the clipbox inside the destination.
- */
- dstClippedBox.x1 = a_dst_box->x1 ;
- dstClippedBox.x2 = a_dst_box->x2 ;
- dstClippedBox.y1 = a_dst_box->y1 ;
- dstClippedBox.y2 = a_dst_box->y2 ;
-
- /*
- * if the cliper leftmost edge is inside
- * the destination area then the leftmost edge of the resulting
- * clipped box is the leftmost edge of the cliper.
- */
- if (a_clipper->x1 > dstClippedBox.x1)
- dstClippedBox.x1 = a_clipper->x1 ;
-
- /*
- * if the cliper top edge is inside the destination area
- * then the bottom horizontal edge of the resulting clipped box
- * is the bottom edge of the cliper
- */
- if (a_clipper->y1 > dstClippedBox.y1)
- dstClippedBox.y1 = a_clipper->y1 ;
-
- /*ditto for right edge*/
- if (a_clipper->x2 < dstClippedBox.x2)
- dstClippedBox.x2 = a_clipper->x2 ;
-
- /*ditto for bottom edge*/
- if (a_clipper->y2 < dstClippedBox.y2)
- dstClippedBox.y2 = a_clipper->y2 ;
-
- memcpy (a_result, &dstClippedBox, sizeof (dstClippedBox)) ;
- return TRUE ;
-}
-
-static Bool
-ephyrLocalAtomToHost (int a_local_atom, int *a_host_atom)
-{
- const char *atom_name=NULL;
- int host_atom=None ;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_host_atom, FALSE) ;
-
- if (!ValidAtom (a_local_atom))
- return FALSE ;
-
- atom_name = NameForAtom (a_local_atom) ;
-
- if (!atom_name)
- return FALSE ;
-
- if (!ephyrHostGetAtom (atom_name, FALSE, &host_atom) || host_atom == None) {
- EPHYR_LOG_ERROR ("no atom for string %s defined in host X\n",
- atom_name) ;
- return FALSE ;
- }
- *a_host_atom = host_atom ;
- return TRUE ;
-}
-
-/*
- Not used yed.
-static Bool
-ephyrHostAtomToLocal (int a_host_atom, int *a_local_atom)
-{
- Bool is_ok=FALSE ;
- char *atom_name=NULL ;
- int atom=None ;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_local_atom, FALSE) ;
-
- atom_name = ephyrHostGetAtomName (a_host_atom) ;
- if (!atom_name)
- goto out ;
-
- atom = MakeAtom (atom_name, strlen (atom_name), TRUE) ;
- if (atom == None)
- goto out ;
-
- *a_local_atom = atom ;
- is_ok = TRUE ;
-
-out:
- if (atom_name) {
- ephyrHostFree (atom_name) ;
- }
- return is_ok ;
-}
-*/
-
-/**************
- *</helpers>
- * ************/
-
-Bool
-ephyrInitVideo (ScreenPtr pScreen)
-{
- Bool is_ok = FALSE ;
- KdScreenPriv(pScreen);
- KdScreenInfo *screen = pScreenPriv->screen;
- static EphyrXVPriv *xv_priv;
-
- EPHYR_LOG ("enter\n") ;
-
- if (screen->fb.bitsPerPixel == 8) {
- EPHYR_LOG_ERROR ("8 bits depth not supported\n") ;
- return FALSE ;
- }
-
- if (!xv_priv) {
- xv_priv = ephyrXVPrivNew () ;
- }
- if (!xv_priv) {
- EPHYR_LOG_ERROR ("failed to create xv_priv\n") ;
- goto out ;
- }
-
- if (!ephyrXVPrivRegisterAdaptors (xv_priv, pScreen)) {
- EPHYR_LOG_ERROR ("failed to register adaptors\n") ;
- goto out ;
- }
- is_ok = TRUE ;
-
-out:
- return is_ok ;
-}
-
-static EphyrXVPriv*
-ephyrXVPrivNew (void)
-{
- EphyrXVPriv *xv_priv=NULL ;
-
- EPHYR_LOG ("enter\n") ;
-
- xv_priv = xcalloc (1, sizeof (EphyrXVPriv)) ;
- if (!xv_priv) {
- EPHYR_LOG_ERROR ("failed to create EphyrXVPriv\n") ;
- goto error ;
- }
-
- ephyrHostXVInit () ;
-
- if (!ephyrXVPrivQueryHostAdaptors (xv_priv)) {
- EPHYR_LOG_ERROR ("failed to query the host x for xv properties\n") ;
- goto error ;
- }
- if (!ephyrXVPrivSetAdaptorsHooks (xv_priv)) {
- EPHYR_LOG_ERROR ("failed to set xv_priv hooks\n") ;
- goto error ;
- }
-
- EPHYR_LOG ("leave\n") ;
- return xv_priv ;
-
-error:
- if (xv_priv) {
- ephyrXVPrivDelete (xv_priv) ;
- xv_priv = NULL ;
- }
- return NULL ;
-}
-
-static void
-ephyrXVPrivDelete (EphyrXVPriv *a_this)
-{
- EPHYR_LOG ("enter\n") ;
-
- if (!a_this)
- return ;
- if (a_this->host_adaptors) {
- ephyrHostXVAdaptorArrayDelete (a_this->host_adaptors) ;
- a_this->host_adaptors = NULL ;
- }
- xfree (a_this->adaptors) ;
- a_this->adaptors = NULL ;
- xfree (a_this) ;
- EPHYR_LOG ("leave\n") ;
-}
-
-static KdVideoEncodingPtr
-videoEncodingDup (EphyrHostEncoding *a_encodings,
- int a_num_encodings)
-{
- KdVideoEncodingPtr result = NULL ;
- int i=0 ;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_encodings && a_num_encodings, NULL) ;
-
- result = xcalloc (a_num_encodings, sizeof (KdVideoEncodingRec)) ;
- for (i=0 ; i < a_num_encodings; i++) {
- result[i].id = a_encodings[i].id ;
- result[i].name = strdup (a_encodings[i].name) ;
- result[i].width = a_encodings[i].width ;
- result[i].height = a_encodings[i].height ;
- result[i].rate.numerator = a_encodings[i].rate.numerator ;
- result[i].rate.denominator = a_encodings[i].rate.denominator ;
- }
- return result ;
-}
-
-static KdAttributePtr
-portAttributesDup (EphyrHostAttribute *a_encodings,
- int a_num_encodings)
-{
- int i=0 ;
- KdAttributePtr result=NULL ;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_encodings && a_num_encodings, NULL) ;
-
- result = xcalloc (a_num_encodings, sizeof (KdAttributeRec)) ;
- if (!result) {
- EPHYR_LOG_ERROR ("failed to allocate attributes\n") ;
- return NULL ;
- }
- for (i=0; i < a_num_encodings; i++) {
- result[i].flags = a_encodings[i].flags ;
- result[i].min_value = a_encodings[i].min_value ;
- result[i].max_value = a_encodings[i].max_value ;
- result[i].name = strdup (a_encodings[i].name) ;
- }
- return result ;
-}
-
-static Bool
-ephyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this)
-{
- EphyrHostXVAdaptor *cur_host_adaptor=NULL ;
- EphyrHostVideoFormat *video_formats=NULL ;
- EphyrHostEncoding *encodings=NULL ;
- EphyrHostAttribute *attributes=NULL ;
- EphyrHostImageFormat *image_formats=NULL ;
- int num_video_formats=0, base_port_id=0,
- num_attributes=0, num_formats=0, i=0,
- port_priv_offset=0;
- unsigned num_encodings=0 ;
- Bool is_ok = FALSE ;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_this, FALSE) ;
-
- EPHYR_LOG ("enter\n") ;
-
- if (!ephyrHostXVQueryAdaptors (&a_this->host_adaptors)) {
- EPHYR_LOG_ERROR ("failed to query host adaptors\n") ;
- goto out ;
- }
- if (a_this->host_adaptors)
- a_this->num_adaptors =
- ephyrHostXVAdaptorArrayGetSize (a_this->host_adaptors) ;
- if (a_this->num_adaptors < 0) {
- EPHYR_LOG_ERROR ("failed to get number of host adaptors\n") ;
- goto out ;
- }
- EPHYR_LOG ("host has %d adaptors\n", a_this->num_adaptors) ;
- /*
- * copy what we can from adaptors into a_this->adaptors
- */
- if (a_this->num_adaptors) {
- a_this->adaptors = xcalloc (a_this->num_adaptors,
- sizeof (KdVideoAdaptorRec)) ;
- if (!a_this->adaptors) {
- EPHYR_LOG_ERROR ("failed to create internal adaptors\n") ;
- goto out ;
- }
- }
- for (i=0; i < a_this->num_adaptors; i++) {
- int j=0 ;
- cur_host_adaptor =
- ephyrHostXVAdaptorArrayAt (a_this->host_adaptors, i) ;
- if (!cur_host_adaptor)
- continue ;
- a_this->adaptors[i].nPorts =
- ephyrHostXVAdaptorGetNbPorts (cur_host_adaptor) ;
- if (a_this->adaptors[i].nPorts <=0) {
- EPHYR_LOG_ERROR ("Could not find any port of adaptor %d\n", i) ;
- continue ;
- }
- a_this->adaptors[i].type =
- ephyrHostXVAdaptorGetType (cur_host_adaptor) ;
- a_this->adaptors[i].type |= XvWindowMask ;
- a_this->adaptors[i].flags =
- VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
- if (ephyrHostXVAdaptorGetName (cur_host_adaptor))
- a_this->adaptors[i].name =
- strdup (ephyrHostXVAdaptorGetName (cur_host_adaptor)) ;
- else
- a_this->adaptors[i].name = strdup ("Xephyr Video Overlay");
- base_port_id = ephyrHostXVAdaptorGetFirstPortID (cur_host_adaptor) ;
- if (base_port_id < 0) {
- EPHYR_LOG_ERROR ("failed to get port id for adaptor %d\n", i) ;
- continue ;
- }
- if (!s_base_port_id)
- s_base_port_id = base_port_id ;
-
- if (!ephyrHostXVQueryEncodings (base_port_id,
- &encodings,
- &num_encodings)) {
- EPHYR_LOG_ERROR ("failed to get encodings for port port id %d,"
- " adaptors %d\n",
- base_port_id, i) ;
- continue ;
- }
- a_this->adaptors[i].nEncodings = num_encodings ;
- a_this->adaptors[i].pEncodings =
- videoEncodingDup (encodings, num_encodings) ;
- video_formats = (EphyrHostVideoFormat*)
- ephyrHostXVAdaptorGetVideoFormats (cur_host_adaptor,
- &num_video_formats);
- a_this->adaptors[i].pFormats = (KdVideoFormatPtr) video_formats ;
- a_this->adaptors[i].nFormats = num_video_formats ;
- /* got a_this->adaptors[i].nPorts already
- a_this->adaptors[i].nPorts =
- ephyrHostXVAdaptorGetNbPorts (cur_host_adaptor) ;
- */
- a_this->adaptors[i].pPortPrivates =
- xcalloc (a_this->adaptors[i].nPorts,
- sizeof (DevUnion) + sizeof (EphyrPortPriv)) ;
- port_priv_offset = a_this->adaptors[i].nPorts;
- for (j=0; j < a_this->adaptors[i].nPorts; j++) {
- EphyrPortPriv *port_privs_base =
- (EphyrPortPriv*)&a_this->adaptors[i].pPortPrivates[port_priv_offset];
- EphyrPortPriv *port_priv = &port_privs_base[j] ;
- port_priv->port_number = base_port_id + j;
- port_priv->current_adaptor = &a_this->adaptors[i] ;
- port_priv->xv_priv = a_this ;
- a_this->adaptors[i].pPortPrivates[j].ptr = port_priv;
- }
- if (!ephyrHostXVQueryPortAttributes (base_port_id,
- &attributes,
- &num_attributes)) {
- EPHYR_LOG_ERROR ("failed to get port attribute "
- "for adaptor %d\n", i) ;
- continue ;
- }
- a_this->adaptors[i].pAttributes =
- portAttributesDup (attributes, num_attributes);
- a_this->adaptors[i].nAttributes = num_attributes ;
- /*make sure atoms of attrs names are created in xephyr*/
- for (j=0; j < a_this->adaptors[i].nAttributes; j++) {
- if (a_this->adaptors[i].pAttributes[j].name)
- MakeAtom (a_this->adaptors[i].pAttributes[j].name,
- strlen (a_this->adaptors[i].pAttributes[j].name),
- TRUE) ;
- }
- if (!ephyrHostXVQueryImageFormats (base_port_id,
- &image_formats,
- &num_formats)) {
- EPHYR_LOG_ERROR ("failed to get image formats "
- "for adaptor %d\n", i) ;
- continue ;
- }
- a_this->adaptors[i].pImages = (KdImagePtr) image_formats ;
- a_this->adaptors[i].nImages = num_formats ;
- }
- is_ok = TRUE ;
-
-out:
- if (encodings) {
- ephyrHostEncodingsDelete (encodings, num_encodings) ;
- encodings = NULL ;
- }
- if (attributes) {
- ephyrHostAttributesDelete (attributes) ;
- attributes = NULL ;
- }
- EPHYR_LOG ("leave\n") ;
- return is_ok ;
-}
-
-static Bool
-ephyrXVPrivSetAdaptorsHooks (EphyrXVPriv *a_this)
-{
- int i=0 ;
- Bool has_it=FALSE ;
- EphyrHostXVAdaptor *cur_host_adaptor=NULL ;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_this, FALSE) ;
-
- EPHYR_LOG ("enter\n") ;
-
- for (i=0; i < a_this->num_adaptors; i++) {
- a_this->adaptors[i].ReputImage = ephyrReputImage ;
- a_this->adaptors[i].StopVideo = ephyrStopVideo ;
- a_this->adaptors[i].SetPortAttribute = ephyrSetPortAttribute ;
- a_this->adaptors[i].GetPortAttribute = ephyrGetPortAttribute ;
- a_this->adaptors[i].QueryBestSize = ephyrQueryBestSize ;
- a_this->adaptors[i].QueryImageAttributes = ephyrQueryImageAttributes ;
-
- cur_host_adaptor =
- ephyrHostXVAdaptorArrayAt (a_this->host_adaptors, i) ;
- if (!cur_host_adaptor) {
- EPHYR_LOG_ERROR ("failed to get host adaptor at index %d\n", i) ;
- continue ;
- }
- has_it = FALSE ;
- if (!ephyrHostXVAdaptorHasPutImage (cur_host_adaptor, &has_it)) {
- EPHYR_LOG_ERROR ("error\n") ;
- }
- if (has_it) {
- a_this->adaptors[i].PutImage = ephyrPutImage;
- }
-
- has_it = FALSE ;
- if (!ephyrHostXVAdaptorHasPutVideo (cur_host_adaptor, &has_it)) {
- EPHYR_LOG_ERROR ("error\n") ;
- }
- if (has_it) {
- a_this->adaptors[i].PutVideo = ephyrPutVideo;
- }
-
- has_it = FALSE ;
- if (!ephyrHostXVAdaptorHasGetVideo (cur_host_adaptor, &has_it)) {
- EPHYR_LOG_ERROR ("error\n") ;
- }
- if (has_it) {
- a_this->adaptors[i].GetVideo = ephyrGetVideo;
- }
-
- has_it = FALSE ;
- if (!ephyrHostXVAdaptorHasPutStill (cur_host_adaptor, &has_it)) {
- EPHYR_LOG_ERROR ("error\n") ;
- }
- if (has_it) {
- a_this->adaptors[i].PutStill = ephyrPutStill;
- }
-
- has_it = FALSE ;
- if (!ephyrHostXVAdaptorHasGetStill (cur_host_adaptor, &has_it)) {
- EPHYR_LOG_ERROR ("error\n") ;
- }
- if (has_it) {
- a_this->adaptors[i].GetStill = ephyrGetStill;
- }
- }
- EPHYR_LOG ("leave\n") ;
- return TRUE ;
-}
-
-static Bool
-ephyrXVPrivRegisterAdaptors (EphyrXVPriv *a_this,
- ScreenPtr a_screen)
-{
- KdScreenPriv(a_screen);
- KdScreenInfo *screen = pScreenPriv->screen;
- Bool is_ok = FALSE ;
- KdVideoAdaptorPtr *adaptors=NULL, *registered_adaptors=NULL ;
- int num_registered_adaptors=0, i=0, num_adaptors=0 ;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_this && a_screen, FALSE) ;
-
- EPHYR_LOG ("enter\n") ;
-
- if (!a_this->num_adaptors)
- goto out ;
- num_registered_adaptors =
- KdXVListGenericAdaptors (screen, &registered_adaptors);
-
- num_adaptors = num_registered_adaptors + a_this->num_adaptors ;
- adaptors = xcalloc (num_adaptors, sizeof (KdVideoAdaptorPtr)) ;
- if (!adaptors) {
- EPHYR_LOG_ERROR ("failed to allocate adaptors tab\n") ;
- goto out ;
- }
- memmove (adaptors, registered_adaptors, num_registered_adaptors) ;
- for (i=0 ; i < a_this->num_adaptors; i++) {
- *(adaptors + num_registered_adaptors + i) = &a_this->adaptors[i] ;
- }
- if (!KdXVScreenInit (a_screen, adaptors, num_adaptors)) {
- EPHYR_LOG_ERROR ("failed to register adaptors\n");
- goto out ;
- }
- EPHYR_LOG ("there are %d registered adaptors\n", num_adaptors) ;
- is_ok = TRUE ;
-
-out:
- xfree (registered_adaptors) ;
- registered_adaptors = NULL ;
- xfree (adaptors) ;
- adaptors = NULL ;
-
- EPHYR_LOG ("leave\n") ;
- return is_ok ;
-}
-
-static Bool
-ephyrXVPrivIsAttrValueValid (KdAttributePtr a_attrs,
- int a_attrs_len,
- const char *a_attr_name,
- int a_attr_value,
- Bool *a_is_valid)
-{
- int i=0 ;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_attrs && a_attr_name && a_is_valid,
- FALSE) ;
-
- for (i=0; i < a_attrs_len; i++) {
- if (a_attrs[i].name && strcmp (a_attrs[i].name, a_attr_name))
- continue ;
- if (a_attrs[i].min_value > a_attr_value ||
- a_attrs[i].max_value < a_attr_value) {
- *a_is_valid = FALSE ;
- EPHYR_LOG_ERROR ("attribute was not valid\n"
- "value:%d. min:%d. max:%d\n",
- a_attr_value,
- a_attrs[i].min_value,
- a_attrs[i].max_value) ;
- } else {
- *a_is_valid = TRUE ;
- }
- return TRUE ;
- }
- return FALSE ;
-}
-
-static Bool
-ephyrXVPrivGetImageBufSize (int a_port_id,
- int a_image_id,
- unsigned short a_width,
- unsigned short a_height,
- int *a_size)
-{
- Bool is_ok=FALSE ;
- unsigned short width=a_width, height=a_height ;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_size, FALSE) ;
-
- EPHYR_LOG ("enter\n") ;
-
- if (!ephyrHostXVQueryImageAttributes (a_port_id, a_image_id,
- &width, &height, a_size, NULL, NULL)) {
- EPHYR_LOG_ERROR ("failed to get image attributes\n") ;
- goto out ;
- }
- is_ok = TRUE ;
-
-out:
- EPHYR_LOG ("leave\n") ;
- return is_ok ;
-}
-
-static Bool
-ephyrXVPrivSaveImageToPortPriv (EphyrPortPriv *a_port_priv,
- const unsigned char *a_image_buf,
- int a_image_len)
-{
- Bool is_ok=FALSE ;
-
- EPHYR_LOG ("enter\n") ;
-
- if (a_port_priv->image_buf_size < a_image_len) {
- unsigned char *buf=NULL ;
- buf = realloc (a_port_priv->image_buf, a_image_len) ;
- if (!buf) {
- EPHYR_LOG_ERROR ("failed to realloc image buffer\n") ;
- goto out ;
- }
- a_port_priv->image_buf = buf ;
- a_port_priv->image_buf_size = a_image_len;
- }
- memmove (a_port_priv->image_buf, a_image_buf, a_image_len) ;
- is_ok = TRUE ;
-
-out:
- return is_ok ;
- EPHYR_LOG ("leave\n") ;
-}
-
-static void
-ephyrStopVideo (KdScreenInfo *a_info, pointer a_port_priv, Bool a_exit)
-{
- EphyrPortPriv *port_priv = a_port_priv ;
-
- EPHYR_RETURN_IF_FAIL (a_info && a_info->pScreen) ;
- EPHYR_RETURN_IF_FAIL (port_priv) ;
-
- EPHYR_LOG ("enter\n") ;
- if (!ephyrHostXVStopVideo (a_info->pScreen->myNum,
- port_priv->port_number)) {
- EPHYR_LOG_ERROR ("XvStopVideo() failed\n") ;
- }
- EPHYR_LOG ("leave\n") ;
-}
-
-static int
-ephyrSetPortAttribute (KdScreenInfo *a_info,
- Atom a_attr_name,
- int a_attr_value,
- pointer a_port_priv)
-{
- int res=Success, host_atom=0 ;
- EphyrPortPriv *port_priv = a_port_priv ;
- Bool is_attr_valid=FALSE ;
-
- EPHYR_RETURN_VAL_IF_FAIL (port_priv, BadMatch) ;
- EPHYR_RETURN_VAL_IF_FAIL (port_priv->current_adaptor, BadMatch) ;
- EPHYR_RETURN_VAL_IF_FAIL (port_priv->current_adaptor->pAttributes,
- BadMatch) ;
- EPHYR_RETURN_VAL_IF_FAIL (port_priv->current_adaptor->nAttributes,
- BadMatch) ;
- EPHYR_RETURN_VAL_IF_FAIL (ValidAtom (a_attr_name), BadMatch) ;
-
- EPHYR_LOG ("enter, portnum:%d, atomid:%d, attr_name:%s, attr_val:%d\n",
- port_priv->port_number,
- (int)a_attr_name,
- NameForAtom (a_attr_name),
- a_attr_value) ;
-
- if (!ephyrLocalAtomToHost (a_attr_name, &host_atom)) {
- EPHYR_LOG_ERROR ("failed to convert local atom to host atom\n") ;
- res = BadMatch ;
- goto out ;
- }
-
- if (!ephyrXVPrivIsAttrValueValid (port_priv->current_adaptor->pAttributes,
- port_priv->current_adaptor->nAttributes,
- NameForAtom (a_attr_name),
- a_attr_value,
- &is_attr_valid)) {
- EPHYR_LOG_ERROR ("failed to validate attribute %s\n",
- NameForAtom (a_attr_name)) ;
- /*
- res = BadMatch ;
- goto out ;
- */
- }
- if (!is_attr_valid) {
- EPHYR_LOG_ERROR ("attribute %s is not valid\n",
- NameForAtom (a_attr_name)) ;
- /*
- res = BadMatch ;
- goto out ;
- */
- }
-
- if (!ephyrHostXVSetPortAttribute (port_priv->port_number,
- host_atom,
- a_attr_value)) {
- EPHYR_LOG_ERROR ("failed to set port attribute\n") ;
- res = BadMatch ;
- goto out ;
- }
-
- res = Success ;
-out:
- EPHYR_LOG ("leave\n") ;
- return res ;
-}
-
-static int
-ephyrGetPortAttribute (KdScreenInfo *a_screen_info,
- Atom a_attr_name,
- int *a_attr_value,
- pointer a_port_priv)
-{
- int res=Success, host_atom=0 ;
- EphyrPortPriv *port_priv = a_port_priv ;
-
- EPHYR_RETURN_VAL_IF_FAIL (port_priv, BadMatch) ;
- EPHYR_RETURN_VAL_IF_FAIL (ValidAtom (a_attr_name), BadMatch) ;
-
- EPHYR_LOG ("enter, portnum:%d, atomid:%d, attr_name:%s\n",
- port_priv->port_number,
- (int)a_attr_name,
- NameForAtom (a_attr_name)) ;
-
- if (!ephyrLocalAtomToHost (a_attr_name, &host_atom)) {
- EPHYR_LOG_ERROR ("failed to convert local atom to host atom\n") ;
- res = BadMatch ;
- goto out ;
- }
-
- if (!ephyrHostXVGetPortAttribute (port_priv->port_number,
- host_atom,
- a_attr_value)) {
- EPHYR_LOG_ERROR ("failed to get port attribute\n") ;
- res = BadMatch ;
- goto out ;
- }
-
- res = Success ;
-out:
- EPHYR_LOG ("leave\n") ;
- return res ;
-}
-
-static void
-ephyrQueryBestSize (KdScreenInfo *a_info,
- Bool a_motion,
- short a_src_w,
- short a_src_h,
- short a_drw_w,
- short a_drw_h,
- unsigned int *a_prefered_w,
- unsigned int *a_prefered_h,
- pointer a_port_priv)
-{
- int res=0 ;
- EphyrPortPriv *port_priv = a_port_priv ;
-
- EPHYR_RETURN_IF_FAIL (port_priv) ;
-
- EPHYR_LOG ("enter\n") ;
- res = ephyrHostXVQueryBestSize (port_priv->port_number,
- a_motion,
- a_src_w, a_src_h,
- a_drw_w, a_drw_h,
- a_prefered_w, a_prefered_h) ;
- if (!res) {
- EPHYR_LOG_ERROR ("Failed to query best size\n") ;
- }
- EPHYR_LOG ("leave\n") ;
-}
-
-static int
-ephyrPutImage (KdScreenInfo *a_info,
- DrawablePtr a_drawable,
- short a_src_x,
- short a_src_y,
- short a_drw_x,
- short a_drw_y,
- short a_src_w,
- short a_src_h,
- short a_drw_w,
- short a_drw_h,
- int a_id,
- unsigned char *a_buf,
- short a_width,
- short a_height,
- Bool a_sync,
- RegionPtr a_clipping_region,
- pointer a_port_priv)
-{
- EphyrPortPriv *port_priv = a_port_priv ;
- Bool is_ok=FALSE ;
- int result=BadImplementation, image_size=0 ;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_info && a_info->pScreen, BadValue) ;
- EPHYR_RETURN_VAL_IF_FAIL (a_drawable, BadValue) ;
-
- EPHYR_LOG ("enter\n") ;
-
- if (!ephyrHostXVPutImage (a_info->pScreen->myNum,
- port_priv->port_number,
- a_id,
- a_drw_x, a_drw_y, a_drw_w, a_drw_h,
- a_src_x, a_src_y, a_src_w, a_src_h,
- a_width, a_height, a_buf,
- (EphyrHostBox*)REGION_RECTS (a_clipping_region),
- REGION_NUM_RECTS (a_clipping_region))) {
- EPHYR_LOG_ERROR ("EphyrHostXVPutImage() failed\n") ;
- goto out ;
- }
-
- /*
- * Now save the image so that we can resend it to host it
- * later, in ReputImage.
- */
- if (!ephyrXVPrivGetImageBufSize (port_priv->port_number,
- a_id, a_width, a_height, &image_size)) {
- EPHYR_LOG_ERROR ("failed to get image size\n") ;
- /*this is a minor error so we won't get bail out abruptly*/
- is_ok = FALSE ;
- } else {
- is_ok = TRUE ;
- }
- if (is_ok) {
- if (!ephyrXVPrivSaveImageToPortPriv (port_priv, a_buf, image_size)) {
- is_ok=FALSE ;
- } else {
- port_priv->image_id = a_id;
- port_priv->drw_x = a_drw_x;
- port_priv->drw_y = a_drw_y;
- port_priv->drw_w = a_drw_w ;
- port_priv->drw_h = a_drw_h ;
- port_priv->src_x = a_src_x;
- port_priv->src_y = a_src_y ;
- port_priv->src_w = a_src_w ;
- port_priv->src_h = a_src_h ;
- port_priv->image_width = a_width ;
- port_priv->image_height = a_height ;
- }
- }
- if (!is_ok) {
- if (port_priv->image_buf) {
- free (port_priv->image_buf) ;
- port_priv->image_buf = NULL ;
- port_priv->image_buf_size = 0 ;
- }
- }
-
- result = Success ;
-
-out:
- EPHYR_LOG ("leave\n") ;
- return result ;
-}
-
-static int
-ephyrReputImage (KdScreenInfo *a_info,
- DrawablePtr a_drawable,
- short a_drw_x,
- short a_drw_y,
- RegionPtr a_clipping_region,
- pointer a_port_priv)
-{
- EphyrPortPriv *port_priv = a_port_priv ;
- int result=BadImplementation ;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_info->pScreen, FALSE) ;
- EPHYR_RETURN_VAL_IF_FAIL (a_drawable && port_priv, BadValue) ;
-
- EPHYR_LOG ("enter\n") ;
-
- if (!port_priv->image_buf_size || !port_priv->image_buf) {
- EPHYR_LOG_ERROR ("has null image buf in cache\n") ;
- goto out ;
- }
- if (!ephyrHostXVPutImage (a_info->pScreen->myNum,
- port_priv->port_number,
- port_priv->image_id,
- a_drw_x, a_drw_y,
- port_priv->drw_w, port_priv->drw_h,
- port_priv->src_x, port_priv->src_y,
- port_priv->src_w, port_priv->src_h,
- port_priv->image_width, port_priv->image_height,
- port_priv->image_buf,
- (EphyrHostBox*)REGION_RECTS (a_clipping_region),
- REGION_NUM_RECTS (a_clipping_region))) {
- EPHYR_LOG_ERROR ("ephyrHostXVPutImage() failed\n") ;
- goto out ;
- }
-
- result = Success ;
-
-out:
- EPHYR_LOG ("leave\n") ;
- return result ;
-}
-
-static int
-ephyrPutVideo (KdScreenInfo *a_info,
- DrawablePtr a_drawable,
- short a_vid_x, short a_vid_y,
- short a_drw_x, short a_drw_y,
- short a_vid_w, short a_vid_h,
- short a_drw_w, short a_drw_h,
- RegionPtr a_clipping_region,
- pointer a_port_priv)
-{
- EphyrPortPriv *port_priv = a_port_priv ;
- BoxRec clipped_area, dst_box ;
- int result=BadImplementation ;
- int drw_x=0, drw_y=0, drw_w=0, drw_h=0 ;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_info->pScreen, BadValue) ;
- EPHYR_RETURN_VAL_IF_FAIL (a_drawable && port_priv, BadValue) ;
-
- EPHYR_LOG ("enter\n") ;
-
- dst_box.x1 = a_drw_x ;
- dst_box.x2 = a_drw_x + a_drw_w;
- dst_box.y1 = a_drw_y ;
- dst_box.y2 = a_drw_y + a_drw_h;
-
- if (!DoSimpleClip (&dst_box,
- REGION_EXTENTS (pScreen->pScreen, a_clipping_region),
- &clipped_area)) {
- EPHYR_LOG_ERROR ("failed to simple clip\n") ;
- goto out ;
- }
-
- drw_x = clipped_area.x1 ;
- drw_y = clipped_area.y1 ;
- drw_w = clipped_area.x2 - clipped_area.x1 ;
- drw_h = clipped_area.y2 - clipped_area.y1 ;
-
- if (!ephyrHostXVPutVideo (a_info->pScreen->myNum,
- port_priv->port_number,
- a_vid_x, a_vid_y, a_vid_w, a_vid_h,
- a_drw_x, a_drw_y, a_drw_w, a_drw_h)) {
- EPHYR_LOG_ERROR ("ephyrHostXVPutVideo() failed\n") ;
- goto out ;
- }
- result = Success ;
-
-out:
- EPHYR_LOG ("leave\n") ;
- return result ;
-}
-
-static int
-ephyrGetVideo (KdScreenInfo *a_info,
- DrawablePtr a_drawable,
- short a_vid_x, short a_vid_y,
- short a_drw_x, short a_drw_y,
- short a_vid_w, short a_vid_h,
- short a_drw_w, short a_drw_h,
- RegionPtr a_clipping_region,
- pointer a_port_priv)
-{
- EphyrPortPriv *port_priv = a_port_priv ;
- BoxRec clipped_area, dst_box ;
- int result=BadImplementation ;
- int drw_x=0, drw_y=0, drw_w=0, drw_h=0 ;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_info && a_info->pScreen, BadValue) ;
- EPHYR_RETURN_VAL_IF_FAIL (a_drawable && port_priv, BadValue) ;
-
- EPHYR_LOG ("enter\n") ;
-
- dst_box.x1 = a_drw_x ;
- dst_box.x2 = a_drw_x + a_drw_w;
- dst_box.y1 = a_drw_y ;
- dst_box.y2 = a_drw_y + a_drw_h;
-
- if (!DoSimpleClip (&dst_box,
- REGION_EXTENTS (pScreen->pScreen, a_clipping_region),
- &clipped_area)) {
- EPHYR_LOG_ERROR ("failed to simple clip\n") ;
- goto out ;
- }
-
- drw_x = clipped_area.x1 ;
- drw_y = clipped_area.y1 ;
- drw_w = clipped_area.x2 - clipped_area.x1 ;
- drw_h = clipped_area.y2 - clipped_area.y1 ;
-
- if (!ephyrHostXVGetVideo (a_info->pScreen->myNum,
- port_priv->port_number,
- a_vid_x, a_vid_y, a_vid_w, a_vid_h,
- a_drw_x, a_drw_y, a_drw_w, a_drw_h)) {
- EPHYR_LOG_ERROR ("ephyrHostXVGetVideo() failed\n") ;
- goto out ;
- }
- result = Success ;
-
-out:
- EPHYR_LOG ("leave\n") ;
- return result ;
-}
-
-static int
-ephyrPutStill (KdScreenInfo *a_info,
- DrawablePtr a_drawable,
- short a_vid_x, short a_vid_y,
- short a_drw_x, short a_drw_y,
- short a_vid_w, short a_vid_h,
- short a_drw_w, short a_drw_h,
- RegionPtr a_clipping_region,
- pointer a_port_priv)
-{
- EphyrPortPriv *port_priv = a_port_priv ;
- BoxRec clipped_area, dst_box ;
- int result=BadImplementation ;
- int drw_x=0, drw_y=0, drw_w=0, drw_h=0 ;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_info && a_info->pScreen, BadValue) ;
- EPHYR_RETURN_VAL_IF_FAIL (a_drawable && port_priv, BadValue) ;
-
- EPHYR_LOG ("enter\n") ;
-
- dst_box.x1 = a_drw_x ;
- dst_box.x2 = a_drw_x + a_drw_w;
- dst_box.y1 = a_drw_y ;
- dst_box.y2 = a_drw_y + a_drw_h;
-
- if (!DoSimpleClip (&dst_box,
- REGION_EXTENTS (pScreen->pScreen, a_clipping_region),
- &clipped_area)) {
- EPHYR_LOG_ERROR ("failed to simple clip\n") ;
- goto out ;
- }
-
- drw_x = clipped_area.x1 ;
- drw_y = clipped_area.y1 ;
- drw_w = clipped_area.x2 - clipped_area.x1 ;
- drw_h = clipped_area.y2 - clipped_area.y1 ;
-
- if (!ephyrHostXVPutStill (a_info->pScreen->myNum,
- port_priv->port_number,
- a_vid_x, a_vid_y, a_vid_w, a_vid_h,
- a_drw_x, a_drw_y, a_drw_w, a_drw_h)) {
- EPHYR_LOG_ERROR ("ephyrHostXVPutStill() failed\n") ;
- goto out ;
- }
- result = Success ;
-
-out:
- EPHYR_LOG ("leave\n") ;
- return result ;
-}
-
-static int
-ephyrGetStill (KdScreenInfo *a_info,
- DrawablePtr a_drawable,
- short a_vid_x, short a_vid_y,
- short a_drw_x, short a_drw_y,
- short a_vid_w, short a_vid_h,
- short a_drw_w, short a_drw_h,
- RegionPtr a_clipping_region,
- pointer a_port_priv)
-{
- EphyrPortPriv *port_priv = a_port_priv ;
- BoxRec clipped_area, dst_box ;
- int result=BadImplementation ;
- int drw_x=0, drw_y=0, drw_w=0, drw_h=0 ;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_info && a_info->pScreen, BadValue) ;
- EPHYR_RETURN_VAL_IF_FAIL (a_drawable && port_priv, BadValue) ;
-
- EPHYR_LOG ("enter\n") ;
-
- dst_box.x1 = a_drw_x ;
- dst_box.x2 = a_drw_x + a_drw_w;
- dst_box.y1 = a_drw_y ;
- dst_box.y2 = a_drw_y + a_drw_h;
-
- if (!DoSimpleClip (&dst_box,
- REGION_EXTENTS (pScreen->pScreen, a_clipping_region),
- &clipped_area)) {
- EPHYR_LOG_ERROR ("failed to simple clip\n") ;
- goto out ;
- }
-
- drw_x = clipped_area.x1 ;
- drw_y = clipped_area.y1 ;
- drw_w = clipped_area.x2 - clipped_area.x1 ;
- drw_h = clipped_area.y2 - clipped_area.y1 ;
-
- if (!ephyrHostXVGetStill (a_info->pScreen->myNum,
- port_priv->port_number,
- a_vid_x, a_vid_y, a_vid_w, a_vid_h,
- a_drw_x, a_drw_y, a_drw_w, a_drw_h)) {
- EPHYR_LOG_ERROR ("ephyrHostXVGetStill() failed\n") ;
- goto out ;
- }
- result = Success ;
-
-out:
- EPHYR_LOG ("leave\n") ;
- return result ;
-}
-
-static int
-ephyrQueryImageAttributes (KdScreenInfo *a_info,
- int a_id,
- unsigned short *a_w,
- unsigned short *a_h,
- int *a_pitches,
- int *a_offsets)
-{
- int image_size=0 ;
-
- EPHYR_RETURN_VAL_IF_FAIL (a_w && a_h, FALSE) ;
-
- EPHYR_LOG ("enter: dim (%dx%d), pitches: %p, offsets: %p\n",
- *a_w, *a_h, a_pitches, a_offsets) ;
-
- if (!ephyrHostXVQueryImageAttributes (s_base_port_id,
- a_id,
- a_w, a_h,
- &image_size,
- a_pitches, a_offsets)) {
- EPHYR_LOG_ERROR ("EphyrHostXVQueryImageAttributes() failed\n") ;
- goto out ;
- }
- EPHYR_LOG ("image size: %d, dim (%dx%d)\n", image_size, *a_w, *a_h) ;
-
-out:
- EPHYR_LOG ("leave\n") ;
- return image_size ;
-}
+/*
+ * 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
+#include <string.h>
+#include <X11/extensions/Xv.h>
+#include "ephyrlog.h"
+#include "kdrive.h"
+#include "kxv.h"
+#include "ephyr.h"
+#include "hostx.h"
+#include "ephyrhostvideo.h"
+
+struct _EphyrXVPriv {
+ EphyrHostXVAdaptorArray *host_adaptors ;
+ KdVideoAdaptorPtr adaptors ;
+ int num_adaptors ;
+};
+typedef struct _EphyrXVPriv EphyrXVPriv ;
+
+struct _EphyrPortPriv {
+ int port_number ;
+ KdVideoAdaptorPtr current_adaptor ;
+ EphyrXVPriv *xv_priv;
+ unsigned char *image_buf ;
+ int image_buf_size ;
+ int image_id ;
+ int drw_x, drw_y, drw_w, drw_h ;
+ int src_x, src_y, src_w, src_h ;
+ int image_width, image_height ;
+};
+typedef struct _EphyrPortPriv EphyrPortPriv ;
+
+static Bool DoSimpleClip (BoxPtr a_dst_drw,
+ BoxPtr a_clipper,
+ BoxPtr a_result) ;
+
+static Bool ephyrLocalAtomToHost (int a_local_atom, int *a_host_atom) ;
+
+/*
+static Bool ephyrHostAtomToLocal (int a_host_atom, int *a_local_atom) ;
+*/
+
+static EphyrXVPriv* ephyrXVPrivNew (void) ;
+static void ephyrXVPrivDelete (EphyrXVPriv *a_this) ;
+static Bool ephyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this) ;
+static Bool ephyrXVPrivSetAdaptorsHooks (EphyrXVPriv *a_this) ;
+static Bool ephyrXVPrivRegisterAdaptors (EphyrXVPriv *a_this,
+ ScreenPtr a_screen) ;
+
+static Bool ephyrXVPrivIsAttrValueValid (KdAttributePtr a_attrs,
+ int a_attrs_len,
+ const char *a_attr_name,
+ int a_attr_value,
+ Bool *a_is_valid) ;
+
+static Bool ephyrXVPrivGetImageBufSize (int a_port_id,
+ int a_image_id,
+ unsigned short a_width,
+ unsigned short a_height,
+ int *a_size) ;
+
+static Bool ephyrXVPrivSaveImageToPortPriv (EphyrPortPriv *a_port_priv,
+ const unsigned char *a_image,
+ int a_image_len) ;
+
+static void ephyrStopVideo (KdScreenInfo *a_info,
+ pointer a_xv_priv,
+ Bool a_exit);
+
+static int ephyrSetPortAttribute (KdScreenInfo *a_info,
+ Atom a_attr_name,
+ int a_attr_value,
+ pointer a_port_priv);
+
+static int ephyrGetPortAttribute (KdScreenInfo *a_screen_info,
+ Atom a_attr_name,
+ int *a_attr_value,
+ pointer a_port_priv);
+
+static void ephyrQueryBestSize (KdScreenInfo *a_info,
+ Bool a_motion,
+ short a_src_w,
+ short a_src_h,
+ short a_drw_w,
+ short a_drw_h,
+ unsigned int *a_prefered_w,
+ unsigned int *a_prefered_h,
+ pointer a_port_priv);
+
+static int ephyrPutImage (KdScreenInfo *a_info,
+ DrawablePtr a_drawable,
+ short a_src_x,
+ short a_src_y,
+ short a_drw_x,
+ short a_drw_y,
+ short a_src_w,
+ short a_src_h,
+ short a_drw_w,
+ short a_drw_h,
+ int a_id,
+ unsigned char *a_buf,
+ short a_width,
+ short a_height,
+ Bool a_sync,
+ RegionPtr a_clipping_region,
+ pointer a_port_priv);
+
+static int ephyrReputImage (KdScreenInfo *a_info,
+ DrawablePtr a_drawable,
+ short a_drw_x,
+ short a_drw_y,
+ RegionPtr a_clipping_region,
+ pointer a_port_priv) ;
+
+static int ephyrPutVideo (KdScreenInfo *a_info,
+ DrawablePtr a_drawable,
+ short a_vid_x, short a_vid_y,
+ short a_drw_x, short a_drw_y,
+ short a_vid_w, short a_vid_h,
+ short a_drw_w, short a_drw_h,
+ RegionPtr a_clip_region,
+ pointer a_port_priv) ;
+
+static int ephyrGetVideo (KdScreenInfo *a_info,
+ DrawablePtr a_drawable,
+ short a_vid_x, short a_vid_y,
+ short a_drw_x, short a_drw_y,
+ short a_vid_w, short a_vid_h,
+ short a_drw_w, short a_drw_h,
+ RegionPtr a_clip_region,
+ pointer a_port_priv) ;
+
+static int ephyrPutStill (KdScreenInfo *a_info,
+ DrawablePtr a_drawable,
+ short a_vid_x, short a_vid_y,
+ short a_drw_x, short a_drw_y,
+ short a_vid_w, short a_vid_h,
+ short a_drw_w, short a_drw_h,
+ RegionPtr a_clip_region,
+ pointer a_port_priv) ;
+
+static int ephyrGetStill (KdScreenInfo *a_info,
+ DrawablePtr a_drawable,
+ short a_vid_x, short a_vid_y,
+ short a_drw_x, short a_drw_y,
+ short a_vid_w, short a_vid_h,
+ short a_drw_w, short a_drw_h,
+ RegionPtr a_clip_region,
+ pointer a_port_priv) ;
+
+static int ephyrQueryImageAttributes (KdScreenInfo *a_info,
+ int a_id,
+ unsigned short *a_w,
+ unsigned short *a_h,
+ int *a_pitches,
+ int *a_offsets);
+static int s_base_port_id ;
+
+/**************
+ * <helpers>
+ * ************/
+
+static Bool
+DoSimpleClip (BoxPtr a_dst_box,
+ BoxPtr a_clipper,
+ BoxPtr a_result)
+{
+ BoxRec dstClippedBox ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_dst_box && a_clipper && a_result, FALSE) ;
+
+ /*
+ * setup the clipbox inside the destination.
+ */
+ dstClippedBox.x1 = a_dst_box->x1 ;
+ dstClippedBox.x2 = a_dst_box->x2 ;
+ dstClippedBox.y1 = a_dst_box->y1 ;
+ dstClippedBox.y2 = a_dst_box->y2 ;
+
+ /*
+ * if the cliper leftmost edge is inside
+ * the destination area then the leftmost edge of the resulting
+ * clipped box is the leftmost edge of the cliper.
+ */
+ if (a_clipper->x1 > dstClippedBox.x1)
+ dstClippedBox.x1 = a_clipper->x1 ;
+
+ /*
+ * if the cliper top edge is inside the destination area
+ * then the bottom horizontal edge of the resulting clipped box
+ * is the bottom edge of the cliper
+ */
+ if (a_clipper->y1 > dstClippedBox.y1)
+ dstClippedBox.y1 = a_clipper->y1 ;
+
+ /*ditto for right edge*/
+ if (a_clipper->x2 < dstClippedBox.x2)
+ dstClippedBox.x2 = a_clipper->x2 ;
+
+ /*ditto for bottom edge*/
+ if (a_clipper->y2 < dstClippedBox.y2)
+ dstClippedBox.y2 = a_clipper->y2 ;
+
+ memcpy (a_result, &dstClippedBox, sizeof (dstClippedBox)) ;
+ return TRUE ;
+}
+
+static Bool
+ephyrLocalAtomToHost (int a_local_atom, int *a_host_atom)
+{
+ const char *atom_name=NULL;
+ int host_atom=None ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_host_atom, FALSE) ;
+
+ if (!ValidAtom (a_local_atom))
+ return FALSE ;
+
+ atom_name = NameForAtom (a_local_atom) ;
+
+ if (!atom_name)
+ return FALSE ;
+
+ if (!ephyrHostGetAtom (atom_name, FALSE, &host_atom) || host_atom == None) {
+ EPHYR_LOG_ERROR ("no atom for string %s defined in host X\n",
+ atom_name) ;
+ return FALSE ;
+ }
+ *a_host_atom = host_atom ;
+ return TRUE ;
+}
+
+/*
+ Not used yed.
+static Bool
+ephyrHostAtomToLocal (int a_host_atom, int *a_local_atom)
+{
+ Bool is_ok=FALSE ;
+ char *atom_name=NULL ;
+ int atom=None ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_local_atom, FALSE) ;
+
+ atom_name = ephyrHostGetAtomName (a_host_atom) ;
+ if (!atom_name)
+ goto out ;
+
+ atom = MakeAtom (atom_name, strlen (atom_name), TRUE) ;
+ if (atom == None)
+ goto out ;
+
+ *a_local_atom = atom ;
+ is_ok = TRUE ;
+
+out:
+ if (atom_name) {
+ ephyrHostFree (atom_name) ;
+ }
+ return is_ok ;
+}
+*/
+
+/**************
+ *</helpers>
+ * ************/
+
+Bool
+ephyrInitVideo (ScreenPtr pScreen)
+{
+ Bool is_ok = FALSE ;
+ KdScreenPriv(pScreen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ static EphyrXVPriv *xv_priv;
+
+ EPHYR_LOG ("enter\n") ;
+
+ if (screen->fb.bitsPerPixel == 8) {
+ EPHYR_LOG_ERROR ("8 bits depth not supported\n") ;
+ return FALSE ;
+ }
+
+ if (!xv_priv) {
+ xv_priv = ephyrXVPrivNew () ;
+ }
+ if (!xv_priv) {
+ EPHYR_LOG_ERROR ("failed to create xv_priv\n") ;
+ goto out ;
+ }
+
+ if (!ephyrXVPrivRegisterAdaptors (xv_priv, pScreen)) {
+ EPHYR_LOG_ERROR ("failed to register adaptors\n") ;
+ goto out ;
+ }
+ is_ok = TRUE ;
+
+out:
+ return is_ok ;
+}
+
+static EphyrXVPriv*
+ephyrXVPrivNew (void)
+{
+ EphyrXVPriv *xv_priv=NULL ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ xv_priv = calloc(1, sizeof (EphyrXVPriv)) ;
+ if (!xv_priv) {
+ EPHYR_LOG_ERROR ("failed to create EphyrXVPriv\n") ;
+ goto error ;
+ }
+
+ ephyrHostXVInit () ;
+
+ if (!ephyrXVPrivQueryHostAdaptors (xv_priv)) {
+ EPHYR_LOG_ERROR ("failed to query the host x for xv properties\n") ;
+ goto error ;
+ }
+ if (!ephyrXVPrivSetAdaptorsHooks (xv_priv)) {
+ EPHYR_LOG_ERROR ("failed to set xv_priv hooks\n") ;
+ goto error ;
+ }
+
+ EPHYR_LOG ("leave\n") ;
+ return xv_priv ;
+
+error:
+ if (xv_priv) {
+ ephyrXVPrivDelete (xv_priv) ;
+ xv_priv = NULL ;
+ }
+ return NULL ;
+}
+
+static void
+ephyrXVPrivDelete (EphyrXVPriv *a_this)
+{
+ EPHYR_LOG ("enter\n") ;
+
+ if (!a_this)
+ return ;
+ if (a_this->host_adaptors) {
+ ephyrHostXVAdaptorArrayDelete (a_this->host_adaptors) ;
+ a_this->host_adaptors = NULL ;
+ }
+ free(a_this->adaptors) ;
+ a_this->adaptors = NULL ;
+ free(a_this) ;
+ EPHYR_LOG ("leave\n") ;
+}
+
+static KdVideoEncodingPtr
+videoEncodingDup (EphyrHostEncoding *a_encodings,
+ int a_num_encodings)
+{
+ KdVideoEncodingPtr result = NULL ;
+ int i=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_encodings && a_num_encodings, NULL) ;
+
+ result = calloc(a_num_encodings, sizeof (KdVideoEncodingRec)) ;
+ for (i=0 ; i < a_num_encodings; i++) {
+ result[i].id = a_encodings[i].id ;
+ result[i].name = strdup (a_encodings[i].name) ;
+ result[i].width = a_encodings[i].width ;
+ result[i].height = a_encodings[i].height ;
+ result[i].rate.numerator = a_encodings[i].rate.numerator ;
+ result[i].rate.denominator = a_encodings[i].rate.denominator ;
+ }
+ return result ;
+}
+
+static KdAttributePtr
+portAttributesDup (EphyrHostAttribute *a_encodings,
+ int a_num_encodings)
+{
+ int i=0 ;
+ KdAttributePtr result=NULL ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_encodings && a_num_encodings, NULL) ;
+
+ result = calloc(a_num_encodings, sizeof (KdAttributeRec)) ;
+ if (!result) {
+ EPHYR_LOG_ERROR ("failed to allocate attributes\n") ;
+ return NULL ;
+ }
+ for (i=0; i < a_num_encodings; i++) {
+ result[i].flags = a_encodings[i].flags ;
+ result[i].min_value = a_encodings[i].min_value ;
+ result[i].max_value = a_encodings[i].max_value ;
+ result[i].name = strdup (a_encodings[i].name) ;
+ }
+ return result ;
+}
+
+static Bool
+ephyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this)
+{
+ EphyrHostXVAdaptor *cur_host_adaptor=NULL ;
+ EphyrHostVideoFormat *video_formats=NULL ;
+ EphyrHostEncoding *encodings=NULL ;
+ EphyrHostAttribute *attributes=NULL ;
+ EphyrHostImageFormat *image_formats=NULL ;
+ int num_video_formats=0, base_port_id=0,
+ num_attributes=0, num_formats=0, i=0,
+ port_priv_offset=0;
+ unsigned num_encodings=0 ;
+ Bool is_ok = FALSE ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_this, FALSE) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ if (!ephyrHostXVQueryAdaptors (&a_this->host_adaptors)) {
+ EPHYR_LOG_ERROR ("failed to query host adaptors\n") ;
+ goto out ;
+ }
+ if (a_this->host_adaptors)
+ a_this->num_adaptors =
+ ephyrHostXVAdaptorArrayGetSize (a_this->host_adaptors) ;
+ if (a_this->num_adaptors < 0) {
+ EPHYR_LOG_ERROR ("failed to get number of host adaptors\n") ;
+ goto out ;
+ }
+ EPHYR_LOG ("host has %d adaptors\n", a_this->num_adaptors) ;
+ /*
+ * copy what we can from adaptors into a_this->adaptors
+ */
+ if (a_this->num_adaptors) {
+ a_this->adaptors = calloc(a_this->num_adaptors,
+ sizeof (KdVideoAdaptorRec)) ;
+ if (!a_this->adaptors) {
+ EPHYR_LOG_ERROR ("failed to create internal adaptors\n") ;
+ goto out ;
+ }
+ }
+ for (i=0; i < a_this->num_adaptors; i++) {
+ int j=0 ;
+ cur_host_adaptor =
+ ephyrHostXVAdaptorArrayAt (a_this->host_adaptors, i) ;
+ if (!cur_host_adaptor)
+ continue ;
+ a_this->adaptors[i].nPorts =
+ ephyrHostXVAdaptorGetNbPorts (cur_host_adaptor) ;
+ if (a_this->adaptors[i].nPorts <=0) {
+ EPHYR_LOG_ERROR ("Could not find any port of adaptor %d\n", i) ;
+ continue ;
+ }
+ a_this->adaptors[i].type =
+ ephyrHostXVAdaptorGetType (cur_host_adaptor) ;
+ a_this->adaptors[i].type |= XvWindowMask ;
+ a_this->adaptors[i].flags =
+ VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT;
+ if (ephyrHostXVAdaptorGetName (cur_host_adaptor))
+ a_this->adaptors[i].name =
+ strdup (ephyrHostXVAdaptorGetName (cur_host_adaptor)) ;
+ else
+ a_this->adaptors[i].name = strdup ("Xephyr Video Overlay");
+ base_port_id = ephyrHostXVAdaptorGetFirstPortID (cur_host_adaptor) ;
+ if (base_port_id < 0) {
+ EPHYR_LOG_ERROR ("failed to get port id for adaptor %d\n", i) ;
+ continue ;
+ }
+ if (!s_base_port_id)
+ s_base_port_id = base_port_id ;
+
+ if (!ephyrHostXVQueryEncodings (base_port_id,
+ &encodings,
+ &num_encodings)) {
+ EPHYR_LOG_ERROR ("failed to get encodings for port port id %d,"
+ " adaptors %d\n",
+ base_port_id, i) ;
+ continue ;
+ }
+ a_this->adaptors[i].nEncodings = num_encodings ;
+ a_this->adaptors[i].pEncodings =
+ videoEncodingDup (encodings, num_encodings) ;
+ video_formats = (EphyrHostVideoFormat*)
+ ephyrHostXVAdaptorGetVideoFormats (cur_host_adaptor,
+ &num_video_formats);
+ a_this->adaptors[i].pFormats = (KdVideoFormatPtr) video_formats ;
+ a_this->adaptors[i].nFormats = num_video_formats ;
+ /* got a_this->adaptors[i].nPorts already
+ a_this->adaptors[i].nPorts =
+ ephyrHostXVAdaptorGetNbPorts (cur_host_adaptor) ;
+ */
+ a_this->adaptors[i].pPortPrivates =
+ calloc(a_this->adaptors[i].nPorts,
+ sizeof (DevUnion) + sizeof (EphyrPortPriv)) ;
+ port_priv_offset = a_this->adaptors[i].nPorts;
+ for (j=0; j < a_this->adaptors[i].nPorts; j++) {
+ EphyrPortPriv *port_privs_base =
+ (EphyrPortPriv*)&a_this->adaptors[i].pPortPrivates[port_priv_offset];
+ EphyrPortPriv *port_priv = &port_privs_base[j] ;
+ port_priv->port_number = base_port_id + j;
+ port_priv->current_adaptor = &a_this->adaptors[i] ;
+ port_priv->xv_priv = a_this ;
+ a_this->adaptors[i].pPortPrivates[j].ptr = port_priv;
+ }
+ if (!ephyrHostXVQueryPortAttributes (base_port_id,
+ &attributes,
+ &num_attributes)) {
+ EPHYR_LOG_ERROR ("failed to get port attribute "
+ "for adaptor %d\n", i) ;
+ continue ;
+ }
+ a_this->adaptors[i].pAttributes =
+ portAttributesDup (attributes, num_attributes);
+ a_this->adaptors[i].nAttributes = num_attributes ;
+ /*make sure atoms of attrs names are created in xephyr*/
+ for (j=0; j < a_this->adaptors[i].nAttributes; j++) {
+ if (a_this->adaptors[i].pAttributes[j].name)
+ MakeAtom (a_this->adaptors[i].pAttributes[j].name,
+ strlen (a_this->adaptors[i].pAttributes[j].name),
+ TRUE) ;
+ }
+ if (!ephyrHostXVQueryImageFormats (base_port_id,
+ &image_formats,
+ &num_formats)) {
+ EPHYR_LOG_ERROR ("failed to get image formats "
+ "for adaptor %d\n", i) ;
+ continue ;
+ }
+ a_this->adaptors[i].pImages = (KdImagePtr) image_formats ;
+ a_this->adaptors[i].nImages = num_formats ;
+ }
+ is_ok = TRUE ;
+
+out:
+ if (encodings) {
+ ephyrHostEncodingsDelete (encodings, num_encodings) ;
+ encodings = NULL ;
+ }
+ if (attributes) {
+ ephyrHostAttributesDelete (attributes) ;
+ attributes = NULL ;
+ }
+ EPHYR_LOG ("leave\n") ;
+ return is_ok ;
+}
+
+static Bool
+ephyrXVPrivSetAdaptorsHooks (EphyrXVPriv *a_this)
+{
+ int i=0 ;
+ Bool has_it=FALSE ;
+ EphyrHostXVAdaptor *cur_host_adaptor=NULL ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_this, FALSE) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ for (i=0; i < a_this->num_adaptors; i++) {
+ a_this->adaptors[i].ReputImage = ephyrReputImage ;
+ a_this->adaptors[i].StopVideo = ephyrStopVideo ;
+ a_this->adaptors[i].SetPortAttribute = ephyrSetPortAttribute ;
+ a_this->adaptors[i].GetPortAttribute = ephyrGetPortAttribute ;
+ a_this->adaptors[i].QueryBestSize = ephyrQueryBestSize ;
+ a_this->adaptors[i].QueryImageAttributes = ephyrQueryImageAttributes ;
+
+ cur_host_adaptor =
+ ephyrHostXVAdaptorArrayAt (a_this->host_adaptors, i) ;
+ if (!cur_host_adaptor) {
+ EPHYR_LOG_ERROR ("failed to get host adaptor at index %d\n", i) ;
+ continue ;
+ }
+ has_it = FALSE ;
+ if (!ephyrHostXVAdaptorHasPutImage (cur_host_adaptor, &has_it)) {
+ EPHYR_LOG_ERROR ("error\n") ;
+ }
+ if (has_it) {
+ a_this->adaptors[i].PutImage = ephyrPutImage;
+ }
+
+ has_it = FALSE ;
+ if (!ephyrHostXVAdaptorHasPutVideo (cur_host_adaptor, &has_it)) {
+ EPHYR_LOG_ERROR ("error\n") ;
+ }
+ if (has_it) {
+ a_this->adaptors[i].PutVideo = ephyrPutVideo;
+ }
+
+ has_it = FALSE ;
+ if (!ephyrHostXVAdaptorHasGetVideo (cur_host_adaptor, &has_it)) {
+ EPHYR_LOG_ERROR ("error\n") ;
+ }
+ if (has_it) {
+ a_this->adaptors[i].GetVideo = ephyrGetVideo;
+ }
+
+ has_it = FALSE ;
+ if (!ephyrHostXVAdaptorHasPutStill (cur_host_adaptor, &has_it)) {
+ EPHYR_LOG_ERROR ("error\n") ;
+ }
+ if (has_it) {
+ a_this->adaptors[i].PutStill = ephyrPutStill;
+ }
+
+ has_it = FALSE ;
+ if (!ephyrHostXVAdaptorHasGetStill (cur_host_adaptor, &has_it)) {
+ EPHYR_LOG_ERROR ("error\n") ;
+ }
+ if (has_it) {
+ a_this->adaptors[i].GetStill = ephyrGetStill;
+ }
+ }
+ EPHYR_LOG ("leave\n") ;
+ return TRUE ;
+}
+
+static Bool
+ephyrXVPrivRegisterAdaptors (EphyrXVPriv *a_this,
+ ScreenPtr a_screen)
+{
+ KdScreenPriv(a_screen);
+ KdScreenInfo *screen = pScreenPriv->screen;
+ Bool is_ok = FALSE ;
+ KdVideoAdaptorPtr *adaptors=NULL, *registered_adaptors=NULL ;
+ int num_registered_adaptors=0, i=0, num_adaptors=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_this && a_screen, FALSE) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ if (!a_this->num_adaptors)
+ goto out ;
+ num_registered_adaptors =
+ KdXVListGenericAdaptors (screen, &registered_adaptors);
+
+ num_adaptors = num_registered_adaptors + a_this->num_adaptors ;
+ adaptors = calloc(num_adaptors, sizeof (KdVideoAdaptorPtr)) ;
+ if (!adaptors) {
+ EPHYR_LOG_ERROR ("failed to allocate adaptors tab\n") ;
+ goto out ;
+ }
+ memmove (adaptors, registered_adaptors, num_registered_adaptors) ;
+ for (i=0 ; i < a_this->num_adaptors; i++) {
+ *(adaptors + num_registered_adaptors + i) = &a_this->adaptors[i] ;
+ }
+ if (!KdXVScreenInit (a_screen, adaptors, num_adaptors)) {
+ EPHYR_LOG_ERROR ("failed to register adaptors\n");
+ goto out ;
+ }
+ EPHYR_LOG ("there are %d registered adaptors\n", num_adaptors) ;
+ is_ok = TRUE ;
+
+out:
+ free(registered_adaptors) ;
+ registered_adaptors = NULL ;
+ free(adaptors) ;
+ adaptors = NULL ;
+
+ EPHYR_LOG ("leave\n") ;
+ return is_ok ;
+}
+
+static Bool
+ephyrXVPrivIsAttrValueValid (KdAttributePtr a_attrs,
+ int a_attrs_len,
+ const char *a_attr_name,
+ int a_attr_value,
+ Bool *a_is_valid)
+{
+ int i=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_attrs && a_attr_name && a_is_valid,
+ FALSE) ;
+
+ for (i=0; i < a_attrs_len; i++) {
+ if (a_attrs[i].name && strcmp (a_attrs[i].name, a_attr_name))
+ continue ;
+ if (a_attrs[i].min_value > a_attr_value ||
+ a_attrs[i].max_value < a_attr_value) {
+ *a_is_valid = FALSE ;
+ EPHYR_LOG_ERROR ("attribute was not valid\n"
+ "value:%d. min:%d. max:%d\n",
+ a_attr_value,
+ a_attrs[i].min_value,
+ a_attrs[i].max_value) ;
+ } else {
+ *a_is_valid = TRUE ;
+ }
+ return TRUE ;
+ }
+ return FALSE ;
+}
+
+static Bool
+ephyrXVPrivGetImageBufSize (int a_port_id,
+ int a_image_id,
+ unsigned short a_width,
+ unsigned short a_height,
+ int *a_size)
+{
+ Bool is_ok=FALSE ;
+ unsigned short width=a_width, height=a_height ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_size, FALSE) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ if (!ephyrHostXVQueryImageAttributes (a_port_id, a_image_id,
+ &width, &height, a_size, NULL, NULL)) {
+ EPHYR_LOG_ERROR ("failed to get image attributes\n") ;
+ goto out ;
+ }
+ is_ok = TRUE ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return is_ok ;
+}
+
+static Bool
+ephyrXVPrivSaveImageToPortPriv (EphyrPortPriv *a_port_priv,
+ const unsigned char *a_image_buf,
+ int a_image_len)
+{
+ Bool is_ok=FALSE ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ if (a_port_priv->image_buf_size < a_image_len) {
+ unsigned char *buf=NULL ;
+ buf = realloc (a_port_priv->image_buf, a_image_len) ;
+ if (!buf) {
+ EPHYR_LOG_ERROR ("failed to realloc image buffer\n") ;
+ goto out ;
+ }
+ a_port_priv->image_buf = buf ;
+ a_port_priv->image_buf_size = a_image_len;
+ }
+ memmove (a_port_priv->image_buf, a_image_buf, a_image_len) ;
+ is_ok = TRUE ;
+
+out:
+ return is_ok ;
+ EPHYR_LOG ("leave\n") ;
+}
+
+static void
+ephyrStopVideo (KdScreenInfo *a_info, pointer a_port_priv, Bool a_exit)
+{
+ EphyrPortPriv *port_priv = a_port_priv ;
+
+ EPHYR_RETURN_IF_FAIL (a_info && a_info->pScreen) ;
+ EPHYR_RETURN_IF_FAIL (port_priv) ;
+
+ EPHYR_LOG ("enter\n") ;
+ if (!ephyrHostXVStopVideo (a_info->pScreen->myNum,
+ port_priv->port_number)) {
+ EPHYR_LOG_ERROR ("XvStopVideo() failed\n") ;
+ }
+ EPHYR_LOG ("leave\n") ;
+}
+
+static int
+ephyrSetPortAttribute (KdScreenInfo *a_info,
+ Atom a_attr_name,
+ int a_attr_value,
+ pointer a_port_priv)
+{
+ int res=Success, host_atom=0 ;
+ EphyrPortPriv *port_priv = a_port_priv ;
+ Bool is_attr_valid=FALSE ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (port_priv, BadMatch) ;
+ EPHYR_RETURN_VAL_IF_FAIL (port_priv->current_adaptor, BadMatch) ;
+ EPHYR_RETURN_VAL_IF_FAIL (port_priv->current_adaptor->pAttributes,
+ BadMatch) ;
+ EPHYR_RETURN_VAL_IF_FAIL (port_priv->current_adaptor->nAttributes,
+ BadMatch) ;
+ EPHYR_RETURN_VAL_IF_FAIL (ValidAtom (a_attr_name), BadMatch) ;
+
+ EPHYR_LOG ("enter, portnum:%d, atomid:%d, attr_name:%s, attr_val:%d\n",
+ port_priv->port_number,
+ (int)a_attr_name,
+ NameForAtom (a_attr_name),
+ a_attr_value) ;
+
+ if (!ephyrLocalAtomToHost (a_attr_name, &host_atom)) {
+ EPHYR_LOG_ERROR ("failed to convert local atom to host atom\n") ;
+ res = BadMatch ;
+ goto out ;
+ }
+
+ if (!ephyrXVPrivIsAttrValueValid (port_priv->current_adaptor->pAttributes,
+ port_priv->current_adaptor->nAttributes,
+ NameForAtom (a_attr_name),
+ a_attr_value,
+ &is_attr_valid)) {
+ EPHYR_LOG_ERROR ("failed to validate attribute %s\n",
+ NameForAtom (a_attr_name)) ;
+ /*
+ res = BadMatch ;
+ goto out ;
+ */
+ }
+ if (!is_attr_valid) {
+ EPHYR_LOG_ERROR ("attribute %s is not valid\n",
+ NameForAtom (a_attr_name)) ;
+ /*
+ res = BadMatch ;
+ goto out ;
+ */
+ }
+
+ if (!ephyrHostXVSetPortAttribute (port_priv->port_number,
+ host_atom,
+ a_attr_value)) {
+ EPHYR_LOG_ERROR ("failed to set port attribute\n") ;
+ res = BadMatch ;
+ goto out ;
+ }
+
+ res = Success ;
+out:
+ EPHYR_LOG ("leave\n") ;
+ return res ;
+}
+
+static int
+ephyrGetPortAttribute (KdScreenInfo *a_screen_info,
+ Atom a_attr_name,
+ int *a_attr_value,
+ pointer a_port_priv)
+{
+ int res=Success, host_atom=0 ;
+ EphyrPortPriv *port_priv = a_port_priv ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (port_priv, BadMatch) ;
+ EPHYR_RETURN_VAL_IF_FAIL (ValidAtom (a_attr_name), BadMatch) ;
+
+ EPHYR_LOG ("enter, portnum:%d, atomid:%d, attr_name:%s\n",
+ port_priv->port_number,
+ (int)a_attr_name,
+ NameForAtom (a_attr_name)) ;
+
+ if (!ephyrLocalAtomToHost (a_attr_name, &host_atom)) {
+ EPHYR_LOG_ERROR ("failed to convert local atom to host atom\n") ;
+ res = BadMatch ;
+ goto out ;
+ }
+
+ if (!ephyrHostXVGetPortAttribute (port_priv->port_number,
+ host_atom,
+ a_attr_value)) {
+ EPHYR_LOG_ERROR ("failed to get port attribute\n") ;
+ res = BadMatch ;
+ goto out ;
+ }
+
+ res = Success ;
+out:
+ EPHYR_LOG ("leave\n") ;
+ return res ;
+}
+
+static void
+ephyrQueryBestSize (KdScreenInfo *a_info,
+ Bool a_motion,
+ short a_src_w,
+ short a_src_h,
+ short a_drw_w,
+ short a_drw_h,
+ unsigned int *a_prefered_w,
+ unsigned int *a_prefered_h,
+ pointer a_port_priv)
+{
+ int res=0 ;
+ EphyrPortPriv *port_priv = a_port_priv ;
+
+ EPHYR_RETURN_IF_FAIL (port_priv) ;
+
+ EPHYR_LOG ("enter\n") ;
+ res = ephyrHostXVQueryBestSize (port_priv->port_number,
+ a_motion,
+ a_src_w, a_src_h,
+ a_drw_w, a_drw_h,
+ a_prefered_w, a_prefered_h) ;
+ if (!res) {
+ EPHYR_LOG_ERROR ("Failed to query best size\n") ;
+ }
+ EPHYR_LOG ("leave\n") ;
+}
+
+static int
+ephyrPutImage (KdScreenInfo *a_info,
+ DrawablePtr a_drawable,
+ short a_src_x,
+ short a_src_y,
+ short a_drw_x,
+ short a_drw_y,
+ short a_src_w,
+ short a_src_h,
+ short a_drw_w,
+ short a_drw_h,
+ int a_id,
+ unsigned char *a_buf,
+ short a_width,
+ short a_height,
+ Bool a_sync,
+ RegionPtr a_clipping_region,
+ pointer a_port_priv)
+{
+ EphyrPortPriv *port_priv = a_port_priv ;
+ Bool is_ok=FALSE ;
+ int result=BadImplementation, image_size=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_info && a_info->pScreen, BadValue) ;
+ EPHYR_RETURN_VAL_IF_FAIL (a_drawable, BadValue) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ if (!ephyrHostXVPutImage (a_info->pScreen->myNum,
+ port_priv->port_number,
+ a_id,
+ a_drw_x, a_drw_y, a_drw_w, a_drw_h,
+ a_src_x, a_src_y, a_src_w, a_src_h,
+ a_width, a_height, a_buf,
+ (EphyrHostBox*)REGION_RECTS (a_clipping_region),
+ REGION_NUM_RECTS (a_clipping_region))) {
+ EPHYR_LOG_ERROR ("EphyrHostXVPutImage() failed\n") ;
+ goto out ;
+ }
+
+ /*
+ * Now save the image so that we can resend it to host it
+ * later, in ReputImage.
+ */
+ if (!ephyrXVPrivGetImageBufSize (port_priv->port_number,
+ a_id, a_width, a_height, &image_size)) {
+ EPHYR_LOG_ERROR ("failed to get image size\n") ;
+ /*this is a minor error so we won't get bail out abruptly*/
+ is_ok = FALSE ;
+ } else {
+ is_ok = TRUE ;
+ }
+ if (is_ok) {
+ if (!ephyrXVPrivSaveImageToPortPriv (port_priv, a_buf, image_size)) {
+ is_ok=FALSE ;
+ } else {
+ port_priv->image_id = a_id;
+ port_priv->drw_x = a_drw_x;
+ port_priv->drw_y = a_drw_y;
+ port_priv->drw_w = a_drw_w ;
+ port_priv->drw_h = a_drw_h ;
+ port_priv->src_x = a_src_x;
+ port_priv->src_y = a_src_y ;
+ port_priv->src_w = a_src_w ;
+ port_priv->src_h = a_src_h ;
+ port_priv->image_width = a_width ;
+ port_priv->image_height = a_height ;
+ }
+ }
+ if (!is_ok) {
+ if (port_priv->image_buf) {
+ free (port_priv->image_buf) ;
+ port_priv->image_buf = NULL ;
+ port_priv->image_buf_size = 0 ;
+ }
+ }
+
+ result = Success ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return result ;
+}
+
+static int
+ephyrReputImage (KdScreenInfo *a_info,
+ DrawablePtr a_drawable,
+ short a_drw_x,
+ short a_drw_y,
+ RegionPtr a_clipping_region,
+ pointer a_port_priv)
+{
+ EphyrPortPriv *port_priv = a_port_priv ;
+ int result=BadImplementation ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_info->pScreen, FALSE) ;
+ EPHYR_RETURN_VAL_IF_FAIL (a_drawable && port_priv, BadValue) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ if (!port_priv->image_buf_size || !port_priv->image_buf) {
+ EPHYR_LOG_ERROR ("has null image buf in cache\n") ;
+ goto out ;
+ }
+ if (!ephyrHostXVPutImage (a_info->pScreen->myNum,
+ port_priv->port_number,
+ port_priv->image_id,
+ a_drw_x, a_drw_y,
+ port_priv->drw_w, port_priv->drw_h,
+ port_priv->src_x, port_priv->src_y,
+ port_priv->src_w, port_priv->src_h,
+ port_priv->image_width, port_priv->image_height,
+ port_priv->image_buf,
+ (EphyrHostBox*)REGION_RECTS (a_clipping_region),
+ REGION_NUM_RECTS (a_clipping_region))) {
+ EPHYR_LOG_ERROR ("ephyrHostXVPutImage() failed\n") ;
+ goto out ;
+ }
+
+ result = Success ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return result ;
+}
+
+static int
+ephyrPutVideo (KdScreenInfo *a_info,
+ DrawablePtr a_drawable,
+ short a_vid_x, short a_vid_y,
+ short a_drw_x, short a_drw_y,
+ short a_vid_w, short a_vid_h,
+ short a_drw_w, short a_drw_h,
+ RegionPtr a_clipping_region,
+ pointer a_port_priv)
+{
+ EphyrPortPriv *port_priv = a_port_priv ;
+ BoxRec clipped_area, dst_box ;
+ int result=BadImplementation ;
+ int drw_x=0, drw_y=0, drw_w=0, drw_h=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_info->pScreen, BadValue) ;
+ EPHYR_RETURN_VAL_IF_FAIL (a_drawable && port_priv, BadValue) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ dst_box.x1 = a_drw_x ;
+ dst_box.x2 = a_drw_x + a_drw_w;
+ dst_box.y1 = a_drw_y ;
+ dst_box.y2 = a_drw_y + a_drw_h;
+
+ if (!DoSimpleClip (&dst_box,
+ REGION_EXTENTS (pScreen->pScreen, a_clipping_region),
+ &clipped_area)) {
+ EPHYR_LOG_ERROR ("failed to simple clip\n") ;
+ goto out ;
+ }
+
+ drw_x = clipped_area.x1 ;
+ drw_y = clipped_area.y1 ;
+ drw_w = clipped_area.x2 - clipped_area.x1 ;
+ drw_h = clipped_area.y2 - clipped_area.y1 ;
+
+ if (!ephyrHostXVPutVideo (a_info->pScreen->myNum,
+ port_priv->port_number,
+ a_vid_x, a_vid_y, a_vid_w, a_vid_h,
+ a_drw_x, a_drw_y, a_drw_w, a_drw_h)) {
+ EPHYR_LOG_ERROR ("ephyrHostXVPutVideo() failed\n") ;
+ goto out ;
+ }
+ result = Success ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return result ;
+}
+
+static int
+ephyrGetVideo (KdScreenInfo *a_info,
+ DrawablePtr a_drawable,
+ short a_vid_x, short a_vid_y,
+ short a_drw_x, short a_drw_y,
+ short a_vid_w, short a_vid_h,
+ short a_drw_w, short a_drw_h,
+ RegionPtr a_clipping_region,
+ pointer a_port_priv)
+{
+ EphyrPortPriv *port_priv = a_port_priv ;
+ BoxRec clipped_area, dst_box ;
+ int result=BadImplementation ;
+ int drw_x=0, drw_y=0, drw_w=0, drw_h=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_info && a_info->pScreen, BadValue) ;
+ EPHYR_RETURN_VAL_IF_FAIL (a_drawable && port_priv, BadValue) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ dst_box.x1 = a_drw_x ;
+ dst_box.x2 = a_drw_x + a_drw_w;
+ dst_box.y1 = a_drw_y ;
+ dst_box.y2 = a_drw_y + a_drw_h;
+
+ if (!DoSimpleClip (&dst_box,
+ REGION_EXTENTS (pScreen->pScreen, a_clipping_region),
+ &clipped_area)) {
+ EPHYR_LOG_ERROR ("failed to simple clip\n") ;
+ goto out ;
+ }
+
+ drw_x = clipped_area.x1 ;
+ drw_y = clipped_area.y1 ;
+ drw_w = clipped_area.x2 - clipped_area.x1 ;
+ drw_h = clipped_area.y2 - clipped_area.y1 ;
+
+ if (!ephyrHostXVGetVideo (a_info->pScreen->myNum,
+ port_priv->port_number,
+ a_vid_x, a_vid_y, a_vid_w, a_vid_h,
+ a_drw_x, a_drw_y, a_drw_w, a_drw_h)) {
+ EPHYR_LOG_ERROR ("ephyrHostXVGetVideo() failed\n") ;
+ goto out ;
+ }
+ result = Success ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return result ;
+}
+
+static int
+ephyrPutStill (KdScreenInfo *a_info,
+ DrawablePtr a_drawable,
+ short a_vid_x, short a_vid_y,
+ short a_drw_x, short a_drw_y,
+ short a_vid_w, short a_vid_h,
+ short a_drw_w, short a_drw_h,
+ RegionPtr a_clipping_region,
+ pointer a_port_priv)
+{
+ EphyrPortPriv *port_priv = a_port_priv ;
+ BoxRec clipped_area, dst_box ;
+ int result=BadImplementation ;
+ int drw_x=0, drw_y=0, drw_w=0, drw_h=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_info && a_info->pScreen, BadValue) ;
+ EPHYR_RETURN_VAL_IF_FAIL (a_drawable && port_priv, BadValue) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ dst_box.x1 = a_drw_x ;
+ dst_box.x2 = a_drw_x + a_drw_w;
+ dst_box.y1 = a_drw_y ;
+ dst_box.y2 = a_drw_y + a_drw_h;
+
+ if (!DoSimpleClip (&dst_box,
+ REGION_EXTENTS (pScreen->pScreen, a_clipping_region),
+ &clipped_area)) {
+ EPHYR_LOG_ERROR ("failed to simple clip\n") ;
+ goto out ;
+ }
+
+ drw_x = clipped_area.x1 ;
+ drw_y = clipped_area.y1 ;
+ drw_w = clipped_area.x2 - clipped_area.x1 ;
+ drw_h = clipped_area.y2 - clipped_area.y1 ;
+
+ if (!ephyrHostXVPutStill (a_info->pScreen->myNum,
+ port_priv->port_number,
+ a_vid_x, a_vid_y, a_vid_w, a_vid_h,
+ a_drw_x, a_drw_y, a_drw_w, a_drw_h)) {
+ EPHYR_LOG_ERROR ("ephyrHostXVPutStill() failed\n") ;
+ goto out ;
+ }
+ result = Success ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return result ;
+}
+
+static int
+ephyrGetStill (KdScreenInfo *a_info,
+ DrawablePtr a_drawable,
+ short a_vid_x, short a_vid_y,
+ short a_drw_x, short a_drw_y,
+ short a_vid_w, short a_vid_h,
+ short a_drw_w, short a_drw_h,
+ RegionPtr a_clipping_region,
+ pointer a_port_priv)
+{
+ EphyrPortPriv *port_priv = a_port_priv ;
+ BoxRec clipped_area, dst_box ;
+ int result=BadImplementation ;
+ int drw_x=0, drw_y=0, drw_w=0, drw_h=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_info && a_info->pScreen, BadValue) ;
+ EPHYR_RETURN_VAL_IF_FAIL (a_drawable && port_priv, BadValue) ;
+
+ EPHYR_LOG ("enter\n") ;
+
+ dst_box.x1 = a_drw_x ;
+ dst_box.x2 = a_drw_x + a_drw_w;
+ dst_box.y1 = a_drw_y ;
+ dst_box.y2 = a_drw_y + a_drw_h;
+
+ if (!DoSimpleClip (&dst_box,
+ REGION_EXTENTS (pScreen->pScreen, a_clipping_region),
+ &clipped_area)) {
+ EPHYR_LOG_ERROR ("failed to simple clip\n") ;
+ goto out ;
+ }
+
+ drw_x = clipped_area.x1 ;
+ drw_y = clipped_area.y1 ;
+ drw_w = clipped_area.x2 - clipped_area.x1 ;
+ drw_h = clipped_area.y2 - clipped_area.y1 ;
+
+ if (!ephyrHostXVGetStill (a_info->pScreen->myNum,
+ port_priv->port_number,
+ a_vid_x, a_vid_y, a_vid_w, a_vid_h,
+ a_drw_x, a_drw_y, a_drw_w, a_drw_h)) {
+ EPHYR_LOG_ERROR ("ephyrHostXVGetStill() failed\n") ;
+ goto out ;
+ }
+ result = Success ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return result ;
+}
+
+static int
+ephyrQueryImageAttributes (KdScreenInfo *a_info,
+ int a_id,
+ unsigned short *a_w,
+ unsigned short *a_h,
+ int *a_pitches,
+ int *a_offsets)
+{
+ int image_size=0 ;
+
+ EPHYR_RETURN_VAL_IF_FAIL (a_w && a_h, FALSE) ;
+
+ EPHYR_LOG ("enter: dim (%dx%d), pitches: %p, offsets: %p\n",
+ *a_w, *a_h, a_pitches, a_offsets) ;
+
+ if (!ephyrHostXVQueryImageAttributes (s_base_port_id,
+ a_id,
+ a_w, a_h,
+ &image_size,
+ a_pitches, a_offsets)) {
+ EPHYR_LOG_ERROR ("EphyrHostXVQueryImageAttributes() failed\n") ;
+ goto out ;
+ }
+ EPHYR_LOG ("image size: %d, dim (%dx%d)\n", image_size, *a_w, *a_h) ;
+
+out:
+ EPHYR_LOG ("leave\n") ;
+ return image_size ;
+}