diff options
author | marha <marha@users.sourceforge.net> | 2010-05-16 20:50:58 +0000 |
---|---|---|
committer | marha <marha@users.sourceforge.net> | 2010-05-16 20:50:58 +0000 |
commit | 1c94119ae26b94a60bb2c2b33494ed43c3b8a52f (patch) | |
tree | cfe0c736c95314edac7d9f1065be9c13026ed0c1 /xorg-server/hw/kdrive/ephyr/ephyrvideo.c | |
parent | 6b29aa4559aeb6f795caee047561654bfa0a1954 (diff) | |
download | vcxsrv-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.c | 2546 |
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, ®istered_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, ®istered_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 ;
+}
|