terminal.c 15.4 KB
Newer Older
1
/* Functions related to terminal devices.
2
   Copyright (C) 2005-2011 Free Software Foundation, Inc.
3 4 5

This file is part of GNU Emacs.

6
GNU Emacs is free software: you can redistribute it and/or modify
7
it under the terms of the GNU General Public License as published by
8 9
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
10 11 12 13 14 15 16

GNU Emacs is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
GNU General Public License for more details.

You should have received a copy of the GNU General Public License
17
along with GNU Emacs.  If not, see <http://www.gnu.org/licenses/>.  */
18 19

#include <config.h>
20
#include <stdio.h>
21
#include <setjmp.h>
22 23 24 25 26 27 28 29 30

#include "lisp.h"
#include "frame.h"
#include "termchar.h"
#include "termhooks.h"
#include "charset.h"
#include "coding.h"
#include "keyboard.h"

31 32
/* Chain of all terminals currently in use. */
struct terminal *terminal_list;
33

34 35
/* The first unallocated terminal id. */
static int next_terminal_id;
36

37 38
/* The initial terminal device, created by initial_term_init. */
struct terminal *initial_terminal;
39

40
static void delete_initial_terminal (struct terminal *);
41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65



void
ring_bell (struct frame *f)
{
  if (!NILP (Vring_bell_function))
    {
      Lisp_Object function;

      /* Temporarily set the global variable to nil
	 so that if we get an error, it stays nil
	 and we don't call it over and over.

	 We don't specbind it, because that would carefully
	 restore the bad value if there's an error
	 and make the loop of errors happen anyway.  */

      function = Vring_bell_function;
      Vring_bell_function = Qnil;

      call0 (function);

      Vring_bell_function = function;
    }
66 67
  else if (FRAME_TERMINAL (f)->ring_bell_hook)
    (*FRAME_TERMINAL (f)->ring_bell_hook) (f);
68 69 70 71 72
}

void
update_begin (struct frame *f)
{
73 74
  if (FRAME_TERMINAL (f)->update_begin_hook)
    (*FRAME_TERMINAL (f)->update_begin_hook) (f);
75 76 77 78 79
}

void
update_end (struct frame *f)
{
80 81
  if (FRAME_TERMINAL (f)->update_end_hook)
    (*FRAME_TERMINAL (f)->update_end_hook) (f);
82 83 84 85 86 87 88 89 90 91
}

/* Specify how many text lines, from the top of the window,
   should be affected by insert-lines and delete-lines operations.
   This, and those operations, are used only within an update
   that is bounded by calls to update_begin and update_end.  */

void
set_terminal_window (struct frame *f, int size)
{
92 93
  if (FRAME_TERMINAL (f)->set_terminal_window_hook)
    (*FRAME_TERMINAL (f)->set_terminal_window_hook) (f, size);
94 95 96 97 98 99 100 101
}

/* Move cursor to row/column position VPOS/HPOS.  HPOS/VPOS are
   frame-relative coordinates.  */

void
cursor_to (struct frame *f, int vpos, int hpos)
{
102 103
  if (FRAME_TERMINAL (f)->cursor_to_hook)
    (*FRAME_TERMINAL (f)->cursor_to_hook) (f, vpos, hpos);
104 105 106 107 108 109 110
}

/* Similar but don't take any account of the wasted characters.  */

void
raw_cursor_to (struct frame *f, int row, int col)
{
111
  if (FRAME_TERMINAL (f)->raw_cursor_to_hook)
112
    (*FRAME_TERMINAL (f)->raw_cursor_to_hook) (f, row, col);
113 114 115 116 117 118 119 120
}

/* Erase operations */

/* Clear from cursor to end of frame. */
void
clear_to_end (struct frame *f)
{
121 122
  if (FRAME_TERMINAL (f)->clear_to_end_hook)
    (*FRAME_TERMINAL (f)->clear_to_end_hook) (f);
123 124 125 126 127 128 129
}

/* Clear entire frame */

void
clear_frame (struct frame *f)
{
130 131
  if (FRAME_TERMINAL (f)->clear_frame_hook)
    (*FRAME_TERMINAL (f)->clear_frame_hook) (f);
132 133 134 135 136 137 138 139 140 141
}

