/* Keyboard and mouse input; editor command loop.
-Copyright (C) 1985-1989, 1993-1997, 1999-2013 Free Software Foundation,
-Inc.
+Copyright (C) 1985-1989, 1993-1997, 1999-2014 Free Software Foundation, Inc.
This file is part of GNU Emacs.
#include <config.h>
#include "sysstdio.h"
+#include <sys/stat.h>
#include "lisp.h"
#include "termchar.h"
/* Symbols to use for parts of windows. */
Lisp_Object Qmode_line;
Lisp_Object Qvertical_line;
+Lisp_Object Qright_divider, Qbottom_divider;
static Lisp_Object Qvertical_scroll_bar;
Lisp_Object Qmenu_bar;
\f
DEFUN ("recursive-edit", Frecursive_edit, Srecursive_edit, 0, 0, "",
doc: /* Invoke the editor command loop recursively.
-To get out of the recursive edit, a command can do `(throw 'exit nil)';
-that tells this function to return.
-Alternatively, `(throw 'exit t)' makes this function signal an error.
+To get out of the recursive edit, a command can throw to `exit' -- for
+instance `(throw 'exit nil)'.
+If you throw a value other than t, `recursive-edit' returns normally
+to the function that called it. Throwing a t value causes
+`recursive-edit' to quit, so that control returns to the command loop
+one level up.
+
This function is called by the editor initialization to begin editing. */)
(void)
{
if (input_blocked_p ())
return Qnil;
- command_loop_level++;
- update_mode_lines = 1;
-
- if (command_loop_level
+ if (command_loop_level >= 0
&& current_buffer != XBUFFER (XWINDOW (selected_window)->contents))
buffer = Fcurrent_buffer ();
else
buffer = Qnil;
+ /* Don't do anything interesting between the increment and the
+ record_unwind_protect! Otherwise, we could get distracted and
+ never decrement the counter again. */
+ command_loop_level++;
+ update_mode_lines = 17;
+ record_unwind_protect (recursive_edit_unwind, buffer);
+
/* If we leave recursive_edit_1 below with a `throw' for instance,
like it is done in the splash screen display, we have to
make sure that we restore single_kboard as command_loop_1
would have done if it were left normally. */
if (command_loop_level > 0)
temporarily_switch_to_single_kboard (SELECTED_FRAME ());
- record_unwind_protect (recursive_edit_unwind, buffer);
recursive_edit_1 ();
return unbind_to (count, Qnil);
Fset_buffer (buffer);
command_loop_level--;
- update_mode_lines = 1;
+ update_mode_lines = 18;
}
\f
/* The last boundary auto-added to buffer-undo-list. */
Lisp_Object last_undo_boundary;
+extern Lisp_Object Qregion_extract_function;
+
/* FIXME: This is wrong rather than test window-system, we should call
a new set-selection, which will then dispatch to x-set-selection, or
tty-set-selection, or w32-set-selection, ... */
&& NILP (Fmemq (Vthis_command,
Vselection_inhibit_update_commands)))
{
- ptrdiff_t beg =
- XINT (Fmarker_position (BVAR (current_buffer, mark)));
- ptrdiff_t end = PT;
- if (beg < end)
- call2 (Qx_set_selection, QPRIMARY,
- make_buffer_string (beg, end, 0));
- else if (beg > end)
- call2 (Qx_set_selection, QPRIMARY,
- make_buffer_string (end, beg, 0));
- /* Don't set empty selections. */
+ Lisp_Object txt
+ = call1 (Fsymbol_value (Qregion_extract_function), Qnil);
+ if (XINT (Flength (txt)) > 0)
+ /* Don't set empty selections. */
+ call2 (Qx_set_selection, QPRIMARY, txt);
}
if (current_buffer != prev_buffer || MODIFF != prev_modiff)
than skip both boundaries. However, this code
also stops anywhere in a non-sticky text-property,
which breaks (e.g.) Org mode. */
- && (val = get_pos_property (make_number (end),
- Qinvisible, Qnil),
+ && (val = Fget_pos_property (make_number (end),
+ Qinvisible, Qnil),
TEXT_PROP_MEANS_INVISIBLE (val))
#endif
&& !NILP (val = get_char_property_and_overlay
}
while (beg > BEGV
#if 0
- && (val = get_pos_property (make_number (beg),
- Qinvisible, Qnil),
+ && (val = Fget_pos_property (make_number (beg),
+ Qinvisible, Qnil),
TEXT_PROP_MEANS_INVISIBLE (val))
#endif
&& !NILP (val = get_char_property_and_overlay
to the other end would mean moving backwards and thus
could lead to an infinite loop. */
;
- else if (val = get_pos_property (make_number (PT),
- Qinvisible, Qnil),
+ else if (val = Fget_pos_property (make_number (PT),
+ Qinvisible, Qnil),
TEXT_PROP_MEANS_INVISIBLE (val)
- && (val = get_pos_property
- (make_number (PT == beg ? end : beg),
- Qinvisible, Qnil),
+ && (val = (Fget_pos_property
+ (make_number (PT == beg ? end : beg),
+ Qinvisible, Qnil)),
!TEXT_PROP_MEANS_INVISIBLE (val)))
(check_composition = check_display = 1,
SET_PT (PT == beg ? end : beg));
static struct atimer *poll_timer;
-/* Poll for input, so that we catch a C-g if it comes in. This
- function is called from x_make_frame_visible, see comment
- there. */
-
+/* Poll for input, so that we catch a C-g if it comes in. */
void
poll_for_input_1 (void)
{
been turned off in process.c. */
turn_on_atimers (1);
- /* If poll timer doesn't exist, are we need one with
+ /* If poll timer doesn't exist, or we need one with
a different interval, start a new one. */
if (poll_timer == NULL
|| poll_timer->interval.tv_sec != polling_period)
\f
/* Apply the control modifier to CHARACTER. */
-#ifndef WINDOWSNT
+#ifndef HAVE_NTGUI
static
#endif
int
\f
-/* Input of single characters from keyboard */
+/* Input of single characters from keyboard. */
static Lisp_Object kbd_buffer_get_event (KBOARD **kbp, bool *used_mouse_menu,
struct timespec *end_time);
-2 means do neither.
1 means do both. */
-/* The arguments MAP is for menu prompting. MAP is a keymap.
+/* The argument MAP is a keymap for menu prompting.
PREV_EVENT is the previous input event, or nil if we are reading
the first event of a key sequence (or not reading a key sequence).
{
c = read_decoded_event_from_main_queue (end_time, local_getcjmp,
prev_event, used_mouse_menu);
- if (end_time && timespec_cmp (*end_time, current_timespec ()) <= 0)
- goto exit;
+ if (NILP(c) && end_time &&
+ timespec_cmp (*end_time, current_timespec ()) <= 0)
+ {
+ goto exit;
+ }
+
if (EQ (c, make_number (-2)))
{
/* This is going to exit from read_char
RETURN_UNGCPRO (c);
}
-#ifdef HAVE_MENUS
-
/* Record a key that came from a mouse menu.
Record it for echoing, for this-command-keys, and so on. */
/* Record this character as part of the current key. */
add_command_key (c);
- /* Re-reading in the middle of a command */
+ /* Re-reading in the middle of a command. */
last_input_event = c;
num_input_events++;
}
-#endif /* HAVE_MENUS */
-
/* Return true if should recognize C as "the help character". */
static bool
*kbd_store_ptr = *event;
++kbd_store_ptr;
#ifdef subprocesses
- if (kbd_buffer_nr_stored () > KBD_BUFFER_SIZE/2 && ! kbd_on_hold_p ())
+ if (kbd_buffer_nr_stored () > KBD_BUFFER_SIZE / 2
+ && ! kbd_on_hold_p ())
{
/* Don't read keyboard input until we have processed kbd_buffer.
This happens when pasting text longer than KBD_BUFFER_SIZE/2. */
}
#endif /* subprocesses */
-#ifndef HAVE_DBUS /* We want to read D-Bus events in batch mode. */
+#if !defined HAVE_DBUS && !defined USE_FILE_NOTIFY
if (noninteractive
/* In case we are running as a daemon, only do this before
detaching from the terminal. */
*kbp = current_kboard;
return obj;
}
-#endif /* ! HAVE_DBUS */
+#endif /* !defined HAVE_DBUS && !defined USE_FILE_NOTIFY */
/* Wait until there is input available. */
for (;;)
dy = yret = wy;
}
/* Nothing special for part == ON_SCROLL_BAR. */
+ else if (part == ON_RIGHT_DIVIDER)
+ {
+ posn = Qright_divider;
+ width = WINDOW_RIGHT_DIVIDER_WIDTH (w);
+ dx = xret = wx;
+ dy = yret = wy;
+ }
+ else if (part == ON_BOTTOM_DIVIDER)
+ {
+ posn = Qbottom_divider;
+ width = WINDOW_BOTTOM_DIVIDER_WIDTH (w);
+ dx = xret = wx;
+ dy = yret = wy;
+ }
/* For clicks in the text area, fringes, or margins, call
buffer_posn_from_coords to extract TEXTPOS, the buffer
/* End critical section.
If doing signal-driven input, and a signal came in when input was
- blocked, reinvoke the signal handler now to deal with it. */
+ blocked, reinvoke the signal handler now to deal with it.
+
+ It will also process queued input, if it was not read before.
+ When a longer code sequence does not use block/unblock input
+ at all, the whole input gathered up to the next call to
+ unblock_input will be processed inside that call. */
void
unblock_input (void)
if (! menu_prompting)
return Qnil;
-#ifdef HAVE_MENUS
/* If we got to this point via a mouse click,
use a real menu for mouse selection. */
if (EVENT_HAS_PARAMETERS (prev_event)
*used_mouse_menu = 1;
return value;
}
-#endif /* HAVE_MENUS */
return Qnil ;
}
first_unbound = min (t, first_unbound);
head = EVENT_HEAD (key);
- if (help_char_p (head) && t > 0)
- {
- read_key_sequence_cmd = Vprefix_help_command;
- keybuf[t++] = key;
- last_nonmenu_event = key;
- /* The Microsoft C compiler can't handle the goto that
- would go here. */
- dummyflag = 1;
- break;
- }
if (SYMBOLP (head))
{
goto replay_sequence;
}
+
+ if (NILP (current_binding)
+ && help_char_p (EVENT_HEAD (key)) && t > 1)
+ {
+ read_key_sequence_cmd = Vprefix_help_command;
+ /* The Microsoft C compiler can't handle the goto that
+ would go here. */
+ dummyflag = 1;
+ break;
+ }
+
/* If KEY is not defined in any of the keymaps,
and cannot be part of a function key or translation,
and is a shifted function key,
"FOpen dribble file: ",
doc: /* Start writing all keyboard characters to a dribble file called FILE.
If FILE is nil, close any open dribble file.
-The file will be closed when Emacs exits. */)
+The file will be closed when Emacs exits.
+
+Be aware that this records ALL characters you type!
+This may include sensitive information such as passwords. */)
(Lisp_Object file)
{
if (dribble)
}
if (!NILP (file))
{
+ int fd;
+ Lisp_Object encfile;
+
file = Fexpand_file_name (file, Qnil);
- dribble = emacs_fopen (SSDATA (file), "w");
+ encfile = ENCODE_FILE (file);
+ fd = emacs_open (SSDATA (encfile), O_WRONLY | O_CREAT | O_EXCL, 0600);
+ if (fd < 0 && errno == EEXIST && unlink (SSDATA (encfile)) == 0)
+ fd = emacs_open (SSDATA (encfile), O_WRONLY | O_CREAT | O_EXCL, 0600);
+ dribble = fd < 0 ? 0 : fdopen (fd, "w");
if (dribble == 0)
report_file_error ("Opening dribble", file);
}
with a window system; but suspend should be disabled in that case. */
get_tty_size (fileno (CURTTY ()->input), &width, &height);
if (width != old_width || height != old_height)
- change_frame_size (SELECTED_FRAME (), height, width, 0, 0, 0);
+ change_frame_size (SELECTED_FRAME (), width, height, 0, 0, 0, 0);
/* Run suspend-resume-hook. */
hook = intern ("suspend-resume-hook");
DEFSYM (Qvertical_line, "vertical-line");
DEFSYM (Qvertical_scroll_bar, "vertical-scroll-bar");
DEFSYM (Qmenu_bar, "menu-bar");
+ DEFSYM (Qright_divider, "right-divider");
+ DEFSYM (Qbottom_divider, "bottom-divider");
DEFSYM (Qmouse_fixup_help_message, "mouse-fixup-help-message");
DEFVAR_KBOARD ("overriding-terminal-local-map",
Voverriding_terminal_local_map,
doc: /* Per-terminal keymap that takes precedence over all other keymaps.
-
This variable is intended to let commands such as `universal-argument'
set up a different keymap for reading the next command.
`overriding-terminal-local-map' has a separate binding for each
-terminal device.
-See Info node `(elisp)Multiple Terminals'. */);
+terminal device. See Info node `(elisp)Multiple Terminals'. */);
DEFVAR_LISP ("overriding-local-map", Voverriding_local_map,
- doc: /* Keymap that overrides almost all other local keymaps.
-If this variable is non-nil, it is used as a keymap--replacing the
-buffer's local map, the minor mode keymaps, and char property keymaps. */);
+ doc: /* Keymap that replaces (overrides) local keymaps.
+If this variable is non-nil, Emacs looks up key bindings in this
+keymap INSTEAD OF the keymap char property, minor mode maps, and the
+buffer's local map. Hence, the only active keymaps would be
+`overriding-terminal-local-map', this keymap, and `global-keymap', in
+order of precedence. */);
Voverriding_local_map = Qnil;
DEFVAR_LISP ("overriding-local-map-menu-flag", Voverriding_local_map_menu_flag,