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