Mercurial > hg > xemacs-beta
diff src/device-tty.c @ 428:3ecd8885ac67 r21-2-22
Import from CVS: tag r21-2-22
author | cvs |
---|---|
date | Mon, 13 Aug 2007 11:28:15 +0200 |
parents | |
children | ed498ef2108b |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/device-tty.c Mon Aug 13 11:28:15 2007 +0200 @@ -0,0 +1,215 @@ +/* TTY device functions. + Copyright (C) 1994, 1995 Board of Trustees, University of Illinois. + Copyright (C) 1994, 1995 Free Software Foundation, Inc. + Copyright (C) 1996 Ben Wing. + +This file is part of XEmacs. + +XEmacs is free software; you can redistribute it and/or modify it +under the terms of the GNU General Public License as published by the +Free Software Foundation; either version 2, or (at your option) any +later version. + +XEmacs 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 +along with XEmacs; see the file COPYING. If not, write to +the Free Software Foundation, Inc., 59 Temple Place - Suite 330, +Boston, MA 02111-1307, USA. */ + +/* Synched up with: Not in FSF. */ + +/* Authors: Ben Wing and Chuck Thompson. */ + +#include <config.h> +#include "lisp.h" + +#include "console-tty.h" +#include "console-stream.h" +#include "events.h" +#include "faces.h" +#include "frame.h" +#include "lstream.h" +#include "redisplay.h" +#include "sysdep.h" + +#include "syssignal.h" /* for SIGWINCH */ + +#include <errno.h> + +Lisp_Object Qinit_pre_tty_win, Qinit_post_tty_win; + + +static void +allocate_tty_device_struct (struct device *d) +{ + d->device_data = xnew_and_zero (struct tty_device); +} + +static void +tty_init_device (struct device *d, Lisp_Object props) +{ + struct console *con = XCONSOLE (DEVICE_CONSOLE (d)); + Lisp_Object terminal_type = CONSOLE_TTY_DATA (con)->terminal_type; + + DEVICE_INFD (d) = CONSOLE_TTY_DATA (con)->infd; + DEVICE_OUTFD (d) = CONSOLE_TTY_DATA (con)->outfd; + + allocate_tty_device_struct (d); + init_baud_rate (d); + + switch (init_tty_for_redisplay (d, (char *) XSTRING_DATA (terminal_type))) + { +#if 0 + case TTY_UNABLE_OPEN_DATABASE: + suppress_early_error_handler_backtrace = 1; + error ("Can't access terminal information database"); + break; +#endif + case TTY_TYPE_UNDEFINED: + suppress_early_error_handler_backtrace = 1; + error ("Terminal type `%s' undefined (or can't access database?)", + XSTRING_DATA (terminal_type)); + break; + case TTY_TYPE_INSUFFICIENT: + suppress_early_error_handler_backtrace = 1; + error ("Terminal type `%s' not powerful enough to run Emacs", + XSTRING_DATA (terminal_type)); + break; + case TTY_SIZE_UNSPECIFIED: + suppress_early_error_handler_backtrace = 1; + error ("Can't determine window size of terminal"); + break; + case TTY_INIT_SUCCESS: + break; + default: + abort (); + } + + init_one_device (d); + + /* Run part of the elisp side of the TTY device initialization. + The post-init is run in the tty_after_init_frame() method. */ + call0 (Qinit_pre_tty_win); +} + +static void +free_tty_device_struct (struct device *d) +{ + struct tty_device *td = (struct tty_device *) d->device_data; + if (td) + xfree (td); +} + +static void +tty_delete_device (struct device *d) +{ + free_tty_device_struct (d); +} + +#ifdef SIGWINCH + +static SIGTYPE +tty_device_size_change_signal (int signo) +{ + int old_errno = errno; + asynch_device_change_pending++; +#ifdef HAVE_UNIXOID_EVENT_LOOP + signal_fake_event (); +#endif + EMACS_REESTABLISH_SIGNAL (SIGWINCH, tty_device_size_change_signal); + errno = old_errno; + SIGRETURN; +} + +/* frame_change_signal does nothing but set a flag that it was called. + When redisplay is called, it will notice that the flag is set and + call handle_pending_device_size_change to do the actual work. */ +static void +tty_asynch_device_change (void) +{ + Lisp_Object devcons, concons; + + DEVICE_LOOP_NO_BREAK (devcons, concons) + { + int width, height; + Lisp_Object tail; + struct device *d = XDEVICE (XCAR (devcons)); + struct console *con = XCONSOLE (DEVICE_CONSOLE (d)); + + if (!DEVICE_TTY_P (d)) + continue; + + get_tty_device_size (d, &width, &height); + if (width > 0 && height > 0 + && (CONSOLE_TTY_DATA (con)->width != width + || CONSOLE_TTY_DATA (con)->height != height)) + { + CONSOLE_TTY_DATA (con)->width = width; + CONSOLE_TTY_DATA (con)->height = height; + + for (tail = DEVICE_FRAME_LIST (d); + !NILP (tail); + tail = XCDR (tail)) + { + struct frame *f = XFRAME (XCAR (tail)); + + /* We know the frame is tty because we made sure that the + device is tty. */ + change_frame_size (f, height, width, 1); + } + } + } +} + +#endif /* SIGWINCH */ + +static Lisp_Object +tty_device_system_metrics (struct device *d, + enum device_metrics m) +{ + struct console *con = XCONSOLE (DEVICE_CONSOLE (d)); + switch (m) + { + case DM_size_device: + return Fcons (make_int (CONSOLE_TTY_DATA (con)->width), + make_int (CONSOLE_TTY_DATA (con)->height)); + default: /* No such device metric property for TTY devices */ + return Qunbound; + } +} + +/************************************************************************/ +/* initialization */ +/************************************************************************/ + +void +syms_of_device_tty (void) +{ + defsymbol (&Qinit_pre_tty_win, "init-pre-tty-win"); + defsymbol (&Qinit_post_tty_win, "init-post-tty-win"); +} + +void +console_type_create_device_tty (void) +{ + /* device methods */ + CONSOLE_HAS_METHOD (tty, init_device); + CONSOLE_HAS_METHOD (tty, delete_device); +#ifdef SIGWINCH + CONSOLE_HAS_METHOD (tty, asynch_device_change); +#endif /* SIGWINCH */ + CONSOLE_HAS_METHOD (tty, device_system_metrics); +} + +void +init_device_tty (void) +{ +#ifdef SIGWINCH + if (initialized && !noninteractive) + signal (SIGWINCH, tty_device_size_change_signal); +#endif /* SIGWINCH */ +}