]> code.delx.au - gnu-emacs/blobdiff - src/dispnew.c
(XTmouse_position, x_term_init):
[gnu-emacs] / src / dispnew.c
index e996c78ffd007d10ea03cd53ec5d02e7763fcf6e..691ea4be410719d72a7e2c3f09d2ac11d5534a05 100644 (file)
@@ -34,6 +34,7 @@ Boston, MA 02111-1307, USA.  */
 #include "dispextern.h"
 #include "cm.h"
 #include "buffer.h"
+#include "charset.h"
 #include "frame.h"
 #include "window.h"
 #include "commands.h"
@@ -42,7 +43,9 @@ Boston, MA 02111-1307, USA.  */
 #include "intervals.h"
 #include "blockinput.h"
 
-#include "systty.h"
+/* I don't know why DEC Alpha OSF1 fail to compile this file if we
+   include the following file.  */
+/* #include "systty.h" */
 #include "syssignal.h"
 
 #ifdef HAVE_X_WINDOWS
@@ -223,7 +226,7 @@ make_frame_glyphs (frame, empty)
      int empty;
 {
   register int i;
-  register width = FRAME_WIDTH (frame);
+  register width = FRAME_WINDOW_WIDTH (frame);
   register height = FRAME_HEIGHT (frame);
   register struct frame_glyphs *new
     = (struct frame_glyphs *) xmalloc (sizeof (struct frame_glyphs));
@@ -346,7 +349,7 @@ remake_frame_glyphs (frame)
 
       FRAME_MESSAGE_BUF (frame)
        = (char *) xrealloc (FRAME_MESSAGE_BUF (frame),
-                            FRAME_WIDTH (frame) + 1);
+                            FRAME_MESSAGE_BUF_SIZE (frame) + 1);
 
       if (echo_area_glyphs == old_message_buf)
        echo_area_glyphs = FRAME_MESSAGE_BUF (frame);
@@ -355,7 +358,7 @@ remake_frame_glyphs (frame)
     }
   else
     FRAME_MESSAGE_BUF (frame)
-      = (char *) xmalloc (FRAME_WIDTH (frame) + 1);
+      = (char *) xmalloc (FRAME_MESSAGE_BUF_SIZE (frame) + 1);
 
   FRAME_CURRENT_GLYPHS (frame) = make_frame_glyphs (frame, 0);
   FRAME_DESIRED_GLYPHS (frame) = make_frame_glyphs (frame, 0);
@@ -609,7 +612,7 @@ scroll_frame_lines (frame, from, end, amount, newpos)
   register struct frame_glyphs *current_frame
     = FRAME_CURRENT_GLYPHS (frame);
   int pos_adjust;
-  int width = FRAME_WIDTH (frame);
+  int width = FRAME_WINDOW_WIDTH (frame);
 
   if (!line_ins_del_ok)
     return 0;
@@ -823,8 +826,8 @@ preserve_other_columns (w)
   register int vpos;
   register struct frame_glyphs *current_frame, *desired_frame;
   register FRAME_PTR frame = XFRAME (w->frame);
-  int start = XFASTINT (w->left);
-  int end = XFASTINT (w->left) + XFASTINT (w->width);
+  int start = WINDOW_LEFT_MARGIN (w);
+  int end = WINDOW_RIGHT_EDGE (w);
   int bot = XFASTINT (w->top) + XFASTINT (w->height);
 
   current_frame = FRAME_CURRENT_GLYPHS (frame);
@@ -886,8 +889,8 @@ preserve_my_columns (w)
   register int vpos, fin;
   register struct frame_glyphs *l1, *l2;
   register FRAME_PTR frame = XFRAME (w->frame);
-  int start = XFASTINT (w->left);
-  int end = XFASTINT (w->left) + XFASTINT (w->width);
+  int start = WINDOW_LEFT_MARGIN (w);
+  int end = WINDOW_RIGHT_EDGE (w);
   int bot = XFASTINT (w->top) + XFASTINT (w->height);
 
   for (vpos = XFASTINT (w->top); vpos < bot; vpos++)