/* Clear from cursor to end of line.
   Assume that the line is already clear starting at column first_unused_hpos.

   Note that the cursor may be moved, on terminals lacking a `ce' string.  */

void
clear_end_of_line (struct frame *f, int first_unused_hpos)
{
142 143
  if (FRAME_TERMINAL (f)->clear_end_of_line_hook)
    (*FRAME_TERMINAL (f)->clear_end_of_line_hook) (f, first_unused_hpos);
144 145 146 147 148 149 150 151
}

/* Output LEN glyphs starting at STRING at the nominal cursor position.
   Advance the nominal cursor over the text.  */

void
write_glyphs (struct frame *f, struct glyph *string, int len)
{
152 153
  if (FRAME_TERMINAL (f)->write_glyphs_hook)
    (*FRAME_TERMINAL (f)->write_glyphs_hook) (f, string, len);
154 155 156 157 158 159 160 161 162 163 164 165
}

/* Insert LEN glyphs from START at the nominal cursor position.

   If start is zero, insert blanks instead of a string at start */

void
insert_glyphs (struct frame *f, struct glyph *start, int len)
{
  if (len <= 0)
    return;

166 167
  if (FRAME_TERMINAL (f)->insert_glyphs_hook)
    (*FRAME_TERMINAL (f)->insert_glyphs_hook) (f, start, len);
168 169 170 171 172 173 174
}

/* Delete N glyphs at the nominal cursor position. */

void
delete_glyphs (struct frame *f, int n)
{
175 176
  if (FRAME_TERMINAL (f)->delete_glyphs_hook)
    (*FRAME_TERMINAL (f)->delete_glyphs_hook) (f, n);
177 178 179 180 181 182 183
}

/* Insert N lines at vpos VPOS.  If N is negative, delete -N lines.  */

void
ins_del_lines (struct frame *f, int vpos, int n)
{
184 185
  if (FRAME_TERMINAL (f)->ins_del_lines_hook)
    (*FRAME_TERMINAL (f)->ins_del_lines_hook) (f, vpos, n);
186 187 188 189 190
}




Chong Yidong's avatar
Chong Yidong committed
191 192 193 194
/* Return the terminal object specified by TERMINAL.  TERMINAL may be
   a terminal object, a frame, or nil for the terminal device of the
   current frame.  If THROW is zero, return NULL for failure,
   otherwise throw an error.  */
195

196 197
struct terminal *
get_terminal (Lisp_Object terminal, int throw)
198
{
199
  struct terminal *result = NULL;
200

201 202
  if (NILP (terminal))
    terminal = selected_frame;
203

204 205
  if (TERMINALP (terminal))
    result = XTERMINAL (terminal);
206
  else if (FRAMEP (terminal))
Chong Yidong's avatar
Chong Yidong committed
207
    result = FRAME_TERMINAL (XFRAME (terminal));
208

209 210 211
  if (result && !result->name)
    result = NULL;

212
  if (result == NULL && throw)
213
    wrong_type_argument (Qterminal_live_p, terminal);
214 215 216 217 218 219

  return result;
}



220
/* Create a new terminal object and add it to the terminal list. */
221

222 223
struct terminal *
create_terminal (void)
224
{
225
  struct terminal *terminal = allocate_terminal ();
226
  Lisp_Object terminal_coding, keyboard_coding;
227 228

  terminal->name = NULL;
229 230
  terminal->next_terminal = terminal_list;
  terminal_list = terminal;
231

232
  terminal->id = next_terminal_id++;
233

234
  terminal->keyboard_coding =
235
    (struct coding_system *) xmalloc (sizeof (struct coding_system));
236
  terminal->terminal_coding =
237 238
    (struct coding_system *) xmalloc (sizeof (struct coding_system));

239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256
  /* If default coding systems for the terminal and the keyboard are
     already defined, use them in preference to the defaults.  This is
     needed when Emacs runs in daemon mode.  */
  keyboard_coding =
    find_symbol_value (intern ("default-keyboard-coding-system"));
  if (NILP (keyboard_coding)
      || EQ (keyboard_coding, Qunbound)
      || NILP (Fcoding_system_p (keyboard_coding)))
    keyboard_coding = Qno_conversion;
  terminal_coding =
    find_symbol_value (intern ("default-terminal-coding-system"));
  if (NILP (terminal_coding)
      || EQ (terminal_coding, Qunbound)
      || NILP (Fcoding_system_p (terminal_coding)))
    terminal_coding = Qundecided;

  setup_coding_system (keyboard_coding, terminal->keyboard_coding);
  setup_coding_system (terminal_coding, terminal->terminal_coding);
257

258
  terminal->param_alist = Qnil;
Chong Yidong's avatar
Chong Yidong committed
259 260
  terminal->charset_list = Qnil;
  terminal->Vselection_alist = Qnil;
261
  return terminal;
262 263
}

