diff options
author | Carl Worth <cworth@cworth.org> | 2008-03-19 13:00:47 -0700 |
---|---|---|
committer | Carl Worth <cworth@cworth.org> | 2008-03-20 11:51:57 -0700 |
commit | e96f382549eb3411d461162fdd8989f4ade8b448 (patch) | |
tree | 3981955e80d314132ab850c877f6ea291b2cab4e /src/cairo-xlib-screen.c | |
parent | d413c5ab21efb2ccc6a4847ff387f8e39ba2f3e1 (diff) |
Add support for 8-bit PseudoColor visuals
This support involves allocating a 16-bit grayscale ramp as well
as a 5x5x5 RGB color cube. Afterwards, the 256 colors are queried
and an array is generated mapping from r3g3b3 colors to the closest
available color. Both the queried colors and the reverse mapping
are stored in a new visual-specific cairo_xlib_visual_info_t
structure which hangs off of the cairo_xlib_screen_info_t.
Both the color-cube allocation and the distance metric could be
improved by someone sufficiently motivated, (for example, allocating
and matching in a perceptually linear color space rather than just
in RGB space). Also, making this work well in the face of a changing
color map, or in the case of GrayScale, StaticGray, or DirectColor
visuals are left entirely as exercises for the reader. StaticColor
support should be fine as is, but is entirely untested.
Diffstat (limited to 'src/cairo-xlib-screen.c')
-rw-r--r-- | src/cairo-xlib-screen.c | 49 |
1 files changed, 49 insertions, 0 deletions
diff --git a/src/cairo-xlib-screen.c b/src/cairo-xlib-screen.c index b759a85e3..cdba294d1 100644 --- a/src/cairo-xlib-screen.c +++ b/src/cairo-xlib-screen.c @@ -269,6 +269,8 @@ _cairo_xlib_screen_info_destroy (cairo_xlib_screen_info_t *info) { cairo_xlib_screen_info_t **prev; cairo_xlib_screen_info_t *list; + cairo_xlib_visual_info_t **visuals; + int i; assert (CAIRO_REFERENCE_COUNT_HAS_REFERENCE (&info->ref_count)); @@ -282,12 +284,17 @@ _cairo_xlib_screen_info_destroy (cairo_xlib_screen_info_t *info) break; } } + visuals = _cairo_array_index (&info->visuals, 0); + for (i = 0; i < _cairo_array_num_elements (&info->visuals); i++) + free (visuals[i]); CAIRO_MUTEX_UNLOCK (info->display->mutex); _cairo_xlib_screen_info_close_display (info); _cairo_xlib_display_destroy (info->display); + _cairo_array_fini (&info->visuals); + free (info); } @@ -335,6 +342,9 @@ _cairo_xlib_screen_info_get (Display *dpy, Screen *screen) memset (info->gc, 0, sizeof (info->gc)); info->gc_needs_clip_reset = 0; + _cairo_array_init (&info->visuals, + sizeof (cairo_xlib_visual_info_t*)); + if (screen) { int event_base, error_base; info->has_render = (XRenderQueryExtension (dpy, &event_base, &error_base) && @@ -411,3 +421,42 @@ _cairo_xlib_screen_put_gc (cairo_xlib_screen_info_t *info, int depth, GC gc, cai return status; } + +cairo_xlib_visual_info_t * +_cairo_xlib_screen_get_visual_info (cairo_xlib_screen_info_t *info, + Visual *visual) +{ + cairo_xlib_visual_info_t **visuals, *ret = NULL; + cairo_status_t status; + int i; + + CAIRO_MUTEX_LOCK (info->display->mutex); + visuals = _cairo_array_index (&info->visuals, 0); + for (i = 0; i < _cairo_array_num_elements (&info->visuals); i++) { + if (visuals[i]->visualid == visual->visualid) { + ret = visuals[i]; + break; + } + } + CAIRO_MUTEX_UNLOCK (info->display->mutex); + + if (ret) + return ret; + + ret = _cairo_xlib_visual_info_create (info->display->display, + XScreenNumberOfScreen (info->screen), + visual->visualid); + if (ret == NULL) + return ret; + + CAIRO_MUTEX_LOCK (info->display->mutex); + status = _cairo_array_append (&info->visuals, &ret); + CAIRO_MUTEX_UNLOCK (info->display->mutex); + + if (status) { + free (ret); + ret = NULL; + } + + return ret; +} |