428
+ − 1 /* TTY device functions.
+ − 2 Copyright (C) 1994, 1995 Board of Trustees, University of Illinois.
+ − 3 Copyright (C) 1994, 1995 Free Software Foundation, Inc.
+ − 4 Copyright (C) 1996 Ben Wing.
+ − 5
+ − 6 This file is part of XEmacs.
+ − 7
+ − 8 XEmacs is free software; you can redistribute it and/or modify it
+ − 9 under the terms of the GNU General Public License as published by the
+ − 10 Free Software Foundation; either version 2, or (at your option) any
+ − 11 later version.
+ − 12
+ − 13 XEmacs is distributed in the hope that it will be useful, but WITHOUT
+ − 14 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ − 15 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ − 16 for more details.
+ − 17
+ − 18 You should have received a copy of the GNU General Public License
+ − 19 along with XEmacs; see the file COPYING. If not, write to
+ − 20 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ − 21 Boston, MA 02111-1307, USA. */
+ − 22
+ − 23 /* Synched up with: Not in FSF. */
+ − 24
+ − 25 /* Authors: Ben Wing and Chuck Thompson. */
+ − 26
+ − 27 #include <config.h>
+ − 28 #include "lisp.h"
+ − 29
872
+ − 30 #include "device-impl.h"
428
+ − 31 #include "events.h"
+ − 32 #include "faces.h"
+ − 33 #include "frame.h"
+ − 34 #include "lstream.h"
+ − 35 #include "redisplay.h"
+ − 36 #include "sysdep.h"
+ − 37
872
+ − 38 #include "console-tty-impl.h"
800
+ − 39 #include "console-stream.h"
+ − 40
558
+ − 41 #include "sysfile.h"
428
+ − 42 #include "syssignal.h" /* for SIGWINCH */
+ − 43
+ − 44 Lisp_Object Qinit_pre_tty_win, Qinit_post_tty_win;
+ − 45
+ − 46
3092
+ − 47 #ifdef NEW_GC
+ − 48 static const struct memory_description tty_device_data_description_1 [] = {
+ − 49 { XD_END }
+ − 50 };
+ − 51
+ − 52 DEFINE_LRECORD_IMPLEMENTATION ("tty-device", tty_device,
+ − 53 1, /*dumpable-flag*/
+ − 54 0, 0, 0, 0, 0,
+ − 55 tty_device_data_description_1,
+ − 56 Lisp_Tty_Device);
+ − 57 #endif /* NEW_GC */
+ − 58
428
+ − 59 static void
+ − 60 allocate_tty_device_struct (struct device *d)
+ − 61 {
3092
+ − 62 #ifdef NEW_GC
+ − 63 d->device_data = alloc_lrecord_type (struct tty_device, &lrecord_tty_device);
+ − 64 #else /* not NEW_GC */
428
+ − 65 d->device_data = xnew_and_zero (struct tty_device);
3092
+ − 66 #endif /* not NEW_GC */
428
+ − 67 }
+ − 68
+ − 69 static void
2286
+ − 70 tty_init_device (struct device *d, Lisp_Object UNUSED (props))
428
+ − 71 {
+ − 72 struct console *con = XCONSOLE (DEVICE_CONSOLE (d));
+ − 73 Lisp_Object terminal_type = CONSOLE_TTY_DATA (con)->terminal_type;
+ − 74
+ − 75 DEVICE_INFD (d) = CONSOLE_TTY_DATA (con)->infd;
+ − 76 DEVICE_OUTFD (d) = CONSOLE_TTY_DATA (con)->outfd;
+ − 77
+ − 78 allocate_tty_device_struct (d);
+ − 79 init_baud_rate (d);
+ − 80
+ − 81 switch (init_tty_for_redisplay (d, (char *) XSTRING_DATA (terminal_type)))
+ − 82 {
+ − 83 #if 0
+ − 84 case TTY_UNABLE_OPEN_DATABASE:
+ − 85 suppress_early_error_handler_backtrace = 1;
563
+ − 86 signal_error (Qio_error, "Can't access terminal information database", Qunbound);
428
+ − 87 break;
+ − 88 #endif
+ − 89 case TTY_TYPE_UNDEFINED:
+ − 90 suppress_early_error_handler_backtrace = 1;
563
+ − 91 signal_error (Qio_error, "Terminal type undefined (or can't access database?)",
+ − 92 terminal_type);
428
+ − 93 break;
+ − 94 case TTY_TYPE_INSUFFICIENT:
+ − 95 suppress_early_error_handler_backtrace = 1;
563
+ − 96 signal_error (Qio_error, "Terminal type not powerful enough to run Emacs",
+ − 97 terminal_type);
428
+ − 98 break;
+ − 99 case TTY_SIZE_UNSPECIFIED:
+ − 100 suppress_early_error_handler_backtrace = 1;
563
+ − 101 signal_error (Qio_error, "Can't determine window size of terminal", Qunbound);
428
+ − 102 break;
+ − 103 case TTY_INIT_SUCCESS:
+ − 104 break;
+ − 105 default:
2500
+ − 106 ABORT ();
428
+ − 107 }
+ − 108
+ − 109 init_one_device (d);
+ − 110
+ − 111 /* Run part of the elisp side of the TTY device initialization.
+ − 112 The post-init is run in the tty_after_init_frame() method. */
+ − 113 call0 (Qinit_pre_tty_win);
+ − 114 }
+ − 115
3092
+ − 116 #ifndef NEW_GC
428
+ − 117 static void
+ − 118 free_tty_device_struct (struct device *d)
+ − 119 {
1726
+ − 120 if (d->device_data)
+ − 121 xfree (d->device_data, void *);
428
+ − 122 }
+ − 123
+ − 124 static void
+ − 125 tty_delete_device (struct device *d)
+ − 126 {
+ − 127 free_tty_device_struct (d);
+ − 128 }
3092
+ − 129 #endif /* not NEW_GC */
428
+ − 130
+ − 131 #ifdef SIGWINCH
+ − 132
+ − 133 static SIGTYPE
2286
+ − 134 tty_device_size_change_signal (int UNUSED (signo))
428
+ − 135 {
+ − 136 int old_errno = errno;
+ − 137 asynch_device_change_pending++;
+ − 138 #ifdef HAVE_UNIXOID_EVENT_LOOP
+ − 139 signal_fake_event ();
+ − 140 #endif
+ − 141 EMACS_REESTABLISH_SIGNAL (SIGWINCH, tty_device_size_change_signal);
+ − 142 errno = old_errno;
+ − 143 SIGRETURN;
+ − 144 }
+ − 145
+ − 146 /* frame_change_signal does nothing but set a flag that it was called.
+ − 147 When redisplay is called, it will notice that the flag is set and
+ − 148 call handle_pending_device_size_change to do the actual work. */
+ − 149 static void
+ − 150 tty_asynch_device_change (void)
+ − 151 {
+ − 152 Lisp_Object devcons, concons;
+ − 153
+ − 154 DEVICE_LOOP_NO_BREAK (devcons, concons)
+ − 155 {
+ − 156 int width, height;
+ − 157 Lisp_Object tail;
+ − 158 struct device *d = XDEVICE (XCAR (devcons));
+ − 159 struct console *con = XCONSOLE (DEVICE_CONSOLE (d));
+ − 160
+ − 161 if (!DEVICE_TTY_P (d))
+ − 162 continue;
+ − 163
+ − 164 get_tty_device_size (d, &width, &height);
+ − 165 if (width > 0 && height > 0
+ − 166 && (CONSOLE_TTY_DATA (con)->width != width
+ − 167 || CONSOLE_TTY_DATA (con)->height != height))
+ − 168 {
+ − 169 CONSOLE_TTY_DATA (con)->width = width;
+ − 170 CONSOLE_TTY_DATA (con)->height = height;
+ − 171
+ − 172 for (tail = DEVICE_FRAME_LIST (d);
+ − 173 !NILP (tail);
+ − 174 tail = XCDR (tail))
+ − 175 {
+ − 176 struct frame *f = XFRAME (XCAR (tail));
+ − 177
+ − 178 /* We know the frame is tty because we made sure that the
+ − 179 device is tty. */
+ − 180 change_frame_size (f, height, width, 1);
+ − 181 }
+ − 182 }
+ − 183 }
+ − 184 }
+ − 185
+ − 186 #endif /* SIGWINCH */
+ − 187
+ − 188 static Lisp_Object
+ − 189 tty_device_system_metrics (struct device *d,
+ − 190 enum device_metrics m)
+ − 191 {
+ − 192 struct console *con = XCONSOLE (DEVICE_CONSOLE (d));
+ − 193 switch (m)
+ − 194 {
+ − 195 case DM_size_device:
+ − 196 return Fcons (make_int (CONSOLE_TTY_DATA (con)->width),
+ − 197 make_int (CONSOLE_TTY_DATA (con)->height));
+ − 198 default: /* No such device metric property for TTY devices */
+ − 199 return Qunbound;
+ − 200 }
+ − 201 }
+ − 202
+ − 203 /************************************************************************/
+ − 204 /* initialization */
+ − 205 /************************************************************************/
+ − 206
+ − 207 void
+ − 208 syms_of_device_tty (void)
+ − 209 {
3092
+ − 210 #ifdef NEW_GC
+ − 211 INIT_LRECORD_IMPLEMENTATION (tty_device);
+ − 212 #endif /* NEW_GC */
+ − 213
563
+ − 214 DEFSYMBOL (Qinit_pre_tty_win);
+ − 215 DEFSYMBOL (Qinit_post_tty_win);
428
+ − 216 }
+ − 217
+ − 218 void
+ − 219 console_type_create_device_tty (void)
+ − 220 {
+ − 221 /* device methods */
+ − 222 CONSOLE_HAS_METHOD (tty, init_device);
3092
+ − 223 #ifndef NEW_GC
428
+ − 224 CONSOLE_HAS_METHOD (tty, delete_device);
3092
+ − 225 #endif /* not NEW_GC */
428
+ − 226 #ifdef SIGWINCH
+ − 227 CONSOLE_HAS_METHOD (tty, asynch_device_change);
+ − 228 #endif /* SIGWINCH */
+ − 229 CONSOLE_HAS_METHOD (tty, device_system_metrics);
+ − 230 }
+ − 231
+ − 232 void
+ − 233 init_device_tty (void)
+ − 234 {
+ − 235 #ifdef SIGWINCH
+ − 236 if (initialized && !noninteractive)
613
+ − 237 EMACS_SIGNAL (SIGWINCH, tty_device_size_change_signal);
428
+ − 238 #endif /* SIGWINCH */
+ − 239 }