Initial git import
[sxemacs] / src / ui / console-stream.c
1 /* Stream device functions.
2    Copyright (C) 1995 Free Software Foundation, Inc.
3    Copyright (C) 1996 Ben Wing.
4
5 This file is part of SXEmacs
6
7 SXEmacs is free software: you can redistribute it and/or modify
8 it under the terms of the GNU General Public License as published by
9 the Free Software Foundation, either version 3 of the License, or
10 (at your option) any later version.
11
12 SXEmacs is distributed in the hope that it will be useful,
13 but WITHOUT ANY WARRANTY; without even the implied warranty of
14 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
15 GNU General Public License for more details.
16
17 You should have received a copy of the GNU General Public License
18 along with this program.  If not, see <http://www.gnu.org/licenses/>. */
19
20
21 /* Synched up with: Not in FSF. */
22
23 /* This file has been Mule-ized. */
24
25 /* Written by Ben Wing. */
26
27 #include <config.h>
28 #include "lisp.h"
29
30 #include "console-stream.h"
31 #include "events/events.h"
32 #include "frame.h"
33 #include "redisplay.h"
34 #include "sysdep.h"
35 #include "sysfile.h"
36 #include "window.h"
37
38 DEFINE_CONSOLE_TYPE(stream);
39
40 Lisp_Object Vterminal_console;
41 Lisp_Object Vterminal_device;
42 Lisp_Object Vterminal_frame;
43
44 Lisp_Object Vstdio_str;
45
46 static void stream_init_console(struct console *con, Lisp_Object params)
47 {
48         Lisp_Object tty = CONSOLE_CONNECTION(con);
49         struct stream_console *stream_con;
50
51         if (CONSOLE_STREAM_DATA(con) == NULL) {
52                 CONSOLE_DATA(con) = xnew(struct stream_console);
53         }
54         stream_con = CONSOLE_STREAM_DATA(con);
55
56         stream_con->needs_newline = 0;
57
58         /* Open the specified console */
59         if (NILP(tty) || internal_equal(tty, Vstdio_str, 0)) {
60                 stream_con->in = stdin;
61                 stream_con->out = stdout;
62                 stream_con->err = stderr;
63         } else {
64                 CHECK_STRING(tty);
65                 stream_con->in = stream_con->out = stream_con->err =
66                     /* #### We don't currently do coding-system translation on
67                        this descriptor. */
68                     fopen((char *)XSTRING_DATA(tty), READ_PLUS_TEXT);
69                 if (!stream_con->in)
70                         error("Unable to open tty %s", XSTRING_DATA(tty));
71         }
72 }
73
74 static void stream_init_device(struct device *d, Lisp_Object params)
75 {
76         struct console *con = XCONSOLE(DEVICE_CONSOLE(d));
77
78         DEVICE_INFD(d) = fileno(CONSOLE_STREAM_DATA(con)->in);
79         DEVICE_OUTFD(d) = fileno(CONSOLE_STREAM_DATA(con)->out);
80         init_baud_rate(d);
81         init_one_device(d);
82 }
83
84 static int stream_initially_selected_for_input(struct console *con)
85 {
86         return noninteractive && initialized;
87 }
88
89 extern int stdout_needs_newline;
90
91 static void stream_delete_console(struct console *con)
92 {
93         struct stream_console *stream_con = CONSOLE_STREAM_DATA(con);
94         if (stream_con) {
95                 if (            /* stream_con->needs_newline */
96                            stdout_needs_newline) {      /* #### clean this up */
97                         fputc('\n', stream_con->out);
98                         fflush(stream_con->out);
99                 }
100                 if (stream_con->in != stdin)
101                         fclose(stream_con->in);
102
103                 xfree(stream_con);
104                 CONSOLE_DATA(con) = NULL;
105         }
106 }
107
108 Lisp_Object
109 stream_semi_canonicalize_console_connection(Lisp_Object connection,
110                                             Error_behavior errb)
111 {
112         return NILP(connection) ? Vstdio_str : connection;
113 }
114
115 Lisp_Object
116 stream_canonicalize_console_connection(Lisp_Object connection,
117                                        Error_behavior errb)
118 {
119         if (NILP(connection) || internal_equal(connection, Vstdio_str, 0))
120                 return Vstdio_str;
121
122         if (!ERRB_EQ(errb, ERROR_ME)) {
123                 if (!STRINGP(connection))
124                         return Qunbound;
125         } else
126                 CHECK_STRING(connection);
127
128         return Ffile_truename(connection, Qnil);
129 }
130
131 Lisp_Object
132 stream_semi_canonicalize_device_connection(Lisp_Object connection,
133                                            Error_behavior errb)
134 {
135         return stream_semi_canonicalize_console_connection(connection, errb);
136 }
137
138 Lisp_Object
139 stream_canonicalize_device_connection(Lisp_Object connection,
140                                       Error_behavior errb)
141 {
142         return stream_canonicalize_console_connection(connection, errb);
143 }
144 \f
145 static void stream_init_frame_1(struct frame *f, Lisp_Object props)
146 {
147 #if 0
148         struct device *d = XDEVICE(FRAME_DEVICE(f));
149         if (!NILP(DEVICE_FRAME_LIST(d)))
150                 error("Only one frame allowed on stream devices");
151 #endif
152         f->name = build_string("stream");
153         f->height = 80;
154         f->width = 24;
155         f->visible = 0;         /* so redisplay doesn't try to do anything */
156 }
157 \f
158 static int
159 stream_text_width(struct frame *f, struct face_cachel *cachel,
160                   const Emchar * str, Charcount len)
161 {
162         return len;
163 }
164
165 static int stream_left_margin_width(struct window *w)
166 {
167         return 0;
168 }
169
170 static int stream_right_margin_width(struct window *w)
171 {
172         return 0;
173 }
174
175 static int stream_divider_height(void)
176 {
177         return 1;
178 }
179
180 static int stream_eol_cursor_width(void)
181 {
182         return 1;
183 }
184
185 static void
186 stream_output_display_block(struct window *w, struct display_line *dl,
187                             int block, int start, int end,
188                             int start_pixpos, int cursor_start,
189                             int cursor_width, int cursor_height)
190 {
191 }
192
193 static void
194 stream_clear_region(Lisp_Object window, struct device *d, struct frame *f,
195                     face_index findex, int x, int y,
196                     int width, int height, Lisp_Object fcolor,
197                     Lisp_Object bcolor, Lisp_Object background_pixmap)
198 {
199 }
200
201 static int stream_flash(struct device *d)
202 {
203         return 0;               /* sorry can't do it */
204 }
205
206 static void
207 stream_ring_bell(struct device *d, int volume, int pitch, int duration)
208 {
209         struct console *c = XCONSOLE(DEVICE_CONSOLE(d));
210         fputc(07, CONSOLE_STREAM_DATA(c)->out);
211         fflush(CONSOLE_STREAM_DATA(c)->out);
212 }
213 \f
214 /************************************************************************/
215 /*                            initialization                            */
216 /************************************************************************/
217
218 void console_type_create_stream(void)
219 {
220         INITIALIZE_CONSOLE_TYPE(stream, "stream", "console-stream-p");
221
222         /* console methods */
223         CONSOLE_HAS_METHOD(stream, init_console);
224         CONSOLE_HAS_METHOD(stream, initially_selected_for_input);
225         CONSOLE_HAS_METHOD(stream, delete_console);
226         CONSOLE_HAS_METHOD(stream, canonicalize_console_connection);
227         CONSOLE_HAS_METHOD(stream, canonicalize_device_connection);
228         CONSOLE_HAS_METHOD(stream, semi_canonicalize_console_connection);
229         CONSOLE_HAS_METHOD(stream, semi_canonicalize_device_connection);
230
231         /* device methods */
232         CONSOLE_HAS_METHOD(stream, init_device);
233
234         /* frame methods */
235         CONSOLE_HAS_METHOD(stream, init_frame_1);
236
237         /* redisplay methods */
238         CONSOLE_HAS_METHOD(stream, left_margin_width);
239         CONSOLE_HAS_METHOD(stream, right_margin_width);
240         CONSOLE_HAS_METHOD(stream, text_width);
241         CONSOLE_HAS_METHOD(stream, output_display_block);
242         CONSOLE_HAS_METHOD(stream, divider_height);
243         CONSOLE_HAS_METHOD(stream, eol_cursor_width);
244         CONSOLE_HAS_METHOD(stream, clear_region);
245         CONSOLE_HAS_METHOD(stream, flash);
246         CONSOLE_HAS_METHOD(stream, ring_bell);
247 }
248
249 void reinit_console_type_create_stream(void)
250 {
251         REINITIALIZE_CONSOLE_TYPE(stream);
252 }
253
254 void vars_of_console_stream(void)
255 {
256         DEFVAR_LISP("terminal-console", &Vterminal_console      /*
257 The initial console object, which represents SXEmacs' stdout.
258                                                                  */ );
259         Vterminal_console = Qnil;
260
261         DEFVAR_LISP("terminal-device", &Vterminal_device        /*
262 The initial device object, which represents SXEmacs' stdout.
263                                                                  */ );
264         Vterminal_device = Qnil;
265
266         DEFVAR_LISP("terminal-frame", &Vterminal_frame  /*
267 The initial frame object, which represents SXEmacs' stdout.
268                                                          */ );
269         Vterminal_frame = Qnil;
270
271         /* Moved from console-tty.c */
272         Vstdio_str = build_string("stdio");
273         staticpro(&Vstdio_str);
274 }
275
276 #ifndef PDUMP
277 void init_console_stream(int reinit)
278 {
279         /* This function can GC */
280         if (!initialized) {
281                 Vterminal_device = Fmake_device(Qstream, Qnil, Qnil);
282                 Vterminal_console = Fdevice_console(Vterminal_device);
283                 Vterminal_frame = Fmake_frame(Qnil, Vterminal_device);
284                 minibuf_window = XFRAME(Vterminal_frame)->minibuffer_window;
285         } else {
286                 /* Re-initialize the FILE fields of the console. */
287                 stream_init_console(XCONSOLE(Vterminal_console), Qnil);
288                 if (noninteractive)
289                         event_stream_select_console(XCONSOLE
290                                                     (Vterminal_console));
291         }
292 }
293
294 #else
295
296 void init_console_stream(int reinit)
297 {
298         /* This function can GC */
299         if (!reinit) {
300                 Vterminal_device = Fmake_device(Qstream, Qnil, Qnil);
301                 Vterminal_console = Fdevice_console(Vterminal_device);
302                 Vterminal_frame = Fmake_frame(Qnil, Vterminal_device);
303                 minibuf_window = XFRAME(Vterminal_frame)->minibuffer_window;
304         }
305         if (initialized) {
306                 stream_init_console(XCONSOLE(Vterminal_console), Qnil);
307                 if (noninteractive)
308                         event_stream_select_console(XCONSOLE
309                                                     (Vterminal_console));
310         }
311 }
312 #endif