Exemple #1
0
void X11BufferSurface::apply(const BufferGuard&) noexcept
{
	if(!active_)
	{
		warning("ny::X11BufferSurface::apply: no currently active BufferGuard");
		return;
	}

	active_ = false;

	//we use the checked versions here since those function are very error prone due to
	//the rather complex depth/visual/bpp x system. We catch invalid x request here
	//directly.

	auto depth = windowContext().visualDepth();
	auto window = windowContext().xWindow();
	if(shm_)
	{
		auto cookie = xcb_shm_put_image_checked(&xConnection(), window, gc_, size_.x, size_.y,
			0, 0, size_.x, size_.y, 0, 0, depth, XCB_IMAGE_FORMAT_Z_PIXMAP, 0, shmseg_, 0);
		windowContext().errorCategory().checkWarn(cookie, "ny::X11BufferSurface: shm_put_image");
	}
	else
	{
		auto bpp = imageDataFormatSize(format_); //Bytes per pixel (XXX NOT bits!)
		auto length = size_.x * size_.y * bpp;

		auto cookie = xcb_put_image_checked(&xConnection(), XCB_IMAGE_FORMAT_Z_PIXMAP, window,
			gc_, size_.x, size_.y, 0, 0, 0, depth, length, data_);
		windowContext().errorCategory().checkWarn(cookie, "ny::X11BufferSurface: put_image");
	}
}
bool VlcWindowlessXCB::handle_event(void *event)
{
    XEvent *xevent = static_cast<XEvent *>(event);
    switch (xevent->type) {
    case GraphicsExpose:

        xcb_gcontext_t gc;
        xcb_void_cookie_t cookie;
        xcb_generic_error_t *err;
        XGraphicsExposeEvent *xgeevent = reinterpret_cast<XGraphicsExposeEvent *>(xevent);

        /* Something went wrong during initialization */
        if (!m_conn || !m_screen)
            break;

        drawBackground(xgeevent->drawable);

        /* Validate video size */
        if (m_media_width == 0 || m_media_height == 0)
            break;

        /* Compute the position of the video */
        int left = (npwindow.width  - m_media_width)  / 2;
        int top  = (npwindow.height - m_media_height) / 2;

        gc = xcb_generate_id(m_conn);
        xcb_create_gc(m_conn, gc, xgeevent->drawable, 0, NULL);

        /* Push the frame in X11 */
        cookie = xcb_put_image_checked(
                    m_conn,
                    XCB_IMAGE_FORMAT_Z_PIXMAP,
                    xgeevent->drawable,
                    gc,
                    m_media_width,
                    m_media_height,
                    left, top,
                    0, 24,
                    m_media_width * m_media_height * 4,
                    (const uint8_t *)&m_frame_buf[0]);

        if (err = xcb_request_check(m_conn, cookie))
        {
            fprintf(stderr, "Unable to put picture into drawable. Error %d\n",
                            err->error_code);
            free(err);
        }

        /* Flush the the connection */
        xcb_flush(m_conn);
        xcb_free_gc(m_conn, gc);
    }
    return VlcWindowlessBase::handle_event(event);
}
Exemple #3
0
/**
 * Sends an image to the X server.
 */
