aboutsummaryrefslogtreecommitdiff
path: root/xorg-server/hw/kdrive/ephyr/ephyrvideo.c
diff options
context:
space:
mode:
Diffstat (limited to 'xorg-server/hw/kdrive/ephyr/ephyrvideo.c')
-rw-r--r--xorg-server/hw/kdrive/ephyr/ephyrvideo.c746
1 files changed, 410 insertions, 336 deletions
diff --git a/xorg-server/hw/kdrive/ephyr/ephyrvideo.c b/xorg-server/hw/kdrive/ephyr/ephyrvideo.c
index dfc29f533..4a05721af 100644
--- a/xorg-server/hw/kdrive/ephyr/ephyrvideo.c
+++ b/xorg-server/hw/kdrive/ephyr/ephyrvideo.c
@@ -31,15 +31,17 @@
#endif
#include <string.h>
#include <X11/extensions/Xv.h>
+#include <xcb/xcb.h>
+#include <xcb/xcb_aux.h>
+#include <xcb/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;
+ xcb_xv_query_adaptors_reply_t *host_adaptors;
KdVideoAdaptorPtr adaptors;
int num_adaptors;
};
@@ -58,14 +60,8 @@ struct _EphyrPortPriv {
};
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);
@@ -174,53 +170,18 @@ static int s_base_port_id;
* ************/
static Bool
-DoSimpleClip(BoxPtr a_dst_box, BoxPtr a_clipper, BoxPtr a_result)
+adaptor_has_flags(const xcb_xv_adaptor_info_t *adaptor, uint32_t flags)
{
- 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;
+ return (adaptor->type & flags) == flags;
}
static Bool
ephyrLocalAtomToHost(int a_local_atom, int *a_host_atom)
{
+ xcb_connection_t *conn = hostx_get_xcbconn();
+ xcb_intern_atom_cookie_t cookie;
+ xcb_intern_atom_reply_t *reply;
const char *atom_name = NULL;
- int host_atom = None;
EPHYR_RETURN_VAL_IF_FAIL(a_host_atom, FALSE);
@@ -232,43 +193,18 @@ ephyrLocalAtomToHost(int a_local_atom, int *a_host_atom)
if (!atom_name)
return FALSE;
- if (!ephyrHostGetAtom(atom_name, FALSE, &host_atom) || host_atom == None) {
+ cookie = xcb_intern_atom(conn, FALSE, strlen(atom_name), atom_name);
+ reply = xcb_intern_atom_reply(conn, cookie, NULL);
+ if (!reply || reply->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 ;
+ *a_host_atom = reply->atom;
+ free(reply);
-out:
- if (atom_name) {
- ephyrHostFree (atom_name) ;
- }
- return is_ok ;
+ return TRUE;
}
-*/
/**************
*</helpers>
@@ -321,8 +257,6 @@ ephyrXVPrivNew(void)
goto error;
}
- ephyrHostXVInit();
-
if (!ephyrXVPrivQueryHostAdaptors(xv_priv)) {
EPHYR_LOG_ERROR("failed to query the host x for xv properties\n");
goto error;
@@ -351,7 +285,7 @@ ephyrXVPrivDelete(EphyrXVPriv * a_this)
if (!a_this)
return;
if (a_this->host_adaptors) {
- ephyrHostXVAdaptorArrayDelete(a_this->host_adaptors);
+ free(a_this->host_adaptors);
a_this->host_adaptors = NULL;
}
free(a_this->adaptors);
@@ -360,72 +294,174 @@ ephyrXVPrivDelete(EphyrXVPriv * a_this)
EPHYR_LOG("leave\n");
}
-static KdVideoEncodingPtr
-videoEncodingDup(EphyrHostEncoding * a_encodings, int a_num_encodings)
+static Bool
+translate_video_encodings(KdVideoAdaptorPtr adaptor,
+ xcb_xv_adaptor_info_t *host_adaptor)
{
- KdVideoEncodingPtr result = NULL;
- int i = 0;
+ xcb_connection_t *conn = hostx_get_xcbconn();
+ int i;
+ xcb_xv_query_encodings_cookie_t cookie;
+ xcb_xv_query_encodings_reply_t *reply;
+ xcb_xv_encoding_info_iterator_t encoding_it;
+
+ cookie = xcb_xv_query_encodings(conn, host_adaptor->base_id);
+ reply = xcb_xv_query_encodings_reply(conn, cookie, NULL);
+ if (!reply)
+ return FALSE;
+
+ adaptor->nEncodings = reply->num_encodings;
+ adaptor->pEncodings = calloc(adaptor->nEncodings,
+ sizeof(*adaptor->pEncodings));
+ if (!adaptor->pEncodings) {
+ free(reply);
+ return FALSE;
+ }
+
+ encoding_it = xcb_xv_query_encodings_info_iterator(reply);
+ for (i = 0; i < adaptor->nEncodings; i++) {
+ xcb_xv_encoding_info_t *encoding_info = encoding_it.data;
+ KdVideoEncodingPtr encoding = &adaptor->pEncodings[i];
- EPHYR_RETURN_VAL_IF_FAIL(a_encodings && a_num_encodings, NULL);
+ encoding->id = encoding_info->encoding;
+ encoding->name = strndup(xcb_xv_encoding_info_name(encoding_info),
+ encoding_info->name_size);
+ encoding->width = encoding_info->width;
+ encoding->height = encoding_info->height;
+ encoding->rate.numerator = encoding_info->rate.numerator;
+ encoding->rate.denominator = encoding_info->rate.denominator;
- 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;
+ xcb_xv_encoding_info_next(&encoding_it);
}
- return result;
+
+ free(reply);
+ return TRUE;
}
-static KdAttributePtr
-portAttributesDup(EphyrHostAttribute * a_encodings, int a_num_encodings)
+static Bool
+translate_xv_attributes(KdVideoAdaptorPtr adaptor,
+ xcb_xv_adaptor_info_t *host_adaptor)
{
+ xcb_connection_t *conn = hostx_get_xcbconn();
int i = 0;
- KdAttributePtr result = NULL;
+ xcb_xv_attribute_info_iterator_t it;
+ xcb_xv_query_port_attributes_cookie_t cookie =
+ xcb_xv_query_port_attributes(conn, host_adaptor->base_id);
+ xcb_xv_query_port_attributes_reply_t *reply =
+ xcb_xv_query_port_attributes_reply(conn, cookie, NULL);
- EPHYR_RETURN_VAL_IF_FAIL(a_encodings && a_num_encodings, NULL);
+ if (!reply)
+ return FALSE;
- result = calloc(a_num_encodings, sizeof(KdAttributeRec));
- if (!result) {
+ adaptor->nAttributes = reply->num_attributes;
+ adaptor->pAttributes = calloc(reply->num_attributes,
+ sizeof(*adaptor->pAttributes));
+ if (!adaptor->pAttributes) {
EPHYR_LOG_ERROR("failed to allocate attributes\n");
- return NULL;
+ free(reply);
+ return FALSE;
}
- 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);
+
+ it = xcb_xv_query_port_attributes_attributes_iterator(reply);
+ for (i = 0; i < reply->num_attributes; i++) {
+ KdAttributePtr attribute = &adaptor->pAttributes[i];
+
+ attribute->flags = it.data->flags;
+ attribute->min_value = it.data->min;
+ attribute->max_value = it.data->max;
+ attribute->name = strndup(xcb_xv_attribute_info_name(it.data),
+ it.data->size);
+
+ /* make sure atoms of attrs names are created in xephyr */
+ MakeAtom(xcb_xv_attribute_info_name(it.data), it.data->size, TRUE);
+
+ xcb_xv_attribute_info_next(&it);
}
- return result;
+
+ free(reply);
+ return TRUE;
+}
+
+static Bool
+translate_xv_image_formats(KdVideoAdaptorPtr adaptor,
+ xcb_xv_adaptor_info_t *host_adaptor)
+{
+ xcb_connection_t *conn = hostx_get_xcbconn();
+ int i = 0;
+ xcb_xv_list_image_formats_cookie_t cookie =
+ xcb_xv_list_image_formats(conn, host_adaptor->base_id);
+ xcb_xv_list_image_formats_reply_t *reply =
+ xcb_xv_list_image_formats_reply(conn, cookie, NULL);
+ xcb_xv_image_format_info_t *formats;
+
+ if (!reply)
+ return FALSE;
+
+ adaptor->nImages = reply->num_formats;
+ adaptor->pImages = calloc(reply->num_formats, sizeof(KdImageRec));
+ if (!adaptor->pImages) {
+ free(reply);
+ return FALSE;
+ }
+
+ formats = xcb_xv_list_image_formats_format(reply);
+ for (i = 0; i < reply->num_formats; i++) {
+ KdImagePtr image = &adaptor->pImages[i];
+
+ image->id = formats[i].id;
+ image->type = formats[i].type;
+ image->byte_order = formats[i].byte_order;
+ memcpy(image->guid, formats[i].guid, 16);
+ image->bits_per_pixel = formats[i].bpp;
+ image->format = formats[i].format;
+ image->num_planes = formats[i].num_planes;
+ image->depth = formats[i].depth;
+ image->red_mask = formats[i].red_mask;
+ image->green_mask = formats[i].green_mask;
+ image->blue_mask = formats[i].blue_mask;
+ image->y_sample_bits = formats[i].y_sample_bits;
+ image->u_sample_bits = formats[i].u_sample_bits;
+ image->v_sample_bits = formats[i].v_sample_bits;
+ image->horz_y_period = formats[i].vhorz_y_period;
+ image->horz_u_period = formats[i].vhorz_u_period;
+ image->horz_v_period = formats[i].vhorz_v_period;
+ image->vert_y_period = formats[i].vvert_y_period;
+ image->vert_u_period = formats[i].vvert_u_period;
+ image->vert_v_period = formats[i].vvert_v_period;
+ memcpy(image->component_order, formats[i].vcomp_order, 32);
+ image->scanline_order = formats[i].vscanline_order;
+ }
+
+ free(reply);
+ return TRUE;
}
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;
+ xcb_connection_t *conn = hostx_get_xcbconn();
+ xcb_screen_t *xscreen = xcb_aux_get_screen(conn, hostx_get_screen());
+ int base_port_id = 0, i = 0, port_priv_offset = 0;
Bool is_ok = FALSE;
+ xcb_generic_error_t *e = NULL;
+ xcb_xv_adaptor_info_iterator_t it;
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;
+ {
+ xcb_xv_query_adaptors_cookie_t cookie =
+ xcb_xv_query_adaptors(conn, xscreen->root);
+ a_this->host_adaptors = xcb_xv_query_adaptors_reply(conn, cookie, &e);
+ if (e) {
+ free(e);
+ 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);
+ a_this->num_adaptors = a_this->host_adaptors->num_adaptors;
if (a_this->num_adaptors < 0) {
EPHYR_LOG_ERROR("failed to get number of host adaptors\n");
goto out;
@@ -442,28 +478,28 @@ ephyrXVPrivQueryHostAdaptors(EphyrXVPriv * a_this)
goto out;
}
}
+
+ it = xcb_xv_query_adaptors_info_iterator(a_this->host_adaptors);
for (i = 0; i < a_this->num_adaptors; i++) {
+ xcb_xv_adaptor_info_t *cur_host_adaptor = it.data;
+ xcb_xv_format_t *format = xcb_xv_adaptor_info_formats(cur_host_adaptor);
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);
+ a_this->adaptors[i].nPorts = cur_host_adaptor->num_ports;
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 = cur_host_adaptor->type;
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 =
+ strndup(xcb_xv_adaptor_info_name(cur_host_adaptor),
+ cur_host_adaptor->name_size);
+ if (!a_this->adaptors[i].name)
a_this->adaptors[i].name = strdup("Xephyr Video Overlay");
- base_port_id = ephyrHostXVAdaptorGetFirstPortID(cur_host_adaptor);
+ base_port_id = cur_host_adaptor->base_id;
if (base_port_id < 0) {
EPHYR_LOG_ERROR("failed to get port id for adaptor %d\n", i);
continue;
@@ -471,24 +507,24 @@ ephyrXVPrivQueryHostAdaptors(EphyrXVPriv * a_this)
if (!s_base_port_id)
s_base_port_id = base_port_id;
- if (!ephyrHostXVQueryEncodings(base_port_id,
- &encodings, &num_encodings)) {
+ if (!translate_video_encodings(&a_this->adaptors[i],
+ cur_host_adaptor)) {
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].nFormats = cur_host_adaptor->num_formats;
+ a_this->adaptors[i].pFormats =
+ calloc(cur_host_adaptor->num_formats,
+ sizeof(*a_this->adaptors[i].pFormats));
+ for (j = 0; j < cur_host_adaptor->num_formats; j++) {
+ xcb_visualtype_t *visual =
+ xcb_aux_find_visual_by_id(xscreen, format[j].visual);
+ a_this->adaptors[i].pFormats[j].depth = format[j].depth;
+ a_this->adaptors[i].pFormats[j].class = visual->_class;
+ }
+
a_this->adaptors[i].pPortPrivates =
calloc(a_this->adaptors[i].nPorts,
sizeof(DevUnion) + sizeof(EphyrPortPriv));
@@ -504,41 +540,26 @@ ephyrXVPrivQueryHostAdaptors(EphyrXVPriv * a_this)
port_priv->xv_priv = a_this;
a_this->adaptors[i].pPortPrivates[j].ptr = port_priv;
}
- if (!ephyrHostXVQueryPortAttributes(base_port_id,
- &attributes, &num_attributes)) {
+
+ if (!translate_xv_attributes(&a_this->adaptors[i], cur_host_adaptor)) {
+ {
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)) {
+
+ if (!translate_xv_image_formats(&a_this->adaptors[i], cur_host_adaptor)) {
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;
+
+ xcb_xv_adaptor_info_next(&it);
}
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;
}
@@ -547,14 +568,16 @@ static Bool
ephyrXVPrivSetAdaptorsHooks(EphyrXVPriv * a_this)
{
int i = 0;
- Bool has_it = FALSE;
- EphyrHostXVAdaptor *cur_host_adaptor = NULL;
+ xcb_xv_adaptor_info_iterator_t it;
EPHYR_RETURN_VAL_IF_FAIL(a_this, FALSE);
EPHYR_LOG("enter\n");
+ it = xcb_xv_query_adaptors_info_iterator(a_this->host_adaptors);
for (i = 0; i < a_this->num_adaptors; i++) {
+ xcb_xv_adaptor_info_t *cur_host_adaptor = it.data;
+
a_this->adaptors[i].ReputImage = ephyrReputImage;
a_this->adaptors[i].StopVideo = ephyrStopVideo;
a_this->adaptors[i].SetPortAttribute = ephyrSetPortAttribute;
@@ -562,50 +585,25 @@ ephyrXVPrivSetAdaptorsHooks(EphyrXVPriv * a_this)
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) {
+ if (adaptor_has_flags(cur_host_adaptor,
+ XCB_XV_TYPE_IMAGE_MASK | XCB_XV_TYPE_INPUT_MASK))
a_this->adaptors[i].PutImage = ephyrPutImage;
- }
- has_it = FALSE;
- if (!ephyrHostXVAdaptorHasPutVideo(cur_host_adaptor, &has_it)) {
- EPHYR_LOG_ERROR("error\n");
- }
- if (has_it) {
+ if (adaptor_has_flags(cur_host_adaptor,
+ XCB_XV_TYPE_VIDEO_MASK | XCB_XV_TYPE_INPUT_MASK))
a_this->adaptors[i].PutVideo = ephyrPutVideo;
- }
- has_it = FALSE;
- if (!ephyrHostXVAdaptorHasGetVideo(cur_host_adaptor, &has_it)) {
- EPHYR_LOG_ERROR("error\n");
- }
- if (has_it) {
+ if (adaptor_has_flags(cur_host_adaptor,
+ XCB_XV_TYPE_VIDEO_MASK | XCB_XV_TYPE_OUTPUT_MASK))
a_this->adaptors[i].GetVideo = ephyrGetVideo;
- }
- has_it = FALSE;
- if (!ephyrHostXVAdaptorHasPutStill(cur_host_adaptor, &has_it)) {
- EPHYR_LOG_ERROR("error\n");
- }
- if (has_it) {
+ if (adaptor_has_flags(cur_host_adaptor,
+ XCB_XV_TYPE_STILL_MASK | XCB_XV_TYPE_INPUT_MASK))
a_this->adaptors[i].PutStill = ephyrPutStill;
- }
- has_it = FALSE;
- if (!ephyrHostXVAdaptorHasGetStill(cur_host_adaptor, &has_it)) {
- EPHYR_LOG_ERROR("error\n");
- }
- if (has_it) {
+ if (adaptor_has_flags(cur_host_adaptor,
+ XCB_XV_TYPE_STILL_MASK | XCB_XV_TYPE_OUTPUT_MASK))
a_this->adaptors[i].GetStill = ephyrGetStill;
- }
}
EPHYR_LOG("leave\n");
return TRUE;
@@ -691,20 +689,27 @@ ephyrXVPrivGetImageBufSize(int a_port_id,
unsigned short a_width,
unsigned short a_height, int *a_size)
{
+ xcb_connection_t *conn = hostx_get_xcbconn();
+ xcb_xv_query_image_attributes_cookie_t cookie;
+ xcb_xv_query_image_attributes_reply_t *reply;
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");
+ cookie = xcb_xv_query_image_attributes(conn,
+ a_port_id, a_image_id,
+ a_width, a_height);
+ reply = xcb_xv_query_image_attributes_reply(conn, cookie, NULL);
+ if (!reply)
goto out;
- }
+
+ *a_size = reply->data_size;
is_ok = TRUE;
+ free(reply);
+
out:
EPHYR_LOG("leave\n");
return is_ok;
@@ -741,15 +746,14 @@ ephyrXVPrivSaveImageToPortPriv(EphyrPortPriv * a_port_priv,
static void
ephyrStopVideo(KdScreenInfo * a_info, pointer a_port_priv, Bool a_exit)
{
+ xcb_connection_t *conn = hostx_get_xcbconn();
EphyrPortPriv *port_priv = a_port_priv;
+ EphyrScrPriv *scrpriv = a_info->driver;
- 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");
- }
+ xcb_xv_stop_video(conn, port_priv->port_number, scrpriv->win);
EPHYR_LOG("leave\n");
}
@@ -757,6 +761,7 @@ static int
ephyrSetPortAttribute(KdScreenInfo * a_info,
Atom a_attr_name, int a_attr_value, pointer a_port_priv)
{
+ xcb_connection_t *conn = hostx_get_xcbconn();
int res = Success, host_atom = 0;
EphyrPortPriv *port_priv = a_port_priv;
Bool is_attr_valid = FALSE;
@@ -797,12 +802,9 @@ ephyrSetPortAttribute(KdScreenInfo * a_info,
*/
}
- if (!ephyrHostXVSetPortAttribute(port_priv->port_number,
- host_atom, a_attr_value)) {
- EPHYR_LOG_ERROR("failed to set port attribute\n");
- res = BadMatch;
- goto out;
- }
+ xcb_xv_set_port_attribute(conn, port_priv->port_number,
+ host_atom, a_attr_value);
+ xcb_flush(conn);
res = Success;
out:
@@ -814,8 +816,12 @@ static int
ephyrGetPortAttribute(KdScreenInfo * a_screen_info,
Atom a_attr_name, int *a_attr_value, pointer a_port_priv)
{
+ xcb_connection_t *conn = hostx_get_xcbconn();
int res = Success, host_atom = 0;
EphyrPortPriv *port_priv = a_port_priv;
+ xcb_generic_error_t *e;
+ xcb_xv_get_port_attribute_cookie_t cookie;
+ xcb_xv_get_port_attribute_reply_t *reply;
EPHYR_RETURN_VAL_IF_FAIL(port_priv, BadMatch);
EPHYR_RETURN_VAL_IF_FAIL(ValidAtom(a_attr_name), BadMatch);
@@ -830,12 +836,17 @@ ephyrGetPortAttribute(KdScreenInfo * a_screen_info,
goto out;
}
- if (!ephyrHostXVGetPortAttribute(port_priv->port_number,
- host_atom, a_attr_value)) {
- EPHYR_LOG_ERROR("failed to get port attribute\n");
+ cookie = xcb_xv_get_port_attribute(conn, port_priv->port_number, host_atom);
+ reply = xcb_xv_get_port_attribute_reply(conn, cookie, &e);
+ if (e) {
+ EPHYR_LOG_ERROR ("XvGetPortAttribute() failed: %d \n", e->error_code);
+ free(e);
res = BadMatch;
goto out;
}
+ *a_attr_value = reply->value;
+
+ free(reply);
res = Success;
out:
@@ -853,21 +864,117 @@ ephyrQueryBestSize(KdScreenInfo * a_info,
unsigned int *a_prefered_w,
unsigned int *a_prefered_h, pointer a_port_priv)
{
- int res = 0;
+ xcb_connection_t *conn = hostx_get_xcbconn();
EphyrPortPriv *port_priv = a_port_priv;
+ xcb_xv_query_best_size_cookie_t cookie =
+ xcb_xv_query_best_size(conn,
+ port_priv->port_number,
+ a_src_w, a_src_h,
+ a_drw_w, a_drw_h,
+ a_motion);
+ xcb_xv_query_best_size_reply_t *reply =
+ xcb_xv_query_best_size_reply(conn, cookie, NULL);
+
+ EPHYR_LOG("enter: frame (%dx%d), drw (%dx%d)\n",
+ a_src_w, a_src_h, a_drw_w, a_drw_h);
+
+ if (!reply) {
+ EPHYR_LOG_ERROR ("XvQueryBestSize() failed\n");
+ return;
+ }
+ *a_prefered_w = reply->actual_width;
+ *a_prefered_h = reply->actual_height;
+ EPHYR_LOG("actual (%dx%d)\n", *a_prefered_w, *a_prefered_h);
+ free(reply);
- EPHYR_RETURN_IF_FAIL(port_priv);
+ EPHYR_LOG("leave\n");
+}
- 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");
+
+static Bool
+ephyrHostXVPutImage(KdScreenInfo * a_info,
+ EphyrPortPriv *port_priv,
+ int a_image_id,
+ int a_drw_x,
+ int a_drw_y,
+ int a_drw_w,
+ int a_drw_h,
+ int a_src_x,
+ int a_src_y,
+ int a_src_w,
+ int a_src_h,
+ int a_image_width,
+ int a_image_height,
+ unsigned char *a_buf,
+ BoxPtr a_clip_rects, int a_clip_rect_nums)
+{
+ EphyrScrPriv *scrpriv = a_info->driver;
+ xcb_connection_t *conn = hostx_get_xcbconn();
+ xcb_gcontext_t gc;
+ Bool is_ok = TRUE;
+ xcb_rectangle_t *rects = NULL;
+ int data_len, width, height;
+ xcb_xv_query_image_attributes_cookie_t image_attr_cookie;
+ xcb_xv_query_image_attributes_reply_t *image_attr_reply;
+
+ EPHYR_RETURN_VAL_IF_FAIL(a_buf, FALSE);
+
+ EPHYR_LOG("enter, num_clip_rects: %d\n", a_clip_rect_nums);
+
+ image_attr_cookie = xcb_xv_query_image_attributes(conn,
+ port_priv->port_number,
+ a_image_id,
+ a_image_width,
+ a_image_height);
+ image_attr_reply = xcb_xv_query_image_attributes_reply(conn,
+ image_attr_cookie,
+ NULL);
+ if (!image_attr_reply)
+ goto out;
+ data_len = image_attr_reply->data_size;
+ width = image_attr_reply->width;
+ height = image_attr_reply->height;
+ free(image_attr_reply);
+
+ gc = xcb_generate_id(conn);
+ xcb_create_gc(conn, gc, scrpriv->win, 0, NULL);
+
+ if (a_clip_rect_nums) {
+ int i = 0;
+ rects = calloc(a_clip_rect_nums, sizeof(xcb_rectangle_t));
+ for (i=0; i < a_clip_rect_nums; i++) {
+ rects[i].x = a_clip_rects[i].x1;
+ rects[i].y = a_clip_rects[i].y1;
+ rects[i].width = a_clip_rects[i].x2 - a_clip_rects[i].x1;
+ rects[i].height = a_clip_rects[i].y2 - a_clip_rects[i].y1;
+ EPHYR_LOG("(x,y,w,h): (%d,%d,%d,%d)\n",
+ rects[i].x, rects[i].y, rects[i].width, rects[i].height);
+ }
+ xcb_set_clip_rectangles(conn,
+ XCB_CLIP_ORDERING_YX_BANDED,
+ gc,
+ 0,
+ 0,
+ a_clip_rect_nums,
+ rects);
+ free(rects);
}
+ xcb_xv_put_image(conn,
+ port_priv->port_number,
+ scrpriv->win,
+ gc,
+ a_image_id,
+ a_src_x, a_src_y, a_src_w, a_src_h,
+ a_drw_x, a_drw_y, a_drw_w, a_drw_h,
+ width, height,
+ data_len, a_buf);
+ xcb_free_gc(conn, gc);
+
+ is_ok = TRUE;
+
+out:
EPHYR_LOG("leave\n");
+ return is_ok;
}
static int
@@ -896,13 +1003,12 @@ ephyrPutImage(KdScreenInfo * a_info,
EPHYR_LOG("enter\n");
- if (!ephyrHostXVPutImage(a_info->pScreen->myNum,
- port_priv->port_number,
+ if (!ephyrHostXVPutImage(a_info, port_priv,
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 *) RegionRects(a_clipping_region),
+ RegionRects(a_clipping_region),
RegionNumRects(a_clipping_region))) {
EPHYR_LOG_ERROR("EphyrHostXVPutImage() failed\n");
goto out;
@@ -972,8 +1078,8 @@ ephyrReputImage(KdScreenInfo * a_info,
EPHYR_LOG_ERROR("has null image buf in cache\n");
goto out;
}
- if (!ephyrHostXVPutImage(a_info->pScreen->myNum,
- port_priv->port_number,
+ if (!ephyrHostXVPutImage(a_info,
+ port_priv,
port_priv->image_id,
a_drw_x, a_drw_y,
port_priv->drw_w, port_priv->drw_h,
@@ -981,7 +1087,7 @@ ephyrReputImage(KdScreenInfo * a_info,
port_priv->src_w, port_priv->src_h,
port_priv->image_width, port_priv->image_height,
port_priv->image_buf,
- (EphyrHostBox *) RegionRects(a_clipping_region),
+ RegionRects(a_clipping_region),
RegionNumRects(a_clipping_region))) {
EPHYR_LOG_ERROR("ephyrHostXVPutImage() failed\n");
goto out;
@@ -1003,38 +1109,26 @@ ephyrPutVideo(KdScreenInfo * a_info,
short a_drw_w, short a_drw_h,
RegionPtr a_clipping_region, pointer a_port_priv)
{
+ EphyrScrPriv *scrpriv = a_info->driver;
+ xcb_connection_t *conn = hostx_get_xcbconn();
+ xcb_gcontext_t gc;
EphyrPortPriv *port_priv = a_port_priv;
- BoxRec clipped_area, dst_box;
- int result = BadImplementation;
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;
+ gc = xcb_generate_id(conn);
+ xcb_create_gc(conn, gc, scrpriv->win, 0, NULL);
+ xcb_xv_put_video(conn, port_priv->port_number,
+ scrpriv->win, gc,
+ a_vid_x, a_vid_y, a_vid_w, a_vid_h,
+ a_drw_x, a_drw_y, a_drw_w, a_drw_h);
+ xcb_free_gc(conn, gc);
- if (!DoSimpleClip(&dst_box,
- RegionExtents(a_clipping_region), &clipped_area)) {
- EPHYR_LOG_ERROR("failed to simple clip\n");
- goto out;
- }
-
- 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;
+ return Success;
}
static int
@@ -1046,38 +1140,27 @@ ephyrGetVideo(KdScreenInfo * a_info,
short a_drw_w, short a_drw_h,
RegionPtr a_clipping_region, pointer a_port_priv)
{
+ EphyrScrPriv *scrpriv = a_info->driver;
+ xcb_connection_t *conn = hostx_get_xcbconn();
+ xcb_gcontext_t gc;
EphyrPortPriv *port_priv = a_port_priv;
- BoxRec clipped_area, dst_box;
- int result = BadImplementation;
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,
- RegionExtents(a_clipping_region), &clipped_area)) {
- EPHYR_LOG_ERROR("failed to simple clip\n");
- goto out;
- }
+ gc = xcb_generate_id(conn);
+ xcb_create_gc(conn, gc, scrpriv->win, 0, NULL);
+ xcb_xv_get_video(conn, port_priv->port_number,
+ scrpriv->win, gc,
+ a_vid_x, a_vid_y, a_vid_w, a_vid_h,
+ a_drw_x, a_drw_y, a_drw_w, a_drw_h);
- if (!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;
+ xcb_free_gc(conn, gc);
- out:
EPHYR_LOG("leave\n");
- return result;
+ return Success;
}
static int
@@ -1089,38 +1172,26 @@ ephyrPutStill(KdScreenInfo * a_info,
short a_drw_w, short a_drw_h,
RegionPtr a_clipping_region, pointer a_port_priv)
{
+ EphyrScrPriv *scrpriv = a_info->driver;
+ xcb_connection_t *conn = hostx_get_xcbconn();
+ xcb_gcontext_t gc;
EphyrPortPriv *port_priv = a_port_priv;
- BoxRec clipped_area, dst_box;
- int result = BadImplementation;
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,
- RegionExtents(a_clipping_region), &clipped_area)) {
- EPHYR_LOG_ERROR("failed to simple clip\n");
- goto out;
- }
+ gc = xcb_generate_id(conn);
+ xcb_create_gc(conn, gc, scrpriv->win, 0, NULL);
+ xcb_xv_put_still(conn, port_priv->port_number,
+ scrpriv->win, gc,
+ a_vid_x, a_vid_y, a_vid_w, a_vid_h,
+ a_drw_x, a_drw_y, a_drw_w, a_drw_h);
+ xcb_free_gc(conn, gc);
- 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;
+ return Success;
}
static int
@@ -1132,38 +1203,26 @@ ephyrGetStill(KdScreenInfo * a_info,
short a_drw_w, short a_drw_h,
RegionPtr a_clipping_region, pointer a_port_priv)
{
+ EphyrScrPriv *scrpriv = a_info->driver;
+ xcb_connection_t *conn = hostx_get_xcbconn();
+ xcb_gcontext_t gc;
EphyrPortPriv *port_priv = a_port_priv;
- BoxRec clipped_area, dst_box;
- int result = BadImplementation;
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,
- RegionExtents(a_clipping_region), &clipped_area)) {
- EPHYR_LOG_ERROR("failed to simple clip\n");
- goto out;
- }
+ gc = xcb_generate_id(conn);
+ xcb_create_gc(conn, gc, scrpriv->win, 0, NULL);
+ xcb_xv_get_still(conn, port_priv->port_number,
+ scrpriv->win, gc,
+ a_vid_x, a_vid_y, a_vid_w, a_vid_h,
+ a_drw_x, a_drw_y, a_drw_w, a_drw_h);
+ xcb_free_gc(conn, gc);
- 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;
+ return Success;
}
static int
@@ -1172,6 +1231,9 @@ ephyrQueryImageAttributes(KdScreenInfo * a_info,
unsigned short *a_w,
unsigned short *a_h, int *a_pitches, int *a_offsets)
{
+ xcb_connection_t *conn = hostx_get_xcbconn();
+ xcb_xv_query_image_attributes_cookie_t cookie;
+ xcb_xv_query_image_attributes_reply_t *reply;
int image_size = 0;
EPHYR_RETURN_VAL_IF_FAIL(a_w && a_h, FALSE);
@@ -1179,13 +1241,25 @@ ephyrQueryImageAttributes(KdScreenInfo * a_info,
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");
+ cookie = xcb_xv_query_image_attributes(conn,
+ s_base_port_id, a_id,
+ *a_w, *a_h);
+ reply = xcb_xv_query_image_attributes_reply(conn, cookie, NULL);
+ if (!reply)
goto out;
+
+ *a_w = reply->width;
+ *a_h = reply->height;
+ if (a_pitches && a_offsets) {
+ memcpy(a_pitches, xcb_xv_query_image_attributes_pitches(reply),
+ reply->num_planes << 2);
+ memcpy(a_offsets, xcb_xv_query_image_attributes_offsets(reply),
+ reply->num_planes << 2);
}
+ image_size = reply->data_size;
+
+ free(reply);
+
EPHYR_LOG("image size: %d, dim (%dx%d)\n", image_size, *a_w, *a_h);
out: