home *** CD-ROM | disk | FTP | other *** search
- /* Communication module for TTY terminals.
- Copyright (C) 1994, 1995 Board of Trustees, University of Illinois
-
- This file is part of XEmacs.
-
- XEmacs is free software; you can redistribute it and/or modify it
- under the terms of the GNU General Public License as published by the
- Free Software Foundation; either version 2, or (at your option) any
- later version.
-
- XEmacs is distributed in the hope that it will be useful, but WITHOUT
- ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
- FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
- for more details.
-
- You should have received a copy of the GNU General Public License
- along with XEmacs; see the file COPYING. If not, write to the Free
- Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */
-
- /* Synched up with: Divergent from FSF. */
-
- /* This file has been Mule-ized, but needs more work before it will
- compile with Mule support enabled. */
-
- /* Written by Chuck Thompson. */
-
- #include <config.h>
- #include "lisp.h"
-
- #include "buffer.h"
- #include "device.h"
- #include "device-tty.h"
- #include "events.h"
- #include "faces.h"
- #include "frame.h"
- #include "glyphs.h"
- #include "redisplay.h"
- #include "sysdep.h"
- #include "window.h"
-
- /* These headers #define all kinds of common words like "columns"...
- What a bunch of losers. If we were to include them, we'd have to
- include them last to prevent them from messing up our own header
- files (struct slot names, etc.). But it turns out that there are
- other conflicts as well on some systems, so screw it: we'll just
- re-declare the routines we use and assume the code in this file is
- invoking them correctly. */
- /* # include <curses.h> */
- /* # include <term.h> */
- extern int tgetent (CONST char *, CONST char *);
- extern int tgetflag (CONST char *);
- extern int tgetnum (CONST char *);
- extern char *tgetstr (CONST char *, char **);
- extern void tputs (CONST char *, int, void (*)(int));
- char *tparam (CONST char *string, char *outstring, int len, int arg1, int arg2,
- int arg3, int arg4, int arg5, int arg6, int arg7, int arg8,
- int arg9);
- #define OUTPUTN(d, a, n) \
- do { cmputc_device = d; tputs (a, n, cmputc); } while (0)
- #define OUTPUT1(d, a) OUTPUTN (d, a, 1)
- #define OUTPUTN_IF(d, a, n) \
- do { cmputc_device = d; if (a) tputs (a, n, cmputc); } while (0)
- #define OUTPUT1_IF(d, a) OUTPUTN_IF (d, a, 1)
-
- static void tty_output_string (struct window *w, struct display_line *dl,
- emchar_dynarr *buf, int xpos, face_index findex,
- int cursor);
- static void tty_turn_on_face (struct window *w, face_index findex);
- static void tty_turn_off_face (struct window *w, face_index findex);
-
- /*****************************************************************************
- tty_font_metric_info
-
- tty's don't have fonts (that we use at least), so this actually
- ignores the font argument and just returns some constants.
- ****************************************************************************/
- static void
- tty_font_metric_info (struct device *d, Lisp_Object font,
- struct font_metric_info *fm)
- {
- fm->width = 1;
- fm->height = 1;
- fm->ascent = 1;
- fm->descent = 0;
- fm->proportional = 0;
- }
-
- /*****************************************************************************
- tty_text_width
-
- tty's don't have fonts (that we use at least), so everything is
- considered to be fixed width. In other words, we just return len.
- ****************************************************************************/
- static int
- tty_text_width (struct window *w, Lisp_Object font, CONST Emchar *s,
- Charcount len)
- {
- #ifdef MULE
- /* !!####
-
- This might get more complicated. Some extended characters
- have a width of 2. */
- #endif
- return len;
- }
-
- /*****************************************************************************
- tty_divider_width
-
- Return the width of the vertical divider. This is a function because
- divider_width is a device method.
- ****************************************************************************/
- static int
- tty_divider_width (void)
- {
- return 1;
- }
-
- /*****************************************************************************
- tty_divider_height
-
- Return the width of the horizontal divider. This is a function
- because divider_height is a device method.
- ****************************************************************************/
- static int
- tty_divider_height (void)
- {
- return 1;
- }
-
- /*****************************************************************************
- tty_eol_cursor_width
-
- Return the width of the end-of-line cursor. This is a function
- because eol_cursor_width is a device method.
- ****************************************************************************/
- static int
- tty_eol_cursor_width (void)
- {
- return 1;
- }
-
- /*****************************************************************************
- tty_output_begin
-
- Perform any necessary initialization prior to an update.
- ****************************************************************************/
- #ifdef DEBUG_XEMACS
- void tty_output_begin (struct device *d);
- void
- #else
- static void
- #endif
- tty_output_begin (struct device *d)
- {
- /* Termcap requires this to be a global variable so we have to
- always set it for whatever tty device we are actually currently
- working with. */
- ospeed = DEVICE_TTY_DATA (d)->ospeed;
- }
-
- /*****************************************************************************
- tty_output_end
-
- Perform any necessary flushing of queues when an update has completed.
- ****************************************************************************/
- #ifdef DEBUG_XEMACS
- void tty_output_end (struct device *d);
- void
- #else
- static void
- #endif
- tty_output_end (struct device *d)
- {
- fflush (DEVICE_TTY_DATA (d)->outfd);
- }
-
- /*****************************************************************************
- tty_output_display_block
-
- Given a display line, a block number for that start line, output all
- runes between start and end in the specified display block.
- ****************************************************************************/
- static void
- tty_output_display_block (struct window *w, struct display_line *dl, int block,
- int start, int end, int start_pixpos,
- int cursor_start, int cursor_width,
- int cursor_height)
- {
- struct frame *f = XFRAME (w->frame);
- emchar_dynarr *buf = Dynarr_new (Emchar);
-
- struct display_block *db = Dynarr_atp (dl->display_blocks, block);
- rune_dynarr *rba = db->runes;
- struct rune *rb;
-
- int elt = start;
- face_index findex;
- int xpos;
-
- rb = Dynarr_atp (rba, elt);
-
- if (!rb)
- {
- /* Nothing to do so don't do anything. */
- return;
- }
- else
- {
- findex = rb->findex;
- xpos = rb->xpos;
- }
-
- if (end < 0)
- end = Dynarr_length (rba);
-
- Dynarr_reset (buf);
-
- while (elt < end && Dynarr_atp (rba, elt)->xpos < start_pixpos)
- {
- elt++;
- findex = Dynarr_atp (rba, elt)->findex;
- xpos = Dynarr_atp (rba, elt)->xpos;
- }
-
- while (elt < end)
- {
- rb = Dynarr_atp (rba, elt);
-
- if (rb->findex == findex && rb->type == CHAR && rb->object.ch != '\n'
- && rb->cursor_type != CURSOR_ON)
- {
- Dynarr_add (buf, rb->object.ch);
- elt++;
- }
- else
- {
- if (Dynarr_length (buf))
- {
- tty_output_string (w, dl, buf, xpos, findex, 0);
- xpos = rb->xpos;
- }
- Dynarr_reset (buf);
-
- if (rb->type == CHAR)
- {
- findex = rb->findex;
- xpos = rb->xpos;
-
- if (rb->object.ch == '\n')
- {
- /* Clear in case a cursor was formerly here. */
-
- Dynarr_add (buf, ' ');
- tty_output_string (w, dl, buf, rb->xpos, DEFAULT_INDEX, 0);
- Dynarr_reset (buf);
-
- cmgoto (f, dl->ypos - 1, rb->xpos);
-
- elt++;
- }
- else if (rb->cursor_type == CURSOR_ON)
- {
- /* There is not a distinct eol cursor on tty's. */
-
- Dynarr_add (buf, rb->object.ch);
- tty_output_string (w, dl, buf, xpos, findex, 0);
- Dynarr_reset (buf);
-
- cmgoto (f, dl->ypos - 1, xpos);
-
- xpos += rb->width;
- elt++;
- }
- }
- /* #### HLINE is actualy a little more complicated than this
- but at the moment it is only used to draw a turned off
- modeline and this will suffice for that. */
- else if (rb->type == BLANK || rb->type == HLINE)
- {
- Emchar ch_to_add;
- int size = rb->width;
-
- if (rb->type == BLANK)
- ch_to_add = ' ';
- else
- ch_to_add = '-';
-
- while (size--)
- Dynarr_add (buf, ch_to_add);
- tty_output_string (w, dl, buf, rb->xpos, findex, 0);
-
- if (xpos >= cursor_start
- && cursor_start < xpos + Dynarr_length (buf))
- {
- cmgoto (f, dl->ypos - 1, cursor_start);
- }
-
- Dynarr_reset (buf);
-
- elt++;
- if (elt < end)
- {
- rb = Dynarr_atp (rba, elt);
-
- findex = rb->findex;
- xpos = rb->xpos;
- }
- }
- else if (rb->type == DGLYPH)
- {
- Lisp_Object window;
- Lisp_Object instance;
-
- XSETWINDOW (window, w);
- instance = glyph_image_instance (rb->object.dglyph.glyph,
- window, 1);
-
- switch (XIMAGE_INSTANCE_TYPE (instance))
- {
- case IMAGE_TEXT:
- {
- /* #### This is way losing. See the comment in
- add_glyph_rune(). */
- #ifdef MULE
- /* lose; */
- /* !!#### Chuck, you need to lower this stuff
- to the device-independent level. */
- Dynarr_add (buf, 'l');
- Dynarr_add (buf, 'o');
- Dynarr_add (buf, 's');
- Dynarr_add (buf, 'e');
- #else
- Bytecount lossage;
- Lisp_Object string =
- XIMAGE_INSTANCE_TEXT_STRING (instance);
-
- for (lossage = 0;
- lossage < string_length (XSTRING (string));
- lossage++)
- {
- if (lossage >= rb->object.dglyph.xoffset)
- Dynarr_add (buf,
- (Emchar) string_byte (XSTRING (string),
- lossage));
- }
-
- tty_output_string (w, dl, buf, xpos, findex, 0);
-
- if (xpos >= cursor_start
- && cursor_start < xpos + Dynarr_length (buf))
- {
- cmgoto (f, dl->ypos - 1, cursor_start);
- }
-
- Dynarr_reset (buf);
- #endif
- }
- break;
-
- case IMAGE_MONO_PIXMAP:
- case IMAGE_COLOR_PIXMAP:
- case IMAGE_SUBWINDOW:
- /* just do nothing here */
- break;
-
- case IMAGE_CURSOR:
- abort ();
-
- case IMAGE_NOTHING:
- /* nothing is as nothing does */
- break;
-
- default:
- abort ();
- }
-
- xpos += rb->width;
- elt++;
- }
- else
- abort ();
- }
- }
-
- if (Dynarr_length (buf))
- tty_output_string (w, dl, buf, xpos, findex, 0);
- Dynarr_free (buf);
-
- }
-
- /*****************************************************************************
- tty_output_vertical_divider
-
- Draw a vertical divider down the left side of the given window.
- ****************************************************************************/
- static void
- tty_output_vertical_divider (struct window *w, int clear)
- {
- struct frame *f = XFRAME (w->frame);
- struct device *d = XDEVICE (f->device);
- int line;
- int y1 = WINDOW_TEXT_TOP (w);
- int y2 = WINDOW_TEXT_BOTTOM (w);
-
- for (line = y1; line < y2; line++)
- {
- cmgoto (f, line, WINDOW_TEXT_LEFT (w) - 1);
- fputc ('|', DEVICE_TTY_DATA (d)->outfd);
- TTY_INC_CURSOR_X (d, 1);
- }
-
- /* Draw the divider in the modeline. */
- cmgoto (f, y2, WINDOW_TEXT_LEFT (w) - 1);
- tty_turn_on_face (w, MODELINE_INDEX);
- fputc ('|', DEVICE_TTY_DATA (d)->outfd);
- TTY_INC_CURSOR_X (d, 1);
- tty_turn_off_face (w, MODELINE_INDEX);
- }
-
- /*****************************************************************************
- tty_clear_to_window_end
-
- Clear the area between ypos1 and ypos2. Each margin area and the
- text area is handled separately since they may each have their own
- background color.
- ****************************************************************************/
- static void
- tty_clear_to_window_end (struct window *w, int ypos1, int ypos2)
- {
- struct frame *f = XFRAME (w->frame);
- struct device *d = XDEVICE (f->device);
- int x, width;
-
- x = WINDOW_TEXT_LEFT (w);
- width = WINDOW_TEXT_WIDTH (w);
-
- if (window_is_rightmost (w))
- {
- /* #### Optimize to use clr_to_eol function of tty if available, if
- the window is the entire width of the frame. */
- /* #### Is this actually an optimization? */
- int line;
- for (line = ypos1; line < ypos2; line++)
- {
- cmgoto (XFRAME (w->frame), line, x);
- OUTPUT1 (d, TTY_SE (d).clr_to_eol);
- }
- }
- else
- {
- Lisp_Object window;
-
- XSETWINDOW (window, w);
- tty_clear_region (window, DEFAULT_INDEX, x, ypos1, width, ypos2 - ypos1);
- }
- }
-
- /****************************************************************************
- tty_clear_region
-
- Clear the area in the box defined by the given parameters.
- ****************************************************************************/
- void
- tty_clear_region (Lisp_Object window, face_index findex, int x, int y,
- int width, int height)
- {
- struct window *w = XWINDOW (window);
- struct frame *f = XFRAME (w->frame);
- struct device *d = XDEVICE (f->device);
- int line;
-
- if (!width || !height)
- return;
-
- for (line = y; line < y + height; line++)
- {
- int col;
-
- cmgoto (f, line, x);
-
- if (window_is_leftmost (w)
- && window_is_rightmost (w)
- && TTY_SE (d).clr_to_eol)
- {
- OUTPUT1 (d, TTY_SE (d).clr_to_eol);
- }
- else
- {
- /* #### This should be static and adjusted as necessary. */
- /* #### Of course, this is all complete and utter crap. */
- bufbyte_dynarr *buf = Dynarr_new (Bufbyte);
-
- for (col = x; col < x + width; col++)
- Dynarr_add (buf, ' ');
- Dynarr_add (buf, '\0');
- fputs ((char *) Dynarr_atp (buf, 0), DEVICE_TTY_DATA (d)->outfd);
- TTY_INC_CURSOR_X (d, Dynarr_length (buf));
- Dynarr_free (buf);
- }
- }
-
- cmgoto (f, y, x);
- }
-
- /****************************************************************************
- tty_clear_frame
-
- Clear the entire frame.
- ****************************************************************************/
- static void
- tty_clear_frame (struct frame *f)
- {
- struct device *d = XDEVICE (f->device);
-
- if (TTY_SE (d).clr_frame)
- {
- OUTPUT1 (d, TTY_SE (d).clr_frame);
- #ifdef NOT_SURE
- FRAME_CURSOR_X (f) = 0;
- FRAME_CURSOR_Y (f) = 0;
- #endif
- }
- else
- {
- #ifdef NOT_SURE
- internal_cursor_to (f, 0, 0);
- clear_to_end (f);
- #else
- /* #### Not implemented. */
- fprintf (stderr, "Not yet.\n");
- #endif
- }
- }
-
- /*****************************************************************************
- tty_output_string
-
- Given a string and a starting position, output that string in the
- given face. If cursor is true, draw a cursor around the string.
- ****************************************************************************/
- static void
- tty_output_string (struct window *w, struct display_line *dl,
- emchar_dynarr *buf, int xpos, face_index findex, int cursor)
- {
- struct frame *f = XFRAME (w->frame);
- struct device *d = XDEVICE (f->device);
-
- /* First position the cursor. */
- cmgoto (f, dl->ypos - 1, xpos);
-
- /* Enable any face properties. */
- tty_turn_on_face (w, findex);
-
- /* Output the string. */
- #ifdef MULE
- {
- int i;
- Emchar *s = Dynarr_atp (buf, 0);
- int len = Dynarr_length (buf);
- char *one_byte_string = (char *) alloca (len + 1);
- for (i = 0; i < len; i++)
- {
- if (s[i] < 0x80)
- one_byte_string[i] = (char) s[i];
- else
- one_byte_string[i] = 'X';
- }
- one_byte_string[len] = '\0';
- /* #### Ben sez: need a level of abstraction here to handle
- the termscript and such.
-
- #### Ben also sez: don't some terminals need nulls outputted
- for proper timing? */
- fputs (one_byte_string, DEVICE_TTY_DATA (d)->outfd);
- TTY_INC_CURSOR_X (d, len);
- }
- /* !!#### presumably there are some escape sequences blah blah that can
- be issued to support kterms and such. Need to figure this out.
- I think actually that kterms support both JIS and EUC encoding
- (they can coexist at the same time because EUC uses entirely
- characters with the high-bit set and JIS uses entirely seven-bit
- characters). */
- #else
- {
- int i;
- Emchar *s = Dynarr_atp (buf, 0);
- int len = Dynarr_length (buf);
- char *one_byte_string = (char *) alloca (len + 1);
- for (i = 0; i < len; i++)
- {
- /* #### perhaps should use DASSERT? */
- assert (s[i] < 0x100);
- one_byte_string[i] = (char) s[i];
- }
- one_byte_string[len] = '\0';
- /* #### Ben sez: need a level of abstraction here to handle
- the termscript and such.
-
- #### Ben also sez: don't some terminals need nulls outputted
- for proper timing? */
- fputs (one_byte_string, DEVICE_TTY_DATA (d)->outfd);
- TTY_INC_CURSOR_X (d, len);
- }
- #endif
-
- /* Turn the face properties back off. */
- tty_turn_off_face (w, findex);
- }
-
- /*****************************************************************************
- tty_turn_on_face
-
- Turn on all set properties of the given face.
- ****************************************************************************/
- static void
- tty_turn_on_face (struct window *w, face_index findex)
- {
- struct frame *f = XFRAME (w->frame);
- struct device *d = XDEVICE (f->device);
-
- /* #### still need to handle color */
-
- if (FACE_CACHE_ELEMENT_HIGHLIGHT_P (w, findex))
- {
- OUTPUT1_IF (d, TTY_SD (d).turn_on_bold);
- }
-
- if (FACE_CACHE_ELEMENT_REVERSE_P (w, findex))
- {
- /* #### punt for now if standout mode is glitchy */
- if (!TTY_FLAGS (d).standout_width)
- {
- OUTPUT1_IF (d, TTY_SD (d).begin_standout);
- }
- }
-
- if (FACE_CACHE_ELEMENT_BLINKING_P (w, findex))
- {
- OUTPUT1_IF (d, TTY_SD (d).turn_on_blinking);
- }
-
- if (FACE_CACHE_ELEMENT_DIM_P (w, findex))
- {
- OUTPUT1_IF (d, TTY_SD (d).turn_on_dim);
- }
-
- if (FACE_CACHE_ELEMENT_UNDERLINE_P (w, findex))
- {
- /* #### punt for now if underline mode is glitchy */
- if (!TTY_FLAGS (d).underline_width)
- {
- OUTPUT1_IF (d, TTY_SD (d).begin_underline);
- }
- }
- }
-
- /*****************************************************************************
- tty_turn_off_face
-
- Turn off all set properties of the given face (revert to default
- face). We assume that tty_turn_on_face has been called for the given
- face so that it's properties are actually active.
- ****************************************************************************/
- static void
- tty_turn_off_face (struct window *w, face_index findex)
- {
- struct frame *f = XFRAME (w->frame);
- struct device *d = XDEVICE (f->device);
-
- if (FACE_CACHE_ELEMENT_UNDERLINE_P (w, findex))
- {
- /* #### punt for now if underline mode is glitchy */
- if (!TTY_FLAGS (d).underline_width)
- {
- OUTPUT1_IF (d, TTY_SD (d).end_underline);
- }
- }
-
- if (FACE_CACHE_ELEMENT_HIGHLIGHT_P (w, findex) ||
- FACE_CACHE_ELEMENT_BLINKING_P (w, findex) ||
- FACE_CACHE_ELEMENT_DIM_P (w, findex))
- {
- OUTPUT1_IF (d, TTY_SD (d).turn_off_attributes);
- }
-
- if (FACE_CACHE_ELEMENT_REVERSE_P (w, findex))
- {
- /* #### punt for now if standout mode is glitchy */
- if (!TTY_FLAGS (d).standout_width)
- {
- OUTPUT1_IF (d, TTY_SD (d).end_standout);
- }
- }
- }
-
- /*****************************************************************************
- set_tty_modes
-
- Sets up various parameters on tty modes.
- ****************************************************************************/
- void
- set_tty_modes (struct device *d)
- {
- if (!DEVICE_IS_TTY (d))
- return;
-
- OUTPUT1_IF (d, TTY_SD (d).init_motion);
- OUTPUT1_IF (d, TTY_SD (d).cursor_visible);
- OUTPUT1_IF (d, TTY_SD (d).keypad_on);
- }
-
- /*****************************************************************************
- reset_tty_modes
-
- Restore default state of tty.
- ****************************************************************************/
- void
- reset_tty_modes (struct device *d)
- {
- if (!DEVICE_IS_TTY (d))
- return;
-
- OUTPUT1_IF (d, TTY_SD (d).keypad_off);
- OUTPUT1_IF (d, TTY_SD (d).cursor_normal);
- OUTPUT1_IF (d, TTY_SD (d).end_motion);
- }
-
-
- /* #### Everything below here is old shit. It should either be moved
- up or removed. */
-
-
- /* FLAGS - these don't need to be device local since only one device
- can be being updated at a time. */
- static int insert_mode_on; /* nonzero if in insert mode */
- static int standout_mode_on; /* nonzero if in standout mode */
- static int underline_mode_on; /* nonzero if in underline mode */
- static int alternate_mode_on; /* nonzero if in alternate char set */
- static int attributes_on; /* nonzero if any attributes on */
-
- #ifdef NOT_YET
- static void
- turn_on_insert (struct frame *f)
- {
- struct device *d = XDEVICE (f->device);
-
- if (!insert_mode_on)
- OUTPUT1_IF (d, TTY_SE (d).begin_ins_mode);
- insert_mode_on = 1;
- }
-
- static void
- turn_off_insert (struct frame *f)
- {
- struct device *d = XDEVICE (f->device);
-
- if (insert_mode_on)
- OUTPUT1 (d, TTY_SE (d).end_ins_mode);
- insert_mode_on = 0;
- }
-
- static void
- internal_cursor_to (struct frame *f, int row, int col)
- {
- struct device *d = XDEVICE (f->device);
-
- if (!TTY_FLAGS (d).insert_mode_motion)
- turn_off_insert (f);
- if (!TTY_FLAGS (d).standout_motion)
- {
- turn_off_standout (f);
- turn_off_underline (f);
- turn_off_alternate (f);
- }
-
- cmgoto (f, row, col);
- }
-
- static void
- clear_to_end (struct frame *f)
- {
- struct device *d = XDEVICE (f->device);
-
- /* assumes cursor is already positioned */
- if (TTY_SE (d).clr_from_cursor)
- {
- OUTPUT1 (d, TTY_SE (d).clr_from_cursor);
- }
- else
- {
- int line = FRAME_CURSOR_Y (f);
-
- while (line < FRAME_HEIGHT (f))
- {
- internal_cursor_to (f, line, 0);
- OUTPUT1 (d, TTY_SE (d).clr_to_eol);
- }
- }
- }
- #endif /* 0 */
-
- #if 0
- /*
- * clear from last visible line on window to window end (presumably
- * the line above window's modeline
- */
- static void
- tty_clear_window_end (struct window *w, int ystart, int yend)
- {
- struct device *d = XDEVICE (XFRAME (w->frame)->device);
- int line;
-
- for (line = ystart; line < yend; line++)
- {
- cmgoto (XFRAME (w->frame), line, 0);
- OUTPUT1 (d, TTY_SE (d).clr_to_eol);
- }
- }
-
- /*
- * tty_shift_region - shift a region between START and END to its new position
- */
- static void
- tty_shift_region (struct window *w, struct line_header *start,
- struct line_header *end)
- {
- stderr_out ("tty_shift_region: NOT YET IMPLEMENTED\n");
- }
- #endif /* 0 */
-
- #ifdef OLD_REDISPLAY_SHIT
-
- static void
- tty_update_begin (struct window *w)
- {
- }
-
- static void
- tty_update_end (struct window *w)
- {
- struct frame *f = XFRAME (w->frame);
-
- /* reset state */
- turn_off_insert (f);
- turn_off_standout (f);
- turn_off_underline (f);
- turn_off_alternate (f);
- turn_off_attributes (f);
-
- internal_cursor_to (f, f->cursor_y, f->cursor_x);
-
- tty_flush (XDEVICE (f->device));
- }
-
- static void
- tty_cursor_to (struct line_header *l, struct char_block *cb, int row, int col,
- struct window_mirror *mir, struct frame *f)
- {
- internal_cursor_to (f, l->ypos, cb->xpos);
- }
-
- #endif /* OLD_REDISPLAY_SHIT */
-
- static int
- tty_flash (struct device *d)
- {
- if (TTY_SD (d).visual_bell)
- {
- OUTPUT1 (d, TTY_SD (d).visual_bell);
- fflush (DEVICE_TTY_DATA (d)->outfd);
- return 1;
- }
- else
- return 0;
- }
-
- /*
- * tty_ring_bell - sound an audio beep.
- */
- static void
- tty_ring_bell (struct device *d, int volume, int pitch, int duration)
- {
- OUTPUT1 (d, TTY_SD (d).audio_bell);
- fflush (DEVICE_TTY_DATA (d)->outfd);
- }
-
- int
- init_tty_for_redisplay (struct device *d, char *terminal_type)
- {
- int status;
- char entry_buffer[2044];
- /* char temp_buffer[2044]; */
- char *bufptr;
-
- /* What we should really do is allocate just enough space for
- the actual strings that are stored; but this would require
- doing this after all the tgetstr()s and adjusting all the
- pointers. */
- DEVICE_TTY_DATA (d)->term_entry_buffer = (char *) xmalloc (2044);
- bufptr = DEVICE_TTY_DATA (d)->term_entry_buffer;
-
- status = tgetent (entry_buffer, terminal_type);
- if (status < 0)
- return TTY_UNABLE_OPEN_DATABASE;
- else if (status == 0)
- return TTY_TYPE_UNDEFINED;
-
- /*
- * Establish the terminal size.
- */
- /* First try to get the info from the system. If that fails, check
- the termcap entry. */
- get_tty_device_size (d, &DEVICE_TTY_DATA(d)->width,
- &DEVICE_TTY_DATA(d)->height);
-
- if (DEVICE_TTY_DATA (d)->width <= 0)
- DEVICE_TTY_DATA (d)->width = tgetnum ("co");
- if (DEVICE_TTY_DATA (d)->height <= 0)
- DEVICE_TTY_DATA (d)->height = tgetnum ("li");
-
- if (DEVICE_TTY_DATA (d)->width <= 0 || DEVICE_TTY_DATA (d)->height <= 0)
- return TTY_SIZE_UNSPECIFIED;
-
- /*
- * Initialize cursor motion information.
- */
-
- /* local cursor movement */
- TTY_CM (d).up = tgetstr ("up", &bufptr);
- TTY_CM (d).down = tgetstr ("do", &bufptr);
- TTY_CM (d).left = tgetstr ("le", &bufptr);
- TTY_CM (d).right = tgetstr ("nd", &bufptr);
- TTY_CM (d).home = tgetstr ("ho", &bufptr);
- TTY_CM (d).low_left = tgetstr ("ll", &bufptr);
- TTY_CM (d).car_return = tgetstr ("cr", &bufptr);
-
- /* absolute cursor motion */
- TTY_CM (d).abs = tgetstr ("cm", &bufptr);
- TTY_CM (d).hor_abs = tgetstr ("ch", &bufptr);
- TTY_CM (d).ver_abs = tgetstr ("cv", &bufptr);
-
- /* Verify that the terminal is powerful enough to run Emacs */
- if (!TTY_CM (d).abs)
- {
- if (!TTY_CM (d).up || !TTY_CM (d).down
- || !TTY_CM (d).left || !TTY_CM (d).right)
- return TTY_TYPE_INSUFFICIENT;
- }
-
- /* parameterized local cursor movement */
- TTY_CM (d).multi_up = tgetstr ("UP", &bufptr);
- TTY_CM (d).multi_down = tgetstr ("DO", &bufptr);
- TTY_CM (d).multi_left = tgetstr ("LE", &bufptr);
- TTY_CM (d).multi_right = tgetstr ("RI", &bufptr);
-
- /* scrolling */
- TTY_CM (d).scroll_forw = tgetstr ("sf", &bufptr);
- TTY_CM (d).scroll_back = tgetstr ("sr", &bufptr);
- TTY_CM (d).multi_scroll_forw = tgetstr ("SF", &bufptr);
- TTY_CM (d).multi_scroll_back = tgetstr ("SR", &bufptr);
- TTY_CM (d).set_scroll_region = tgetstr ("cs", &bufptr);
-
-
- /*
- * Initialize screen editing information.
- */
-
- /* adding to the screen */
- TTY_SE (d).ins_line = tgetstr ("al", &bufptr);
- TTY_SE (d).multi_ins_line = tgetstr ("AL", &bufptr);
- TTY_SE (d).repeat = tgetstr ("rp", &bufptr);
- TTY_SE (d).begin_ins_mode = tgetstr ("im", &bufptr);
- TTY_SE (d).end_ins_mode = tgetstr ("ei", &bufptr);
- TTY_SE (d).ins_char = tgetstr ("ic", &bufptr);
- TTY_SE (d).multi_ins_char = tgetstr ("IC", &bufptr);
- TTY_SE (d).insert_pad = tgetstr ("ip", &bufptr);
-
- /* deleting from the screen */
- TTY_SE (d).clr_frame = tgetstr ("cl", &bufptr);
- TTY_SE (d).clr_from_cursor = tgetstr ("cd", &bufptr);
- TTY_SE (d).clr_to_eol = tgetstr ("ce", &bufptr);
- TTY_SE (d).del_line = tgetstr ("dl", &bufptr);
- TTY_SE (d).multi_del_line = tgetstr ("DL", &bufptr);
- TTY_SE (d).del_char = tgetstr ("dc", &bufptr);
- TTY_SE (d).multi_del_char = tgetstr ("DC", &bufptr);
- TTY_SE (d).begin_del_mode = tgetstr ("dm", &bufptr);
- TTY_SE (d).end_del_mode = tgetstr ("ed", &bufptr);
- TTY_SE (d).erase_at_cursor = tgetstr ("ec", &bufptr);
-
-
- /*
- * Initialize screen display information.
- */
- TTY_SD (d).begin_standout = tgetstr ("so", &bufptr);
- TTY_SD (d).end_standout = tgetstr ("se", &bufptr);
- TTY_SD (d).begin_underline = tgetstr ("us", &bufptr);
- TTY_SD (d).end_underline = tgetstr ("ue", &bufptr);
- TTY_SD (d).begin_alternate = tgetstr ("as", &bufptr);
- TTY_SD (d).end_alternate = tgetstr ("ae", &bufptr);
- TTY_SD (d).turn_on_reverse = tgetstr ("mr", &bufptr);
- TTY_SD (d).turn_on_blinking = tgetstr ("mb", &bufptr);
- TTY_SD (d).turn_on_bold = tgetstr ("md", &bufptr);
- TTY_SD (d).turn_on_dim = tgetstr ("mh", &bufptr);
- TTY_SD (d).turn_off_attributes = tgetstr ("me", &bufptr);
-
- TTY_SD (d).visual_bell = tgetstr ("vb", &bufptr);
- TTY_SD (d).audio_bell = tgetstr ("bl", &bufptr);
- if (!TTY_SD (d).audio_bell)
- {
- /* If audio_bell doesn't get set, then assume C-g. This is gross and
- ugly but is what Emacs has done from time immortal. */
- TTY_SD (d).audio_bell = "\07";
- }
-
- TTY_SD (d).cursor_visible = tgetstr ("ve", &bufptr);
- TTY_SD (d).cursor_normal = tgetstr ("vs", &bufptr);
- TTY_SD (d).init_motion = tgetstr ("ti", &bufptr);
- TTY_SD (d).end_motion = tgetstr ("te", &bufptr);
- TTY_SD (d).keypad_on = tgetstr ("ks", &bufptr);
- TTY_SD (d).keypad_off = tgetstr ("ke", &bufptr);
-
-
- /*
- * Initialize additional terminal information.
- */
- TTY_FLAGS (d).must_write_spaces = tgetflag ("in");
- TTY_FLAGS (d).insert_mode_motion = tgetflag ("mi");
- TTY_FLAGS (d).standout_motion = tgetflag ("ms");
- TTY_FLAGS (d).memory_above_frame = tgetflag ("da");
- TTY_FLAGS (d).memory_below_frame = tgetflag ("db");
- TTY_FLAGS (d).meta_key = tgetflag ("km") || tgetflag ("MT");
- TTY_FLAGS (d).standout_width = tgetnum ("sg");
- TTY_FLAGS (d).underline_width = tgetnum ("ug");
-
- if (TTY_FLAGS (d).standout_width == -1)
- TTY_FLAGS (d).standout_width = 0;
- if (TTY_FLAGS (d).underline_width == -1)
- TTY_FLAGS (d).underline_width = 0;
-
- /*
- * Setup the costs tables for this tty device.
- */
- cm_cost_init (d);
-
- /*
- * Initialize local flags.
- */
- insert_mode_on = 0;
- standout_mode_on = 0;
- underline_mode_on = 0;
- alternate_mode_on = 0;
- attributes_on = 0;
-
- /* #### fix this */
- DEVICE_CLASS (d) = Qmono;
-
- return TTY_INIT_SUCCESS;
- }
-
-
- /************************************************************************/
- /* initialization */
- /************************************************************************/
-
- void
- device_type_create_redisplay_tty (void)
- {
- /* redisplay methods */
- DEVICE_HAS_METHOD (tty, text_width);
- DEVICE_HAS_METHOD (tty, font_metric_info);
- DEVICE_HAS_METHOD (tty, output_display_block);
- DEVICE_HAS_METHOD (tty, output_vertical_divider);
- DEVICE_HAS_METHOD (tty, divider_width);
- DEVICE_HAS_METHOD (tty, divider_height);
- DEVICE_HAS_METHOD (tty, eol_cursor_width);
- DEVICE_HAS_METHOD (tty, clear_to_window_end);
- DEVICE_HAS_METHOD (tty, clear_region);
- DEVICE_HAS_METHOD (tty, clear_frame);
- DEVICE_HAS_METHOD (tty, output_begin);
- DEVICE_HAS_METHOD (tty, output_end);
- DEVICE_HAS_METHOD (tty, flash);
- DEVICE_HAS_METHOD (tty, ring_bell);
- }
-