264 265
/* Low-level function to close all frames on a terminal, remove it
   from the terminal list and free its memory.  */
266 267

void
268
delete_terminal (struct terminal *terminal)
269
{
270
  struct terminal **tp;
271
  Lisp_Object tail, frame;
272

273
  /* Protect against recursive calls.  delete_frame calls the
274
     delete_terminal_hook when we delete our last frame.  */
275
  if (!terminal->name)
276
    return;
277 278
  xfree (terminal->name);
  terminal->name = NULL;
279

280
  /* Check for live frames that are still on this terminal. */
281 282 283
  FOR_EACH_FRAME (tail, frame)
    {
      struct frame *f = XFRAME (frame);
284
      if (FRAME_LIVE_P (f) && f->terminal == terminal)
285
        {
286 287
	  /* Pass Qnoelisp rather than Qt.  */
          delete_frame (frame, Qnoelisp);
288 289 290
        }
    }

291 292
  for (tp = &terminal_list; *tp != terminal; tp = &(*tp)->next_terminal)
    if (! *tp)
293
      abort ();
294 295
  *tp = terminal->next_terminal;

296 297 298 299
  xfree (terminal->keyboard_coding);
  terminal->keyboard_coding = NULL;
  xfree (terminal->terminal_coding);
  terminal->terminal_coding = NULL;
300

301
  if (terminal->kboard && --terminal->kboard->reference_count == 0)
302 303 304 305
    {
      delete_kboard (terminal->kboard);
      terminal->kboard = NULL;
    }
306 307
}

308 309
Lisp_Object Qrun_hook_with_args;
static Lisp_Object Qdelete_terminal_functions;
Paul Eggert's avatar
Paul Eggert committed
310
DEFUN ("delete-terminal", Fdelete_terminal, Sdelete_terminal, 0, 2, 0,
311
       doc: /* Delete TERMINAL by deleting all frames on it and closing the terminal.
312 313
TERMINAL may be a terminal object, a frame, or nil (meaning the
selected frame's terminal).
314 315 316

Normally, you may not delete a display if all other displays are suspended,
but if the second argument FORCE is non-nil, you may do so. */)
Dan Nicolaescu's avatar
Dan Nicolaescu committed
317
  (Lisp_Object terminal, Lisp_Object force)
318
{
319
  struct terminal *t = get_terminal (terminal, 0);
320

321
  if (!t)
322 323
    return Qnil;

324 325 326 327 328
  if (NILP (force))
    {
      struct terminal *p = terminal_list;
      while (p && (p == t || !TERMINAL_ACTIVE_P (p)))
	p = p->next_terminal;
329

330 331 332
      if (!p)
	error ("Attempt to delete the sole active display terminal");
    }
333

334 335 336 337 338 339 340 341 342 343
  if (NILP (Vrun_hooks))
    ;
  else if (EQ (force, Qnoelisp))
    pending_funcalls
      = Fcons (list3 (Qrun_hook_with_args,
		      Qdelete_terminal_functions, terminal),
	       pending_funcalls);
  else
    safe_call2 (Qrun_hook_with_args, Qdelete_terminal_functions, terminal);

344 345
  if (t->delete_terminal_hook)
    (*t->delete_terminal_hook) (t);
346
  else
347
    delete_terminal (t);
348 349 350 351

  return Qnil;
}

352

Paul Eggert's avatar
Paul Eggert committed
353
DEFUN ("frame-terminal", Fframe_terminal, Sframe_terminal, 0, 1, 0,
354 355 356 357
       doc: /* Return the terminal that FRAME is displayed on.
If FRAME is nil, the selected frame is used.

The terminal device is represented by its integer identifier.  */)
Dan Nicolaescu's avatar
Dan Nicolaescu committed
358
  (Lisp_Object frame)
