/* 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.
#include <stdio.h>
#include "lisp.h"
-#include "charset.h"
+#include "character.h"
#ifdef HAVE_X_WINDOWS
#include "xterm.h"
#endif
#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;
Lisp_Object Qvisible;
Lisp_Object Qdisplay_type;
Lisp_Object Qbackground_mode;
+Lisp_Object Qnoelisp;
Lisp_Object Qx_frame_parameter;
Lisp_Object Qx_resource_name;
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;
return Qnil;
else
return type;
-}
+}
struct frame *
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)
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)))
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;
}
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;
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)
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)
#endif
#endif
#endif /* not MSDOS */
-
+
{
Lisp_Object terminal;
t = get_terminal (terminal, 1);
}
}
-
+
if (!t)
- {
+ {
char *name = 0, *type = 0;
Lisp_Object tty, tty_type;
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
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));
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);
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;
{
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
&& 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];
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. */
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));
{
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.
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
CHECK_LIVE_FRAME (frame);
f = XFRAME (frame);
-
+
/* Do like the documentation says. */
Fmake_frame_visible (frame);
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);
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. */
CHECK_LIVE_FRAME (focus_frame);
f = XFRAME (frame);
-
+
f->focus_frame = focus_frame;
if (FRAME_TERMINAL (f)->frame_rehighlight_hook)
static int
frame_name_fnn_p (str, len)
char *str;
- int len;
+ EMACS_INT len;
{
if (len > 1 && str[0] == 'F')
{
{"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
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);
}
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);
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. */
/* Ensure we redraw it. */
clear_current_matrices (f);
- store_frame_param (f, Qfont, result);
recompute_basic_faces (f);
}
else
}
+#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;
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;
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);
staticpro (&Qterminal);
Qterminal_live_p = intern ("terminal-live-p");
staticpro (&Qterminal_live_p);
-
+
{
int i;
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;
#else
focus_follows_mouse = 0;
#endif
-
+
staticpro (&Vframe_list);
defsubr (&Sactive_minibuffer_window);