]> Pileus Git - ~andy/gtk/blobdiff - gdk/x11/gdkvisual-x11.c
Make GdkDevice parallel-implementable
[~andy/gtk] / gdk / x11 / gdkvisual-x11.c
index f9d1ffd7dec4ade9df95c94c3203c8401188987e..36ef9798f30fe83c724b1cda68f557013d8b1fe4 100644 (file)
  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
  */
 
-#include <X11/Xlib.h>
-#include <X11/Xutil.h>
+#include "config.h"
 
 #include "gdkvisual.h"
+
+#include "gdkx.h"
 #include "gdkprivate-x11.h"
 #include "gdkscreen-x11.h"
 #include "gdkinternals.h"
 
-struct _GdkVisualClass
+#include <X11/Xlib.h>
+#include <X11/Xutil.h>
+
+typedef struct _GdkVisualX11 GdkVisualX11;
+typedef struct _GdkVisualClass GdkVisualX11Class;
+
+#define GDK_TYPE_VISUAL_X11 (gdk_visual_x11_get_type ())
+#define GDK_VISUAL_X11(object) (G_TYPE_CHECK_INSTANCE_CAST ((object), GDK_TYPE_VISUAL_X11, GdkVisualX11))
+
+struct _GdkVisualX11
 {
-  GObjectClass parent_class;
+  GdkVisual visual;
+
+  Visual *xvisual;
+  Colormap colormap;
 };
 
 static void     gdk_visual_add            (GdkVisual *visual);