@@ -920,7 +923,7 @@ adjust_window_charstarts (w, vpos, adjust)
      int vpos;
      int adjust;
 {
-  int left = XFASTINT (w->left);
+  int left = WINDOW_LEFT_MARGIN (w);
   int top = XFASTINT (w->top);
   int right = left + window_internal_width (w);
   int bottom = top + window_internal_height (w);
@@ -948,12 +951,12 @@ verify_charstarts (w)
   int i;
   int top = XFASTINT (w->top);
   int bottom = top + window_internal_height (w);
-  int left = XFASTINT (w->left);
+  int left = WINDOW_LEFT_MARGIN (w);
   int right = left + window_internal_width (w);
   int next_line;
   int truncate = (XINT (w->hscroll)
                  || (truncate_partial_width_windows
-                     && (XFASTINT (w->width) < FRAME_WIDTH (f)))
+                     && !WINDOW_FULL_WIDTH_P (w))
                  || !NILP (XBUFFER (w->buffer)->truncate_lines));
 
   for (i = top; i < bottom; i++)
@@ -1003,7 +1006,7 @@ cancel_my_columns (w)
   register int vpos;
   register struct frame_glyphs *desired_glyphs
     = FRAME_DESIRED_GLYPHS (XFRAME (w->frame));
-  register int start = XFASTINT (w->left);
+  register int start = WINDOW_LEFT_MARGIN (w);
   register int bot = XFASTINT (w->top) + XFASTINT (w->height);
 
   for (vpos = XFASTINT (w->top); vpos < bot; vpos++)
@@ -1042,10 +1045,10 @@ direct_output_for_insert (g)
     int vpos = FRAME_CURSOR_Y (frame);
 
   /* Give up if about to continue line.  */
-  if (hpos >= XFASTINT (w->left) + window_internal_width (w) - 1
+  if (hpos >= WINDOW_LEFT_MARGIN (w) + window_internal_width (w) - 1
     
   /* Avoid losing if cursor is in invisible text off left margin */
-      || (XINT (w->hscroll) && hpos == XFASTINT (w->left))
+      || (XINT (w->hscroll) && hpos == WINDOW_LEFT_MARGIN (w))
     
   /* Give up if cursor outside window (in minibuf, probably) */
       || cursor_in_echo_area
@@ -1092,6 +1095,7 @@ direct_output_for_insert (g)
   XSETFASTINT (w->last_point, PT);
   XSETFASTINT (w->last_point_x, hpos);
   XSETFASTINT (w->last_modified, MODIFF);
+  XSETFASTINT (w->last_overlay_modified, OVERLAY_MODIFF);
 
   reassert_line_highlight (0, vpos);
   write_glyphs (&current_frame->glyphs[vpos][hpos], 1);
@@ -1113,18 +1117,29 @@ direct_output_forward_char (n)
   register FRAME_PTR frame = selected_frame;
   register struct window *w = XWINDOW (selected_window);
   Lisp_Object position;
+  /* This check is redundant.  It's checked at "losing cursor" below.  */
+#if 0
   int hpos = FRAME_CURSOR_X (frame);
 
   /* Give up if in truncated text at end of line.  */
-  if (hpos >= XFASTINT (w->left) + window_internal_width (w) - 1)
+  if (hpos >= WINDOW_LEFT_MARGIN (w) + window_internal_width (w) - 1)
+    return 0;
+#endif /* 0 */
+
+  /* Give up if the buffer's direction is reversed (i.e. right-to-left).  */
+  if (!NILP (XBUFFER(w->buffer)->direction_reversed))
     return 0;
 
   /* Avoid losing if cursor is in invisible text off left margin
      or about to go off either side of window.  */
-  if ((FRAME_CURSOR_X (frame) == XFASTINT (w->left)
+  if ((FRAME_CURSOR_X (frame) == WINDOW_LEFT_MARGIN (w)
        && (XINT (w->hscroll) || n < 0))
       || (n > 0
-         && (FRAME_CURSOR_X (frame) + 1 >= window_internal_width (w) - 1))
+         && (FRAME_CURSOR_X (frame) + 1 
+             >= XFASTINT (w->left) + window_internal_width (w) - 1))
+      /* BUG FIX: Added "XFASTINT (w->left)".  Without this,
+        direct_output_forward_char() always fails on "the right"
+        window.  */
       || cursor_in_echo_area)
     return 0;
 
@@ -1271,10 +1286,11 @@ update_frame (f, force, inhibit_hairy_id)
                        sleep (outq / baud_rate);
                    }
                }
-             if ((i - 1) % preempt_count == 0)
-               detect_input_pending ();
            }
 
