]> code.delx.au - gnu-emacs/blobdiff - src/frame.c
(enlarge_buffer_text): Fix int -> EMACS_INT.
[gnu-emacs] / src / frame.c
index 090de96cebd19463040db3dfbabede974a264fbb..b163be53f770482333ce8fd68683c313f69313f1 100644 (file)
@@ -1,6 +1,6 @@
 /* Generic frame functions.
    Copyright (C) 1993, 1994, 1995, 1997, 1999, 2000, 2001, 2002, 2003,
-                 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
+                 2004, 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
 
 This file is part of GNU Emacs.
 
@@ -23,7 +23,7 @@ Boston, MA 02110-1301, USA.  */
 
 #include <stdio.h>
 #include "lisp.h"
-#include "charset.h"
+#include "character.h"
 #ifdef HAVE_X_WINDOWS
 #include "xterm.h"
 #endif
@@ -54,6 +54,10 @@ Boston, MA 02110-1301, USA.  */
 
 #ifdef HAVE_WINDOW_SYSTEM
 
+#ifdef USE_FONT_BACKEND
+#include "font.h"
+#endif /* USE_FONT_BACKEND */
+
 /* The name we're using in resource queries.  Most often "emacs".  */
 
 Lisp_Object Vx_resource_name;
@@ -72,6 +76,7 @@ Lisp_Object Qx, Qw32, Qmac, Qpc;
 Lisp_Object Qvisible;
 Lisp_Object Qdisplay_type;
 Lisp_Object Qbackground_mode;
+Lisp_Object Qnoelisp;
 
 Lisp_Object Qx_frame_parameter;
 Lisp_Object Qx_resource_name;
@@ -110,9 +115,11 @@ Lisp_Object Qleft_fringe, Qright_fringe;
 Lisp_Object Qbuffer_predicate, Qbuffer_list, Qburied_buffer_list;
 Lisp_Object Qtty_color_mode;
 Lisp_Object Qtty, Qtty_type;
-Lisp_Object Qwindow_system;
 
 Lisp_Object Qfullscreen, Qfullwidth, Qfullheight, Qfullboth;
+#ifdef USE_FONT_BACKEND
+Lisp_Object Qfont_backend;
+#endif /* USE_FONT_BACKEND */
 
 Lisp_Object Qinhibit_face_set_after_frame_default;
 Lisp_Object Qface_set_after_frame_default;
@@ -261,7 +268,7 @@ FRAME defaults to the currently selected frame.  */)
     return Qnil;
   else
     return type;
-}      
+}
 
 struct frame *
 make_frame (mini_p)
@@ -327,6 +334,10 @@ make_frame (mini_p)
 #endif
   f->size_hint_flags = 0;
   f->win_gravity = 0;
+#ifdef USE_FONT_BACKEND
+  f->font_driver_list = NULL;
+  f->font_data_list = NULL;
+#endif /* USE_FONT_BACKEND */
 
   root_window = make_window ();
   if (mini_p)
@@ -514,16 +525,7 @@ make_initial_frame (void)
   struct terminal *terminal;
   Lisp_Object frame;
 
-#ifdef MULTI_KBOARD
-  /* Create the initial keyboard. */
-  if (!initial_kboard)
-    {
-      initial_kboard = (KBOARD *) xmalloc (sizeof (KBOARD));
-      init_kboard (initial_kboard);
-      initial_kboard->next_kboard = all_kboards;
-      all_kboards = initial_kboard;
-    }
-#endif
+  eassert (initial_kboard);
 
   /* The first call must initialize Vframe_list.  */
   if (! (NILP (Vframe_list) || CONSP (Vframe_list)))
@@ -546,10 +548,10 @@ make_initial_frame (void)
   f->terminal = terminal;
   f->terminal->reference_count++;
   f->output_data.nothing = 0;
-  
+
   FRAME_FOREGROUND_PIXEL (f) = FACE_TTY_DEFAULT_FG_COLOR;
   FRAME_BACKGROUND_PIXEL (f) = FACE_TTY_DEFAULT_BG_COLOR;
-    
+
   FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
   FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none;
 
@@ -602,19 +604,16 @@ make_terminal_frame (struct terminal *terminal)
     }
   else
     f->output_method = output_termcap;
