1706f2543Smrg/* 2706f2543Smrg * Xephyr - A kdrive X server thats runs in a host X window. 3706f2543Smrg * Authored by Matthew Allum <mallum@openedhand.com> 4706f2543Smrg * 5706f2543Smrg * Copyright © 2007 OpenedHand Ltd 6706f2543Smrg * 7706f2543Smrg * Permission to use, copy, modify, distribute, and sell this software and its 8706f2543Smrg * documentation for any purpose is hereby granted without fee, provided that 9706f2543Smrg * the above copyright notice appear in all copies and that both that 10706f2543Smrg * copyright notice and this permission notice appear in supporting 11706f2543Smrg * documentation, and that the name of OpenedHand Ltd not be used in 12706f2543Smrg * advertising or publicity pertaining to distribution of the software without 13706f2543Smrg * specific, written prior permission. OpenedHand Ltd makes no 14706f2543Smrg * representations about the suitability of this software for any purpose. It 15706f2543Smrg * is provided "as is" without express or implied warranty. 16706f2543Smrg * 17706f2543Smrg * OpenedHand Ltd DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, 18706f2543Smrg * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO 19706f2543Smrg * EVENT SHALL OpenedHand Ltd BE LIABLE FOR ANY SPECIAL, INDIRECT OR 20706f2543Smrg * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, 21706f2543Smrg * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER 22706f2543Smrg * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR 23706f2543Smrg * PERFORMANCE OF THIS SOFTWARE. 24706f2543Smrg * 25706f2543Smrg * Authors: 26706f2543Smrg * Dodji Seketeli <dodji@openedhand.com> 27706f2543Smrg */ 28706f2543Smrg 29706f2543Smrg#ifdef HAVE_CONFIG_H 30706f2543Smrg#include <kdrive-config.h> 31706f2543Smrg#endif 32706f2543Smrg#include <string.h> 33706f2543Smrg#include <X11/extensions/Xv.h> 34706f2543Smrg#include "ephyrlog.h" 35706f2543Smrg#include "kdrive.h" 36706f2543Smrg#include "kxv.h" 37706f2543Smrg#include "ephyr.h" 38706f2543Smrg#include "hostx.h" 39706f2543Smrg#include "ephyrhostvideo.h" 40706f2543Smrg 41706f2543Smrgstruct _EphyrXVPriv { 42706f2543Smrg EphyrHostXVAdaptorArray *host_adaptors ; 43706f2543Smrg KdVideoAdaptorPtr adaptors ; 44706f2543Smrg int num_adaptors ; 45706f2543Smrg}; 46706f2543Smrgtypedef struct _EphyrXVPriv EphyrXVPriv ; 47706f2543Smrg 48706f2543Smrgstruct _EphyrPortPriv { 49706f2543Smrg int port_number ; 50706f2543Smrg KdVideoAdaptorPtr current_adaptor ; 51706f2543Smrg EphyrXVPriv *xv_priv; 52706f2543Smrg unsigned char *image_buf ; 53706f2543Smrg int image_buf_size ; 54706f2543Smrg int image_id ; 55706f2543Smrg int drw_x, drw_y, drw_w, drw_h ; 56706f2543Smrg int src_x, src_y, src_w, src_h ; 57706f2543Smrg int image_width, image_height ; 58706f2543Smrg}; 59706f2543Smrgtypedef struct _EphyrPortPriv EphyrPortPriv ; 60706f2543Smrg 61706f2543Smrgstatic Bool DoSimpleClip (BoxPtr a_dst_drw, 62706f2543Smrg BoxPtr a_clipper, 63706f2543Smrg BoxPtr a_result) ; 64706f2543Smrg 65706f2543Smrgstatic Bool ephyrLocalAtomToHost (int a_local_atom, int *a_host_atom) ; 66706f2543Smrg 67706f2543Smrg/* 68706f2543Smrgstatic Bool ephyrHostAtomToLocal (int a_host_atom, int *a_local_atom) ; 69706f2543Smrg*/ 70706f2543Smrg 71706f2543Smrgstatic EphyrXVPriv* ephyrXVPrivNew (void) ; 72706f2543Smrgstatic void ephyrXVPrivDelete (EphyrXVPriv *a_this) ; 73706f2543Smrgstatic Bool ephyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this) ; 74706f2543Smrgstatic Bool ephyrXVPrivSetAdaptorsHooks (EphyrXVPriv *a_this) ; 75706f2543Smrgstatic Bool ephyrXVPrivRegisterAdaptors (EphyrXVPriv *a_this, 76706f2543Smrg ScreenPtr a_screen) ; 77706f2543Smrg 78706f2543Smrgstatic Bool ephyrXVPrivIsAttrValueValid (KdAttributePtr a_attrs, 79706f2543Smrg int a_attrs_len, 80706f2543Smrg const char *a_attr_name, 81706f2543Smrg int a_attr_value, 82706f2543Smrg Bool *a_is_valid) ; 83706f2543Smrg 84706f2543Smrgstatic Bool ephyrXVPrivGetImageBufSize (int a_port_id, 85706f2543Smrg int a_image_id, 86706f2543Smrg unsigned short a_width, 87706f2543Smrg unsigned short a_height, 88706f2543Smrg int *a_size) ; 89706f2543Smrg 90706f2543Smrgstatic Bool ephyrXVPrivSaveImageToPortPriv (EphyrPortPriv *a_port_priv, 91706f2543Smrg const unsigned char *a_image, 92706f2543Smrg int a_image_len) ; 93706f2543Smrg 94706f2543Smrgstatic void ephyrStopVideo (KdScreenInfo *a_info, 95706f2543Smrg pointer a_xv_priv, 96706f2543Smrg Bool a_exit); 97706f2543Smrg 98706f2543Smrgstatic int ephyrSetPortAttribute (KdScreenInfo *a_info, 99706f2543Smrg Atom a_attr_name, 100706f2543Smrg int a_attr_value, 101706f2543Smrg pointer a_port_priv); 102706f2543Smrg 103706f2543Smrgstatic int ephyrGetPortAttribute (KdScreenInfo *a_screen_info, 104706f2543Smrg Atom a_attr_name, 105706f2543Smrg int *a_attr_value, 106706f2543Smrg pointer a_port_priv); 107706f2543Smrg 108706f2543Smrgstatic void ephyrQueryBestSize (KdScreenInfo *a_info, 109706f2543Smrg Bool a_motion, 110706f2543Smrg short a_src_w, 111706f2543Smrg short a_src_h, 112706f2543Smrg short a_drw_w, 113706f2543Smrg short a_drw_h, 114706f2543Smrg unsigned int *a_prefered_w, 115706f2543Smrg unsigned int *a_prefered_h, 116706f2543Smrg pointer a_port_priv); 117706f2543Smrg 118706f2543Smrgstatic int ephyrPutImage (KdScreenInfo *a_info, 119706f2543Smrg DrawablePtr a_drawable, 120706f2543Smrg short a_src_x, 121706f2543Smrg short a_src_y, 122706f2543Smrg short a_drw_x, 123706f2543Smrg short a_drw_y, 124706f2543Smrg short a_src_w, 125706f2543Smrg short a_src_h, 126706f2543Smrg short a_drw_w, 127706f2543Smrg short a_drw_h, 128706f2543Smrg int a_id, 129706f2543Smrg unsigned char *a_buf, 130706f2543Smrg short a_width, 131706f2543Smrg short a_height, 132706f2543Smrg Bool a_sync, 133706f2543Smrg RegionPtr a_clipping_region, 134706f2543Smrg pointer a_port_priv); 135706f2543Smrg 136706f2543Smrgstatic int ephyrReputImage (KdScreenInfo *a_info, 137706f2543Smrg DrawablePtr a_drawable, 138706f2543Smrg short a_drw_x, 139706f2543Smrg short a_drw_y, 140706f2543Smrg RegionPtr a_clipping_region, 141706f2543Smrg pointer a_port_priv) ; 142706f2543Smrg 143706f2543Smrgstatic int ephyrPutVideo (KdScreenInfo *a_info, 144706f2543Smrg DrawablePtr a_drawable, 145706f2543Smrg short a_vid_x, short a_vid_y, 146706f2543Smrg short a_drw_x, short a_drw_y, 147706f2543Smrg short a_vid_w, short a_vid_h, 148706f2543Smrg short a_drw_w, short a_drw_h, 149706f2543Smrg RegionPtr a_clip_region, 150706f2543Smrg pointer a_port_priv) ; 151706f2543Smrg 152706f2543Smrgstatic int ephyrGetVideo (KdScreenInfo *a_info, 153706f2543Smrg DrawablePtr a_drawable, 154706f2543Smrg short a_vid_x, short a_vid_y, 155706f2543Smrg short a_drw_x, short a_drw_y, 156706f2543Smrg short a_vid_w, short a_vid_h, 157706f2543Smrg short a_drw_w, short a_drw_h, 158706f2543Smrg RegionPtr a_clip_region, 159706f2543Smrg pointer a_port_priv) ; 160706f2543Smrg 161706f2543Smrgstatic int ephyrPutStill (KdScreenInfo *a_info, 162706f2543Smrg DrawablePtr a_drawable, 163706f2543Smrg short a_vid_x, short a_vid_y, 164706f2543Smrg short a_drw_x, short a_drw_y, 165706f2543Smrg short a_vid_w, short a_vid_h, 166706f2543Smrg short a_drw_w, short a_drw_h, 167706f2543Smrg RegionPtr a_clip_region, 168706f2543Smrg pointer a_port_priv) ; 169706f2543Smrg 170706f2543Smrgstatic int ephyrGetStill (KdScreenInfo *a_info, 171706f2543Smrg DrawablePtr a_drawable, 172706f2543Smrg short a_vid_x, short a_vid_y, 173706f2543Smrg short a_drw_x, short a_drw_y, 174706f2543Smrg short a_vid_w, short a_vid_h, 175706f2543Smrg short a_drw_w, short a_drw_h, 176706f2543Smrg RegionPtr a_clip_region, 177706f2543Smrg pointer a_port_priv) ; 178706f2543Smrg 179706f2543Smrgstatic int ephyrQueryImageAttributes (KdScreenInfo *a_info, 180706f2543Smrg int a_id, 181706f2543Smrg unsigned short *a_w, 182706f2543Smrg unsigned short *a_h, 183706f2543Smrg int *a_pitches, 184706f2543Smrg int *a_offsets); 185706f2543Smrgstatic int s_base_port_id ; 186706f2543Smrg 187706f2543Smrg/************** 188706f2543Smrg * <helpers> 189706f2543Smrg * ************/ 190706f2543Smrg 191706f2543Smrgstatic Bool 192706f2543SmrgDoSimpleClip (BoxPtr a_dst_box, 193706f2543Smrg BoxPtr a_clipper, 194706f2543Smrg BoxPtr a_result) 195706f2543Smrg{ 196706f2543Smrg BoxRec dstClippedBox ; 197706f2543Smrg 198706f2543Smrg EPHYR_RETURN_VAL_IF_FAIL (a_dst_box && a_clipper && a_result, FALSE) ; 199706f2543Smrg 200706f2543Smrg /* 201706f2543Smrg * setup the clipbox inside the destination. 202706f2543Smrg */ 203706f2543Smrg dstClippedBox.x1 = a_dst_box->x1 ; 204706f2543Smrg dstClippedBox.x2 = a_dst_box->x2 ; 205706f2543Smrg dstClippedBox.y1 = a_dst_box->y1 ; 206706f2543Smrg dstClippedBox.y2 = a_dst_box->y2 ; 207706f2543Smrg 208706f2543Smrg /* 209706f2543Smrg * if the cliper leftmost edge is inside 210706f2543Smrg * the destination area then the leftmost edge of the resulting 211706f2543Smrg * clipped box is the leftmost edge of the cliper. 212706f2543Smrg */ 213706f2543Smrg if (a_clipper->x1 > dstClippedBox.x1) 214706f2543Smrg dstClippedBox.x1 = a_clipper->x1 ; 215706f2543Smrg 216706f2543Smrg /* 217706f2543Smrg * if the cliper top edge is inside the destination area 218706f2543Smrg * then the bottom horizontal edge of the resulting clipped box 219706f2543Smrg * is the bottom edge of the cliper 220706f2543Smrg */ 221706f2543Smrg if (a_clipper->y1 > dstClippedBox.y1) 222706f2543Smrg dstClippedBox.y1 = a_clipper->y1 ; 223706f2543Smrg 224706f2543Smrg /*ditto for right edge*/ 225706f2543Smrg if (a_clipper->x2 < dstClippedBox.x2) 226706f2543Smrg dstClippedBox.x2 = a_clipper->x2 ; 227706f2543Smrg 228706f2543Smrg /*ditto for bottom edge*/ 229706f2543Smrg if (a_clipper->y2 < dstClippedBox.y2) 230706f2543Smrg dstClippedBox.y2 = a_clipper->y2 ; 231706f2543Smrg 232706f2543Smrg memcpy (a_result, &dstClippedBox, sizeof (dstClippedBox)) ; 233706f2543Smrg return TRUE ; 234706f2543Smrg} 235706f2543Smrg 236706f2543Smrgstatic Bool 237706f2543SmrgephyrLocalAtomToHost (int a_local_atom, int *a_host_atom) 238706f2543Smrg{ 239706f2543Smrg const char *atom_name=NULL; 240706f2543Smrg int host_atom=None ; 241706f2543Smrg 242706f2543Smrg EPHYR_RETURN_VAL_IF_FAIL (a_host_atom, FALSE) ; 243706f2543Smrg 244706f2543Smrg if (!ValidAtom (a_local_atom)) 245706f2543Smrg return FALSE ; 246706f2543Smrg 247706f2543Smrg atom_name = NameForAtom (a_local_atom) ; 248706f2543Smrg 249706f2543Smrg if (!atom_name) 250706f2543Smrg return FALSE ; 251706f2543Smrg 252706f2543Smrg if (!ephyrHostGetAtom (atom_name, FALSE, &host_atom) || host_atom == None) { 253706f2543Smrg EPHYR_LOG_ERROR ("no atom for string %s defined in host X\n", 254706f2543Smrg atom_name) ; 255706f2543Smrg return FALSE ; 256706f2543Smrg } 257706f2543Smrg *a_host_atom = host_atom ; 258706f2543Smrg return TRUE ; 259706f2543Smrg} 260706f2543Smrg 261706f2543Smrg/* 262706f2543Smrg Not used yed. 263706f2543Smrgstatic Bool 264706f2543SmrgephyrHostAtomToLocal (int a_host_atom, int *a_local_atom) 265706f2543Smrg{ 266706f2543Smrg Bool is_ok=FALSE ; 267706f2543Smrg char *atom_name=NULL ; 268706f2543Smrg int atom=None ; 269706f2543Smrg 270706f2543Smrg EPHYR_RETURN_VAL_IF_FAIL (a_local_atom, FALSE) ; 271706f2543Smrg 272706f2543Smrg atom_name = ephyrHostGetAtomName (a_host_atom) ; 273706f2543Smrg if (!atom_name) 274706f2543Smrg goto out ; 275706f2543Smrg 276706f2543Smrg atom = MakeAtom (atom_name, strlen (atom_name), TRUE) ; 277706f2543Smrg if (atom == None) 278706f2543Smrg goto out ; 279706f2543Smrg 280706f2543Smrg *a_local_atom = atom ; 281706f2543Smrg is_ok = TRUE ; 282706f2543Smrg 283706f2543Smrgout: 284706f2543Smrg if (atom_name) { 285706f2543Smrg ephyrHostFree (atom_name) ; 286706f2543Smrg } 287706f2543Smrg return is_ok ; 288706f2543Smrg} 289706f2543Smrg*/ 290706f2543Smrg 291706f2543Smrg/************** 292706f2543Smrg *</helpers> 293706f2543Smrg * ************/ 294706f2543Smrg 295706f2543SmrgBool 296706f2543SmrgephyrInitVideo (ScreenPtr pScreen) 297706f2543Smrg{ 298706f2543Smrg Bool is_ok = FALSE ; 299706f2543Smrg KdScreenPriv(pScreen); 300706f2543Smrg KdScreenInfo *screen = pScreenPriv->screen; 301706f2543Smrg static EphyrXVPriv *xv_priv; 302706f2543Smrg 303706f2543Smrg EPHYR_LOG ("enter\n") ; 304706f2543Smrg 305706f2543Smrg if (screen->fb.bitsPerPixel == 8) { 306706f2543Smrg EPHYR_LOG_ERROR ("8 bits depth not supported\n") ; 307706f2543Smrg return FALSE ; 308706f2543Smrg } 309706f2543Smrg 310706f2543Smrg if (!xv_priv) { 311706f2543Smrg xv_priv = ephyrXVPrivNew () ; 312706f2543Smrg } 313706f2543Smrg if (!xv_priv) { 314706f2543Smrg EPHYR_LOG_ERROR ("failed to create xv_priv\n") ; 315706f2543Smrg goto out ; 316706f2543Smrg } 317706f2543Smrg 318706f2543Smrg if (!ephyrXVPrivRegisterAdaptors (xv_priv, pScreen)) { 319706f2543Smrg EPHYR_LOG_ERROR ("failed to register adaptors\n") ; 320706f2543Smrg goto out ; 321706f2543Smrg } 322706f2543Smrg is_ok = TRUE ; 323706f2543Smrg 324706f2543Smrgout: 325706f2543Smrg return is_ok ; 326706f2543Smrg} 327706f2543Smrg 328706f2543Smrgstatic EphyrXVPriv* 329706f2543SmrgephyrXVPrivNew (void) 330706f2543Smrg{ 331706f2543Smrg EphyrXVPriv *xv_priv=NULL ; 332706f2543Smrg 333706f2543Smrg EPHYR_LOG ("enter\n") ; 334706f2543Smrg 335706f2543Smrg xv_priv = calloc(1, sizeof (EphyrXVPriv)) ; 336706f2543Smrg if (!xv_priv) { 337706f2543Smrg EPHYR_LOG_ERROR ("failed to create EphyrXVPriv\n") ; 338706f2543Smrg goto error ; 339706f2543Smrg } 340706f2543Smrg 341706f2543Smrg ephyrHostXVInit () ; 342706f2543Smrg 343706f2543Smrg if (!ephyrXVPrivQueryHostAdaptors (xv_priv)) { 344706f2543Smrg EPHYR_LOG_ERROR ("failed to query the host x for xv properties\n") ; 345706f2543Smrg goto error ; 346706f2543Smrg } 347706f2543Smrg if (!ephyrXVPrivSetAdaptorsHooks (xv_priv)) { 348706f2543Smrg EPHYR_LOG_ERROR ("failed to set xv_priv hooks\n") ; 349706f2543Smrg goto error ; 350706f2543Smrg } 351706f2543Smrg 352706f2543Smrg EPHYR_LOG ("leave\n") ; 353706f2543Smrg return xv_priv ; 354706f2543Smrg 355706f2543Smrgerror: 356706f2543Smrg if (xv_priv) { 357706f2543Smrg ephyrXVPrivDelete (xv_priv) ; 358706f2543Smrg xv_priv = NULL ; 359706f2543Smrg } 360706f2543Smrg return NULL ; 361706f2543Smrg} 362706f2543Smrg 363706f2543Smrgstatic void 364706f2543SmrgephyrXVPrivDelete (EphyrXVPriv *a_this) 365706f2543Smrg{ 366706f2543Smrg EPHYR_LOG ("enter\n") ; 367706f2543Smrg 368706f2543Smrg if (!a_this) 369706f2543Smrg return ; 370706f2543Smrg if (a_this->host_adaptors) { 371706f2543Smrg ephyrHostXVAdaptorArrayDelete (a_this->host_adaptors) ; 372706f2543Smrg a_this->host_adaptors = NULL ; 373706f2543Smrg } 374706f2543Smrg free(a_this->adaptors) ; 375706f2543Smrg a_this->adaptors = NULL ; 376706f2543Smrg free(a_this) ; 377706f2543Smrg EPHYR_LOG ("leave\n") ; 378706f2543Smrg} 379706f2543Smrg 380706f2543Smrgstatic KdVideoEncodingPtr 381706f2543SmrgvideoEncodingDup (EphyrHostEncoding *a_encodings, 382706f2543Smrg int a_num_encodings) 383706f2543Smrg{ 384706f2543Smrg KdVideoEncodingPtr result = NULL ; 385706f2543Smrg int i=0 ; 386706f2543Smrg 387706f2543Smrg EPHYR_RETURN_VAL_IF_FAIL (a_encodings && a_num_encodings, NULL) ; 388706f2543Smrg 389706f2543Smrg result = calloc(a_num_encodings, sizeof (KdVideoEncodingRec)) ; 390706f2543Smrg for (i=0 ; i < a_num_encodings; i++) { 391706f2543Smrg result[i].id = a_encodings[i].id ; 392706f2543Smrg result[i].name = strdup (a_encodings[i].name) ; 393706f2543Smrg result[i].width = a_encodings[i].width ; 394706f2543Smrg result[i].height = a_encodings[i].height ; 395706f2543Smrg result[i].rate.numerator = a_encodings[i].rate.numerator ; 396706f2543Smrg result[i].rate.denominator = a_encodings[i].rate.denominator ; 397706f2543Smrg } 398706f2543Smrg return result ; 399706f2543Smrg} 400706f2543Smrg 401706f2543Smrgstatic KdAttributePtr 402706f2543SmrgportAttributesDup (EphyrHostAttribute *a_encodings, 403706f2543Smrg int a_num_encodings) 404706f2543Smrg{ 405706f2543Smrg int i=0 ; 406706f2543Smrg KdAttributePtr result=NULL ; 407706f2543Smrg 408706f2543Smrg EPHYR_RETURN_VAL_IF_FAIL (a_encodings && a_num_encodings, NULL) ; 409706f2543Smrg 410706f2543Smrg result = calloc(a_num_encodings, sizeof (KdAttributeRec)) ; 411706f2543Smrg if (!result) { 412706f2543Smrg EPHYR_LOG_ERROR ("failed to allocate attributes\n") ; 413706f2543Smrg return NULL ; 414706f2543Smrg } 415706f2543Smrg for (i=0; i < a_num_encodings; i++) { 416706f2543Smrg result[i].flags = a_encodings[i].flags ; 417706f2543Smrg result[i].min_value = a_encodings[i].min_value ; 418706f2543Smrg result[i].max_value = a_encodings[i].max_value ; 419706f2543Smrg result[i].name = strdup (a_encodings[i].name) ; 420706f2543Smrg } 421706f2543Smrg return result ; 422706f2543Smrg} 423706f2543Smrg 424706f2543Smrgstatic Bool 425706f2543SmrgephyrXVPrivQueryHostAdaptors (EphyrXVPriv *a_this) 426706f2543Smrg{ 427706f2543Smrg EphyrHostXVAdaptor *cur_host_adaptor=NULL ; 428706f2543Smrg EphyrHostVideoFormat *video_formats=NULL ; 429706f2543Smrg EphyrHostEncoding *encodings=NULL ; 430706f2543Smrg EphyrHostAttribute *attributes=NULL ; 431706f2543Smrg EphyrHostImageFormat *image_formats=NULL ; 432706f2543Smrg int num_video_formats=0, base_port_id=0, 433706f2543Smrg num_attributes=0, num_formats=0, i=0, 434706f2543Smrg port_priv_offset=0; 435706f2543Smrg unsigned num_encodings=0 ; 436706f2543Smrg Bool is_ok = FALSE ; 437706f2543Smrg 438706f2543Smrg EPHYR_RETURN_VAL_IF_FAIL (a_this, FALSE) ; 439706f2543Smrg 440706f2543Smrg EPHYR_LOG ("enter\n") ; 441706f2543Smrg 442706f2543Smrg if (!ephyrHostXVQueryAdaptors (&a_this->host_adaptors)) { 443706f2543Smrg EPHYR_LOG_ERROR ("failed to query host adaptors\n") ; 444706f2543Smrg goto out ; 445706f2543Smrg } 446706f2543Smrg if (a_this->host_adaptors) 447706f2543Smrg a_this->num_adaptors = 448706f2543Smrg ephyrHostXVAdaptorArrayGetSize (a_this->host_adaptors) ; 449706f2543Smrg if (a_this->num_adaptors < 0) { 450706f2543Smrg EPHYR_LOG_ERROR ("failed to get number of host adaptors\n") ; 451706f2543Smrg goto out ; 452706f2543Smrg } 453706f2543Smrg EPHYR_LOG ("host has %d adaptors\n", a_this->num_adaptors) ; 454706f2543Smrg /* 455706f2543Smrg * copy what we can from adaptors into a_this->adaptors 456706f2543Smrg */ 457706f2543Smrg if (a_this->num_adaptors) { 458706f2543Smrg a_this->adaptors = calloc(a_this->num_adaptors, 459706f2543Smrg sizeof (KdVideoAdaptorRec)) ; 460706f2543Smrg if (!a_this->adaptors) { 461706f2543Smrg EPHYR_LOG_ERROR ("failed to create internal adaptors\n") ; 462706f2543Smrg goto out ; 463706f2543Smrg } 464706f2543Smrg } 465706f2543Smrg for (i=0; i < a_this->num_adaptors; i++) { 466706f2543Smrg int j=0 ; 467706f2543Smrg cur_host_adaptor = 468706f2543Smrg ephyrHostXVAdaptorArrayAt (a_this->host_adaptors, i) ; 469706f2543Smrg if (!cur_host_adaptor) 470706f2543Smrg continue ; 471706f2543Smrg a_this->adaptors[i].nPorts = 472706f2543Smrg ephyrHostXVAdaptorGetNbPorts (cur_host_adaptor) ; 473706f2543Smrg if (a_this->adaptors[i].nPorts <=0) { 474706f2543Smrg EPHYR_LOG_ERROR ("Could not find any port of adaptor %d\n", i) ; 475706f2543Smrg continue ; 476706f2543Smrg } 477706f2543Smrg a_this->adaptors[i].type = 478706f2543Smrg ephyrHostXVAdaptorGetType (cur_host_adaptor) ; 479706f2543Smrg a_this->adaptors[i].type |= XvWindowMask ; 480706f2543Smrg a_this->adaptors[i].flags = 481706f2543Smrg VIDEO_OVERLAID_IMAGES | VIDEO_CLIP_TO_VIEWPORT; 482706f2543Smrg if (ephyrHostXVAdaptorGetName (cur_host_adaptor)) 483706f2543Smrg a_this->adaptors[i].name = 484706f2543Smrg strdup (ephyrHostXVAdaptorGetName (cur_host_adaptor)) ; 485706f2543Smrg else 486706f2543Smrg a_this->adaptors[i].name = strdup ("Xephyr Video Overlay"); 487706f2543Smrg base_port_id = ephyrHostXVAdaptorGetFirstPortID (cur_host_adaptor) ; 488706f2543Smrg if (base_port_id < 0) { 489706f2543Smrg EPHYR_LOG_ERROR ("failed to get port id for adaptor %d\n", i) ; 490706f2543Smrg continue ; 491706f2543Smrg } 492706f2543Smrg if (!s_base_port_id) 493706f2543Smrg s_base_port_id = base_port_id ; 494706f2543Smrg 495706f2543Smrg if (!ephyrHostXVQueryEncodings (base_port_id, 496706f2543Smrg &encodings, 497706f2543Smrg &num_encodings)) { 498706f2543Smrg EPHYR_LOG_ERROR ("failed to get encodings for port port id %d," 499706f2543Smrg " adaptors %d\n", 500706f2543Smrg base_port_id, i) ; 501706f2543Smrg continue ; 502706f2543Smrg } 503706f2543Smrg a_this->adaptors[i].nEncodings = num_encodings ; 504706f2543Smrg a_this->adaptors[i].pEncodings = 505706f2543Smrg videoEncodingDup (encodings, num_encodings) ; 506706f2543Smrg video_formats = (EphyrHostVideoFormat*) 507706f2543Smrg ephyrHostXVAdaptorGetVideoFormats (cur_host_adaptor, 508706f2543Smrg &num_video_formats); 509706f2543Smrg a_this->adaptors[i].pFormats = (KdVideoFormatPtr) video_formats ; 510706f2543Smrg a_this->adaptors[i].nFormats = num_video_formats ; 511706f2543Smrg /* got a_this->adaptors[i].nPorts already 512706f2543Smrg a_this->adaptors[i].nPorts = 513706f2543Smrg ephyrHostXVAdaptorGetNbPorts (cur_host_adaptor) ; 514706f2543Smrg */ 515706f2543Smrg a_this->adaptors[i].pPortPrivates = 516706f2543Smrg calloc(a_this->adaptors[i].nPorts, 517706f2543Smrg sizeof (DevUnion) + sizeof (EphyrPortPriv)) ; 518706f2543Smrg port_priv_offset = a_this->adaptors[i].nPorts; 519706f2543Smrg for (j=0; j < a_this->adaptors[i].nPorts; j++) { 520706f2543Smrg EphyrPortPriv *port_privs_base = 521706f2543Smrg (EphyrPortPriv*)&a_this->adaptors[i].pPortPrivates[port_priv_offset]; 522706f2543Smrg EphyrPortPriv *port_priv = &port_privs_base[j] ; 523706f2543Smrg port_priv->port_number = base_port_id + j; 524706f2543Smrg port_priv->current_adaptor = &a_this->adaptors[i] ; 525706f2543Smrg port_priv->xv_priv = a_this ; 526706f2543Smrg a_this->adaptors[i].pPortPrivates[j].ptr = port_priv; 527706f2543Smrg } 528706f2543Smrg if (!ephyrHostXVQueryPortAttributes (base_port_id, 529706f2543Smrg &attributes, 530706f2543Smrg &num_attributes)) { 531706f2543Smrg EPHYR_LOG_ERROR ("failed to get port attribute " 532706f2543Smrg "for adaptor %d\n", i) ; 533706f2543Smrg continue ; 534706f2543Smrg } 535706f2543Smrg a_this->adaptors[i].pAttributes = 536706f2543Smrg portAttributesDup (attributes, num_attributes); 537706f2543Smrg a_this->adaptors[i].nAttributes = num_attributes ; 538706f2543Smrg /*make sure atoms of attrs names are created in xephyr*/ 539706f2543Smrg for (j=0; j < a_this->adaptors[i].nAttributes; j++) { 540706f2543Smrg if (a_this->adaptors[i].pAttributes[j].name) 541706f2543Smrg MakeAtom (a_this->adaptors[i].pAttributes[j].name, 542706f2543Smrg strlen (a_this->adaptors[i].pAttributes[j].name), 543706f2543Smrg TRUE) ; 544706f2543Smrg } 545706f2543Smrg if (!ephyrHostXVQueryImageFormats (base_port_id, 546706f2543Smrg &image_formats, 547706f2543Smrg &num_formats)) { 548706f2543Smrg EPHYR_LOG_ERROR ("failed to get image formats " 549706f2543Smrg "for adaptor %d\n", i) ; 550706f2543Smrg continue ; 551706f2543Smrg } 552706f2543Smrg a_this->adaptors[i].pImages = (KdImagePtr) image_formats ; 553706f2543Smrg a_this->adaptors[i].nImages = num_formats ; 554706f2543Smrg } 555706f2543Smrg is_ok = TRUE ; 556706f2543Smrg 557706f2543Smrgout: 558706f2543Smrg if (encodings) { 559706f2543Smrg ephyrHostEncodingsDelete (encodings, num_encodings) ; 560706f2543Smrg encodings = NULL ; 561706f2543Smrg } 562706f2543Smrg if (attributes) { 563706f2543Smrg ephyrHostAttributesDelete (attributes) ; 564706f2543Smrg attributes = NULL ; 565706f2543Smrg } 566706f2543Smrg EPHYR_LOG ("leave\n") ; 567706f2543Smrg return is_ok ; 568706f2543Smrg} 569706f2543Smrg 570706f2543Smrgstatic Bool 571706f2543SmrgephyrXVPrivSetAdaptorsHooks (EphyrXVPriv *a_this) 572706f2543Smrg{ 573706f2543Smrg int i=0 ; 574706f2543Smrg Bool has_it=FALSE ; 575706f2543Smrg EphyrHostXVAdaptor *cur_host_adaptor=NULL ; 576706f2543Smrg 577706f2543Smrg EPHYR_RETURN_VAL_IF_FAIL (a_this, FALSE) ; 578706f2543Smrg 579706f2543Smrg EPHYR_LOG ("enter\n") ; 580706f2543Smrg 581706f2543Smrg for (i=0; i < a_this->num_adaptors; i++) { 582706f2543Smrg a_this->adaptors[i].ReputImage = ephyrReputImage ; 583706f2543Smrg a_this->adaptors[i].StopVideo = ephyrStopVideo ; 584706f2543Smrg a_this->adaptors[i].SetPortAttribute = ephyrSetPortAttribute ; 585706f2543Smrg a_this->adaptors[i].GetPortAttribute = ephyrGetPortAttribute ; 586706f2543Smrg a_this->adaptors[i].QueryBestSize = ephyrQueryBestSize ; 587706f2543Smrg a_this->adaptors[i].QueryImageAttributes = ephyrQueryImageAttributes ; 588706f2543Smrg 589706f2543Smrg cur_host_adaptor = 590706f2543Smrg ephyrHostXVAdaptorArrayAt (a_this->host_adaptors, i) ; 591706f2543Smrg if (!cur_host_adaptor) { 592706f2543Smrg EPHYR_LOG_ERROR ("failed to get host adaptor at index %d\n", i) ; 593706f2543Smrg continue ; 594706f2543Smrg } 595706f2543Smrg has_it = FALSE ; 596706f2543Smrg if (!ephyrHostXVAdaptorHasPutImage (cur_host_adaptor, &has_it)) { 597706f2543Smrg EPHYR_LOG_ERROR ("error\n") ; 598706f2543Smrg } 599706f2543Smrg if (has_it) { 600706f2543Smrg a_this->adaptors[i].PutImage = ephyrPutImage; 601706f2543Smrg } 602706f2543Smrg 603706f2543Smrg has_it = FALSE ; 604706f2543Smrg if (!ephyrHostXVAdaptorHasPutVideo (cur_host_adaptor, &has_it)) { 605706f2543Smrg EPHYR_LOG_ERROR ("error\n") ; 606706f2543Smrg } 607706f2543Smrg if (has_it) { 608706f2543Smrg a_this->adaptors[i].PutVideo = ephyrPutVideo; 609706f2543Smrg } 610706f2543Smrg 611706f2543Smrg has_it = FALSE ; 612706f2543Smrg if (!ephyrHostXVAdaptorHasGetVideo (cur_host_adaptor, &has_it)) { 613706f2543Smrg EPHYR_LOG_ERROR ("error\n") ; 614706f2543Smrg } 615706f2543Smrg if (has_it) { 616706f2543Smrg a_this->adaptors[i].GetVideo = ephyrGetVideo; 617706f2543Smrg } 618706f2543Smrg 619706f2543Smrg has_it = FALSE ; 620706f2543Smrg if (!ephyrHostXVAdaptorHasPutStill (cur_host_adaptor, &has_it)) { 621706f2543Smrg EPHYR_LOG_ERROR ("error\n") ; 622706f2543Smrg } 623706f2543Smrg if (has_it) { 624706f2543Smrg a_this->adaptors[i].PutStill = ephyrPutStill; 625706f2543Smrg } 626706f2543Smrg 627706f2543Smrg has_it = FALSE ; 628706f2543Smrg if (!ephyrHostXVAdaptorHasGetStill (cur_host_adaptor, &has_it)) { 629706f2543Smrg EPHYR_LOG_ERROR ("error\n") ; 630706f2543Smrg } 631706f2543Smrg if (has_it) { 632706f2543Smrg a_this->adaptors[i].GetStill = ephyrGetStill; 633706f2543Smrg } 634706f2543Smrg } 635706f2543Smrg EPHYR_LOG ("leave\n") ; 636706f2543Smrg return TRUE ; 637706f2543Smrg} 638706f2543Smrg 639706f2543Smrgstatic Bool 640706f2543SmrgephyrXVPrivRegisterAdaptors (EphyrXVPriv *a_this, 641706f2543Smrg ScreenPtr a_screen) 642706f2543Smrg{ 643706f2543Smrg KdScreenPriv(a_screen); 644706f2543Smrg KdScreenInfo *screen = pScreenPriv->screen; 645706f2543Smrg Bool is_ok = FALSE ; 646706f2543Smrg KdVideoAdaptorPtr *adaptors=NULL, *registered_adaptors=NULL ; 647706f2543Smrg int num_registered_adaptors=0, i=0, num_adaptors=0 ; 648706f2543Smrg 649706f2543Smrg EPHYR_RETURN_VAL_IF_FAIL (a_this && a_screen, FALSE) ; 650706f2543Smrg 651706f2543Smrg EPHYR_LOG ("enter\n") ; 652706f2543Smrg 653706f2543Smrg if (!a_this->num_adaptors) 654706f2543Smrg goto out ; 655706f2543Smrg num_registered_adaptors = 656706f2543Smrg KdXVListGenericAdaptors (screen, ®istered_adaptors); 657706f2543Smrg 658706f2543Smrg num_adaptors = num_registered_adaptors + a_this->num_adaptors ; 659706f2543Smrg adaptors = calloc(num_adaptors, sizeof (KdVideoAdaptorPtr)) ; 660706f2543Smrg if (!adaptors) { 661706f2543Smrg EPHYR_LOG_ERROR ("failed to allocate adaptors tab\n") ; 662706f2543Smrg goto out ; 663706f2543Smrg } 664706f2543Smrg memmove (adaptors, registered_adaptors, num_registered_adaptors) ; 665706f2543Smrg for (i=0 ; i < a_this->num_adaptors; i++) { 666706f2543Smrg *(adaptors + num_registered_adaptors + i) = &a_this->adaptors[i] ; 667706f2543Smrg } 668706f2543Smrg if (!KdXVScreenInit (a_screen, adaptors, num_adaptors)) { 669706f2543Smrg EPHYR_LOG_ERROR ("failed to register adaptors\n"); 670706f2543Smrg goto out ; 671706f2543Smrg } 672706f2543Smrg EPHYR_LOG ("there are %d registered adaptors\n", num_adaptors) ; 673706f2543Smrg is_ok = TRUE ; 674706f2543Smrg 675706f2543Smrgout: 676706f2543Smrg free(registered_adaptors) ; 677706f2543Smrg registered_adaptors = NULL ; 678706f2543Smrg free(adaptors) ; 679706f2543Smrg adaptors = NULL ; 680706f2543Smrg 681706f2543Smrg EPHYR_LOG ("leave\n") ; 682706f2543Smrg return is_ok ; 683706f2543Smrg} 684706f2543Smrg 685706f2543Smrgstatic Bool 686706f2543SmrgephyrXVPrivIsAttrValueValid (KdAttributePtr a_attrs, 687706f2543Smrg int a_attrs_len, 688706f2543Smrg const char *a_attr_name, 689706f2543Smrg int a_attr_value, 690706f2543Smrg Bool *a_is_valid) 691706f2543Smrg{ 692706f2543Smrg int i=0 ; 693706f2543Smrg 694706f2543Smrg EPHYR_RETURN_VAL_IF_FAIL (a_attrs && a_attr_name && a_is_valid, 695706f2543Smrg FALSE) ; 696706f2543Smrg 697706f2543Smrg for (i=0; i < a_attrs_len; i++) { 698706f2543Smrg if (a_attrs[i].name && strcmp (a_attrs[i].name, a_attr_name)) 699706f2543Smrg continue ; 700706f2543Smrg if (a_attrs[i].min_value > a_attr_value || 701706f2543Smrg a_attrs[i].max_value < a_attr_value) { 702706f2543Smrg *a_is_valid = FALSE ; 703706f2543Smrg EPHYR_LOG_ERROR ("attribute was not valid\n" 704706f2543Smrg "value:%d. min:%d. max:%d\n", 705706f2543Smrg a_attr_value, 706706f2543Smrg a_attrs[i].min_value, 707706f2543Smrg a_attrs[i].max_value) ; 708706f2543Smrg } else { 709706f2543Smrg *a_is_valid = TRUE ; 710706f2543Smrg } 711706f2543Smrg return TRUE ; 712706f2543Smrg } 713706f2543Smrg return FALSE ; 714706f2543Smrg} 715706f2543Smrg 716706f2543Smrgstatic Bool 717706f2543SmrgephyrXVPrivGetImageBufSize (int a_port_id, 718706f2543Smrg int a_image_id, 719706f2543Smrg unsigned short a_width, 720706f2543Smrg unsigned short a_height, 721706f2543Smrg int *a_size) 722706f2543Smrg{ 723706f2543Smrg Bool is_ok=FALSE ; 724706f2543Smrg unsigned short width=a_width, height=a_height ; 725706f2543Smrg 726706f2543Smrg EPHYR_RETURN_VAL_IF_FAIL (a_size, FALSE) ; 727706f2543Smrg 728706f2543Smrg EPHYR_LOG ("enter\n") ; 729706f2543Smrg 730706f2543Smrg if (!ephyrHostXVQueryImageAttributes (a_port_id, a_image_id, 731706f2543Smrg &width, &height, a_size, NULL, NULL)) { 732706f2543Smrg EPHYR_LOG_ERROR ("failed to get image attributes\n") ; 733706f2543Smrg goto out ; 734706f2543Smrg } 735706f2543Smrg is_ok = TRUE ; 736706f2543Smrg 737706f2543Smrgout: 738706f2543Smrg EPHYR_LOG ("leave\n") ; 739706f2543Smrg return is_ok ; 740706f2543Smrg} 741706f2543Smrg 742706f2543Smrgstatic Bool 743706f2543SmrgephyrXVPrivSaveImageToPortPriv (EphyrPortPriv *a_port_priv, 744706f2543Smrg const unsigned char *a_image_buf, 745706f2543Smrg int a_image_len) 746706f2543Smrg{ 747706f2543Smrg Bool is_ok=FALSE ; 748706f2543Smrg 749706f2543Smrg EPHYR_LOG ("enter\n") ; 750706f2543Smrg 751706f2543Smrg if (a_port_priv->image_buf_size < a_image_len) { 752706f2543Smrg unsigned char *buf=NULL ; 753706f2543Smrg buf = realloc (a_port_priv->image_buf, a_image_len) ; 754706f2543Smrg if (!buf) { 755706f2543Smrg EPHYR_LOG_ERROR ("failed to realloc image buffer\n") ; 756706f2543Smrg goto out ; 757706f2543Smrg } 758706f2543Smrg a_port_priv->image_buf = buf ; 759706f2543Smrg a_port_priv->image_buf_size = a_image_len; 760706f2543Smrg } 761706f2543Smrg memmove (a_port_priv->image_buf, a_image_buf, a_image_len) ; 762706f2543Smrg is_ok = TRUE ; 763706f2543Smrg 764706f2543Smrgout: 765706f2543Smrg return is_ok ; 766706f2543Smrg EPHYR_LOG ("leave\n") ; 767706f2543Smrg} 768706f2543Smrg 769706f2543Smrgstatic void 770706f2543SmrgephyrStopVideo (KdScreenInfo *a_info, pointer a_port_priv, Bool a_exit) 771706f2543Smrg{ 772706f2543Smrg EphyrPortPriv *port_priv = a_port_priv ; 773706f2543Smrg 774706f2543Smrg EPHYR_RETURN_IF_FAIL (a_info && a_info->pScreen) ; 775706f2543Smrg EPHYR_RETURN_IF_FAIL (port_priv) ; 776706f2543Smrg 777706f2543Smrg EPHYR_LOG ("enter\n") ; 778706f2543Smrg if (!ephyrHostXVStopVideo (a_info->pScreen->myNum, 779706f2543Smrg port_priv->port_number)) { 780706f2543Smrg EPHYR_LOG_ERROR ("XvStopVideo() failed\n") ; 781706f2543Smrg } 782706f2543Smrg EPHYR_LOG ("leave\n") ; 783706f2543Smrg} 784706f2543Smrg 785706f2543Smrgstatic int 786706f2543SmrgephyrSetPortAttribute (KdScreenInfo *a_info, 787706f2543Smrg Atom a_attr_name, 788706f2543Smrg int a_attr_value, 789706f2543Smrg pointer a_port_priv) 790706f2543Smrg{ 791706f2543Smrg int res=Success, host_atom=0 ; 792706f2543Smrg EphyrPortPriv *port_priv = a_port_priv ; 793706f2543Smrg Bool is_attr_valid=FALSE ; 794706f2543Smrg 795706f2543Smrg EPHYR_RETURN_VAL_IF_FAIL (port_priv, BadMatch) ; 796706f2543Smrg EPHYR_RETURN_VAL_IF_FAIL (port_priv->current_adaptor, BadMatch) ; 797706f2543Smrg EPHYR_RETURN_VAL_IF_FAIL (port_priv->current_adaptor->pAttributes, 798706f2543Smrg BadMatch) ; 799706f2543Smrg EPHYR_RETURN_VAL_IF_FAIL (port_priv->current_adaptor->nAttributes, 800706f2543Smrg BadMatch) ; 801706f2543Smrg EPHYR_RETURN_VAL_IF_FAIL (ValidAtom (a_attr_name), BadMatch) ; 802706f2543Smrg 803706f2543Smrg EPHYR_LOG ("enter, portnum:%d, atomid:%d, attr_name:%s, attr_val:%d\n", 804706f2543Smrg port_priv->port_number, 805706f2543Smrg (int)a_attr_name, 806706f2543Smrg NameForAtom (a_attr_name), 807706f2543Smrg a_attr_value) ; 808706f2543Smrg 809706f2543Smrg if (!ephyrLocalAtomToHost (a_attr_name, &host_atom)) { 810706f2543Smrg EPHYR_LOG_ERROR ("failed to convert local atom to host atom\n") ; 811706f2543Smrg res = BadMatch ; 812706f2543Smrg goto out ; 813706f2543Smrg } 814706f2543Smrg 815706f2543Smrg if (!ephyrXVPrivIsAttrValueValid (port_priv->current_adaptor->pAttributes, 816706f2543Smrg port_priv->current_adaptor->nAttributes, 817706f2543Smrg NameForAtom (a_attr_name), 818706f2543Smrg a_attr_value, 819706f2543Smrg &is_attr_valid)) { 820706f2543Smrg EPHYR_LOG_ERROR ("failed to validate attribute %s\n", 821706f2543Smrg NameForAtom (a_attr_name)) ; 822706f2543Smrg /* 823706f2543Smrg res = BadMatch ; 824706f2543Smrg goto out ; 825706f2543Smrg */ 826706f2543Smrg } 827706f2543Smrg if (!is_attr_valid) { 828706f2543Smrg EPHYR_LOG_ERROR ("attribute %s is not valid\n", 829706f2543Smrg NameForAtom (a_attr_name)) ; 830706f2543Smrg /* 831706f2543Smrg res = BadMatch ; 832706f2543Smrg goto out ; 833706f2543Smrg */ 834706f2543Smrg } 835706f2543Smrg 836706f2543Smrg if (!ephyrHostXVSetPortAttribute (port_priv->port_number, 837706f2543Smrg host_atom, 838706f2543Smrg a_attr_value)) { 839706f2543Smrg EPHYR_LOG_ERROR ("failed to set port attribute\n") ; 840706f2543Smrg res = BadMatch ; 841706f2543Smrg goto out ; 842706f2543Smrg } 843706f2543Smrg 844706f2543Smrg res = Success ; 845706f2543Smrgout: 846706f2543Smrg EPHYR_LOG ("leave\n") ; 847706f2543Smrg return res ; 848706f2543Smrg} 849706f2543Smrg 850706f2543Smrgstatic int 851706f2543SmrgephyrGetPortAttribute (KdScreenInfo *a_screen_info, 852706f2543Smrg Atom a_attr_name, 853706f2543Smrg int *a_attr_value, 854706f2543Smrg pointer a_port_priv) 855706f2543Smrg{ 856706f2543Smrg int res=Success, host_atom=0 ; 857706f2543Smrg EphyrPortPriv *port_priv = a_port_priv ; 858706f2543Smrg 859706f2543Smrg EPHYR_RETURN_VAL_IF_FAIL (port_priv, BadMatch) ; 860706f2543Smrg EPHYR_RETURN_VAL_IF_FAIL (ValidAtom (a_attr_name), BadMatch) ; 861706f2543Smrg 862706f2543Smrg EPHYR_LOG ("enter, portnum:%d, atomid:%d, attr_name:%s\n", 863706f2543Smrg port_priv->port_number, 864706f2543Smrg (int)a_attr_name, 865706f2543Smrg NameForAtom (a_attr_name)) ; 866706f2543Smrg 867706f2543Smrg if (!ephyrLocalAtomToHost (a_attr_name, &host_atom)) { 868706f2543Smrg EPHYR_LOG_ERROR ("failed to convert local atom to host atom\n") ; 869706f2543Smrg res = BadMatch ; 870706f2543Smrg goto out ; 871706f2543Smrg } 872706f2543Smrg 873706f2543Smrg if (!ephyrHostXVGetPortAttribute (port_priv->port_number, 874706f2543Smrg host_atom, 875706f2543Smrg a_attr_value)) { 876706f2543Smrg EPHYR_LOG_ERROR ("failed to get port attribute\n") ; 877706f2543Smrg res = BadMatch ; 878706f2543Smrg goto out ; 879706f2543Smrg } 880706f2543Smrg 881706f2543Smrg res = Success ; 882706f2543Smrgout: 883706f2543Smrg EPHYR_LOG ("leave\n") ; 884706f2543Smrg return res ; 885706f2543Smrg} 886706f2543Smrg 887706f2543Smrgstatic void 888706f2543SmrgephyrQueryBestSize (KdScreenInfo *a_info, 889706f2543Smrg Bool a_motion, 890706f2543Smrg short a_src_w, 891706f2543Smrg short a_src_h, 892706f2543Smrg short a_drw_w, 893706f2543Smrg short a_drw_h, 894706f2543Smrg unsigned int *a_prefered_w, 895706f2543Smrg unsigned int *a_prefered_h, 896706f2543Smrg pointer a_port_priv) 897706f2543Smrg{ 898706f2543Smrg int res=0 ; 899706f2543Smrg EphyrPortPriv *port_priv = a_port_priv ; 900706f2543Smrg 901706f2543Smrg EPHYR_RETURN_IF_FAIL (port_priv) ; 902706f2543Smrg 903706f2543Smrg EPHYR_LOG ("enter\n") ; 904706f2543Smrg res = ephyrHostXVQueryBestSize (port_priv->port_number, 905706f2543Smrg a_motion, 906706f2543Smrg a_src_w, a_src_h, 907706f2543Smrg a_drw_w, a_drw_h, 908706f2543Smrg a_prefered_w, a_prefered_h) ; 909706f2543Smrg if (!res) { 910706f2543Smrg EPHYR_LOG_ERROR ("Failed to query best size\n") ; 911706f2543Smrg } 912706f2543Smrg EPHYR_LOG ("leave\n") ; 913706f2543Smrg} 914706f2543Smrg 915706f2543Smrgstatic int 916706f2543SmrgephyrPutImage (KdScreenInfo *a_info, 917706f2543Smrg DrawablePtr a_drawable, 918706f2543Smrg short a_src_x, 919706f2543Smrg short a_src_y, 920706f2543Smrg short a_drw_x, 921706f2543Smrg short a_drw_y, 922706f2543Smrg short a_src_w, 923706f2543Smrg short a_src_h, 924706f2543Smrg short a_drw_w, 925706f2543Smrg short a_drw_h, 926706f2543Smrg int a_id, 927706f2543Smrg unsigned char *a_buf, 928706f2543Smrg short a_width, 929706f2543Smrg short a_height, 930706f2543Smrg Bool a_sync, 931706f2543Smrg RegionPtr a_clipping_region, 932706f2543Smrg pointer a_port_priv) 933706f2543Smrg{ 934706f2543Smrg EphyrPortPriv *port_priv = a_port_priv ; 935706f2543Smrg Bool is_ok=FALSE ; 936706f2543Smrg int result=BadImplementation, image_size=0 ; 937706f2543Smrg 938706f2543Smrg EPHYR_RETURN_VAL_IF_FAIL (a_info && a_info->pScreen, BadValue) ; 939706f2543Smrg EPHYR_RETURN_VAL_IF_FAIL (a_drawable, BadValue) ; 940706f2543Smrg 941706f2543Smrg EPHYR_LOG ("enter\n") ; 942706f2543Smrg 943706f2543Smrg if (!ephyrHostXVPutImage (a_info->pScreen->myNum, 944706f2543Smrg port_priv->port_number, 945706f2543Smrg a_id, 946706f2543Smrg a_drw_x, a_drw_y, a_drw_w, a_drw_h, 947706f2543Smrg a_src_x, a_src_y, a_src_w, a_src_h, 948706f2543Smrg a_width, a_height, a_buf, 949706f2543Smrg (EphyrHostBox*)RegionRects (a_clipping_region), 950706f2543Smrg RegionNumRects (a_clipping_region))) { 951706f2543Smrg EPHYR_LOG_ERROR ("EphyrHostXVPutImage() failed\n") ; 952706f2543Smrg goto out ; 953706f2543Smrg } 954706f2543Smrg 955706f2543Smrg /* 956706f2543Smrg * Now save the image so that we can resend it to host it 957706f2543Smrg * later, in ReputImage. 958706f2543Smrg */ 959706f2543Smrg if (!ephyrXVPrivGetImageBufSize (port_priv->port_number, 960706f2543Smrg a_id, a_width, a_height, &image_size)) { 961706f2543Smrg EPHYR_LOG_ERROR ("failed to get image size\n") ; 962706f2543Smrg /*this is a minor error so we won't get bail out abruptly*/ 963706f2543Smrg is_ok = FALSE ; 964706f2543Smrg } else { 965706f2543Smrg is_ok = TRUE ; 966706f2543Smrg } 967706f2543Smrg if (is_ok) { 968706f2543Smrg if (!ephyrXVPrivSaveImageToPortPriv (port_priv, a_buf, image_size)) { 969706f2543Smrg is_ok=FALSE ; 970706f2543Smrg } else { 971706f2543Smrg port_priv->image_id = a_id; 972706f2543Smrg port_priv->drw_x = a_drw_x; 973706f2543Smrg port_priv->drw_y = a_drw_y; 974706f2543Smrg port_priv->drw_w = a_drw_w ; 975706f2543Smrg port_priv->drw_h = a_drw_h ; 976706f2543Smrg port_priv->src_x = a_src_x; 977706f2543Smrg port_priv->src_y = a_src_y ; 978706f2543Smrg port_priv->src_w = a_src_w ; 979706f2543Smrg port_priv->src_h = a_src_h ; 980706f2543Smrg port_priv->image_width = a_width ; 981706f2543Smrg port_priv->image_height = a_height ; 982706f2543Smrg } 983706f2543Smrg } 984706f2543Smrg if (!is_ok) { 985706f2543Smrg if (port_priv->image_buf) { 986706f2543Smrg free (port_priv->image_buf) ; 987706f2543Smrg port_priv->image_buf = NULL ; 988706f2543Smrg port_priv->image_buf_size = 0 ; 989706f2543Smrg } 990706f2543Smrg } 991706f2543Smrg 992706f2543Smrg result = Success ; 993706f2543Smrg 994706f2543Smrgout: 995706f2543Smrg EPHYR_LOG ("leave\n") ; 996706f2543Smrg return result ; 997706f2543Smrg} 998706f2543Smrg 999706f2543Smrgstatic int 1000706f2543SmrgephyrReputImage (KdScreenInfo *a_info, 1001706f2543Smrg DrawablePtr a_drawable, 1002706f2543Smrg short a_drw_x, 1003706f2543Smrg short a_drw_y, 1004706f2543Smrg RegionPtr a_clipping_region, 1005706f2543Smrg pointer a_port_priv) 1006706f2543Smrg{ 1007706f2543Smrg EphyrPortPriv *port_priv = a_port_priv ; 1008706f2543Smrg int result=BadImplementation ; 1009706f2543Smrg 1010706f2543Smrg EPHYR_RETURN_VAL_IF_FAIL (a_info->pScreen, FALSE) ; 1011706f2543Smrg EPHYR_RETURN_VAL_IF_FAIL (a_drawable && port_priv, BadValue) ; 1012706f2543Smrg 1013706f2543Smrg EPHYR_LOG ("enter\n") ; 1014706f2543Smrg 1015706f2543Smrg if (!port_priv->image_buf_size || !port_priv->image_buf) { 1016706f2543Smrg EPHYR_LOG_ERROR ("has null image buf in cache\n") ; 1017706f2543Smrg goto out ; 1018706f2543Smrg } 1019706f2543Smrg if (!ephyrHostXVPutImage (a_info->pScreen->myNum, 1020706f2543Smrg port_priv->port_number, 1021706f2543Smrg port_priv->image_id, 1022706f2543Smrg a_drw_x, a_drw_y, 1023706f2543Smrg port_priv->drw_w, port_priv->drw_h, 1024706f2543Smrg port_priv->src_x, port_priv->src_y, 1025706f2543Smrg port_priv->src_w, port_priv->src_h, 1026706f2543Smrg port_priv->image_width, port_priv->image_height, 1027706f2543Smrg port_priv->image_buf, 1028706f2543Smrg (EphyrHostBox*)RegionRects (a_clipping_region), 1029706f2543Smrg RegionNumRects (a_clipping_region))) { 1030706f2543Smrg EPHYR_LOG_ERROR ("ephyrHostXVPutImage() failed\n") ; 1031706f2543Smrg goto out ; 1032706f2543Smrg } 1033706f2543Smrg 1034706f2543Smrg result = Success ; 1035706f2543Smrg 1036706f2543Smrgout: 1037706f2543Smrg EPHYR_LOG ("leave\n") ; 1038706f2543Smrg return result ; 1039706f2543Smrg} 1040706f2543Smrg 1041706f2543Smrgstatic int 1042706f2543SmrgephyrPutVideo (KdScreenInfo *a_info, 1043706f2543Smrg DrawablePtr a_drawable, 1044706f2543Smrg short a_vid_x, short a_vid_y, 1045706f2543Smrg short a_drw_x, short a_drw_y, 1046706f2543Smrg short a_vid_w, short a_vid_h, 1047706f2543Smrg short a_drw_w, short a_drw_h, 1048706f2543Smrg RegionPtr a_clipping_region, 1049706f2543Smrg pointer a_port_priv) 1050706f2543Smrg{ 1051706f2543Smrg EphyrPortPriv *port_priv = a_port_priv ; 1052706f2543Smrg BoxRec clipped_area, dst_box ; 1053706f2543Smrg int result=BadImplementation ; 1054706f2543Smrg int drw_x=0, drw_y=0, drw_w=0, drw_h=0 ; 1055706f2543Smrg 1056706f2543Smrg EPHYR_RETURN_VAL_IF_FAIL (a_info->pScreen, BadValue) ; 1057706f2543Smrg EPHYR_RETURN_VAL_IF_FAIL (a_drawable && port_priv, BadValue) ; 1058706f2543Smrg 1059706f2543Smrg EPHYR_LOG ("enter\n") ; 1060706f2543Smrg 1061706f2543Smrg dst_box.x1 = a_drw_x ; 1062706f2543Smrg dst_box.x2 = a_drw_x + a_drw_w; 1063706f2543Smrg dst_box.y1 = a_drw_y ; 1064706f2543Smrg dst_box.y2 = a_drw_y + a_drw_h; 1065706f2543Smrg 1066706f2543Smrg if (!DoSimpleClip (&dst_box, 1067706f2543Smrg RegionExtents(a_clipping_region), 1068706f2543Smrg &clipped_area)) { 1069706f2543Smrg EPHYR_LOG_ERROR ("failed to simple clip\n") ; 1070706f2543Smrg goto out ; 1071706f2543Smrg } 1072706f2543Smrg 1073706f2543Smrg drw_x = clipped_area.x1 ; 1074706f2543Smrg drw_y = clipped_area.y1 ; 1075706f2543Smrg drw_w = clipped_area.x2 - clipped_area.x1 ; 1076706f2543Smrg drw_h = clipped_area.y2 - clipped_area.y1 ; 1077706f2543Smrg 1078706f2543Smrg if (!ephyrHostXVPutVideo (a_info->pScreen->myNum, 1079706f2543Smrg port_priv->port_number, 1080706f2543Smrg a_vid_x, a_vid_y, a_vid_w, a_vid_h, 1081706f2543Smrg a_drw_x, a_drw_y, a_drw_w, a_drw_h)) { 1082706f2543Smrg EPHYR_LOG_ERROR ("ephyrHostXVPutVideo() failed\n") ; 1083706f2543Smrg goto out ; 1084706f2543Smrg } 1085706f2543Smrg result = Success ; 1086706f2543Smrg 1087706f2543Smrgout: 1088706f2543Smrg EPHYR_LOG ("leave\n") ; 1089706f2543Smrg return result ; 1090706f2543Smrg} 1091706f2543Smrg 1092706f2543Smrgstatic int 1093706f2543SmrgephyrGetVideo (KdScreenInfo *a_info, 1094706f2543Smrg DrawablePtr a_drawable, 1095706f2543Smrg short a_vid_x, short a_vid_y, 1096706f2543Smrg short a_drw_x, short a_drw_y, 1097706f2543Smrg short a_vid_w, short a_vid_h, 1098706f2543Smrg short a_drw_w, short a_drw_h, 1099706f2543Smrg RegionPtr a_clipping_region, 1100706f2543Smrg pointer a_port_priv) 1101706f2543Smrg{ 1102706f2543Smrg EphyrPortPriv *port_priv = a_port_priv ; 1103706f2543Smrg BoxRec clipped_area, dst_box ; 1104706f2543Smrg int result=BadImplementation ; 1105706f2543Smrg int drw_x=0, drw_y=0, drw_w=0, drw_h=0 ; 1106706f2543Smrg 1107706f2543Smrg EPHYR_RETURN_VAL_IF_FAIL (a_info && a_info->pScreen, BadValue) ; 1108706f2543Smrg EPHYR_RETURN_VAL_IF_FAIL (a_drawable && port_priv, BadValue) ; 1109706f2543Smrg 1110706f2543Smrg EPHYR_LOG ("enter\n") ; 1111706f2543Smrg 1112706f2543Smrg dst_box.x1 = a_drw_x ; 1113706f2543Smrg dst_box.x2 = a_drw_x + a_drw_w; 1114706f2543Smrg dst_box.y1 = a_drw_y ; 1115706f2543Smrg dst_box.y2 = a_drw_y + a_drw_h; 1116706f2543Smrg 1117706f2543Smrg if (!DoSimpleClip (&dst_box, 1118706f2543Smrg RegionExtents(a_clipping_region), 1119706f2543Smrg &clipped_area)) { 1120706f2543Smrg EPHYR_LOG_ERROR ("failed to simple clip\n") ; 1121706f2543Smrg goto out ; 1122706f2543Smrg } 1123706f2543Smrg 1124706f2543Smrg drw_x = clipped_area.x1 ; 1125706f2543Smrg drw_y = clipped_area.y1 ; 1126706f2543Smrg drw_w = clipped_area.x2 - clipped_area.x1 ; 1127706f2543Smrg drw_h = clipped_area.y2 - clipped_area.y1 ; 1128706f2543Smrg 1129706f2543Smrg if (!ephyrHostXVGetVideo (a_info->pScreen->myNum, 1130706f2543Smrg port_priv->port_number, 1131706f2543Smrg a_vid_x, a_vid_y, a_vid_w, a_vid_h, 1132706f2543Smrg a_drw_x, a_drw_y, a_drw_w, a_drw_h)) { 1133706f2543Smrg EPHYR_LOG_ERROR ("ephyrHostXVGetVideo() failed\n") ; 1134706f2543Smrg goto out ; 1135706f2543Smrg } 1136706f2543Smrg result = Success ; 1137706f2543Smrg 1138706f2543Smrgout: 1139706f2543Smrg EPHYR_LOG ("leave\n") ; 1140706f2543Smrg return result ; 1141706f2543Smrg} 1142706f2543Smrg 1143706f2543Smrgstatic int 1144706f2543SmrgephyrPutStill (KdScreenInfo *a_info, 1145706f2543Smrg DrawablePtr a_drawable, 1146706f2543Smrg short a_vid_x, short a_vid_y, 1147706f2543Smrg short a_drw_x, short a_drw_y, 1148706f2543Smrg short a_vid_w, short a_vid_h, 1149706f2543Smrg short a_drw_w, short a_drw_h, 1150706f2543Smrg RegionPtr a_clipping_region, 1151706f2543Smrg pointer a_port_priv) 1152706f2543Smrg{ 1153706f2543Smrg EphyrPortPriv *port_priv = a_port_priv ; 1154706f2543Smrg BoxRec clipped_area, dst_box ; 1155706f2543Smrg int result=BadImplementation ; 1156706f2543Smrg int drw_x=0, drw_y=0, drw_w=0, drw_h=0 ; 1157706f2543Smrg 1158706f2543Smrg EPHYR_RETURN_VAL_IF_FAIL (a_info && a_info->pScreen, BadValue) ; 1159706f2543Smrg EPHYR_RETURN_VAL_IF_FAIL (a_drawable && port_priv, BadValue) ; 1160706f2543Smrg 1161706f2543Smrg EPHYR_LOG ("enter\n") ; 1162706f2543Smrg 1163706f2543Smrg dst_box.x1 = a_drw_x ; 1164706f2543Smrg dst_box.x2 = a_drw_x + a_drw_w; 1165706f2543Smrg dst_box.y1 = a_drw_y ; 1166706f2543Smrg dst_box.y2 = a_drw_y + a_drw_h; 1167706f2543Smrg 1168706f2543Smrg if (!DoSimpleClip (&dst_box, 1169706f2543Smrg RegionExtents(a_clipping_region), 1170706f2543Smrg &clipped_area)) { 1171706f2543Smrg EPHYR_LOG_ERROR ("failed to simple clip\n") ; 1172706f2543Smrg goto out ; 1173706f2543Smrg } 1174706f2543Smrg 1175706f2543Smrg drw_x = clipped_area.x1 ; 1176706f2543Smrg drw_y = clipped_area.y1 ; 1177706f2543Smrg drw_w = clipped_area.x2 - clipped_area.x1 ; 1178706f2543Smrg drw_h = clipped_area.y2 - clipped_area.y1 ; 1179706f2543Smrg 1180706f2543Smrg if (!ephyrHostXVPutStill (a_info->pScreen->myNum, 1181706f2543Smrg port_priv->port_number, 1182706f2543Smrg a_vid_x, a_vid_y, a_vid_w, a_vid_h, 1183706f2543Smrg a_drw_x, a_drw_y, a_drw_w, a_drw_h)) { 1184706f2543Smrg EPHYR_LOG_ERROR ("ephyrHostXVPutStill() failed\n") ; 1185706f2543Smrg goto out ; 1186706f2543Smrg } 1187706f2543Smrg result = Success ; 1188706f2543Smrg 1189706f2543Smrgout: 1190706f2543Smrg EPHYR_LOG ("leave\n") ; 1191706f2543Smrg return result ; 1192706f2543Smrg} 1193706f2543Smrg 1194706f2543Smrgstatic int 1195706f2543SmrgephyrGetStill (KdScreenInfo *a_info, 1196706f2543Smrg DrawablePtr a_drawable, 1197706f2543Smrg short a_vid_x, short a_vid_y, 1198706f2543Smrg short a_drw_x, short a_drw_y, 1199706f2543Smrg short a_vid_w, short a_vid_h, 1200706f2543Smrg short a_drw_w, short a_drw_h, 1201706f2543Smrg RegionPtr a_clipping_region, 1202706f2543Smrg pointer a_port_priv) 1203706f2543Smrg{ 1204706f2543Smrg EphyrPortPriv *port_priv = a_port_priv ; 1205706f2543Smrg BoxRec clipped_area, dst_box ; 1206706f2543Smrg int result=BadImplementation ; 1207706f2543Smrg int drw_x=0, drw_y=0, drw_w=0, drw_h=0 ; 1208706f2543Smrg 1209706f2543Smrg EPHYR_RETURN_VAL_IF_FAIL (a_info && a_info->pScreen, BadValue) ; 1210706f2543Smrg EPHYR_RETURN_VAL_IF_FAIL (a_drawable && port_priv, BadValue) ; 1211706f2543Smrg 1212706f2543Smrg EPHYR_LOG ("enter\n") ; 1213706f2543Smrg 1214706f2543Smrg dst_box.x1 = a_drw_x ; 1215706f2543Smrg dst_box.x2 = a_drw_x + a_drw_w; 1216706f2543Smrg dst_box.y1 = a_drw_y ; 1217706f2543Smrg dst_box.y2 = a_drw_y + a_drw_h; 1218706f2543Smrg 1219706f2543Smrg if (!DoSimpleClip (&dst_box, 1220706f2543Smrg RegionExtents(a_clipping_region), 1221706f2543Smrg &clipped_area)) { 1222706f2543Smrg EPHYR_LOG_ERROR ("failed to simple clip\n") ; 1223706f2543Smrg goto out ; 1224706f2543Smrg } 1225706f2543Smrg 1226706f2543Smrg drw_x = clipped_area.x1 ; 1227706f2543Smrg drw_y = clipped_area.y1 ; 1228706f2543Smrg drw_w = clipped_area.x2 - clipped_area.x1 ; 1229706f2543Smrg drw_h = clipped_area.y2 - clipped_area.y1 ; 1230706f2543Smrg 1231706f2543Smrg if (!ephyrHostXVGetStill (a_info->pScreen->myNum, 1232706f2543Smrg port_priv->port_number, 1233706f2543Smrg a_vid_x, a_vid_y, a_vid_w, a_vid_h, 1234706f2543Smrg a_drw_x, a_drw_y, a_drw_w, a_drw_h)) { 1235706f2543Smrg EPHYR_LOG_ERROR ("ephyrHostXVGetStill() failed\n") ; 1236706f2543Smrg goto out ; 1237706f2543Smrg } 1238706f2543Smrg result = Success ; 1239706f2543Smrg 1240706f2543Smrgout: 1241706f2543Smrg EPHYR_LOG ("leave\n") ; 1242706f2543Smrg return result ; 1243706f2543Smrg} 1244706f2543Smrg 1245706f2543Smrgstatic int 1246706f2543SmrgephyrQueryImageAttributes (KdScreenInfo *a_info, 1247706f2543Smrg int a_id, 1248706f2543Smrg unsigned short *a_w, 1249706f2543Smrg unsigned short *a_h, 1250706f2543Smrg int *a_pitches, 1251706f2543Smrg int *a_offsets) 1252706f2543Smrg{ 1253706f2543Smrg int image_size=0 ; 1254706f2543Smrg 1255706f2543Smrg EPHYR_RETURN_VAL_IF_FAIL (a_w && a_h, FALSE) ; 1256706f2543Smrg 1257706f2543Smrg EPHYR_LOG ("enter: dim (%dx%d), pitches: %p, offsets: %p\n", 1258706f2543Smrg *a_w, *a_h, a_pitches, a_offsets) ; 1259706f2543Smrg 1260706f2543Smrg if (!ephyrHostXVQueryImageAttributes (s_base_port_id, 1261706f2543Smrg a_id, 1262706f2543Smrg a_w, a_h, 1263706f2543Smrg &image_size, 1264706f2543Smrg a_pitches, a_offsets)) { 1265706f2543Smrg EPHYR_LOG_ERROR ("EphyrHostXVQueryImageAttributes() failed\n") ; 1266706f2543Smrg goto out ; 1267706f2543Smrg } 1268706f2543Smrg EPHYR_LOG ("image size: %d, dim (%dx%d)\n", image_size, *a_w, *a_h) ; 1269706f2543Smrg 1270706f2543Smrgout: 1271706f2543Smrg EPHYR_LOG ("leave\n") ; 1272706f2543Smrg return image_size ; 1273706f2543Smrg} 1274