+         if ((i - 1) % preempt_count == 0)
+           detect_input_pending ();
+
          update_line (f, i);
 #ifdef HAVE_WINDOW_SYSTEM
          if (FRAME_WINDOW_P (f))
@@ -1330,7 +1346,7 @@ update_frame (f, force, inhibit_hairy_id)
                }
              while (row > top && col == 0);
 
-             if (col >= FRAME_WIDTH (f))
+             if (col >= FRAME_WINDOW_WIDTH (f))
                {
                  col = 0;
                  if (row < FRAME_HEIGHT (f) - 1)
@@ -1341,8 +1357,9 @@ update_frame (f, force, inhibit_hairy_id)
          cursor_to (row, col);
        }
       else
-       cursor_to (FRAME_CURSOR_Y (f), max (min (FRAME_CURSOR_X (f),
-                                                 FRAME_WIDTH (f) - 1), 0));
+       cursor_to (FRAME_CURSOR_Y (f), 
+                  max (min (FRAME_CURSOR_X (f),
+                            FRAME_WINDOW_WIDTH (f) - 1), 0));
     }
 
   update_end (f);
@@ -1466,7 +1483,7 @@ buffer_posn_from_coords (window, col, line)
      int col, line;
 {
   int hscroll = XINT (window->hscroll);
-  int window_left = XFASTINT (window->left);
+  int window_left = WINDOW_LEFT_MARGIN (window);
 
   /* The actual width of the window is window->width less one for the
      DISP_CONTINUE_GLYPH, and less one if it's not the rightmost
@@ -1533,7 +1550,7 @@ count_match (str1, str2)
 /* Char insertion/deletion cost vector, from term.c */
 extern int *char_ins_del_vector;
 
-#define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_WIDTH((f))])
+#define char_ins_del_cost(f) (&char_ins_del_vector[FRAME_WINDOW_WIDTH((f))])
 
 static void
 update_line (frame, vpos)
@@ -1544,7 +1561,7 @@ update_line (frame, vpos)
   int *temp1;
   int tem;
   int osp, nsp, begmatch, endmatch, olen, nlen;
-  int save;
+  GLYPH save;
   register struct frame_glyphs *current_frame
     = FRAME_CURRENT_GLYPHS (frame);
   register struct frame_glyphs *desired_frame
@@ -1581,7 +1598,7 @@ update_line (frame, vpos)
             spaces all the way to the frame edge
             so that the reverse video extends all the way across.  */
 
-         while (olen < FRAME_WIDTH (frame) - 1)
+         while (olen < FRAME_WINDOW_WIDTH (frame) - 1)
            obody[olen++] = SPACEGLYPH;
        }
     }
@@ -1627,7 +1644,7 @@ update_line (frame, vpos)
         all the way to the frame edge
         so that the reverse video extends all the way across.  */
 
-      while (nlen < FRAME_WIDTH (frame) - 1)
+      while (nlen < FRAME_WINDOW_WIDTH (frame) - 1)
        nbody[nlen++] = SPACEGLYPH;
     }
 
