Ejemplo n.º 1
0
static void
swrastGetImage(__DRIdrawable * read,
               int x, int y, int w, int h,
               char *data, void *loaderPrivate)
{
   struct dri2_egl_surface *dri2_surf = loaderPrivate;
   struct dri2_egl_display *dri2_dpy = dri2_egl_display(dri2_surf->base.Resource.Display);

   xcb_get_image_cookie_t cookie;
   xcb_get_image_reply_t *reply;
   xcb_generic_error_t *error;

   cookie = xcb_get_image (dri2_dpy->conn, XCB_IMAGE_FORMAT_Z_PIXMAP,
                           dri2_surf->drawable, x, y, w, h, ~0);
   reply = xcb_get_image_reply (dri2_dpy->conn, cookie, &error);
   if (reply == NULL)
      return;

   if (error != NULL) {
      _eglLog(_EGL_WARNING, "error in xcb_get_image");
      free(error);
   } else {
      uint32_t bytes = xcb_get_image_data_length(reply);
      uint8_t *idata = xcb_get_image_data(reply);
      memcpy(data, idata, bytes);
   }
   free(reply);
}
Ejemplo n.º 2
0
xcb_image_t *
xcb_image_get (xcb_connection_t *  conn,
	       xcb_drawable_t      draw,
	       int16_t             x,
	       int16_t             y,
	       uint16_t            width,
	       uint16_t            height,
	       uint32_t            plane_mask,
	       xcb_image_format_t  format)
{
  xcb_get_image_cookie_t   image_cookie;
  xcb_get_image_reply_t *  imrep;
  xcb_image_t *            image = 0;
  uint32_t                 bytes;
  uint8_t *                data;

  image_cookie = xcb_get_image(conn, format, draw, x, y,
			       width, height, plane_mask);
  imrep = xcb_get_image_reply(conn, image_cookie, 0);
  if (!imrep)
      return 0;
  bytes = xcb_get_image_data_length(imrep);
  data = xcb_get_image_data(imrep);
  switch (format) {
  case XCB_IMAGE_FORMAT_XY_PIXMAP:
      plane_mask &= xcb_mask(imrep->depth);
      if (plane_mask != xcb_mask(imrep->depth)) {
	  xcb_image_t *  tmp_image =
	    xcb_image_create_native(conn, width, height, format,
				    imrep->depth, 0, 0, 0);
	  
	  if (!tmp_image) {
	      free(imrep);
	      return 0;
	  }

	  int            i;
	  uint32_t       rpm = plane_mask;
	  uint8_t *      src_plane = image->data;
	  uint8_t *      dst_plane = tmp_image->data;
	  uint32_t       size = image->height * image->stride;

	  if (tmp_image->bit_order == XCB_IMAGE_ORDER_MSB_FIRST)
	      rpm = xcb_bit_reverse(plane_mask, imrep->depth);
	  for (i = 0; i < imrep->depth; i++) {
	      if (rpm & 1) {
		  memcpy(dst_plane, src_plane, size);
		  src_plane += size;
	      } else {
		  memset(dst_plane, 0, size);
	      }
	      dst_plane += size;
	  }
	  tmp_image->plane_mask = plane_mask;
	  image = tmp_image;
	  free(imrep);
	  break;
      }
      /* fall through */
  case XCB_IMAGE_FORMAT_Z_PIXMAP:
      image = xcb_image_create_native(conn, width, height, format,
				      imrep->depth, imrep, bytes, data);
      if (!image) {
	  free(imrep);
	  return 0;
      }
      break;
  default:
      assert(0);
  }
  assert(bytes == image->size);
  return image;
}
Ejemplo n.º 3
0
void draw_gc(xcb_window_t win)
{
	// the only problem to draw bgr24 it  bps=4 but 3, if depth=24,
	/*
	fmt depth	 bps
	32	  32    4
	bgr24 24    4
	16    16    2
	8      8     1
	0      0      0
		 */
	//draw something in parent window for test
	//w = s->root;
	xcb_gcontext_t       g_solid;
	uint32_t             mask;
	uint32_t             values[2];
	xcb_rectangle_t      r = { 0, 0,  10,10 };
	xcb_rectangle_t      r2 = { 20, 20,  100,100 };
	xcb_connection_t    *c = G.conn;

	if(win==0) {
		win=G.root;
		// atach to root will cause  error=Resource temporary unavailable
	}
	xcb_map_window(c, win); xcb_flush(c);
	g_solid = xcb_generate_id(c);
	mask = XCB_GC_FOREGROUND | XCB_GC_GRAPHICS_EXPOSURES;
	values[0] = G.s->white_pixel;
	values[1] = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_KEY_PRESS;
	xcb_create_gc(c, g_solid, win, 0,NULL);
	xcb_change_gc(c, g_solid,  mask, values);
	xcb_poly_fill_rectangle(c, win, g_solid,  1, &r2); xcb_flush(c);
	xcb_free_gc(c,g_solid);

	if(1){
		//getimage 
		xcb_get_image_cookie_t cookie;
		xcb_get_image_reply_t *reply;
		xcb_generic_error_t *error;
		int psize= r.width * r.height * G.s->root_depth/8;
		psize = r.width * r.height * 4; //correct
		static uint8_t *pbuf = NULL;
		xcb_void_cookie_t ck;

		if( pbuf == NULL){
			pbuf = malloc(psize);
			printf("malloc pbuf=0x%x size=%d\n",pbuf, psize);
			memset(pbuf, 0x18, psize);
		}

#if 0
		cookie = xcb_get_image (c, XCB_IMAGE_FORMAT_Z_PIXMAP,
				win, r.x, r.y, r.width, r.height, ~0);
		reply = xcb_get_image_reply (c, cookie, &error);
		if (reply == NULL){
			perror("get_image_replay");
			return;
		}

		if (error != NULL) {
			perror("error in xcb_get_image");
			free(error);
		} else {
			uint32_t bytes = xcb_get_image_data_length(reply);
			uint8_t *idata = xcb_get_image_data(reply);
			printf("get_image size=%d p=%p\n", bytes, idata);
			memcpy(pbuf, idata, bytes);
			printf("root_depth=%d\n", G.s->root_depth);
			psize=bytes;
		}
		free(reply);
#endif

		//draw image with xcb_put_image
		// creat gc and draw to parent window
		xcb_gcontext_t       g;
		g = xcb_generate_id(c);
		xcb_create_gc(c, g, win, 0,NULL);

		memset(pbuf, 0xf8, psize);
		int i=0;
		uint8_t *p2=pbuf;
		//fmt = bgr24
		for( i=0; i<psize; ){
			*(p2+i)= 0;		i++;  //blue
			*(p2+i)= 0xff;		i++; //green
			*(p2+i)= 0;		i++; //red
			*(p2+i)= 0x80;		i++; //??
		}
		ck = xcb_put_image_checked(c, XCB_IMAGE_FORMAT_Z_PIXMAP,
				win, g,
				r.width, r.height, r.x,r.y,
				0, G.s->root_depth,
				psize, pbuf);
		xcb_flush(c);

#if 0
		//BadMatch=8 BadLength=16
		xcb_generic_error_t *err;
		err = xcb_request_check (c, ck);
		if (err)
		{
			int code = err->error_code;
			free (err);
			printf("put image error %d\n", code);
			assert (code != 0);
		}   
		xcb_free_gc(c, g);
#endif
	}

}
Ejemplo n.º 4
0
/**
 * Processing callback
 */
