예제 #1
0
static xcb_render_pictforminfo_t *
find_depth (xcb_connection_t  *connection,
	    int 	       depth,
	    void	     **formats_out)
{
    xcb_render_query_pict_formats_reply_t *formats;
    xcb_render_query_pict_formats_cookie_t cookie;
    xcb_render_pictforminfo_iterator_t i;

    cookie = xcb_render_query_pict_formats (connection);
    xcb_flush (connection);

    formats = xcb_render_query_pict_formats_reply (connection, cookie, 0);
    if (formats == NULL)
	return NULL;

    for (i = xcb_render_query_pict_formats_formats_iterator (formats);
	 i.rem;
	 xcb_render_pictforminfo_next (&i))
    {
	if (XCB_RENDER_PICT_TYPE_DIRECT != i.data->type)
	    continue;

	if (depth != i.data->depth)
	    continue;

	*formats_out = formats;
	return i.data;
    }

    free (formats);
    return NULL;
}
예제 #2
0
파일: cache.c 프로젝트: aosm/X11libs
static connection_cache *
find_or_create_display (xcb_connection_t *c)
{
    connection_cache *info;
    xcb_render_query_version_cookie_t version_cookie;
    xcb_render_query_pict_formats_cookie_t formats_cookie;
    int present;

    /*
     * look for display in list
     */
    for (info = connections.head; info; info = info->next)
        if (info->c == c) {
            connections.cur = info;     /* cache most recently used */
	    return info;
        }

    /*
     * don't already have this display: add it.
     */
    info = malloc (sizeof (connection_cache));
    if (!info)
	return NULL;
    info->c = c;

    version_cookie = xcb_render_query_version(c, 0, 10);
    formats_cookie = xcb_render_query_pict_formats(c);
    xcb_flush(c);
    present = has_required_depths (c);
    info->version = xcb_render_query_version_reply(c, version_cookie, 0);
    info->formats = xcb_render_query_pict_formats_reply(c, formats_cookie, 0);

    if (!present || !info->version || !info->formats)
    {
	free(info->version);
	info->version = 0;
	free(info->formats);
	info->formats = 0;
    }
    /* Check for the lack of sub-pixel data */
    else if (info->version->major_version == 0 && info->version->minor_version < 6)
	info->formats->num_subpixel = 0;

    /*
     * now, chain it onto the list
     */
    info->next = connections.head;
    connections.head = info;
    connections.cur = info;

    return info;
}
예제 #3
0
int main(int, char **)
{
    int primaryScreen = 0;
    xcb_generic_error_t *error = 0;

    xcb_connection_t *connection = xcb_connect("", &primaryScreen);
    xcb_render_query_pict_formats_cookie_t formatsCookie =
        xcb_render_query_pict_formats(connection);

    xcb_render_query_pict_formats_reply_t *formatsReply =
        xcb_render_query_pict_formats_reply(
            connection,
            formatsCookie,
            &error);

    xcb_render_util_find_standard_format(formatsReply,
                                         XCB_PICT_STANDARD_ARGB_32);

    return 0;
}
예제 #4
0
파일: render.c 프로젝트: mstorsjo/vlc
/**
 * Probe the X server.
 */
