 b664be5ffb
			
		
	
	b664be5ffb
	
	
	
		
			
			2000-11-13 Sebastian Wilhelmi <wilhelmi@ira.uka.de> * gdk/linux-fb/gdkcolor-fb.c, gdk/nanox/gdkmain-nanox.c, gdk/win32/gdkcolor-win32.c, gdk/win32/gdkwin32id.c, gdk/x11/gdkcolor-x11.c, gdk/x11/gdkvisual-x11.c, gdk/x11/gdkxid.c, gtk/gtkgc.c, gtk/gtkrc.c, gtk/gtktext.c: GCompareFunc -> GEqualFunc where applicable. * gdk/linux-fb/gdkpango-fb.c: pango_font_description_compare -> pango_font_description_equal as changed in pango. * gdk/nanox/gdkmain-nanox.c: gdk_xid_compare -> gdk_xid_equal. * gdk/win32/gdkcolor-win32.c: gdk_colormap_cmp -> gdk_colormap_equal. * gdk/win32/gdkwin32id.c: gdk_handle_compare -> gdk_handle_equal. * gdk/x11/gdkcolor-x11.c: gdk_colormap_cmp -> gdk_colormap_equal. * gdk/x11/gdkvisual-x11.c: gdk_visual_compare -> gdk_visual_equal. * gdk/x11/gdkxid.c: gdk_xid_compare -> gdk_xid_equal. * gtk/gtkgc.c: gtk_gc_key_compare -> gtk_gc_key_equal and gtk_gc_drawable_compare -> gtk_gc_drawable_equal. * gtk/gtkrc.c: gtk_rc_style_compare -> gtk_rc_style_equal and gtk_rc_styles_compare -> gtk_rc_styles_equal.
		
			
				
	
	
		
			454 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			454 lines
		
	
	
		
			10 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* GDK - The GIMP Drawing Kit
 | |
|  * Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
 | |
|  *
 | |
|  * This library is free software; you can redistribute it and/or
 | |
|  * modify it under the terms of the GNU Lesser General Public
 | |
|  * License as published by the Free Software Foundation; either
 | |
|  * version 2 of the License, or (at your option) any later version.
 | |
|  *
 | |
|  * This library is distributed in the hope that it will be useful,
 | |
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | |
|  * Lesser General Public License for more details.
 | |
|  *
 | |
|  * You should have received a copy of the GNU Lesser General Public
 | |
|  * License along with this library; if not, write to the
 | |
|  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
 | |
|  * Boston, MA 02111-1307, USA.
 | |
|  */
 | |
| 
 | |
| /*
 | |
|  * Modified by the GTK+ Team and others 1997-2000.  See the AUTHORS
 | |
|  * file for a list of people on the GTK+ Team.  See the ChangeLog
 | |
|  * files for a list of changes.  These files are distributed with
 | |
|  * GTK+ at ftp://ftp.gtk.org/pub/gtk/. 
 | |
|  */
 | |
| 
 | |
| #include <X11/Xlib.h>
 | |
| #include <X11/Xutil.h>
 | |
| 
 | |
| #include "gdkvisual.h"
 | |
| #include "gdkprivate-x11.h"
 | |
| #include "gdkinternals.h"
 | |
| 
 | |
| static void     gdk_visual_add            (GdkVisual *visual);
 | |
| static void     gdk_visual_decompose_mask (gulong     mask,
 | |
| 					   gint      *shift,
 | |
| 					   gint      *prec);
 | |
| static guint    gdk_visual_hash           (Visual    *key);
 | |
| 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 gray",
 | |
|   "grayscale",
 | |
|   "static color",
 | |
|   "pseudo color",
 | |
|   "true color",
 | |
|   "direct color",
 | |
| };
 | |
| 
 | |
| #endif /* G_ENABLE_DEBUG */
 | |
| 
 | |
| static GHashTable *visual_hash = NULL;
 | |
| 
 | |
| void
 | |
| gdk_visual_init (void)
 | |
| {
 | |
|   static const gint possible_depths[7] = { 32, 24, 16, 15, 8, 4, 1 };
 | |
|   static const GdkVisualType possible_types[6] =
 | |
|     {
 | |
|       GDK_VISUAL_DIRECT_COLOR,
 | |
|       GDK_VISUAL_TRUE_COLOR,
 | |
|       GDK_VISUAL_PSEUDO_COLOR,
 | |
|       GDK_VISUAL_STATIC_COLOR,
 | |
|       GDK_VISUAL_GRAYSCALE,
 | |
|       GDK_VISUAL_STATIC_GRAY
 | |
|     };
 | |
| 
 | |
|   static const gint npossible_depths = sizeof(possible_depths)/sizeof(gint);
 | |
|   static const gint npossible_types = sizeof(possible_types)/sizeof(GdkVisualType);
 | |
| 
 | |
|   XVisualInfo *visual_list;
 | |
|   XVisualInfo visual_template;
 | |
|   GdkVisualPrivate temp_visual;
 | |
|   Visual *default_xvisual;
 | |
|   int nxvisuals;
 | |
|   int i, j;
 | |
| 
 | |
|   visual_template.screen = gdk_screen;
 | |
|   visual_list = XGetVisualInfo (gdk_display, VisualScreenMask, &visual_template, &nxvisuals);
 | |
|   visuals = g_new (GdkVisualPrivate, nxvisuals);
 | |
| 
 | |
|   default_xvisual = DefaultVisual (gdk_display, gdk_screen);
 | |
| 
 | |
|   nvisuals = 0;
 | |
|   for (i = 0; i < nxvisuals; i++)
 | |
|     {
 | |
|       if (visual_list[i].depth >= 1)
 | |
| 	{
 | |
| #ifdef __cplusplus
 | |
| 	  switch (visual_list[i].c_class)
 | |
| #else /* __cplusplus */
 | |
| 	  switch (visual_list[i].class)
 | |
| #endif /* __cplusplus */
 | |
| 	    {
 | |
| 	    case StaticGray:
 | |
| 	      visuals[nvisuals].visual.type = GDK_VISUAL_STATIC_GRAY;
 | |
| 	      break;
 | |
| 	    case GrayScale:
 | |
| 	      visuals[nvisuals].visual.type = GDK_VISUAL_GRAYSCALE;
 | |
| 	      break;
 | |
| 	    case StaticColor:
 | |
| 	      visuals[nvisuals].visual.type = GDK_VISUAL_STATIC_COLOR;
 | |
| 	      break;
 | |
| 	    case PseudoColor:
 | |
| 	      visuals[nvisuals].visual.type = GDK_VISUAL_PSEUDO_COLOR;
 | |
| 	      break;
 | |
| 	    case TrueColor:
 | |
| 	      visuals[nvisuals].visual.type = GDK_VISUAL_TRUE_COLOR;
 | |
| 	      break;
 | |
| 	    case DirectColor:
 | |
| 	      visuals[nvisuals].visual.type = GDK_VISUAL_DIRECT_COLOR;
 | |
| 	      break;
 | |
| 	    }
 | |
| 
 | |
| 	  visuals[nvisuals].visual.depth = visual_list[i].depth;
 | |
| 	  visuals[nvisuals].visual.byte_order =
 | |
| 	    (ImageByteOrder(gdk_display) == 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))
 | |
| 	    {
 | |
| 	      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].visual.green_mask,
 | |
| 					 &visuals[nvisuals].visual.green_shift,
 | |
| 					 &visuals[nvisuals].visual.green_prec);
 | |
| 
 | |
| 	      gdk_visual_decompose_mask (visuals[nvisuals].visual.blue_mask,
 | |
| 					 &visuals[nvisuals].visual.blue_shift,
 | |
| 					 &visuals[nvisuals].visual.blue_prec);
 | |
| 	    }
 | |
| 	  else
 | |
| 	    {
 | |
| 	      visuals[nvisuals].visual.red_mask = 0;
 | |
| 	      visuals[nvisuals].visual.red_shift = 0;
 | |
| 	      visuals[nvisuals].visual.red_prec = 0;
 | |
| 
 | |
| 	      visuals[nvisuals].visual.green_mask = 0;
 | |
| 	      visuals[nvisuals].visual.green_shift = 0;
 | |
| 	      visuals[nvisuals].visual.green_prec = 0;
 | |
| 
 | |
| 	      visuals[nvisuals].visual.blue_mask = 0;
 | |
| 	      visuals[nvisuals].visual.blue_shift = 0;
 | |
| 	      visuals[nvisuals].visual.blue_prec = 0;
 | |
| 	    }
 | |
| 
 | |
| 	  nvisuals += 1;
 | |
| 	}
 | |
|     }
 | |
| 
 | |
|   if (visual_list)
 | |
|     XFree (visual_list);
 | |
| 
 | |
|   for (i = 0; i < nvisuals; i++)
 | |
|     {
 | |
|       for (j = i+1; j < nvisuals; j++)
 | |
| 	{
 | |
| 	  if (visuals[j].visual.depth >= visuals[i].visual.depth)
 | |
| 	    {
 | |
| 	      if ((visuals[j].visual.depth == 8) && (visuals[i].visual.depth == 8))
 | |
| 		{
 | |
| 		  if (visuals[j].visual.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)
 | |
| 		    {
 | |
| 		      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)))
 | |
| 		{
 | |
| 		  temp_visual = visuals[j];
 | |
| 		  visuals[j] = visuals[i];
 | |
| 		  visuals[i] = temp_visual;
 | |
| 		}
 | |
| 	    }
 | |
| 	}
 | |
|     }
 | |
| 
 | |
|   for (i = 0; i < nvisuals; i++)
 | |
|     if (default_xvisual->visualid == visuals[i].xvisual->visualid)
 | |
|       {
 | |
| 	system_visual = &visuals[i];
 | |
| 	break;
 | |
|       }
 | |
| 
 | |
| #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);
 | |
| #endif /* G_ENABLE_DEBUG */
 | |
| 
 | |
|   navailable_depths = 0;
 | |
|   for (i = 0; i < npossible_depths; i++)
 | |
|     {
 | |
|       for (j = 0; j < nvisuals; j++)
 | |
| 	{
 | |
| 	  if (visuals[j].visual.depth == possible_depths[i])
 | |
| 	    {
 | |
| 	      available_depths[navailable_depths++] = visuals[j].visual.depth;
 | |
| 	      break;
 | |
| 	    }
 | |
| 	}
 | |
|     }
 | |
| 
 | |
|   if (navailable_depths == 0)
 | |
|     g_error ("unable to find a usable depth");
 | |
| 
 | |
|   navailable_types = 0;
 | |
|   for (i = 0; i < npossible_types; i++)
 | |
|     {
 | |
|       for (j = 0; j < nvisuals; j++)
 | |
| 	{
 | |
| 	  if (visuals[j].visual.type == possible_types[i])
 | |
| 	    {
 | |
| 	      available_types[navailable_types++] = visuals[j].visual.type;
 | |
| 	      break;
 | |
| 	    }
 | |
| 	}
 | |
|     }
 | |
| 
 | |
|   for (i = 0; i < nvisuals; i++)
 | |
|     gdk_visual_add ((GdkVisual*) &visuals[i]);
 | |
| 
 | |
|   if (npossible_types == 0)
 | |
|     g_error ("unable to find a usable visual type");
 | |
| }
 | |
| 
 | |
| GdkVisual*
 | |
| gdk_visual_ref (GdkVisual *visual)
 | |
| {
 | |
|   return visual;
 | |
| }
 | |
| 
 | |
| void
 | |
| gdk_visual_unref (GdkVisual *visual)
 | |
| {
 | |
|   return;
 | |
| }
 | |
| 
 | |
| gint
 | |
| gdk_visual_get_best_depth (void)
 | |
| {
 | |
|   return available_depths[0];
 | |
| }
 | |
| 
 | |
| GdkVisualType
 | |
| gdk_visual_get_best_type (void)
 | |
| {
 | |
|   return available_types[0];
 | |
| }
 | |
| 
 | |
| GdkVisual*
 | |
| gdk_visual_get_system (void)
 | |
| {
 | |
|   return ((GdkVisual*) system_visual);
 | |
| }
 | |
| 
 | |
| GdkVisual*
 | |
| gdk_visual_get_best (void)
 | |
| {
 | |
|   return ((GdkVisual*) &(visuals[0]));
 | |
| }
 | |
| 
 | |
| GdkVisual*
 | |
| gdk_visual_get_best_with_depth (gint depth)
 | |
