Blame gdk/x11/gdkxftdefaults.c

Packit 98cdb6
/* GDK - The GIMP Drawing Kit
Packit 98cdb6
 * Copyright © 2005 Red Hat, Inc
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
 * Based on code from xftdpy.c
Packit 98cdb6
 *
Packit 98cdb6
 * Copyright © 2000 Keith Packard
Packit 98cdb6
 *
Packit 98cdb6
 * Permission to use, copy, modify, distribute, and sell this software and its
Packit 98cdb6
 * documentation for any purpose is hereby granted without fee, provided that
Packit 98cdb6
 * the above copyright notice appear in all copies and that both that
Packit 98cdb6
 * copyright notice and this permission notice appear in supporting
Packit 98cdb6
 * documentation, and that the name of Keith Packard not be used in
Packit 98cdb6
 * advertising or publicity pertaining to distribution of the software without
Packit 98cdb6
 * specific, written prior permission.  Keith Packard makes no
Packit 98cdb6
 * representations about the suitability of this software for any purpose.  It
Packit 98cdb6
 * is provided "as is" without express or implied warranty.
Packit 98cdb6
 *
Packit 98cdb6
 * KEITH PACKARD DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
Packit 98cdb6
 * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
Packit 98cdb6
 * EVENT SHALL KEITH PACKARD BE LIABLE FOR ANY SPECIAL, INDIRECT OR
Packit 98cdb6
 * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
Packit 98cdb6
 * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
Packit 98cdb6
 * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
Packit 98cdb6
 * PERFORMANCE OF THIS SOFTWARE.
Packit 98cdb6
 */