359 360 361 362 363 364 365 366
{
  struct terminal *t;

  if (NILP (frame))
    frame = selected_frame;

  CHECK_LIVE_FRAME (frame);

367
  t = FRAME_TERMINAL (XFRAME (frame));
368 369 370 371

  if (!t)
    return Qnil;
  else
372 373 374 375 376
    {
      Lisp_Object terminal;
      XSETTERMINAL (terminal, t);
      return terminal;
    }
377 378 379 380 381 382 383
}

DEFUN ("terminal-live-p", Fterminal_live_p, Sterminal_live_p, 1, 1, 0,
       doc: /* Return non-nil if OBJECT is a terminal which has not been deleted.
Value is nil if OBJECT is not a live display terminal.
If object is a live display terminal, the return value indicates what
sort of output terminal it uses.  See the documentation of `framep' for
384
possible return values.  */)
Dan Nicolaescu's avatar
Dan Nicolaescu committed
385
  (Lisp_Object object)
386
{
387
  struct terminal *t;
388

389
  t = get_terminal (object, 0);
390

391
  if (!t)
392 393
    return Qnil;

394
  switch (t->type)
395 396 397 398 399 400 401 402 403 404 405 406
    {
    case output_initial: /* The initial frame is like a termcap frame. */
    case output_termcap:
      return Qt;
    case output_x_window:
      return Qx;
    case output_w32:
      return Qw32;
    case output_msdos_raw:
      return Qpc;
    case output_mac:
      return Qmac;
407 408
    case output_ns:
      return Qns;
409 410 411 412 413
    default:
      abort ();
    }
}

414
DEFUN ("terminal-list", Fterminal_list, Sterminal_list, 0, 0, 0,
415
       doc: /* Return a list of all terminal devices.  */)
Dan Nicolaescu's avatar
Dan Nicolaescu committed
416
  (void)
417
{
418
  Lisp_Object terminal, terminals = Qnil;
419
  struct terminal *t;
420

421
  for (t = terminal_list; t; t = t->next_terminal)
422 423 424 425
    {
      XSETTERMINAL (terminal, t);
      terminals = Fcons (terminal, terminals);
    }
426

427
  return terminals;
428 429
}

430 431
DEFUN ("terminal-name", Fterminal_name, Sterminal_name, 0, 1, 0,
       doc: /* Return the name of the terminal device TERMINAL.
432 433
It is not guaranteed that the returned value is unique among opened devices.

434
TERMINAL may be a terminal object, a frame, or nil (meaning the
435
selected frame's terminal). */)
Dan Nicolaescu's avatar
Dan Nicolaescu committed
436
  (Lisp_Object terminal)
437
{
438 439
  struct terminal *t
    = TERMINALP (terminal) ? XTERMINAL (terminal) : get_terminal (terminal, 1);
440

441
  return t->name ? build_string (t->name) : Qnil;
442 443 444 445
}



446
/* Set the value of terminal parameter PARAMETER in terminal D to VALUE.
447 448
   Return the previous value.  */

449
static Lisp_Object
450
store_terminal_param (struct terminal *t, Lisp_Object parameter, Lisp_Object value)
451
{
452
  Lisp_Object old_alist_elt = Fassq (parameter, t->param_alist);
453 454
  if (EQ (old_alist_elt, Qnil))
    {
455
      t->param_alist = Fcons (Fcons (parameter, value), t->param_alist);
456 457 458 459 460 461 462 463 464 465 466 467 468 469 470 471
      return Qnil;
    }
  else
    {
      Lisp_Object result = Fcdr (old_alist_elt);
      Fsetcdr (old_alist_elt, value);
      return result;
    }
}


DEFUN ("terminal-parameters", Fterminal_parameters, Sterminal_parameters, 0, 1, 0,
       doc: /* Return the parameter-alist of terminal TERMINAL.
The value is a list of elements of the form (PARM . VALUE), where PARM
is a symbol.

472 473
TERMINAL can be a terminal object, a frame, or nil (meaning the
selected frame's terminal).  */)
Dan Nicolaescu's avatar
Dan Nicolaescu committed
474
  (Lisp_Object terminal)
