Esempio n. 1
0
int BC_XImage::read_drawable(Drawable &pixmap, int source_x, int source_y)
{
	XGetSubImage(top_level->display, pixmap,
		source_x, source_y, bitmap->w, bitmap->h,
		0xffffffff, ZPixmap, ximage, 0, 0);
	return 0;
}
Esempio n. 2
0
static void
swrastGetImage2(__DRIdrawable * read,
                int x, int y, int w, int h, int stride,
                char *data, void *loaderPrivate)
{
   struct drisw_drawable *prp = loaderPrivate;
   __GLXDRIdrawable *pread = &(prp->base);
   Display *dpy = pread->psc->dpy;
   Drawable readable;
   XImage *ximage;

   if (!prp->ximage || prp->shminfo.shmid >= 0) {
      if (!XCreateDrawable(prp, -1, dpy))
         return;
   }

   readable = pread->xDrawable;

   ximage = prp->ximage;
   ximage->data = data;
   ximage->width = w;
   ximage->height = h;
   ximage->bytes_per_line = stride ? stride : bytes_per_line(w * ximage->bits_per_pixel, 32);

   XGetSubImage(dpy, readable, x, y, w, h, ~0L, ZPixmap, ximage, 0, 0);

   ximage->data = NULL;
}
Esempio n. 3
0
// the bitmap must be wholly contained in the source during a GetImage
int BC_Bitmap::read_drawable(Drawable &pixmap, int source_x, int source_y)
{
    if(use_shm)
        XShmGetImage(top_level->display, pixmap, ximage[current_ringbuffer], source_x, source_y, 0xffffffff);
    else
        XGetSubImage(top_level->display, pixmap, source_x, source_y, w, h, 0xffffffff, ZPixmap, ximage[current_ringbuffer], 0, 0);
    return 0;
}
Esempio n. 4
0
Bool
get_xshm_image (Display *dpy, Drawable d, XImage *image, int x, int y,
                unsigned long plane_mask, XShmSegmentInfo *shm_info)
{
#ifdef HAVE_XSHM_EXTENSION
  if (shm_info->shmid != -1) {
    return XShmGetImage (dpy, d, image, x, y, plane_mask);
  }
#endif /* HAVE_XSHM_EXTENSION */
  return XGetSubImage (dpy, d, x, y, image->width, image->height, plane_mask,
                       image->format, image, 0, 0) != NULL;
}
Esempio n. 5
0
static struct fbuf_t *grab_x11_read(void *desc)
{
	/* read frame from X11 */
	struct grab_x11_desc *v = desc;
	struct fbuf_t *b = &v->b;

	XGetSubImage(v->dpy,
		RootWindow(v->dpy, DefaultScreen(v->dpy)),
			b->x, b->y, b->w, b->h, AllPlanes, ZPixmap, v->image, 0, 0);

