mirror of
https://gitlab.freedesktop.org/cairo/cairo.git
synced 2026-02-18 21:10:52 +01:00
xcb: Query the display's subpixel order via RENDER
With commite691d242, the xcb backend started parsing the resources, just like cairo-xlib does. One behavior from cairo-xlib was missing: If no Xft.rgba property was specified, cairo-xlib defaults to the screen's subpixel order. This commit brings that last bit of functionality to cairo-xcb (but currently disabled due to commite0c0a673). This commits adds a new array to cairo_xcb_connection_t that contains the subpixel order for each screen. There is also a new member in cairo_xcb_screen_t which contains the subpixel order of that screen and which is initialized from the array when the screen is constructed. With this in place, the resource-parsing code can just pick the subpixel order from the screen if needed. Signed-off-by: Uli Schlachter <psychon@znc.in>
This commit is contained in:
parent
02e4efc961
commit
b47209a03f
4 changed files with 43 additions and 29 deletions
|
|
@ -79,6 +79,7 @@ typedef struct _cairo_xcb_xid {
|
|||
#define XCB_RENDER_HAS_FILTERS(surface) XCB_RENDER_AT_LEAST((surface), 0, 6)
|
||||
#define XCB_RENDER_HAS_FILTER_GOOD(surface) FALSE
|
||||
#define XCB_RENDER_HAS_FILTER_BEST(surface) FALSE
|
||||
#define XCB_RENDER_HAS_SUBPIXEL_ORDER(surface) XCB_RENDER_AT_LEAST((surface), 0, 6)
|
||||
|
||||
#define XCB_RENDER_HAS_EXTENDED_REPEAT(surface) XCB_RENDER_AT_LEAST((surface), 0, 10)
|
||||
#define XCB_RENDER_HAS_GRADIENTS(surface) XCB_RENDER_AT_LEAST((surface), 0, 10)
|
||||
|
|
@ -407,6 +408,15 @@ _cairo_xcb_connection_query_render (cairo_xcb_connection_t *connection)
|
|||
if (XCB_RENDER_HAS_GRADIENTS (version))
|
||||
connection->flags |= CAIRO_XCB_RENDER_HAS_GRADIENTS;
|
||||
|
||||
if (XCB_RENDER_HAS_SUBPIXEL_ORDER (version)) {
|
||||
uint32_t screen;
|
||||
uint32_t *subpixel = xcb_render_query_pict_formats_subpixels(formats);
|
||||
|
||||
/* The spec explicitly allows to have too few entries in the reply... */
|
||||
for (screen = 0; screen < formats->num_subpixel && screen < connection->root->roots_len; screen++)
|
||||
connection->subpixel_orders[screen] = subpixel[screen];
|
||||
}
|
||||
|
||||
free (version);
|
||||
|
||||
status = _cairo_xcb_connection_parse_xrender_formats (connection, formats);
|
||||
|
|
@ -581,6 +591,7 @@ _device_destroy (void *device)
|
|||
CAIRO_MUTEX_FINI (connection->shm_mutex);
|
||||
CAIRO_MUTEX_FINI (connection->screens_mutex);
|
||||
|
||||
free (connection->subpixel_orders);
|
||||
free (connection);
|
||||
}
|
||||
|
||||
|
|
@ -684,6 +695,14 @@ _cairo_xcb_connection_get (xcb_connection_t *xcb_connection)
|
|||
|
||||
connection->root = xcb_get_setup (xcb_connection);
|
||||
connection->render = NULL;
|
||||
connection->subpixel_orders = calloc (connection->root->roots_len, sizeof(*connection->subpixel_orders));
|
||||
if (unlikely (connection->subpixel_orders == NULL)) {
|
||||
CAIRO_MUTEX_UNLOCK (connection->device.mutex);
|
||||
_cairo_xcb_connection_destroy (connection);
|
||||
connection = NULL;
|
||||
goto unlock;
|
||||
}
|
||||
|
||||
ext = xcb_get_extension_data (xcb_connection, &xcb_render_id);
|
||||
if (ext != NULL && ext->present) {
|
||||
status = _cairo_xcb_connection_query_render (connection);
|
||||
|
|
|
|||
|
|
@ -181,7 +181,8 @@ struct _cairo_xcb_font {
|
|||
struct _cairo_xcb_screen {
|
||||
cairo_xcb_connection_t *connection;
|
||||
|
||||
xcb_screen_t *xcb_screen;
|
||||
xcb_screen_t *xcb_screen;
|
||||
xcb_render_sub_pixel_t subpixel_order;
|
||||
|
||||
xcb_gcontext_t gc[GC_CACHE_SIZE];
|
||||
uint8_t gc_depths[GC_CACHE_SIZE];
|
||||
|
|
@ -223,6 +224,7 @@ struct _cairo_xcb_connection {
|
|||
const xcb_setup_t *root;
|
||||
const xcb_query_extension_reply_t *render;
|
||||
const xcb_query_extension_reply_t *shm;
|
||||
xcb_render_sub_pixel_t *subpixel_orders;
|
||||
|
||||
cairo_list_t free_xids;
|
||||
cairo_freepool_t xid_pool;
|
||||
|
|
|
|||
|
|
@ -251,21 +251,13 @@ get_resources(xcb_connection_t *connection, xcb_screen_t *screen, cairo_xcb_reso
|
|||
resource_parser_done (&parser);
|
||||
}
|
||||
|
||||
#if 0 && XCB_RENDER_MAJOR_VERSION > 99 && XCB_RENDER_MINOR_VERSION > 99
|
||||
static void
|
||||
get_rgba_from_render (xcb_connection_t *connection, xcb_screen_t *screen, cairo_xcb_resources_t *resources)
|
||||
void
|
||||
_cairo_xcb_resources_get (cairo_xcb_screen_t *screen, cairo_xcb_resources_t *resources)
|
||||
{
|
||||
/* this is a mock-up of what the function might look like,
|
||||
xcb_render_query_sub_pixel is not actually implemented in XCB (yet) */
|
||||
get_resources (screen->connection->xcb_connection, screen->xcb_screen, resources);
|
||||
|
||||
xcb_render_query_sub_pixel_order_cookie_t cookie;
|
||||
xcb_render_query_sub_pixel_order_reply_t *reply;
|
||||
|
||||
cookie = xcb_render_query_sub_pixel (connection, screen);
|
||||
reply = xcb_render_query_sub_pixel_reply (connection, cookie, NULL);
|
||||
|
||||
if (reply) {
|
||||
switch (reply->sub_pixel_order) {
|
||||
if (resources->xft_rgba == FC_RGBA_UNKNOWN) {
|
||||
switch (screen->subpixel_order) {
|
||||
case XCB_RENDER_SUB_PIXEL_UNKNOWN:
|
||||
resources->xft_rgba = FC_RGBA_UNKNOWN;
|
||||
break;
|
||||
|
|
@ -285,20 +277,5 @@ get_rgba_from_render (xcb_connection_t *connection, xcb_screen_t *screen, cairo_
|
|||
resources->xft_rgba = FC_RGBA_NONE;
|
||||
break;
|
||||
}
|
||||
|
||||
free(reply);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void
|
||||
_cairo_xcb_resources_get (cairo_xcb_screen_t *screen, cairo_xcb_resources_t *resources)
|
||||
{
|
||||
get_resources (screen->connection->xcb_connection, screen->xcb_screen, resources);
|
||||
|
||||
#if 0 && XCB_RENDER_MAJOR_VERSION > 99 && XCB_RENDER_MINOR_VERSION > 99
|
||||
if (resources->xft_rgba == FC_RGBA_UNKNOWN) {
|
||||
get_rgba_from_render (screen->connection->xcb_connection, screen->xcb_screen, resources);
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
|
|
|||
|
|
@ -207,6 +207,18 @@ _pattern_cache_entry_destroy (void *closure)
|
|||
_cairo_freelist_free (&entry->screen->pattern_cache_entry_freelist, entry);
|
||||
}
|
||||
|
||||
static int _get_screen_index(cairo_xcb_connection_t *xcb_connection,
|
||||
xcb_screen_t *xcb_screen)
|
||||
{
|
||||
int idx = 0;
|
||||
xcb_screen_iterator_t iter = xcb_setup_roots_iterator(xcb_connection->root);
|
||||
for (; iter.rem; xcb_screen_next(&iter), idx++)
|
||||
if (iter.data->root == xcb_screen->root)
|
||||
return idx;
|
||||
|
||||
ASSERT_NOT_REACHED;
|
||||
}
|
||||
|
||||
cairo_xcb_screen_t *
|
||||
_cairo_xcb_screen_get (xcb_connection_t *xcb_connection,
|
||||
xcb_screen_t *xcb_screen)
|
||||
|
|
@ -214,6 +226,7 @@ _cairo_xcb_screen_get (xcb_connection_t *xcb_connection,
|
|||
cairo_xcb_connection_t *connection;
|
||||
cairo_xcb_screen_t *screen;
|
||||
cairo_status_t status;
|
||||
int screen_idx;
|
||||
int i;
|
||||
|
||||
connection = _cairo_xcb_connection_get (xcb_connection);
|
||||
|
|
@ -240,9 +253,12 @@ _cairo_xcb_screen_get (xcb_connection_t *xcb_connection,
|
|||
if (unlikely (screen == NULL))
|
||||
goto unlock;
|
||||
|
||||
screen_idx = _get_screen_index(connection, xcb_screen);
|
||||
|
||||
screen->connection = connection;
|
||||
screen->xcb_screen = xcb_screen;
|
||||
screen->has_font_options = FALSE;
|
||||
screen->subpixel_order = connection->subpixel_orders[screen_idx];
|
||||
|
||||
_cairo_freelist_init (&screen->pattern_cache_entry_freelist,
|
||||
sizeof (struct pattern_cache_entry));
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue