XEmacs 21.2.28 "Hermes".
[chise/xemacs-chise.git.1] / src / device-tty.c
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
30 #include "console-tty.h"
31 #include "console-stream.h"
32 #include "events.h"
33 #include "faces.h"
34 #include "frame.h"
35 #include "lstream.h"
36 #include "redisplay.h"
37 #include "sysdep.h"
38
39 #include "syssignal.h" /* for SIGWINCH */
40
41 #include <errno.h>
42
43 Lisp_Object Qinit_pre_tty_win, Qinit_post_tty_win;
44
45 \f
46 static void
47 allocate_tty_device_struct (struct device *d)
48 {
49   d->device_data = xnew_and_zero (struct tty_device);
50 }
51
52 static void
53 tty_init_device (struct device *d, Lisp_Object props)
54 {
55   struct console *con = XCONSOLE (DEVICE_CONSOLE (d));
56   Lisp_Object terminal_type = CONSOLE_TTY_DATA (con)->terminal_type;
57
58   DEVICE_INFD (d) = CONSOLE_TTY_DATA (con)->infd;
59   DEVICE_OUTFD (d) = CONSOLE_TTY_DATA (con)->outfd;
60
61   allocate_tty_device_struct (d);
62   init_baud_rate (d);
63
64   switch (init_tty_for_redisplay (d, (char *) XSTRING_DATA (terminal_type)))
65     {
66 #if 0
67     case TTY_UNABLE_OPEN_DATABASE:
68       suppress_early_error_handler_backtrace = 1;
69       error ("Can't access terminal information database");
70       break;
71 #endif
72     case TTY_TYPE_UNDEFINED:
73       suppress_early_error_handler_backtrace = 1;
74       error ("Terminal type `%s' undefined (or can't access database?)",
75              XSTRING_DATA (terminal_type));
76       break;
77     case TTY_TYPE_INSUFFICIENT:
78       suppress_early_error_handler_backtrace = 1;
79       error ("Terminal type `%s' not powerful enough to run Emacs",
80              XSTRING_DATA (terminal_type));
81       break;
82     case TTY_SIZE_UNSPECIFIED:
83       suppress_early_error_handler_backtrace = 1;
84       error ("Can't determine window size of terminal");
85       break;
86     case TTY_INIT_SUCCESS:
87       break;
88     default:
89       abort ();
90     }
91
92   init_one_device (d);
93
94   /* Run part of the elisp side of the TTY device initialization.
95      The post-init is run in the tty_after_init_frame() method. */
96   call0 (Qinit_pre_tty_win);
97 }
98
99 static void
100 free_tty_device_struct (struct device *d)
101 {
102   struct tty_device *td = (struct tty_device *) d->device_data;
103   if (td)
104     xfree (td);
105 }
106
107 static void
108 tty_delete_device (struct device *d)
109 {
110   free_tty_device_struct (d);
111 }
112
113 #ifdef SIGWINCH
114
115 static SIGTYPE
116 tty_device_size_change_signal (int signo)
117 {
118   int old_errno = errno;
119   asynch_device_change_pending++;
120 #ifdef HAVE_UNIXOID_EVENT_LOOP
121   signal_fake_event ();
122 #endif
123   EMACS_REESTABLISH_SIGNAL (SIGWINCH, tty_device_size_change_signal);
124   errno = old_errno;
125   SIGRETURN;
126 }
127
128 /* frame_change_signal does nothing but set a flag that it was called.
129    When redisplay is called, it will notice that the flag is set and
130    call handle_pending_device_size_change to do the actual work. */
131 static void
132 tty_asynch_device_change (void)
133 {
134   Lisp_Object devcons, concons;
135
136   DEVICE_LOOP_NO_BREAK (devcons, concons)
137     {
138       int width, height;
139       Lisp_Object tail;
140       struct device *d = XDEVICE (XCAR (devcons));
141       struct console *con = XCONSOLE (DEVICE_CONSOLE (d));
142
143       if (!DEVICE_TTY_P (d))
144         continue;
145
146       get_tty_device_size (d, &width, &height);
147       if (width > 0 && height > 0
148           && (CONSOLE_TTY_DATA (con)->width != width
149               || CONSOLE_TTY_DATA (con)->height != height))
150         {
151           CONSOLE_TTY_DATA (con)->width = width;
152           CONSOLE_TTY_DATA (con)->height = height;
153
154           for (tail = DEVICE_FRAME_LIST (d);
155                !NILP (tail);
156                tail = XCDR (tail))
157             {
158               struct frame *f = XFRAME (XCAR (tail));
159
160               /* We know the frame is tty because we made sure that the
161                  device is tty. */
162               change_frame_size (f, height, width, 1);
163             }
164         }
165     }
166 }
167
168 #endif /* SIGWINCH */
169
170 static Lisp_Object
171 tty_device_system_metrics (struct device *d,
172                            enum device_metrics m)
173 {
174   struct console *con = XCONSOLE (DEVICE_CONSOLE (d));
175   switch (m)
176     {
177     case DM_size_device:
178       return Fcons (make_int (CONSOLE_TTY_DATA (con)->width),
179                     make_int (CONSOLE_TTY_DATA (con)->height));
180     default: /* No such device metric property for TTY devices */
181       return Qunbound;
182     }
183 }
184 \f
185 /************************************************************************/
186 /*                            initialization                            */
187 /************************************************************************/
188
189 void
190 syms_of_device_tty (void)
191 {
192   defsymbol (&Qinit_pre_tty_win, "init-pre-tty-win");
193   defsymbol (&Qinit_post_tty_win, "init-post-tty-win");
194 }
195
196 void
197 console_type_create_device_tty (void)
198 {
199   /* device methods */
200   CONSOLE_HAS_METHOD (tty, init_device);
201   CONSOLE_HAS_METHOD (tty, delete_device);
202 #ifdef SIGWINCH
203   CONSOLE_HAS_METHOD (tty, asynch_device_change);
204 #endif /* SIGWINCH */
205   CONSOLE_HAS_METHOD (tty, device_system_metrics);
206 }
207
208 void
209 init_device_tty (void)
210 {
211 #ifdef SIGWINCH
212   if (initialized && !noninteractive)
213     signal (SIGWINCH, tty_device_size_change_signal);
214 #endif /* SIGWINCH */
215 }