]> Pileus Git - ~andy/gtk/blobdiff - gdk/x11/gdkvisual-x11.c
Make GdkDevice parallel-implementable
[~andy/gtk] / gdk / x11 / gdkvisual-x11.c
index 66c42ff769e865cc31d7a07bff6a11cb8c4ae037..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);
@@ -45,19 +59,9 @@ static gboolean gdk_visual_equal          (Visual    *a,
                                           Visual    *b);
 
 
-static GdkVisualPrivate *system_visual;
-static GdkVisualPrivate **visuals;
-static gint nvisuals;
-
-static gint available_depths[7];
-static gint navailable_depths;
-
-static GdkVisualType available_types[6];
-static gint navailable_types;
-
 #ifdef G_ENABLE_DEBUG
 
-static const gchar* visual_names[] =
+static const gchar *const visual_names[] =
 {
   "static gray",
   "grayscale",
@@ -69,54 +73,38 @@ static const gchar* visual_names[] =
 
 #endif /* G_ENABLE_DEBUG */
 
-static GHashTable *visual_hash = NULL;
+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 (void)
+_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,
@@ -127,28 +115,34 @@ _gdk_visual_init (void)
       GDK_VISUAL_STATIC_GRAY
     };
 
-  static const gint npossible_depths = sizeof(possible_depths)/sizeof(gint);
-  static const gint npossible_types = sizeof(possible_types)/sizeof(GdkVisualType);
-
+  GdkScreenX11 *screen_x11;
   XVisualInfo *visual_list;
   XVisualInfo visual_template;
-  GdkVisualPrivate *temp_visual;
+  GdkVisual *temp_visual;
   Visual *default_xvisual;
+  GdkVisual **visuals;
   int nxvisuals;
+  int nvisuals;
   int i, j;
 
