]> code.delx.au - gnu-emacs/commitdiff
Merged in changes from CVS HEAD
authorKaroly Lorentey <lorentey@elte.hu>
Sat, 28 Feb 2004 04:52:40 +0000 (04:52 +0000)
committerKaroly Lorentey <lorentey@elte.hu>
Sat, 28 Feb 2004 04:52:40 +0000 (04:52 +0000)
Patches applied:

 * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-118
   Update from CVS

 * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-119
   src/keyboard.c (adjust_point_for_property): #ifdef-out dodgy xassert

 * miles@gnu.org--gnu-2004/emacs--cvs-trunk--0--patch-120
   Update from CVS

git-archimport-id: lorentey@elte.hu--2004/emacs--multi-tty--0--patch-107

13 files changed:
1  2 
lisp/faces.el
src/dispnew.c
src/keyboard.c
src/keyboard.h
src/lisp.h
src/macterm.c
src/sysdep.c
src/termhooks.h
src/w32term.c
src/window.c
src/xsmfns.c
src/xterm.c
src/xterm.h

diff --cc lisp/faces.el
Simple merge
diff --cc src/dispnew.c
Simple merge
diff --cc src/keyboard.c
index 2aff293c610d7f34c6347056388b57c8e5563785,3e58a2a75a864f2c991f3885c5c1ea414743f85a..5e8397e745820f0486dabac09c679bfea5b45c71
@@@ -6586,218 -6608,145 +6612,215 @@@ read_avail_input (expected
  {
    register int i;
    int nread = 0;
 +  int err;
 +  struct display *d;
  
 -  if (read_socket_hook)
 +  /* Loop through the available displays, and call their input hooks. */
 +  d = display_list;
 +  while (d)
      {
 -      int discard = 0;
 -      int nr;
 -      struct input_event hold_quit;
 +      struct display *next = d->next_display;
  
 -      EVENT_INIT (hold_quit);
 -      hold_quit.kind = NO_EVENT;
 +      if (d->read_socket_hook)
 +        {
 +          int discard = 0;
 +          int nr;
  
-           do {
-             struct input_event buf[NREAD_INPUT_EVENTS];
 -      /* No need for FIONREAD or fcntl; just say don't wait.  */
 -      while (nr = (*read_socket_hook) (input_fd, expected, &hold_quit), nr > 0)
 -      {
 -        nread += nr;
 -        expected = 0;
 -      }
 -      if (hold_quit.kind != NO_EVENT)
 -      kbd_buffer_store_event (&hold_quit);
++          struct input_event hold_quit;
 +
-             for (i = 0; i < NREAD_INPUT_EVENTS; i++)
-               EVENT_INIT (buf[i]);
++          EVENT_INIT (hold_quit);
++          hold_quit.kind = NO_EVENT;
 +
-             /* No need for FIONREAD or fcntl; just say don't wait.  */
-             nr = (*d->read_socket_hook) (d, buf, NREAD_INPUT_EVENTS, expected);
++          /* No need for FIONREAD or fcntl; just say don't wait.  */
++          while (nr = (*d->read_socket_hook) (d, expected, &hold_quit), nr > 0)
++            {
++              nread += nr;
++              expected = 0;
++            }
++          
++          if (nr == -1)          /* Not OK to read input now. */
++            {
++              err = 1;
++            }
++          else if (nr == -2)          /* Non-transient error. */
++            {
++              /* The display device terminated; it should be closed. */
++              
++              /* Kill Emacs if this was our last display. */
++              if (! display_list->next_display)
++                /* Formerly simply reported no input, but that
++                   sometimes led to a failure of Emacs to terminate.
++                   SIGHUP seems appropriate if we can't reach the
++                   terminal.  */
++                /* ??? Is it really right to send the signal just to
++                   this process rather than to the whole process
++                   group?  Perhaps on systems with FIONREAD Emacs is
++                   alone in its group.  */
++                kill (getpid (), SIGHUP);
++              
++              /* XXX Is calling delete_display safe here?  It calls Fdelete_frame. */
++              if (d->delete_display_hook)
++                (*d->delete_display_hook) (d);
++              else
++                delete_display (d);
++            }
 +
-             if (nr > 0)
-               {
-                 /* We've got input. */
-                 nread += nr;
-                 expected = 0;
-                 /* Scan the chars for C-g and store them in kbd_buffer.  */
-                 for (i = 0; !discard && i < nr; i++)
-                   {
-                     kbd_buffer_store_event (&buf[i]);
-                     /* Don't look at input that follows a C-g too closely.
-                        This reduces lossage due to autorepeat on C-g.  */
-                     if (buf[i].kind == ASCII_KEYSTROKE_EVENT
-                         && buf[i].code == quit_char)
-                       discard = 1;
-                   }
-               }
-             else if (nr == -1)          /* Not OK to read input now. */
-               {
-                 err = 1;
-               }
-             else if (nr == -2)          /* Non-transient error. */
-               {
-                 /* The display device terminated; it should be closed. */
-                 /* Kill Emacs if this was our last display. */
-                 if (! display_list->next_display)
-                   /* Formerly simply reported no input, but that
-                      sometimes led to a failure of Emacs to terminate.
-                      SIGHUP seems appropriate if we can't reach the
-                      terminal.  */
-                   /* ??? Is it really right to send the signal just to
-                      this process rather than to the whole process
-                      group?  Perhaps on systems with FIONREAD Emacs is
-                      alone in its group.  */
-                   kill (getpid (), SIGHUP);
-                 /* XXX Is calling delete_display safe here?  It calls Fdelete_frame. */
-                 if (d->delete_display_hook)
-                   (*d->delete_display_hook) (d);
-                 else
-                   delete_display (d);
-               }
-           } while (nr == NREAD_INPUT_EVENTS);
++          if (hold_quit.kind != NO_EVENT)
++            kbd_buffer_store_event (&hold_quit);
 +        }
 +
 +      d = next;
      }
 -  else
 -    {
 -      /* Using KBD_BUFFER_SIZE - 1 here avoids reading more than
 -       the kbd_buffer can really hold.  That may prevent loss
 -       of characters on some systems when input is stuffed at us.  */
 -      unsigned char cbuf[KBD_BUFFER_SIZE - 1];
 -      int n_to_read;
  
 -      /* Determine how many characters we should *try* to read.  */
 +  if (err && !nread)
 +    nread = -1;
 +
 +  return nread;
 +}
 +
 +/* This is the tty way of reading available input.
 +
 +   Note that each terminal device has its own `struct display' object,
 +   and so this function is called once for each individual termcap
 +   display.  The first parameter indicates which device to read from.  */
 +
 +int
 +tty_read_avail_input (struct display *display,
-                       struct input_event *buf,
-                       int numchars, int expected)
++                      int expected,
++                      struct input_event *hold_quit)
 +{
-   /* Using numchars here avoids reading more than the buf can
-      really hold.  That may prevent loss of characters on some systems
-      when input is stuffed at us.  */
-   unsigned char cbuf[numchars];
++  /* Using KBD_BUFFER_SIZE - 1 here avoids reading more than
++     the kbd_buffer can really hold.  That may prevent loss
++     of characters on some systems when input is stuffed at us.  */
++  unsigned char cbuf[KBD_BUFFER_SIZE - 1];
 +  int n_to_read, i;
 +  struct tty_display_info *tty = display->display_info.tty;
 +  int nread = 0;
 +
 +  if (display->type != output_termcap)
 +    abort ();
 +
 +  /* XXX I think the following code should be moved to separate hook
 +     functions in system-dependent files. */
  #ifdef WINDOWSNT
 -      return 0;
 +  return 0;
  #else /* not WINDOWSNT */
  #ifdef MSDOS
 -      n_to_read = dos_keysns ();
 -      if (n_to_read == 0)
 -      return 0;
 +  n_to_read = dos_keysns ();
 +  if (n_to_read == 0)
 +    return 0;
 +
 +  cbuf[0] = dos_keyread ();
 +  nread = 1;
 +
  #else /* not MSDOS */
 +
 +  if (! tty->term_initted)      /* In case we get called during bootstrap. */
 +    return 0;
 +
 +  if (! tty->input)
 +    return 0;                   /* The terminal is suspended. */
 +
 +  /* Determine how many characters we should *try* to read.  */
  #ifdef FIONREAD
 -      /* Find out how much input is available.  */
 -      if (ioctl (input_fd, FIONREAD, &n_to_read) < 0)
 -      /* Formerly simply reported no input, but that sometimes led to
 -         a failure of Emacs to terminate.
 -         SIGHUP seems appropriate if we can't reach the terminal.  */
 -      /* ??? Is it really right to send the signal just to this process
 -         rather than to the whole process group?
 -         Perhaps on systems with FIONREAD Emacs is alone in its group.  */
 -      {
 -        if (! noninteractive)
 -          kill (getpid (), SIGHUP);
 -        else
 -          n_to_read = 0;
 -      }
 -      if (n_to_read == 0)
 -      return 0;
 -      if (n_to_read > sizeof cbuf)
 -      n_to_read = sizeof cbuf;
 +  /* Find out how much input is available.  */
 +  if (ioctl (fileno (tty->input), FIONREAD, &n_to_read) < 0)
 +    {
 +      if (! noninteractive)
 +        return -2;          /* Close this display. */
 +      else
 +        n_to_read = 0;
 +    }
 +  if (n_to_read == 0)
 +    return 0;
 +  if (n_to_read > sizeof cbuf)
 +    n_to_read = sizeof cbuf;
  #else /* no FIONREAD */
  #if defined (USG) || defined (DGUX) || defined(CYGWIN)
 -      /* Read some input if available, but don't wait.  */
 -      n_to_read = sizeof cbuf;
 -      fcntl (input_fd, F_SETFL, O_NDELAY);
 +  /* Read some input if available, but don't wait.  */
 +  n_to_read = sizeof cbuf;
 +  fcntl (fileno (tty->input), F_SETFL, O_NDELAY);
  #else
 -      you lose;
 +  you lose;
  #endif
  #endif
 -#endif /* not MSDOS */
 -#endif /* not WINDOWSNT */
  
 -      /* Now read; for one reason or another, this will not block.
 -       NREAD is set to the number of chars read.  */
 -      do
 -      {
 -#ifdef MSDOS
 -        cbuf[0] = dos_keyread ();
 -        nread = 1;
 -#else
 -        nread = emacs_read (input_fd, cbuf, n_to_read);
 -#endif
 -        /* POSIX infers that processes which are not in the session leader's
 -           process group won't get SIGHUP's at logout time.  BSDI adheres to
 -           this part standard and returns -1 from read (0) with errno==EIO
 -           when the control tty is taken away.
 -           Jeffrey Honig <jch@bsdi.com> says this is generally safe.  */
 -        if (nread == -1 && errno == EIO)
 -          kill (0, SIGHUP);
 +  /* Now read; for one reason or another, this will not block.
 +     NREAD is set to the number of chars read.  */
 +  do
 +    {
 +      nread = emacs_read (fileno (tty->input), cbuf, n_to_read);
 +      /* POSIX infers that processes which are not in the session leader's
 +         process group won't get SIGHUP's at logout time.  BSDI adheres to
 +         this part standard and returns -1 from read (0) with errno==EIO
 +         when the control tty is taken away.
 +         Jeffrey Honig <jch@bsdi.com> says this is generally safe. */
 +      if (nread == -1 && errno == EIO)
 +        return -2;          /* Close this display. */
  #if defined (AIX) && (! defined (aix386) && defined (_BSD))
 -        /* The kernel sometimes fails to deliver SIGHUP for ptys.
 -           This looks incorrect, but it isn't, because _BSD causes
 -           O_NDELAY to be defined in fcntl.h as O_NONBLOCK,
 -           and that causes a value other than 0 when there is no input.  */
 -        if (nread == 0)
 -          kill (0, SIGHUP);
 +      /* The kernel sometimes fails to deliver SIGHUP for ptys.
 +         This looks incorrect, but it isn't, because _BSD causes
 +         O_NDELAY to be defined in fcntl.h as O_NONBLOCK,
 +         and that causes a value other than 0 when there is no input.  */
 +      if (nread == 0)
 +        return -2;          /* Close this display. */
  #endif
 -      }
 -      while (
 -           /* We used to retry the read if it was interrupted.
 -              But this does the wrong thing when O_NDELAY causes
 -              an EAGAIN error.  Does anybody know of a situation
 -              where a retry is actually needed?  */
 +    }
 +  while (
 +         /* We used to retry the read if it was interrupted.
 +            But this does the wrong thing when O_NDELAY causes
 +            an EAGAIN error.  Does anybody know of a situation
 +            where a retry is actually needed?  */
  #if 0
 -           nread < 0 && (errno == EAGAIN
 +         nread < 0 && (errno == EAGAIN
  #ifdef EFAULT
 -                         || errno == EFAULT
 +                       || errno == EFAULT
  #endif
  #ifdef EBADSLT
 -                         || errno == EBADSLT
 +                       || errno == EBADSLT
  #endif
 -                         )
 +                       )
  #else
 -           0
 +         0
  #endif
 -           );
 +         );
  
  #ifndef FIONREAD
  #if defined (USG) || defined (DGUX) || defined (CYGWIN)
 -      fcntl (input_fd, F_SETFL, 0);
 +  fcntl (fileno (tty->input), F_SETFL, 0);
  #endif /* USG or DGUX or CYGWIN */
  #endif /* no FIONREAD */
 -      for (i = 0; i < nread; i++)
 -      {
 -        struct input_event buf;
 -        EVENT_INIT (buf);
 -        buf.kind = ASCII_KEYSTROKE_EVENT;
 -        buf.modifiers = 0;
 -        if (meta_key == 1 && (cbuf[i] & 0x80))
 -          buf.modifiers = meta_modifier;
 -        if (meta_key != 2)
 -          cbuf[i] &= ~0x80;
 -
 -        buf.code = cbuf[i];
 -        buf.frame_or_window = selected_frame;
 -        buf.arg = Qnil;
 -
 -        kbd_buffer_store_event (&buf);
 -        /* Don't look at input that follows a C-g too closely.
 -           This reduces lossage due to autorepeat on C-g.  */
 -        if (buf.kind == ASCII_KEYSTROKE_EVENT
 -            && buf.code == quit_char)
 -          break;
 -      }
 +
 +  if (nread <= 0)
 +    return nread;
 +
 +#endif /* not MSDOS */
 +#endif /* not WINDOWSNT */
 +
 +  for (i = 0; i < nread; i++)
 +    {
-       buf[i].kind = ASCII_KEYSTROKE_EVENT;
-       buf[i].modifiers = 0;
++      struct input_event buf;
++      EVENT_INIT (buf);
++      buf.kind = ASCII_KEYSTROKE_EVENT;
++      buf.modifiers = 0;
 +      if (tty->meta_key == 1 && (cbuf[i] & 0x80))
-         buf[i].modifiers = meta_modifier;
++        buf.modifiers = meta_modifier;
 +      if (tty->meta_key != 2)
 +        cbuf[i] &= ~0x80;
-       buf[i].code = cbuf[i];
++      
++      buf.code = cbuf[i];
 +      /* Set the frame corresponding to the active tty.  Note that the
 +         value of selected_frame is not reliable here, redisplay tends
 +         to temporarily change it. */
-       buf[i].frame_or_window = tty->top_frame;
-       buf[i].arg = Qnil;
++      buf.frame_or_window = tty->top_frame;
++      buf.arg = Qnil;
++      
++      kbd_buffer_store_event (&buf);
++      /* Don't look at input that follows a C-g too closely.
++         This reduces lossage due to autorepeat on C-g.  */
++      if (buf.kind == ASCII_KEYSTROKE_EVENT
++          && buf.code == quit_char)
++        break;
      }
  
    return nread;
diff --cc src/keyboard.h
index a084efa77919cae391c2c8318d5b4c2bb80ba738,d92f13a50596b6fc0d9a6b52f5e68cadc31c2f8a..3f38b7ded6b42d747cca8ab6bff4c364f0c18c08
@@@ -340,8 -342,5 +342,8 @@@ extern void kbd_buffer_store_help_even
  extern Lisp_Object menu_item_eval_property P_ ((Lisp_Object));
  extern int  kbd_buffer_events_waiting P_ ((int));
  
- extern int tty_read_avail_input P_ ((struct display *,
-                                      struct input_event *, int, int));
++extern int tty_read_avail_input P_ ((struct display *, int,
++                                     struct input_event *));
 +
  /* arch-tag: 769cbade-1ba9-4950-b886-db265b061aa3
     (do not change this comment) */
diff --cc src/lisp.h
Simple merge
diff --cc src/macterm.c
Simple merge
diff --cc src/sysdep.c
Simple merge
diff --cc src/termhooks.h
index 6b2b0d07867fb47635f48ad31ca625dea4bbb2f6,83721f659122aabdb33661316d4bbe5c14f114b3..49a0cbac85b77da149acd0d425f6cff93892c387
@@@ -273,286 -429,7 +273,287 @@@ enum 
    meta_modifier       =  CHAR_META    /* Under X, the XK_Meta_[LR] keysyms.  */
  };
  
 +#endif /* CONSP */
 +
 +\f
 +/* Display-local parameters. */
 +struct display
 +{
 +  /* Chain of all displays. */
 +  struct display *next_display;
 +
 +  /* The number of frames that are on this display. */
 +  int reference_count;
 +  
 +  /* The type of the display. */
 +  enum output_method type;
 +
 +  /* Display-type dependent data shared amongst all frames on this display. */
 +  union display_info
 +  {
 +    struct tty_display_info *tty;     /* termchar.h */
 +    struct x_display_info *x;         /* xterm.h */
 +  } display_info;
 +
 +\f
 +  /* Terminal characteristics. */
 +  /* XXX Are these really used on non-termcap displays? */
 +  
 +  int must_write_spaces;      /* Nonzero means spaces in the text must
 +                                 actually be output; can't just skip over
 +                                 some columns to leave them blank.  */
 +  int fast_clear_end_of_line;   /* Nonzero means terminal has a `ce' string */
 +  
 +  int line_ins_del_ok;          /* Terminal can insert and delete lines */
 +  int char_ins_del_ok;          /* Terminal can insert and delete chars */
 +  int scroll_region_ok;         /* Terminal supports setting the scroll
 +                                   window */
 +  int scroll_region_cost;     /* Cost of setting the scroll window,
 +                                   measured in characters. */
 +  int memory_below_frame;     /* Terminal remembers lines scrolled
 +                                   off bottom */
 +
 +#if 0  /* These are not used anywhere. */
 +  /* EMACS_INT baud_rate; */  /* Output speed in baud */
 +  int min_padding_speed;      /* Speed below which no padding necessary. */
 +  int dont_calculate_costs;     /* Nonzero means don't bother computing
 +                                   various cost tables; we won't use them. */
  #endif
  
-   */
 +\f
 +  /* Window-based redisplay interface for this device (0 for tty
 +     devices). */
 +  struct redisplay_interface *rif;
 +
 +  /* Frame-based redisplay interface. */
 +  
 +  /* Text display hooks.  */
 +
 +  void (*cursor_to_hook) P_ ((int vpos, int hpos));
 +  void (*raw_cursor_to_hook) P_ ((int, int));
 +  
 +  void (*clear_to_end_hook) P_ ((void));
 +  void (*clear_frame_hook) P_ ((void));
 +  void (*clear_end_of_line_hook) P_ ((int));
 +  
 +  void (*ins_del_lines_hook) P_ ((int, int));
 +  
 +  void (*insert_glyphs_hook) P_ ((struct glyph *s, int n));
 +  void (*write_glyphs_hook) P_ ((struct glyph *s, int n));
 +  void (*delete_glyphs_hook) P_ ((int));
 +  
 +  void (*ring_bell_hook) P_ ((void));
 +  
 +  void (*reset_terminal_modes_hook) P_ ((struct display *));
 +  void (*set_terminal_modes_hook) P_ ((struct display *));
 +  void (*update_begin_hook) P_ ((struct frame *));
 +  void (*update_end_hook) P_ ((struct frame *));
 +  void (*set_terminal_window_hook) P_ ((int));
 +
 +  /* Multi-frame and mouse support hooks.  */
 +
 +  /* Return the current position of the mouse.
 +
 +     Set *f to the frame the mouse is in, or zero if the mouse is in no
 +     Emacs frame.  If it is set to zero, all the other arguments are
 +     garbage.
 +  
 +     If the motion started in a scroll bar, set *bar_window to the
 +     scroll bar's window, *part to the part the mouse is currently over,
 +     *x to the position of the mouse along the scroll bar, and *y to the
 +     overall length of the scroll bar.
 +
 +     Otherwise, set *bar_window to Qnil, and *x and *y to the column and
 +     row of the character cell the mouse is over.
 +
 +     Set *time to the time the mouse was at the returned position.
 +     
 +     This should clear mouse_moved until the next motion
 +     event arrives.  */
 +  void (*mouse_position_hook) P_ ((struct frame **f, int,
 +                                   Lisp_Object *bar_window,
 +                                   enum scroll_bar_part *part,
 +                                   Lisp_Object *x,
 +                                   Lisp_Object *y,
 +                                   unsigned long *time));
 +
 +  /* The window system handling code should set this if the mouse has
 +     moved since the last call to the mouse_position_hook.  Calling that
 +     hook should clear this.  */
 +  int mouse_moved;
 +
 +  /* When a frame's focus redirection is changed, this hook tells the
 +     window system code to re-decide where to put the highlight.  Under
 +     X, this means that Emacs lies about where the focus is.  */
 +  void (*frame_rehighlight_hook) P_ ((struct frame *));
 +
 +  /* If we're displaying frames using a window system that can stack
 +     frames on top of each other, this hook allows you to bring a frame
 +     to the front, or bury it behind all the other windows.  If this
 +     hook is zero, that means the device we're displaying on doesn't
 +     support overlapping frames, so there's no need to raise or lower
 +     anything.
 +     
 +     If RAISE is non-zero, F is brought to the front, before all other
 +     windows.  If RAISE is zero, F is sent to the back, behind all other
 +     windows.  */
 +  void (*frame_raise_lower_hook) P_ ((struct frame *f, int raise));
 +
 +  \f
 +  /* Scroll bar hooks.  */
 +
 +  /* The representation of scroll bars is determined by the code which
 +     implements them, except for one thing: they must be represented by
 +     lisp objects.  This allows us to place references to them in
 +     Lisp_Windows without worrying about those references becoming
 +     dangling references when the scroll bar is destroyed.
 +     
 +     The window-system-independent portion of Emacs just refers to
 +     scroll bars via their windows, and never looks inside the scroll bar
 +     representation; it always uses hook functions to do all the
 +     scroll bar manipulation it needs.
 +     
 +     The `vertical_scroll_bar' field of a Lisp_Window refers to that
 +     window's scroll bar, or is nil if the window doesn't have a
 +     scroll bar.
 +     
 +     The `scroll_bars' and `condemned_scroll_bars' fields of a Lisp_Frame
 +     are free for use by the scroll bar implementation in any way it sees
 +     fit.  They are marked by the garbage collector.  */
 +  
 +  
 +  /* Set the vertical scroll bar for WINDOW to have its upper left corner
 +     at (TOP, LEFT), and be LENGTH rows high.  Set its handle to
 +     indicate that we are displaying PORTION characters out of a total
 +     of WHOLE characters, starting at POSITION.  If WINDOW doesn't yet
 +     have a scroll bar, create one for it.  */
 +  void (*set_vertical_scroll_bar_hook) P_ ((struct window *window,
 +                                            int portion, int whole,
 +                                            int position));
 +
 +
 +  /* The following three hooks are used when we're doing a thorough
 +     redisplay of the frame.  We don't explicitly know which scroll bars
 +     are going to be deleted, because keeping track of when windows go
 +     away is a real pain - can you say set-window-configuration?
 +     Instead, we just assert at the beginning of redisplay that *all*
 +     scroll bars are to be removed, and then save scroll bars from the
 +     fiery pit when we actually redisplay their window.  */
 +  
 +  /* Arrange for all scroll bars on FRAME to be removed at the next call
 +     to `*judge_scroll_bars_hook'.  A scroll bar may be spared if
 +     `*redeem_scroll_bar_hook' is applied to its window before the judgement.
 +     
 +     This should be applied to each frame each time its window tree is
 +     redisplayed, even if it is not displaying scroll bars at the moment;
 +     if the HAS_SCROLL_BARS flag has just been turned off, only calling
 +     this and the judge_scroll_bars_hook will get rid of them.
 +     
 +     If non-zero, this hook should be safe to apply to any frame,
 +     whether or not it can support scroll bars, and whether or not it is
 +     currently displaying them.  */
 +  void (*condemn_scroll_bars_hook) P_ ((struct frame *frame));
 +
 +  /* Unmark WINDOW's scroll bar for deletion in this judgement cycle.
 +     Note that it's okay to redeem a scroll bar that is not condemned.  */
 +  void (*redeem_scroll_bar_hook) P_ ((struct window *window));
 +
 +  /* Remove all scroll bars on FRAME that haven't been saved since the
 +     last call to `*condemn_scroll_bars_hook'.
 +
 +     This should be applied to each frame after each time its window
 +     tree is redisplayed, even if it is not displaying scroll bars at the
 +     moment; if the HAS_SCROLL_BARS flag has just been turned off, only
 +     calling this and condemn_scroll_bars_hook will get rid of them.
 +     
 +     If non-zero, this hook should be safe to apply to any frame,
 +     whether or not it can support scroll bars, and whether or not it is
 +     currently displaying them.  */
 +  void (*judge_scroll_bars_hook) P_ ((struct frame *FRAME));
 +
 +\f
 +  /* Called to read input events.
 +
 +     DISPLAY indicates which display to read from.  Input events
 +     should be read into BUF, the size of which is given in SIZE.
 +     EXPECTED is non-zero if the caller suspects that new input is
 +     available.
 +
 +     A positive return value indicates that that many input events
 +     where read into BUF.
 +     Zero means no events were immediately available.
 +     A value of -1 means a transient read error, while -2 indicates
 +     that the display was closed (hangup), and it should be deleted.
 +
 +     XXX Please note that a non-zero value of EXPECTED only means that
 +     there is available input on at least one of the currently opened
 +     display devices -- but not necessarily on this device.
 +     Therefore, in most cases EXPECTED should be simply ignored.
-                                struct input_event *buf,
-                                int size, int expected));
++
++     XXX This documentation needs to be updated.  */
 +  int (*read_socket_hook) P_ ((struct display *display,
++                               int expected,
++                               struct input_event *hold_quit));
 +
 +  /* Called when a frame's display becomes entirely up to date.  */
 +  void (*frame_up_to_date_hook) P_ ((struct frame *));
 +
 +\f
 +  /* Called to delete the device-specific portions of a frame that is
 +     on this display. */
 +  void (*delete_frame_hook) P_ ((struct frame *));
 +
 +  /* Called after the last frame on this display is deleted, or when
 +     the display device was closed (hangup).
 +     
 +     If this is NULL, then the generic delete_display() is called
 +     instead.
 +
 +     The hook must check for and close any live frames that are still
 +     on the display.  Fdelete_frame ensures that there are no live
 +     frames on the display when it calls this hook, so infinite
 +     recursion is prevented.  */
 +  void (*delete_display_hook) P_ ((struct display *));
 +};
 +
 +
 +/* Chain of all displays currently in use. */
 +extern struct display *display_list;
 +
 +#define FRAME_MUST_WRITE_SPACES(f) ((f)->display->must_write_spaces)
 +#define FRAME_FAST_CLEAR_END_OF_LINE(f) ((f)->display->fast_clear_end_of_line)
 +#define FRAME_LINE_INS_DEL_OK(f) ((f)->display->line_ins_del_ok)
 +#define FRAME_CHAR_INS_DEL_OK(f) ((f)->display->char_ins_del_ok)
 +#define FRAME_SCROLL_REGION_OK(f) ((f)->display->scroll_region_ok)
 +#define FRAME_SCROLL_REGION_COST(f) ((f)->display->scroll_region_cost)
 +#define FRAME_MEMORY_BELOW_FRAME(f) ((f)->display->memory_below_frame)
 +
 +#define FRAME_RIF(f) ((f)->display->rif)
 +
 +#define FRAME_DISPLAY(f) ((f)->display)
 +
 +/* FRAME_WINDOW_P tests whether the frame is a window, and is
 +   defined to be the predicate for the window system being used.  */
 +
 +#ifdef HAVE_X_WINDOWS
 +#define FRAME_WINDOW_P(f) FRAME_X_P (f)
 +#endif
 +#ifdef HAVE_NTGUI
 +#define FRAME_WINDOW_P(f) FRAME_W32_P (f)
 +#endif
 +#ifdef MAC_OS
 +#define FRAME_WINDOW_P(f) FRAME_MAC_P (f)
 +#endif
 +#ifndef FRAME_WINDOW_P
 +#define FRAME_WINDOW_P(f) (0)
 +#endif
 +
 +
 +extern struct display *create_display P_ ((void));
 +extern void delete_display P_ ((struct display *));
 +
 +/* The initial display device, created by initial_term_init. */
 +extern struct display *initial_display;
 +
  /* arch-tag: 33a00ecc-52b5-4186-a410-8801ac9f087d
     (do not change this comment) */
diff --cc src/w32term.c
Simple merge
diff --cc src/window.c
Simple merge
diff --cc src/xsmfns.c
Simple merge
diff --cc src/xterm.c
index 546c93600d460765586611ee965b6590f3ef0cb0,0f1faeafbbd6a66ee43eb0c36009e31401f8a5d1..6100eaacffa55c02889324cc2fe2962cb64b584f
@@@ -6382,49 -6309,37 +6318,37 @@@ handle_one_xevent (dpyinfo, eventp, fin
  
            orig_keysym = keysym;
  
-           if (numchars > 0)
-             {
-               Lisp_Object c;
 -        /* Common for all keysym input events.  */
 -        XSETFRAME (inev.frame_or_window, f);
 -        inev.modifiers
 -          = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f), modifiers);
 -        inev.timestamp = event.xkey.time;
--
-               /* First deal with keysyms which have defined
-                  translations to characters.  */
-               if (keysym >= 32 && keysym < 128)
-                 /* Avoid explicitly decoding each ASCII character.  */
-                 {
-                   bufp->kind = ASCII_KEYSTROKE_EVENT;
-                   bufp->code = keysym;
-                   XSETFRAME (bufp->frame_or_window, f);
-                   bufp->arg = Qnil;
-                   bufp->modifiers
-                     = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f),
-                                               modifiers);
-                   bufp->timestamp = event.xkey.time;
-                   bufp++;
-                   count++;
-                   numchars--;
-                 }
-               /* Now non-ASCII.  */
-               else if (HASH_TABLE_P (Vx_keysym_table)
-                        && (NATNUMP (c = Fgethash (make_number (keysym),
-                                                   Vx_keysym_table,
-                                                   Qnil))))
-                 {
-                   bufp->kind = (SINGLE_BYTE_CHAR_P (XFASTINT (c))
-                                 ? ASCII_KEYSTROKE_EVENT
-                                 : MULTIBYTE_CHAR_KEYSTROKE_EVENT);
-                   bufp->code = XFASTINT (c);
-                   XSETFRAME (bufp->frame_or_window, f);
-                   bufp->arg = Qnil;
-                   bufp->modifiers
-                     = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f),
-                                               modifiers);
-                   bufp->timestamp = event.xkey.time;
-                   bufp++;
-                   count++;
-                   numchars--;
-                 }
-               /* Random non-modifier sorts of keysyms.  */
-               else if (((keysym >= XK_BackSpace && keysym <= XK_Escape)
 -        /* First deal with keysyms which have defined
 -           translations to characters.  */
 -        if (keysym >= 32 && keysym < 128)
 -          /* Avoid explicitly decoding each ASCII character.  */
 -          {
 -            inev.kind = ASCII_KEYSTROKE_EVENT;
 -            inev.code = keysym;
 -            goto done_keysym;
 -          }
 -
 -        /* Now non-ASCII.  */
 -        if (HASH_TABLE_P (Vx_keysym_table)
 -            && (NATNUMP (c = Fgethash (make_number (keysym),
 -                                       Vx_keysym_table,
 -                                       Qnil))))
 -          {
 -            inev.kind = (SINGLE_BYTE_CHAR_P (XFASTINT (c))
 -                          ? ASCII_KEYSTROKE_EVENT
 -                          : MULTIBYTE_CHAR_KEYSTROKE_EVENT);
 -            inev.code = XFASTINT (c);
 -            goto done_keysym;
 -          }
 -
 -        /* Random non-modifier sorts of keysyms.  */
 -        if (((keysym >= XK_BackSpace && keysym <= XK_Escape)
++        /* Common for all keysym input events.  */
++        XSETFRAME (inev.frame_or_window, f);
++        inev.modifiers
++          = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f), modifiers);
++        inev.timestamp = event.xkey.time;
++
++        /* First deal with keysyms which have defined
++           translations to characters.  */
++        if (keysym >= 32 && keysym < 128)
++          /* Avoid explicitly decoding each ASCII character.  */
++          {
++            inev.kind = ASCII_KEYSTROKE_EVENT;
++            inev.code = keysym;
++            goto done_keysym;
++          }
++ 
++        /* Now non-ASCII.  */
++        if (HASH_TABLE_P (Vx_keysym_table)
++            && (NATNUMP (c = Fgethash (make_number (keysym),
++                                       Vx_keysym_table,
++                                       Qnil))))
++          {
++            inev.kind = (SINGLE_BYTE_CHAR_P (XFASTINT (c))
++                          ? ASCII_KEYSTROKE_EVENT
++                          : MULTIBYTE_CHAR_KEYSTROKE_EVENT);
++            inev.code = XFASTINT (c);
++            goto done_keysym;
++          }
++ 
++        /* Random non-modifier sorts of keysyms.  */
++        if (((keysym >= XK_BackSpace && keysym <= XK_Escape)
                          || keysym == XK_Delete
  #ifdef XK_ISO_Left_Tab
                          || (keysym >= XK_ISO_Left_Tab
@@@ -7132,11 -6955,10 +6964,10 @@@ x_dispatch_event (event, display
     EXPECTED is nonzero if the caller knows input is available.  */
  
  static int
- XTread_socket (display, bufp, numchars, expected)
 -XTread_socket (sd, expected, hold_quit)
 -     register int sd;
++XTread_socket (display, expected, hold_quit)
 +     struct display *display;
-      struct input_event *bufp;
-      int numchars;
       int expected;
+      struct input_event *hold_quit;
  {
    int count = 0;
    XEvent event;
diff --cc src/xterm.h
Simple merge