Blame gdk/x11/gdkproperty-x11.c

Packit 98cdb6
/* GDK - The GIMP Drawing Kit
Packit 98cdb6
 * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
Packit 98cdb6
 *
Packit 98cdb6
 * This library is free software; you can redistribute it and/or
Packit 98cdb6
 * modify it under the terms of the GNU Lesser General Public
Packit 98cdb6
 * License as published by the Free Software Foundation; either
Packit 98cdb6
 * version 2 of the License, or (at your option) any later version.
Packit 98cdb6
 *
Packit 98cdb6
 * This library is distributed in the hope that it will be useful,
Packit 98cdb6
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
Packit 98cdb6
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
Packit 98cdb6
 * Lesser General Public License for more details.
Packit 98cdb6
 *
Packit 98cdb6
 * You should have received a copy of the GNU Lesser General Public
Packit 98cdb6
 * License along with this library; if not, write to the
Packit 98cdb6
 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
Packit 98cdb6
 * Boston, MA 02111-1307, USA.
Packit 98cdb6
 */
Packit 98cdb6
Packit 98cdb6
/*
Packit 98cdb6
 * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
Packit 98cdb6
 * file for a list of people on the GTK+ Team.  See the ChangeLog
Packit 98cdb6
 * files for a list of changes.  These files are distributed with
Packit 98cdb6
 * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
Packit 98cdb6
 */
Packit 98cdb6
Packit 98cdb6
#include "config.h"
Packit 98cdb6
#include <X11/Xlib.h>
Packit 98cdb6
#include <X11/Xatom.h>
Packit 98cdb6
#include <string.h>
Packit 98cdb6
Packit 98cdb6
#include "gdk.h"          /* For gdk_error_trap_push/pop() */
Packit 98cdb6
#include "gdkx.h"
Packit 98cdb6
#include "gdkproperty.h"
Packit 98cdb6
#include "gdkprivate.h"
Packit 98cdb6
#include "gdkinternals.h"
Packit 98cdb6
#include "gdkdisplay-x11.h"
Packit 98cdb6
#include "gdkscreen-x11.h"
Packit 98cdb6
#include "gdkselection.h"	/* only from predefined atom */
Packit 98cdb6
#include "gdkalias.h"
Packit 98cdb6
Packit 98cdb6
static GPtrArray *virtual_atom_array;
Packit 98cdb6
static GHashTable *virtual_atom_hash;
Packit 98cdb6
Packit 98cdb6
static const gchar xatoms_string[] = 
Packit 98cdb6
  /* These are all the standard predefined X atoms */
Packit 98cdb6
  "\0"  /* leave a space for None, even though it is not a predefined atom */
Packit 98cdb6
  "PRIMARY\0"
Packit 98cdb6
  "SECONDARY\0"
Packit 98cdb6
  "ARC\0"
Packit 98cdb6
  "ATOM\0"
Packit 98cdb6
  "BITMAP\0"
Packit 98cdb6
  "CARDINAL\0"
Packit 98cdb6
  "COLORMAP\0"
Packit 98cdb6
  "CURSOR\0"
Packit 98cdb6
  "CUT_BUFFER0\0"
Packit 98cdb6
  "CUT_BUFFER1\0"
Packit 98cdb6
  "CUT_BUFFER2\0"
Packit 98cdb6
  "CUT_BUFFER3\0"
Packit 98cdb6
  "CUT_BUFFER4\0"
Packit 98cdb6
  "CUT_BUFFER5\0"
Packit 98cdb6
  "CUT_BUFFER6\0"
Packit 98cdb6
  "CUT_BUFFER7\0"
Packit 98cdb6
  "DRAWABLE\0"
Packit 98cdb6
  "FONT\0"
Packit 98cdb6
  "INTEGER\0"
Packit 98cdb6
  "PIXMAP\0"
Packit 98cdb6
  "POINT\0"
Packit 98cdb6
  "RECTANGLE\0"
Packit 98cdb6
  "RESOURCE_MANAGER\0"
Packit 98cdb6
  "RGB_COLOR_MAP\0"
Packit 98cdb6
  "RGB_BEST_MAP\0"
Packit 98cdb6
  "RGB_BLUE_MAP\0"
Packit 98cdb6
  "RGB_DEFAULT_MAP\0"
Packit 98cdb6
  "RGB_GRAY_MAP\0"
Packit 98cdb6
  "RGB_GREEN_MAP\0"
Packit 98cdb6
  "RGB_RED_MAP\0"
Packit 98cdb6
  "STRING\0"
Packit 98cdb6
  "VISUALID\0"
Packit 98cdb6
  "WINDOW\0"
Packit 98cdb6
  "WM_COMMAND\0"
Packit 98cdb6
  "WM_HINTS\0"
Packit 98cdb6
  "WM_CLIENT_MACHINE\0"
Packit 98cdb6
  "WM_ICON_NAME\0"
Packit 98cdb6
  "WM_ICON_SIZE\0"
Packit 98cdb6
  "WM_NAME\0"
Packit 98cdb6
  "WM_NORMAL_HINTS\0"
Packit 98cdb6
  "WM_SIZE_HINTS\0"
