Description
GdkRgb converts RGB, grayscale, and colormapped images into the native
window pixel format and displays them. It takes care of colormaps,
visuals, dithering, and management of the temporary buffers.
You must call gdk_rgb_init() before using any GdkRgb functionality. If
you fail to do so, expect coredumps. All Gtk+ widgets that use GdkRgb
(including GtkPreview) call gdk_rgb_init() in their class_init method.
Thus, if you use GdkRgb only indirectly, you don't need to worry
about it.
GdkRgb tries to use the system default visual and colormap, but
doesn't always succeed. Thus, you have to be prepared to install the
visual and colormap generated by GdkRgb. The following code sequence
(before any widgets are created) should work in most applications:
You can also push the colormap and visual, but in general it doesn't
work unless the push wraps the window creation call. If you wrap the
push around a widget which is embedded in a window without the GdkRgb
colormap and visual, it probably won't work, and is likely to cause
colormap flashing, as well.
On 8-bit systems, the colormaps used by Imlib and GdkRgb may
conflict. There is no good general solution to this other than phasing
out the dependence on Imlib.
You can set the threshold for installing colormaps with
gdk_rgb_set_min_colors(). The default is 5x5x5 (125). If a colorcube
of this size or larger can be allocated in the default colormap, then
that's done. Otherwise, GdkRgb creates its own private colormap.
Setting it to 0 means that it always tries to use the default
colormap, and setting it to 216 means that it always creates a private
one if it cannot allocate the 6x6x6 colormap in the default. If you
always want a private colormap (to avoid consuming too many colormap
entries for other apps, say), you can use gdk_rgb_set_install(TRUE).
Setting the value greater than 216 exercises a bug in older versions
of GdkRgb. Note, however, that setting it to 0 doesn't let you get
away with ignoring the colormap and visual - a colormap is always
created in grayscale and direct color modes, and the visual is changed
in cases where a "better" visual than the default is available.
Example 1. A simple example program using GdkRGB.
include <gtk/gtk.h>
define IMAGE_WIDTH 256
define IMAGE_HEIGHT 256
guchar rgbbuf[IMAGE_WIDTH * IMAGE_HEIGHT * 3];
gboolean on_darea_expose (GtkWidget *widget,
GdkEventExpose *event,
gpointer user_data);
int
main (int argc, char *argv[])
{
GtkWidget *window, *darea;
gint x, y;
guchar *pos;
gtk_init (&argc, &argv);
gdk_rgb_init();
window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
darea = gtk_drawing_area_new();
gtk_drawing_area_size (GTK_DRAWING_AREA (darea), IMAGE_WIDTH, IMAGE_HEIGHT);
gtk_container_add (GTK_CONTAINER (window), darea);
gtk_signal_connect (GTK_OBJECT (darea), "expose-event",
GTK_SIGNAL_FUNC (on_darea_expose), NULL);
gtk_widget_show_all (window);
/* Set up the RGB buffer. */
pos = rgbbuf;
for (y = 0; y < IMAGE_HEIGHT; y++)
{
for (x = 0; x < IMAGE_WIDTH; x++)
{
*pos++ = x - x % 32; /* Red. */
*pos++ = (x / 32) * 4 + y - y % 32; /* Green. */
*pos++ = y - y % 32; /* Blue. */
}
}
gtk_main();
return 0;
}
gboolean
on_darea_expose (GtkWidget *widget,
GdkEventExpose *event,
gpointer user_data)
{
gdk_draw_rgb_image (widget->window, widget->style->fg_gc[GTK_STATE_NORMAL],
0, 0, IMAGE_WIDTH, IMAGE_HEIGHT,
GDK_RGB_DITHER_MAX, rgbbuf, IMAGE_WIDTH * 3);
} |
Details
gdk_rgb_init ()
void gdk_rgb_init (void); |
Initializes GdkRgb statically. It may be called more than once with no
ill effects. It must, however, be called before any other GdkRgb
operations are performed.
The GdkRgb "context" is allocated statically. Thus, GdkRgb may be used
to drive only one visual in any given application. GdkRgb
automatically selects a best visual and sets its own colormap, if
necessary. gdk_rgb_get_visual() and gdk_rgb_get_cmap() retrieve
the chosen visual and colormap, respectively.
gdk_draw_rgb_image ()
Draws an RGB image in the drawable. This is the core GdkRgb
function, and likely the only one you will need to use other than the
initialization stuff.
The rowstride parameter allows for lines to be aligned more flexibly.
For example, lines may be allocated to begin on 32-bit boundaries,
even if the width of the rectangle is odd. Rowstride is also useful
when drawing a subrectangle of a larger image in memory. Finally, to
replicate the same line a number of times, the trick of setting
rowstride to 0 is allowed.
In general, for 0 <= i < width and 0 <= j < height,
the pixel (x + i, y + j) is colored with red value rgb_buf[j *
rowstride + i * 3], green value rgb_buf[j * rowstride + i * 3 +
1], and blue value rgb_buf[j * rowstride + i * 3 + 2].
gdk_draw_rgb_image_dithalign ()
void gdk_draw_rgb_image_dithalign (GdkDrawable *drawable,
GdkGC *gc,
gint x,
gint y,
gint width,
gint height,
GdkRgbDither dith,
guchar *rgb_buf,
gint rowstride,
gint xdith,
gint ydith); |
Draws an RGB image in the drawable, with an adjustment for dither alignment.
This function is useful when drawing dithered images into a window
that may be scrolled. Pixel (x, y) will be drawn dithered as if its
actual location is (x + xdith, y + ydith). Thus, if you draw an
image into a window using zero dither alignment, then scroll up one
pixel, subsequent draws to the window should have ydith = 1.
Setting the dither alignment correctly allows updating of small parts
of the screen while avoiding visible "seams" between the different
dither textures.
gdk_draw_indexed_image ()
Draws an indexed image in the drawable, using a GdkRgbCmap to assign
actual colors to the color indices.
gdk_draw_gray_image ()
Draws a grayscale image in the drawable.
gdk_draw_rgb_32_image ()
Draws a padded RGB image in the drawable. The image is stored as one
pixel per 32-bit word. It is laid out as a red byte, a green byte, a
blue byte, and a padding byte.
It's unlikely that this function will give significant performance
gains in practice. In my experience, the performance gain from having
pixels aligned to 32-bit boundaries is cancelled out by the increased
memory bandwidth.
gdk_draw_rgb_32_image_dithalign ()
void gdk_draw_rgb_32_image_dithalign (GdkDrawable *drawable,
GdkGC *gc,
gint x,
gint y,
gint width,
gint height,
GdkRgbDither dith,
guchar *buf,
gint rowstride,
gint xdith,
gint ydith); |
enum GdkRgbDither
typedef enum
{
GDK_RGB_DITHER_NONE,
GDK_RGB_DITHER_NORMAL,
GDK_RGB_DITHER_MAX
} GdkRgbDither; |
Selects whether or not GdkRgb applies dithering
to the image on display. There are three values:
GDK_RGB_DITHER_NONE: Never use dithering.
GDK_RGB_DITHER_NORMAL: Use dithering in 8 bits per pixel (and below)
only.
GDK_RGB_DITHER_MAX: Use dithering in 16 bits per pixel and below.
Since GdkRgb currently only handles images with 8 bits per component,
dithering on 24 bit per pixel displays is a moot point.
gdk_rgb_cmap_new ()
Creates a new GdkRgbCmap structure. The cmap maps color indexes to
RGB colors. If n_colors is less than 256, then images containing
color values greater than or equal to n_colors will produce undefined
results, including possibly segfaults.
struct GdkRgbCmap
struct GdkRgbCmap {
guint32 colors[256];
gint n_colors;
/*< private >*/
GSList *info_list;
}; |
A private data structure which maps color indices to actual RGB
colors. This is used only for gdk_draw_indexed_image().
gdk_rgb_gc_set_foreground ()
Sets the foreground color in gc to the specified color (or the
closest approximation, in the case of limited visuals).
gdk_rgb_gc_set_background ()
Sets the background color in gc to the specified color (or the
closest approximation, in the case of limited visuals).
gdk_rgb_xpixel_from_rgb ()
Finds the X pixel closest in color to the rgb color specified. This
value may be used to set the pixel field of
a GdkColor struct.
gdk_rgb_set_install ()
void gdk_rgb_set_install (gboolean install); |
If install is TRUE, directs GdkRgb to always install a new "private"
colormap rather than trying to find a best fit with the colors already
allocated. Ordinarily, GdkRgb will install a colormap only if a
sufficient cube cannot be allocated.
A private colormap has more colors, leading to better quality display,
but also leads to the dreaded "colormap flashing" effect.
gdk_rgb_set_min_colors ()
void gdk_rgb_set_min_colors (gint min_colors); |
Sets the minimum number of colors for the color cube. Generally,
GdkRgb tries to allocate the largest color cube it can. If it can't
allocate a color cube at least as large as min_colors, it installs a
private colormap.
gdk_rgb_get_visual ()
Gets the visual chosen by GdkRgb. This visual and the corresponding
colormap should be used when creating windows that will be drawn in by GdkRgb.
gdk_rgb_get_cmap
#define gdk_rgb_get_cmap gdk_rgb_get_colormap |
Gets the colormap set by GdkRgb. This colormap and the corresponding
visual should be used when creating windows that will be drawn in by GdkRgb.
gdk_rgb_ditherable ()
Determine whether the visual is ditherable. This function may be
useful for presenting a user interface choice to the user about which
dither mode is desired; if the display is not ditherable, it may make
sense to gray out or hide the corresponding UI widget.
gdk_rgb_set_verbose ()
void gdk_rgb_set_verbose (gboolean verbose); |
Sets the "verbose" flag. This is generally only useful for debugging.