summaryrefslogtreecommitdiffstats
path: root/sys/ximage
diff options
context:
space:
mode:
authorZaheer Abbas Merali <zaheerabbas@merali.org>2006-07-08 22:41:25 +0000
committerZaheer Abbas Merali <zaheerabbas@merali.org>2006-07-08 22:41:25 +0000
commite0855a0eb935a2095ede91089e79e1868daac7cf (patch)
treed4c52f1e9bc13b1e05a7c74e7586ec9f9ed3c586 /sys/ximage
parente6c882b7679394bdccca0e82582a64335e80a92a (diff)
sys/ximage/gstximagesrc.*: Fix use-damage property to actually work :)
Original commit message from CVS: 2006-07-09 Zaheer Abbas Merali <zaheerabbas at merali dot org> * sys/ximage/gstximagesrc.c: (gst_ximage_src_ximage_get), (gst_ximage_src_set_property), (gst_ximage_src_get_property), (gst_ximage_src_get_caps), (gst_ximage_src_class_init), (gst_ximage_src_init): * sys/ximage/gstximagesrc.h: Fix use-damage property to actually work :) Add startx, starty, endx, endy properties so screencasts other than full screen ones can work.
Diffstat (limited to 'sys/ximage')
-rw-r--r--sys/ximage/gstximagesrc.c289
-rw-r--r--sys/ximage/gstximagesrc.h7
2 files changed, 242 insertions, 54 deletions
diff --git a/sys/ximage/gstximagesrc.c b/sys/ximage/gstximagesrc.c
index f0376d5f..17c9d708 100644
--- a/sys/ximage/gstximagesrc.c
+++ b/sys/ximage/gstximagesrc.c
@@ -79,7 +79,11 @@ enum
PROP_DISPLAY_NAME,
PROP_SCREEN_NUM,
PROP_SHOW_POINTER,
- PROP_USE_DAMAGE
+ PROP_USE_DAMAGE,
+ PROP_STARTX,
+ PROP_STARTY,
+ PROP_ENDX,
+ PROP_ENDY
};
GST_BOILERPLATE (GstXImageSrc, gst_ximage_src, GstPushSrc, GST_TYPE_PUSH_SRC);
@@ -363,6 +367,7 @@ gst_ximage_src_ximage_get (GstXImageSrc * ximagesrc)
xcontext = ximagesrc->xcontext;
+
caps = gst_caps_new_simple ("video/x-raw-rgb",
"bpp", G_TYPE_INT, xcontext->bpp,
"depth", G_TYPE_INT, xcontext->depth,
@@ -370,8 +375,8 @@ gst_ximage_src_ximage_get (GstXImageSrc * ximagesrc)
"red_mask", G_TYPE_INT, xcontext->r_mask_output,
"green_mask", G_TYPE_INT, xcontext->g_mask_output,
"blue_mask", G_TYPE_INT, xcontext->b_mask_output,
- "width", G_TYPE_INT, xcontext->width,
- "height", G_TYPE_INT, xcontext->height,
+ "width", G_TYPE_INT, ximagesrc->width,
+ "height", G_TYPE_INT, ximagesrc->height,
"framerate", GST_TYPE_FRACTION, ximagesrc->fps_n, ximagesrc->fps_d,
"pixel-aspect-ratio", GST_TYPE_FRACTION,
gst_value_get_fraction_numerator (xcontext->par),
@@ -382,7 +387,6 @@ gst_ximage_src_ximage_get (GstXImageSrc * ximagesrc)
}
g_return_val_if_fail (GST_IS_XIMAGE_SRC (ximagesrc), NULL);
-
#ifdef HAVE_XDAMAGE
if (ximagesrc->have_xdamage && ximagesrc->use_damage) {
XEvent ev;
@@ -396,11 +400,11 @@ gst_ximage_src_ximage_get (GstXImageSrc * ximagesrc)
#ifdef HAVE_XSHM
if (ximagesrc->xcontext->use_xshm &&
- dev->area.width == ximagesrc->width &&
- dev->area.height == ximagesrc->height) {
+ dev->area.width == ximagesrc->xcontext->width &&
+ dev->area.height == ximagesrc->xcontext->height) {
GST_DEBUG_OBJECT (ximagesrc, "Entire screen was damaged");
XShmGetImage (ximagesrc->xcontext->disp, ximagesrc->xwindow,
- ximage->ximage, 0, 0, AllPlanes);
+ ximage->ximage, ximagesrc->startx, ximagesrc->starty, AllPlanes);
/* No need to collect more events */
while (XPending (ximagesrc->xcontext->disp)) {
XNextEvent (ximagesrc->xcontext->disp, &ev);
@@ -409,20 +413,57 @@ gst_ximage_src_ximage_get (GstXImageSrc * ximagesrc)
} else
#endif
{
- GST_LOG_OBJECT (ximagesrc,
- "Retrieving damaged sub-region @ %d,%d size %dx%d",
- dev->area.x, dev->area.y, dev->area.width, dev->area.height);
-
- XGetSubImage (ximagesrc->xcontext->disp, ximagesrc->xwindow,
- dev->area.x, dev->area.y,
- dev->area.width, dev->area.height,
- AllPlanes, ZPixmap, ximage->ximage, dev->area.x, dev->area.y);
+ /* if we only want a small area, clip this damage region to
+ * area we want */
+ if (ximagesrc->endx > ximagesrc->startx &&
+ ximagesrc->endy > ximagesrc->starty) {
+ /* see if damage area intersects */
+ if (dev->area.x + dev->area.width < ximagesrc->startx ||
+ dev->area.x > ximagesrc->endx) {
+ /* trivial reject */
+ } else if (dev->area.y + dev->area.height < ximagesrc->starty ||
+ dev->area.y > ximagesrc->endy) {
+ /* trivial reject */
+ } else {
+ /* find intersect region */
+ int startx, starty, width, height;
+
+ startx = (dev->area.x < ximagesrc->startx) ? ximagesrc->startx :
+ dev->area.x;
+ starty = (dev->area.y < ximagesrc->starty) ? ximagesrc->starty :
+ dev->area.y;
+ width = (dev->area.x + dev->area.width < ximagesrc->endx) ?
+ dev->area.x + dev->area.width - startx :
+ ximagesrc->endx - startx;
+ height = (dev->area.y + dev->area.height < ximagesrc->endy) ?
+ dev->area.y + dev->area.height - starty : ximagesrc->endy -
+ starty;
+ GST_LOG_OBJECT (ximagesrc,
+ "Retrieving damaged sub-region @ %d,%d size %dx%d as intersect region",
+ startx, starty, width, height);
+ XGetSubImage (ximagesrc->xcontext->disp, ximagesrc->xwindow,
+ startx, starty, width, height, AllPlanes, ZPixmap,
+ ximage->ximage, startx - ximagesrc->startx,
+ starty - ximagesrc->starty);
+ }
+ } else {
+
+ GST_LOG_OBJECT (ximagesrc,
+ "Retrieving damaged sub-region @ %d,%d size %dx%d",
+ dev->area.x, dev->area.y, dev->area.width, dev->area.height);
+
+ XGetSubImage (ximagesrc->xcontext->disp, ximagesrc->xwindow,
+ dev->area.x, dev->area.y,
+ dev->area.width, dev->area.height,
+ AllPlanes, ZPixmap, ximage->ximage, dev->area.x, dev->area.y);
+ }
}
}
} while (XPending (ximagesrc->xcontext->disp));
XDamageSubtract (ximagesrc->xcontext->disp, ximagesrc->damage, None, None);
#ifdef HAVE_XFIXES
- /* re-get area where last mouse pointer was */
+ /* re-get area where last mouse pointer was but only if in our clipping
+ * bounds */
if (ximagesrc->cursor_image) {
gint x, y, width, height;
@@ -436,24 +477,50 @@ gst_ximage_src_ximage_get (GstXImageSrc * ximagesrc)
x = 0;
if (y < 0)
y = 0;
- if (x + width > ximagesrc->width)
- width = ximagesrc->width - x;
- if (y + height > ximagesrc->height)
- height = ximagesrc->height - y;
+ if (x + width > ximagesrc->xcontext->width)
+ width = ximagesrc->xcontext->width - x;
+ if (y + height > ximagesrc->xcontext->height)
+ height = ximagesrc->xcontext->height - y;
g_assert (x >= 0);
g_assert (y >= 0);
+ GST_DEBUG_OBJECT (ximagesrc,
+ "Cursor was at (%d,%d) width: %d, height: %d and our range is: (%d,%d) - (%d,%d)",
+ x, y, width, height, ximagesrc->startx, ximagesrc->starty,
+ ximagesrc->endx, ximagesrc->endy);
+ /* only get where cursor last was, if it is in our range */
+ if (ximagesrc->endx > ximagesrc->startx &&
+ ximagesrc->endy > ximagesrc->starty) {
+ /* check bounds */
+ if (x + width < ximagesrc->startx || x > ximagesrc->endx) {
+ /* trivial reject */
+ } else if (y + height < ximagesrc->starty || y > ximagesrc->endy) {
+ /* trivial reject */
+ } else {
+ /* find intersect region */
+ int startx, starty, iwidth, iheight;
+
+ startx = (x < ximagesrc->startx) ? ximagesrc->startx : x;
+ starty = (y < ximagesrc->starty) ? ximagesrc->starty : y;
+ iwidth = (x + width < ximagesrc->endx) ?
+ x + width - startx : ximagesrc->endx - startx;
+ iheight = (y + height < ximagesrc->endy) ?
+ y + height - starty : ximagesrc->endy - starty;
+ GST_DEBUG_OBJECT (ximagesrc, "Removing cursor from %d,%d", x, y);
+ XGetSubImage (ximagesrc->xcontext->disp, ximagesrc->xwindow,
+ startx, starty, iwidth, iheight, AllPlanes, ZPixmap,
+ ximage->ximage, startx - ximagesrc->startx,
+ starty - ximagesrc->starty);
+ }
+ } else {
- GST_DEBUG_OBJECT (ximagesrc, "Removing cursor from %d,%d", x, y);
- XGetSubImage (ximagesrc->xcontext->disp, ximagesrc->xwindow,
- x, y, width, height, AllPlanes, ZPixmap, ximage->ximage, x, y);
+ GST_DEBUG_OBJECT (ximagesrc, "Removing cursor from %d,%d", x, y);
+ XGetSubImage (ximagesrc->xcontext->disp, ximagesrc->xwindow,
+ x, y, width, height, AllPlanes, ZPixmap, ximage->ximage, x, y);
+ }
}
#endif
- } else if (ximagesrc->have_xdamage && ximagesrc->damage) {
- /* Free up XDamage we allocated earlier when we did not know whether
- * we wanted to use damage or not */
- XDamageDestroy (ximagesrc->xcontext->disp, ximagesrc->damage);
} else {
#endif
@@ -461,14 +528,15 @@ gst_ximage_src_ximage_get (GstXImageSrc * ximagesrc)
if (ximagesrc->xcontext->use_xshm) {
GST_DEBUG_OBJECT (ximagesrc, "Retrieving screen using XShm");
XShmGetImage (ximagesrc->xcontext->disp, ximagesrc->xwindow,
- ximage->ximage, 0, 0, AllPlanes);
+ ximage->ximage, ximagesrc->startx, ximagesrc->starty, AllPlanes);
} else
#endif /* HAVE_XSHM */
{
GST_DEBUG_OBJECT (ximagesrc, "Retrieving screen using XGetImage");
ximage->ximage = XGetImage (ximagesrc->xcontext->disp, ximagesrc->xwindow,
- 0, 0, ximagesrc->width, ximagesrc->height, AllPlanes, ZPixmap);
+ ximagesrc->startx, ximagesrc->starty, ximagesrc->width,
+ ximagesrc->height, AllPlanes, ZPixmap);
}
#ifdef HAVE_XDAMAGE
}
@@ -482,6 +550,9 @@ gst_ximage_src_ximage_get (GstXImageSrc * ximagesrc)
ximagesrc->cursor_image = XFixesGetCursorImage (ximagesrc->xcontext->disp);
if (ximagesrc->cursor_image != NULL) {
int cx, cy, i, j, count;
+ int startx, starty, iwidth, iheight;
+ gboolean clipped = FALSE;
+ gboolean cursor_in_image = TRUE;
cx = ximagesrc->cursor_image->x - ximagesrc->cursor_image->xhot;
if (cx < 0)
@@ -490,28 +561,64 @@ gst_ximage_src_ximage_get (GstXImageSrc * ximagesrc)
if (cy < 0)
cy = 0;
count = ximagesrc->cursor_image->width * ximagesrc->cursor_image->height;
- for (i = 0; i < count; i++)
- ximagesrc->cursor_image->pixels[i] =
- GUINT_TO_LE (ximagesrc->cursor_image->pixels[i]);
-
- /* copy those pixels across */
- for (j = cy;
- j < cy + ximagesrc->cursor_image->height && j < ximagesrc->height;
- j++) {
- for (i = cx;
- i < cx + ximagesrc->cursor_image->width && i < ximagesrc->width;
- i++) {
- guint8 *src, *dest;
-
- src =
- (guint8 *) & (ximagesrc->cursor_image->pixels[((j -
- cy) * ximagesrc->cursor_image->width + (i - cx))]);
- dest =
- (guint8 *) & (ximage->ximage->data[(j * ximagesrc->width +
- i) * (ximagesrc->xcontext->bpp / 8)]);
-
- composite_pixel (ximagesrc->xcontext, (guint8 *) dest,
- (guint8 *) src);
+
+ /* only get where cursor last was, if it is in our range */
+ if (ximagesrc->endx > ximagesrc->startx &&
+ ximagesrc->endy > ximagesrc->starty) {
+ /* check bounds */
+ if (cx + ximagesrc->cursor_image->width < ximagesrc->startx ||
+ cx > ximagesrc->endx) {
+ /* trivial reject */
+ cursor_in_image = FALSE;
+ } else if (cy + ximagesrc->cursor_image->height < ximagesrc->starty ||
+ cy > ximagesrc->endy) {
+ /* trivial reject */
+ cursor_in_image = FALSE;
+ } else {
+ /* find intersect region */
+
+ startx = (cx < ximagesrc->startx) ? ximagesrc->startx : cx;
+ starty = (cy < ximagesrc->starty) ? ximagesrc->starty : cy;
+ iwidth = (cx + ximagesrc->cursor_image->width < ximagesrc->endx) ?
+ cx + ximagesrc->cursor_image->width - startx :
+ ximagesrc->endx - startx;
+ iheight = (cy + ximagesrc->cursor_image->height < ximagesrc->endy) ?
+ cy + ximagesrc->cursor_image->height - starty :
+ ximagesrc->endy - starty;
+ clipped = TRUE;
+ }
+ } else {
+ startx = cx;
+ starty = cy;
+ iwidth = ximagesrc->cursor_image->width;
+ iheight = ximagesrc->cursor_image->height;
+ }
+
+ if (cursor_in_image) {
+ GST_DEBUG_OBJECT (ximagesrc, "Cursor is in image so trying to draw it");
+ for (i = 0; i < count; i++)
+ ximagesrc->cursor_image->pixels[i] =
+ GUINT_TO_LE (ximagesrc->cursor_image->pixels[i]);
+
+ /* copy those pixels across */
+ for (j = starty;
+ j < starty + iheight && j - starty < ximagesrc->height; j++) {
+ for (i = startx;
+ i < startx + iwidth && i - startx < ximagesrc->width; i++) {
+ guint8 *src, *dest;
+
+ src =
+ (guint8 *) & (ximagesrc->cursor_image->pixels[((j -
+ cy) * ximagesrc->cursor_image->width + (i - cx))]);
+ dest =
+ (guint8 *) & (ximage->ximage->data[((j -
+ ximagesrc->starty) * ximagesrc->width + (i -
+ ximagesrc->startx)) * (ximagesrc->xcontext->bpp /
+ 8)]);
+
+ composite_pixel (ximagesrc->xcontext, (guint8 *) dest,
+ (guint8 *) src);
+ }
}
}
}
@@ -630,6 +737,18 @@ gst_ximage_src_set_property (GObject * object, guint prop_id,
case PROP_USE_DAMAGE:
src->use_damage = g_value_get_boolean (value);
break;
+ case PROP_STARTX:
+ src->startx = g_value_get_uint (value);
+ break;
+ case PROP_STARTY:
+ src->starty = g_value_get_uint (value);
+ break;
+ case PROP_ENDX:
+ src->endx = g_value_get_uint (value);
+ break;
+ case PROP_ENDY:
+ src->endy = g_value_get_uint (value);
+ break;
default:
break;
}
@@ -657,6 +776,19 @@ gst_ximage_src_get_property (GObject * object, guint prop_id, GValue * value,
break;
case PROP_USE_DAMAGE:
g_value_set_boolean (value, src->use_damage);
+ break;
+ case PROP_STARTX:
+ g_value_set_uint (value, src->startx);
+ break;
+ case PROP_STARTY:
+ g_value_set_uint (value, src->starty);
+ break;
+ case PROP_ENDX:
+ g_value_set_uint (value, src->endx);
+ break;
+ case PROP_ENDY:
+ g_value_set_uint (value, src->endy);
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
break;
@@ -713,6 +845,7 @@ gst_ximage_src_get_caps (GstBaseSrc * bs)
{
GstXImageSrc *s = GST_XIMAGE_SRC (bs);
GstXContext *xcontext;
+ gint x, y, width, height;
if ((!s->xcontext) && (!gst_ximage_src_open_display (s, NULL)))
return gst_caps_copy (gst_pad_get_pad_template_caps (GST_BASE_SRC (s)->
@@ -724,6 +857,34 @@ gst_ximage_src_get_caps (GstBaseSrc * bs)
xcontext = s->xcontext;
+ x = y = 0;
+ width = xcontext->width;
+ height = xcontext->height;
+ if (s->endx > s->startx && s->endy > s->starty) {
+ /* this means user has put in values */
+ if (s->startx < xcontext->width && s->endx < xcontext->width &&
+ s->starty < xcontext->height && s->endy < xcontext->height) {
+ /* values are fine */
+ x = s->startx;
+ y = s->starty;
+ s->width = width = s->endx - s->startx;
+ s->height = height = s->endy - s->starty;
+ } else {
+ GST_WARNING
+ ("User put in co-ordinates overshooting the X resolution, setting to full screen");
+ s->startx = 0;
+ s->starty = 0;
+ s->endx = 0;
+ s->endy = 0;
+ }
+ } else {
+ GST_WARNING ("User put in bogus co-ordinates, setting to full screen");
+ s->startx = 0;
+ s->starty = 0;
+ s->endx = 0;
+ s->endy = 0;
+ }
+ GST_DEBUG ("width = %d, height=%d", width, height);
return gst_caps_new_simple ("video/x-raw-rgb",
"bpp", G_TYPE_INT, xcontext->bpp,
"depth", G_TYPE_INT, xcontext->depth,
@@ -731,8 +892,8 @@ gst_ximage_src_get_caps (GstBaseSrc * bs)
"red_mask", G_TYPE_INT, xcontext->r_mask_output,
"green_mask", G_TYPE_INT, xcontext->g_mask_output,
"blue_mask", G_TYPE_INT, xcontext->b_mask_output,
- "width", G_TYPE_INT, xcontext->width,
- "height", G_TYPE_INT, xcontext->height,
+ "width", G_TYPE_INT, width,
+ "height", G_TYPE_INT, height,
"framerate", GST_TYPE_FRACTION_RANGE, 1, G_MAXINT, G_MAXINT, 1,
"pixel-aspect-ratio", GST_TYPE_FRACTION_RANGE, 1, G_MAXINT, G_MAXINT, 1,
NULL);
@@ -799,10 +960,26 @@ gst_ximage_src_class_init (GstXImageSrcClass * klass)
g_param_spec_boolean ("show_pointer", "Show Mouse Pointer",
"Show mouse pointer (if XFixes extension enabled)", TRUE,
G_PARAM_READWRITE));
- g_object_class_install_property (gc, PROP_SHOW_POINTER,
+ g_object_class_install_property (gc, PROP_USE_DAMAGE,
g_param_spec_boolean ("use_damage", "Use XDamage",
"Use XDamage (if XDamage extension enabled)", TRUE,
G_PARAM_READWRITE));
+ g_object_class_install_property (gc, PROP_STARTX,
+ g_param_spec_uint ("startx", "Start X co-ordinate",
+ "X coordinate of top left corner of area to be recorded (0 for top left of screen)",
+ 0, G_MAXINT, 0, G_PARAM_READWRITE));
+ g_object_class_install_property (gc, PROP_STARTY,
+ g_param_spec_uint ("starty", "Start Y co-ordinate",
+ "Y coordinate of top left corner of area to be recorded (0 for top left of screen)",
+ 0, G_MAXINT, 0, G_PARAM_READWRITE));
+ g_object_class_install_property (gc, PROP_ENDX,
+ g_param_spec_uint ("endx", "End X",
+ "X coordinate of bottom right corner of area to be recorded (0 for bottom right of screen)",
+ 0, G_MAXINT, 0, G_PARAM_READWRITE));
+ g_object_class_install_property (gc, PROP_ENDY,
+ g_param_spec_uint ("endy", "End Y",
+ "Y coordinate of bottom right corner of area to be recorded (0 for bottom right of screen)",
+ 0, G_MAXINT, 0, G_PARAM_READWRITE));
parent_class = g_type_class_peek_parent (klass);
@@ -825,6 +1002,10 @@ gst_ximage_src_init (GstXImageSrc * ximagesrc, GstXImageSrcClass * klass)
ximagesrc->x_lock = g_mutex_new ();
ximagesrc->show_pointer = TRUE;
ximagesrc->use_damage = TRUE;
+ ximagesrc->startx = 0;
+ ximagesrc->starty = 0;
+ ximagesrc->endx = 0;
+ ximagesrc->endy = 0;
}
static gboolean
diff --git a/sys/ximage/gstximagesrc.h b/sys/ximage/gstximagesrc.h
index dead37d2..c56870c2 100644
--- a/sys/ximage/gstximagesrc.h
+++ b/sys/ximage/gstximagesrc.h
@@ -76,6 +76,13 @@ struct _GstXImageSrc
gboolean have_xdamage;
gboolean show_pointer;
gboolean use_damage;
+
+ /* co-ordinates for start and end */
+ guint startx;
+ guint starty;
+ guint endx;
+ guint endy;
+
#ifdef HAVE_XFIXES
int fixes_event_base;
XFixesCursorImage *cursor_image;