static void Demux (void *data)
{
    demux_t *demux = data;
    demux_sys_t *sys = demux->p_sys;
    xcb_connection_t *conn = sys->conn;

    /* Determine capture region */
    xcb_get_geometry_cookie_t gc;
    xcb_query_pointer_cookie_t qc;

    gc = xcb_get_geometry (conn, sys->window);
    if (sys->follow_mouse)
        qc = xcb_query_pointer (conn, sys->window);

    xcb_get_geometry_reply_t *geo = xcb_get_geometry_reply (conn, gc, NULL);
    if (geo == NULL)
    {
        msg_Err (demux, "bad X11 drawable 0x%08"PRIx32, sys->window);
discard:
        if (sys->follow_mouse)
            xcb_discard_reply (conn, gc.sequence);
        return;
    }

    int w = sys->w;
    int h = sys->h;
    int x, y;

    if (sys->follow_mouse)
    {
        xcb_query_pointer_reply_t *ptr =
            xcb_query_pointer_reply (conn, qc, NULL);
        if (ptr == NULL)
        {
            free (geo);
            return;
        }

        if (w == 0 || w > geo->width)
            w = geo->width;
        x = ptr->win_x;
        if (x < w / 2)
            x = 0;
        else if (x >= (int)geo->width - (w / 2))
            x = geo->width - w;
        else
            x -= w / 2;

        if (h == 0 || h > geo->height)
            h = geo->height;
        y = ptr->win_y;
        if (y < h / 2)
            y = 0;
        else if (y >= (int)geo->height - (h / 2))
            y = geo->height - h;
        else
            y -= h / 2;
    }
    else
    {
        int max;

        x = sys->x;
        max = (int)geo->width - x;
        if (max <= 0)
            goto discard;
        if (w == 0 || w > max)
            w = max;

        y = sys->y;
        max = (int)geo->height - y;
        if (max <= 0)
            goto discard;
        if (h == 0 || h > max)
            h = max;
    }

    /* Update elementary stream format (if needed) */
    if (w != sys->cur_w || h != sys->cur_h)
    {
        if (sys->es != NULL)
            es_out_Del (demux->out, sys->es);

        /* Update composite pixmap */
        if (sys->window != geo->root)
        {
            xcb_free_pixmap (conn, sys->pixmap); /* no-op first time */
            xcb_composite_name_window_pixmap (conn, sys->window, sys->pixmap);
            xcb_create_pixmap (conn, geo->depth, sys->pixmap,
                               geo->root, geo->width, geo->height);
        }

        sys->es = InitES (demux, w, h, geo->depth);
        if (sys->es != NULL)
        {
            sys->cur_w = w;
            sys->cur_h = h;
        }
    }

    /* Capture screen */
    xcb_drawable_t drawable =
        (sys->window != geo->root) ? sys->pixmap : sys->window;
    free (geo);

    xcb_get_image_reply_t *img;
    img = xcb_get_image_reply (conn,
        xcb_get_image (conn, XCB_IMAGE_FORMAT_Z_PIXMAP, drawable,
                       x, y, w, h, ~0), NULL);
    if (img == NULL)
        return;

    block_t *block = block_heap_Alloc (img, xcb_get_image_data (img),
                                       xcb_get_image_data_length (img));
    if (block == NULL)
        return;

    /* Send block - zero copy */
    if (sys->es != NULL)
    {
        if (sys->pts == VLC_TS_INVALID)
            sys->pts = mdate ();
        block->i_pts = block->i_dts = sys->pts;

        es_out_Control (demux->out, ES_OUT_SET_PCR, sys->pts);
        es_out_Send (demux->out, sys->es, block);
        sys->pts += sys->interval;
    }
}
Ejemplo n.º 5
0
Archivo: xcb.c Proyecto: FLYKingdom/vlc
/**
 * Processing callback
 */
