]> Pileus Git - ~andy/gtk/blobdiff - gdk/x11/gdkproperty-x11.c
moved and renamed the gdk_settings_names and gdk_settings_map.
[~andy/gtk] / gdk / x11 / gdkproperty-x11.c
index 96cb6317db335af34dfa1081880ec23dd0ba1337..709512517d3bf2d7ff5988d5a08697fd0e35642d 100644 (file)
@@ -24,6 +24,7 @@
  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
  */
 
+#include <config.h>
 #include <X11/Xlib.h>
 #include <X11/Xatom.h>
 #include <string.h>
 #include "gdkdisplay-x11.h"
 #include "gdkscreen-x11.h"
 #include "gdkselection.h"      /* only from predefined atom */
+#include "gdkalias.h"
 
 static GPtrArray *virtual_atom_array;
 static GHashTable *virtual_atom_hash;
 
-static gchar *XAtomsStrings[] = {
+static const gchar xatoms_string[] = 
   /* These are all the standard predefined X atoms */
-  "NONE",
-  "PRIMARY",
-  "SECONDARY",
-  "ARC",
-  "ATOM",
-  "BITMAP",
-  "CARDINAL",
-  "COLORMAP",
-  "CURSOR",
-  "CUT_BUFFER0",
-  "CUT_BUFFER1",
-  "CUT_BUFFER2",
-  "CUT_BUFFER3",
-  "CUT_BUFFER4",
-  "CUT_BUFFER5",
-  "CUT_BUFFER6",
-  "CUT_BUFFER7",
-  "DRAWABLE",
-  "FONT",
-  "INTEGER",
-  "PIXMAP",
-  "POINT",
-  "RECTANGLE",
-  "RESOURCE_MANAGER",
-  "RGB_COLOR_MAP",
-  "RGB_BEST_MAP",
-  "RGB_BLUE_MAP",
-  "RGB_DEFAULT_MAP",
-  "RGB_GRAY_MAP",
-  "RGB_GREEN_MAP",
-  "RGB_RED_MAP",
-  "STRING",
-  "VISUALID",
-  "WINDOW",
-  "WM_COMMAND",
-  "WM_HINTS",
-  "WM_CLIENT_MACHINE",
-  "WM_ICON_NAME",
-  "WM_ICON_SIZE",
-  "WM_NAME",
-  "WM_NORMAL_HINTS",
-  "WM_SIZE_HINTS",
-  "WM_ZOOM_HINTS",
-  "MIN_SPACE",
-  "NORM_SPACE",
-  "MAX_SPACE",
-  "END_SPACE",
-  "SUPERSCRIPT_X",
-  "SUPERSCRIPT_Y",
-  "SUBSCRIPT_X",
-  "SUBSCRIPT_Y",
-  "UNDERLINE_POSITION",
-  "UNDERLINE_THICKNESS",
-  "STRIKEOUT_ASCENT",
-  "STRIKEOUT_DESCENT",
-  "ITALIC_ANGLE",
-  "X_HEIGHT",
-  "QUAD_WIDTH",
-  "WEIGHT",
-  "POINT_SIZE",
-  "RESOLUTION",
-  "COPYRIGHT",
-  "NOTICE",
-  "FONT_NAME",
-  "FAMILY_NAME",
-  "FULL_NAME",
-  "CAP_HEIGHT",
-  "WM_CLASS",
-  "WM_TRANSIENT_FOR",
+  "NONE\0"
+  "PRIMARY\0"
+  "SECONDARY\0"
+  "ARC\0"
+  "ATOM\0"
+  "BITMAP\0"
+  "CARDINAL\0"
+  "COLORMAP\0"
+  "CURSOR\0"
+  "CUT_BUFFER0\0"
+  "CUT_BUFFER1\0"
+  "CUT_BUFFER2\0"
+  "CUT_BUFFER3\0"
+  "CUT_BUFFER4\0"
+  "CUT_BUFFER5\0"
+  "CUT_BUFFER6\0"
+  "CUT_BUFFER7\0"
+  "DRAWABLE\0"
+  "FONT\0"
+  "INTEGER\0"
+  "PIXMAP\0"
+  "POINT\0"
+  "RECTANGLE\0"
+  "RESOURCE_MANAGER\0"
+  "RGB_COLOR_MAP\0"
+  "RGB_BEST_MAP\0"
+  "RGB_BLUE_MAP\0"
+  "RGB_DEFAULT_MAP\0"
+  "RGB_GRAY_MAP\0"
+  "RGB_GREEN_MAP\0"
+  "RGB_RED_MAP\0"
+  "STRING\0"
+  "VISUALID\0"
+  "WINDOW\0"
+  "WM_COMMAND\0"
+  "WM_HINTS\0"
+  "WM_CLIENT_MACHINE\0"
+  "WM_ICON_NAME\0"
+  "WM_ICON_SIZE\0"
+  "WM_NAME\0"
+  "WM_NORMAL_HINTS\0"
+  "WM_SIZE_HINTS\0"
+  "WM_ZOOM_HINTS\0"
+  "MIN_SPACE\0"
+  "NORM_SPACE\0"
+  "MAX_SPACE\0"
+  "END_SPACE\0"
+  "SUPERSCRIPT_X\0"
+  "SUPERSCRIPT_Y\0"
+  "SUBSCRIPT_X\0"
+  "SUBSCRIPT_Y\0"
+  "UNDERLINE_POSITION\0"
+  "UNDERLINE_THICKNESS\0"
+  "STRIKEOUT_ASCENT\0"
+  "STRIKEOUT_DESCENT\0"
+  "ITALIC_ANGLE\0"
+  "X_HEIGHT\0"
+  "QUAD_WIDTH\0"
+  "WEIGHT\0"
+  "POINT_SIZE\0"
+  "RESOLUTION\0"
+  "COPYRIGHT\0"
+  "NOTICE\0"
+  "FONT_NAME\0"
+  "FAMILY_NAME\0"
+  "FULL_NAME\0"
+  "CAP_HEIGHT\0"
+  "WM_CLASS\0"
+  "WM_TRANSIENT_FOR\0"
   /* Below here, these are our additions. Increment N_CUSTOM_PREDEFINED
    * if you add any.
    */
-  "CLIPBOARD"                  /* = 69 */
+  "CLIPBOARD\0"                        /* = 69 */
+;
+
+static const gint xatoms_offset[] = {
+    0,   5,  13,  23,  27,  32,  39,  48,  57,  64,  76,  88, 
+  100, 112, 124, 136, 148, 160, 169, 174, 182, 189, 195, 205, 
+  222, 236, 249, 262, 278, 291, 305, 317, 324, 333, 340, 351, 
+  360, 378, 391, 404, 412, 428, 442, 456, 466, 477, 487, 497, 
+  511, 525, 537, 549, 568, 588, 605, 623, 636, 645, 656, 663, 
+  674, 685, 695, 702, 712, 724, 734, 745, 754, 771
 };
 
 #define N_CUSTOM_PREDEFINED 1
@@ -149,7 +160,7 @@ lookup_cached_xatom (GdkDisplay *display,
 {
   GdkDisplayX11 *display_x11 = GDK_DISPLAY_X11 (display);
 
-  if (ATOM_TO_INDEX (atom) < G_N_ELEMENTS (XAtomsStrings) - N_CUSTOM_PREDEFINED)
+  if (ATOM_TO_INDEX (atom) < G_N_ELEMENTS (xatoms_offset) - N_CUSTOM_PREDEFINED)
     return ATOM_TO_INDEX (atom);
   
   if (display_x11->atom_from_virtual)
@@ -217,7 +228,7 @@ _gdk_x11_precache_atoms (GdkDisplay          *display,
   n_xatoms = 0;
   for (i = 0; i < n_atoms; i++)
     {
-      GdkAtom atom = gdk_atom_intern (atom_names[i], FALSE);
+      GdkAtom atom = gdk_atom_intern_static_string (atom_names[i]);
       if (lookup_cached_xatom (display, atom) == None)
        {
          atoms[n_xatoms] = atom;
@@ -227,8 +238,16 @@ _gdk_x11_precache_atoms (GdkDisplay          *display,
     }
 
   if (n_xatoms)
-    XInternAtoms (GDK_DISPLAY_XDISPLAY (display),
-                 (char **)xatom_names, n_xatoms, False, xatoms);
+    {
+#ifdef HAVE_XINTERNATOMS
+      XInternAtoms (GDK_DISPLAY_XDISPLAY (display),
+                   (char **)xatom_names, n_xatoms, False, xatoms);
+#else
+      for (i = 0; i < n_xatoms; i++)
+       xatoms[i] = XInternAtom (GDK_DISPLAY_XDISPLAY (display),
+                                xatom_names[i], False);
+#endif
+    }
 
   for (i = 0; i < n_xatoms; i++)
     insert_atom_pair (display, atoms[i], xatoms[i]);
@@ -279,7 +298,7 @@ gdk_x11_xatom_to_atom_for_display (GdkDisplay *display,
 
   display_x11 = GDK_DISPLAY_X11 (display);
   
-  if (xatom < G_N_ELEMENTS (XAtomsStrings) - N_CUSTOM_PREDEFINED)
+  if (xatom < G_N_ELEMENTS (xatoms_offset) - N_CUSTOM_PREDEFINED)
     return INDEX_TO_ATOM (xatom);
   
   if (display_x11->atom_to_virtual)
@@ -335,18 +354,18 @@ virtual_atom_check_init (void)
       virtual_atom_hash = g_hash_table_new (g_str_hash, g_str_equal);
       virtual_atom_array = g_ptr_array_new ();
       
-      for (i = 0; i < G_N_ELEMENTS (XAtomsStrings); i++)
+      for (i = 0; i < G_N_ELEMENTS (xatoms_offset); i++)
        {
-         g_ptr_array_add (virtual_atom_array, XAtomsStrings[i]);
-         g_hash_table_insert (virtual_atom_hash, XAtomsStrings[i],
+         g_ptr_array_add (virtual_atom_array, (gchar *)(xatoms_string + xatoms_offset[i]));
+         g_hash_table_insert (virtual_atom_hash, (gchar *)(xatoms_string + xatoms_offset[i]),
                               GUINT_TO_POINTER (i));
        }
     }
 }
 
-GdkAtom
-gdk_atom_intern (const gchar *atom_name, 
-                gboolean     only_if_exists)
+static GdkAtom
+intern_atom (const gchar *atom_name, 
+            gboolean     dup)
 {
   GdkAtom result;
 
@@ -357,7 +376,7 @@ gdk_atom_intern (const gchar *atom_name,
     {
       result = INDEX_TO_ATOM (virtual_atom_array->len);
       
-      g_ptr_array_add (virtual_atom_array, g_strdup (atom_name));
+      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)),
@@ -367,6 +386,38 @@ gdk_atom_intern (const gchar *atom_name,
   return result;
 }
 
+GdkAtom
+gdk_atom_intern (const gchar *atom_name, 
+                gboolean     only_if_exists)
+{
+  return intern_atom (atom_name, TRUE);
+}
+
+/**
+ * gdk_atom_intern_static_string:
+ * @atom_name: a static string
+ *
+ * Finds or creates an atom corresponding to a given string.
+ *
+ * Note that this function is identical to gdk_atom_intern() except
+ * that if a new #GdkAtom is created the string itself is used rather 
+ * than a copy. This saves memory, but can only be used if the string 
+ * will <emphasis>always</emphasis> exist. It can be used with statically
+ * allocated strings in the main program, but not with statically 
+ * allocated memory in dynamically loaded modules, if you expect to
+ * ever unload the module again (e.g. do not use this function in
+ * GTK+ theme engines).
+ *
+ * Returns: the atom corresponding to @atom_name
+ * 
+ * Since: 2.10
+ */
+GdkAtom
+gdk_atom_intern_static_string (const gchar *atom_name)
+{
+  return intern_atom (atom_name, FALSE);
+}
+
 static G_CONST_RETURN char *
 get_atom_name (GdkAtom atom)
 {
@@ -412,8 +463,7 @@ gdk_x11_get_xatom_by_name_for_display (GdkDisplay  *display,
  * 
  * Returns the X atom for GDK's default display corresponding to @atom_name.
  * This function caches the result, so if called repeatedly it is much
- * faster than <function>XInternAtom()</function>, which is a round trip to 
- * the server each time.
+ * faster than XInternAtom(), which is a round trip to the server each time.
  * 
  * Return value: a X atom for GDK's default display.
  **/
@@ -484,6 +534,7 @@ gdk_property_get (GdkWindow   *window,
   gint ret_format;
   gulong ret_nitems;
   gulong ret_bytes_after;
+  gulong get_length;
   gulong ret_length;
   guchar *ret_data;
   Atom xproperty;
@@ -505,13 +556,34 @@ gdk_property_get (GdkWindow   *window,
 
   display = gdk_drawable_get_display (window);
   xproperty = gdk_x11_atom_to_xatom_for_display (display, property);
-  xtype = gdk_x11_atom_to_xatom_for_display (display, type);
+  if (type == GDK_NONE)
+    xtype = AnyPropertyType;
+  else
+    xtype = gdk_x11_atom_to_xatom_for_display (display, type);
 
   ret_data = NULL;
   
+  /* 
+   * Round up length to next 4 byte value.  Some code is in the (bad?)
+   * habit of passing G_MAXLONG as the length argument, causing an
+   * overflow to negative on the add.  In this case, we clamp the
+   * value to G_MAXLONG.
+   */
+  get_length = length + 3;
+  if (get_length > G_MAXLONG)
+    get_length = G_MAXLONG;
+
+  /* To fail, either the user passed 0 or G_MAXULONG */
+  get_length = get_length / 4;
+  if (get_length == 0)
+    {
+      g_warning ("gdk_propery-get(): invalid length 0");
+      return FALSE;
+    }
+
   res = XGetWindowProperty (GDK_DISPLAY_XDISPLAY (display),
                            GDK_WINDOW_XWINDOW (window), xproperty,
-                           offset, (length + 3) / 4, pdelete,
+                           offset, get_length, pdelete,
                            xtype, &ret_prop_type, &ret_format,
                            &ret_nitems, &ret_bytes_after,
                            &ret_data);
@@ -612,7 +684,7 @@ gdk_property_change (GdkWindow    *window,
       screen = gdk_screen_get_default ();
       window = gdk_screen_get_root_window (screen);
       
-      GDK_NOTE (MULTIHEAD, g_message ("gdk_property_delete(): window is NULL\n"));
+      GDK_NOTE (MULTIHEAD, g_message ("gdk_property_change(): window is NULL\n"));
     }
 
 
@@ -672,3 +744,6 @@ gdk_property_delete (GdkWindow *window,
                   gdk_x11_atom_to_xatom_for_display (GDK_WINDOW_DISPLAY (window),
                                                      property));
 }
+
+#define __GDK_PROPERTY_X11_C__
+#include "gdkaliasdef.c"