	b->data = (uint8_t *)v->image->data;
	return b;
}
Esempio n. 6
0
int fbx_read(fbx_struct *fb, int x_, int y_)
{
	int x, y;
	#ifdef _WIN32
	fbx_gc gc;
	#endif

	if(!fb) _throw("Invalid argument");

	x=x_>=0? x_:0;  y=y_>=0? y_:0;

	#ifdef _WIN32

	if(!fb->hmdc || fb->width<=0 || fb->height<=0 || !fb->bits || !fb->wh)
		_throw("Not initialized");
	_w32(gc=GetDC(fb->wh));
	_w32(BitBlt(fb->hmdc, 0, 0, fb->width, fb->height, gc, x, y, SRCCOPY));
	_w32(ReleaseDC(fb->wh, gc));
	return 0;

	#else

	if(!fb->wh.dpy || !fb->wh.d || !fb->xi || !fb->bits)
		_throw("Not initialized");
	#ifdef USESHM
	if(!fb->xattach && fb->shm)
	{
		_x11(XShmAttach(fb->wh.dpy, &fb->shminfo));  fb->xattach=1;
	}
	#endif

	#ifdef USESHM
	if(fb->shm)
	{
		_x11(XShmGetImage(fb->wh.dpy, fb->wh.d, fb->xi, x, y, AllPlanes));
	}
	else
	#endif
	{
		_x11(XGetSubImage(fb->wh.dpy, fb->wh.d, x, y, fb->width, fb->height,
			AllPlanes, ZPixmap, fb->xi, 0, 0));
	}
	return 0;

	#endif

	finally:
	return -1;
}
Esempio n. 7
0
static void
swrastGetImage(__DRIdrawable * draw,
               int x, int y, int w, int h, char *data, void *loaderPrivate)
{
   __GLXDRIdrawablePrivate *pdp = loaderPrivate;
   __GLXDRIdrawable *pdraw = &(pdp->base);
   Display *dpy = pdraw->psc->dpy;
   Drawable drawable;
   XImage *ximage;

   drawable = pdraw->xDrawable;

   ximage = pdp->ximage;
   ximage->data = data;
   ximage->width = w;
   ximage->height = h;
   ximage->bytes_per_line = bytes_per_line(w, pdp->bpp, 32);

   XGetSubImage(dpy, drawable, x, y, w, h, ~0L, ZPixmap, ximage, 0, 0);

   ximage->data = NULL;
}
int BC_Capture::capture_frame(VFrame *frame, int &x1, int &y1)
{
    if(!display) return 1;
    if(x1 < 0) x1 = 0;
    if(y1 < 0) y1 = 0;
    if(x1 > get_top_w() - w) x1 = get_top_w() - w;
    if(y1 > get_top_h() - h) y1 = get_top_h() - h;


// Read the raw data
    if(use_shm)
        XShmGetImage(display, rootwin, ximage, x1, y1, 0xffffffff);
    else
        XGetSubImage(display, rootwin, x1, y1, w, h, 0xffffffff, ZPixmap, ximage, 0, 0);

    BC_WindowBase::get_cmodels()->transfer(frame->get_rows(),
                                           row_data,
                                           frame->get_y(),
                                           frame->get_u(),
                                           frame->get_v(),
                                           0,
                                           0,
                                           0,
                                           0,
                                           0,
                                           w,
                                           h,
                                           0,
                                           0,
                                           frame->get_w(),
                                           frame->get_h(),
                                           bitmap_color_model,
                                           frame->get_color_model(),
                                           0,
                                           frame->get_w(),
                                           w);

    return 0;
}
Esempio n. 9
0
XImage*
_xgetxdata(Memimage *m, Rectangle r)
{
	int x, y;
	uchar *p;
	Point tp, xdelta, delta;
	Xmem *xm;
	
	xm = m->X;
	if(xm == nil)
		return nil;

	if(xm->dirty == 0)
		return xm->xi;

	abort();	/* should never call this now */

	r = xm->dirtyr;
	if(Dx(r)==0 || Dy(r)==0)
		return xm->xi;

	delta = subpt(r.min, m->r.min);

	tp = xm->r.min;	/* need temp for Digital UNIX */
	xdelta = subpt(r.min, tp);

	XGetSubImage(_x.display, xm->pixmap, delta.x, delta.y, Dx(r), Dy(r),
		AllPlanes, ZPixmap, xm->xi, xdelta.x, delta.y);

	if(_x.usetable && m->chan==CMAP8){
		for(y=r.min.y; y<r.max.y; y++)
		for(x=r.min.x, p=byteaddr(m, Pt(x,y)); x<r.max.x; x++, p++)
			*p = _x.toplan9[*p];
	}
	xm->dirty = 0;
	xm->dirtyr = Rect(0,0,0,0);
	return xm->xi;
}
Esempio n. 10
0
static void
swrastGetImage(__DRIdrawable * read,
               int x, int y, int w, int h,
               char *data, void *loaderPrivate)
{
   struct drisw_drawable *prp = loaderPrivate;
   __GLXDRIdrawable *pread = &(prp->base);
   Display *dpy = pread->psc->dpy;
   Drawable readable;
   XImage *ximage;

   readable = pread->xDrawable;

   ximage = prp->ximage;
   ximage->data = data;
   ximage->width = w;
   ximage->height = h;
   ximage->bytes_per_line = bytes_per_line(w * ximage->bits_per_pixel, 32);

   XGetSubImage(dpy, readable, x, y, w, h, ~0L, ZPixmap, ximage, 0, 0);

   ximage->data = NULL;
}
Esempio n. 11
0
static DFBResult
x11Read( CoreSurfacePool       *pool,
         void                  *pool_data,
         void                  *pool_local,
         CoreSurfaceAllocation *allocation,
         void                  *alloc_data,
         void                  *destination,
         int                    pitch,
         const DFBRectangle    *rect )
{
     XImage            *image;
     XImage            *sub;
     x11PoolLocalData  *local = pool_local;
     x11AllocationData *alloc = alloc_data;
     DFBX11            *x11   = local->x11;

     D_DEBUG_AT( X11_Surfaces, "%s( %p )\n", __FUNCTION__, allocation );
     D_DEBUG_AT( X11_Surfaces, "  -> allocation: %s\n", ToString_CoreSurfaceAllocation( allocation ) );

     D_MAGIC_ASSERT( pool, CoreSurfacePool );
     D_MAGIC_ASSERT( allocation, CoreSurfaceAllocation );
     D_ASSERT( destination != NULL );
     D_ASSERT( pitch >= 0 );
     DFB_RECTANGLE_ASSERT( rect );

     D_DEBUG_AT( X11_Surfaces, "  => %p 0x%08lx [%4d,%4d-%4dx%4d]\n", alloc, alloc->xid, DFB_RECTANGLE_VALS(rect) );


     XLockDisplay( x11->display );

#if 1
     image = XCreateImage( x11->display, alloc->visual, alloc->depth, ZPixmap, 0, destination, rect->w, rect->h, 32, pitch );
     if (!image) {
          D_ERROR( "X11/Surfaces: XCreateImage( %dx%d, depth %d ) failed!\n", rect->w, rect->h, alloc->depth );
          XUnlockDisplay( x11->display );
          return DFB_FAILURE;
     }

     sub = XGetSubImage( x11->display, alloc->xid, rect->x, rect->y, rect->w, rect->h, ~0, ZPixmap, image, 0, 0 );
#else
     image = XGetImage( x11->display, alloc->window ? alloc->window : alloc->xid,
                        rect->x, rect->y, rect->w, rect->h, ~0, ZPixmap );
#endif

     if (image) {
//          dfb_surface_buffer_dump_type_locked2( allocation->buffer, ".", "x11Read", false, image->data, image->bytes_per_line );

          /* FIXME: Why the X-hell is XDestroyImage() freeing *MY* data? */
          image->data = NULL;
          XDestroyImage( image );
     }

     XUnlockDisplay( x11->display );

#if 1
     if (!sub) {
          D_ERROR( "X11/Surfaces: XGetSubImage( %d,%d-%dx%d ) failed!\n", DFB_RECTANGLE_VALS(rect) );
          return DFB_FAILURE;
     }
#endif
     return DFB_OK;
}
Esempio n. 12
0
static void
_cogl_texture_pixmap_x11_update_image_texture (CoglTexturePixmapX11 *tex_pixmap)
{
  CoglTexture *tex = COGL_TEXTURE (tex_pixmap);
  Display *display;
  Visual *visual;
  CoglPixelFormat image_format;
  XImage *image;
  int src_x, src_y;
  int x, y, width, height;
  int bpp;
  int offset;
  CoglError *ignore = NULL;

  _COGL_GET_CONTEXT (ctx, NO_RETVAL);

  display = cogl_xlib_renderer_get_display (ctx->display->renderer);
  visual = tex_pixmap->visual;

  /* If the damage region is empty then there's nothing to do */
  if (tex_pixmap->damage_rect.x2 == tex_pixmap->damage_rect.x1)
    return;

  x = tex_pixmap->damage_rect.x1;
  y = tex_pixmap->damage_rect.y1;
  width = tex_pixmap->damage_rect.x2 - x;
  height = tex_pixmap->damage_rect.y2 - y;

  /* We lazily create the texture the first time it is needed in case
     this texture can be entirely handled using the GLX texture
     instead */
  if (tex_pixmap->tex == NULL)
    {
      CoglPixelFormat texture_format;

      texture_format = (tex_pixmap->depth >= 32
                        ? COGL_PIXEL_FORMAT_RGBA_8888_PRE
                        : COGL_PIXEL_FORMAT_RGB_888);

      tex_pixmap->tex = create_fallback_texture (ctx,
                                                 tex->width,
                                                 tex->height,
                                                 texture_format);
    }

  if (tex_pixmap->image == NULL)
    {
      /* If we also haven't got a shm segment then this must be the
         first time we've tried to update, so lets try allocating shm
         first */
      if (tex_pixmap->shm_info.shmid == -1)
        try_alloc_shm (tex_pixmap);

      if (tex_pixmap->shm_info.shmid == -1)
        {
          COGL_NOTE (TEXTURE_PIXMAP, "Updating %p using XGetImage", tex_pixmap);

          /* We'll fallback to using a regular XImage. We'll download
             the entire area instead of a sub region because presumably
             if this is the first update then the entire pixmap is
             needed anyway and it saves trying to manually allocate an
             XImage at the right size */
          tex_pixmap->image = XGetImage (display,
                                         tex_pixmap->pixmap,
                                         0, 0,
                                         tex->width, tex->height,
                                         AllPlanes, ZPixmap);
          image = tex_pixmap->image;
          src_x = x;
          src_y = y;
        }
      else
        {
          COGL_NOTE (TEXTURE_PIXMAP, "Updating %p using XShmGetImage",
                     tex_pixmap);

          /* Create a temporary image using the beginning of the
             shared memory segment and the right size for the region
             we want to update. We need to reallocate the XImage every
             time because there is no XShmGetSubImage. */
          image = XShmCreateImage (display,
                                   tex_pixmap->visual,
                                   tex_pixmap->depth,
                                   ZPixmap,
                                   NULL,
                                   &tex_pixmap->shm_info,
                                   width,
                                   height);
          image->data = tex_pixmap->shm_info.shmaddr;
          src_x = 0;
          src_y = 0;

          XShmGetImage (display, tex_pixmap->pixmap, image, x, y, AllPlanes);
        }
    }
  else
    {
      COGL_NOTE (TEXTURE_PIXMAP, "Updating %p using XGetSubImage", tex_pixmap);

      image = tex_pixmap->image;
      src_x = x;
      src_y = y;

      XGetSubImage (display,
                    tex_pixmap->pixmap,
                    x, y, width, height,
                    AllPlanes, ZPixmap,
                    image,
                    x, y);
    }

  image_format =
    _cogl_util_pixel_format_from_masks (visual->red_mask,
                                        visual->green_mask,
                                        visual->blue_mask,
                                        image->depth,
                                        image->bits_per_pixel,
                                        image->byte_order == LSBFirst);

  bpp = _cogl_pixel_format_get_bytes_per_pixel (image_format);
  offset = image->bytes_per_line * src_y + bpp * src_x;

  _cogl_texture_set_region (tex_pixmap->tex,
                            width,
                            height,
                            image_format,
                            image->bytes_per_line,
                            ((const uint8_t *) image->data) + offset,
                            x, y,
                            0, /* level */
                            &ignore);

  /* If we have a shared memory segment then the XImage would be a
     temporary one with no data allocated so we can just XFree it */
  if (tex_pixmap->shm_info.shmid != -1)
    XFree (image);

  memset (&tex_pixmap->damage_rect, 0, sizeof (CoglDamageRectangle));
}
Esempio n. 13
0
static void
_cogl_texture_pixmap_x11_update_image_texture (CoglTexturePixmapX11 *tex_pixmap)
{
  Display *display;
  CoglPixelFormat image_format;
  XImage *image;
  int src_x, src_y;
  int x, y, width, height;

  display = cogl_xlib_get_display ();

  /* If the damage region is empty then there's nothing to do */
  if (tex_pixmap->damage_rect.x2 == tex_pixmap->damage_rect.x1)
    return;

  x = tex_pixmap->damage_rect.x1;
  y = tex_pixmap->damage_rect.y1;
  width = tex_pixmap->damage_rect.x2 - x;
  height = tex_pixmap->damage_rect.y2 - y;

  /* We lazily create the texture the first time it is needed in case
     this texture can be entirely handled using the GLX texture
     instead */
  if (tex_pixmap->tex == COGL_INVALID_HANDLE)
    {
      CoglPixelFormat texture_format;

      texture_format = (tex_pixmap->depth >= 32
                        ? COGL_PIXEL_FORMAT_RGBA_8888_PRE
                        : COGL_PIXEL_FORMAT_RGB_888);

      tex_pixmap->tex = cogl_texture_new_with_size (tex_pixmap->width,
                                                    tex_pixmap->height,
                                                    COGL_TEXTURE_NONE,
                                                    texture_format);
    }

  if (tex_pixmap->image == NULL)
    {
      /* If we also haven't got a shm segment then this must be the
         first time we've tried to update, so lets try allocating shm
         first */
      if (tex_pixmap->shm_info.shmid == -1)
        try_alloc_shm (tex_pixmap);

      if (tex_pixmap->shm_info.shmid == -1)
        {
          COGL_NOTE (TEXTURE_PIXMAP, "Updating %p using XGetImage", tex_pixmap);

          /* We'll fallback to using a regular XImage. We'll download
             the entire area instead of a sub region because presumably
             if this is the first update then the entire pixmap is
             needed anyway and it saves trying to manually allocate an
             XImage at the right size */
          tex_pixmap->image = XGetImage (display,
                                         tex_pixmap->pixmap,
                                         0, 0,
                                         tex_pixmap->width, tex_pixmap->height,
                                         AllPlanes, ZPixmap);
          image = tex_pixmap->image;
          src_x = x;
          src_y = y;
        }
      else
        {
          COGL_NOTE (TEXTURE_PIXMAP, "Updating %p using XShmGetImage",
                     tex_pixmap);

          /* Create a temporary image using the beginning of the
             shared memory segment and the right size for the region
             we want to update. We need to reallocate the XImage every
             time because there is no XShmGetSubImage. */
          image = XShmCreateImage (display,
                                   tex_pixmap->visual,
                                   tex_pixmap->depth,
                                   ZPixmap,
                                   NULL,
                                   &tex_pixmap->shm_info,
                                   width,
                                   height);
          image->data = tex_pixmap->shm_info.shmaddr;
          src_x = 0;
          src_y = 0;

          XShmGetImage (display, tex_pixmap->pixmap, image, x, y, AllPlanes);
        }
    }
  else
    {
      COGL_NOTE (TEXTURE_PIXMAP, "Updating %p using XGetSubImage", tex_pixmap);

      image = tex_pixmap->image;
      src_x = x;
      src_y = y;

      XGetSubImage (display,
                    tex_pixmap->pixmap,
                    x, y, width, height,
                    AllPlanes, ZPixmap,
                    image,
                    x, y);
    }

  /* xlib doesn't appear to fill in image->{red,green,blue}_mask so
     this just assumes that the image is stored as ARGB from most
     significant byte to to least significant. If the format is little
     endian that means the order will be BGRA in memory */

  switch (image->bits_per_pixel)
    {
    default:
    case 32:
      {
        /* If the pixmap is actually non-packed-pixel RGB format then
           the texture would have been created in RGB_888 format so Cogl
           will ignore the alpha channel and effectively pack it for
           us */
        image_format = COGL_PIXEL_FORMAT_RGBA_8888_PRE;

        /* If the format is actually big endian then the alpha
           component will come first */
        if (image->byte_order == MSBFirst)
          image_format |= COGL_AFIRST_BIT;
      }
      break;

    case 24:
      image_format = COGL_PIXEL_FORMAT_RGB_888;
      break;

    case 16:
      /* FIXME: this should probably swap the orders around if the
         endianness does not match */
      image_format = COGL_PIXEL_FORMAT_RGB_565;
      break;
    }

  if (image->bits_per_pixel != 16)
    {
      /* If the image is in little-endian then the order in memory is
         reversed */
      if (image->byte_order == LSBFirst)
        image_format |= COGL_BGR_BIT;
    }

  cogl_texture_set_region (tex_pixmap->tex,
                           src_x, src_y,
                           x, y, width, height,
                           image->width,
                           image->height,
                           image_format,
                           image->bytes_per_line,
                           (const guint8 *) image->data);

  /* If we have a shared memory segment then the XImage would be a
     temporary one with no data allocated so we can just XFree it */
  if (tex_pixmap->shm_info.shmid != -1)
    XFree (image);

  memset (&tex_pixmap->damage_rect, 0, sizeof (CoglDamageRectangle));
}
static void
clutter_x11_texture_pixmap_update_area_real (ClutterX11TexturePixmap *texture,
                                             gint                     x,
                                             gint                     y,
                                             gint                     width,
                                             gint                     height)
{
  ClutterX11TexturePixmapPrivate       *priv;
  Display                              *dpy;
  XImage                               *image;
  char				       *first_pixel;
  GError                               *error = NULL;
  guint                                 bytes_per_line;
  char				       *data;
  int                                   err_code;
  char                                  pixel_bpp;
  gboolean                              pixel_has_alpha;

#if 0
  clock_t start_t = clock();
#endif

  if (!CLUTTER_ACTOR_IS_REALIZED (texture))
    return;

  priv = texture->priv;
  dpy  = clutter_x11_get_default_display();

  if (!priv->pixmap)
    return;

  if (priv->shminfo.shmid == -1)
    try_alloc_shm (texture);

  clutter_x11_trap_x_errors ();

  if (priv->have_shm)
    {
      image =
	XShmCreateImage(dpy,
			DefaultVisual(dpy,
				      clutter_x11_get_default_screen()),
			priv->depth,
			ZPixmap,
			NULL,
			&priv->shminfo,
			width,
			height);
      image->data = priv->shminfo.shmaddr;

      XShmGetImage (dpy, priv->pixmap, image, x, y, AllPlanes);
      first_pixel = image->data;
    }
  else
    {
      if (!priv->image)
	{
          priv->image = XGetImage (dpy,
                                   priv->pixmap,
                                   0, 0,
                                   priv->pixmap_width, priv->pixmap_height,
                                   AllPlanes,
                                   ZPixmap);
          if (priv->image)
	    first_pixel = priv->image->data + priv->image->bytes_per_line * y
			  + x * priv->image->bits_per_pixel/8;
          else
            {
              g_warning ("%s: XGetImage() failed", __FUNCTION__);
              return;
            }
	}
      else
	{
          XGetSubImage (dpy,
                        priv->pixmap,
                        x, y,
                        width, height,
                        AllPlanes,
                        ZPixmap,
                        priv->image,
                        x, y);
	  first_pixel  = priv->image->data + priv->image->bytes_per_line * y
            + x * priv->image->bits_per_pixel/8;
	}
      image = priv->image;
    }

  XSync (dpy, FALSE);

  if ((err_code = clutter_x11_untrap_x_errors ()))
    {
      g_warning ("Failed to get XImage of pixmap: %lx, removing",
                 priv->pixmap);
      /* safe to assume pixmap has gone away? - therefor reset */
      clutter_x11_texture_pixmap_set_pixmap (texture, None);
      goto free_image_and_return;
    }

  if (priv->depth == 24)
    {
      bytes_per_line = image->bytes_per_line;
      data = first_pixel;
      pixel_bpp = 3;
      pixel_has_alpha = FALSE;
    }
  else if (priv->depth == 16)
    {
      bytes_per_line = image->bytes_per_line;
      data = first_pixel;
      pixel_bpp = 2;
      pixel_has_alpha = FALSE;
    }
  else if (priv->depth == 32)
    {
      bytes_per_line = image->bytes_per_line;
      data = first_pixel;
      pixel_bpp = 4;
      pixel_has_alpha = TRUE;
    }
  else
    goto free_image_and_return;

  if (!priv->allow_alpha)
    pixel_has_alpha = FALSE;

  /* For debugging purposes, un comment to simply generate dummy
   * pixmap data. (A Green background and Blue cross) */
#if 0
  {
    guint xpos, ypos;

    if (data_allocated)
      g_free (data);
    data_allocated = TRUE;
    data = g_malloc (width*height*4);
    bytes_per_line = width *4;

    for (ypos=0; ypos<height; ypos++)
      for (xpos=0; xpos<width; xpos++)
	{
	  char *p = data + width*4*ypos + xpos * 4;
	  guint32 *pixel = (guint32 *)p;
	  if ((xpos > width/2 && xpos <= (width/2) + width/4)
	      || (ypos > height/2 && ypos <= (height/2) + height/4))
	    *pixel=0xff0000ff;
	  else
	    *pixel=0xff00ff00;
	}
  }
#endif

  if (x != 0 || y != 0 ||
      width != priv->pixmap_width || height != priv->pixmap_height)
    clutter_texture_set_area_from_rgb_data  (CLUTTER_TEXTURE (texture),
					     (guint8 *)data,
					     pixel_has_alpha,
					     x, y,
					     width, height,
					     bytes_per_line,
					     pixel_bpp,
					     CLUTTER_TEXTURE_RGB_FLAG_BGR,
					     &error);
  else
    clutter_texture_set_from_rgb_data  (CLUTTER_TEXTURE (texture),
					(guint8 *)data,
					pixel_has_alpha,
					width, height,
					bytes_per_line,
					pixel_bpp,
					CLUTTER_TEXTURE_RGB_FLAG_BGR,
					&error);



  if (error)
    {
      g_warning ("Error when uploading from pixbuf: %s",
                 error->message);
      g_error_free (error);
    }

free_image_and_return:
  if (priv->have_shm)
    XFree (image);
#if 0
  clock_t end_t = clock();
  int time = (int)((double)(end_t - start_t) * (1000.0 / CLOCKS_PER_SEC));
  g_print("clutter-x11-update-area-real(%d,%d,%d,%d) %d bits - %d ms\n",x,y,width,height,priv->depth,time);
#endif
}
Esempio n. 15
0
void
screenhack_record_anim (record_anim_state *st)
{
  int bytes_per_line = st->xgwa.width * 3;
  double start_time = double_time();

# ifndef USE_GL

  Display *dpy = DisplayOfScreen (st->screen);
  char *data = (char *) st->img->data;

  /* Under XQuartz we can't just do XGetImage on the Window, we have to
     go through an intermediate Pixmap first.  I don't understand why.
     Also, the f*****g resize handle shows up as black.  God dammit.
     A workaround for that is to temporarily remove /opt/X11/bin/quartz-wm
   */
  XCopyArea (dpy, st->window, st->p, st->gc, 0, 0,
             st->xgwa.width, st->xgwa.height, 0, 0);
  XGetSubImage (dpy, st->p, 0, 0, st->xgwa.width, st->xgwa.height,
                ~0L, ZPixmap, st->img, 0, 0);

  /* Convert BGRA to RGB */
  {
    const char *in = st->img->data;
    char *out = st->img->data;
    int x, y;
    int w = st->img->width;
    int h = st->img->height;
    for (y = 0; y < h; y++)
      {
        const char *in2 = in;
        for (x = 0; x < w; x++)
          {
            *out++ = in2[2];
            *out++ = in2[1];
            *out++ = in2[0];
            in2 += 4;
          }
        in += st->img->bytes_per_line;
      }
  }
# else  /* USE_GL */

  char *data = st->data2;
  int y;

# ifdef HAVE_JWZGLES
#  undef glReadPixels /* Kludge -- unimplemented in the GLES compat layer */
# endif

  /* First OpenGL frame tends to be random data like a shot of my desktop,
     since it is the front buffer when we were drawing in the back buffer.
     Leave it black. */
  /* glDrawBuffer (GL_BACK); */
  if (st->frame_count != 0)
    glReadPixels (0, 0, st->xgwa.width, st->xgwa.height,
                  GL_RGB, GL_UNSIGNED_BYTE, st->data);

  /* Flip vertically */
  for (y = 0; y < st->xgwa.height; y++)
    memcpy (data      + bytes_per_line * y,
            st->data  + bytes_per_line * (st->xgwa.height - y - 1),
            bytes_per_line);

# endif /* USE_GL */


  if (st->frame_count < st->fade_frames)
    fade_frame (st, (unsigned char *) data,
                (double) st->frame_count / st->fade_frames);
  else if (st->frame_count >= st->target_frames - st->fade_frames)
    fade_frame (st, (unsigned char *) data,
                (double) (st->target_frames - st->frame_count - 1) /
                st->fade_frames);

# ifdef HAVE_GDK_PIXBUF
  {
    const char *type = "png";
    char fn[1024];
    GError *error = 0;
    GdkPixbuf *pixbuf;

    pixbuf = gdk_pixbuf_new_from_data ((guchar *) data,
                                       GDK_COLORSPACE_RGB, False, /* alpha */
                                       8, /* bits per sample */
                                       st->xgwa.width, st->xgwa.height,
                                       bytes_per_line,
                                       0, 0);

    sprintf (fn, "%s-%06d.%s", progname, st->frame_count, type);
    gdk_pixbuf_save (pixbuf, fn, type, &error, NULL);

    if (error)
      {
        fprintf (stderr, "%s: %s: %s\n", progname, fn, error->message);
        exit (1);
      }

    g_object_unref (pixbuf);
  }
# else  /* !HAVE_GDK_PIXBUF */
#  error GDK_PIXBUF is required
# endif /* !HAVE_GDK_PIXBUF */

# ifndef HAVE_JWXYZ
  {  /* Put percent done in window title */
    int pct = 100 * (st->frame_count + 1) / st->target_frames;
    if (pct != st->pct && st->title)
      {
        double end   = st->target_frames / (double) st->fps;
        double secs0 = double_time() - st->start_time;
        double secs  = double_timewarp() - st->start_time;
        double rate  = secs / secs0;
        double secs2 = (end - secs) / rate;
        Display *dpy = DisplayOfScreen (st->screen);
        char *t2 = (char *) malloc (strlen(st->title) + 100);
        if (secs2 < 0) secs2 = 0;

        sprintf (t2, "%s: %3d%% done,"
                 " %d:%02d:%02d in"
                 " %d:%02d:%02d;"
                 " %d%% speed,"
                 " %d:%02d:%02d remaining",
                 st->title, pct,

                 ((int) secs) / (60*60),
                 (((int) secs) / 60) % 60,
                 ((int) secs) % 60,

                 ((int) secs0) / (60*60),
                 (((int) secs0) / 60) % 60,
                 ((int) secs0) % 60,

                 (int) (100 * rate),

                 ((int) secs2) / (60*60),
                 (((int) secs2) / 60) % 60,
                 ((int) secs2) % 60
                 );
        XStoreName (dpy, st->window, t2);
        XSync (dpy, 0);
        free (t2);
        st->pct = pct;
      }
  }
# endif /* !HAVE_JWXYZ */

  if (++st->frame_count >= st->target_frames)
    screenhack_record_anim_free (st);

  recanim_time_warp += double_time() - start_time;
}