static int Open(vout_display_t *vd, const vout_display_cfg_t *cfg,
                video_format_t *fmtp, vlc_video_context *ctx)
{
    vlc_object_t *obj = VLC_OBJECT(vd);

    vout_display_sys_t *sys = vlc_obj_malloc(obj, sizeof (*sys));
    if (unlikely(sys == NULL))
        return VLC_ENOMEM;

    vd->sys = sys;

    /* Connect to X */
    xcb_connection_t *conn;
    const xcb_screen_t *screen;

    if (vlc_xcb_parent_Create(vd, cfg, &conn, &screen) == NULL)
        return VLC_EGENERIC;

    sys->conn = conn;
    sys->root = screen->root;
    sys->format.argb = 0;
    sys->format.alpha = 0;

    if (!CheckRender(vd, conn))
        goto error;

    xcb_render_query_pict_formats_cookie_t pic_fmt_ck =
        xcb_render_query_pict_formats(conn);
    xcb_render_query_pict_formats_reply_t *pic_fmt_r =
        xcb_render_query_pict_formats_reply(conn, pic_fmt_ck, NULL);
    if (pic_fmt_r == NULL)
        goto error;

    const xcb_setup_t *setup = xcb_get_setup(conn);
    const xcb_render_pictforminfo_t *const pic_fmts =
        xcb_render_query_pict_formats_formats(pic_fmt_r);
    xcb_visualid_t visual = 0;

    for (unsigned i = 0; i < pic_fmt_r->num_formats; i++) {
        const xcb_render_pictforminfo_t *const pic_fmt = pic_fmts + i;
        const xcb_render_directformat_t *const d = &pic_fmt->direct;

        if (pic_fmt->depth == 8 && pic_fmt->direct.alpha_mask == 0xff) {
            /* Alpha mask format */
            sys->format.alpha = pic_fmt->id;
            continue;
        }

        xcb_visualid_t vid = FindVisual(setup, screen, pic_fmt_r, pic_fmt->id);
        if (vid == 0)
            continue;

        /* Use only ARGB for now. 32-bits is guaranteed to work. */
        if (pic_fmt->depth != 32)
            continue;

        vlc_fourcc_t chroma = ParseFormat(setup, pic_fmt);
        if (chroma == 0)
            continue;

        fmtp->i_chroma = chroma;
        fmtp->i_rmask = ((uint32_t)d->red_mask) << d->red_shift;
        fmtp->i_gmask = ((uint32_t)d->green_mask) << d->green_shift;
        fmtp->i_bmask = ((uint32_t)d->blue_mask) << d->blue_shift;
        sys->format.argb = pic_fmt->id;
        visual = vid;
    }

    free(pic_fmt_r);

    if (unlikely(sys->format.argb == 0 || sys->format.alpha == 0))
        goto error; /* Buggy server */

    msg_Dbg(obj, "using RENDER picture format %u", sys->format.argb);
    msg_Dbg(obj, "using X11 visual 0x%"PRIx32, visual);

    char *filter = var_InheritString(obj, "x11-render-filter");
    if (filter != NULL) {
        msg_Dbg(obj, "using filter \"%s\"", filter);
        sys->filter = ToCharset("ISO 8859-1", filter, &(size_t){ 0 });
        free(filter);
    } else
        sys->filter = NULL;

    sys->drawable.source = xcb_generate_id(conn);
    sys->drawable.crop = xcb_generate_id(conn);
    sys->drawable.scale = xcb_generate_id(conn);
    sys->drawable.subpic = xcb_generate_id(conn);
    sys->drawable.alpha = xcb_generate_id(conn);
    sys->drawable.dest = xcb_generate_id(conn);
    sys->picture.source = xcb_generate_id(conn);
    sys->picture.crop = xcb_generate_id(conn);
    sys->picture.scale = xcb_generate_id(conn);
    sys->picture.subpic = xcb_generate_id(conn);
    sys->picture.alpha = xcb_generate_id(conn);
    sys->picture.dest = xcb_generate_id(conn);
    sys->gc = xcb_generate_id(conn);

    if (XCB_shm_Check(obj, conn))
        sys->segment = xcb_generate_id(conn);
    else
        sys->segment = 0;

    xcb_colormap_t cmap = xcb_generate_id(conn);
    uint32_t cw_mask =
        XCB_CW_BACK_PIXEL |
        XCB_CW_BORDER_PIXEL |
        XCB_CW_EVENT_MASK |
        XCB_CW_COLORMAP;
    const uint32_t cw_list[] = {
        /* XCB_CW_BACK_PIXEL */
        screen->black_pixel,
        /* XCB_CW_BORDER_PIXEL */
        screen->black_pixel,
        /* XCB_CW_EVENT_MASK */
        0,
        /* XCB_CW_COLORMAP */
        cmap,
    };

    xcb_create_colormap(conn, XCB_COLORMAP_ALLOC_NONE, cmap, screen->root,
                        visual);
    xcb_create_pixmap(conn, 32, sys->drawable.source, screen->root,
                      vd->source.i_width, vd->source.i_height);
    xcb_create_gc(conn, sys->gc, sys->drawable.source, 0, NULL);
    xcb_create_window(conn, 32, sys->drawable.dest, cfg->window->handle.xid,
                      0, 0, cfg->display.width, cfg->display.height, 0,
                      XCB_WINDOW_CLASS_INPUT_OUTPUT, visual, cw_mask, cw_list);
    xcb_render_create_picture(conn, sys->picture.source, sys->drawable.source,
                              sys->format.argb, 0, NULL);
    xcb_render_create_picture(conn, sys->picture.dest, sys->drawable.dest,
                              sys->format.argb, 0, NULL);
    CreateBuffers(vd, cfg);
    xcb_map_window(conn, sys->drawable.dest);

    sys->spu_chromas[0] = fmtp->i_chroma;
    sys->spu_chromas[1] = 0;

    vd->info.subpicture_chromas = sys->spu_chromas;
    vd->prepare = Prepare;
    vd->display = Display;
    vd->control = Control;

    (void) ctx;
    return VLC_SUCCESS;

error:
    xcb_disconnect(conn);
    return VLC_EGENERIC;
}
  xcb_render_standard_pictforminforgb_24_t,
  xcb_render_standard_pictforminfoa_8_t,
  xcb_render_standard_pictforminfoa_4_t,
  xcb_render_standard_pictforminfoa_1_t,
  xcb_render_standard_pictforminfo_count_t
};

