Commit 1113d9db authored by Jim Blandy's avatar Jim Blandy
Browse files

*** empty log message ***

parent 492878e4
...@@ -96,8 +96,9 @@ Lisp_Object Vglyph_table; ...@@ -96,8 +96,9 @@ Lisp_Object Vglyph_table;
Lisp_Object Vstandard_display_table; Lisp_Object Vstandard_display_table;
/* Nonzero means reading single-character input with prompt /* Nonzero means reading single-character input with prompt
so put cursor on minibuffer after the prompt. */ so put cursor on minibuffer after the prompt.
positive means at end of text in echo area;
negative means at beginning of line. */
int cursor_in_echo_area; int cursor_in_echo_area;
/* The currently selected screen. /* The currently selected screen.
...@@ -1056,16 +1057,19 @@ update_screen (s, force, inhibit_hairy_id) ...@@ -1056,16 +1057,19 @@ update_screen (s, force, inhibit_hairy_id)
/* Now just clean up termcap drivers and set cursor, etc. */ /* Now just clean up termcap drivers and set cursor, etc. */
if (!pause) if (!pause)
{ {
if (cursor_in_echo_area)
if (s == selected_screen && cursor_in_echo_area < 0) {
cursor_to (SCREEN_HEIGHT (s) - 1, 0); if (s == selected_screen
else if (s == selected_screen && cursor_in_echo_area && cursor_in_echo_area < 0)
&& !desired_screen->used[SCREEN_HEIGHT (s) - 1]) cursor_to (SCREEN_HEIGHT (s) - 1, 0);
cursor_to (SCREEN_HEIGHT (s), 0); else if (s == selected_screen
else if (cursor_in_echo_area) && ! current_screen->enable[SCREEN_HEIGHT (s) - 1])
cursor_to (SCREEN_HEIGHT (s) - 1, cursor_to (SCREEN_HEIGHT (s) - 1, 0);
min (SCREEN_WIDTH (s) - 1, else
desired_screen->used[SCREEN_HEIGHT (s) - 1])); cursor_to (SCREEN_HEIGHT (s) - 1,
min (SCREEN_WIDTH (s) - 1,
current_screen->used[SCREEN_HEIGHT (s) - 1]));
}
else else
cursor_to (SCREEN_CURSOR_Y (s), max (min (SCREEN_CURSOR_X (s), cursor_to (SCREEN_CURSOR_Y (s), max (min (SCREEN_CURSOR_X (s),
SCREEN_WIDTH (s) - 1), 0)); SCREEN_WIDTH (s) - 1), 0));
...@@ -1906,9 +1910,10 @@ Value is t if waited the full time with no input arriving.") ...@@ -1906,9 +1910,10 @@ Value is t if waited the full time with no input arriving.")
Lisp_Object arg, millisec, nodisp; Lisp_Object arg, millisec, nodisp;
{ {
int usec = 0; int usec = 0;
int sec = 0; int sec;
CHECK_NUMBER (arg, 0); CHECK_NUMBER (arg, 0);
sec = XINT (arg);
if (!NILP (millisec)) if (!NILP (millisec))
{ {
......
/* Generic screen functions. /* Generic screen functions.
Copyright (C) 1989 Free Software Foundation. Copyright (C) 1989, 1992 Free Software Foundation.
This file is part of GNU Emacs. This file is part of GNU Emacs.
GNU Emacs is free software; you can redistribute it and/or modify GNU Emacs is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option) the Free Software Foundation; either version 2, or (at your option)
any later version. any later version.
GNU Emacs is distributed in the hope that it will be useful, GNU Emacs is distributed in the hope that it will be useful,
...@@ -194,7 +194,9 @@ make_screen_without_minibuffer (mini_window) ...@@ -194,7 +194,9 @@ make_screen_without_minibuffer (mini_window)
if (NILP (mini_window)) if (NILP (mini_window))
{ {
if (XTYPE (Vdefault_minibuffer_screen) != Lisp_Screen) if (XTYPE (Vdefault_minibuffer_screen) != Lisp_Screen)
error ("default-minibuffer-screen must be set when creating minibufferless screens."); error ("default-minibuffer-screen must be set when creating minibufferless screens");
if (! SCREEN_LIVE_P (XSCREEN (Vdefault_minibuffer_screen)))
error ("default-minibuffer-screen must be a live screen");
mini_window = XSCREEN (Vdefault_minibuffer_screen)->minibuffer_window; mini_window = XSCREEN (Vdefault_minibuffer_screen)->minibuffer_window;
} }
else else
...@@ -492,16 +494,22 @@ A screen may not be deleted if its minibuffer is used by other screens.") ...@@ -492,16 +494,22 @@ A screen may not be deleted if its minibuffer is used by other screens.")
minibuffer for any other screen? */ minibuffer for any other screen? */
if (SCREEN_HAS_MINIBUF (XSCREEN (screen))) if (SCREEN_HAS_MINIBUF (XSCREEN (screen)))
{ {
Lisp_Object screen2; Lisp_Object screens;
for (screen2 = Vscreen_list; CONSP (2); screen2 = XCONS (screen2)->cdr) for (screens = Vscreen_list;
if (! EQ (screen2, screen) CONSP (screens);
&& EQ (screen, screens = XCONS (screens)->cdr)
(WINDOW_SCREEN {
(XWINDOW Lisp_Object this = XCONS (screens)->car;
(SCREEN_MINIBUF_WINDOW
(XSCREEN (screen2))))))) if (! EQ (this, screen)
error ("Attempt to delete a surrogate minibuffer screen"); && EQ (screen,
(WINDOW_SCREEN
(XWINDOW
(SCREEN_MINIBUF_WINDOW
(XSCREEN (this)))))))
error ("Attempt to delete a surrogate minibuffer screen");
}
} }
/* Don't let the screen remain selected. */ /* Don't let the screen remain selected. */
...@@ -530,11 +538,15 @@ A screen may not be deleted if its minibuffer is used by other screens.") ...@@ -530,11 +538,15 @@ A screen may not be deleted if its minibuffer is used by other screens.")
another one. */ another one. */
if (s == last_nonminibuf_screen) if (s == last_nonminibuf_screen)
{ {
Lisp_Object screens;
last_nonminibuf_screen = 0; last_nonminibuf_screen = 0;
for (screen = Vscreen_list; CONSP (screen); screen = XCONS (screen)->cdr) for (screens = Vscreen_list;
CONSP (screens);
screen = XCONS (screens)->cdr)
{ {
s = XSCREEN (XCONS (screen)->car); s = XSCREEN (XCONS (screens)->car);
if (!SCREEN_MINIBUF_ONLY_P (s)) if (!SCREEN_MINIBUF_ONLY_P (s))
{ {
last_nonminibuf_screen = s; last_nonminibuf_screen = s;
...@@ -543,6 +555,46 @@ A screen may not be deleted if its minibuffer is used by other screens.") ...@@ -543,6 +555,46 @@ A screen may not be deleted if its minibuffer is used by other screens.")
} }
} }
/* If we've deleted Vdefault_minibuffer_screen, try to find another
one. Prefer minibuffer-only screens, but also notice screens
with other windows. */
if (EQ (screen, Vdefault_minibuffer_screen))
{
Lisp_Object screens;
/* The last screen we saw with a minibuffer, minibuffer-only or not. */
Lisp_Object screen_with_minibuf = Qnil;
for (screens = Vscreen_list;
CONSP (screens);
screens = XCONS (screens)->cdr)
{
Lisp_Object this = XCONS (screens)->car;
if (XTYPE (this) != Lisp_Screen)
abort ();
s = XSCREEN (this);
if (SCREEN_HAS_MINIBUF (s))
{
screen_with_minibuf = this;
if (SCREEN_MINIBUF_ONLY_P (s))
break;
}
}
/* We know that there must be some screen with a minibuffer out
there. If this were not true, all of the screens present
would have to be minibufferless, which implies that at some
point their minibuffer screens must have been deleted, but
that is prohibited at the top; you can't delete surrogate
minibuffer screens. */
if (NILP (screen_with_minibuf))
abort ();
Vdefault_minibuffer_screen = screen_with_minibuf;
}
return Qnil; return Qnil;
} }
......
...@@ -210,7 +210,8 @@ Lisp_Object Vmouse_motion_handler; ...@@ -210,7 +210,8 @@ Lisp_Object Vmouse_motion_handler;
new screen. */ new screen. */
Lisp_Object Vlast_event_screen; Lisp_Object Vlast_event_screen;
/* X Windows wants this for selection ownership. */ /* The timestamp of the last input event we received from the X server.
X Windows wants this for selection ownership. */
unsigned long last_event_timestamp; unsigned long last_event_timestamp;
Lisp_Object Qself_insert_command; Lisp_Object Qself_insert_command;
...@@ -1610,7 +1611,7 @@ kbd_buffer_get_event () ...@@ -1610,7 +1611,7 @@ kbd_buffer_get_event ()
if (kbd_fetch_ptr == kbd_buffer + KBD_BUFFER_SIZE) if (kbd_fetch_ptr == kbd_buffer + KBD_BUFFER_SIZE)
kbd_fetch_ptr = kbd_buffer; kbd_fetch_ptr = kbd_buffer;
XSET (Vlast_event_screen, Lisp_Screen, kbd_fetch_ptr->screen); XSET (Vlast_event_screen, Lisp_Screen, kbd_fetch_ptr->screen);
last_event_timestamp = XINT (kbd_fetch_ptr->timestamp); last_event_timestamp = kbd_fetch_ptr->timestamp;
obj = make_lispy_event (kbd_fetch_ptr); obj = make_lispy_event (kbd_fetch_ptr);
kbd_fetch_ptr->kind = no_event; kbd_fetch_ptr->kind = no_event;
kbd_fetch_ptr++; kbd_fetch_ptr++;
...@@ -1791,7 +1792,8 @@ make_lispy_event (event) ...@@ -1791,7 +1792,8 @@ make_lispy_event (event)
Fcons (window, Fcons (window,
Fcons (posn, Fcons (posn,
Fcons (Fcons (event->x, event->y), Fcons (Fcons (event->x, event->y),
Fcons (event->timestamp, Fcons (make_number
(event->timestamp),
Qnil))))); Qnil)))));
} }
...@@ -1810,7 +1812,8 @@ make_lispy_event (event) ...@@ -1810,7 +1812,8 @@ make_lispy_event (event)
Fcons (SCREEN_SELECTED_WINDOW (event->screen), Fcons (SCREEN_SELECTED_WINDOW (event->screen),
Fcons (button, Fcons (button,
Fcons (Fcons (event->x, event->y), Fcons (Fcons (event->x, event->y),
Fcons (event->timestamp, Fcons (make_number
(event->timestamp),
Qnil))))); Qnil)))));
} }
...@@ -1872,8 +1875,8 @@ format_modifiers (modifiers, buf) ...@@ -1872,8 +1875,8 @@ format_modifiers (modifiers, buf)
{ {
char *p = buf; char *p = buf;
if (modifiers & meta_modifier) { *p++ = 'M'; *p++ = '-'; }
if (modifiers & ctrl_modifier) { *p++ = 'C'; *p++ = '-'; } if (modifiers & ctrl_modifier) { *p++ = 'C'; *p++ = '-'; }
if (modifiers & meta_modifier) { *p++ = 'M'; *p++ = '-'; }
if (modifiers & shift_modifier) { *p++ = 'S'; *p++ = '-'; } if (modifiers & shift_modifier) { *p++ = 'S'; *p++ = '-'; }
if (modifiers & up_modifier) { *p++ = 'U'; *p++ = '-'; } if (modifiers & up_modifier) { *p++ = 'U'; *p++ = '-'; }
*p = '\0'; *p = '\0';
...@@ -2982,17 +2985,31 @@ DEFUN ("execute-extended-command", Fexecute_extended_command, Sexecute_extended_ ...@@ -2982,17 +2985,31 @@ DEFUN ("execute-extended-command", Fexecute_extended_command, Sexecute_extended_
Vobarray, Qcommandp, Vobarray, Qcommandp,
Qt, Qnil, Qnil); Qt, Qnil, Qnil);
/* Add the text read to this_command_keys. */ /* Set this_command_keys to the concatenation of saved_keys and
function, followed by a RET. */
{ {
struct Lisp_String *func_str = XSTRING (function); struct Lisp_String *str;
int i; int i;
Lisp_Object tem; Lisp_Object tem;
for (i = 0; i < func_str->size; i++) this_command_key_count = 0;
str = XSTRING (saved_keys);
for (i = 0; i < str->size; i++)
{ {
XSET (tem, Lisp_Int, func_str->data[i]); XFASTINT (tem) = str->data[i];
add_command_key (tem); add_command_key (tem);
} }
str = XSTRING (function);
for (i = 0; i < str->size; i++)
{
XFASTINT (tem) = str->data[i];
add_command_key (tem);
}
XFASTINT (tem) = '\015';
add_command_key (tem);
} }
UNGCPRO; UNGCPRO;
......
...@@ -47,8 +47,16 @@ Lisp_Object last_regexp; ...@@ -47,8 +47,16 @@ Lisp_Object last_regexp;
Since the registers are now dynamically allocated, we need to make Since the registers are now dynamically allocated, we need to make
sure not to refer to the Nth register before checking that it has sure not to refer to the Nth register before checking that it has
been allocated. */ been allocated by checking search_regs.num_regs.
The regex code keeps track of whether it has allocated the search
buffer using bits in searchbuf. This means that whenever you
compile a new pattern, it completely forgets whether it has
allocated any registers, and will allocate new registers the next
time you call a searching or matching function. Therefore, we need
to call re_set_registers after compiling a new pattern or after
setting the match registers, so that the regex functions will be
able to free or re-allocate it properly. */
static struct re_registers search_regs; static struct re_registers search_regs;
/* Nonzero if search_regs are indices in a string; 0 if in a buffer. */ /* Nonzero if search_regs are indices in a string; 0 if in a buffer. */
...@@ -73,9 +81,10 @@ matcher_overflow () ...@@ -73,9 +81,10 @@ matcher_overflow ()
/* Compile a regexp and signal a Lisp error if anything goes wrong. */ /* Compile a regexp and signal a Lisp error if anything goes wrong. */
compile_pattern (pattern, bufp, translate) compile_pattern (pattern, bufp, regp, translate)
Lisp_Object pattern; Lisp_Object pattern;
struct re_pattern_buffer *bufp; struct re_pattern_buffer *bufp;
struct re_registers *regp;
char *translate; char *translate;
{ {
CONST char *val; CONST char *val;
...@@ -84,6 +93,7 @@ compile_pattern (pattern, bufp, translate) ...@@ -84,6 +93,7 @@ compile_pattern (pattern, bufp, translate)
if (EQ (pattern, last_regexp) if (EQ (pattern, last_regexp)
&& translate == bufp->translate) && translate == bufp->translate)
return; return;
last_regexp = Qnil; last_regexp = Qnil;
bufp->translate = translate; bufp->translate = translate;
val = re_compile_pattern ((char *) XSTRING (pattern)->data, val = re_compile_pattern ((char *) XSTRING (pattern)->data,
...@@ -95,7 +105,13 @@ compile_pattern (pattern, bufp, translate) ...@@ -95,7 +105,13 @@ compile_pattern (pattern, bufp, translate)
while (1) while (1)
Fsignal (Qinvalid_regexp, Fcons (dummy, Qnil)); Fsignal (Qinvalid_regexp, Fcons (dummy, Qnil));
} }
last_regexp = pattern; last_regexp = pattern;
/* Advise the searching functions about the space we have allocated
for register data. */
re_set_registers (bufp, regp, regp->num_regs, regp->start, regp->end);
return; return;
} }
...@@ -124,7 +140,7 @@ data if you want to preserve them.") ...@@ -124,7 +140,7 @@ data if you want to preserve them.")
register int i; register int i;
CHECK_STRING (string, 0); CHECK_STRING (string, 0);
compile_pattern (string, &searchbuf, compile_pattern (string, &searchbuf, &search_regs,
!NILP (current_buffer->case_fold_search) ? DOWNCASE_TABLE : 0); !NILP (current_buffer->case_fold_search) ? DOWNCASE_TABLE : 0);
immediate_quit = 1; immediate_quit = 1;
...@@ -196,7 +212,7 @@ matched by parenthesis constructs in the pattern.") ...@@ -196,7 +212,7 @@ matched by parenthesis constructs in the pattern.")
args_out_of_range (string, start); args_out_of_range (string, start);
} }
compile_pattern (regexp, &searchbuf, compile_pattern (regexp, &searchbuf, &search_regs,
!NILP (current_buffer->case_fold_search) ? DOWNCASE_TABLE : 0); !NILP (current_buffer->case_fold_search) ? DOWNCASE_TABLE : 0);
immediate_quit = 1; immediate_quit = 1;
val = re_search (&searchbuf, (char *) XSTRING (string)->data, val = re_search (&searchbuf, (char *) XSTRING (string)->data,
...@@ -506,7 +522,7 @@ search_buffer (string, pos, lim, n, RE, trt, inverse_trt) ...@@ -506,7 +522,7 @@ search_buffer (string, pos, lim, n, RE, trt, inverse_trt)
return pos; return pos;
if (RE) if (RE)
compile_pattern (string, &searchbuf, (char *) trt); compile_pattern (string, &searchbuf, &search_regs, (char *) trt);
if (RE /* Here we detect whether the */ if (RE /* Here we detect whether the */
/* generality of an RE search is */ /* generality of an RE search is */
...@@ -768,6 +784,22 @@ search_buffer (string, pos, lim, n, RE, trt, inverse_trt) ...@@ -768,6 +784,22 @@ search_buffer (string, pos, lim, n, RE, trt, inverse_trt)
if (i + direction == 0) if (i + direction == 0)
{ {
cursor -= direction; cursor -= direction;
/* Make sure we have registers in which to store
the match position. */
if (search_regs.num_regs == 0)
{
regoff_t *starts, *ends;
starts =
(regoff_t *) xmalloc (2 * sizeof (regoff_t));
ends =
(regoff_t *) xmalloc (2 * sizeof (regoff_t));
re_set_registers (&searchbuf,
&search_regs,
2, starts, ends);
}
search_regs.start[0] search_regs.start[0]
= pos + cursor - p2 + ((direction > 0) = pos + cursor - p2 + ((direction > 0)
? 1 - len : 0); ? 1 - len : 0);
...@@ -827,6 +859,22 @@ search_buffer (string, pos, lim, n, RE, trt, inverse_trt) ...@@ -827,6 +859,22 @@ search_buffer (string, pos, lim, n, RE, trt, inverse_trt)
if (i + direction == 0) if (i + direction == 0)
{ {
pos -= direction; pos -= direction;
/* Make sure we have registers in which to store
the match position. */
if (search_regs.num_regs == 0)
{
regoff_t *starts, *ends;
starts =
(regoff_t *) xmalloc (2 * sizeof (regoff_t));
ends =
(regoff_t *) xmalloc (2 * sizeof (regoff_t));
re_set_registers (&searchbuf,
&search_regs,
2, starts, ends);
}
search_regs.start[0] search_regs.start[0]
= pos + ((direction > 0) ? 1 - len : 0); = pos + ((direction > 0) ? 1 - len : 0);
search_regs.end[0] = len + search_regs.start[0]; search_regs.end[0] = len + search_regs.start[0];
...@@ -1004,6 +1052,7 @@ Otherwise treat `\\' as special:\n\ ...@@ -1004,6 +1052,7 @@ Otherwise treat `\\' as special:\n\
`\\N' means substitute what matched the Nth `\\(...\\)'.\n\ `\\N' means substitute what matched the Nth `\\(...\\)'.\n\
If Nth parens didn't match, substitute nothing.\n\ If Nth parens didn't match, substitute nothing.\n\
`\\\\' means insert one `\\'.\n\ `\\\\' means insert one `\\'.\n\
FIXEDCASE and LITERAL are optional arguments.\n\
Leaves point at end of replacement text.") Leaves point at end of replacement text.")
(string, fixedcase, literal) (string, fixedcase, literal)
Lisp_Object string, fixedcase, literal; Lisp_Object string, fixedcase, literal;
...@@ -1221,20 +1270,25 @@ LIST should have been created by calling `match-data' previously.") ...@@ -1221,20 +1270,25 @@ LIST should have been created by calling `match-data' previously.")
if (length > search_regs.num_regs) if (length > search_regs.num_regs)
{ {
if (search_regs.start) if (search_regs.num_regs == 0)
search_regs.start = {
(regoff_t *) realloc (search_regs.start, search_regs.start
length * sizeof (regoff_t)); = (regoff_t *) xmalloc (length * sizeof (regoff_t));
else search_regs.end
search_regs.start = (regoff_t *) malloc (length * sizeof (regoff_t)); = (regoff_t *) xmalloc (length * sizeof (regoff_t));
if (search_regs.end) }
search_regs.end =
(regoff_t *) realloc (search_regs.end,
length * sizeof (regoff_t));
else else
search_regs.end = (regoff_t *) malloc (length * sizeof (regoff_t)); {
search_regs.start
= (regoff_t *) xrealloc (search_regs.start,
length * sizeof (regoff_t));
search_regs.end
= (regoff_t *) xrealloc (search_regs.end,
length * sizeof (regoff_t));
}
search_regs.num_regs = length; re_set_registers (&searchbuf, &search_regs, length,
search_regs.start, search_regs.end);
} }
} }
......
...@@ -105,7 +105,7 @@ struct input_event { ...@@ -105,7 +105,7 @@ struct input_event {
.modifiers holds the state of the .modifiers holds the state of the
modifier keys. modifier keys.
.x and .y give the mouse position, .x and .y give the mouse position,
in pixels, within the window. in characters, within the window.
.screen gives the screen the mouse .screen gives the screen the mouse
click occurred in. click occurred in.
.timestamp gives a timestamp (in .timestamp gives a timestamp (in
......
/* Window creation, deletion and examination for GNU Emacs. /* Window creation, deletion and examination for GNU Emacs.
Does not include redisplay. Does not include redisplay.
Copyright (C) 1985, 1986, 1987 Free Software Foundation, Inc. Copyright (C) 1985, 1986, 1987, 1992 Free Software Foundation, Inc.
This file is part of GNU Emacs. This file is part of GNU Emacs.
GNU Emacs is free software; you can redistribute it and/or modify GNU Emacs is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option) the Free Software Foundation; either version 2, or (at your option)
any later version. any later version.
GNU Emacs is distributed in the hope that it will be useful, GNU Emacs is distributed in the hope that it will be useful,
...@@ -357,7 +357,10 @@ coordinates_in_window (w, x, y) ...@@ -357,7 +357,10 @@ coordinates_in_window (w, x, y)
DEFUN ("coordinates-in-window-p", Fcoordinates_in_window_p, DEFUN ("coordinates-in-window-p", Fcoordinates_in_window_p,
Scoordinates_in_window_p, 2, 2, 0, Scoordinates_in_window_p, 2, 2, 0,
"Return non-nil if COORDINATES are in WINDOW.\n\ "Return non-nil if COORDINATES are in WINDOW.\n\
COORDINATES is a cons of the form (X . Y), X and Y being screen-relative.\n\ COORDINATES is a cons of the form (X . Y), X and Y being distances\n\
measured in characters from the upper-left corner of the screen.\n\
(0 . 0) denotes the character in the upper left corner of the\n\
screen.\n\
If COORDINATES are in the text portion of WINDOW,\n\ If COORDINATES are in the text portion of WINDOW,\n\
the coordinates relative to the window are returned.\n\ the coordinates relative to the window are returned.\n\
If they are in the mode line of WINDOW, 'mode-line is returned.\n\ If they are in the mode line of WINDOW, 'mode-line is returned.\n\
......
/* Functions for the X window system. /* Functions for the X window system.
Copyright (C) 1989 Free Software Foundation. Copyright (C) 1989, 1992 Free Software Foundation.
This file is part of GNU Emacs. This file is part of GNU Emacs.
GNU Emacs is free software; you can redistribute it and/or modify GNU Emacs is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 1, or (at your option) the Free Software Foundation; either version 2, or (at your option)
any later version. any later version.
GNU Emacs is distributed in the hope that it will be useful, GNU Emacs is distributed in the hope that it will be useful,
...@@ -1045,6 +1045,17 @@ x_set_name (s, arg, oldval) ...@@ -1045,6 +1045,17 @@ x_set_name (s, arg, oldval)
if (s->display.x->window_desc) if (s->display.x->window_desc)
{ {