static void Demux (void *data)
{
    demux_t *demux = data;
    demux_sys_t *p_sys = demux->p_sys;
    xcb_connection_t *conn = p_sys->conn;

    /* Update capture region (if needed) */
    xcb_get_geometry_cookie_t gc = xcb_get_geometry (conn, p_sys->window);
    int16_t x = p_sys->x, y = p_sys->y;
    xcb_translate_coordinates_cookie_t tc;

    if (p_sys->window != p_sys->root)
        tc = xcb_translate_coordinates (conn, p_sys->window, p_sys->root,
                                        x, y);

    xcb_get_geometry_reply_t *geo = xcb_get_geometry_reply (conn, gc, NULL);
    if (geo == NULL)
    {
        msg_Err (demux, "bad X11 drawable 0x%08"PRIx32, p_sys->window);
        return;
    }

    uint16_t w = geo->width - x;
    uint16_t h = geo->height - y;
    free (geo);
    if (p_sys->w > 0 && p_sys->w < w)
        w = p_sys->w;
    if (p_sys->h > 0 && p_sys->h < h)
        h = p_sys->h;

    if (p_sys->window != p_sys->root)
    {
        xcb_translate_coordinates_reply_t *coords =
             xcb_translate_coordinates_reply (conn, tc, NULL);
        if (coords == NULL)
            return;
        x = coords->dst_x;
        y = coords->dst_y;
        free (coords);
    }

    xcb_get_image_reply_t *img;
    img = xcb_get_image_reply (conn,
        xcb_get_image (conn, XCB_IMAGE_FORMAT_Z_PIXMAP, p_sys->root,
                       x, y, w, h, ~0), NULL);
    if (img == NULL)
        return;

    /* Send block - zero copy */
    block_t *block = block_heap_Alloc (img, xcb_get_image_data (img),
                                       xcb_get_image_data_length (img));
    if (block == NULL)
        return;

    vlc_mutex_lock (&p_sys->lock);
    if (w != p_sys->fmt.video.i_visible_width
     || h != p_sys->fmt.video.i_visible_height)
    {
        if (p_sys->es != NULL)
            es_out_Del (demux->out, p_sys->es);
        p_sys->fmt.video.i_visible_width = p_sys->fmt.video.i_width = w;
        p_sys->fmt.video.i_visible_height = p_sys->fmt.video.i_height = h;
        p_sys->es = es_out_Add (demux->out, &p_sys->fmt);
    }

    /* Capture screen */
    if (p_sys->es != NULL)
    {
        if (p_sys->pts == VLC_TS_INVALID)
            p_sys->pts = mdate ();
        block->i_pts = block->i_dts = p_sys->pts;

        es_out_Control (demux->out, ES_OUT_SET_PCR, p_sys->pts);
        es_out_Send (demux->out, p_sys->es, block);
        p_sys->pts += p_sys->interval;
    }
    vlc_mutex_unlock (&p_sys->lock);
}
Ejemplo n.º 6
0
/**
 * Processing callback
 */
