Implement ReputImage and StopVideo
* hw/kdrive/ephyr/ephyrhostvideo.c/h: (ephyrHostXVStopVideo): add this entry point. * hw/kdrive/ephyr/ephyrvideo.c: Basically add ReputImage and StopVideo implementations. Now, when other windows obscur the video window, the reclipping seems to be well handled using StopVideo and ReputImage. To do this, I was obliged to save the frame in PutImage, so that I could resend it un ReputImage.
This commit is contained in:
parent
810dc55866
commit
0b85451449
|
@ -976,3 +976,26 @@ out:
|
||||||
return is_ok ;
|
return is_ok ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Bool
|
||||||
|
ephyrHostXVStopVideo (int a_port_id)
|
||||||
|
{
|
||||||
|
int ret=0 ;
|
||||||
|
Bool is_ok=FALSE ;
|
||||||
|
Display *dpy = hostx_get_display () ;
|
||||||
|
|
||||||
|
EPHYR_RETURN_VAL_IF_FAIL (dpy, FALSE) ;
|
||||||
|
|
||||||
|
EPHYR_LOG ("enter\n") ;
|
||||||
|
|
||||||
|
ret = XvStopVideo (dpy, a_port_id, hostx_get_window ()) ;
|
||||||
|
if (ret != Success) {
|
||||||
|
EPHYR_LOG_ERROR ("XvStopVideo() failed: %d \n", ret) ;
|
||||||
|
goto out ;
|
||||||
|
}
|
||||||
|
is_ok = TRUE ;
|
||||||
|
|
||||||
|
out:
|
||||||
|
EPHYR_LOG ("leave\n") ;
|
||||||
|
return is_ok ;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -223,5 +223,11 @@ Bool ephyrHostXVPutStill (int a_port_id,
|
||||||
Bool ephyrHostXVGetStill (int a_port_id,
|
Bool ephyrHostXVGetStill (int a_port_id,
|
||||||
int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
|
int a_vid_x, int a_vid_y, int a_vid_w, int a_vid_h,
|
||||||
int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h) ;
|
int a_drw_x, int a_drw_y, int a_drw_w, int a_drw_h) ;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* StopVideo
|
||||||
|
*/
|
||||||
|
Bool ephyrHostXVStopVideo (int a_port_id) ;
|
||||||
|
|
||||||
#endif /*__EPHYRHOSTVIDEO_H__*/
|
#endif /*__EPHYRHOSTVIDEO_H__*/
|
||||||
|
|
||||||
|
|
|
@ -49,6 +49,12 @@ struct _EphyrPortPriv {
|
||||||
int port_number ;
|
int port_number ;
|
||||||
KdVideoAdaptorPtr current_adaptor ;
|
KdVideoAdaptorPtr current_adaptor ;
|
||||||
EphyrXVPriv *xv_priv;
|
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 ;
|
typedef struct _EphyrPortPriv EphyrPortPriv ;
|
||||||
|
|
||||||
|
@ -73,6 +79,16 @@ static Bool ephyrXVPrivIsAttrValueValid (KdAttributePtr a_attrs,
|
||||||
int a_attr_value,
|
int a_attr_value,
|
||||||
Bool *a_is_valid) ;
|
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,
|
static void ephyrStopVideo (KdScreenInfo *a_info,
|
||||||
pointer a_xv_priv,
|
pointer a_xv_priv,
|
||||||
Bool a_exit);
|
Bool a_exit);
|
||||||
|
@ -115,6 +131,13 @@ static int ephyrPutImage (KdScreenInfo *a_info,
|
||||||
RegionPtr a_clipping_region,
|
RegionPtr a_clipping_region,
|
||||||
pointer a_port_priv);
|
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,
|
static int ephyrPutVideo (KdScreenInfo *a_info,
|
||||||
DrawablePtr a_drawable,
|
DrawablePtr a_drawable,
|
||||||
short a_vid_x, short a_vid_y,
|
short a_vid_x, short a_vid_y,
|
||||||
|
@ -233,6 +256,8 @@ ephyrLocalAtomToHost (int a_local_atom, int *a_host_atom)
|
||||||
return TRUE ;
|
return TRUE ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
Not used yed.
|
||||||
static Bool
|
static Bool
|
||||||
ephyrHostAtomToLocal (int a_host_atom, int *a_local_atom)
|
ephyrHostAtomToLocal (int a_host_atom, int *a_local_atom)
|
||||||
{
|
{
|
||||||
|
@ -259,6 +284,7 @@ out:
|
||||||
}
|
}
|
||||||
return is_ok ;
|
return is_ok ;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
/**************
|
/**************
|
||||||
*</helpers>
|
*</helpers>
|
||||||
|
@ -553,6 +579,7 @@ ephyrXVPrivSetAdaptorsHooks (EphyrXVPriv *a_this)
|
||||||
EPHYR_LOG ("enter\n") ;
|
EPHYR_LOG ("enter\n") ;
|
||||||
|
|
||||||
for (i=0; i < a_this->num_adaptors; i++) {
|
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].StopVideo = ephyrStopVideo ;
|
||||||
a_this->adaptors[i].SetPortAttribute = ephyrSetPortAttribute ;
|
a_this->adaptors[i].SetPortAttribute = ephyrSetPortAttribute ;
|
||||||
a_this->adaptors[i].GetPortAttribute = ephyrGetPortAttribute ;
|
a_this->adaptors[i].GetPortAttribute = ephyrGetPortAttribute ;
|
||||||
|
@ -569,36 +596,41 @@ ephyrXVPrivSetAdaptorsHooks (EphyrXVPriv *a_this)
|
||||||
if (!ephyrHostXVAdaptorHasPutImage (cur_host_adaptor, &has_it)) {
|
if (!ephyrHostXVAdaptorHasPutImage (cur_host_adaptor, &has_it)) {
|
||||||
EPHYR_LOG_ERROR ("error\n") ;
|
EPHYR_LOG_ERROR ("error\n") ;
|
||||||
}
|
}
|
||||||
if (has_it)
|
if (has_it) {
|
||||||
a_this->adaptors[i].PutImage = ephyrPutImage;
|
a_this->adaptors[i].PutImage = ephyrPutImage;
|
||||||
|
}
|
||||||
|
|
||||||
has_it = FALSE ;
|
has_it = FALSE ;
|
||||||
if (!ephyrHostXVAdaptorHasPutVideo (cur_host_adaptor, &has_it)) {
|
if (!ephyrHostXVAdaptorHasPutVideo (cur_host_adaptor, &has_it)) {
|
||||||
EPHYR_LOG_ERROR ("error\n") ;
|
EPHYR_LOG_ERROR ("error\n") ;
|
||||||
}
|
}
|
||||||
if (has_it)
|
if (has_it) {
|
||||||
a_this->adaptors[i].PutVideo = ephyrPutVideo;
|
a_this->adaptors[i].PutVideo = ephyrPutVideo;
|
||||||
|
}
|
||||||
|
|
||||||
has_it = FALSE ;
|
has_it = FALSE ;
|
||||||
if (!ephyrHostXVAdaptorHasGetVideo (cur_host_adaptor, &has_it)) {
|
if (!ephyrHostXVAdaptorHasGetVideo (cur_host_adaptor, &has_it)) {
|
||||||
EPHYR_LOG_ERROR ("error\n") ;
|
EPHYR_LOG_ERROR ("error\n") ;
|
||||||
}
|
}
|
||||||
if (has_it)
|
if (has_it) {
|
||||||
a_this->adaptors[i].GetVideo = ephyrGetVideo;
|
a_this->adaptors[i].GetVideo = ephyrGetVideo;
|
||||||
|
}
|
||||||
|
|
||||||
has_it = FALSE ;
|
has_it = FALSE ;
|
||||||
if (!ephyrHostXVAdaptorHasPutStill (cur_host_adaptor, &has_it)) {
|
if (!ephyrHostXVAdaptorHasPutStill (cur_host_adaptor, &has_it)) {
|
||||||
EPHYR_LOG_ERROR ("error\n") ;
|
EPHYR_LOG_ERROR ("error\n") ;
|
||||||
}
|
}
|
||||||
if (has_it)
|
if (has_it) {
|
||||||
a_this->adaptors[i].PutStill = ephyrPutStill;
|
a_this->adaptors[i].PutStill = ephyrPutStill;
|
||||||
|
}
|
||||||
|
|
||||||
has_it = FALSE ;
|
has_it = FALSE ;
|
||||||
if (!ephyrHostXVAdaptorHasGetStill (cur_host_adaptor, &has_it)) {
|
if (!ephyrHostXVAdaptorHasGetStill (cur_host_adaptor, &has_it)) {
|
||||||
EPHYR_LOG_ERROR ("error\n") ;
|
EPHYR_LOG_ERROR ("error\n") ;
|
||||||
}
|
}
|
||||||
if (has_it)
|
if (has_it) {
|
||||||
a_this->adaptors[i].GetStill = ephyrGetStill;
|
a_this->adaptors[i].GetStill = ephyrGetStill;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
EPHYR_LOG ("leave\n") ;
|
EPHYR_LOG ("leave\n") ;
|
||||||
return TRUE ;
|
return TRUE ;
|
||||||
|
@ -679,10 +711,70 @@ ephyrXVPrivIsAttrValueValid (KdAttributePtr a_attrs,
|
||||||
return FALSE ;
|
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
|
static void
|
||||||
ephyrStopVideo (KdScreenInfo *a_info, pointer a_port_priv, Bool a_exit)
|
ephyrStopVideo (KdScreenInfo *a_info, pointer a_port_priv, Bool a_exit)
|
||||||
{
|
{
|
||||||
|
EphyrPortPriv *port_priv = a_port_priv ;
|
||||||
|
|
||||||
|
EPHYR_RETURN_IF_FAIL (port_priv) ;
|
||||||
|
|
||||||
EPHYR_LOG ("enter\n") ;
|
EPHYR_LOG ("enter\n") ;
|
||||||
|
if (!ephyrHostXVStopVideo (port_priv->port_number)) {
|
||||||
|
EPHYR_LOG_ERROR ("XvStopVideo() failed\n") ;
|
||||||
|
}
|
||||||
EPHYR_LOG ("leave\n") ;
|
EPHYR_LOG ("leave\n") ;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -832,7 +924,8 @@ ephyrPutImage (KdScreenInfo *a_info,
|
||||||
pointer a_port_priv)
|
pointer a_port_priv)
|
||||||
{
|
{
|
||||||
EphyrPortPriv *port_priv = a_port_priv ;
|
EphyrPortPriv *port_priv = a_port_priv ;
|
||||||
int result=BadImplementation ;
|
Bool is_ok=FALSE ;
|
||||||
|
int result=BadImplementation, image_size=0 ;
|
||||||
|
|
||||||
EPHYR_RETURN_VAL_IF_FAIL (a_drawable, BadValue) ;
|
EPHYR_RETURN_VAL_IF_FAIL (a_drawable, BadValue) ;
|
||||||
|
|
||||||
|
@ -849,6 +942,82 @@ ephyrPutImage (KdScreenInfo *a_info,
|
||||||
goto out ;
|
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_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 (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 ;
|
result = Success ;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
|
Loading…
Reference in New Issue