| {
 | |
|   GdkVisual *return_val;
 | |
|   int i;
 | |
| 
 | |
|   return_val = NULL;
 | |
|   for (i = 0; i < nvisuals; i++)
 | |
|     if (depth == visuals[i].visual.depth)
 | |
|       {
 | |
| 	return_val = (GdkVisual*) &(visuals[i]);
 | |
| 	break;
 | |
|       }
 | |
| 
 | |
|   return return_val;
 | |
| }
 | |
| 
 | |
| GdkVisual*
 | |
| gdk_visual_get_best_with_type (GdkVisualType visual_type)
 | |
| {
 | |
|   GdkVisual *return_val;
 | |
|   int i;
 | |
| 
 | |
|   return_val = NULL;
 | |
|   for (i = 0; i < nvisuals; i++)
 | |
|     if (visual_type == visuals[i].visual.type)
 | |
|       {
 | |
| 	return_val = (GdkVisual*) &(visuals[i]);
 | |
| 	break;
 | |
|       }
 | |
| 
 | |
|   return return_val;
 | |
| }
 | |
| 
 | |
| GdkVisual*
 | |
| gdk_visual_get_best_with_both (gint          depth,
 | |
| 			       GdkVisualType visual_type)
 | |
| {
 | |
|   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))
 | |
|       {
 | |
| 	return_val = (GdkVisual*) &(visuals[i]);
 | |
| 	break;
 | |
|       }
 | |
| 
 | |
|   return return_val;
 | |
| }
 | |
| 
 | |
| void
 | |
| gdk_query_depths  (gint **depths,
 | |
| 		   gint  *count)
 | |
| {
 | |
|   *count = navailable_depths;
 | |
|   *depths = available_depths;
 | |
| }
 | |
| 
 | |
| void
 | |
| gdk_query_visual_types (GdkVisualType **visual_types,
 | |
| 			gint           *count)
 | |
| {
 | |
|   *count = navailable_types;
 | |
|   *visual_types = available_types;
 | |
| }
 | |
| 
 | |
| GList*
 | |
| gdk_list_visuals (void)
 | |
| {
 | |
|   GList *list;
 | |
|   guint i;
 | |
| 
 | |
|   list = NULL;
 | |
|   for (i = 0; i < nvisuals; ++i)
 | |
|     list = g_list_append (list, (gpointer) &visuals[i]);
 | |
| 
 | |
|   return list;
 | |
| }
 | |
| 
 | |
| 
 | |
| GdkVisual*
 | |
| gdk_visual_lookup (Visual *xvisual)
 | |
| {
 | |
|   GdkVisual *visual;
 | |
| 
 | |
|   if (!visual_hash)
 | |
|     return NULL;
 | |
| 
 | |
|   visual = g_hash_table_lookup (visual_hash, xvisual);
 | |
|   return visual;
 | |
| }
 | |
| 
 | |
| 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;
 | |
| }
 | |
| 
 | |
| 
 | |
| 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);
 | |
| 
 | |
|   private = (GdkVisualPrivate*) visual;
 | |
| 
 | |
|   g_hash_table_insert (visual_hash, private->xvisual, visual);
 | |
| }
 | |
| 
 | |
| static void
 | |
| gdk_visual_decompose_mask (gulong  mask,
 | |
| 			   gint   *shift,
 | |
| 			   gint   *prec)
 | |
| {
 | |
|   *shift = 0;
 | |
|   *prec = 0;
 | |
| 
 | |
|   while (!(mask & 0x1))
 | |
|     {
 | |
|       (*shift)++;
 | |
|       mask >>= 1;
 | |
|     }
 | |
| 
 | |
|   while (mask & 0x1)
 | |
|     {
 | |
|       (*prec)++;
 | |
|       mask >>= 1;
 | |
|     }
 | |
| }
 | |
| 
 | |
| static guint
 | |
| gdk_visual_hash (Visual *key)
 | |
| {
 | |
|   return key->visualid;
 | |
| }
 | |
| 
 | |
| static gboolean
 | |
| gdk_visual_equal (Visual *a,
 | |
| 		  Visual *b)
 | |
| {
 | |
|   return (a->visualid == b->visualid);
 | |
| }
 |