X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/e37f06d7db86fad8daff7b1cba12dda2199556a6..254277e15d6906634686a682bfc7a163b20d7be5:/src/dispnew.c diff --git a/src/dispnew.c b/src/dispnew.c index dbc8f59e7b..0faabda929 100644 --- a/src/dispnew.c +++ b/src/dispnew.c @@ -19,9 +19,10 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include -#include #include + +#include #include #include "lisp.h" @@ -39,22 +40,34 @@ the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA. */ #include "intervals.h" #include "systty.h" -#include "systime.h" #ifdef HAVE_X_WINDOWS #include "xterm.h" #endif /* HAVE_X_WINDOWS */ +/* Include systime.h after xterm.h to avoid double inclusion of time.h. */ +#include "systime.h" + +#include + #define max(a, b) ((a) > (b) ? (a) : (b)) #define min(a, b) ((a) < (b) ? (a) : (b)) -#ifndef PENDING_OUTPUT_COUNT /* Get number of chars of output now in the buffer of a stdio stream. This ought to be built in in stdio, but it isn't. Some s- files override this because their stdio internals differ. */ #ifdef __GNU_LIBRARY__ -#define PENDING_OUTPUT_COUNT(FILE) ((FILE)->__bufp - (FILE)->__buffer) +/* The s- file might have overridden the definition with one that works for + the system's C library. But we are using the GNU C library, so this is + the right definition for every system. */ +#ifdef GNU_LIBRARY_PENDING_OUTPUT_COUNT +#define PENDING_OUTPUT_COUNT GNU_LIBRARY_PENDING_OUTPUT_COUNT #else +#undef PENDING_OUTPUT_COUNT +#define PENDING_OUTPUT_COUNT(FILE) ((FILE)->__bufp - (FILE)->__buffer) +#endif +#else /* not __GNU_LIBRARY__ */ +#ifndef PENDING_OUTPUT_COUNT #define PENDING_OUTPUT_COUNT(FILE) ((FILE)->_ptr - (FILE)->_base) #endif #endif @@ -305,7 +318,7 @@ make_frame_glyphs (frame, empty) return new; } -static void +void free_frame_glyphs (frame, glyphs) FRAME_PTR frame; struct frame_glyphs *glyphs; @@ -838,10 +851,10 @@ preserve_other_columns (w) bcopy (current_frame->glyphs[vpos], desired_frame->glyphs[vpos], - start * sizeof (current_frame->glyphs[vpos])); + start * sizeof (current_frame->glyphs[vpos][0])); bcopy (current_frame->charstarts[vpos], desired_frame->charstarts[vpos], - start * sizeof (current_frame->charstarts[vpos])); + start * sizeof (current_frame->charstarts[vpos][0])); len = min (start, current_frame->used[vpos]); if (desired_frame->used[vpos] < len) desired_frame->used[vpos] = len; @@ -858,11 +871,11 @@ preserve_other_columns (w) bcopy (current_frame->glyphs[vpos] + end, desired_frame->glyphs[vpos] + end, ((current_frame->used[vpos] - end) - * sizeof (current_frame->glyphs[vpos]))); + * sizeof (current_frame->glyphs[vpos][0]))); bcopy (current_frame->charstarts[vpos] + end, desired_frame->charstarts[vpos] + end, ((current_frame->used[vpos] - end) - * sizeof (current_frame->charstarts[vpos]))); + * sizeof (current_frame->charstarts[vpos][0]))); desired_frame->used[vpos] = current_frame->used[vpos]; } } @@ -1064,7 +1077,7 @@ direct_output_for_insert (g) At the moment we only lose at end of line or end of buffer and only with faces that have some background */ /* Instead of wasting time, give up if character has any text properties */ - || ! NILP (Ftext_properties_at (XFASTINT (point - 1), Qnil)) + || ! NILP (Ftext_properties_at (make_number (point - 1), Qnil)) #endif /* Give up if w is minibuffer and a message is being displayed there */ @@ -1072,9 +1085,12 @@ direct_output_for_insert (g) return 0; { + int face = 0; #ifdef HAVE_X_WINDOWS int dummy; - int face = compute_char_face (frame, w, point - 1, -1, -1, &dummy, point); + + if (FRAME_X_P (frame)) + face = compute_char_face (frame, w, point - 1, -1, -1, &dummy, point, 0); #endif current_frame->glyphs[vpos][hpos] = MAKE_GLYPH (frame, g, face); current_frame->charstarts[vpos][hpos] = point - 1; @@ -1107,7 +1123,7 @@ direct_output_forward_char (n) { register FRAME_PTR frame = selected_frame; register struct window *w = XWINDOW (selected_window); - int position; + Lisp_Object position; int hpos = FRAME_CURSOR_X (frame); /* Give up if in truncated text at end of line. */ @@ -1167,8 +1183,8 @@ update_frame (f, force, inhibit_hairy_id) int force; int inhibit_hairy_id; { - register struct frame_glyphs *current_frame = FRAME_CURRENT_GLYPHS (f); - register struct frame_glyphs *desired_frame = FRAME_DESIRED_GLYPHS (f); + register struct frame_glyphs *current_frame; + register struct frame_glyphs *desired_frame = 0; register int i; int pause; int preempt_count = baud_rate / 2400 + 1; @@ -1194,6 +1210,10 @@ update_frame (f, force, inhibit_hairy_id) if (!line_ins_del_ok) inhibit_hairy_id = 1; + /* These are separate to avoid a possible bug in the AIX C compiler. */ + current_frame = FRAME_CURRENT_GLYPHS (f); + desired_frame = FRAME_DESIRED_GLYPHS (f); + /* See if any of the desired lines are enabled; don't compute for i/d line if just want cursor motion. */ for (i = 0; i < FRAME_HEIGHT (f); i++) @@ -1250,7 +1270,7 @@ update_frame (f, force, inhibit_hairy_id) outq = PENDING_OUTPUT_COUNT (stdout); #endif outq *= 10; - if (baud_rate >= outq) + if (baud_rate <= outq && baud_rate > 0) sleep (outq / baud_rate); } } @@ -1331,7 +1351,7 @@ update_frame (f, force, inhibit_hairy_id) if (FRAME_HEIGHT (f) == 0) abort (); /* Some bug zeros some core */ display_completed = !pause; - bzero (desired_frame->enable, FRAME_HEIGHT (f)); + bzero (FRAME_DESIRED_GLYPHS (f)->enable, FRAME_HEIGHT (f)); return pause; } @@ -1562,7 +1582,7 @@ update_line (frame, vpos) = current_frame->used[vpos] * FONT_WIDTH (frame->display.x->font); current_frame->pix_height[vpos] - = FONT_HEIGHT (frame->display.x->font); + = frame->display.x->line_height; } #endif /* HAVE_X_WINDOWS */ @@ -1842,6 +1862,65 @@ update_line (frame, vpos) current_frame->charstarts[vpos] = temp1; } +/* A vector of size >= NFRAMES + 3 * NBUFFERS + 1, containing the session's + frames, buffers, buffer-read-only flags, and buffer-modified-flags, + and a trailing sentinel (so we don't need to add length checks). */ +static Lisp_Object frame_and_buffer_state; + +DEFUN ("frame-or-buffer-changed-p", Fframe_or_buffer_changed_p, + Sframe_or_buffer_changed_p, 0, 0, 0, + "Return non-nil if the frame and buffer state appears to have changed.\n\ +The state variable is an internal vector containing all frames and buffers,\n\ +along with the buffers' read-only and modified flags, which allows a fast\n\ +check to see whether the menu bars might need to be recomputed.\n\ +If this function returns non-nil, it updates the internal vector to reflect\n\ +the current state.\n") + () +{ + Lisp_Object tail, frame, buf; + Lisp_Object *vecp; + int n; + vecp = XVECTOR (frame_and_buffer_state)->contents; + FOR_EACH_FRAME (tail, frame) + if (!EQ (*vecp++, frame)) + goto changed; + for (tail = Vbuffer_alist; CONSP (tail); tail = XCONS (tail)->cdr) + { + buf = XCONS (XCONS (tail)->car)->cdr; + if (!EQ (*vecp++, buf)) + goto changed; + if (!EQ (*vecp++, XBUFFER (buf)->read_only)) + goto changed; + if (!EQ (*vecp++, Fbuffer_modified_p (buf))) + goto changed; + } + return Qnil; + changed: + n = 1; + FOR_EACH_FRAME (tail, frame) + n++; + for (tail = Vbuffer_alist; CONSP (tail); tail = XCONS (tail)->cdr) + n += 3; + /* Reallocate the vector if it's grown, or if it's shrunk a lot. */ + if (n > XVECTOR (frame_and_buffer_state)->size + || n < XVECTOR (frame_and_buffer_state)->size / 2) + frame_and_buffer_state = Fmake_vector (make_number (n), Qlambda); + vecp = XVECTOR (frame_and_buffer_state)->contents; + FOR_EACH_FRAME (tail, frame) + *vecp++ = frame; + for (tail = Vbuffer_alist; CONSP (tail); tail = XCONS (tail)->cdr) + { + buf = XCONS (XCONS (tail)->car)->cdr; + *vecp++ = buf; + *vecp++ = XBUFFER (buf)->read_only; + *vecp++ = Fbuffer_modified_p (buf); + } + /* If we left any slack in the vector, fill it up now. */ + for (; n < XVECTOR (frame_and_buffer_state)->size; ++n) + *vecp++ = Qlambda; + return Qt; +} + DEFUN ("open-termscript", Fopen_termscript, Sopen_termscript, 1, 1, "FOpen termscript file: ", "Start writing all terminal output to FILE as well as the terminal.\n\ @@ -2011,7 +2090,12 @@ change_frame_size (frame, newheight, newwidth, pretend, delay) FRAME_HEIGHT (frame) = newheight; FRAME_WIDTH (frame) = newwidth; - + + if (FRAME_CURSOR_X (frame) >= FRAME_WIDTH (frame)) + FRAME_CURSOR_X (frame) = FRAME_WIDTH (frame) - 1; + if (FRAME_CURSOR_Y (frame) >= FRAME_HEIGHT (frame)) + FRAME_CURSOR_Y (frame) = FRAME_HEIGHT (frame) - 1; + remake_frame_glyphs (frame); calculate_costs (frame); } @@ -2374,14 +2458,18 @@ syms_of_display () defsubr (&Sredraw_frame); #endif defsubr (&Sredraw_display); + defsubr (&Sframe_or_buffer_changed_p); defsubr (&Sopen_termscript); defsubr (&Sding); defsubr (&Ssit_for); defsubr (&Ssleep_for); defsubr (&Ssend_string_to_terminal); + frame_and_buffer_state = Fmake_vector (make_number (1), Qlambda); + staticpro (&frame_and_buffer_state); + DEFVAR_INT ("baud-rate", &baud_rate, - "The output baud rate of the terminal.\n\ + "*The output baud rate of the terminal.\n\ On most systems, changing this value will affect the amount of padding\n\ and the other strategic decisions made during redisplay."); DEFVAR_BOOL ("inverse-video", &inverse_video, @@ -2409,7 +2497,7 @@ Each element can be:\n\ integer: a glyph code which this glyph is an alias for.\n\ string: output this glyph using that string (not impl. in X windows).\n\ nil: this glyph mod 256 is char code to output,\n\ - and this glyph / 256 is face code for X windows (see `x-set-face')."); + and this glyph / 256 is face code for X windows (see `face-id')."); Vglyph_table = Qnil; DEFVAR_LISP ("standard-display-table", &Vstandard_display_table,