remove `declare' macro
[bpt/emacs.git] / src / xfont.c
index 1a0e0f7..f90904a 100644 (file)
@@ -1,5 +1,5 @@
 /* xfont.c -- X core font driver.
 /* xfont.c -- X core font driver.
-   Copyright (C) 2006-2013 Free Software Foundation, Inc.
+   Copyright (C) 2006-2014 Free Software Foundation, Inc.
    Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011
      National Institute of Advanced Industrial Science and Technology (AIST)
      Registration Number H13PRO009
    Copyright (C) 2006, 2007, 2008, 2009, 2010, 2011
      National Institute of Advanced Industrial Science and Technology (AIST)
      Registration Number H13PRO009
@@ -42,6 +42,7 @@ struct xfont_info
   struct font font;
   Display *display;
   XFontStruct *xfont;
   struct font font;
   Display *display;
   XFontStruct *xfont;
+  unsigned x_display_id;
 };
 
 /* Prototypes of support functions.  */
 };
 
 /* Prototypes of support functions.  */
@@ -114,19 +115,19 @@ xfont_get_pcm (XFontStruct *xfont, XChar2b *char2b)
          ? NULL : pcm);
 }
 
          ? NULL : pcm);
 }
 
-static Lisp_Object xfont_get_cache (FRAME_PTR);
+static Lisp_Object xfont_get_cache (struct frame *);
 static Lisp_Object xfont_list (struct frame *, Lisp_Object);
 static Lisp_Object xfont_match (struct frame *, Lisp_Object);
 static Lisp_Object xfont_list_family (struct frame *);
 static Lisp_Object xfont_list (struct frame *, Lisp_Object);
 static Lisp_Object xfont_match (struct frame *, Lisp_Object);
 static Lisp_Object xfont_list_family (struct frame *);
-static Lisp_Object xfont_open (FRAME_PTR, Lisp_Object, int);
-static void xfont_close (FRAME_PTR, struct font *);
-static int xfont_prepare_face (FRAME_PTR, struct face *);
+static Lisp_Object xfont_open (struct frame *, Lisp_Object, int);
+static void xfont_close (struct font *);
+static void xfont_prepare_face (struct frame *, struct face *);
 static int xfont_has_char (Lisp_Object, int);
 static unsigned xfont_encode_char (struct font *, int);
 static int xfont_text_extents (struct font *, unsigned *, int,
                                struct font_metrics *);
 static int xfont_draw (struct glyph_string *, int, int, int, int, bool);
 static int xfont_has_char (Lisp_Object, int);
 static unsigned xfont_encode_char (struct font *, int);
 static int xfont_text_extents (struct font *, unsigned *, int,
                                struct font_metrics *);
 static int xfont_draw (struct glyph_string *, int, int, int, int, bool);
-static int xfont_check (FRAME_PTR, struct font *);
+static int xfont_check (struct frame *, struct font *);
 
 struct font_driver xfont_driver =
   {
 
 struct font_driver xfont_driver =
   {
@@ -152,9 +153,9 @@ struct font_driver xfont_driver =
   };
 
 static Lisp_Object
   };
 
 static Lisp_Object
-xfont_get_cache (FRAME_PTR f)
+xfont_get_cache (struct frame *f)
 {
 {
-  Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+  Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
 
   return (dpyinfo->name_list_element);
 }
 
   return (dpyinfo->name_list_element);
 }
@@ -488,7 +489,7 @@ xfont_list_pattern (Display *display, const char *pattern,
 static Lisp_Object
 xfont_list (struct frame *f, Lisp_Object spec)
 {
 static Lisp_Object
 xfont_list (struct frame *f, Lisp_Object spec)
 {
-  Display *display = FRAME_X_DISPLAY_INFO (f)->display;
+  Display *display = FRAME_DISPLAY_INFO (f)->display;
   Lisp_Object registry, list, val, extra, script;
   int len;
   /* Large enough to contain the longest XLFD (255 bytes) in UTF-8.  */
   Lisp_Object registry, list, val, extra, script;
   int len;
   /* Large enough to contain the longest XLFD (255 bytes) in UTF-8.  */
@@ -566,7 +567,7 @@ xfont_list (struct frame *f, Lisp_Object spec)
 static Lisp_Object
 xfont_match (struct frame *f, Lisp_Object spec)
 {
 static Lisp_Object
 xfont_match (struct frame *f, Lisp_Object spec)
 {
-  Display *display = FRAME_X_DISPLAY_INFO (f)->display;
+  Display *display = FRAME_DISPLAY_INFO (f)->display;
   Lisp_Object extra, val, entity;
   char name[512];
   XFontStruct *xfont;
   Lisp_Object extra, val, entity;
   char name[512];
   XFontStruct *xfont;
@@ -593,9 +594,7 @@ xfont_match (struct frame *f, Lisp_Object spec)
     {
       if (XGetFontProperty (xfont, XA_FONT, &value))
        {
     {
       if (XGetFontProperty (xfont, XA_FONT, &value))
        {
-         char *s;
-
-         s = (char *) XGetAtomName (display, (Atom) value);
+         char *s = XGetAtomName (display, (Atom) value);
 
          /* If DXPC (a Differential X Protocol Compressor)
             Ver.3.7 is running, XGetAtomName will return null
 
          /* If DXPC (a Differential X Protocol Compressor)
             Ver.3.7 is running, XGetAtomName will return null
@@ -622,7 +621,7 @@ xfont_match (struct frame *f, Lisp_Object spec)
 static Lisp_Object
 xfont_list_family (struct frame *f)
 {
 static Lisp_Object
 xfont_list_family (struct frame *f)
 {
-  Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+  Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
   char **names;
   int num_fonts, i;
   Lisp_Object list;
   char **names;
   int num_fonts, i;
   Lisp_Object list;
@@ -676,9 +675,9 @@ xfont_list_family (struct frame *f)
 }
 
 static Lisp_Object
 }
 
 static Lisp_Object
-xfont_open (FRAME_PTR f, Lisp_Object entity, int pixel_size)
+xfont_open (struct frame *f, Lisp_Object entity, int pixel_size)
 {
 {
-  Display_Info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+  Display_Info *dpyinfo = FRAME_DISPLAY_INFO (f);
   Display *display = dpyinfo->display;
   char name[512];
   int len;
   Display *display = dpyinfo->display;
   char name[512];
   int len;
@@ -760,7 +759,7 @@ xfont_open (FRAME_PTR f, Lisp_Object entity, int pixel_size)
       char *p0, *p;
       int dashes = 0;
 
       char *p0, *p;
       int dashes = 0;
 
-      p0 = p = (char *) XGetAtomName (FRAME_X_DISPLAY (f), (Atom) value);
+      p0 = p = XGetAtomName (FRAME_X_DISPLAY (f), (Atom) value);
       /* Count the number of dashes in the "full name".
         If it is too few, this isn't really the font's full name,
         so don't use it.
       /* Count the number of dashes in the "full name".
         If it is too few, this isn't really the font's full name,
         so don't use it.
@@ -810,6 +809,7 @@ xfont_open (FRAME_PTR f, Lisp_Object entity, int pixel_size)
   font = XFONT_OBJECT (font_object);
   ((struct xfont_info *) font)->xfont = xfont;
   ((struct xfont_info *) font)->display = FRAME_X_DISPLAY (f);
   font = XFONT_OBJECT (font_object);
   ((struct xfont_info *) font)->xfont = xfont;
   ((struct xfont_info *) font)->display = FRAME_X_DISPLAY (f);
+  ((struct xfont_info *) font)->x_display_id = FRAME_DISPLAY_INFO (f)->x_id;
   font->pixel_size = pixel_size;
   font->driver = &xfont_driver;
   font->encoding_charset = encoding->id;
   font->pixel_size = pixel_size;
   font->driver = &xfont_driver;
   font->encoding_charset = encoding->id;
@@ -892,22 +892,37 @@ xfont_open (FRAME_PTR f, Lisp_Object entity, int pixel_size)
 }
 
 static void
 }
 
 static void
-xfont_close (FRAME_PTR f, struct font *font)
+xfont_close (struct font *font)
 {
 {
-  block_input ();
-  XFreeFont (FRAME_X_DISPLAY (f), ((struct xfont_info *) font)->xfont);
-  unblock_input ();
+  struct x_display_info *xdi;
+  struct xfont_info *xfi = (struct xfont_info *) font;
+
+  /* This function may be called from GC when X connection is gone
+     (Bug#16093), and an attempt to free font resources on invalid
+     display may lead to X protocol errors or segfaults.  Moreover,
+     the memory referenced by 'Display *' pointer may be reused for
+     the logically different X connection after the previous display
+     connection was closed.  That's why we also check whether font's
+     ID matches the one recorded in x_display_info for this display.
+     See http://debbugs.gnu.org/cgi/bugreport.cgi?bug=16069.  */
+  if (xfi->xfont
+      && ((xdi = x_display_info_for_display (xfi->display))
+         && xfi->x_display_id == xdi->x_id))
+    {
+      block_input ();
+      XFreeFont (xfi->display, xfi->xfont);
+      unblock_input ();
+      xfi->xfont = NULL;
+    }
 }
 
 }
 
-static int
-xfont_prepare_face (FRAME_PTR f, struct face *face)
+static void
+xfont_prepare_face (struct frame *f, struct face *face)
 {
   block_input ();
   XSetFont (FRAME_X_DISPLAY (f), face->gc,
            ((struct xfont_info *) face->font)->xfont->fid);
   unblock_input ();
 {
   block_input ();
   XSetFont (FRAME_X_DISPLAY (f), face->gc,
            ((struct xfont_info *) face->font)->xfont->fid);
   unblock_input ();
-
-  return 0;
 }
 
 static int
 }
 
 static int
@@ -1089,7 +1104,7 @@ xfont_draw (struct glyph_string *s, int from, int to, int x, int y,
 }
 
 static int
 }
 
 static int
-xfont_check (FRAME_PTR f, struct font *font)
+xfont_check (struct frame *f, struct font *font)
 {
   struct xfont_info *xfont = (struct xfont_info *) font;
 
 {
   struct xfont_info *xfont = (struct xfont_info *) font;