428
+ − 1 /* Stream device functions.
+ − 2 Copyright (C) 1995 Free Software Foundation, Inc.
1279
+ − 3 Copyright (C) 1996, 2001, 2002, 2003 Ben Wing.
428
+ − 4
+ − 5 This file is part of XEmacs.
+ − 6
+ − 7 XEmacs is free software; you can redistribute it and/or modify it
+ − 8 under the terms of the GNU General Public License as published by the
+ − 9 Free Software Foundation; either version 2, or (at your option) any
+ − 10 later version.
+ − 11
+ − 12 XEmacs is distributed in the hope that it will be useful, but WITHOUT
+ − 13 ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ − 14 FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
+ − 15 for more details.
+ − 16
+ − 17 You should have received a copy of the GNU General Public License
+ − 18 along with XEmacs; see the file COPYING. If not, write to
+ − 19 the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ − 20 Boston, MA 02111-1307, USA. */
+ − 21
+ − 22 /* Synched up with: Not in FSF. */
+ − 23
+ − 24 /* This file has been Mule-ized. */
+ − 25
+ − 26 /* Written by Ben Wing. */
+ − 27
+ − 28 #include <config.h>
+ − 29 #include "lisp.h"
+ − 30
872
+ − 31 #include "device-impl.h"
428
+ − 32 #include "events.h"
872
+ − 33 #include "frame-impl.h"
428
+ − 34 #include "redisplay.h"
+ − 35 #include "sysdep.h"
800
+ − 36 #include "window.h"
+ − 37
872
+ − 38 #include "console-stream-impl.h"
800
+ − 39 #include "console-tty.h"
+ − 40
428
+ − 41 #include "sysfile.h"
+ − 42
+ − 43 DEFINE_CONSOLE_TYPE (stream);
+ − 44
+ − 45 Lisp_Object Vterminal_console;
+ − 46 Lisp_Object Vterminal_device;
+ − 47 Lisp_Object Vterminal_frame;
+ − 48
+ − 49 Lisp_Object Vstdio_str;
+ − 50
1204
+ − 51 static const struct memory_description stream_console_data_description_1 [] = {
+ − 52 { XD_LISP_OBJECT, offsetof (struct stream_console, instream) },
+ − 53 { XD_END }
+ − 54 };
+ − 55
3092
+ − 56 #ifdef NEW_GC
+ − 57 DEFINE_LRECORD_IMPLEMENTATION ("stream-console", stream_console,
+ − 58 1, /*dumpable-flag*/
+ − 59 0, 0, 0, 0, 0,
+ − 60 stream_console_data_description_1,
+ − 61 Lisp_Stream_Console);
+ − 62 #else /* not NEW_GC */
1204
+ − 63 const struct sized_memory_description stream_console_data_description = {
+ − 64 sizeof (struct stream_console), stream_console_data_description_1
+ − 65 };
3092
+ − 66 #endif /* not NEW_GC */
1204
+ − 67
428
+ − 68 static void
2286
+ − 69 stream_init_console (struct console *con, Lisp_Object UNUSED (params))
428
+ − 70 {
+ − 71 Lisp_Object tty = CONSOLE_CONNECTION (con);
+ − 72 struct stream_console *stream_con;
+ − 73
3092
+ − 74 #ifdef NEW_GC
+ − 75 if (CONSOLE_STREAM_DATA (con) == NULL)
+ − 76 CONSOLE_STREAM_DATA (con) = alloc_lrecord_type (struct stream_console,
+ − 77 &lrecord_stream_console);
+ − 78 #else /* not NEW_GC */
428
+ − 79 if (CONSOLE_STREAM_DATA (con) == NULL)
1204
+ − 80 CONSOLE_STREAM_DATA (con) = xnew_and_zero (struct stream_console);
3092
+ − 81 #endif /* not NEW_GC */
428
+ − 82
+ − 83 stream_con = CONSOLE_STREAM_DATA (con);
+ − 84
1204
+ − 85 stream_con->instream = Qnil;
428
+ − 86
+ − 87 /* Open the specified console */
+ − 88 if (NILP (tty) || internal_equal (tty, Vstdio_str, 0))
+ − 89 {
+ − 90 stream_con->in = stdin;
+ − 91 stream_con->out = stdout;
+ − 92 stream_con->err = stderr;
+ − 93 }
+ − 94 else
+ − 95 {
+ − 96 CHECK_STRING (tty);
+ − 97 stream_con->in = stream_con->out = stream_con->err =
442
+ − 98 /* #### We don't currently do coding-system translation on
+ − 99 this descriptor. */
771
+ − 100 qxe_fopen (XSTRING_DATA (tty), READ_PLUS_TEXT);
428
+ − 101 if (!stream_con->in)
563
+ − 102 signal_error (Qio_error, "Unable to open tty", tty);
428
+ − 103 }
+ − 104 }
+ − 105
+ − 106 static void
2286
+ − 107 stream_init_device (struct device *d, Lisp_Object UNUSED (params))
428
+ − 108 {
+ − 109 struct console *con = XCONSOLE (DEVICE_CONSOLE (d));
+ − 110
+ − 111 DEVICE_INFD (d) = fileno (CONSOLE_STREAM_DATA (con)->in);
+ − 112 DEVICE_OUTFD (d) = fileno (CONSOLE_STREAM_DATA (con)->out);
+ − 113 init_baud_rate (d);
+ − 114 init_one_device (d);
+ − 115 }
+ − 116
+ − 117 static int
2286
+ − 118 stream_initially_selected_for_input (struct console *UNUSED (con))
428
+ − 119 {
+ − 120 return noninteractive && initialized;
+ − 121 }
+ − 122
+ − 123 extern int stdout_needs_newline;
+ − 124
+ − 125 static void
+ − 126 stream_delete_console (struct console *con)
+ − 127 {
+ − 128 struct stream_console *stream_con = CONSOLE_STREAM_DATA (con);
+ − 129 if (stream_con)
+ − 130 {
+ − 131 if (/* stream_con->needs_newline */
+ − 132 stdout_needs_newline) /* #### clean this up */
+ − 133 {
+ − 134 fputc ('\n', stream_con->out);
+ − 135 fflush (stream_con->out);
+ − 136 }
+ − 137 if (stream_con->in != stdin)
771
+ − 138 retry_fclose (stream_con->in);
428
+ − 139
3263
+ − 140 #ifndef NEW_GC
1726
+ − 141 xfree (stream_con, struct stream_console *);
3092
+ − 142 #endif /* not NEW_GC */
428
+ − 143 CONSOLE_STREAM_DATA (con) = NULL;
+ − 144 }
+ − 145 }
+ − 146
+ − 147 Lisp_Object
+ − 148 stream_semi_canonicalize_console_connection (Lisp_Object connection,
2286
+ − 149 Error_Behavior UNUSED (errb))
428
+ − 150 {
+ − 151 return NILP (connection) ? Vstdio_str : connection;
+ − 152 }
+ − 153
+ − 154 Lisp_Object
+ − 155 stream_canonicalize_console_connection (Lisp_Object connection,
578
+ − 156 Error_Behavior errb)
428
+ − 157 {
+ − 158 if (NILP (connection) || internal_equal (connection, Vstdio_str, 0))
+ − 159 return Vstdio_str;
+ − 160
+ − 161 if (!ERRB_EQ (errb, ERROR_ME))
+ − 162 {
+ − 163 if (!STRINGP (connection))
+ − 164 return Qunbound;
+ − 165 }
+ − 166 else
+ − 167 CHECK_STRING (connection);
+ − 168
+ − 169 return Ffile_truename (connection, Qnil);
+ − 170 }
+ − 171
+ − 172 Lisp_Object
+ − 173 stream_semi_canonicalize_device_connection (Lisp_Object connection,
578
+ − 174 Error_Behavior errb)
428
+ − 175 {
+ − 176 return stream_semi_canonicalize_console_connection (connection, errb);
+ − 177 }
+ − 178
+ − 179 Lisp_Object
+ − 180 stream_canonicalize_device_connection (Lisp_Object connection,
578
+ − 181 Error_Behavior errb)
428
+ − 182 {
+ − 183 return stream_canonicalize_console_connection (connection, errb);
+ − 184 }
+ − 185
+ − 186
+ − 187 static void
2286
+ − 188 stream_init_frame_1 (struct frame *f, Lisp_Object UNUSED (props),
771
+ − 189 int frame_name_is_defaulted)
428
+ − 190 {
+ − 191 #if 0
+ − 192 struct device *d = XDEVICE (FRAME_DEVICE (f));
+ − 193 if (!NILP (DEVICE_FRAME_LIST (d)))
563
+ − 194 invalid_operation ("Only one frame allowed on stream devices", Qunbound);
428
+ − 195 #endif
771
+ − 196 if (frame_name_is_defaulted)
+ − 197 f->name = build_string ("stream");
428
+ − 198 f->height = 80;
+ − 199 f->width = 24;
+ − 200 f->visible = 0; /* so redisplay doesn't try to do anything */
+ − 201 }
+ − 202
+ − 203
+ − 204 static int
2286
+ − 205 stream_text_width (struct frame *UNUSED (f),
+ − 206 struct face_cachel *UNUSED (cachel),
+ − 207 const Ichar *UNUSED (str), Charcount len)
428
+ − 208 {
+ − 209 return len;
+ − 210 }
+ − 211
+ − 212 static int
2286
+ − 213 stream_left_margin_width (struct window *UNUSED (w))
428
+ − 214 {
+ − 215 return 0;
+ − 216 }
+ − 217
+ − 218 static int
2286
+ − 219 stream_right_margin_width (struct window *UNUSED (w))
428
+ − 220 {
+ − 221 return 0;
+ − 222 }
+ − 223
+ − 224 static int
+ − 225 stream_divider_height (void)
+ − 226 {
+ − 227 return 1;
+ − 228 }
+ − 229
+ − 230 static int
+ − 231 stream_eol_cursor_width (void)
+ − 232 {
+ − 233 return 1;
+ − 234 }
+ − 235
1279
+ − 236 /* We used to try and check for redisplaying on stream devices (e.g. in
+ − 237 redisplay_device(), and beg out if so. However, we didn't always manage
+ − 238 completely. Now we do manage completely, and to verify this we abort if
+ − 239 we try to display a stream device. This might fix some crashes I've
+ − 240 been getting in pdump -- the only difference between crash and non-crash
+ − 241 is a few changes to the redisplay critical-section handling. */
+ − 242
+ − 243 static void
2286
+ − 244 stream_window_output_begin (struct window *UNUSED (w))
1279
+ − 245 {
2500
+ − 246 ABORT ();
1279
+ − 247 }
+ − 248
+ − 249 static void
2286
+ − 250 stream_window_output_end (struct window *UNUSED (w))
1279
+ − 251 {
2500
+ − 252 ABORT ();
1279
+ − 253 }
+ − 254
+ − 255 static void
2286
+ − 256 stream_frame_output_begin (struct frame *UNUSED (f))
1279
+ − 257 {
2500
+ − 258 ABORT ();
1279
+ − 259 }
+ − 260
+ − 261 static void
2286
+ − 262 stream_frame_output_end (struct frame *UNUSED (f))
1279
+ − 263 {
2500
+ − 264 ABORT ();
1279
+ − 265 }
+ − 266
428
+ − 267 static void
2286
+ − 268 stream_output_display_block (struct window *UNUSED (w),
+ − 269 struct display_line *UNUSED (dl),
+ − 270 int UNUSED (block), int UNUSED (start),
+ − 271 int UNUSED (end), int UNUSED (start_pixpos),
+ − 272 int UNUSED (cursor_start),
+ − 273 int UNUSED (cursor_width),
+ − 274 int UNUSED (cursor_height))
428
+ − 275 {
2500
+ − 276 ABORT ();
428
+ − 277 }
+ − 278
+ − 279 static void
2286
+ − 280 stream_clear_region (Lisp_Object UNUSED (window), struct device* UNUSED (d),
+ − 281 struct frame *UNUSED (f), face_index UNUSED (findex),
+ − 282 int UNUSED (x), int UNUSED (y), int UNUSED (width),
+ − 283 int UNUSED (height), Lisp_Object UNUSED (fcolor),
+ − 284 Lisp_Object UNUSED (bcolor),
+ − 285 Lisp_Object UNUSED (background_pixmap))
428
+ − 286 {
2500
+ − 287 ABORT ();
428
+ − 288 }
+ − 289
+ − 290 static int
2286
+ − 291 stream_flash (struct device *UNUSED (d))
428
+ − 292 {
+ − 293 return 0; /* sorry can't do it */
+ − 294 }
+ − 295
+ − 296 static void
2286
+ − 297 stream_ring_bell (struct device *d, int UNUSED (volume), int UNUSED (pitch),
+ − 298 int UNUSED (duration))
428
+ − 299 {
+ − 300 struct console *c = XCONSOLE (DEVICE_CONSOLE (d));
826
+ − 301 /* Don't output ^G when not a TTY -- in particular, under MS Windows, ^G
+ − 302 is interpreted as bell by the console, but not when running under
+ − 303 VC++. Probably this would be the same under Unix. */
+ − 304 if (isatty (fileno (CONSOLE_STREAM_DATA (c)->out)))
+ − 305 {
+ − 306 fputc (07, CONSOLE_STREAM_DATA (c)->out);
+ − 307 fflush (CONSOLE_STREAM_DATA (c)->out);
+ − 308 }
428
+ − 309 }
+ − 310
+ − 311
+ − 312 /************************************************************************/
+ − 313 /* initialization */
+ − 314 /************************************************************************/
+ − 315
+ − 316 void
+ − 317 console_type_create_stream (void)
+ − 318 {
+ − 319 INITIALIZE_CONSOLE_TYPE (stream, "stream", "console-stream-p");
+ − 320
+ − 321 /* console methods */
+ − 322 CONSOLE_HAS_METHOD (stream, init_console);
+ − 323 CONSOLE_HAS_METHOD (stream, initially_selected_for_input);
+ − 324 CONSOLE_HAS_METHOD (stream, delete_console);
+ − 325 CONSOLE_HAS_METHOD (stream, canonicalize_console_connection);
+ − 326 CONSOLE_HAS_METHOD (stream, canonicalize_device_connection);
+ − 327 CONSOLE_HAS_METHOD (stream, semi_canonicalize_console_connection);
+ − 328 CONSOLE_HAS_METHOD (stream, semi_canonicalize_device_connection);
+ − 329
+ − 330 /* device methods */
+ − 331 CONSOLE_HAS_METHOD (stream, init_device);
+ − 332
+ − 333 /* frame methods */
+ − 334 CONSOLE_HAS_METHOD (stream, init_frame_1);
+ − 335
+ − 336 /* redisplay methods */
1279
+ − 337 CONSOLE_HAS_METHOD (stream, text_width);
428
+ − 338 CONSOLE_HAS_METHOD (stream, left_margin_width);
+ − 339 CONSOLE_HAS_METHOD (stream, right_margin_width);
+ − 340 CONSOLE_HAS_METHOD (stream, divider_height);
+ − 341 CONSOLE_HAS_METHOD (stream, eol_cursor_width);
1279
+ − 342 CONSOLE_HAS_METHOD (stream, window_output_begin);
+ − 343 CONSOLE_HAS_METHOD (stream, window_output_end);
+ − 344 CONSOLE_HAS_METHOD (stream, frame_output_begin);
+ − 345 CONSOLE_HAS_METHOD (stream, frame_output_end);
+ − 346 CONSOLE_HAS_METHOD (stream, output_display_block);
428
+ − 347 CONSOLE_HAS_METHOD (stream, clear_region);
+ − 348 CONSOLE_HAS_METHOD (stream, flash);
+ − 349 CONSOLE_HAS_METHOD (stream, ring_bell);
+ − 350 }
+ − 351
+ − 352 void
+ − 353 reinit_console_type_create_stream (void)
+ − 354 {
+ − 355 REINITIALIZE_CONSOLE_TYPE (stream);
+ − 356 }
+ − 357
+ − 358 void
+ − 359 vars_of_console_stream (void)
+ − 360 {
+ − 361 DEFVAR_LISP ("terminal-console", &Vterminal_console /*
444
+ − 362 The initial console object, which represents XEmacs' stdout.
428
+ − 363 */ );
+ − 364 Vterminal_console = Qnil;
+ − 365
+ − 366 DEFVAR_LISP ("terminal-device", &Vterminal_device /*
444
+ − 367 The initial device object, which represents XEmacs' stdout.
428
+ − 368 */ );
+ − 369 Vterminal_device = Qnil;
+ − 370
+ − 371 DEFVAR_LISP ("terminal-frame", &Vterminal_frame /*
444
+ − 372 The initial frame object, which represents XEmacs' stdout.
428
+ − 373 */ );
+ − 374 Vterminal_frame = Qnil;
+ − 375
+ − 376 /* Moved from console-tty.c */
+ − 377 Vstdio_str = build_string ("stdio");
+ − 378 staticpro (&Vstdio_str);
+ − 379 }
+ − 380
+ − 381 #ifndef PDUMP
+ − 382 void
2342
+ − 383 init_console_stream (int UNUSED (reinit))
428
+ − 384 {
+ − 385 /* This function can GC */
+ − 386 if (!initialized)
+ − 387 {
+ − 388 Vterminal_device = Fmake_device (Qstream, Qnil, Qnil);
+ − 389 Vterminal_console = Fdevice_console (Vterminal_device);
+ − 390 Vterminal_frame = Fmake_frame (Qnil, Vterminal_device);
+ − 391 minibuf_window = XFRAME (Vterminal_frame)->minibuffer_window;
+ − 392 }
+ − 393 else
+ − 394 {
+ − 395 /* Re-initialize the FILE fields of the console. */
+ − 396 stream_init_console (XCONSOLE (Vterminal_console), Qnil);
+ − 397 if (noninteractive)
+ − 398 event_stream_select_console (XCONSOLE (Vterminal_console));
+ − 399 }
+ − 400 }
+ − 401
+ − 402 #else
+ − 403
+ − 404 void
442
+ − 405 init_console_stream (int reinit)
428
+ − 406 {
+ − 407 /* This function can GC */
442
+ − 408 if (!reinit)
+ − 409 {
+ − 410 Vterminal_device = Fmake_device (Qstream, Qnil, Qnil);
+ − 411 Vterminal_console = Fdevice_console (Vterminal_device);
+ − 412 Vterminal_frame = Fmake_frame (Qnil, Vterminal_device);
+ − 413 minibuf_window = XFRAME (Vterminal_frame)->minibuffer_window;
+ − 414 }
428
+ − 415 if (initialized)
+ − 416 {
+ − 417 stream_init_console (XCONSOLE (Vterminal_console), Qnil);
+ − 418 if (noninteractive)
+ − 419 event_stream_select_console (XCONSOLE (Vterminal_console));
+ − 420 }
+ − 421 }
+ − 422 #endif