Function: make-terminal-frame
make-terminal-frame is a function defined in frame.c.
Signature
(make-terminal-frame PARMS)
Documentation
Create an additional terminal frame, possibly on another terminal.
This function takes one argument, an alist specifying frame parameters.
You can create multiple frames on a single text terminal, but only one of them (the selected terminal frame) is actually displayed.
In practice, generally you don't need to specify any parameters,
except when you want to create a new frame on another terminal.
In that case, the tty parameter specifies the device file to open,
and the tty-type parameter specifies the terminal type. Example:
(make-terminal-frame '((tty . "/dev/pts/5") (tty-type . "xterm")))
Note that changing the size of one terminal frame automatically affects all frames on the same terminal device.
Probably introduced at or before Emacs version 23.1.
Source Code
// Defined in /usr/src/emacs/src/frame.c
// Skipping highlighting due to helpful-max-highlight.
{
#ifdef HAVE_ANDROID
error ("Text terminals are not supported on this platform");
return Qnil;
#else
struct terminal *t = NULL;
struct frame *sf = SELECTED_FRAME ();
#ifdef MSDOS
if (sf->output_method != output_msdos_raw
&& sf->output_method != output_termcap)
emacs_abort ();
#else /* not MSDOS */
#ifdef WINDOWSNT /* This should work now! */
if (sf->output_method != output_termcap)
error ("Not using an ASCII terminal now; cannot make a new ASCII frame");
#endif
#endif /* not MSDOS */
{
Lisp_Object terminal;
terminal = Fassq (Qterminal, parms);
if (CONSP (terminal))
{
terminal = XCDR (terminal);
t = decode_live_terminal (terminal);
}
#ifdef MSDOS
if (t && t != the_only_display_info.terminal)
/* msdos.c assumes a single tty_display_info object. */
error ("Multiple terminals are not supported on this platform");
if (!t)
t = the_only_display_info.terminal;
# endif
}
if (!t)
{
char *name = 0, *type = 0;
Lisp_Object tty, tty_type;
USE_SAFE_ALLOCA;
tty = get_future_frame_param
(Qtty, parms, (FRAME_TERMCAP_P (XFRAME (selected_frame))
? FRAME_TTY (XFRAME (selected_frame))->name
: NULL));
if (!NILP (tty))
SAFE_ALLOCA_STRING (name, tty);
tty_type = get_future_frame_param
(Qtty_type, parms, (FRAME_TERMCAP_P (XFRAME (selected_frame))
? FRAME_TTY (XFRAME (selected_frame))->type
: NULL));
if (!NILP (tty_type))
SAFE_ALLOCA_STRING (type, tty_type);
t = init_tty (name, type, 0); /* Errors are not fatal. */
SAFE_FREE ();
}
/* Make a new frame. We need to know up front if a parent frame is
specified because we behave differently in this case, e.g., child
frames don't obscure other frames. */
Lisp_Object parent = Fcdr (Fassq (Qparent_frame, parms));
struct frame *f = make_terminal_frame (t, parent, parms);
if (!noninteractive)
init_frame_faces (f);
/* Visibility of root frames cannot be set with a frame parameter.
Their visibility solely depends on whether or not they are the
top_frame on the terminal. */
if (FRAME_PARENT_FRAME (f))
{
Lisp_Object visible = Fassq (Qvisibility, parms);
if (CONSP (visible))
SET_FRAME_VISIBLE (f, !NILP (visible));
/* FIXME/tty: The only way, for now, to get borders on a tty is
to allow decorations. */
Lisp_Object undecorated = Fassq (Qundecorated, parms);
if (CONSP (undecorated) && !NILP (XCDR (undecorated)))
f->undecorated = true;
/* Unused at present. */
Lisp_Object no_focus = Fassq (Qno_accept_focus, parms);
if (CONSP (no_focus) && !NILP (XCDR (no_focus)))
f->no_accept_focus = true;
Lisp_Object no_split = Fassq (Qunsplittable, parms);
if (CONSP (no_split) && !NILP (XCDR (no_split)))
f->no_split = true;
}
/* Determine width and height of the frame. For root frames use the
width/height of the terminal. For child frames, take it from frame
parameters. Note that a default (80x25) has been set in
make_frame. We handle root frames in this way because otherwise we
would end up needing glyph matrices for the terminal, which is both
more work and has its downsides (think of clipping frames to the
terminal size). */
int x = 0, y = 0, width, height;
if (FRAME_PARENT_FRAME (f))
tty_child_frame_rect (f, parms, &x, &y, &width, &height);
else
get_tty_size (fileno (FRAME_TTY (f)->input), &width, &height);
adjust_frame_size (f, width, height - FRAME_TOP_MARGIN (f), 5, 0,
Qterminal_frame);
adjust_frame_glyphs (f);
calculate_costs (f);
f->left_pos = x;
f->top_pos = y;
store_in_alist (&parms, Qtty_type, build_string (t->display_info.tty->type));
store_in_alist (&parms, Qtty,
(t->display_info.tty->name
? build_string (t->display_info.tty->name)
: Qnil));
/* Make the frame face hash be frame-specific, so that each
frame could change its face definitions independently. */
fset_face_hash_table (f, Fcopy_hash_table (sf->face_hash_table));
/* Simple copy_hash_table isn't enough, because we need the contents of
the vectors which are the values in face_hash_table to
be copied as well. */
ptrdiff_t idx = 0;
struct Lisp_Hash_Table *table = XHASH_TABLE (f->face_hash_table);
for (idx = 0; idx < table->count; ++idx)
set_hash_value_slot (table, idx, Fcopy_sequence (HASH_VALUE (table, idx)));
/* On terminal frames the `minibuffer' frame parameter is always
virtually t. Avoid that a different value in parms causes
complaints, see Bug#24758. */
if (!FRAME_PARENT_FRAME (f))
store_in_alist (&parms, Qminibuffer, Qt);
Lisp_Object frame;
XSETFRAME (frame, f);
Fmodify_frame_parameters (frame, parms);
f->can_set_window_size = true;
f->after_make_frame = true;
return frame;
#endif
}