-  visual_template.screen = _gdk_screen;
-  visual_list = XGetVisualInfo (gdk_display, VisualScreenMask, &visual_template, &nxvisuals);
-  
-  visuals = g_new (GdkVisualPrivate *, nxvisuals);
+  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 (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 (gdk_display, _gdk_screen);
+  default_xvisual = DefaultVisual (screen_x11->xdisplay, screen_x11->screen_num);
 
   nvisuals = 0;
   for (i = 0; i < nxvisuals; i++)
     {
+      visuals[nvisuals]->screen = screen;
+
       if (visual_list[i].depth >= 1)
        {
 #ifdef __cplusplus
@@ -158,64 +152,64 @@ _gdk_visual_init (void)
 #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 =
-           (ImageByteOrder(gdk_display) == LSBFirst) ?
+         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;
@@ -229,27 +223,27 @@ _gdk_visual_init (void)
     {
       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];
@@ -260,91 +254,125 @@ _gdk_visual_init (void)
     }
 
   for (i = 0; i < nvisuals; i++)
-    if (default_xvisual->visualid == visuals[i]->xvisual->visualid)
-      {
-       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 */
 
-  navailable_depths = 0;
-  for (i = 0; i < npossible_depths; i++)
+  screen_x11->navailable_depths = 0;
+  for (i = 0; i < G_N_ELEMENTS (possible_depths); i++)
     {
       for (j = 0; j < nvisuals; j++)
        {
-         if (visuals[j]->visual.depth == possible_depths[i])
+         if (visuals[j]->depth == possible_depths[i])
            {
-             available_depths[navailable_depths++] = visuals[j]->visual.depth;
+             screen_x11->available_depths[screen_x11->navailable_depths++] = visuals[j]->depth;
              break;
            }
        }
     }
 
-  if (navailable_depths == 0)
+  if (screen_x11->navailable_depths == 0)
     g_error ("unable to find a usable depth");
 
-  navailable_types = 0;
-  for (i = 0; i < npossible_types; i++)
+  screen_x11->navailable_types = 0;
+  for (i = 0; i < G_N_ELEMENTS (possible_types); i++)
     {
       for (j = 0; j < nvisuals; j++)
        {
-         if (visuals[j]->visual.type == possible_types[i])
+         if (visuals[j]->type == possible_types[i])
            {
-             available_types[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 (npossible_types == 0)
+  if (screen_x11->navailable_types == 0)
     g_error ("unable to find a usable visual type");
+
+  screen_x11->visuals = visuals;
+  screen_x11->nvisuals = nvisuals;
 }
 
 gint
-gdk_visual_get_best_depth (void)
+_gdk_screen_x11_visual_get_best_depth (GdkScreen *screen)
 {
-  return available_depths[0];
+  return GDK_SCREEN_X11 (screen)->available_depths[0];
 }
 
 GdkVisualType
-gdk_visual_get_best_type (void)
+_gdk_screen_x11_visual_get_best_type (GdkScreen *screen)
 {
-  return available_types[0];
+  return GDK_SCREEN_X11 (screen)->available_types[0];
 }
 
-GdkVisual*
-gdk_visual_get_system (void)
+GdkVisual *
+_gdk_screen_x11_get_system_visual (GdkScreen *screen)
 {
-  return ((GdkVisual*) system_visual);
+  g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
+
+  return ((GdkVisual *) GDK_SCREEN_X11 (screen)->system_visual);
 }
 
 GdkVisual*
-gdk_visual_get_best (void)
+_gdk_screen_x11_visual_get_best (GdkScreen *screen)
 {
-  return ((GdkVisual*) visuals[0]);
+  GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
+
+  return screen_x11->visuals[0];
 }
 
 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 (screen);
   GdkVisual *return_val;
   int i;
-
+  
   return_val = NULL;
-  for (i = 0; i < nvisuals; i++)
-    if (depth == visuals[i]->visual.depth)
+  for (i = 0; i < screen_x11->nvisuals; i++)
+    if (depth == screen_x11->visuals[i]->depth)
       {
-       return_val = (GdkVisual*) visuals[i];
+       return_val = screen_x11->visuals[i];
        break;
       }
 
@@ -352,16 +380,18 @@ gdk_visual_get_best_with_depth (gint depth)
 }
 
 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 (screen);
   GdkVisual *return_val;
   int i;
 
   return_val = NULL;
-  for (i = 0; i < nvisuals; i++)
-    if (visual_type == visuals[i]->visual.type)
+  for (i = 0; i < screen_x11->nvisuals; i++)
+    if (visual_type == screen_x11->visuals[i]->type)
       {
-       return_val = (GdkVisual*) visuals[i];
+       return_val = screen_x11->visuals[i];
        break;
       }
 
@@ -369,18 +399,20 @@ gdk_visual_get_best_with_type (GdkVisualType visual_type)
 }
 
 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 (screen);
   GdkVisual *return_val;
   int i;
 
   return_val = NULL;
-  for (i = 0; i < nvisuals; i++)
-    if ((depth == visuals[i]->visual.depth) &&
-       (visual_type == visuals[i]->visual.type))
+  for (i = 0; i < screen_x11->nvisuals; i++)
+    if ((depth == screen_x11->visuals[i]->depth) &&
+       (visual_type == screen_x11->visuals[i]->type))
       {
-       return_val = (GdkVisual*) visuals[i];
+       return_val = screen_x11->visuals[i];
        break;
       }
 
@@ -388,82 +420,113 @@ gdk_visual_get_best_with_both (gint          depth,
 }
 
 void
-gdk_query_depths  (gint **depths,
-                  gint  *count)
+_gdk_screen_x11_query_depths  (GdkScreen  *screen,
+                               gint      **depths,
+                               gint       *count)
 {
-  *count = navailable_depths;
-  *depths = available_depths;
+  GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
+
+  *count = screen_x11->navailable_depths;
+  *depths = screen_x11->available_depths;
 }
 
 void
-gdk_query_visual_types (GdkVisualType **visual_types,
-                       gint           *count)
+_gdk_screen_x11_query_visual_types (GdkScreen      *screen,
+                                    GdkVisualType **visual_types,
+                                    gint           *count)
 {
-  *count = navailable_types;
-  *visual_types = available_types;
+  GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
+
+  *count = screen_x11->navailable_types;
+  *visual_types = screen_x11->available_types;
 }
 
-GList*
-gdk_list_visuals (void)
+GList *
+_gdk_screen_x11_list_visuals (GdkScreen *screen)
 {
   GList *list;
+  GdkScreenX11 *screen_x11;
   guint i;
 
+  g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
+  screen_x11 = GDK_SCREEN_X11 (screen);
+
   list = NULL;
-  for (i = 0; i < nvisuals; ++i)
-    list = g_list_append (list, (gpointer) visuals[i]);
+
+  for (i = 0; i < screen_x11->nvisuals; ++i)
+    list = g_list_append (list, screen_x11->visuals[i]);
 
   return list;
 }
 
-
-GdkVisual*
-gdk_visual_lookup (Visual *xvisual)
+/**
+ * gdk_x11_screen_lookup_visual:
+ * @screen: a #GdkScreen.
+ * @xvisualid: an 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.
+ *
+ * Since: 2.2
+ */
+GdkVisual *
+gdk_x11_screen_lookup_visual (GdkScreen *screen,
+                              VisualID   xvisualid)
 {
-  GdkVisual *visual;
+  int i;
+  GdkScreenX11 *screen_x11;
+  g_return_val_if_fail (GDK_IS_SCREEN (screen), NULL);
+  screen_x11 = GDK_SCREEN_X11 (screen);
 
-  if (!visual_hash)
-    return NULL;
+  for (i = 0; i < screen_x11->nvisuals; i++)
+    if (xvisualid == GDK_VISUAL_X11 (screen_x11->visuals[i])->xvisual->visualid)
+      return screen_x11->visuals[i];
 
-  visual = g_hash_table_lookup (visual_hash, xvisual);
-  return visual;
+  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)
 {
-  int i;
-
-  for (i = 0; i < nvisuals; i++)
-    if (xvisualid == visuals[i]->xvisual->visualid)
-      return (GdkVisual*) visuals[i];
-
-  return NULL;
+  return gdk_x11_screen_lookup_visual (gdk_screen_get_default (), xvisualid);
 }
 
-
 static void
 gdk_visual_add (GdkVisual *visual)
 {
-  GdkVisualPrivate *private;
-
-  if (!visual_hash)
-    visual_hash = g_hash_table_new ((GHashFunc) gdk_visual_hash,
-                                   (GEqualFunc) gdk_visual_equal);
+  GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (visual->screen);
 
-  private = (GdkVisualPrivate*) visual;
+  if (!screen_x11->visual_hash)
+    screen_x11->visual_hash = g_hash_table_new ((GHashFunc) gdk_visual_hash,
+                                                (GEqualFunc) gdk_visual_equal);
 
-  g_hash_table_insert (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)++;
@@ -485,15 +548,51 @@ gdk_visual_hash (Visual *key)
 
 static gboolean
 gdk_visual_equal (Visual *a,
-                 Visual *b)
+                  Visual *b)
 {
   return (a->visualid == b->visualid);
 }
 
+/**
+ * _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)
+{
+  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 visual_x11->colormap;
+}
+
+/**
+ * gdk_x11_visual_get_xvisual:
+ * @visual: a #GdkVisual.
+ *
+ * Returns the X visual belonging to a #GdkVisual.
+ *
+ * Return value: an Xlib <type>Visual*</type>.
+ **/
 Visual *
 gdk_x11_visual_get_xvisual (GdkVisual *visual)
 {
-  g_return_val_if_fail (visual != NULL, NULL);
+  g_return_val_if_fail (GDK_IS_VISUAL (visual), NULL);
 
-  return  ((GdkVisualPrivate*) visual)->xvisual;
+  return GDK_VISUAL_X11 (visual)->xvisual;
 }