-#else
-#ifdef MAC_OS8
-  make_mac_terminal_frame (f);
 #else
   {
     f->output_method = output_termcap;
     f->terminal = terminal;
     f->terminal->reference_count++;
     create_tty_output (f);
-    
+
     FRAME_FOREGROUND_PIXEL (f) = FACE_TTY_DEFAULT_FG_COLOR;
     FRAME_BACKGROUND_PIXEL (f) = FACE_TTY_DEFAULT_BG_COLOR;
-    
+
     FRAME_CAN_HAVE_SCROLL_BARS (f) = 0;
     FRAME_VERTICAL_SCROLL_BAR_TYPE (f) = vertical_scroll_bar_none;
 
@@ -622,15 +621,14 @@ make_terminal_frame (struct terminal *terminal)
     if (FRAMEP (FRAME_TTY (f)->top_frame)
         && FRAME_LIVE_P (XFRAME (FRAME_TTY (f)->top_frame)))
       XFRAME (FRAME_TTY (f)->top_frame)->async_visible = 2; /* obscured */
-    
+
     FRAME_TTY (f)->top_frame = frame;
   }
-  
+
 #ifdef CANNOT_DUMP
   FRAME_FOREGROUND_PIXEL(f) = FACE_TTY_DEFAULT_FG_COLOR;
   FRAME_BACKGROUND_PIXEL(f) = FACE_TTY_DEFAULT_BG_COLOR;
 #endif
-#endif /* MAC_OS8 */
 #endif /* MSDOS */
 
   if (!noninteractive)
@@ -697,7 +695,7 @@ affects all frames on the same terminal device.  */)
     abort ();
 #else /* not MSDOS */
 
-#if 0 /* #ifdef MAC_OS */
+#if 0
   /* This can happen for multi-tty when using both terminal frames and
      Carbon frames. */
   if (sf->output_method != output_mac)
@@ -709,7 +707,7 @@ affects all frames on the same terminal device.  */)
 #endif
 #endif
 #endif /* not MSDOS */
-  
+
   {
     Lisp_Object terminal;
 
@@ -720,9 +718,9 @@ affects all frames on the same terminal device.  */)
         t = get_terminal (terminal, 1);
       }
   }
-  
+
   if (!t)
-    { 
+    {
       char *name = 0, *type = 0;
       Lisp_Object tty, tty_type;
 
@@ -736,7 +734,7 @@ affects all frames on the same terminal device.  */)
           strncpy (name, SDATA (tty), SBYTES (tty));
           name[SBYTES (tty)] = 0;
         }
-      
+
       tty_type = get_future_frame_param
         (Qtty_type, parms, (FRAME_TERMCAP_P (XFRAME (selected_frame))
                             ? FRAME_TTY (XFRAME (selected_frame))->type
@@ -758,13 +756,12 @@ affects all frames on the same terminal device.  */)
     get_tty_size (fileno (FRAME_TTY (f)->input), &width, &height);
     change_frame_size (f, height, width, 0, 0, 0);
   }
-  
+
   adjust_glyphs (f);
   calculate_costs (f);
   XSETFRAME (frame, f);
   Fmodify_frame_parameters (frame, Vdefault_frame_alist);
   Fmodify_frame_parameters (frame, parms);
-  Fmodify_frame_parameters (frame, Fcons (Fcons (Qwindow_system, Qnil), Qnil));
   Fmodify_frame_parameters (frame, Fcons (Fcons (Qtty_type,
                                                  build_string (t->display_info.tty->type)),
                                           Qnil));
@@ -774,7 +771,7 @@ affects all frames on the same terminal device.  */)
                                             Qnil));
   else
     Fmodify_frame_parameters (frame, Fcons (Fcons (Qtty, Qnil), Qnil));
-  
+
   /* Make the frame face alist be frame-specific, so that each
      frame could change its face definitions independently.  */
   f->face_alist = Fcopy_alist (sf->face_alist);