@@ -1660,8 +1677,10 @@ update_line (frame, vpos)
          if (i >= olen || nbody[i] != obody[i])    /* A non-matching char. */
            {
              cursor_to (vpos, i);
-             for (j = 1; (i + j < nlen &&
-                          (i + j >= olen || nbody[i+j] != obody[i+j]));
+             for (j = 1;
+                  (i + j < nlen
+                   && (i + j >= olen || nbody[i + j] != obody[i + j]
+                       || (nbody[i + j] & GLYPH_MASK_PADDING)));
                   j++);
 
              /* Output this run of non-matching chars.  */ 
@@ -1819,7 +1838,7 @@ update_line (frame, vpos)
             there is no need to do clear-to-eol at the end.
             (and it would not be safe, since cursor is not
             going to be "at the margin" after the text is done) */
-         if (nlen == FRAME_WIDTH (frame))
+         if (nlen == FRAME_WINDOW_WIDTH (frame))
            olen = 0;
          write_glyphs (nbody + nsp + begmatch, nlen - tem);
 
@@ -1833,7 +1852,7 @@ update_line (frame, vpos)
             it will lose one way or another (depending on AutoWrap)
             to clear to end of line after outputting all the text.
             So pause with one character to go and clear the line then.  */
-         if (nlen == FRAME_WIDTH (frame) && fast_clear_end_of_line && olen > nlen)
+         if (nlen == FRAME_WINDOW_WIDTH (frame) && fast_clear_end_of_line && olen > nlen)
            {
              /* endmatch must be zero, and tem must equal nsp + begmatch */
              write_glyphs (nbody + tem, nlen - tem - 1);
@@ -1848,8 +1867,24 @@ update_line (frame, vpos)
        }
       else if (nlen > olen)
        {
-         write_glyphs (nbody + nsp + begmatch, olen - tem);
-         insert_glyphs (nbody + nsp + begmatch + olen - tem, nlen - olen);
+         /* Here, we used to have the following simple code:
+            ----------------------------------------
+            write_glyphs (nbody + nsp + begmatch, olen - tem);
+            insert_glyphs (nbody + nsp + begmatch + olen - tem, nlen - olen);
+            ----------------------------------------
+            but it doesn't work if nbody[nsp + begmatch + olen - tem]
+            is a padding glyph.  */
+         int out = olen - tem; /* Columns to be overwritten originally.  */
+         int del;
+
+         /* Calculate columns we can actually overwrite.  */
+         while (nbody[nsp + begmatch + out] & GLYPH_MASK_PADDING) out--;
+         write_glyphs (nbody + nsp + begmatch, out);
+         /* If we left columns to be overwritten. we must delete them.  */
+         del = olen - tem - out;
+         if (del > 0) delete_glyphs (del);
+         /* At last, we insert columns not yet written out.  */
+         insert_glyphs (nbody + nsp + begmatch + out, nlen - olen + del);
          olen = nlen;
        }
       else if (olen > nlen)
@@ -1926,7 +1961,7 @@ the current state.\n")
        goto changed;
     }
   /* Detect deletion of a buffer at the end of the list.  */
-  if (*vecp == Qlambda)
+  if (EQ (*vecp, Qlambda))
     return Qnil;
  changed:
   /* Start with 1 so there is room for at least one lambda at the end.  */
@@ -2064,6 +2099,7 @@ change_frame_size (f, newheight, newwidth, pretend, delay)
      int newheight, newwidth, pretend;
 {
   Lisp_Object tail, frame;
+
   if (! FRAME_WINDOW_P (f))
     {
       /* When using termcap, or on MS-DOS, all frames use
@@ -2082,6 +2118,9 @@ change_frame_size_1 (frame, newheight, newwidth, pretend, delay)
      register FRAME_PTR frame;
      int newheight, newwidth, pretend, delay;
 {
+  int new_frame_window_width;
+  unsigned int total_glyphs;
+
   /* If we can't deal with the change now, queue it for later.  */
   if (delay)
     {
@@ -2100,13 +2139,21 @@ change_frame_size_1 (frame, newheight, newwidth, pretend, delay)
     newheight = FRAME_HEIGHT (frame);
   if (newwidth == 0)
     newwidth  = FRAME_WIDTH  (frame);
+  new_frame_window_width = FRAME_WINDOW_WIDTH_ARG (frame, newwidth);
+
+  total_glyphs = newheight * (newwidth + 2) * sizeof (GLYPH);
+
+  /* If these sizes are so big they cause overflow,
+     just ignore the change.  It's not clear what better we could do.  */
+  if (total_glyphs / sizeof (GLYPH) / newheight != newwidth + 2)
+    return;
 
   /* Round up to the smallest acceptable size.  */
   check_frame_size (frame, &newheight, &newwidth);
 
   /* If we're not changing the frame size, quit now.  */
   if (newheight == FRAME_HEIGHT (frame)
-      && newwidth == FRAME_WIDTH (frame))
+      && new_frame_window_width == FRAME_WINDOW_WIDTH (frame))
     return;
 
   BLOCK_INPUT;
@@ -2148,11 +2195,11 @@ change_frame_size_1 (frame, newheight, newwidth, pretend, delay)
 #endif
     }
 
-  if (newwidth != FRAME_WIDTH (frame))
+  if (new_frame_window_width  != FRAME_WINDOW_WIDTH (frame))
     {
-      set_window_width (FRAME_ROOT_WINDOW (frame), newwidth, 0);
+      set_window_width (FRAME_ROOT_WINDOW (frame), new_frame_window_width, 0);
       if (FRAME_HAS_MINIBUF_P (frame))
-       set_window_width (FRAME_MINIBUF_WINDOW (frame), newwidth, 0);
+       set_window_width (FRAME_MINIBUF_WINDOW (frame), new_frame_window_width, 0);
 
       if (FRAME_TERMCAP_P (frame) && !pretend)
        FrameCols = newwidth;
@@ -2167,10 +2214,10 @@ change_frame_size_1 (frame, newheight, newwidth, pretend, delay)
     }
 
   FRAME_HEIGHT (frame) = newheight;
-  FRAME_WIDTH (frame)  = newwidth;
+  SET_FRAME_WIDTH (frame, newwidth);
 
-  if (FRAME_CURSOR_X (frame) >= FRAME_WIDTH (frame))
-    FRAME_CURSOR_X (frame) = FRAME_WIDTH (frame) - 1;
+  if (FRAME_CURSOR_X (frame) >= FRAME_WINDOW_WIDTH (frame))
+    FRAME_CURSOR_X (frame) = FRAME_WINDOW_WIDTH (frame) - 1;
   if (FRAME_CURSOR_Y (frame) >= FRAME_HEIGHT (frame))
     FRAME_CURSOR_Y (frame) = FRAME_HEIGHT (frame) - 1;
 
@@ -2178,6 +2225,10 @@ change_frame_size_1 (frame, newheight, newwidth, pretend, delay)
   calculate_costs (frame);
 
   UNBLOCK_INPUT;
+
+  /* This isn't quite a no-op: it runs window-configuration-change-hook.  */
+  Fset_window_buffer (FRAME_SELECTED_WINDOW (frame),
+                     XWINDOW (FRAME_SELECTED_WINDOW (frame))->buffer);
 }
 \f
 DEFUN ("send-string-to-terminal", Fsend_string_to_terminal,
@@ -2466,7 +2517,7 @@ init_display ()
       display_arg = (display != 0 && *display != 0);
     }
 
-  if (!inhibit_window_system && display_arg)
+  if (!inhibit_window_system && display_arg && initialized)
     {
       Vwindow_system = intern ("x");
 #ifdef HAVE_X11
@@ -2487,7 +2538,7 @@ init_display ()
 #ifdef HAVE_NTGUI
   if (!inhibit_window_system) 
     {
-      Vwindow_system = intern ("win32");
+      Vwindow_system = intern ("w32");
       Vwindow_system_version = make_number (1);
       return;
     }
@@ -2496,7 +2547,7 @@ init_display ()
   /* If no window system has been specified, try to use the terminal.  */
   if (! isatty (0))
     {
-      fprintf (stderr, "emacs: standard input is not a tty\n");
+      fatal ("standard input is not a tty");
       exit (1);
     }
 
@@ -2534,6 +2585,18 @@ For types not defined in VMS, use  define emacs_term \"TYPE\".\n\
 
   term_init (terminal_type);
 
+  {
+    int width = FRAME_WINDOW_WIDTH (selected_frame);
+    int height = FRAME_HEIGHT (selected_frame);
+
+    unsigned int total_glyphs = height * (width + 2) * sizeof (GLYPH);
+
+    /* If these sizes are so big they cause overflow,
+       just ignore the change.  It's not clear what better we could do.  */
+    if (total_glyphs / sizeof (GLYPH) / height != width + 2)
+      fatal ("screen size %dx%d too big", width, height);
+  }
+
   remake_frame_glyphs (selected_frame);
   calculate_costs (selected_frame);