475
{
476 477
  struct terminal *t
    = TERMINALP (terminal) ? XTERMINAL (terminal) : get_terminal (terminal, 1);
478
  return Fcopy_alist (t->param_alist);
479 480 481 482
}

DEFUN ("terminal-parameter", Fterminal_parameter, Sterminal_parameter, 2, 2, 0,
       doc: /* Return TERMINAL's value for parameter PARAMETER.
483 484
TERMINAL can be a terminal object, a frame, or nil (meaning the
selected frame's terminal).  */)
Dan Nicolaescu's avatar
Dan Nicolaescu committed
485
  (Lisp_Object terminal, Lisp_Object parameter)
486 487
{
  Lisp_Object value;
488 489
  struct terminal *t
    = TERMINALP (terminal) ? XTERMINAL (terminal) : get_terminal (terminal, 1);
490
  CHECK_SYMBOL (parameter);
491
  value = Fcdr (Fassq (parameter, t->param_alist));
492 493 494 495 496 497 498 499
  return value;
}

DEFUN ("set-terminal-parameter", Fset_terminal_parameter,
       Sset_terminal_parameter, 3, 3, 0,
       doc: /* Set TERMINAL's value for parameter PARAMETER to VALUE.
Return the previous value of PARAMETER.

500 501
TERMINAL can be a terminal object, a frame or nil (meaning the
selected frame's terminal).  */)
Dan Nicolaescu's avatar
Dan Nicolaescu committed
502
  (Lisp_Object terminal, Lisp_Object parameter, Lisp_Object value)
503
{
504 505
  struct terminal *t
    = TERMINALP (terminal) ? XTERMINAL (terminal) : get_terminal (terminal, 1);
506
  return store_terminal_param (t, parameter, value);
507 508 509 510
}



511 512
/* Create the bootstrap display terminal for the initial frame.
   Returns a terminal of type output_initial.  */
513

514 515
struct terminal *
init_initial_terminal (void)
516
{
517
  if (initialized || terminal_list || tty_list)
518 519
    abort ();

520 521 522 523 524
  initial_terminal = create_terminal ();
  initial_terminal->type = output_initial;
  initial_terminal->name = xstrdup ("initial_terminal");
  initial_terminal->kboard = initial_kboard;
  initial_terminal->delete_terminal_hook = &delete_initial_terminal;
525 526
  /* All other hooks are NULL. */

527
  return initial_terminal;
528 529
}

530 531
/* Deletes the bootstrap terminal device.
   Called through delete_terminal_hook. */
532

533 534
static void
delete_initial_terminal (struct terminal *terminal)
535
{
536
  if (terminal != initial_terminal)
537 538
    abort ();

539 540
  delete_terminal (terminal);
  initial_terminal = NULL;
541 542 543
}

void
544
syms_of_terminal (void)
545 546
{

547
  DEFVAR_LISP ("ring-bell-function", Vring_bell_function,
548 549 550 551
    doc: /* Non-nil means call this function to ring the bell.
The function should accept no arguments.  */);
  Vring_bell_function = Qnil;

552
  DEFVAR_LISP ("delete-terminal-functions", Vdelete_terminal_functions,
553 554 555 556 557
    doc: /* Special hook run when a terminal is deleted.
Each function is called with argument, the terminal.
This may be called just before actually deleting the terminal,
or some time later.  */);
  Vdelete_terminal_functions = Qnil;
Dan Nicolaescu's avatar
Dan Nicolaescu committed
558
  Qdelete_terminal_functions = intern_c_string ("delete-terminal-functions");
559
  staticpro (&Qdelete_terminal_functions);
Dan Nicolaescu's avatar
Dan Nicolaescu committed
560
  Qrun_hook_with_args = intern_c_string ("run-hook-with-args");
561 562
  staticpro (&Qrun_hook_with_args);

563 564 565 566 567
  defsubr (&Sdelete_terminal);
  defsubr (&Sframe_terminal);
  defsubr (&Sterminal_live_p);
  defsubr (&Sterminal_list);
  defsubr (&Sterminal_name);
568 569 570 571
  defsubr (&Sterminal_parameters);
  defsubr (&Sterminal_parameter);
  defsubr (&Sset_terminal_parameter);

Dan Nicolaescu's avatar
Dan Nicolaescu committed
572
  Fprovide (intern_c_string ("multi-tty"), Qnil);
573
}