@@ -1346,7 +1343,9 @@ but if the second optional argument FORCE is non-nil, you may do so.
 
 This function runs `delete-frame-functions' before actually deleting the
 frame, unless the frame is a tooltip.
-The functions are run with one arg, the frame to be deleted.  */)
+The functions are run with one arg, the frame to be deleted.
+But FORCE inhibits this too.  */)
+/* FORCE is non-nil when handling a disconnected terminal.  */
      (frame, force)
      Lisp_Object frame, force;
 {
@@ -1370,13 +1369,7 @@ The functions are run with one arg, the frame to be deleted.  */)
   if (! FRAME_LIVE_P (f))
     return Qnil;
 
-  if (NILP (force) && !other_visible_frames (f)
-#ifdef MAC_OS8
-      /* Terminal frame deleted before any other visible frames are
-        created.  */
-      && strcmp (SDATA (f->name), "F1") != 0
-#endif
-     )
+  if (NILP (force) && !other_visible_frames (f))
     error ("Attempt to delete the sole visible or iconified frame");
 
 #if 0
@@ -1403,12 +1396,21 @@ The functions are run with one arg, the frame to be deleted.  */)
              && EQ (frame,
                     WINDOW_FRAME (XWINDOW
                                   (FRAME_MINIBUF_WINDOW (XFRAME (this))))))
-           error ("Attempt to delete a surrogate minibuffer frame");
+           {
+             /* If we MUST delete this frame, delete the other first.  */
+             if (!NILP (force))
+               Fdelete_frame (this, force);
+             else
+               error ("Attempt to delete a surrogate minibuffer frame");
+           }
        }
     }
 
-  /* Run `delete-frame-functions' unless frame is a tooltip.  */
-  if (!NILP (Vrun_hooks)
+  /* Run `delete-frame-functions'
+     unless FORCE is `noelisp' or frame is a tooltip.
+     FORCE is set to `noelisp' when handling a disconnect from the terminal,
+     so we don't dare call Lisp code.  */
+  if (!NILP (Vrun_hooks) && !EQ (force, Qnoelisp)
       && NILP (Fframe_parameter (frame, intern ("tooltip"))))
     {
       Lisp_Object args[2];
@@ -1428,6 +1430,9 @@ The functions are run with one arg, the frame to be deleted.  */)
   if (! FRAME_LIVE_P (f))
     return Qnil;
 
+  /* At this point, we are committed to deleting the frame.
+     There is no more chance for errors to prevent it.  */
+
   minibuffer_selected = EQ (minibuf_window, selected_window);
 
   /* Don't let the frame remain selected.  */
@@ -1485,6 +1490,11 @@ The functions are run with one arg, the frame to be deleted.  */)
      memory. */
   free_glyphs (f);
 
+#ifdef USE_FONT_BACKEND
+  /* Give chance to each font driver to free a frame specific data.  */
+  font_update_drivers (f, Qnil);
+#endif /* USE_FONT_BACKEND */
+
   /* Mark all the windows that used to be on FRAME as deleted, and then
      remove the reference to them.  */
   delete_all_subwindows (XWINDOW (f->root_window));
@@ -1520,7 +1530,7 @@ The functions are run with one arg, the frame to be deleted.  */)
 
   {
     struct terminal *terminal = FRAME_TERMINAL (f);
-    f->output_data.nothing = 0; 
+    f->output_data.nothing = 0;
     f->terminal = 0;             /* Now the frame is dead. */
 
     /* If needed, delete the terminal that this frame was on.
@@ -1528,11 +1538,11 @@ The functions are run with one arg, the frame to be deleted.  */)
     terminal->reference_count--;
     if (terminal->reference_count == 0)
       {
+       Lisp_Object tmp;
+       XSETTERMINAL (tmp, terminal);
+
         kb = NULL;
-        if (terminal->delete_terminal_hook)
-          (*terminal->delete_terminal_hook) (terminal);
-        else
-          delete_terminal (terminal);
+       Fdelete_terminal (tmp, NILP (force) ? Qt : force);
       }
 #ifdef MULTI_KBOARD
     else
@@ -2027,7 +2037,7 @@ doesn't support multiple overlapping frames, this function does nothing.  */)
   CHECK_LIVE_FRAME (frame);
 
   f = XFRAME (frame);
-  
+
   /* Do like the documentation says. */
   Fmake_frame_visible (frame);
 
