How GNOME Uses X Visuals April 2002 Ximian GNOME on HP-UX Technical Note #1 Copyright 2002 Hewlett-Packard Company ______________________________________ Background: Most CDE applications run on the overlay plane in HP-UX, and they only create windows with "fat" visuals (e.g. 24 bits per pixel) when they are absolutely required. The latter is the case for CAD and image manipulation programs, for example. GTK+ defaults to using the X server's default visual. It does not pay any attention to overlay planes. For historical reasons, applications have tended to override the default GTK+ visual with a fat, high-quality visual for ease of programming. [1] Very small applications that only use stock GTK+ widgets will usually pay no attention to the visual/colormap, and just use whatever GTK+ gives them as the default. More complex applications like Evolution frequently opt for using a high-quality visual for all widgets so that they can get 24-bit images on the screen easily. Most GTK+/GNOME applications use the GdkRGB module in GTK+ to render 24-bit RGB buffers to drawables. In GNOME 1.4, however, GdkRGB can only render to the highest-quality visual supported by the X server. [2] This is why applications tend to fall back to the highest-quality visual when they do any image handling at all. The GTK+ Visual/Colormap Stacks: GTK+ keeps two stacks, one for visuals and one for colormaps, respectively. Applications can manipulate this with the gtk_widget_push_visual(), gtk_widget_push_colormap(), gtk_widget_pop_visual(), and gtk_widget_pop_colormap() functions. When you push a colormap or visual, widgets that are created from that point on will use the colormap and visual that are at the top of the stack. A common pattern is: /* Here we are using the default visual/colormap */ window = gtk_window_new (GTK_WINDOW_TOPLEVEL); controls = ...; gtk_container_add (window, controls); /* We need a high-quality widget here */ gtk_widget_push_visual (gdk_rgb_get_visual ()); gtk_widget_push_colormap (gdk_rgb_get_cmap ()); image_display = image_display_new (); gtk_container_add (parent_of_image_display, image_display); /* Go on normally */ gtk_widget_pop_visual (); gtk_widget_pop_colormap (); more_controls = ...; gtk_container_add (..., more_controls); In this way, applications can fine-tune their use of visuals. Solution: The easiest thing to do is to insert a call to gtk_widget_push_visual() and gtk_widget_push_colormap() at the beginning of every application or even in gtk_init(). [3] This will ensure that all widgets in the application use the highest-quality visual and colormap from the beginning. We decided that we would use a backdrop window to get 24 bit when the default visual is 8 bit. We noted that application windows using overlay visuals will get 24 bit image plan decorations unless they are simple override_redirect popups. That reduces any incentive to make simple applications like gnome_terminal choose overlay visuals. We also discussed tweaking the window manager colormap installation code to minimize colormap flashing when switching to applications that are using more colormaps than can fit in the hardware. Footnotes: [1] People like to do things like create a GC and share it between drawables. If these drawables do not all have the same visual/colormap, then BadMatch errors will occur. People found it easier to just run the whole application in a high-quality visual rather than fix these mismatches by careful programming. [2] In GNOME 2.0 GdkRGB can render to any visual/colormap, so it may be possible to do more fine-grained optimizations in the future. [3] Note that you need to call gdk_rgb_init() before calling other GdkRGB functions. References: Xlib programming manual. X Concepts - this presents a particularly easy to understand view of X's way of life.