Packit 98cdb6
  "WM_ZOOM_HINTS\0"
Packit 98cdb6
  "MIN_SPACE\0"
Packit 98cdb6
  "NORM_SPACE\0"
Packit 98cdb6
  "MAX_SPACE\0"
Packit 98cdb6
  "END_SPACE\0"
Packit 98cdb6
  "SUPERSCRIPT_X\0"
Packit 98cdb6
  "SUPERSCRIPT_Y\0"
Packit 98cdb6
  "SUBSCRIPT_X\0"
Packit 98cdb6
  "SUBSCRIPT_Y\0"
Packit 98cdb6
  "UNDERLINE_POSITION\0"
Packit 98cdb6
  "UNDERLINE_THICKNESS\0"
Packit 98cdb6
  "STRIKEOUT_ASCENT\0"
Packit 98cdb6
  "STRIKEOUT_DESCENT\0"
Packit 98cdb6
  "ITALIC_ANGLE\0"
Packit 98cdb6
  "X_HEIGHT\0"
Packit 98cdb6
  "QUAD_WIDTH\0"
Packit 98cdb6
  "WEIGHT\0"
Packit 98cdb6
  "POINT_SIZE\0"
Packit 98cdb6
  "RESOLUTION\0"
Packit 98cdb6
  "COPYRIGHT\0"
Packit 98cdb6
  "NOTICE\0"
Packit 98cdb6
  "FONT_NAME\0"
Packit 98cdb6
  "FAMILY_NAME\0"
Packit 98cdb6
  "FULL_NAME\0"
Packit 98cdb6
  "CAP_HEIGHT\0"
Packit 98cdb6
  "WM_CLASS\0"
Packit 98cdb6
  "WM_TRANSIENT_FOR\0"
Packit 98cdb6
  /* Below here, these are our additions. Increment N_CUSTOM_PREDEFINED
Packit 98cdb6
   * if you add any.
Packit 98cdb6
   */
Packit 98cdb6
  "CLIPBOARD\0"			/* = 69 */
Packit 98cdb6
;
Packit 98cdb6
Packit 98cdb6
static const gint xatoms_offset[] = {
Packit 98cdb6
    0,   1,   9,  19,  23,  28,  35,  44,  53,  60,  72,  84,
Packit 98cdb6
   96, 108, 120, 132, 144, 156, 165, 170, 178, 185, 189, 201,
Packit 98cdb6
  218, 232, 245, 258, 274, 287, 301, 313, 320, 329, 336, 347,
Packit 98cdb6
  356, 374, 387, 400, 408, 424, 438, 452, 462, 473, 483, 493,
Packit 98cdb6
  507, 521, 533, 545, 564, 584, 601, 619, 632, 641, 652, 659,
Packit 98cdb6
  670, 681, 691, 698, 708, 720, 730, 741, 750, 767
Packit 98cdb6
};
Packit 98cdb6
Packit 98cdb6
#define N_CUSTOM_PREDEFINED 1
Packit 98cdb6
Packit 98cdb6
#define ATOM_TO_INDEX(atom) (GPOINTER_TO_UINT(atom))
Packit 98cdb6
#define INDEX_TO_ATOM(atom) ((GdkAtom)GUINT_TO_POINTER(atom))
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
insert_atom_pair (GdkDisplay *display,
Packit 98cdb6
		  GdkAtom     virtual_atom,
Packit 98cdb6
		  Atom        xatom)
Packit 98cdb6
{
Packit 98cdb6
  GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);  
Packit 98cdb6
  
Packit 98cdb6
  if (!display_x11->atom_from_virtual)
Packit 98cdb6
    {
Packit 98cdb6
      display_x11->atom_from_virtual = g_hash_table_new (g_direct_hash, NULL);
Packit 98cdb6
      display_x11->atom_to_virtual = g_hash_table_new (g_direct_hash, NULL);
Packit 98cdb6
    }
Packit 98cdb6
  
Packit 98cdb6
  g_hash_table_insert (display_x11->atom_from_virtual, 
Packit 98cdb6
		       GDK_ATOM_TO_POINTER (virtual_atom), 
Packit 98cdb6
		       GUINT_TO_POINTER (xatom));
Packit 98cdb6
  g_hash_table_insert (display_x11->atom_to_virtual,
Packit 98cdb6
		       GUINT_TO_POINTER (xatom), 
Packit 98cdb6
		       GDK_ATOM_TO_POINTER (virtual_atom));
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static Atom
Packit 98cdb6
lookup_cached_xatom (GdkDisplay *display,
Packit 98cdb6
		     GdkAtom     atom)
