X-Git-Url: https://code.delx.au/gnu-emacs/blobdiff_plain/2a7a50eaea867625fbe46e80fce41983f6ad2fc2..4985dde2d0220cf74334261e0f558c377d295815:/src/keyboard.c diff --git a/src/keyboard.c b/src/keyboard.c index b854d423cd..30b06ef38f 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -1,6 +1,7 @@ /* Keyboard and mouse input; editor command loop. - Copyright (C) 1985, 1986, 1987, 1988, 1989, 1993, 1994, 1995, 1996, 1997, - 1999, 2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc. + Copyright (C) 1985, 1986, 1987, 1988, 1989, 1993, 1994, 1995, + 1996, 1997, 1999, 2000, 2001, 2002, 2003, 2004, + 2005, 2006 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -380,12 +381,15 @@ Lisp_Object real_this_command; command is stored in this-original-command. It is nil otherwise. */ Lisp_Object Vthis_original_command; -/* The value of point when the last command was executed. */ +/* The value of point when the last command was started. */ int last_point_position; /* The buffer that was current when the last command was started. */ Lisp_Object last_point_position_buffer; +/* The window that was selected when the last command was started. */ +Lisp_Object last_point_position_window; + /* The frame in which the last input event occurred, or Qmacro if the last event came from a macro. We use this to determine when to generate switch-frame events. This may be cleared by functions @@ -473,10 +477,6 @@ int input_pending; int meta_key; -/* Non-zero means force key bindings update in parse_menu_item. */ - -int update_menu_bindings; - extern char *pending_malloc_warning; /* Circular buffer for pre-read keyboard input. */ @@ -530,6 +530,9 @@ Lisp_Object Qlanguage_change; #endif Lisp_Object Qdrag_n_drop; Lisp_Object Qsave_session; +#ifdef MAC_OS +Lisp_Object Qmac_apple_event; +#endif /* Lisp_Object Qmouse_movement; - also an event header */ @@ -646,6 +649,11 @@ static EMACS_TIME timer_idleness_start_time; static EMACS_TIME timer_last_idleness_start_time; +/* If non-nil, events produced by disabled menu items and tool-bar + buttons are not ignored. Help functions bind this to allow help on + those items and buttons. */ +Lisp_Object Venable_disabled_menus_and_buttons; + /* Global variable declarations. */ @@ -787,6 +795,8 @@ echo_char (c) else echo_string = concat2 (echo_string, build_string (" ")); } + else if (STRINGP (echo_string)) + echo_string = concat2 (echo_string, build_string (" ")); current_kboard->echo_string = concat2 (echo_string, make_string (buffer, ptr - buffer)); @@ -817,16 +827,16 @@ echo_dash () /* Do nothing if we have already put a dash at the end. */ if (SCHARS (current_kboard->echo_string) > 1) { - Lisp_Object last_char, prev_char, idx; + Lisp_Object last_char, prev_char, idx; - idx = make_number (SCHARS (current_kboard->echo_string) - 2); - prev_char = Faref (current_kboard->echo_string, idx); + idx = make_number (SCHARS (current_kboard->echo_string) - 2); + prev_char = Faref (current_kboard->echo_string, idx); - idx = make_number (SCHARS (current_kboard->echo_string) - 1); - last_char = Faref (current_kboard->echo_string, idx); + idx = make_number (SCHARS (current_kboard->echo_string) - 1); + last_char = Faref (current_kboard->echo_string, idx); - if (XINT (last_char) == '-' && XINT (prev_char) != ' ') - return; + if (XINT (last_char) == '-' && XINT (prev_char) != ' ') + return; } /* Put a dash at the end of the buffer temporarily, @@ -1408,7 +1418,7 @@ command_loop_1 () Lisp_Object keybuf[30]; int i; int no_direct; - int prev_modiff; + int prev_modiff = 0; struct buffer *prev_buffer = NULL; #ifdef MULTI_KBOARD int was_locked = single_kboard; @@ -1444,8 +1454,6 @@ command_loop_1 () safe_run_hooks (Qdeferred_action_function); } - Vmemory_full = Qnil; - /* Do this after running Vpost_command_hook, for consistency. */ current_kboard->Vlast_command = Vthis_command; current_kboard->Vreal_last_command = real_this_command; @@ -1583,6 +1591,7 @@ command_loop_1 () prev_buffer = current_buffer; prev_modiff = MODIFF; last_point_position = PT; + last_point_position_window = selected_window; XSETBUFFER (last_point_position_buffer, prev_buffer); /* By default, we adjust point to a boundary of a region that @@ -2778,7 +2787,7 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu) available, garbage collect if there has been enough consing going on to make it worthwhile. */ if (!detect_input_pending_run_timers (0) - && consing_since_gc > gc_cons_combined_threshold / 2) + && consing_since_gc > gc_cons_threshold / 2) Fgarbage_collect (); redisplay (); @@ -4001,7 +4010,7 @@ kbd_buffer_get_event (kbp, used_mouse_menu) kbd_fetch_ptr = event + 1; } #endif -#if defined (HAVE_X11) || defined (HAVE_NTGUI) +#if defined (HAVE_X11) || defined (HAVE_NTGUI) || defined (MAC_OS) else if (event->kind == ICONIFY_EVENT) { /* Make an event (iconify-frame (FRAME)). */ @@ -5057,7 +5066,11 @@ make_lispy_position (f, x, y, time) XSETINT (*x, wx); XSETINT (*y, wy); - if (part == ON_MODE_LINE || part == ON_HEADER_LINE) + if (part == ON_TEXT) + { + wx += WINDOW_LEFT_MARGIN_WIDTH (w); + } + else if (part == ON_MODE_LINE || part == ON_HEADER_LINE) { /* Mode line or header line. Look for a string under the mouse that may have a `local-map' property. */ @@ -5093,20 +5106,37 @@ make_lispy_position (f, x, y, time) &object, &dx, &dy, &width, &height); if (STRINGP (string)) string_info = Fcons (string, make_number (charpos)); + if (part == ON_LEFT_MARGIN) + wx = 0; + else + wx = window_box_right_offset (w, TEXT_AREA) - 1; } - else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE) + else if (part == ON_LEFT_FRINGE) { - posn = (part == ON_LEFT_FRINGE) ? Qleft_fringe : Qright_fringe; + posn = Qleft_fringe; rx = 0; dx = wx; - if (part == ON_RIGHT_FRINGE) - dx -= (window_box_width (w, LEFT_MARGIN_AREA) - + window_box_width (w, TEXT_AREA) - + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w) - ? window_box_width (w, RIGHT_MARGIN_AREA) - : 0)); - else if (!WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)) - dx -= window_box_width (w, LEFT_MARGIN_AREA); + wx = (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w) + ? 0 + : window_box_width (w, LEFT_MARGIN_AREA)); + dx -= wx; + } + else if (part == ON_RIGHT_FRINGE) + { + posn = Qright_fringe; + rx = 0; + dx = wx; + wx = (window_box_width (w, LEFT_MARGIN_AREA) + + window_box_width (w, TEXT_AREA) + + (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w) + ? window_box_width (w, RIGHT_MARGIN_AREA) + : 0)); + dx -= wx; + } + else + { + /* Note: We have no special posn for part == ON_SCROLL_BAR. */ + wx = max (WINDOW_LEFT_MARGIN_WIDTH (w), wx); } if (textpos < 0) @@ -5115,7 +5145,6 @@ make_lispy_position (f, x, y, time) struct display_pos p; int dx2, dy2; int width2, height2; - wx = max (WINDOW_LEFT_MARGIN_WIDTH (w), wx); string2 = buffer_posn_from_coords (w, &wx, &wy, &p, &object2, &dx2, &dy2, &width2, &height2); @@ -5510,13 +5539,23 @@ make_lispy_event (event) if (CONSP (down) && INTEGERP (XCAR (down)) && INTEGERP (XCDR (down))) { - xdiff = XFASTINT (event->x) - XFASTINT (XCAR (down)); - ydiff = XFASTINT (event->y) - XFASTINT (XCDR (down)); + xdiff = XINT (event->x) - XINT (XCAR (down)); + ydiff = XINT (event->y) - XINT (XCDR (down)); } if (xdiff < double_click_fuzz && xdiff > - double_click_fuzz - && ydiff < double_click_fuzz - && ydiff > - double_click_fuzz) + && ydiff < double_click_fuzz && ydiff > - double_click_fuzz + /* Maybe the mouse has moved a lot, caused scrolling, and + eventually ended up at the same screen position (but + not buffer position) in which case it is a drag, not + a click. */ + /* FIXME: OTOH if the buffer position has changed + because of a timer or process filter rather than + because of mouse movement, it should be considered as + a click. But mouse-drag-region completely ignores + this case and it hasn't caused any real problem, so + it's probably OK to ignore it as well. */ + && EQ (Fcar (Fcdr (start_pos)), Fcar (Fcdr (position)))) /* Mouse hasn't moved (much). */ event->modifiers |= click_modifier; else @@ -5777,14 +5816,8 @@ make_lispy_event (event) Lisp_Object head, position; Lisp_Object files; - /* The frame_or_window field should be a cons of the frame in - which the event occurred and a list of the filenames - dropped. */ - if (! CONSP (event->frame_or_window)) - abort (); - - f = XFRAME (XCAR (event->frame_or_window)); - files = XCDR (event->frame_or_window); + f = XFRAME (event->frame_or_window); + files = event->arg; /* Ignore mouse events that were made on frames that have been deleted. */ @@ -5839,6 +5872,19 @@ make_lispy_event (event) case SAVE_SESSION_EVENT: return Qsave_session; +#ifdef MAC_OS + case MAC_APPLE_EVENT: + { + Lisp_Object spec[2]; + + spec[0] = event->x; + spec[1] = event->y; + return Fcons (Qmac_apple_event, + Fcons (Fvector (2, spec), + Fcons (event->arg, Qnil))); + } +#endif + /* The 'kind' field of the event is something we don't recognize. */ default: abort (); @@ -7229,7 +7275,9 @@ parse_menu_item (item, notreal, inmenubar) if (SYMBOLP (item)) { tem = Fget (item, Qmenu_enable); - if (!NILP (tem)) + if (!NILP (Venable_disabled_menus_and_buttons)) + AREF (item_properties, ITEM_PROPERTY_ENABLE) = Qt; + else if (!NILP (tem)) AREF (item_properties, ITEM_PROPERTY_ENABLE) = tem; } } @@ -7258,7 +7306,12 @@ parse_menu_item (item, notreal, inmenubar) item = XCDR (item); if (EQ (tem, QCenable)) - AREF (item_properties, ITEM_PROPERTY_ENABLE) = XCAR (item); + { + if (!NILP (Venable_disabled_menus_and_buttons)) + AREF (item_properties, ITEM_PROPERTY_ENABLE) = Qt; + else + AREF (item_properties, ITEM_PROPERTY_ENABLE) = XCAR (item); + } else if (EQ (tem, QCvisible) && !notreal) { /* If got a visible property and that evaluates to nil @@ -7402,9 +7455,7 @@ parse_menu_item (item, notreal, inmenubar) else def = AREF (item_properties, ITEM_PROPERTY_DEF); - if (!update_menu_bindings) - chkcache = 0; - else if (NILP (XCAR (cachelist))) /* Have no saved key. */ + if (NILP (XCAR (cachelist))) /* Have no saved key. */ { if (newcache /* Always check first time. */ /* Should we check everything when precomputing key @@ -7529,7 +7580,7 @@ Lisp_Object QCimage; /* Function prototypes. */ static void init_tool_bar_items P_ ((Lisp_Object)); -static void process_tool_bar_item P_ ((Lisp_Object, Lisp_Object)); +static void process_tool_bar_item P_ ((Lisp_Object, Lisp_Object, Lisp_Object, void*)); static int parse_tool_bar_item P_ ((Lisp_Object, Lisp_Object)); static void append_tool_bar_item P_ ((void)); @@ -7607,17 +7658,7 @@ tool_bar_items (reuse, nitems) keymap = get_keymap (access_keymap (maps[i], Qtool_bar, 1, 0, 1), 0, 1); if (CONSP (keymap)) - { - Lisp_Object tail; - - /* KEYMAP is a list `(keymap (KEY . BINDING) ...)'. */ - for (tail = keymap; CONSP (tail); tail = XCDR (tail)) - { - Lisp_Object keydef = XCAR (tail); - if (CONSP (keydef)) - process_tool_bar_item (XCAR (keydef), XCDR (keydef)); - } - } + map_keymap (keymap, process_tool_bar_item, Qnil, NULL, 1); } Vinhibit_quit = oquit; @@ -7629,8 +7670,9 @@ tool_bar_items (reuse, nitems) /* Process the definition of KEY which is DEF. */ static void -process_tool_bar_item (key, def) - Lisp_Object key, def; +process_tool_bar_item (key, def, data, args) + Lisp_Object key, def, data; + void *args; { int i; extern Lisp_Object Qundefined; @@ -7780,8 +7822,13 @@ parse_tool_bar_item (key, item) value = XCAR (XCDR (item)); if (EQ (key, QCenable)) - /* `:enable FORM'. */ - PROP (TOOL_BAR_ITEM_ENABLED_P) = value; + { + /* `:enable FORM'. */ + if (!NILP (Venable_disabled_menus_and_buttons)) + PROP (TOOL_BAR_ITEM_ENABLED_P) = Qt; + else + PROP (TOOL_BAR_ITEM_ENABLED_P) = value; + } else if (EQ (key, QCvisible)) { /* `:visible FORM'. If got a visible property and that @@ -9431,6 +9478,7 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last, /* Don't downcase the last character if the caller says don't. Don't downcase it if the result is undefined, either. */ if ((dont_downcase_last || first_binding >= nmaps) + && t > 0 && t - 1 == original_uppercase_position) keybuf[t - 1] = original_uppercase; @@ -9660,7 +9708,7 @@ a special event, so ignore the prefix argument and don't clear it. */) while (1) { - final = Findirect_function (cmd); + final = Findirect_function (cmd, Qnil); if (CONSP (final) && (tem = Fcar (final), EQ (tem, Qautoload))) { @@ -10571,11 +10619,11 @@ The `posn-' functions access elements of such lists. */) CHECK_LIVE_WINDOW (frame_or_window); w = XWINDOW (frame_or_window); - XSETINT (x, (WINDOW_TO_FRAME_PIXEL_X (w, XINT (x)) + XSETINT (x, (XINT (x) + + WINDOW_LEFT_EDGE_X (w) + (NILP (whole) ? window_box_left_offset (w, TEXT_AREA) - : - (WINDOW_LEFT_SCROLL_BAR_COLS (w) - * WINDOW_FRAME_COLUMN_WIDTH (w))))); + : 0))); XSETINT (y, WINDOW_TO_FRAME_PIXEL_Y (w, XINT (y))); frame_or_window = w->frame; } @@ -10601,9 +10649,21 @@ The `posn-' functions access elements of such lists. */) { Lisp_Object tem; + if (NILP (window)) + window = selected_window; + tem = Fpos_visible_in_window_p (pos, window, Qt); if (!NILP (tem)) - tem = Fposn_at_x_y (XCAR (tem), XCAR (XCDR (tem)), window, Qnil); + { + Lisp_Object x = XCAR (tem); + Lisp_Object y = XCAR (XCDR (tem)); + + /* Point invisible due to hscrolling? */ + if (XINT (x) < 0) + return Qnil; + tem = Fposn_at_x_y (x, y, window, Qnil); + } + return tem; } @@ -10748,11 +10808,6 @@ init_keyboard () poll_suppress_count = 1; start_polling (); #endif - -#ifdef MAC_OSX - /* At least provide an escape route since C-g doesn't work. */ - signal (SIGINT, interrupt_signal); -#endif } /* This type's only use is in syms_of_keyboard, to initialize the @@ -10849,6 +10904,11 @@ syms_of_keyboard () Qsave_session = intern ("save-session"); staticpro (&Qsave_session); +#ifdef MAC_OS + Qmac_apple_event = intern ("mac-apple-event"); + staticpro (&Qmac_apple_event); +#endif + Qusr1_signal = intern ("usr1-signal"); staticpro (&Qusr1_signal); Qusr2_signal = intern ("usr2-signal"); @@ -10939,6 +10999,7 @@ syms_of_keyboard () Fset (Qinput_method_use_echo_area, Qnil); last_point_position_buffer = Qnil; + last_point_position_window = Qnil; { struct event_head *p; @@ -11282,6 +11343,7 @@ might happen repeatedly and make Emacs nonfunctional. */); doc: /* Normal hook run when clearing the echo area. */); #endif Qecho_area_clear_hook = intern ("echo-area-clear-hook"); + staticpro (&Qecho_area_clear_hook); SET_SYMBOL_VALUE (Qecho_area_clear_hook, Qnil); DEFVAR_LISP ("lucid-menu-bar-dirty-flag", &Vlucid_menu_bar_dirty_flag, @@ -11407,12 +11469,6 @@ suppressed only after special commands that set `disable-point-adjustment' (which see) to non-nil. */); Vglobal_disable_point_adjustment = Qnil; - DEFVAR_BOOL ("update-menu-bindings", &update_menu_bindings, - doc: /* Non-nil means updating menu bindings is allowed. -A value of nil means menu bindings should not be updated. -Used during Emacs' startup. */); - update_menu_bindings = 1; - DEFVAR_LISP ("minibuffer-message-timeout", &Vminibuffer_message_timeout, doc: /* *How long to display an echo-area message when the minibuffer is active. If the value is not a number, such messages don't time out. */); @@ -11423,6 +11479,14 @@ If the value is not a number, such messages don't time out. */); The value of that variable is passed to `quit-flag' and later causes a peculiar kind of quitting. */); Vthrow_on_input = Qnil; + + DEFVAR_LISP ("enable-disabled-menus-and-buttons", + &Venable_disabled_menus_and_buttons, + doc: /* If non-nil, don't ignore events produced by disabled menu items and tool-bar. + +Help functions bind this to allow help on disabled menu items +and tool-bar buttons. */); + Venable_disabled_menus_and_buttons = Qnil; } void