/**
 * gdk_x11_atom_to_xatom_for_display:
 * @display: A #GdkDisplay
 * @atom: A #GdkAtom, or %GDK_NONE
 *
 * Converts from a #GdkAtom to the X atom for a #GdkDisplay
 * with the same string value. The special value %GDK_NONE
 * is converted to %None.
 *
 * Return value: the X atom corresponding to @atom, or %None
 *
 * Since: 2.2
 **/
Atom
gdk_x11_atom_to_xatom_for_display (GdkDisplay *display,
				   GdkAtom     atom)
{
  Atom xatom = None;

  g_return_val_if_fail (GDK_IS_DISPLAY (display), None);

  if (atom == GDK_NONE)
    return None;

  if (display->closed)
    return None;

  xatom = lookup_cached_xatom (display, atom);

  if (!xatom)
    {
      char *name;

      g_return_val_if_fail (ATOM_TO_INDEX (atom) < virtual_atom_array->len, None);

      name = g_ptr_array_index (virtual_atom_array, ATOM_TO_INDEX (atom));

      xatom = XInternAtom (GDK_DISPLAY_XDISPLAY (display), name, FALSE);
      insert_atom_pair (display, atom, xatom);
    }

  return xatom;
}
/**
 * gdk_x11_atom_to_xatom_for_display:
 * @display: A #GdkDisplay
 * @atom: A #GdkAtom 
 * 
 * Converts from a #GdkAtom to the X atom for a #GdkDisplay
 * with the same string value.
 * 
 * Return value: the X atom corresponding to @atom.
 *
 * Since: 2.2
 **/
gi_atom_id_t
gdk_x11_atom_to_xatom_for_display (GdkDisplay *display, 
				   GdkAtom atom)
{
  gi_atom_id_t xatom = 0;
  
  g_return_val_if_fail (GDK_IS_DISPLAY (display), 0);

  if (display->closed)
    return 0;
  
  xatom = lookup_cached_xatom (display, atom);
  
  if (!xatom)
    {
      char *name;
      
      g_return_val_if_fail (ATOM_TO_INDEX (atom) < virtual_atom_array->len, 0);

      name = g_ptr_array_index (virtual_atom_array, ATOM_TO_INDEX (atom));
      
      xatom = gi_intern_atom ( name, FALSE);
      insert_atom_pair (display, atom, xatom);
    }

  return xatom;
}
static const char *
get_atom_name (GdkAtom atom)
{
  virtual_atom_check_init ();

  if (ATOM_TO_INDEX (atom) < virtual_atom_array->len)
    return g_ptr_array_index (virtual_atom_array, ATOM_TO_INDEX (atom));
  else
    return NULL;
}
static Atom
lookup_cached_xatom (GdkDisplay *display,
		     GdkAtom     atom)
{
  GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);

  if (ATOM_TO_INDEX (atom) < G_N_ELEMENTS (xatoms_offset) - N_CUSTOM_PREDEFINED)
    return ATOM_TO_INDEX (atom);
  
  if (display_x11->atom_from_virtual)
    return GPOINTER_TO_UINT (g_hash_table_lookup (display_x11->atom_from_virtual,
						  GDK_ATOM_TO_POINTER (atom)));

  return None;
}
static GdkAtom
intern_atom (const gchar *atom_name, 
	     gboolean     dup)
{
  GdkAtom result;

  virtual_atom_check_init ();
  
  result = GDK_POINTER_TO_ATOM (g_hash_table_lookup (virtual_atom_hash, atom_name));
  if (!result)
    {
      result = INDEX_TO_ATOM (virtual_atom_array->len);
      
      g_ptr_array_add (virtual_atom_array, dup ? g_strdup (atom_name) : (gchar *)atom_name);
      g_hash_table_insert (virtual_atom_hash, 
			   g_ptr_array_index (virtual_atom_array,
					      ATOM_TO_INDEX (result)),
			   GDK_ATOM_TO_POINTER (result));
    }

  return result;
}