Packit 98cdb6
{
Packit 98cdb6
  GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
Packit 98cdb6
Packit 98cdb6
  if (ATOM_TO_INDEX (atom) < G_N_ELEMENTS (xatoms_offset) - N_CUSTOM_PREDEFINED)
Packit 98cdb6
    return ATOM_TO_INDEX (atom);
Packit 98cdb6
  
Packit 98cdb6
  if (display_x11->atom_from_virtual)
Packit 98cdb6
    return GPOINTER_TO_UINT (g_hash_table_lookup (display_x11->atom_from_virtual,
Packit 98cdb6
						  GDK_ATOM_TO_POINTER (atom)));
Packit 98cdb6
Packit 98cdb6
  return None;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_x11_atom_to_xatom_for_display:
Packit 98cdb6
 * @display: A #GdkDisplay
Packit 98cdb6
 * @atom: A #GdkAtom, or %GDK_NONE
Packit 98cdb6
 *
Packit 98cdb6
 * Converts from a #GdkAtom to the X atom for a #GdkDisplay
Packit 98cdb6
 * with the same string value. The special value %GDK_NONE
Packit 98cdb6
 * is converted to %None.
Packit 98cdb6
 *
Packit 98cdb6
 * Return value: the X atom corresponding to @atom, or %None
Packit 98cdb6
 *
Packit 98cdb6
 * Since: 2.2
Packit 98cdb6
 **/
Packit 98cdb6
Atom
Packit 98cdb6
gdk_x11_atom_to_xatom_for_display (GdkDisplay *display,
Packit 98cdb6
				   GdkAtom     atom)
Packit 98cdb6
{
Packit 98cdb6
  Atom xatom = None;
Packit 98cdb6
Packit 98cdb6
  g_return_val_if_fail (GDK_IS_DISPLAY (display), None);
Packit 98cdb6
Packit 98cdb6
  if (atom == GDK_NONE)
Packit 98cdb6
    return None;
Packit 98cdb6
Packit 98cdb6
  if (display->closed)
Packit 98cdb6
    return None;
Packit 98cdb6
Packit 98cdb6
  xatom = lookup_cached_xatom (display, atom);
Packit 98cdb6
Packit 98cdb6
  if (!xatom)
Packit 98cdb6
    {
Packit 98cdb6
      char *name;
Packit 98cdb6
Packit 98cdb6
      g_return_val_if_fail (ATOM_TO_INDEX (atom) < virtual_atom_array->len, None);
Packit 98cdb6
Packit 98cdb6
      name = g_ptr_array_index (virtual_atom_array, ATOM_TO_INDEX (atom));
Packit 98cdb6
Packit 98cdb6
      xatom = XInternAtom (GDK_DISPLAY_XDISPLAY (display), name, FALSE);
Packit 98cdb6
      insert_atom_pair (display, atom, xatom);
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  return xatom;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
void
Packit 98cdb6
_gdk_x11_precache_atoms (GdkDisplay          *display,
Packit 98cdb6
			 const gchar * const *atom_names,
Packit 98cdb6
			 gint                 n_atoms)
Packit 98cdb6
{
Packit 98cdb6
  Atom *xatoms;
Packit 98cdb6
  GdkAtom *atoms;
Packit 98cdb6
  const gchar **xatom_names;
Packit 98cdb6
  gint n_xatoms;
Packit 98cdb6
  gint i;
Packit 98cdb6
Packit 98cdb6
  xatoms = g_new (Atom, n_atoms);
Packit 98cdb6
  xatom_names = g_new (const gchar *, n_atoms);
Packit 98cdb6
  atoms = g_new (GdkAtom, n_atoms);
Packit 98cdb6
Packit 98cdb6
  n_xatoms = 0;
Packit 98cdb6
  for (i = 0; i < n_atoms; i++)
Packit 98cdb6
    {
Packit 98cdb6
      GdkAtom atom = gdk_atom_intern_static_string (atom_names[i]);
Packit 98cdb6
      if (lookup_cached_xatom (display, atom) == None)
Packit 98cdb6
	{
Packit 98cdb6
	  atoms[n_xatoms] = atom;
Packit 98cdb6
	  xatom_names[n_xatoms] = atom_names[i];
Packit 98cdb6
	  n_xatoms++;
Packit 98cdb6
	}
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  if (n_xatoms)
Packit 98cdb6
    {
Packit 98cdb6
#ifdef HAVE_XINTERNATOMS
Packit 98cdb6
      XInternAtoms (GDK_DISPLAY_XDISPLAY (display),
Packit 98cdb6
		    (char **)xatom_names, n_xatoms, False, xatoms);
Packit 98cdb6
#else
Packit 98cdb6
      for (i = 0; i < n_xatoms; i++)
Packit 98cdb6
	xatoms[i] = XInternAtom (GDK_DISPLAY_XDISPLAY (display),
Packit 98cdb6
				 xatom_names[i], False);
Packit 98cdb6
#endif
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  for (i = 0; i < n_xatoms; i++)
Packit 98cdb6
    insert_atom_pair (display, atoms[i], xatoms[i]);
Packit 98cdb6
Packit 98cdb6
  g_free (xatoms);
Packit 98cdb6
  g_free (xatom_names);
Packit 98cdb6
  g_free (atoms);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_x11_atom_to_xatom:
Packit 98cdb6
 * @atom: A #GdkAtom 
Packit 98cdb6
 * 
Packit 98cdb6
 * Converts from a #GdkAtom to the X atom for the default GDK display
Packit 98cdb6
 * with the same string value.
Packit 98cdb6
 * 
Packit 98cdb6
 * Return value: the X atom corresponding to @atom.
Packit 98cdb6
 **/
Packit 98cdb6
Atom
Packit 98cdb6
gdk_x11_atom_to_xatom (GdkAtom atom)
Packit 98cdb6
{
Packit 98cdb6
  return gdk_x11_atom_to_xatom_for_display (gdk_display_get_default (), atom);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_x11_xatom_to_atom_for_display:
Packit 98cdb6
 * @display: A #GdkDisplay
Packit 98cdb6
 * @xatom: an X atom 
Packit 98cdb6
 * 
Packit 98cdb6
 * Convert from an X atom for a #GdkDisplay to the corresponding
Packit 98cdb6
 * #GdkAtom.
Packit 98cdb6
 * 
Packit 98cdb6
 * Return value: the corresponding #GdkAtom.
Packit 98cdb6
 *
Packit 98cdb6
 * Since: 2.2
Packit 98cdb6
 **/
Packit 98cdb6
GdkAtom
Packit 98cdb6
gdk_x11_xatom_to_atom_for_display (GdkDisplay *display,
Packit 98cdb6
				   Atom	       xatom)
Packit 98cdb6
{
Packit 98cdb6
  GdkDisplayX11 *display_x11;
Packit 98cdb6
  GdkAtom virtual_atom = GDK_NONE;
Packit 98cdb6
  
Packit 98cdb6
  g_return_val_if_fail (GDK_IS_DISPLAY (display), GDK_NONE);
Packit 98cdb6
Packit 98cdb6
  if (xatom == None)
Packit 98cdb6
    return GDK_NONE;
Packit 98cdb6
Packit 98cdb6
  if (display->closed)
Packit 98cdb6
    return GDK_NONE;
Packit 98cdb6
Packit 98cdb6
  display_x11 = GDK_DISPLAY_X11 (display);
Packit 98cdb6
  
Packit 98cdb6
  if (xatom < G_N_ELEMENTS (xatoms_offset) - N_CUSTOM_PREDEFINED)
Packit 98cdb6
    return INDEX_TO_ATOM (xatom);
Packit 98cdb6
  
Packit 98cdb6
  if (display_x11->atom_to_virtual)
Packit 98cdb6
    virtual_atom = GDK_POINTER_TO_ATOM (g_hash_table_lookup (display_x11->atom_to_virtual,
Packit 98cdb6
							     GUINT_TO_POINTER (xatom)));
Packit 98cdb6
  
Packit 98cdb6
  if (!virtual_atom)
Packit 98cdb6
    {
Packit 98cdb6
      /* If this atom doesn't exist, we'll die with an X error unless
Packit 98cdb6
       * we take precautions
Packit 98cdb6
       */
Packit 98cdb6
      char *name;
Packit 98cdb6
      gdk_error_trap_push ();
Packit 98cdb6
      name = XGetAtomName (GDK_DISPLAY_XDISPLAY (display), xatom);
Packit 98cdb6
      if (gdk_error_trap_pop ())
Packit 98cdb6
	{
Packit 98cdb6
	  g_warning (G_STRLOC " invalid X atom: %ld", xatom);
Packit 98cdb6
	}
Packit 98cdb6
      else
Packit 98cdb6
	{
Packit 98cdb6
	  virtual_atom = gdk_atom_intern (name, FALSE);
Packit 98cdb6
	  XFree (name);
Packit 98cdb6
	  
Packit 98cdb6
	  insert_atom_pair (display, virtual_atom, xatom);
Packit 98cdb6
	}
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  return virtual_atom;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_x11_xatom_to_atom:
Packit 98cdb6
 * @xatom: an X atom for the default GDK display
Packit 98cdb6
 * 
Packit 98cdb6
 * Convert from an X atom for the default display to the corresponding
Packit 98cdb6
 * #GdkAtom.
Packit 98cdb6
 * 
Packit 98cdb6
 * Return value: the corresponding G#dkAtom.
Packit 98cdb6
 **/
Packit 98cdb6
GdkAtom
Packit 98cdb6
gdk_x11_xatom_to_atom (Atom xatom)
Packit 98cdb6
{
Packit 98cdb6
  return gdk_x11_xatom_to_atom_for_display (gdk_display_get_default (), xatom);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
virtual_atom_check_init (void)
Packit 98cdb6
{
Packit 98cdb6
  if (!virtual_atom_hash)
Packit 98cdb6
    {
Packit 98cdb6
      gint i;
Packit 98cdb6
      
Packit 98cdb6
      virtual_atom_hash = g_hash_table_new (g_str_hash, g_str_equal);
Packit 98cdb6
      virtual_atom_array = g_ptr_array_new ();
Packit 98cdb6
      
Packit 98cdb6
      for (i = 0; i < G_N_ELEMENTS (xatoms_offset); i++)
Packit 98cdb6
	{
Packit 98cdb6
	  g_ptr_array_add (virtual_atom_array, (gchar *)(xatoms_string + xatoms_offset[i]));
Packit 98cdb6
	  g_hash_table_insert (virtual_atom_hash, (gchar *)(xatoms_string + xatoms_offset[i]),
Packit 98cdb6
			       GUINT_TO_POINTER (i));
Packit 98cdb6
	}
Packit 98cdb6
    }
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static GdkAtom
Packit 98cdb6
intern_atom (const gchar *atom_name, 
Packit 98cdb6
	     gboolean     dup)
Packit 98cdb6
{
Packit 98cdb6
  GdkAtom result;
Packit 98cdb6
Packit 98cdb6
  virtual_atom_check_init ();
Packit 98cdb6
  
Packit 98cdb6
  result = GDK_POINTER_TO_ATOM (g_hash_table_lookup (virtual_atom_hash, atom_name));
Packit 98cdb6
  if (!result)
Packit 98cdb6
    {
Packit 98cdb6
      result = INDEX_TO_ATOM (virtual_atom_array->len);
Packit 98cdb6
      
Packit 98cdb6
      g_ptr_array_add (virtual_atom_array, dup ? g_strdup (atom_name) : (gchar *)atom_name);
Packit 98cdb6
      g_hash_table_insert (virtual_atom_hash, 
Packit 98cdb6
			   g_ptr_array_index (virtual_atom_array,
Packit 98cdb6
					      ATOM_TO_INDEX (result)),
Packit 98cdb6
			   GDK_ATOM_TO_POINTER (result));
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  return result;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
GdkAtom
Packit 98cdb6
gdk_atom_intern (const gchar *atom_name, 
Packit 98cdb6
		 gboolean     only_if_exists)
Packit 98cdb6
{
Packit 98cdb6
  return intern_atom (atom_name, TRUE);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_atom_intern_static_string:
Packit 98cdb6
 * @atom_name: a static string
Packit 98cdb6
 *
Packit 98cdb6
 * Finds or creates an atom corresponding to a given string.
Packit 98cdb6
 *
Packit 98cdb6
 * Note that this function is identical to gdk_atom_intern() except
Packit 98cdb6
 * that if a new #GdkAtom is created the string itself is used rather 
Packit 98cdb6
 * than a copy. This saves memory, but can only be used if the string 
Packit 98cdb6
 * will <emphasis>always</emphasis> exist. It can be used with statically
Packit 98cdb6
 * allocated strings in the main program, but not with statically 
Packit 98cdb6
 * allocated memory in dynamically loaded modules, if you expect to
Packit 98cdb6
 * ever unload the module again (e.g. do not use this function in
Packit 98cdb6
 * GTK+ theme engines).
Packit 98cdb6
 *
Packit 98cdb6
 * Returns: the atom corresponding to @atom_name
Packit 98cdb6
 * 
Packit 98cdb6
 * Since: 2.10
Packit 98cdb6
 */
Packit 98cdb6
GdkAtom
Packit 98cdb6
gdk_atom_intern_static_string (const gchar *atom_name)
Packit 98cdb6
{
Packit 98cdb6
  return intern_atom (atom_name, FALSE);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static const char *
Packit 98cdb6
get_atom_name (GdkAtom atom)
Packit 98cdb6
{
Packit 98cdb6
  virtual_atom_check_init ();
Packit 98cdb6
Packit 98cdb6
  if (ATOM_TO_INDEX (atom) < virtual_atom_array->len)
Packit 98cdb6
    return g_ptr_array_index (virtual_atom_array, ATOM_TO_INDEX (atom));
Packit 98cdb6
  else
Packit 98cdb6
    return NULL;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
gchar *
Packit 98cdb6
gdk_atom_name (GdkAtom atom)
Packit 98cdb6
{
Packit 98cdb6
  return g_strdup (get_atom_name (atom));
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_x11_get_xatom_by_name_for_display:
Packit 98cdb6
 * @display: a #GdkDisplay
Packit 98cdb6
 * @atom_name: a string
Packit 98cdb6
 * 
Packit 98cdb6
 * Returns the X atom for a #GdkDisplay corresponding to @atom_name.
Packit 98cdb6
 * This function caches the result, so if called repeatedly it is much
Packit 98cdb6
 * faster than XInternAtom(), which is a round trip to the server each time.
Packit 98cdb6
 * 
Packit 98cdb6
 * Return value: a X atom for a #GdkDisplay
Packit 98cdb6
 *
Packit 98cdb6
 * Since: 2.2
Packit 98cdb6
 **/
Packit 98cdb6
Atom
Packit 98cdb6
gdk_x11_get_xatom_by_name_for_display (GdkDisplay  *display,
Packit 98cdb6
				       const gchar *atom_name)
Packit 98cdb6
{
Packit 98cdb6
  g_return_val_if_fail (GDK_IS_DISPLAY (display), None);
Packit 98cdb6
  return gdk_x11_atom_to_xatom_for_display (display,
Packit 98cdb6
					    gdk_atom_intern (atom_name, FALSE));
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_x11_get_xatom_by_name:
Packit 98cdb6
 * @atom_name: a string
Packit 98cdb6
 * 
Packit 98cdb6
 * Returns the X atom for GDK's default display corresponding to @atom_name.
Packit 98cdb6
 * This function caches the result, so if called repeatedly it is much
Packit 98cdb6
 * faster than XInternAtom(), which is a round trip to the server each time.
Packit 98cdb6
 * 
Packit 98cdb6
 * Return value: a X atom for GDK's default display.
Packit 98cdb6
 **/
Packit 98cdb6
Atom
Packit 98cdb6
gdk_x11_get_xatom_by_name (const gchar *atom_name)
Packit 98cdb6
{
Packit 98cdb6
  return gdk_x11_get_xatom_by_name_for_display (gdk_display_get_default (),
Packit 98cdb6
						atom_name);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_x11_get_xatom_name_for_display:
Packit 98cdb6
 * @display: the #GdkDisplay where @xatom is defined
Packit 98cdb6
 * @xatom: an X atom 
Packit 98cdb6
 * 
Packit 98cdb6
 * Returns the name of an X atom for its display. This
Packit 98cdb6
 * function is meant mainly for debugging, so for convenience, unlike
Packit 98cdb6
 * XAtomName() and gdk_atom_name(), the result doesn't need to
Packit 98cdb6
 * be freed. 
Packit 98cdb6
 *
Packit 98cdb6
 * Return value: name of the X atom; this string is owned by GDK,
Packit 98cdb6
 *   so it shouldn't be modifed or freed. 
Packit 98cdb6
 *
Packit 98cdb6
 * Since: 2.2
Packit 98cdb6
 **/
Packit 98cdb6
const gchar *
Packit 98cdb6
gdk_x11_get_xatom_name_for_display (GdkDisplay *display,
Packit 98cdb6
				    Atom        xatom)
Packit 98cdb6
{
Packit 98cdb6
  g_return_val_if_fail (GDK_IS_DISPLAY (display), NULL);
Packit 98cdb6
Packit 98cdb6
  return get_atom_name (gdk_x11_xatom_to_atom_for_display (display, xatom));
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
/**
Packit 98cdb6
 * gdk_x11_get_xatom_name:
Packit 98cdb6
 * @xatom: an X atom for GDK's default display
Packit 98cdb6
 * 
Packit 98cdb6
 * Returns the name of an X atom for GDK's default display. This
Packit 98cdb6
 * function is meant mainly for debugging, so for convenience, unlike
Packit 98cdb6
 * <function>XAtomName()</function> and gdk_atom_name(), the result 
Packit 98cdb6
 * doesn't need to be freed. Also, this function will never return %NULL, 
Packit 98cdb6
 * even if @xatom is invalid.
Packit 98cdb6
 * 
Packit 98cdb6
 * Return value: name of the X atom; this string is owned by GTK+,
Packit 98cdb6
 *   so it shouldn't be modifed or freed. 
Packit 98cdb6
 **/
Packit 98cdb6
const gchar *
Packit 98cdb6
gdk_x11_get_xatom_name (Atom xatom)
Packit 98cdb6
{
Packit 98cdb6
  return get_atom_name (gdk_x11_xatom_to_atom (xatom));
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
gboolean
Packit 98cdb6
gdk_property_get (GdkWindow   *window,
Packit 98cdb6
		  GdkAtom      property,
Packit 98cdb6
		  GdkAtom      type,
Packit 98cdb6
		  gulong       offset,
Packit 98cdb6
		  gulong       length,
Packit 98cdb6
		  gint         pdelete,
Packit 98cdb6
		  GdkAtom     *actual_property_type,
Packit 98cdb6
		  gint        *actual_format_type,
Packit 98cdb6
		  gint        *actual_length,
Packit 98cdb6
		  guchar     **data)
Packit 98cdb6
{
Packit 98cdb6
  GdkDisplay *display;
Packit 98cdb6
  Atom ret_prop_type;
Packit 98cdb6
  gint ret_format;
Packit 98cdb6
  gulong ret_nitems;
Packit 98cdb6
  gulong ret_bytes_after;
Packit 98cdb6
  gulong get_length;
Packit 98cdb6
  gulong ret_length;
Packit 98cdb6
  guchar *ret_data;
Packit 98cdb6
  Atom xproperty;
Packit 98cdb6
  Atom xtype;
Packit 98cdb6
  int res;
Packit 98cdb6
Packit 98cdb6
  g_return_val_if_fail (!window || GDK_WINDOW_IS_X11 (window), FALSE);
Packit 98cdb6
Packit 98cdb6
  if (!window)
Packit 98cdb6
    {
Packit 98cdb6
      GdkScreen *screen = gdk_screen_get_default ();
Packit 98cdb6
      window = gdk_screen_get_root_window (screen);
Packit 98cdb6
      
Packit 98cdb6
      GDK_NOTE (MULTIHEAD, g_message ("gdk_property_get(): window is NULL\n"));
Packit 98cdb6
    }
Packit 98cdb6
  else if (!GDK_WINDOW_IS_X11 (window))
Packit 98cdb6
    return FALSE;
Packit 98cdb6
Packit 98cdb6
  if (GDK_WINDOW_DESTROYED (window))
Packit 98cdb6
    return FALSE;
Packit 98cdb6
Packit 98cdb6
  display = gdk_drawable_get_display (window);
Packit 98cdb6
  xproperty = gdk_x11_atom_to_xatom_for_display (display, property);
Packit 98cdb6
  if (type == GDK_NONE)
Packit 98cdb6
    xtype = AnyPropertyType;
Packit 98cdb6
  else
Packit 98cdb6
    xtype = gdk_x11_atom_to_xatom_for_display (display, type);
Packit 98cdb6
Packit 98cdb6
  ret_data = NULL;
Packit 98cdb6
  
Packit 98cdb6
  /* 
Packit 98cdb6
   * Round up length to next 4 byte value.  Some code is in the (bad?)
Packit 98cdb6
   * habit of passing G_MAXLONG as the length argument, causing an
Packit 98cdb6
   * overflow to negative on the add.  In this case, we clamp the
Packit 98cdb6
   * value to G_MAXLONG.
Packit 98cdb6
   */
Packit 98cdb6
  get_length = length + 3;
Packit 98cdb6
  if (get_length > G_MAXLONG)
Packit 98cdb6
    get_length = G_MAXLONG;
Packit 98cdb6
Packit 98cdb6
  /* To fail, either the user passed 0 or G_MAXULONG */
Packit 98cdb6
  get_length = get_length / 4;
Packit 98cdb6
  if (get_length == 0)
Packit 98cdb6
    {
Packit 98cdb6
      g_warning ("gdk_propery-get(): invalid length 0");
Packit 98cdb6
      return FALSE;
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  res = XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display),
Packit 98cdb6
			    GDK_WINDOW_XWINDOW (window), xproperty,
Packit 98cdb6
			    offset, get_length, pdelete,
Packit 98cdb6
			    xtype, &ret_prop_type, &ret_format,
Packit 98cdb6
			    &ret_nitems, &ret_bytes_after,
Packit 98cdb6
			    &ret_data);
Packit 98cdb6
Packit 98cdb6
  if (res != Success || (ret_prop_type == None && ret_format == 0))
Packit 98cdb6
    {
Packit 98cdb6
      return FALSE;
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  if (actual_property_type)
Packit 98cdb6
    *actual_property_type = gdk_x11_xatom_to_atom_for_display (display, ret_prop_type);
Packit 98cdb6
  if (actual_format_type)
Packit 98cdb6
    *actual_format_type = ret_format;
Packit 98cdb6
Packit 98cdb6
  if ((xtype != AnyPropertyType) && (ret_prop_type != xtype))
Packit 98cdb6
    {
Packit 98cdb6
      XFree (ret_data);
Packit 98cdb6
      g_warning ("Couldn't match property type %s to %s\n", 
Packit 98cdb6
		 gdk_x11_get_xatom_name_for_display (display, ret_prop_type), 
Packit 98cdb6
		 gdk_x11_get_xatom_name_for_display (display, xtype));
Packit 98cdb6
      return FALSE;
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  /* FIXME: ignoring bytes_after could have very bad effects */
Packit 98cdb6
Packit 98cdb6
  if (data)
Packit 98cdb6
    {
Packit 98cdb6
      if (ret_prop_type == XA_ATOM ||
Packit 98cdb6
	  ret_prop_type == gdk_x11_get_xatom_by_name_for_display (display, "ATOM_PAIR"))
Packit 98cdb6
	{
Packit 98cdb6
	  /*
Packit 98cdb6
	   * data is an array of X atom, we need to convert it
Packit 98cdb6
	   * to an array of GDK Atoms
Packit 98cdb6
	   */
Packit 98cdb6
	  gint i;
Packit 98cdb6
	  GdkAtom *ret_atoms = g_new (GdkAtom, ret_nitems);
Packit 98cdb6
	  Atom *xatoms = (Atom *)ret_data;
Packit 98cdb6
Packit 98cdb6
	  *data = (guchar *)ret_atoms;
Packit 98cdb6
Packit 98cdb6
	  for (i = 0; i < ret_nitems; i++)
Packit 98cdb6
	    ret_atoms[i] = gdk_x11_xatom_to_atom_for_display (display, xatoms[i]);
Packit 98cdb6
	  
Packit 98cdb6
	  if (actual_length)
Packit 98cdb6
	    *actual_length = ret_nitems * sizeof (GdkAtom);
Packit 98cdb6
	}
Packit 98cdb6
      else
Packit 98cdb6
	{
Packit 98cdb6
	  switch (ret_format)
Packit 98cdb6
	    {
Packit 98cdb6
	    case 8:
Packit 98cdb6
	      ret_length = ret_nitems;
Packit 98cdb6
	      break;
Packit 98cdb6
	    case 16:
Packit 98cdb6
	      ret_length = sizeof(short) * ret_nitems;
Packit 98cdb6
	      break;
Packit 98cdb6
	    case 32:
Packit 98cdb6
	      ret_length = sizeof(long) * ret_nitems;
Packit 98cdb6
	      break;
Packit 98cdb6
	    default:
Packit 98cdb6
	      g_warning ("unknown property return format: %d", ret_format);
Packit 98cdb6
	      XFree (ret_data);
Packit 98cdb6
	      return FALSE;
Packit 98cdb6
	    }
Packit 98cdb6
	  
Packit 98cdb6
	  *data = g_new (guchar, ret_length);
Packit 98cdb6
	  memcpy (*data, ret_data, ret_length);
Packit 98cdb6
	  if (actual_length)
Packit 98cdb6
	    *actual_length = ret_length;
Packit 98cdb6
	}
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  XFree (ret_data);
Packit 98cdb6
Packit 98cdb6
  return TRUE;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
void
Packit 98cdb6
gdk_property_change (GdkWindow    *window,
Packit 98cdb6
		     GdkAtom       property,
Packit 98cdb6
		     GdkAtom       type,
Packit 98cdb6
		     gint          format,
Packit 98cdb6
		     GdkPropMode   mode,
Packit 98cdb6
		     const guchar *data,
Packit 98cdb6
		     gint          nelements)
Packit 98cdb6
{
Packit 98cdb6
  GdkDisplay *display;
Packit 98cdb6
  Window xwindow;
Packit 98cdb6
  Atom xproperty;
Packit 98cdb6
  Atom xtype;
Packit 98cdb6
Packit 98cdb6
  g_return_if_fail (!window || GDK_WINDOW_IS_X11 (window));
Packit 98cdb6
Packit 98cdb6
  if (!window)
Packit 98cdb6
    {
Packit 98cdb6
      GdkScreen *screen;
Packit 98cdb6
      
Packit 98cdb6
      screen = gdk_screen_get_default ();
Packit 98cdb6
      window = gdk_screen_get_root_window (screen);
Packit 98cdb6
      
Packit 98cdb6
      GDK_NOTE (MULTIHEAD, g_message ("gdk_property_change(): window is NULL\n"));
Packit 98cdb6
    }
Packit 98cdb6
  else if (!GDK_WINDOW_IS_X11 (window))
Packit 98cdb6
    return;
Packit 98cdb6
Packit 98cdb6
  if (GDK_WINDOW_DESTROYED (window))
Packit 98cdb6
    return;
Packit 98cdb6
Packit 98cdb6
  gdk_window_ensure_native (window);
Packit 98cdb6
Packit 98cdb6
  display = gdk_drawable_get_display (window);
Packit 98cdb6
  xproperty = gdk_x11_atom_to_xatom_for_display (display, property);
Packit 98cdb6
  xtype = gdk_x11_atom_to_xatom_for_display (display, type);
Packit 98cdb6
  xwindow = GDK_WINDOW_XID (window);
Packit 98cdb6
Packit 98cdb6
  if (xtype == XA_ATOM ||
Packit 98cdb6
      xtype == gdk_x11_get_xatom_by_name_for_display (display, "ATOM_PAIR"))
Packit 98cdb6
    {
Packit 98cdb6
      /*
Packit 98cdb6
       * data is an array of GdkAtom, we need to convert it
Packit 98cdb6
       * to an array of X Atoms
Packit 98cdb6
       */
Packit 98cdb6
      gint i;
Packit 98cdb6
      GdkAtom *atoms = (GdkAtom*) data;
Packit 98cdb6
      Atom *xatoms;
Packit 98cdb6
Packit 98cdb6
      xatoms = g_new (Atom, nelements);
Packit 98cdb6
      for (i = 0; i < nelements; i++)
Packit 98cdb6
	xatoms[i] = gdk_x11_atom_to_xatom_for_display (display, atoms[i]);
Packit 98cdb6
Packit 98cdb6
      XChangeProperty (GDK_DISPLAY_XDISPLAY (display), xwindow,
Packit 98cdb6
		       xproperty, xtype,
Packit 98cdb6
		       format, mode, (guchar *)xatoms, nelements);
Packit 98cdb6
      g_free (xatoms);
Packit 98cdb6
    }
Packit 98cdb6
  else
Packit 98cdb6
    XChangeProperty (GDK_DISPLAY_XDISPLAY (display), xwindow, xproperty, 
Packit 98cdb6
		     xtype, format, mode, (guchar *)data, nelements);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
void
Packit 98cdb6
gdk_property_delete (GdkWindow *window,
Packit 98cdb6
		     GdkAtom    property)
Packit 98cdb6
{
Packit 98cdb6
  g_return_if_fail (!window || GDK_WINDOW_IS_X11 (window));
Packit 98cdb6
Packit 98cdb6
  if (!window)
Packit 98cdb6
    {
Packit 98cdb6
      GdkScreen *screen = gdk_screen_get_default ();
Packit 98cdb6
      window = gdk_screen_get_root_window (screen);
Packit 98cdb6
      
Packit 98cdb6
      GDK_NOTE (MULTIHEAD, 
Packit 98cdb6
		g_message ("gdk_property_delete(): window is NULL\n"));
Packit 98cdb6
    }
Packit 98cdb6
  else if (!GDK_WINDOW_IS_X11 (window))
Packit 98cdb6
    return;
Packit 98cdb6
Packit 98cdb6
  if (GDK_WINDOW_DESTROYED (window))
Packit 98cdb6
    return;
Packit 98cdb6
Packit 98cdb6
  XDeleteProperty (GDK_WINDOW_XDISPLAY (window), GDK_WINDOW_XWINDOW (window),
Packit 98cdb6
		   gdk_x11_atom_to_xatom_for_display (GDK_WINDOW_DISPLAY (window),
Packit 98cdb6
						      property));
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
#define __GDK_PROPERTY_X11_C__
Packit 98cdb6
#include "gdkaliasdef.c"