X-Git-Url: http://git.hcoop.net/bpt/emacs.git/blobdiff_plain/017be6c78048b28ef091095843904daaa18ec63e..b65c1b44897ddae92eca834f60f11008aee94247:/src/keyboard.c diff --git a/src/keyboard.c b/src/keyboard.c index c8780867bb..d6a743489a 100644 --- a/src/keyboard.c +++ b/src/keyboard.c @@ -1,5 +1,5 @@ /* Keyboard and mouse input; editor command loop. - Copyright (C) 1985,86,87,88,89,93,94,95,96,97,99,2000,01,02,03 + Copyright (C) 1985,86,87,88,89,93,94,95,96,97,99,2000,01,02,03,04 Free Software Foundation, Inc. This file is part of GNU Emacs. @@ -547,9 +547,6 @@ Lisp_Object Qhelp_echo; /* Symbols to denote kinds of events. */ Lisp_Object Qfunction_key; Lisp_Object Qmouse_click; -#if defined(WINDOWSNT) || defined(MAC_OSX) -Lisp_Object Qmouse_wheel; -#endif #ifdef WINDOWSNT Lisp_Object Qlanguage_change; #endif @@ -589,6 +586,8 @@ Lisp_Object Qvertical_line; Lisp_Object Qvertical_scroll_bar; Lisp_Object Qmenu_bar; extern Lisp_Object Qleft_margin, Qright_margin; +extern Lisp_Object Qleft_fringe, Qright_fringe; +extern Lisp_Object QCmap; Lisp_Object recursive_edit_unwind (), command_loop (); Lisp_Object Fthis_command_keys (); @@ -2944,13 +2943,13 @@ read_char (commandflag, nmaps, maps, prev_event, used_mouse_menu) { Lisp_Object posn; - posn = POSN_BUFFER_POSN (EVENT_START (c)); + posn = POSN_POSN (EVENT_START (c)); /* Handle menu-bar events: insert the dummy prefix event `menu-bar'. */ if (EQ (posn, Qmenu_bar) || EQ (posn, Qtool_bar)) { /* Change menu-bar to (menu-bar) as the event "position". */ - POSN_BUFFER_SET_POSN (EVENT_START (c), Fcons (posn, Qnil)); + POSN_SET_POSN (EVENT_START (c), Fcons (posn, Qnil)); also_record = c; Vunread_command_events = Fcons (c, Vunread_command_events); @@ -3737,6 +3736,7 @@ discard_mouse_events () sp = kbd_buffer; if (sp->kind == MOUSE_CLICK_EVENT + || sp->kind == WHEEL_EVENT #ifdef WINDOWSNT || sp->kind == W32_SCROLL_BAR_CLICK_EVENT #endif @@ -4436,9 +4436,7 @@ timer_check (do_it_now) static Lisp_Object accent_key_syms; static Lisp_Object func_key_syms; static Lisp_Object mouse_syms; -#if defined(WINDOWSNT) || defined(MAC_OSX) -static Lisp_Object mouse_wheel_syms; -#endif +static Lisp_Object wheel_syms; static Lisp_Object drag_n_drop_syms; /* This is a list of keysym codes for special "accent" characters. @@ -4892,21 +4890,11 @@ static char *iso_lispy_function_keys[] = Lisp_Object Vlispy_mouse_stem; -#if defined(WINDOWSNT) || defined(MAC_OSX) -/* mouse-wheel events are generated by the wheel on devices such as - the MS Intellimouse. The wheel sits in between the left and right - mouse buttons, and is typically used to scroll or zoom the window - underneath the pointer. mouse-wheel events specify the object on - which they operate, and a delta corresponding to the amount and - direction that the wheel is rotated. Clicking the mouse-wheel - generates a mouse-2 event. */ -static char *lispy_mouse_wheel_names[] = -{ - "mouse-wheel" +static char *lispy_wheel_names[] = +{ + "wheel-up", "wheel-down" }; -#endif /* WINDOWSNT */ - /* drag-n-drop events are generated when a set of selected files are dragged from another application and dropped onto an Emacs window. */ static char *lispy_drag_n_drop_names[] = @@ -4969,6 +4957,169 @@ EMACS_INT double_click_fuzz; int double_click_count; +/* Return position of a mouse click or wheel event */ + +static Lisp_Object +make_lispy_position (f, x, y, time) + struct frame *f; + Lisp_Object *x, *y; + unsigned long time; +{ + Lisp_Object window; + enum window_part part; + Lisp_Object posn = Qnil; + Lisp_Object extra_info = Qnil; + int wx, wy; + + /* Set `window' to the window under frame pixel coordinates (x,y) */ + if (f) + window = window_from_coordinates (f, XINT (*x), XINT (*y), + &part, &wx, &wy, 0); + else + window = Qnil; + + if (WINDOWP (window)) + { + /* It's a click in window window at frame coordinates (x,y) */ + struct window *w = XWINDOW (window); + Lisp_Object string_info = Qnil; + int textpos = -1, rx = -1, ry = -1; + int dx = -1, dy = -1; + int width = -1, height = -1; + Lisp_Object object = Qnil; + + /* Set event coordinates to window-relative coordinates + for constructing the Lisp event below. */ + XSETINT (*x, wx); + XSETINT (*y, wy); + + 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. */ + Lisp_Object string; + int charpos; + + posn = part == ON_MODE_LINE ? Qmode_line : Qheader_line; + rx = wx, ry = wy; + string = mode_line_string (w, part, &rx, &ry, &charpos, + &object, &dx, &dy, &width, &height); + if (STRINGP (string)) + string_info = Fcons (string, make_number (charpos)); + if (w == XWINDOW (selected_window)) + textpos = PT; + else + textpos = XMARKER (w->pointm)->charpos; + } + else if (part == ON_VERTICAL_BORDER) + { + posn = Qvertical_line; + wx = -1; + dx = 0; + width = 1; + } + else if (part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN) + { + Lisp_Object string; + int charpos; + + posn = (part == ON_LEFT_MARGIN) ? Qleft_margin : Qright_margin; + rx = wx, ry = wy; + string = marginal_area_string (w, part, &rx, &ry, &charpos, + &object, &dx, &dy, &width, &height); + if (STRINGP (string)) + string_info = Fcons (string, make_number (charpos)); + } + else if (part == ON_LEFT_FRINGE || part == ON_RIGHT_FRINGE) + { + posn = (part == ON_LEFT_FRINGE) ? Qleft_fringe : Qright_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); + } + + if (textpos < 0) + { + Lisp_Object string2, object2 = Qnil; + 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); + textpos = CHARPOS (p.pos); + if (rx < 0) rx = wx; + if (ry < 0) ry = wy; + if (dx < 0) dx = dx2; + if (dy < 0) dy = dy2; + if (width < 0) width = width2; + if (height < 0) height = height2; + + if (NILP (posn)) + { + posn = make_number (textpos); + if (STRINGP (string2)) + string_info = Fcons (string2, + make_number (CHARPOS (p.string_pos))); + } + if (NILP (object)) + object = object2; + } + +#ifdef HAVE_WINDOW_SYSTEM + if (IMAGEP (object)) + { + Lisp_Object image_map, hotspot; + if ((image_map = Fplist_get (XCDR (object), QCmap), + !NILP (image_map)) + && (hotspot = find_hot_spot (image_map, dx, dy), + CONSP (hotspot)) + && (hotspot = XCDR (hotspot), CONSP (hotspot))) + posn = XCAR (hotspot); + } +#endif + + /* Object info */ + extra_info = Fcons (object, + Fcons (Fcons (make_number (dx), + make_number (dy)), + Fcons (Fcons (make_number (width), + make_number (height)), + Qnil))); + + /* String info */ + extra_info = Fcons (string_info, + Fcons (make_number (textpos), + Fcons (Fcons (make_number (rx), + make_number (ry)), + extra_info))); + } + else if (f != 0) + { + XSETFRAME (window, f); + } + else + { + window = Qnil; + XSETFASTINT (*x, 0); + XSETFASTINT (*y, 0); + } + + return Fcons (window, + Fcons (posn, + Fcons (Fcons (*x, *y), + Fcons (make_number (time), + extra_info)))); +} + /* Given a struct input_event, build the lisp event which represents it. If EVENT is 0, build a mouse movement event from the mouse movement buffer, which should have a movement event in it. @@ -5103,24 +5254,23 @@ make_lispy_event (event) Lisp_Object position; Lisp_Object *start_pos_ptr; Lisp_Object start_pos; - Lisp_Object window; position = Qnil; /* Build the position as appropriate for this mouse click. */ if (event->kind == MOUSE_CLICK_EVENT) { - enum window_part part; struct frame *f = XFRAME (event->frame_or_window); - Lisp_Object posn; - Lisp_Object string_info = Qnil; +#if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK) int row, column; +#endif /* Ignore mouse events that were made on frame that have been deleted. */ if (! FRAME_LIVE_P (f)) return Qnil; +#if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK) /* EVENT->x and EVENT->y are frame-relative pixel coordinates at this place. Under old redisplay, COLUMN and ROW are set to frame relative glyph coordinates @@ -5129,7 +5279,6 @@ make_lispy_event (event) pixel_to_glyph_coords (f, XINT (event->x), XINT (event->y), &column, &row, NULL, 1); -#if ! defined (USE_X_TOOLKIT) && ! defined (USE_GTK) /* In the non-toolkit version, clicks on the menu bar are ordinary button events in the event buffer. Distinguish them, and invoke the menu. @@ -5183,81 +5332,14 @@ make_lispy_event (event) } #endif /* not USE_X_TOOLKIT && not USE_GTK */ - /* Set `window' to the window under frame pixel coordinates - event->x/event->y. */ - window = window_from_coordinates (f, XINT (event->x), - XINT (event->y), &part, 0); - - if (!WINDOWP (window)) - { - window = event->frame_or_window; - posn = Qnil; - } - else - { - /* It's a click in window window at frame coordinates - event->x/ event->y. */ - struct window *w = XWINDOW (window); - - /* Get window relative coordinates. Original code - `rounded' this to glyph boundaries. */ - int wx = FRAME_TO_WINDOW_PIXEL_X (w, XINT (event->x)); - int wy = FRAME_TO_WINDOW_PIXEL_Y (w, XINT (event->y)); - - /* Set event coordinates to window-relative coordinates - for constructing the Lisp event below. */ - XSETINT (event->x, wx); - XSETINT (event->y, wy); - - 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. */ - Lisp_Object string; - int charpos; - - posn = part == ON_MODE_LINE ? Qmode_line : Qheader_line; - string = mode_line_string (w, wx, wy, part, &charpos); - if (STRINGP (string)) - string_info = Fcons (string, make_number (charpos)); - } - else if (part == ON_VERTICAL_BORDER) - posn = Qvertical_line; - else if (part == ON_LEFT_MARGIN || part == ON_RIGHT_MARGIN) - { - int charpos; - Lisp_Object object = marginal_area_string (w, wx, wy, part, - &charpos); - posn = (part == ON_LEFT_MARGIN) ? Qleft_margin : Qright_margin; - if (STRINGP (object)) - string_info = Fcons (object, make_number (charpos)); - } - else - { - Lisp_Object object; - struct display_pos p; - buffer_posn_from_coords (w, &wx, &wy, &object, &p); - posn = make_number (CHARPOS (p.pos)); - if (STRINGP (object)) - string_info - = Fcons (object, - make_number (CHARPOS (p.string_pos))); - } - } - - position - = Fcons (window, - Fcons (posn, - Fcons (Fcons (event->x, event->y), - Fcons (make_number (event->timestamp), - (NILP (string_info) - ? Qnil - : Fcons (string_info, Qnil)))))); + position = make_lispy_position (f, &event->x, &event->y, + event->timestamp); } #ifndef USE_TOOLKIT_SCROLL_BARS else { /* It's a scrollbar click. */ + Lisp_Object window; Lisp_Object portion_whole; Lisp_Object part; @@ -5419,6 +5501,113 @@ make_lispy_event (event) } } + case WHEEL_EVENT: + { + Lisp_Object position; + Lisp_Object head; + + /* Build the position as appropriate for this mouse click. */ + struct frame *f = XFRAME (event->frame_or_window); + + /* Ignore wheel events that were made on frame that have been + deleted. */ + if (! FRAME_LIVE_P (f)) + return Qnil; + + position = make_lispy_position (f, &event->x, &event->y, + event->timestamp); + + /* Set double or triple modifiers to indicate the wheel speed. */ + { + /* On window-system frames, use the value of + double-click-fuzz as is. On other frames, interpret it + as a multiple of 1/8 characters. */ + struct frame *f; + int fuzz; + int is_double; + + if (WINDOWP (event->frame_or_window)) + f = XFRAME (XWINDOW (event->frame_or_window)->frame); + else if (FRAMEP (event->frame_or_window)) + f = XFRAME (event->frame_or_window); + else + abort (); + + if (FRAME_WINDOW_P (f)) + fuzz = double_click_fuzz; + else + fuzz = double_click_fuzz / 8; + + is_double = (last_mouse_button < 0 + && (abs (XINT (event->x) - last_mouse_x) <= fuzz) + && (abs (XINT (event->y) - last_mouse_y) <= fuzz) + && button_down_time != 0 + && (EQ (Vdouble_click_time, Qt) + || (INTEGERP (Vdouble_click_time) + && ((int)(event->timestamp - button_down_time) + < XINT (Vdouble_click_time))))); + if (is_double) + { + double_click_count++; + event->modifiers |= ((double_click_count > 2) + ? triple_modifier + : double_modifier); + } + else + { + double_click_count = 1; + event->modifiers |= click_modifier; + } + + button_down_time = event->timestamp; + /* Use a negative value to distinguish wheel from mouse button. */ + last_mouse_button = -1; + last_mouse_x = XINT (event->x); + last_mouse_y = XINT (event->y); + } + + { + int symbol_num; + + if (event->modifiers & up_modifier) + { + /* Emit a wheel-up event. */ + event->modifiers &= ~up_modifier; + symbol_num = 0; + } + else if (event->modifiers & down_modifier) + { + /* Emit a wheel-down event. */ + event->modifiers &= ~down_modifier; + symbol_num = 1; + } + else + /* Every wheel event should either have the down_modifier or + the up_modifier set. */ + abort (); + + /* Get the symbol we should use for the wheel event. */ + head = modify_event_symbol (symbol_num, + event->modifiers, + Qmouse_click, + Qnil, + lispy_wheel_names, + &wheel_syms, + ASIZE (wheel_syms)); + } + + if (event->modifiers & (double_modifier | triple_modifier)) + return Fcons (head, + Fcons (position, + Fcons (make_number (double_click_count), + Qnil))); + else + return Fcons (head, + Fcons (position, + Qnil)); + } + + #ifdef USE_TOOLKIT_SCROLL_BARS /* We don't have down and up events if using toolkit scroll bars, @@ -5517,86 +5706,11 @@ make_lispy_event (event) } } #endif /* WINDOWSNT */ -#if defined(WINDOWSNT) || defined(MAC_OSX) - case MOUSE_WHEEL_EVENT: - { - enum window_part part; - FRAME_PTR f = XFRAME (event->frame_or_window); - Lisp_Object window; - Lisp_Object posn; - Lisp_Object head, position; - int row, column; - - /* Ignore mouse events that were made on frame that - have been deleted. */ - if (! FRAME_LIVE_P (f)) - return Qnil; - pixel_to_glyph_coords (f, XINT (event->x), XINT (event->y), - &column, &row, NULL, 1); - window = window_from_coordinates (f, XINT (event->x), - XINT (event->y), &part, 0); - - if (!WINDOWP (window)) - { - window = event->frame_or_window; - posn = Qnil; - } - else - { - int pixcolumn, pixrow; - column -= XINT (XWINDOW (window)->left); - row -= XINT (XWINDOW (window)->top); - glyph_to_pixel_coords (XWINDOW(window), column, row, - &pixcolumn, &pixrow); - XSETINT (event->x, pixcolumn); - XSETINT (event->y, pixrow); - - if (part == ON_MODE_LINE) - posn = Qmode_line; - else if (part == ON_VERTICAL_BORDER) - posn = Qvertical_line; - else if (part == ON_HEADER_LINE) - posn = Qheader_line; - else - { - Lisp_Object object; - struct display_pos p; - buffer_posn_from_coords (XWINDOW (window), &column, &row, - &object, &p); - posn = make_number (CHARPOS (p.pos)); - } - } - - { - Lisp_Object head, position; - - position - = Fcons (window, - Fcons (posn, - Fcons (Fcons (event->x, event->y), - Fcons (make_number (event->timestamp), - Qnil)))); - - head = modify_event_symbol (0, event->modifiers, - Qmouse_wheel, Qnil, - lispy_mouse_wheel_names, - &mouse_wheel_syms, 1); - return Fcons (head, - Fcons (position, - /* Insert 1 here so event-click-count works. */ - Fcons (make_number (1), - Fcons (make_number (event->code), - Qnil)))); - } - } -#endif /* WINDOWSNT || MAC_OSX */ case DRAG_N_DROP_EVENT: { - enum window_part part; FRAME_PTR f; - Lisp_Object window; - Lisp_Object posn; + Lisp_Object head, position; Lisp_Object files; /* The frame_or_window field should be a cons of the frame in @@ -5613,63 +5727,17 @@ make_lispy_event (event) if (! FRAME_LIVE_P (f)) return Qnil; - window = window_from_coordinates (f, XINT (event->x), - XINT (event->y), &part, 0); - - if (!WINDOWP (window)) - { - window = XCAR (event->frame_or_window); - posn = Qnil; - } - else - { - /* It's an event in window `window' at frame coordinates - event->x/ event->y. */ - struct window *w = XWINDOW (window); - - /* Get window relative coordinates. */ - int wx = FRAME_TO_WINDOW_PIXEL_X (w, XINT (event->x)); - int wy = FRAME_TO_WINDOW_PIXEL_Y (w, XINT (event->y)); - - /* Set event coordinates to window-relative coordinates - for constructing the Lisp event below. */ - XSETINT (event->x, wx); - XSETINT (event->y, wy); - - if (part == ON_MODE_LINE) - posn = Qmode_line; - else if (part == ON_VERTICAL_BORDER) - posn = Qvertical_line; - else if (part == ON_HEADER_LINE) - posn = Qheader_line; - else - { - Lisp_Object object; - struct display_pos p; - buffer_posn_from_coords (w, &wx, &wy, &object, &p); - posn = make_number (CHARPOS (p.pos)); - } - } - - { - Lisp_Object head, position; - - position - = Fcons (window, - Fcons (posn, - Fcons (Fcons (event->x, event->y), - Fcons (make_number (event->timestamp), - Qnil)))); - - head = modify_event_symbol (0, event->modifiers, - Qdrag_n_drop, Qnil, - lispy_drag_n_drop_names, - &drag_n_drop_syms, 1); - return Fcons (head, - Fcons (position, - Fcons (files, - Qnil))); - } + position = make_lispy_position (f, &event->x, &event->y, + event->timestamp); + + head = modify_event_symbol (0, event->modifiers, + Qdrag_n_drop, Qnil, + lispy_drag_n_drop_names, + &drag_n_drop_syms, 1); + return Fcons (head, + Fcons (position, + Fcons (files, + Qnil))); } #endif /* HAVE_MOUSE */ @@ -5742,60 +5810,12 @@ make_lispy_movement (frame, bar_window, part, x, y, time) /* Or is it an ordinary mouse movement? */ else { - enum window_part area; - Lisp_Object window; - Lisp_Object posn; - - if (frame) - /* It's in a frame; which window on that frame? */ - window = window_from_coordinates (frame, XINT (x), XINT (y), &area, 0); - else - window = Qnil; - - if (WINDOWP (window)) - { - struct window *w = XWINDOW (window); - int wx, wy; + Lisp_Object position; - /* Get window relative coordinates. */ - wx = FRAME_TO_WINDOW_PIXEL_X (w, XINT (x)); - wy = FRAME_TO_WINDOW_PIXEL_Y (w, XINT (y)); - XSETINT (x, wx); - XSETINT (y, wy); - - if (area == ON_MODE_LINE) - posn = Qmode_line; - else if (area == ON_VERTICAL_BORDER) - posn = Qvertical_line; - else if (area == ON_HEADER_LINE) - posn = Qheader_line; - else - { - Lisp_Object object; - struct display_pos p; - buffer_posn_from_coords (w, &wx, &wy, &object, &p); - posn = make_number (CHARPOS (p.pos)); - } - } - else if (frame != 0) - { - XSETFRAME (window, frame); - posn = Qnil; - } - else - { - window = Qnil; - posn = Qnil; - XSETFASTINT (x, 0); - XSETFASTINT (y, 0); - } + position = make_lispy_position (frame, &x, &y, time); return Fcons (Qmouse_movement, - Fcons (Fcons (window, - Fcons (posn, - Fcons (Fcons (x, y), - Fcons (make_number (time), - Qnil)))), + Fcons (position, Qnil)); } } @@ -6033,7 +6053,7 @@ parse_modifiers (symbol) SBYTES (SYMBOL_NAME (symbol)) - end), Qnil); - if (modifiers & ~VALMASK) + if (modifiers & ~INTMASK) abort (); XSETFASTINT (mask, modifiers); elements = Fcons (unmodified, Fcons (mask, Qnil)); @@ -6070,7 +6090,7 @@ apply_modifiers (modifiers, base) Lisp_Object cache, index, entry, new_symbol; /* Mask out upper bits. We don't know where this value's been. */ - modifiers &= VALMASK; + modifiers &= INTMASK; /* The click modifier never figures into cache indices. */ cache = Fget (base, Qmodifier_cache); @@ -6534,6 +6554,7 @@ record_asynch_buffer_change () { struct input_event event; Lisp_Object tem; + EVENT_INIT (event); event.kind = BUFFER_SWITCH_EVENT; event.frame_or_window = Qnil; @@ -6592,6 +6613,9 @@ read_avail_input (expected) register int i; int nread; + for (i = 0; i < KBD_BUFFER_SIZE; i++) + EVENT_INIT (buf[i]); + if (read_socket_hook) /* No need for FIONREAD or fcntl; just say don't wait. */ nread = (*read_socket_hook) (input_fd, buf, KBD_BUFFER_SIZE, expected); @@ -6621,7 +6645,12 @@ read_avail_input (expected) /* ??? 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); + { + if (! noninteractive) + kill (getpid (), SIGHUP); + else + n_to_read = 0; + } if (n_to_read == 0) return 0; if (n_to_read > sizeof cbuf) @@ -6718,6 +6747,30 @@ read_avail_input (expected) } #endif /* not VMS */ +void +handle_async_input () +{ +#ifdef BSD4_1 + extern int select_alarmed; +#endif + interrupt_input_pending = 0; + + while (1) + { + int nread; + nread = read_avail_input (1); + /* -1 means it's not ok to read the input now. + UNBLOCK_INPUT will read it later; now, avoid infinite loop. + 0 means there was no keyboard input available. */ + if (nread <= 0) + break; + +#ifdef BSD4_1 + select_alarmed = 1; /* Force the select emulator back to life */ +#endif + } +} + #ifdef SIGIO /* for entire page */ /* Note SIGIO has been undef'd if FIONREAD is missing. */ @@ -6727,9 +6780,6 @@ input_available_signal (signo) { /* Must preserve main program's value of errno. */ int old_errno = errno; -#ifdef BSD4_1 - extern int select_alarmed; -#endif #if defined (USG) && !defined (POSIX_SIGNALS) /* USG systems forget handlers when they are used; @@ -6744,20 +6794,11 @@ input_available_signal (signo) if (input_available_clear_time) EMACS_SET_SECS_USECS (*input_available_clear_time, 0, 0); - while (1) - { - int nread; - nread = read_avail_input (1); - /* -1 means it's not ok to read the input now. - UNBLOCK_INPUT will read it later; now, avoid infinite loop. - 0 means there was no keyboard input available. */ - if (nread <= 0) - break; - -#ifdef BSD4_1 - select_alarmed = 1; /* Force the select emulator back to life */ +#ifdef SYNC_INPUT + interrupt_input_pending = 1; +#else + handle_async_input (); #endif - } #ifdef BSD4_1 sigfree (); @@ -6776,7 +6817,7 @@ void reinvoke_input_signal () { #ifdef SIGIO - kill (getpid (), SIGIO); + handle_async_input (); #endif } @@ -7929,7 +7970,7 @@ read_char_minibuf_menu_prompt (commandflag, nmaps, maps) register Lisp_Object name; int nlength; /* FIXME: Use the minibuffer's frame width. */ - int width = FRAME_WIDTH (SELECTED_FRAME ()) - 4; + int width = FRAME_COLS (SELECTED_FRAME ()) - 4; int idx = -1; int nobindings = 1; Lisp_Object rest, vector; @@ -8831,6 +8872,7 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last, if (EVENT_HAS_PARAMETERS (key)) { Lisp_Object kind; + Lisp_Object string; kind = EVENT_HEAD_KIND (EVENT_HEAD (key)); if (EQ (kind, Qmouse_click)) @@ -8838,7 +8880,7 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last, Lisp_Object window, posn; window = POSN_WINDOW (EVENT_START (key)); - posn = POSN_BUFFER_POSN (EVENT_START (key)); + posn = POSN_POSN (EVENT_START (key)); if (CONSP (posn) || (!NILP (fake_prefixed_keys) @@ -8896,7 +8938,7 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last, localized_local_map = 1; start = EVENT_START (key); - if (CONSP (start) && CONSP (XCDR (start))) + if (CONSP (start) && POSN_INBUFFER_P (start)) { pos = POSN_BUFFER_POSN (start); if (INTEGERP (pos) @@ -8947,11 +8989,11 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last, /* If on a mode line string with a local keymap, reconsider the key sequence with that keymap. */ - if (CONSP (POSN_STRING (EVENT_START (key)))) + if (string = POSN_STRING (EVENT_START (key)), + (CONSP (string) && STRINGP (XCAR (string)))) { - Lisp_Object string, pos, map, map2; + Lisp_Object pos, map, map2; - string = POSN_STRING (EVENT_START (key)); pos = XCDR (string); string = XCAR (string); if (XINT (pos) >= 0 @@ -8970,16 +9012,16 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last, goto replay_key; } - else if (CONSP (POSN_STRING (EVENT_START (key))) - && NILP (from_string)) + else if (NILP (from_string) + && (string = POSN_STRING (EVENT_START (key)), + (CONSP (string) && STRINGP (XCAR (string))))) { /* For a click on a string, i.e. overlay string or a string displayed via the `display' property, consider `local-map' and `keymap' properties of that string. */ - Lisp_Object string, pos, map, map2; + Lisp_Object pos, map, map2; - string = POSN_STRING (EVENT_START (key)); pos = XCDR (string); string = XCAR (string); if (XINT (pos) >= 0 @@ -9006,7 +9048,7 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last, { Lisp_Object posn; - posn = POSN_BUFFER_POSN (EVENT_START (key)); + posn = POSN_POSN (EVENT_START (key)); /* Handle menu-bar events: insert the dummy prefix event `menu-bar'. */ if (EQ (posn, Qmenu_bar) || EQ (posn, Qtool_bar)) @@ -9018,8 +9060,8 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last, /* Zap the position in key, so we know that we've expanded it, and don't try to do so again. */ - POSN_BUFFER_SET_POSN (EVENT_START (key), - Fcons (posn, Qnil)); + POSN_SET_POSN (EVENT_START (key), + Fcons (posn, Qnil)); mock_input = t + 2; goto replay_sequence; @@ -9324,6 +9366,8 @@ read_key_sequence (keybuf, bufsize, prompt, dont_downcase_last, keybuf[t - 1] = new_key; mock_input = max (t, mock_input); + fkey.start = fkey.end = KEYMAPP (fkey.map) ? 0 : bufsize + 1; + keytran.start = keytran.end = KEYMAPP (keytran.map) ? 0 : bufsize + 1; goto replay_sequence; } @@ -10680,10 +10724,6 @@ syms_of_keyboard () staticpro (&Qfunction_key); Qmouse_click = intern ("mouse-click"); staticpro (&Qmouse_click); -#if defined(WINDOWSNT) || defined(MAC_OSX) - Qmouse_wheel = intern ("mouse-wheel"); - staticpro (&Qmouse_wheel); -#endif #ifdef WINDOWSNT Qlanguage_change = intern ("language-change"); staticpro (&Qlanguage_change); @@ -10798,6 +10838,8 @@ syms_of_keyboard () staticpro (&button_down_location); mouse_syms = Fmake_vector (make_number (1), Qnil); staticpro (&mouse_syms); + wheel_syms = Fmake_vector (make_number (2), Qnil); + staticpro (&wheel_syms); { int i; @@ -10832,12 +10874,8 @@ syms_of_keyboard () func_key_syms = Qnil; staticpro (&func_key_syms); -#if defined(WINDOWSNT) || defined(MAC_OSX) - mouse_wheel_syms = Qnil; - staticpro (&mouse_wheel_syms); drag_n_drop_syms = Qnil; staticpro (&drag_n_drop_syms); -#endif unread_switch_frame = Qnil; staticpro (&unread_switch_frame); @@ -11289,3 +11327,45 @@ keys_of_keyboard () initial_define_lispy_key (Vspecial_event_map, "save-session", "handle-save-session"); } + +/* Mark the pointers in the kboard objects. + Called by the Fgarbage_collector. */ +void +mark_kboards () +{ + KBOARD *kb; + Lisp_Object *p; + for (kb = all_kboards; kb; kb = kb->next_kboard) + { + if (kb->kbd_macro_buffer) + for (p = kb->kbd_macro_buffer; p < kb->kbd_macro_ptr; p++) + mark_object (*p); + mark_object (kb->Voverriding_terminal_local_map); + mark_object (kb->Vlast_command); + mark_object (kb->Vreal_last_command); + mark_object (kb->Vprefix_arg); + mark_object (kb->Vlast_prefix_arg); + mark_object (kb->kbd_queue); + mark_object (kb->defining_kbd_macro); + mark_object (kb->Vlast_kbd_macro); + mark_object (kb->Vsystem_key_alist); + mark_object (kb->system_key_syms); + mark_object (kb->Vdefault_minibuffer_frame); + mark_object (kb->echo_string); + } + { + struct input_event *event; + for (event = kbd_fetch_ptr; event != kbd_store_ptr; event++) + { + if (event == kbd_buffer + KBD_BUFFER_SIZE) + event = kbd_buffer; + mark_object (event->x); + mark_object (event->y); + mark_object (event->frame_or_window); + mark_object (event->arg); + } + } +} + +/* arch-tag: 774e34d7-6d31-42f3-8397-e079a4e4c9ca + (do not change this comment) */