#include <config.h>
#include <signal.h>
#include <stdio.h>
+#include "lisp.h"
+#include "systty.h" /* This must be included befor termchar.h. */
#include "termchar.h"
#include "termopts.h"
-#include "lisp.h"
#include "termhooks.h"
#include "macros.h"
#include "keyboard.h"
#endif /* not MSDOS */
#include "syssignal.h"
-#include "systty.h"
#include <sys/types.h>
#ifdef HAVE_UNISTD_H
int interrupt_input_pending;
-/* File descriptor to use for input. */
-extern int input_fd;
-
#ifdef HAVE_WINDOW_SYSTEM
/* Make all keyboard buffers much bigger when using X windows. */
#ifdef MAC_OS8
/* Nonzero if input is available. */
int input_pending;
-/* 1 if should obey 0200 bit in input chars as "Meta", 2 if should
- keep 0200 bit in input chars. 0 to ignore the 0200 bit. */
-
-int meta_key;
-
/* Non-zero means force key bindings update in parse_menu_item. */
int update_menu_bindings;
/* Symbols to denote kinds of events. */
Lisp_Object Qfunction_key;
Lisp_Object Qmouse_click;
-#if defined(MAC_OSX)
-Lisp_Object Qmouse_wheel;
-#endif
#ifdef WINDOWSNT
Lisp_Object Qlanguage_change;
#endif
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 ();
static Lisp_Object func_key_syms;
static Lisp_Object mouse_syms;
static Lisp_Object wheel_syms;
-#if defined(MAC_OSX)
-static Lisp_Object mouse_wheel_syms;
-#endif
static Lisp_Object drag_n_drop_syms;
/* This is a list of keysym codes for special "accent" characters.
"wheel-up", "wheel-down"
};
-#if 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"
-};
-
-#endif /* MAC_OSX */
-
/* 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[] =
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 object = Qnil;
+ int textpos = -1, rx = -1, ry = -1;
+ int dx = -1, dy = -1;
+
+ /* 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, &rx, &ry, &dx, &dy, part, &charpos);
+ if (STRINGP (string))
+ object = 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;
+ }
+ 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, &rx, &ry, &dx, &dy, part, &charpos);
+ if (STRINGP (string))
+ object = Fcons (string, make_number (charpos));
+#ifdef HAVE_WINDOW_SYSTEM
+ else if (IMAGEP (string))
+ {
+ Lisp_Object image_map, hotspot;
+ object = string;
+ 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
+ }
+ 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 string;
+ struct display_pos p;
+ int dx2, dy2;
+ wx = max (WINDOW_LEFT_MARGIN_WIDTH (w), wx);
+ buffer_posn_from_coords (w, &wx, &wy, &dx2, &dy2, &string, &p);
+ 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 (NILP (posn))
+ {
+ posn = make_number (textpos);
+ if (STRINGP (string))
+ object = Fcons (string,
+ make_number (CHARPOS (p.string_pos)));
+#ifdef HAVE_WINDOW_SYSTEM
+ else if (IMAGEP (string))
+ {
+ Lisp_Object image_map, hotspot;
+ object = string;
+ 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
+ }
+ }
+
+ extra_info = Fcons (object,
+ Fcons (make_number (textpos),
+ Fcons (Fcons (make_number (rx),
+ make_number (ry)),
+ Fcons (Fcons (make_number (dx),
+ make_number (dy)),
+ Qnil))));
+ }
+ 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.
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;
- int wx, wy;
+#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
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.
}
#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, &wx, &wy, 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);
-
- /* 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;
case WHEEL_EVENT:
{
Lisp_Object position;
- Lisp_Object window;
Lisp_Object head;
- position = Qnil;
- /* Build the position as appropriate for this mouse click. */
- enum window_part part;
- struct frame *f = XFRAME (event->frame_or_window);
- Lisp_Object posn;
- Lisp_Object string_info = Qnil;
- int row, column;
- int wx, wy;
-
- /* Ignore wheel events that were made on frame that have been
- deleted. */
- if (! FRAME_LIVE_P (f))
- return Qnil;
-
- /* 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
- which are then used to determine whether this click is
- in a menu (non-toolkit version). */
- pixel_to_glyph_coords (f, XINT (event->x), XINT (event->y),
- &column, &row, NULL, 1);
-
- /* 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, &wx, &wy, 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);
-
- /* 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))))));
-
- /* 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));
+ /* 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));
}
}
}
#endif /* WINDOWSNT */
-#if 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, 0, 0);
-
- if (!WINDOWP (window))
- {
- window = event->frame_or_window;
- posn = Qnil;
- }
- else
- {
- int pixcolumn, pixrow;
- column -= WINDOW_LEFT_EDGE_COL (XWINDOW (window));
- row -= WINDOW_TOP_EDGE_LINE (XWINDOW (window));
- 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 /* 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;
- int wx, wy;
/* The frame_or_window field should be a cons of the frame in
which the event occurred and a list of the filenames
if (! FRAME_LIVE_P (f))
return Qnil;
- window = window_from_coordinates (f, XINT (event->x),
- XINT (event->y),
- &part, &wx, &wy, 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);
-
- /* 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 */
/* Or is it an ordinary mouse movement? */
else
{
- enum window_part area;
- Lisp_Object window;
- Lisp_Object posn;
- int wx, wy;
-
- if (frame)
- /* It's in a frame; which window on that frame? */
- window = window_from_coordinates (frame, XINT (x), XINT (y),
- &area, &wx, &wy, 0);
- else
- window = Qnil;
+ Lisp_Object position;
- if (WINDOWP (window))
- {
- struct window *w = XWINDOW (window);
-
- /* Set window relative coordinates. */
- 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));
}
}
SBYTES (SYMBOL_NAME (symbol)) - end),
Qnil);
- if (modifiers & ~VALMASK)
+ if (modifiers & ~INTMASK)
abort ();
XSETFASTINT (mask, modifiers);
elements = Fcons (unmodified, Fcons (mask, Qnil));
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);
/* If input is being read as it arrives, and we have none, there is none. */
if (*addr > 0 || (interrupt_input && ! interrupts_deferred))
return;
-
+
/* Try to read some input and see how much we get. */
gobble_input (0);
*addr = (!NILP (Vquit_flag)
{
struct input_event event;
Lisp_Object tem;
+ EVENT_INIT (event);
event.kind = BUFFER_SWITCH_EVENT;
event.frame_or_window = Qnil;
struct input_event buf[KBD_BUFFER_SIZE];
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);
+ nread = (*read_socket_hook) (buf, KBD_BUFFER_SIZE, expected);
else
{
/* Using KBD_BUFFER_SIZE - 1 here avoids reading more than
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. */
+ struct tty_output *tty;
+ Lisp_Object frame;
+
#ifdef WINDOWSNT
return 0;
#else /* not WINDOWSNT */
n_to_read = dos_keysns ();
if (n_to_read == 0)
return 0;
+
+ cbuf[0] = dos_keyread ();
+ nread = 1;
+
#else /* not MSDOS */
+
+ nread = 0;
+
+ /* Try to read from each available tty, until one succeeds. */
+ for (tty = tty_list; tty; tty = tty->next) {
+
+ if (! tty->term_initted)
+ continue;
+
+ /* 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. */
- kill (getpid (), SIGHUP);
- 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 (tty)), 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. */
+ /* It appears to be the case, see narrow_foreground_group. */
+ if (! noninteractive)
+ {
+ if (! tty_list->next)
+ kill (getpid (), SIGHUP); /* This was the last terminal. */
+ else
+ n_to_read = 0; /* XXX tty should be closed here. */
+ }
+ else
+ {
+ n_to_read = 0;
+ }
+ }
+ if (n_to_read == 0)
+ continue;
+ 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 (tty)), 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 (tty)), 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)
+ {
+ if (! tty_list->next)
+ kill (0, SIGHUP); /* This was the last terminal. */
+ else
+ ; /* XXX tty should be closed here. */
+ }
#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)
+ {
+ if (! tty_list->next)
+ kill (0, SIGHUP); /* This was the last terminal. */
+ else
+ ; /* XXX tty should be closed here. */
+ }
#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 (tty)), F_SETFL, 0);
#endif /* USG or DGUX or CYGWIN */
#endif /* no FIONREAD */
+
+ if (nread > 0)
+ break;
+ } /* for each tty */
+
+ if (nread <= 0)
+ return 0;
+
+#endif /* not MSDOS */
+#endif /* not WINDOWSNT */
+
+ /* Select frame corresponding to the active tty. Note that the
+ value of selected_frame is not reliable here, redisplay tends
+ to temporarily change it. But tty should always be non-NULL. */
+ frame = (tty ? tty->top_frame : selected_frame);
+
for (i = 0; i < nread; i++)
{
buf[i].kind = ASCII_KEYSTROKE_EVENT;
buf[i].modifiers = 0;
- if (meta_key == 1 && (cbuf[i] & 0x80))
+ if (tty->meta_key == 1 && (cbuf[i] & 0x80))
buf[i].modifiers = meta_modifier;
- if (meta_key != 2)
+ if (tty->meta_key != 2)
cbuf[i] &= ~0x80;
- buf[i].code = cbuf[i];
- buf[i].frame_or_window = selected_frame;
+ buf[i].code = cbuf[i];
+ buf[i].frame_or_window = frame;
buf[i].arg = Qnil;
}
}
if (EVENT_HAS_PARAMETERS (key))
{
Lisp_Object kind;
+ Lisp_Object string;
kind = EVENT_HEAD_KIND (EVENT_HEAD (key));
if (EQ (kind, Qmouse_click))
/* 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
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
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;
}
int width, height;
struct gcpro gcpro1;
+ if (tty_list && tty_list->next)
+ error ("Suspend is not supported with multiple ttys");
+
if (!NILP (stuffstring))
CHECK_STRING (stuffstring);
call1 (Vrun_hooks, intern ("suspend-hook"));
GCPRO1 (stuffstring);
- get_frame_size (&old_width, &old_height);
- reset_sys_modes ();
+ get_tty_size (CURTTY (), &old_width, &old_height);
+ reset_all_sys_modes ();
/* sys_suspend can get an error if it tries to fork a subshell
and the system resources aren't available for that. */
record_unwind_protect ((Lisp_Object (*) P_ ((Lisp_Object))) init_sys_modes,
- Qnil);
+ (Lisp_Object)CURTTY()); /* XXX */
stuff_buffered_input (stuffstring);
if (cannot_suspend)
sys_subshell ();
/* Check if terminal/window size has changed.
Note that this is not useful when we are running directly
with a window system; but suspend should be disabled in that case. */
- get_frame_size (&width, &height);
+ get_tty_size (CURTTY (), &width, &height);
if (width != old_width || height != old_height)
change_frame_size (SELECTED_FRAME (), height, width, 0, 0, 0);
sigblock (sigmask (SIGINT));
fflush (stdout);
- reset_sys_modes ();
+ reset_all_sys_modes ();
#ifdef SIGTSTP /* Support possible in later USG versions */
/*
printf ("Continuing...\n");
#endif /* not MSDOS */
fflush (stdout);
- init_sys_modes ();
+ init_all_sys_modes ();
sigfree ();
}
else
#ifndef DOS_NT
/* this causes startup screen to be restored and messes with the mouse */
- reset_sys_modes ();
+ reset_sys_modes (CURTTY ());
#endif
#ifdef SIGIO
flow_control = !NILP (flow);
if (NILP (meta))
- meta_key = 0;
+ CURTTY ()->meta_key = 0;
else if (EQ (meta, Qt))
- meta_key = 1;
+ CURTTY ()->meta_key = 1;
else
- meta_key = 2;
+ CURTTY ()->meta_key = 2;
if (!NILP (quit))
/* Don't let this value be out of range. */
- quit_char = XINT (quit) & (meta_key ? 0377 : 0177);
+ quit_char = XINT (quit) & (CURTTY ()->meta_key ? 0377 : 0177);
#ifndef DOS_NT
- init_sys_modes ();
+ init_sys_modes (CURTTY ());
#endif
#ifdef POLL_FOR_INPUT
val[0] = interrupt_input ? Qt : Qnil;
val[1] = flow_control ? Qt : Qnil;
- val[2] = meta_key == 2 ? make_number (0) : meta_key == 1 ? Qt : Qnil;
+ val[2] = FRAME_TTY (SELECTED_FRAME ())->meta_key == 2
+ ? make_number (0)
+ : FRAME_TTY (SELECTED_FRAME ())->meta_key == 1 ? Qt : Qnil;
XSETFASTINT (val[3], quit_char);
return Flist (sizeof (val) / sizeof (val[0]), val);
staticpro (&Qfunction_key);
Qmouse_click = intern ("mouse-click");
staticpro (&Qmouse_click);
-#if defined(MAC_OSX)
- Qmouse_wheel = intern ("mouse-wheel");
- staticpro (&Qmouse_wheel);
-#endif
#ifdef WINDOWSNT
Qlanguage_change = intern ("language-change");
staticpro (&Qlanguage_change);
func_key_syms = Qnil;
staticpro (&func_key_syms);
-#if 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);
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) */