@@ -48,7 +61,7 @@ static gboolean gdk_visual_equal          (Visual    *a,
 
 #ifdef G_ENABLE_DEBUG
 
-static const gchar* visual_names[] =
+static const gchar *const visual_names[] =
 {
   "static gray",
   "grayscale",
@@ -60,52 +73,38 @@ static const gchar* visual_names[] =
 
 #endif /* G_ENABLE_DEBUG */
 
+G_DEFINE_TYPE (GdkVisualX11, gdk_visual_x11, GDK_TYPE_VISUAL)
+
 static void
-gdk_visual_finalize (GObject *object)
+gdk_visual_x11_init (GdkVisualX11 *visual_x11)
 {
-  g_error ("A GdkVisual object was finalized. This should not happen");
+  visual_x11->colormap = None;
 }
 
 static void
-gdk_visual_class_init (GObjectClass *class)
+gdk_visual_x11_finalize (GObject *object)
 {
-  class->finalize = gdk_visual_finalize;
-}
+  GdkVisual *visual = (GdkVisual *)object;
+  GdkVisualX11 *visual_x11 = (GdkVisualX11 *)object;
+
+  if (visual_x11->colormap != None)
+    XFreeColormap (GDK_SCREEN_XDISPLAY (visual->screen), visual_x11->colormap);
 
+  G_OBJECT_CLASS (gdk_visual_x11_parent_class)->finalize (object);
+}
 
-GType
-gdk_visual_get_type (void)
+static void
+gdk_visual_x11_class_init (GdkVisualX11Class *class)
 {
-  static GType object_type = 0;
+  GObjectClass *object_class = G_OBJECT_CLASS (class);
 
-  if (!object_type)
-    {
-      static const GTypeInfo object_info =
-      {
-        sizeof (GdkVisualClass),
-        (GBaseInitFunc) NULL,
-        (GBaseFinalizeFunc) NULL,
-        (GClassInitFunc) gdk_visual_class_init,
-        NULL,           /* class_finalize */
-        NULL,           /* class_data */
-        sizeof (GdkVisualPrivate),
-        0,              /* n_preallocs */
-        (GInstanceInitFunc) NULL,
-      };
-      
-      object_type = g_type_register_static (G_TYPE_OBJECT,
-                                            "GdkVisual",
-                                            &object_info, 0);
-    }
-  
-  return object_type;
+  object_class->finalize = gdk_visual_x11_finalize;
 }
 
-
 void
-_gdk_visual_init (GdkScreen *screen)
+_gdk_x11_visual_init (GdkScreen *screen)
 {
-  static const gint possible_depths[7] = { 32, 24, 16, 15, 8, 4, 1 };
+  static const gint possible_depths[8] = { 32, 30, 24, 16, 15, 8, 4, 1 };
   static const GdkVisualType possible_types[6] =
     {
       GDK_VISUAL_DIRECT_COLOR,
@@ -119,22 +118,23 @@ _gdk_visual_init (GdkScreen *screen)
   GdkScreenX11 *screen_x11;
   XVisualInfo *visual_list;
   XVisualInfo visual_template;
-  GdkVisualPrivate *temp_visual;
+  GdkVisual *temp_visual;
   Visual *default_xvisual;
-  GdkVisualPrivate **visuals;
+  GdkVisual **visuals;
   int nxvisuals;
   int nvisuals;
   int i, j;
-  
+
   g_return_if_fail (GDK_IS_SCREEN (screen));
   screen_x11 = GDK_SCREEN_X11 (screen);
 
+  nxvisuals = 0;
   visual_template.screen = screen_x11->screen_num;
   visual_list = XGetVisualInfo (screen_x11->xdisplay, VisualScreenMask, &visual_template, &nxvisuals);
-  
-  visuals = g_new (GdkVisualPrivate *, nxvisuals);
+
+  visuals = g_new (GdkVisual *, nxvisuals);
   for (i = 0; i < nxvisuals; i++)
-    visuals[i] = g_object_new (GDK_TYPE_VISUAL, NULL);
+    visuals[i] = g_object_new (GDK_TYPE_VISUAL_X11, NULL);
 
   default_xvisual = DefaultVisual (screen_x11->xdisplay, screen_x11->screen_num);
 
@@ -142,7 +142,7 @@ _gdk_visual_init (GdkScreen *screen)
   for (i = 0; i < nxvisuals; i++)
     {
       visuals[nvisuals]->screen = screen;
-      
+
       if (visual_list[i].depth >= 1)
        {
 #ifdef __cplusplus
@@ -152,66 +152,66 @@ _gdk_visual_init (GdkScreen *screen)
 #endif /* __cplusplus */
            {
            case StaticGray:
-             visuals[nvisuals]->visual.type = GDK_VISUAL_STATIC_GRAY;
+             visuals[nvisuals]->type = GDK_VISUAL_STATIC_GRAY;
              break;
            case GrayScale:
-             visuals[nvisuals]->visual.type = GDK_VISUAL_GRAYSCALE;
+             visuals[nvisuals]->type = GDK_VISUAL_GRAYSCALE;
              break;
            case StaticColor:
-             visuals[nvisuals]->visual.type = GDK_VISUAL_STATIC_COLOR;
+             visuals[nvisuals]->type = GDK_VISUAL_STATIC_COLOR;
              break;
            case PseudoColor:
-             visuals[nvisuals]->visual.type = GDK_VISUAL_PSEUDO_COLOR;
+             visuals[nvisuals]->type = GDK_VISUAL_PSEUDO_COLOR;
              break;
            case TrueColor:
-             visuals[nvisuals]->visual.type = GDK_VISUAL_TRUE_COLOR;
+             visuals[nvisuals]->type = GDK_VISUAL_TRUE_COLOR;
              break;
            case DirectColor:
-             visuals[nvisuals]->visual.type = GDK_VISUAL_DIRECT_COLOR;
+             visuals[nvisuals]->type = GDK_VISUAL_DIRECT_COLOR;
              break;
            }
 
-         visuals[nvisuals]->visual.depth = visual_list[i].depth;
-         visuals[nvisuals]->visual.byte_order =
+         visuals[nvisuals]->depth = visual_list[i].depth;
+         visuals[nvisuals]->byte_order =
            (ImageByteOrder(screen_x11->xdisplay) == LSBFirst) ?
            GDK_LSB_FIRST : GDK_MSB_FIRST;
-         visuals[nvisuals]->visual.red_mask = visual_list[i].red_mask;
-         visuals[nvisuals]->visual.green_mask = visual_list[i].green_mask;
-         visuals[nvisuals]->visual.blue_mask = visual_list[i].blue_mask;
-         visuals[nvisuals]->visual.colormap_size = visual_list[i].colormap_size;
-         visuals[nvisuals]->visual.bits_per_rgb = visual_list[i].bits_per_rgb;
-         visuals[nvisuals]->xvisual = visual_list[i].visual;
-
-         if ((visuals[nvisuals]->visual.type == GDK_VISUAL_TRUE_COLOR) ||
-             (visuals[nvisuals]->visual.type == GDK_VISUAL_DIRECT_COLOR))
+         visuals[nvisuals]->red_mask = visual_list[i].red_mask;
+         visuals[nvisuals]->green_mask = visual_list[i].green_mask;
+         visuals[nvisuals]->blue_mask = visual_list[i].blue_mask;
+         visuals[nvisuals]->colormap_size = visual_list[i].colormap_size;
+         visuals[nvisuals]->bits_per_rgb = visual_list[i].bits_per_rgb;
+         GDK_VISUAL_X11 (visuals[nvisuals])->xvisual = visual_list[i].visual;
+
+         if ((visuals[nvisuals]->type == GDK_VISUAL_TRUE_COLOR) ||
+             (visuals[nvisuals]->type == GDK_VISUAL_DIRECT_COLOR))
            {
-             gdk_visual_decompose_mask (visuals[nvisuals]->visual.red_mask,
-                                        &visuals[nvisuals]->visual.red_shift,
-                                        &visuals[nvisuals]->visual.red_prec);
+             gdk_visual_decompose_mask (visuals[nvisuals]->red_mask,
+                                        &visuals[nvisuals]->red_shift,
+                                        &visuals[nvisuals]->red_prec);
 
-             gdk_visual_decompose_mask (visuals[nvisuals]->visual.green_mask,
-                                        &visuals[nvisuals]->visual.green_shift,
-                                        &visuals[nvisuals]->visual.green_prec);
+             gdk_visual_decompose_mask (visuals[nvisuals]->green_mask,
+                                        &visuals[nvisuals]->green_shift,
+                                        &visuals[nvisuals]->green_prec);
 
-             gdk_visual_decompose_mask (visuals[nvisuals]->visual.blue_mask,
-                                        &visuals[nvisuals]->visual.blue_shift,
-                                        &visuals[nvisuals]->visual.blue_prec);
+             gdk_visual_decompose_mask (visuals[nvisuals]->blue_mask,
+                                        &visuals[nvisuals]->blue_shift,
+                                        &visuals[nvisuals]->blue_prec);
            }
          else
            {
-             visuals[nvisuals]->visual.red_mask = 0;
-             visuals[nvisuals]->visual.red_shift = 0;
-             visuals[nvisuals]->visual.red_prec = 0;
+             visuals[nvisuals]->red_mask = 0;
+             visuals[nvisuals]->red_shift = 0;
+             visuals[nvisuals]->red_prec = 0;
 
-             visuals[nvisuals]->visual.green_mask = 0;
-             visuals[nvisuals]->visual.green_shift = 0;
-             visuals[nvisuals]->visual.green_prec = 0;
+             visuals[nvisuals]->green_mask = 0;
+             visuals[nvisuals]->green_shift = 0;
+             visuals[nvisuals]->green_prec = 0;
 
-             visuals[nvisuals]->visual.blue_mask = 0;
-             visuals[nvisuals]->visual.blue_shift = 0;
-             visuals[nvisuals]->visual.blue_prec = 0;
+             visuals[nvisuals]->blue_mask = 0;
+             visuals[nvisuals]->blue_shift = 0;
+             visuals[nvisuals]->blue_prec = 0;
            }
-         
+
          nvisuals += 1;
        }
     }
@@ -223,27 +223,27 @@ _gdk_visual_init (GdkScreen *screen)
     {
       for (j = i+1; j < nvisuals; j++)
        {
-         if (visuals[j]->visual.depth >= visuals[i]->visual.depth)
+         if (visuals[j]->depth >= visuals[i]->depth)
            {
-             if ((visuals[j]->visual.depth == 8) && (visuals[i]->visual.depth == 8))
+             if ((visuals[j]->depth == 8) && (visuals[i]->depth == 8))
                {
-                 if (visuals[j]->visual.type == GDK_VISUAL_PSEUDO_COLOR)
+                 if (visuals[j]->type == GDK_VISUAL_PSEUDO_COLOR)
                    {
                      temp_visual = visuals[j];
                      visuals[j] = visuals[i];
                      visuals[i] = temp_visual;
                    }
-                 else if ((visuals[i]->visual.type != GDK_VISUAL_PSEUDO_COLOR) &&
-                          visuals[j]->visual.type > visuals[i]->visual.type)
+                 else if ((visuals[i]->type != GDK_VISUAL_PSEUDO_COLOR) &&
+                          visuals[j]->type > visuals[i]->type)
                    {
                      temp_visual = visuals[j];
                      visuals[j] = visuals[i];
                      visuals[i] = temp_visual;
                    }
                }
-             else if ((visuals[j]->visual.depth > visuals[i]->visual.depth) ||
-                      ((visuals[j]->visual.depth == visuals[i]->visual.depth) &&
-                       (visuals[j]->visual.type > visuals[i]->visual.type)))
+             else if ((visuals[j]->depth > visuals[i]->depth) ||
+                      ((visuals[j]->depth == visuals[i]->depth) &&
+                       (visuals[j]->type > visuals[i]->type)))
                {
                  temp_visual = visuals[j];
                  visuals[j] = visuals[i];
@@ -254,18 +254,43 @@ _gdk_visual_init (GdkScreen *screen)
     }
 
   for (i = 0; i < nvisuals; i++)
-    if (default_xvisual->visualid == visuals[i]->xvisual->visualid)
-      {
-       screen_x11->system_visual = visuals[i];
-       break;
-      }
+    {
+      if (default_xvisual->visualid == GDK_VISUAL_X11 (visuals[i])->xvisual->visualid)
+         {
+           screen_x11->system_visual = visuals[i];
+           GDK_VISUAL_X11 (visuals[i])->colormap =
+               DefaultColormap (screen_x11->xdisplay, screen_x11->screen_num);
+         }
+
+      /* For now, we only support 8888 ARGB for the "rgba visual".
+       * Additional formats (like ABGR) could be added later if they
+       * turn up.
+       */
+      if (visuals[i]->depth == 32 &&
+         (visuals[i]->red_mask   == 0xff0000 &&
+          visuals[i]->green_mask == 0x00ff00 &&
+          visuals[i]->blue_mask  == 0x0000ff))
+       {
+         screen_x11->rgba_visual = visuals[i];
+        }
+    }
 
-#ifdef G_ENABLE_DEBUG 
+#ifdef G_ENABLE_DEBUG
   if (_gdk_debug_flags & GDK_DEBUG_MISC)
-    for (i = 0; i < nvisuals; i++)
-      g_message ("visual: %s: %d",
-                visual_names[visuals[i]->visual.type],
-                visuals[i]->visual.depth);
+    {
+      static const gchar *const visual_names[] =
+      {
+        "static gray",
+        "grayscale",
+        "static color",
+        "pseudo color",
+        "true color",
+        "direct color",
+      };
+
+      for (i = 0; i < nvisuals; i++)
+        g_message ("visual: %s: %d", visual_names[visuals[i]->type], visuals[i]->depth);
+    }
 #endif /* G_ENABLE_DEBUG */
 
   screen_x11->navailable_depths = 0;
@@ -273,9 +298,9 @@ _gdk_visual_init (GdkScreen *screen)
     {
       for (j = 0; j < nvisuals; j++)
        {
-         if (visuals[j]->visual.depth == possible_depths[i])
+         if (visuals[j]->depth == possible_depths[i])
            {
-             screen_x11->available_depths[screen_x11->navailable_depths++] = visuals[j]->visual.depth;
+             screen_x11->available_depths[screen_x11->navailable_depths++] = visuals[j]->depth;
              break;
            }
        }
@@ -289,16 +314,16 @@ _gdk_visual_init (GdkScreen *screen)
     {
       for (j = 0; j < nvisuals; j++)
        {
-         if (visuals[j]->visual.type == possible_types[i])
+         if (visuals[j]->type == possible_types[i])
            {
-             screen_x11->available_types[screen_x11->navailable_types++] = visuals[j]->visual.type;
+             screen_x11->available_types[screen_x11->navailable_types++] = visuals[j]->type;
              break;
            }
        }
     }
 
   for (i = 0; i < nvisuals; i++)
-    gdk_visual_add ((GdkVisual*) visuals[i]);
+    gdk_visual_add (visuals[i]);
 
   if (screen_x11->navailable_types == 0)
     g_error ("unable to find a usable visual type");
@@ -307,219 +332,117 @@ _gdk_visual_init (GdkScreen *screen)
   screen_x11->nvisuals = nvisuals;
 }
 
-/**
- * gdk_visual_get_best_depth:
- * 
- * Get the best available depth for the default GDK screen.  "Best"
- * means "largest," i.e. 32 preferred over 24 preferred over 8 bits
- * per pixel.
- * 
- * Return value: best available depth
- **/
 gint
-gdk_visual_get_best_depth (void)
+_gdk_screen_x11_visual_get_best_depth (GdkScreen *screen)
 {
-  GdkScreen *screen = gdk_screen_get_default();
-  
   return GDK_SCREEN_X11 (screen)->available_depths[0];
 }
 
-/**
- * gdk_visual_get_best_type:
- * 
- * Return the best available visual type for the default GDK screen.
- * 
- * Return value: best visual type
- **/
 GdkVisualType
-gdk_visual_get_best_type (void)
+_gdk_screen_x11_visual_get_best_type (GdkScreen *screen)
 {
-  GdkScreen *screen = gdk_screen_get_default();
-  
   return GDK_SCREEN_X11 (screen)->available_types[0];
 }
 
-/**
- * gdk_screen_get_system_visual:
- * @screen : a #GdkScreen.
- * 
- * Get the system's default visual for @screen.
- * This is the visual for the root window of the display.
- * The return value should not be freed.
- * 
- * Return value: system visual
- **/
 GdkVisual *
-gdk_screen_get_system_visual (GdkScreen * screen)
+_gdk_screen_x11_get_system_visual (GdkScreen *screen)
 {
   g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
 
   return ((GdkVisual *) GDK_SCREEN_X11 (screen)->system_visual);
 }
 
-/**
- * gdk_visual_get_best:
- *
- * Get the visual with the most available colors for the default
- * GDK screen. The return value should not be freed.
- * 
- * Return value: best visual
- **/
 GdkVisual*
-gdk_visual_get_best (void)
+_gdk_screen_x11_visual_get_best (GdkScreen *screen)
 {
-  GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (gdk_screen_get_default());
+  GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
 
-  return (GdkVisual *)screen_x11->visuals[0];
+  return screen_x11->visuals[0];
 }
 
-/**
- * gdk_visual_get_best_with_depth:
- * @depth: a bit depth
- * 
- * Get the best visual with depth @depth for the default GDK screen.
- * Color visuals and visuals with mutable colormaps are preferred
- * over grayscale or fixed-colormap visuals. The return value should not
- * be freed. %NULL may be returned if no visual supports @depth.
- * 
- * Return value: best visual for the given depth
- **/
 GdkVisual*
-gdk_visual_get_best_with_depth (gint depth)
+_gdk_screen_x11_visual_get_best_with_depth (GdkScreen *screen,
+                                            gint       depth)
 {
-  GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (gdk_screen_get_default ());
+  GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
   GdkVisual *return_val;
   int i;
   
   return_val = NULL;
   for (i = 0; i < screen_x11->nvisuals; i++)
-    if (depth == screen_x11->visuals[i]->visual.depth)
+    if (depth == screen_x11->visuals[i]->depth)
       {
-       return_val = (GdkVisual *) & (screen_x11->visuals[i]);
+       return_val = screen_x11->visuals[i];
        break;
       }
 
   return return_val;
 }
 
-/**
- * gdk_visual_get_best_with_type:
- * @visual_type: a visual type
- *
- * Get the best visual of the given @visual_type for the default GDK screen.
- * Visuals with higher color depths are considered better. The return value
- * should not be freed. %NULL may be returned if no visual has type
- * @visual_type.
- * 
- * Return value: best visual of the given type
- **/
 GdkVisual*
-gdk_visual_get_best_with_type (GdkVisualType visual_type)
+_gdk_screen_x11_visual_get_best_with_type (GdkScreen     *screen,
+                                           GdkVisualType  visual_type)
 {
-  GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (gdk_screen_get_default ());
+  GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
   GdkVisual *return_val;
   int i;
 
   return_val = NULL;
   for (i = 0; i < screen_x11->nvisuals; i++)
-    if (visual_type == screen_x11->visuals[i]->visual.type)
+    if (visual_type == screen_x11->visuals[i]->type)
       {
-       return_val = (GdkVisual *) screen_x11->visuals[i];
+       return_val = screen_x11->visuals[i];
        break;
       }
 
   return return_val;
 }
 
-/**
- * gdk_visual_get_best_with_both:
- * @depth: a bit depth
- * @visual_type: a visual type
- *
- * Combines gdk_visual_get_best_with_depth() and gdk_visual_get_best_with_type().
- * 
- * Return value: best visual with both @depth and @visual_type, or %NULL if none
- **/
 GdkVisual*
-gdk_visual_get_best_with_both (gint          depth,
-                              GdkVisualType visual_type)
+_gdk_screen_x11_visual_get_best_with_both (GdkScreen     *screen,
+                                           gint           depth,
+                                           GdkVisualType  visual_type)
 {
-  GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (gdk_screen_get_default ());
+  GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
   GdkVisual *return_val;
   int i;
 
   return_val = NULL;
   for (i = 0; i < screen_x11->nvisuals; i++)
-    if ((depth == screen_x11->visuals[i]->visual.depth) &&
-       (visual_type == screen_x11->visuals[i]->visual.type))
+    if ((depth == screen_x11->visuals[i]->depth) &&
+       (visual_type == screen_x11->visuals[i]->type))
       {
-       return_val = (GdkVisual *) screen_x11->visuals[i];
+       return_val = screen_x11->visuals[i];
        break;
       }
 
   return return_val;
 }
 
-/**
- * gdk_query_depths:
- * @depths: return location for available depths 
- * @count: return location for number of available depths
- *
- * This function returns the available bit depths for the default
- * screen. It's equivalent to listing the visuals
- * (gdk_list_visuals()) and then looking at the depth field in each
- * visual, removing duplicates.
- * 
- * The array returned by this function should not be freed.
- * 
- **/
 void
-gdk_query_depths  (gint **depths,
-                  gint  *count)
+_gdk_screen_x11_query_depths  (GdkScreen  *screen,
+                               gint      **depths,
+                               gint       *count)
 {
-  GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (gdk_screen_get_default ());
-  
+  GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
+
   *count = screen_x11->navailable_depths;
   *depths = screen_x11->available_depths;
 }
 
-/**
- * gdk_query_visual_types:
- * @visual_types: return location for the available visual types
- * @count: return location for the number of available visual types
- *
- * This function returns the available visual types for the default
- * screen. It's equivalent to listing the visuals
- * (gdk_list_visuals()) and then looking at the type field in each
- * visual, removing duplicates.
- * 
- * The array returned by this function should not be freed.
- **/
 void
-gdk_query_visual_types (GdkVisualType **visual_types,
-                       gint           *count)
+_gdk_screen_x11_query_visual_types (GdkScreen      *screen,
+                                    GdkVisualType **visual_types,
+                                    gint           *count)
 {
-  GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (gdk_screen_get_default ());
-  
+  GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
+
   *count = screen_x11->navailable_types;
   *visual_types = screen_x11->available_types;
 }
 
-/**
- * gdk_screen_list_visuals:
- *  @screen : the relevant #GdkScreen.
- *  
- * Lists the available visuals for the specified @screen.
- * A visual describes a hardware image data format.
- * For example, a visual might support 24-bit color, or 8-bit color,
- * and might expect pixels to be in a certain format.
- *
- * Call g_list_free() on the return value when you're finished with it.
- * 
- * Return value: a list of visuals; the list must be freed, but not its contents
- **/
 GList *
-gdk_screen_list_visuals (GdkScreen *screen)
+_gdk_screen_x11_list_visuals (GdkScreen *screen)
 {
   GList *list;
   GdkScreenX11 *screen_x11;
@@ -527,7 +450,7 @@ gdk_screen_list_visuals (GdkScreen *screen)
 
   g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
   screen_x11 = GDK_SCREEN_X11 (screen);
-  
+
   list = NULL;
 
   for (i = 0; i < screen_x11->nvisuals; ++i)
@@ -537,17 +460,20 @@ gdk_screen_list_visuals (GdkScreen *screen)
 }
 
 /**
- * gdkx_visual_get_for_screen:
+ * gdk_x11_screen_lookup_visual:
  * @screen: a #GdkScreen.
  * @xvisualid: an X Visual ID.
  *
- * Returns a #GdkVisual from and X Visual id.
+ * Looks up the #GdkVisual for a particular screen and X Visual ID.
+ *
+ * Returns: the #GdkVisual (owned by the screen object), or %NULL
+ *   if the visual ID wasn't found.
  *
- * Returns: a #GdkVisual.
+ * Since: 2.2
  */
 GdkVisual *
-gdkx_visual_get_for_screen (GdkScreen *screen,
-                           VisualID   xvisualid)
+gdk_x11_screen_lookup_visual (GdkScreen *screen,
+                              VisualID   xvisualid)
 {
   int i;
   GdkScreenX11 *screen_x11;
@@ -555,39 +481,52 @@ gdkx_visual_get_for_screen (GdkScreen *screen,
   screen_x11 = GDK_SCREEN_X11 (screen);
 
   for (i = 0; i < screen_x11->nvisuals; i++)
-    if (xvisualid == screen_x11->visuals[i]->xvisual->visualid)
-      return (GdkVisual *)  screen_x11->visuals[i];
+    if (xvisualid == GDK_VISUAL_X11 (screen_x11->visuals[i])->xvisual->visualid)
+      return screen_x11->visuals[i];
 
   return NULL;
 }
 
+/**
+ * gdkx_visual_get:
+ * @xvisualid: a X visual id.
+ *
+ * Returns a #GdkVisual corresponding to a X visual.
+ *
+ * Return value: the #GdkVisual.
+ **/
 GdkVisual*
 gdkx_visual_get (VisualID xvisualid)
 {
-  return gdkx_visual_get_for_screen (gdk_screen_get_default (), xvisualid);
+  return gdk_x11_screen_lookup_visual (gdk_screen_get_default (), xvisualid);
 }
 
 static void
 gdk_visual_add (GdkVisual *visual)
 {
-  GdkVisualPrivate *private = (GdkVisualPrivate *) visual;
-  GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (private->screen);
-  
+  GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (visual->screen);
+
   if (!screen_x11->visual_hash)
     screen_x11->visual_hash = g_hash_table_new ((GHashFunc) gdk_visual_hash,
-                                                (GEqualFunc) gdk_visual_equal);
+                                                (GEqualFunc) gdk_visual_equal);
 
-  g_hash_table_insert (screen_x11->visual_hash, private->xvisual, visual);
+  g_hash_table_insert (screen_x11->visual_hash, GDK_VISUAL_X11 (visual)->xvisual, visual);
 }
 
 static void
 gdk_visual_decompose_mask (gulong  mask,
-                          gint   *shift,
-                          gint   *prec)
+                           gint   *shift,
+                           gint   *prec)
 {
   *shift = 0;
   *prec = 0;
 
+  if (mask == 0)
+    {
+      g_warning ("Mask is 0 in visual. Server bug ?");
+      return;
+    }
+
   while (!(mask & 0x1))
     {
       (*shift)++;
@@ -609,31 +548,51 @@ gdk_visual_hash (Visual *key)
 
 static gboolean
 gdk_visual_equal (Visual *a,
-                 Visual *b)
+                  Visual *b)
 {
   return (a->visualid == b->visualid);
 }
 
-Visual *
-gdk_x11_visual_get_xvisual (GdkVisual *visual)
+/**
+ * _gdk_visual_get_x11_colormap:
+ * @visual: the visual to get the colormap from
+ *
+ * Gets the colormap to use
+ *
+ * Returns: the X Colormap to use for new windows using @visual
+ **/
+Colormap
+_gdk_visual_get_x11_colormap (GdkVisual *visual)
 {
-  g_return_val_if_fail (visual != NULL, NULL);
+  GdkVisualX11 *visual_x11;
+
+  g_return_val_if_fail (GDK_IS_VISUAL (visual), None);
+
+  visual_x11 = GDK_VISUAL_X11 (visual);
+
+  if (visual_x11->colormap == None)
+    {
+      visual_x11->colormap = XCreateColormap (GDK_SCREEN_XDISPLAY (visual->screen),
+                                              GDK_SCREEN_XROOTWIN (visual->screen),
+                                              visual_x11->xvisual,
+                                              AllocNone);
+    }
 
-  return  ((GdkVisualPrivate*) visual)->xvisual;
+  return visual_x11->colormap;
 }
 
 /**
- * gdk_visual_get_screen:
- * @visual: a #GdkVisual
- * 
- * Gets the screen to which this visual belongs
- * 
- * Return value: the screen to which this visual belongs.
+ * gdk_x11_visual_get_xvisual:
+ * @visual: a #GdkVisual.
+ *
+ * Returns the X visual belonging to a #GdkVisual.
+ *
+ * Return value: an Xlib <type>Visual*</type>.
  **/
-GdkScreen *
-gdk_visual_get_screen (GdkVisual *visual)
+Visual *
+gdk_x11_visual_get_xvisual (GdkVisual *visual)
 {
   g_return_val_if_fail (GDK_IS_VISUAL (visual), NULL);
 
-  return  ((GdkVisualPrivate*) visual)->screen;
+  return GDK_VISUAL_X11 (visual)->xvisual;
 }