This is redisplay-tty.c in view mode; [Download] [Up]
/* 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); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.