Packit 98cdb6
#include <stdlib.h>
Packit 98cdb6
#include <string.h>
Packit 98cdb6
Packit 98cdb6
#include <fontconfig/fontconfig.h>
Packit 98cdb6
Packit 98cdb6
#ifndef FC_HINT_STYLE
Packit 98cdb6
#define FC_HINT_NONE        0
Packit 98cdb6
#define FC_HINT_SLIGHT      1
Packit 98cdb6
#define FC_HINT_MEDIUM      2
Packit 98cdb6
#define FC_HINT_FULL        3
Packit 98cdb6
#endif
Packit 98cdb6
Packit 98cdb6
#include <gdkscreen-x11.h>
Packit 98cdb6
#include <gdkx.h>
Packit 98cdb6
Packit 98cdb6
static gint
Packit 98cdb6
parse_boolean (char *v)
Packit 98cdb6
{
Packit 98cdb6
  gchar c0, c1;
Packit 98cdb6
  
Packit 98cdb6
  c0 = *v;
Packit 98cdb6
  if (g_ascii_isupper ((int)c0))
Packit 98cdb6
    c0 = g_ascii_tolower (c0);
Packit 98cdb6
  if (c0 == 't' || c0 == 'y' || c0 == '1')
Packit 98cdb6
    return 1;
Packit 98cdb6
  if (c0 == 'f' || c0 == 'n' || c0 == '0')
Packit 98cdb6
    return 0;
Packit 98cdb6
  if (c0 == 'o')
Packit 98cdb6
    {
Packit 98cdb6
      c1 = v[1];
Packit 98cdb6
      if (g_ascii_isupper ((int)c1))
Packit 98cdb6
	c1 = g_ascii_tolower (c1);
Packit 98cdb6
      if (c1 == 'n')
Packit 98cdb6
	return 1;
Packit 98cdb6
      if (c1 == 'f')
Packit 98cdb6
	return 0;
Packit 98cdb6
    }
Packit 98cdb6
  
Packit 98cdb6
  return -1;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static gboolean
Packit 98cdb6
get_boolean_default (Display *dpy,
Packit 98cdb6
		     gchar   *option,
Packit 98cdb6
		     gboolean *value)
Packit 98cdb6
{
Packit 98cdb6
  gchar *v;
Packit 98cdb6
  gint i;
Packit 98cdb6
  
Packit 98cdb6
  v = XGetDefault (dpy, "Xft", option);
Packit 98cdb6
  if (v)
Packit 98cdb6
    {
Packit 98cdb6
      i = parse_boolean (v);
Packit 98cdb6
      if (i >= 0)
Packit 98cdb6
	{
Packit 98cdb6
	  *value = i;
Packit 98cdb6
	  return TRUE;
Packit 98cdb6
	}
Packit 98cdb6
    }
Packit 98cdb6
  
Packit 98cdb6
  return FALSE;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static gboolean
Packit 98cdb6
get_double_default (Display *dpy,
Packit 98cdb6
		    gchar   *option,
Packit 98cdb6
		    gdouble *value)
Packit 98cdb6
{
Packit 98cdb6
  gchar    *v, *e;
Packit 98cdb6
  
Packit 98cdb6
  v = XGetDefault (dpy, "Xft", option);
Packit 98cdb6
  if (v)
Packit 98cdb6
    {
Packit 98cdb6
      /* Xft uses strtod, though localization probably wasn't
Packit 98cdb6
       * desired. For compatibility, we use the conservative
Packit 98cdb6
       * g_strtod() that accepts either localized or non-localized
Packit 98cdb6
       * decimal separator.
Packit 98cdb6
       */
Packit 98cdb6
      *value = g_strtod (v, &e);
Packit 98cdb6
      if (e != v)
Packit 98cdb6
	return TRUE;
Packit 98cdb6
    }
Packit 98cdb6
  
Packit 98cdb6
  return FALSE;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static gboolean
Packit 98cdb6
get_integer_default (Display *dpy,
Packit 98cdb6
		     gchar   *option,
Packit 98cdb6
		     gint    *value)
Packit 98cdb6
{
Packit 98cdb6
  gchar *v, *e;
Packit 98cdb6
  
Packit 98cdb6
  v = XGetDefault (dpy, "Xft", option);
Packit 98cdb6
  if (v)
Packit 98cdb6
    {
Packit 98cdb6
      if (FcNameConstant ((FcChar8 *) v, value))
Packit 98cdb6
	return TRUE;
Packit 98cdb6
      
Packit 98cdb6
      *value = strtol (v, &e, 0);
Packit 98cdb6
      if (e != v)
Packit 98cdb6
	return TRUE;
Packit 98cdb6
    }
Packit 98cdb6
  
Packit 98cdb6
  return FALSE;
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
static void
Packit 98cdb6
init_xft_settings (GdkScreen *screen)
Packit 98cdb6
{
Packit 98cdb6
  GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
Packit 98cdb6
  Display *xdisplay = GDK_SCREEN_XDISPLAY (screen);
Packit 98cdb6
  int xscreen = GDK_SCREEN_XNUMBER (screen);
Packit 98cdb6
  double dpi_double;
Packit 98cdb6
Packit 98cdb6
  if (screen_x11->xft_init)
Packit 98cdb6
    return;
Packit 98cdb6
Packit 98cdb6
  screen_x11->xft_init = TRUE;
Packit 98cdb6
Packit 98cdb6
  if (!get_boolean_default (xdisplay, "antialias", &screen_x11->xft_antialias))
Packit 98cdb6
    screen_x11->xft_antialias = TRUE;
Packit 98cdb6
Packit 98cdb6
  if (!get_boolean_default (xdisplay, "hinting", &screen_x11->xft_hinting))
Packit 98cdb6
    screen_x11->xft_hinting = TRUE;
Packit 98cdb6
Packit 98cdb6
  if (!get_integer_default (xdisplay, "hintstyle", &screen_x11->xft_hintstyle))
Packit 98cdb6
    screen_x11->xft_hintstyle = FC_HINT_FULL;
Packit 98cdb6
Packit 98cdb6
  if (!get_integer_default (xdisplay, "rgba", &screen_x11->xft_rgba))
Packit 98cdb6
			    
Packit 98cdb6
    {
Packit 98cdb6
      int subpixel = FC_RGBA_UNKNOWN;
Packit 98cdb6
      
Packit 98cdb6
#if RENDER_MAJOR > 0 || RENDER_MINOR >= 6
Packit 98cdb6
      if (_gdk_x11_have_render (screen_x11->display))
Packit 98cdb6
	{
Packit 98cdb6
	  int render_order = XRenderQuerySubpixelOrder (xdisplay, xscreen);
Packit 98cdb6
	  
Packit 98cdb6
	  switch (render_order)
Packit 98cdb6
	    {
Packit 98cdb6
	    default:
Packit 98cdb6
	    case SubPixelUnknown:
Packit 98cdb6
	      subpixel = FC_RGBA_UNKNOWN;
Packit 98cdb6
	      break;
Packit 98cdb6
	    case SubPixelHorizontalRGB:
Packit 98cdb6
	      subpixel = FC_RGBA_RGB;
Packit 98cdb6
	      break;
Packit 98cdb6
	    case SubPixelHorizontalBGR:
Packit 98cdb6
	      subpixel = FC_RGBA_BGR;
Packit 98cdb6
	      break;
Packit 98cdb6
	    case SubPixelVerticalRGB:
Packit 98cdb6
	      subpixel = FC_RGBA_VRGB;
Packit 98cdb6
	      break;
Packit 98cdb6
	    case SubPixelVerticalBGR:
Packit 98cdb6
	      subpixel = FC_RGBA_VBGR;
Packit 98cdb6
	      break;
Packit 98cdb6
	    case SubPixelNone:
Packit 98cdb6
	      subpixel = FC_RGBA_NONE;
Packit 98cdb6
	      break;
Packit 98cdb6
	    }
Packit 98cdb6
	}
Packit 98cdb6
#endif
Packit 98cdb6
Packit 98cdb6
      screen_x11->xft_rgba = subpixel;
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  if (!get_double_default (xdisplay, "dpi", &dpi_double))
Packit 98cdb6
    dpi_double = (((double) DisplayHeight (xdisplay, xscreen) * 25.4) / 
Packit 98cdb6
		  (double) DisplayHeightMM (xdisplay, xscreen));
Packit 98cdb6
Packit 98cdb6
  screen_x11->xft_dpi = (int)(0.5 + PANGO_SCALE * dpi_double);
Packit 98cdb6
}
Packit 98cdb6
Packit 98cdb6
gboolean
Packit 98cdb6
_gdk_x11_get_xft_setting (GdkScreen   *screen,
Packit 98cdb6
			  const gchar *name,
Packit 98cdb6
			  GValue      *value)
Packit 98cdb6
{
Packit 98cdb6
  GdkScreenX11 *screen_x11 = GDK_SCREEN_X11 (screen);
Packit 98cdb6
  
Packit 98cdb6
  if (strncmp (name, "gtk-xft-", 8) != 0)
Packit 98cdb6
    return FALSE;
Packit 98cdb6
Packit 98cdb6
  name += 8;
Packit 98cdb6
Packit 98cdb6
  init_xft_settings (screen);
Packit 98cdb6
Packit 98cdb6
  if (strcmp (name, "antialias") == 0)
Packit 98cdb6
    {
Packit 98cdb6
      g_value_set_int (value, screen_x11->xft_antialias);
Packit 98cdb6
      return TRUE;
Packit 98cdb6
    }
Packit 98cdb6
  else if (strcmp (name, "hinting") == 0)
Packit 98cdb6
    {
Packit 98cdb6
      g_value_set_int (value, screen_x11->xft_hinting);
Packit 98cdb6
      return TRUE;
Packit 98cdb6
    }
Packit 98cdb6
  else if (strcmp (name, "hintstyle") == 0)
Packit 98cdb6
    {
Packit 98cdb6
      const char *str;
Packit 98cdb6
      
Packit 98cdb6
      switch (screen_x11->xft_hintstyle)
Packit 98cdb6
	{
Packit 98cdb6
	case FC_HINT_NONE:
Packit 98cdb6
	  str = "hintnone";
Packit 98cdb6
	  break;
Packit 98cdb6
	case FC_HINT_SLIGHT:
Packit 98cdb6
	  str = "hintslight";
Packit 98cdb6
	  break;
Packit 98cdb6
	case FC_HINT_MEDIUM:
Packit 98cdb6
	  str = "hintmedium";
Packit 98cdb6
	  break;
Packit 98cdb6
	case FC_HINT_FULL:
Packit 98cdb6
	  str = "hintfull";
Packit 98cdb6
	  break;
Packit 98cdb6
	default:
Packit 98cdb6
	  return FALSE;
Packit 98cdb6
	}
Packit 98cdb6
Packit 98cdb6
      g_value_set_string (value, str);
Packit 98cdb6
      return TRUE;
Packit 98cdb6
    }
Packit 98cdb6
  else if (strcmp (name, "rgba") == 0)
Packit 98cdb6
    {
Packit 98cdb6
      const char *str;
Packit 98cdb6
      
Packit 98cdb6
      switch (screen_x11->xft_rgba)
Packit 98cdb6
	{
Packit 98cdb6
	case FC_RGBA_NONE:
Packit 98cdb6
	  str = "none";
Packit 98cdb6
	  break;
Packit 98cdb6
	case FC_RGBA_RGB:
Packit 98cdb6
	  str = "rgb";
Packit 98cdb6
	  break;
Packit 98cdb6
	case FC_RGBA_BGR:
Packit 98cdb6
	  str = "bgr";
Packit 98cdb6
	  break;
Packit 98cdb6
	case FC_RGBA_VRGB:
Packit 98cdb6
	  str = "vrgb";
Packit 98cdb6
	  break;
Packit 98cdb6
	case FC_RGBA_VBGR:
Packit 98cdb6
	  str = "vbgr";
Packit 98cdb6
	  break;
Packit 98cdb6
	case FC_RGBA_UNKNOWN:
Packit 98cdb6
	default:
Packit 98cdb6
	  return FALSE;
Packit 98cdb6
	}
Packit 98cdb6
	
Packit 98cdb6
      g_value_set_string (value, str);
Packit 98cdb6
      return TRUE; 
Packit 98cdb6
   }
Packit 98cdb6
  else if (strcmp (name, "dpi") == 0)
Packit 98cdb6
    {
Packit 98cdb6
      g_value_set_int (value, screen_x11->xft_dpi);
Packit 98cdb6
      return TRUE;
Packit 98cdb6
    }
Packit 98cdb6
Packit 98cdb6
  return FALSE;
Packit 98cdb6
}