static xcb_render_pictforminfo_t *
xcb_render_find_pictforminfo (xcb_connection_t *conn, uint32_t mask, const xcb_render_pictforminfo_t *template, int count)
{
  xcb_render_query_pict_formats_cookie_t cookie;
  xcb_render_query_pict_formats_reply_t *rep;
  xcb_render_pictforminfo_iterator_t     iter_forminfo;

  cookie = xcb_render_query_pict_formats_unchecked (conn);
  rep = xcb_render_query_pict_formats_reply (conn, cookie, NULL);
  iter_forminfo = xcb_render_query_pict_formats_formats_iterator (rep);
  for (; iter_forminfo.rem; xcb_render_pictforminfo_next (&iter_forminfo)) {
    if (mask & xcb_render_pictforminfo_id)
      if (template->id != iter_forminfo.data->id)
        continue;
    if (mask & xcb_render_pictforminfo_type_t)
      if (template->type != iter_forminfo.data->type)
        continue;
    if (mask & xcb_render_pictforminfo_depth_t)
      if (template->depth != iter_forminfo.data->depth)
        continue;
    if (mask & xcb_render_pictforminfo_red_shift_t)
      if (template->direct.red_shift != iter_forminfo.data->direct.red_shift)
        continue;
    if (mask & xcb_render_pictforminfo_red_mask_t)
static cairo_surface_t *
_cairo_boilerplate_xcb_create_surface (const char		 *name,
				       cairo_content_t		  content,
				       double			  width,
				       double			  height,
				       double			  max_width,
				       double			  max_height,
				       cairo_boilerplate_mode_t   mode,
				       void			**closure)
{
    xcb_screen_t *root;
    xcb_target_closure_t *xtc;
    xcb_connection_t *c;
    xcb_render_query_pict_formats_cookie_t formats_cookie;
    xcb_render_pictforminfo_t *render_format;
    xcb_render_pictforminfo_iterator_t i;
    struct xcb_info *info;
    int depth;
    xcb_void_cookie_t cookie;
    cairo_surface_t *surface;
    cairo_status_t status;

    *closure = xtc = xmalloc (sizeof (xcb_target_closure_t));
    info = xcalloc (1, sizeof (struct xcb_info));

    if (width == 0)
	width = 1;
    if (height == 0)
	height = 1;

    xtc->c = c = xcb_connect(NULL,NULL);
    if (c == NULL || xcb_connection_has_error(c)) {
	free (xtc);
	return NULL;
    }

    root = xcb_setup_roots_iterator(xcb_get_setup(c)).data;
    formats_cookie = xcb_render_query_pict_formats (c);

    xtc->surface = NULL;
    xtc->is_pixmap = TRUE;
    xtc->drawable = xcb_generate_id (c);
    switch (content) {
    case CAIRO_CONTENT_COLOR:
	depth = 24;
	break;

    case CAIRO_CONTENT_COLOR_ALPHA:
	depth = 32;
	break;

    case CAIRO_CONTENT_ALPHA:  /* would be XCB_PICT_STANDARD_A_8 */
    default:
	xcb_disconnect (c);
	free (xtc);
	return NULL;
    }

    cookie = xcb_create_pixmap_checked (c, depth,
					xtc->drawable, root->root,
					width, height);

    /* slow, but sure */
    if (xcb_request_check (c, cookie) != NULL) {
	xcb_disconnect (c);
	free (xtc);
	return NULL;
    }

    info->formats = xcb_render_query_pict_formats_reply (c, formats_cookie, 0);
    if (info->formats == NULL)
	return NULL;

    for (i = xcb_render_query_pict_formats_formats_iterator (info->formats);
	 i.rem;
	 xcb_render_pictforminfo_next (&i))
    {
	if (XCB_RENDER_PICT_TYPE_DIRECT != i.data->type)
	    continue;

	if (i.data->depth == 32) {
		if (info->render_format[0] == 0)
			info->render_format[0] = i.data;
	} else if (i.data->depth == 24) {
		if (info->render_format[1] == 0)
			info->render_format[1] = i.data;
	} else if (i.data->depth == 8) {
		if (info->render_format[2] == 0)
			info->render_format[2] = i.data;
	}
    }

    assert (info->render_format[0]);
    assert (info->render_format[1]);
    assert (info->render_format[2]);

    switch (content) {
    default:
    case CAIRO_CONTENT_COLOR_ALPHA:
	    render_format = info->render_format[0];
	    break;

    case CAIRO_CONTENT_COLOR:
	    render_format = info->render_format[1];
	    break;

    case CAIRO_CONTENT_ALPHA:  /* would be XCB_PICT_STANDARD_A_8 */
	    render_format = info->render_format[2];
	    break;
    }

    surface = cairo_xcb_surface_create_with_xrender_format (c, root,
							    xtc->drawable,
							    render_format,
							    width, height);
    cairo_device_set_user_data (cairo_surface_get_device (surface), &key, info, free);
    if (mode != CAIRO_BOILERPLATE_MODE_PERF)
	_cairo_boilerplate_xcb_setup_test_surface(surface);

    xtc->device = cairo_device_reference (cairo_surface_get_device (surface));
    status = cairo_surface_set_user_data (surface, &xcb_closure_key, xtc, NULL);
    if (status == CAIRO_STATUS_SUCCESS)
	return surface;

    cairo_surface_destroy (surface);

    _cairo_boilerplate_xcb_cleanup (xtc);
    return cairo_boilerplate_surface_create_in_error (status);
}