static void Display (vout_display_t *vd, picture_t *pic, subpicture_t *subpicture)
{
    vout_display_sys_t *sys = vd->sys;
    xcb_shm_seg_t segment = XCB_picture_GetSegment(pic);
    xcb_void_cookie_t ck;

    if (!sys->visible)
        goto out;
    if (segment != 0)
        ck = xcb_shm_put_image_checked (sys->conn, sys->window, sys->gc,
          /* real width */ pic->p->i_pitch / pic->p->i_pixel_pitch,
         /* real height */ pic->p->i_lines,
                   /* x */ vd->fmt.i_x_offset,
                   /* y */ vd->fmt.i_y_offset,
               /* width */ vd->fmt.i_visible_width,
              /* height */ vd->fmt.i_visible_height,
                           0, 0, sys->depth, XCB_IMAGE_FORMAT_Z_PIXMAP,
                           0, segment, 0);
    else
    {
        const size_t offset = vd->fmt.i_y_offset * pic->p->i_pitch;
        const unsigned lines = pic->p->i_lines - vd->fmt.i_y_offset;

        ck = xcb_put_image_checked (sys->conn, XCB_IMAGE_FORMAT_Z_PIXMAP,
                       sys->window, sys->gc,
                       pic->p->i_pitch / pic->p->i_pixel_pitch,
                       lines, -vd->fmt.i_x_offset, 0, 0, sys->depth,
                       pic->p->i_pitch * lines, pic->p->p_pixels + offset);
    }

    /* Wait for reply. This makes sure that the X server gets CPU time to
     * display the picture. xcb_flush() is *not* sufficient: especially with
     * shared memory the PUT requests are so short that many of them can fit in
     * X11 socket output buffer before the kernel preempts VLC. */
    xcb_generic_error_t *e = xcb_request_check (sys->conn, ck);
    if (e != NULL)
    {
        msg_Dbg (vd, "%s: X11 error %d", "cannot put image", e->error_code);
        free (e);
    }

    /* FIXME might be WAY better to wait in some case (be carefull with
     * VOUT_DISPLAY_RESET_PICTURES if done) + does not work with
     * vout_display wrapper. */
out:
    picture_Release (pic);
    (void)subpicture;
}
Exemple #4
0
void draw_gc(xcb_window_t win)
{
	xcb_rectangle_t      r = { 0, 0,  0,0 };
	xcb_connection_t    *c = G.conn;
	xcb_get_geometry_reply_t *geo;

	geo = xcb_get_geometry_reply(c, 
			xcb_get_geometry(c, win), NULL);

	if(0)printf("get (%hdx%hd)@(%dx%d)\n",  
			geo->x, geo->y, geo->width, geo->height);

	xcb_get_image_cookie_t cookie;
	xcb_get_image_reply_t *reply;
	xcb_generic_error_t *error;
	xcb_void_cookie_t ck;

	if(geo!=NULL){
		r.width = geo->width ;
		r.height=geo->height;
		r.x=0;
		r.y=0;
		//printf("window depth=%d\n", geo->depth);
		if(geo->depth == 24 |  geo->depth == 32)
			psize = r.width * r.height * 4; //correct
		else if(geo->depth==16)
			psize = r.width * r.height * 2; //correct
		else
			printf(" *** unsupported window depth\n");
	}else
		psize = r.width * r.height * 4; //correct
	free(geo);

	static cairo_surface_t *cmask;
	if( pbuf == NULL){
		//			psize = geo->width *geo->height*4; //for test
		pbuf = malloc(psize);
		printf("malloc pbuf=0x%x size=%d\n",pbuf, psize);
		memset(pbuf, 0x18, psize);

		cmask = cairo_image_surface_create_for_data ((unsigned char *) pbuf,
				CAIRO_FORMAT_ARGB32, 
				geo->width, geo->height, geo->width*4);
		//	12, 4, 48);
		if(cmask == NULL){
			perror("cairo surface create"); exit(1);
		}

	}
	if(0)printf("width (%dx%d=%d\n",  geo->width, geo->height,  geo->width *geo->height*4);
	draw_cairo(cmask);

	//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);

	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);

}
Exemple #5
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
	}

}
Exemple #6
0
int main(void)
{
	xcb_connection_t    *c;
	xcb_screen_t        *s;
	xcb_window_t         w;
	xcb_gcontext_t       g;
	xcb_generic_event_t *e;
	uint32_t             mask;
	uint32_t             values[2];
	int                  done = 0;

	/* open connection with the server */
	c = xcb_connect(NULL,NULL);
	if (xcb_connection_has_error(c)) {
		printf("Cannot open display\n");
		exit(1);
	}

	/* get the first screen */
	s = xcb_setup_roots_iterator( xcb_get_setup(c) ).data;

  G.conn = c;
  G.s= s;

  //enable mouse event
  xcb_cursor_t cursor;
  xcb_font_t cursor_font=0;
  short glyph = 0x34; //cross
  xcb_grab_pointer_cookie_t grab_cookie;
  xcb_grab_pointer_reply_t *grab_reply;
  xcb_generic_error_t *err;
  cursor = xcb_generate_id (c);
  if (!cursor_font) {
    cursor_font = xcb_generate_id (c);
    xcb_open_font (c, cursor_font, strlen ("cursor"), "cursor");
  }

  xcb_create_glyph_cursor (c, cursor, cursor_font, cursor_font,
      glyph, glyph + 1,
      0, 0, 0, 0xffff, 0xffff, 0xffff);  /* rgb, rgb */

  grab_cookie = xcb_grab_pointer(c, 0, s->root,
  		XCB_EVENT_MASK_POINTER_MOTION |
     XCB_EVENT_MASK_BUTTON_PRESS | XCB_EVENT_MASK_BUTTON_RELEASE,
     XCB_GRAB_MODE_SYNC, XCB_GRAB_MODE_ASYNC,
     s->root, cursor, XCB_TIME_CURRENT_TIME);

  assert(grab_reply!=NULL);
  grab_reply = xcb_grab_pointer_reply (c, grab_cookie, &err);
  if (grab_reply->status != XCB_GRAB_STATUS_SUCCESS)
    printf("Can't grab the mouse.");

  printf("grab pointer cookie=0x%x\n", grab_cookie);
  xcb_allow_events (c, XCB_ALLOW_ASYNC_POINTER, XCB_TIME_CURRENT_TIME);  xcb_flush (c);
//  xcb_allow_events (c, XCB_ALLOW_SYNC_POINTER, XCB_TIME_CURRENT_TIME);  xcb_flush (c);

	while (!done ) {
 e = xcb_wait_for_event(c);
 if(e==NULL) printf("wait event error\n");
		//printf("\revent=>%d", e->response_type);
		switch (e->response_type & ~0x80) {
			case XCB_EXPOSE:    /* draw or redraw the window */
          printf("XCB_EXPOSE\n");
          draw_gc(w);
				break;
			case XCB_MOTION_NOTIFY:
				{
					static xcb_window_t    oldw;
        xcb_button_press_event_t *bp = (xcb_button_press_event_t *)e;
        w = bp->child; /* window selected */
        if(oldw!=w){
					oldw = w;
					printf("windowid = %x\n", w);
				}
				//draw it 
				draw_gc(w);
					}
				break;
      case XCB_BUTTON_PRESS:
        {
        xcb_button_press_event_t *bp = (xcb_button_press_event_t *)e;
        w = bp->child; /* window selected */
        if (w== XCB_WINDOW_NONE){
          printf("window select is root\n");
          w=s->root;
        }
        else
          printf("window = %x\n", w);
				draw_gc(w);
        done=1; printf("grab a child\n");
        break;
        }
		}
		free(e);
	}

  xcb_ungrab_pointer(c, XCB_TIME_CURRENT_TIME);

  draw_byxid(w);
  return 0;

#if 0
	/* create window */
	w = xcb_generate_id(c);
	mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
	values[0] = s->white_pixel;
	values[1] = XCB_EVENT_MASK_EXPOSURE | XCB_EVENT_MASK_KEY_PRESS;
	xcb_create_window(c, s->root_depth, w, s->root,
			10, 10, 100, 100, 1,
			XCB_WINDOW_CLASS_INPUT_OUTPUT, s->root_visual,
			mask, values);

	/* map (show) the window */
	xcb_map_window(c, w);

	xcb_flush(c);

	/* event loop */
	while (!done && (e = xcb_wait_for_event(c))) {
		switch (e->response_type & ~0x80) {
			case XCB_EXPOSE:    /* draw or redraw the window */
				xcb_poly_fill_rectangle(c, w, g,  1, &r);
				xcb_flush(c);
				break;
			case XCB_KEY_PRESS:  /* exit on key press */
				//gwj done = 1;
				break;
		}
		free(e);
	}
	/* close connection to server */
	xcb_disconnect(c);

	return 0;
  if(0){
  //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, child, 0,NULL);
  //xcb_poly_fill_rectangle(c, w, g,  1, &r); xcb_flush(c);

  int psize=geo->width * geo->height* (geo->depth/8);
  uint8_t *pbuf = malloc(psize);
  xcb_void_cookie_t ck;
  printf("malloc pbuf=0x%x size=%d\n",pbuf, psize);
  memset(pbuf, 0x18, psize);

  ck = xcb_put_image_checked(c, XCB_IMAGE_FORMAT_Z_PIXMAP,
      child, g,
      geo->width, geo->height , 0, 0,
       0, geo->depth,
     psize, pbuf);

	//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);
    }   
  }
  printf("depth =%d\n", geo->depth);
	/* create black graphics context */
#endif
}