@@ -2047,14 +2057,14 @@ doesn't support multiple overlapping frames, this function does nothing.  */)
      Lisp_Object frame;
 {
   struct frame *f;
-  
+
   if (NILP (frame))
     frame = selected_frame;
 
   CHECK_LIVE_FRAME (frame);
 
   f = XFRAME (frame);
-  
+
   if (FRAME_TERMINAL (f)->frame_raise_lower_hook)
     (*FRAME_TERMINAL (f)->frame_raise_lower_hook) (f, 0);
 
@@ -2091,7 +2101,7 @@ The redirection lasts until `redirect-frame-focus' is called to change it.  */)
      Lisp_Object frame, focus_frame;
 {
   struct frame *f;
-  
+
   /* Note that we don't check for a live frame here.  It's reasonable
      to redirect the focus of a frame you're about to delete, if you
      know what other frame should receive those keystrokes.  */
@@ -2101,7 +2111,7 @@ The redirection lasts until `redirect-frame-focus' is called to change it.  */)
     CHECK_LIVE_FRAME (focus_frame);
 
   f = XFRAME (frame);
-  
+
   f->focus_frame = focus_frame;
 
   if (FRAME_TERMINAL (f)->frame_rehighlight_hook)
@@ -2204,7 +2214,7 @@ store_in_alist (alistptr, prop, val)
 static int
 frame_name_fnn_p (str, len)
      char *str;
-     int len;
+     EMACS_INT len;
 {
   if (len > 1 && str[0] == 'F')
     {
@@ -2845,6 +2855,9 @@ static struct frame_parm_table frame_parms[] =
   {"right-fringe",             &Qright_fringe},
   {"wait-for-wm",              &Qwait_for_wm},
   {"fullscreen",                &Qfullscreen},
+#ifdef USE_FONT_BACKEND
+  {"font-backend",             &Qfont_backend}
+#endif /* USE_FONT_BACKEND */
 };
 
 #ifdef HAVE_WINDOW_SYSTEM
@@ -3290,7 +3303,7 @@ x_set_fullscreen (f, new_value, old_value)
   else if (EQ (new_value, Qfullheight))
     f->want_fullscreen = FULLSCREEN_HEIGHT;
 
-  if (FRAME_TERMINAL (f)->fullscreen_hook != NULL) 
+  if (FRAME_TERMINAL (f)->fullscreen_hook != NULL)
     FRAME_TERMINAL (f)->fullscreen_hook (f);
 }
 
@@ -3359,20 +3372,60 @@ x_set_font (f, arg, oldval)
   Lisp_Object frame;
   int old_fontset = FRAME_FONTSET(f);
 
+#ifdef USE_FONT_BACKEND
+  if (enable_font_backend)
+    {
+      int fontset = -1;
+      Lisp_Object font_object;
+
+      /* ARG is a fontset name, a font name, or a font object.
+        In the last case, this function never fail.  */
+      if (STRINGP (arg))
+       {
+         fontset = fs_query_fontset (arg, 0);
+         if (fontset < 0)
+           font_object = font_open_by_name (f, SDATA (arg));
+         else if (fontset > 0)
+           {
+             Lisp_Object ascii_font = fontset_ascii (fontset);
+
+             font_object = font_open_by_name (f, SDATA (ascii_font));
+           }
+       }
+      else
+       font_object = arg;
+
+      if (fontset < 0 && ! NILP (font_object))
+       fontset = new_fontset_from_font (font_object);
+
+      if (fontset == 0)
+       /* Refuse the default fontset.  */
+       result = Qt;
+      else if (NILP (font_object))
+       result = Qnil;
+      else
+       result = x_new_fontset2 (f, fontset, font_object);
+    }
+  else
+    {
+#endif /* USE_FONT_BACKEND */
   CHECK_STRING (arg);
 
   fontset_name = Fquery_fontset (arg, Qnil);
 
   BLOCK_INPUT;
   result = (STRINGP (fontset_name)
-            ? x_new_fontset (f, SDATA (fontset_name))
-            : x_new_font (f, SDATA (arg)));
+            ? x_new_fontset (f, fontset_name)
+            : x_new_fontset (f, arg));
   UNBLOCK_INPUT;
+#ifdef USE_FONT_BACKEND
+    }
+#endif
 
   if (EQ (result, Qnil))
     error ("Font `%s' is not defined", SDATA (arg));
   else if (EQ (result, Qt))
-    error ("The characters of the given font have varying widths");
+    error ("The default fontset can't be used for a frame font");
   else if (STRINGP (result))
     {
       set_default_ascii_font (result);
@@ -3383,7 +3436,9 @@ x_set_font (f, arg, oldval)
          if (old_fontset == FRAME_FONTSET (f))
            return;
        }
-      else if (!NILP (Fequal (result, oldval)))
+      store_frame_param (f, Qfont, result);
+
+      if (!NILP (Fequal (result, oldval)))
         return;
 
       /* Recalculate toolbar height.  */