static void Demux (void *opaque)
{
    demux_t *demux = opaque;
    demux_sys_t *sys = demux->p_sys;
    xcb_connection_t *conn = sys->conn;

    /* Determine capture region */
    xcb_get_geometry_cookie_t gc;
    xcb_query_pointer_cookie_t qc;

    gc = xcb_get_geometry (conn, sys->window);
    if (sys->follow_mouse)
        qc = xcb_query_pointer (conn, sys->window);

    xcb_get_geometry_reply_t *geo = xcb_get_geometry_reply (conn, gc, NULL);
    if (geo == NULL)
    {
        msg_Err (demux, "bad X11 drawable 0x%08"PRIx32, sys->window);
discard:
        if (sys->follow_mouse)
            xcb_discard_reply (conn, gc.sequence);
        return;
    }

    int w = sys->w;
    int h = sys->h;
    int x, y;

    if (sys->follow_mouse)
    {
        xcb_query_pointer_reply_t *ptr =
            xcb_query_pointer_reply (conn, qc, NULL);
        if (ptr == NULL)
        {
            free (geo);
            return;
        }

        if (w == 0 || w > geo->width)
            w = geo->width;
        x = ptr->win_x;
        if (x < w / 2)
            x = 0;
        else if (x >= (int)geo->width - (w / 2))
            x = geo->width - w;
        else
            x -= w / 2;

        if (h == 0 || h > geo->height)
            h = geo->height;
        y = ptr->win_y;
        if (y < h / 2)
            y = 0;
        else if (y >= (int)geo->height - (h / 2))
            y = geo->height - h;
        else
            y -= h / 2;
    }
    else
    {
        int max;

        x = sys->x;
        max = (int)geo->width - x;
        if (max <= 0)
            goto discard;
        if (w == 0 || w > max)
            w = max;

        y = sys->y;
        max = (int)geo->height - y;
        if (max <= 0)
            goto discard;
        if (h == 0 || h > max)
            h = max;
    }

    /* Update elementary stream format (if needed) */
    if (w != sys->cur_w || h != sys->cur_h)
    {
        if (sys->es != NULL)
            es_out_Del (demux->out, sys->es);

        /* Update composite pixmap */
        if (sys->window != geo->root)
        {
            xcb_free_pixmap (conn, sys->pixmap); /* no-op first time */
            xcb_composite_name_window_pixmap (conn, sys->window, sys->pixmap);
            xcb_create_pixmap (conn, geo->depth, sys->pixmap,
                               geo->root, geo->width, geo->height);
        }

        sys->es = InitES (demux, w, h, geo->depth, &sys->bpp);
        if (sys->es != NULL)
        {
            sys->cur_w = w;
            sys->cur_h = h;
            sys->bpp /= 8; /* bits -> bytes */
        }
    }

    /* Capture screen */
    xcb_drawable_t drawable =
        (sys->window != geo->root) ? sys->pixmap : sys->window;
    free (geo);

    block_t *block = NULL;
#if HAVE_SYS_SHM_H
    if (sys->shm)
    {   /* Capture screen through shared memory */
        size_t size = w * h * sys->bpp;
        int id = shmget (IPC_PRIVATE, size, IPC_CREAT | 0777);
        if (id == -1) /* XXX: fallback */
        {
            msg_Err (demux, "shared memory allocation error: %m");
            goto noshm;
        }

        /* Attach the segment to X and capture */
        xcb_shm_get_image_reply_t *img;
        xcb_shm_get_image_cookie_t ck;

        xcb_shm_attach (conn, sys->segment, id, 0 /* read/write */);
        ck = xcb_shm_get_image (conn, drawable, x, y, w, h, ~0,
                                XCB_IMAGE_FORMAT_Z_PIXMAP, sys->segment, 0);
        xcb_shm_detach (conn, sys->segment);
        img = xcb_shm_get_image_reply (conn, ck, NULL);
        xcb_flush (conn); /* ensure eventual detach */

        if (img == NULL)
        {
            shmctl (id, IPC_RMID, 0);
            goto noshm;
        }
        free (img);

        /* Attach the segment to VLC */
        void *shm = shmat (id, NULL, 0 /* read/write */);
        shmctl (id, IPC_RMID, 0);
        if (-1 == (intptr_t)shm)
        {
            msg_Err (demux, "shared memory attachment error: %m");
            return;
        }

        block = block_shm_Alloc (shm, size);
        if (unlikely(block == NULL))
            shmdt (shm);
    }
noshm:
#endif
    if (block == NULL)
    {   /* Capture screen through socket (fallback) */
        xcb_get_image_reply_t *img;

        img = xcb_get_image_reply (conn,
            xcb_get_image (conn, XCB_IMAGE_FORMAT_Z_PIXMAP, drawable,
                           x, y, w, h, ~0), NULL);
        if (img == NULL)
            return;

        uint8_t *data = xcb_get_image_data (img);
        size_t datalen = xcb_get_image_data_length (img);
        block = block_heap_Alloc (img, data + datalen - (uint8_t *)img);
        if (block == NULL)
            return;
        block->p_buffer = data;
        block->i_buffer = datalen;
    }

    /* Send block - zero copy */
    if (sys->es != NULL)
    {
        block->i_pts = block->i_dts = mdate ();

        es_out_Control (demux->out, ES_OUT_SET_PCR, block->i_pts);
        es_out_Send (demux->out, sys->es, block);
    }
}
Ejemplo n.º 7
0
static cairo_status_t
_get_image (cairo_xcb_surface_t		 *surface,
	    cairo_bool_t		  use_shm,
	    cairo_image_surface_t	**image_out)
{
    cairo_image_surface_t *image;
    cairo_xcb_connection_t *connection;
    xcb_get_image_reply_t *reply;
    cairo_status_t status;

    if (surface->base.is_clear || surface->deferred_clear) {
	image = (cairo_image_surface_t *)
	    _cairo_image_surface_create_with_pixman_format (NULL,
							    surface->pixman_format,
							    surface->width,
							    surface->height,
							    0);
	*image_out = image;
	return image->base.status;
    }

    connection = surface->connection;

    status = _cairo_xcb_connection_acquire (connection);
    if (unlikely (status))
	return status;

    status = _cairo_xcb_connection_take_socket (connection);
    if (unlikely (status))
	goto FAIL;

    if (use_shm) {
	status = _get_shm_image (surface, image_out);
	if (status != CAIRO_INT_STATUS_UNSUPPORTED)
	    goto FAIL;
    }

    if (surface->use_pixmap == 0) {
	status = _cairo_xcb_connection_get_image (connection,
						  surface->drawable,
						  0, 0,
						  surface->width,
						  surface->height,
						  &reply);
	if (unlikely (status))
	    goto FAIL;
    } else {
	surface->use_pixmap--;
	reply = NULL;
    }

    if (reply == NULL && ! surface->owns_pixmap) {
	/* xcb_get_image_t from a window is dangerous because it can
	 * produce errors if the window is unmapped or partially
	 * outside the screen. We could check for errors and
	 * retry, but to keep things simple, we just create a
	 * temporary pixmap
	 */
	xcb_pixmap_t pixmap;
	xcb_gcontext_t gc;

	gc = _cairo_xcb_screen_get_gc (surface->screen,
				       surface->drawable,
				       surface->depth);
	pixmap = _cairo_xcb_connection_create_pixmap (connection,
						      surface->depth,
						      surface->drawable,
						      surface->width,
						      surface->height);

	/* XXX IncludeInferiors? */
	_cairo_xcb_connection_copy_area (connection,
					 surface->drawable,
					 pixmap, gc,
					 0, 0,
					 0, 0,
					 surface->width,
					 surface->height);

	_cairo_xcb_screen_put_gc (surface->screen, surface->depth, gc);

	status = _cairo_xcb_connection_get_image (connection,
						  pixmap,
						  0, 0,
						  surface->width,
						  surface->height,
						  &reply);
	_cairo_xcb_connection_free_pixmap (connection, pixmap);

	if (unlikely (status))
	    goto FAIL;
    }

    if (unlikely (reply == NULL)) {
	status = _cairo_error (CAIRO_STATUS_NO_MEMORY);
	goto FAIL;
    }

    /* XXX byte swap */
    /* XXX format conversion */
    assert (reply->depth == surface->depth);

    image = (cairo_image_surface_t *)
	_cairo_image_surface_create_with_pixman_format
	(xcb_get_image_data (reply),
	 surface->pixman_format,
	 surface->width,
	 surface->height,
	 CAIRO_STRIDE_FOR_WIDTH_BPP (surface->width,
				     PIXMAN_FORMAT_BPP (surface->pixman_format)));
    status = image->base.status;
    if (unlikely (status)) {
	free (reply);
	goto FAIL;
    }

    assert (xcb_get_image_data_length (reply) == image->height * image->stride);

    pixman_image_set_destroy_function (image->pixman_image, _destroy_image, reply);

    _cairo_xcb_connection_release (connection);

    /* synchronisation point */
    surface->marked_dirty = FALSE;

    *image_out = image;
    return CAIRO_STATUS_SUCCESS;

FAIL:
    _cairo_xcb_connection_release (connection);
    return status;
}