@@ -3391,7 +3446,6 @@ x_set_font (f, arg, oldval)
       /* Ensure we redraw it.  */
       clear_current_matrices (f);
 
-      store_frame_param (f, Qfont, result);
       recompute_basic_faces (f);
     }
   else
@@ -3412,6 +3466,62 @@ x_set_font (f, arg, oldval)
 }
 
 
+#ifdef USE_FONT_BACKEND
+void
+x_set_font_backend (f, new_value, old_value)
+     struct frame *f;
+     Lisp_Object new_value, old_value;
+{
+  if (! NILP (new_value)
+      && !CONSP (new_value))
+    {
+      char *p0, *p1;
+       
+      CHECK_STRING (new_value);
+      p0 = p1 = SDATA (new_value);
+      new_value = Qnil;
+      while (*p0)
+       {
+         while (*p1 && *p1 != ',') p1++;
+         if (p0 < p1)
+           new_value = Fcons (Fintern (make_string (p0, p1 - p0), Qnil),
+                              new_value);
+         if (*p1)
+           p1++;
+         p0 = p1;
+       }
+      new_value = Fnreverse (new_value);
+    }
+
+  if (! NILP (old_value) && ! NILP (Fequal (old_value, new_value)))
+    return;
+
+  if (FRAME_FONT_OBJECT (f))
+    free_all_realized_faces (Qnil);
+
+  new_value = font_update_drivers (f, NILP (new_value) ? Qt : new_value);
+  if (NILP (new_value))
+    {
+      if (NILP (old_value))
+       error ("No font backend available");
+      font_update_drivers (f, old_value);
+      error ("None of specified font backends are available");
+    }
+  store_frame_param (f, Qfont_backend, new_value);
+
+  if (FRAME_FONT_OBJECT (f))
+    {
+      Lisp_Object frame;
+
+      XSETFRAME (frame, f);
+      x_set_font (f, Fframe_parameter (frame, Qfont), Qnil);
+      ++face_change_count;
+      ++windows_or_buffers_changed;
+    }
+}
+#endif /* USE_FONT_BACKEND */
+
+
 void
 x_set_fringe_width (f, new_value, old_value)
      struct frame *f;
@@ -4183,7 +4293,7 @@ x_figure_window_size (f, parms, toolbar_p)
       int width, height;
 
       /* It takes both for some WM:s to place it where we want */
-      window_prompting = USPosition | PPosition;
+      window_prompting |= USPosition | PPosition;
       x_fullscreen_adjust (f, &width, &height, &top, &left);
       FRAME_COLS (f) = width;
       FRAME_LINES (f) = height;
@@ -4286,14 +4396,14 @@ syms_of_frame ()
   staticpro (&Qdisplay_type);
   Qbackground_mode = intern ("background-mode");
   staticpro (&Qbackground_mode);
+  Qnoelisp = intern ("noelisp");
+  staticpro (&Qnoelisp);
   Qtty_color_mode = intern ("tty-color-mode");
   staticpro (&Qtty_color_mode);
   Qtty = intern ("tty");
   staticpro (&Qtty);
   Qtty_type = intern ("tty-type");
   staticpro (&Qtty_type);
-  Qwindow_system = intern ("window-system");
-  staticpro (&Qwindow_system);
 
   Qface_set_after_frame_default = intern ("face-set-after-frame-default");
   staticpro (&Qface_set_after_frame_default);
@@ -4318,7 +4428,7 @@ syms_of_frame ()
   staticpro (&Qterminal);
   Qterminal_live_p = intern ("terminal-live-p");
   staticpro (&Qterminal_live_p);
-  
+
   {
     int i;
 
@@ -4420,7 +4530,7 @@ Note that functions in this list may be called twice on the same
 frame.  In the second invocation, the frame is already deleted, and
 the function should do nothing.  (You can use `frame-live-p' to check
 for this.)  This wrinkle happens when an earlier function in
-`delete-frame-functions' (indirectly) calls delete-frame
+`delete-frame-functions' (indirectly) calls `delete-frame'
 recursively.  */);
   Vdelete_frame_functions = Qnil;
 
@@ -4453,7 +4563,7 @@ automatically.  */);
 #else
   focus_follows_mouse = 0;
 #endif
-        
+
   staticpro (&Vframe_list);
 
   defsubr (&Sactive_minibuffer_window);