#ifdef USE_X_TOOLKIT
-extern void free_frame_menubar ();
-extern FRAME_PTR x_menubar_window_to_frame ();
+extern void free_frame_menubar P_ ((struct frame *));
+extern struct frame *x_menubar_window_to_frame P_ ((struct x_display_info *,
+ int));
#if (XtSpecificationRelease >= 5) && !defined(NO_EDITRES)
#define HACK_EDITRES
(The display is done in read_char.) */
static Lisp_Object help_echo;
+static Lisp_Object help_echo_window;
+static Lisp_Object help_echo_object;
+static int help_echo_pos;
/* Temporary variable for XTread_socket. */
static Lisp_Object Qvendor_specific_keysyms;
-extern XrmDatabase x_load_resources ();
-extern Lisp_Object x_icon_type ();
+extern XrmDatabase x_load_resources P_ ((Display *, char *, char *, char *));
+extern Lisp_Object x_icon_type P_ ((struct frame *));
/* Enumeration for overriding/changing the face to use for drawing
DRAW_IMAGE_SUNKEN
};
-static void x_update_window_end P_ ((struct window *, int));
+static void x_update_window_end P_ ((struct window *, int, int));
static void frame_to_window_pixel_xy P_ ((struct window *, int *, int *));
void x_delete_display P_ ((struct x_display_info *));
static unsigned int x_x_to_emacs_modifiers P_ ((struct x_display_info *,
static void x_draw_row_bitmaps P_ ((struct window *, struct glyph_row *));
static void note_overwritten_text_cursor P_ ((struct window *, int, int));
static void x_flush P_ ((struct frame *f));
-
+static void x_update_begin P_ ((struct frame *));
+static void x_update_window_begin P_ ((struct window *));
+static void x_draw_vertical_border P_ ((struct window *));
+static void x_after_update_window_line P_ ((struct glyph_row *));
+static INLINE void take_vertical_position_into_account P_ ((struct it *));
+static void x_produce_stretch_glyph P_ ((struct it *));
+
/* Flush display of frame F, or of all frames if F is null. */
}
-/* End update of window W (which is equal to updated_window). Draw
- vertical borders between horizontally adjacent windows, and display
- W's cursor if CURSOR_ON_P is non-zero. W may be a menu bar
- pseudo-window in case we don't have X toolkit support. Such
- windows don't have a cursor, so don't display it here. */
+/* End update of window W (which is equal to updated_window).
+
+ Draw vertical borders between horizontally adjacent windows, and
+ display W's cursor if CURSOR_ON_P is non-zero.
+
+ MOUSE_FACE_OVERWRITTEN_P non-zero means that some row containing
+ glyphs in mouse-face were overwritten. In that case we have to
+ make sure that the mouse-highlight is properly redrawn.
+
+ W may be a menu bar pseudo-window in case we don't have X toolkit
+ support. Such windows don't have a cursor, so don't display it
+ here. */
static void
-x_update_window_end (w, cursor_on_p)
+x_update_window_end (w, cursor_on_p, mouse_face_overwritten_p)
struct window *w;
- int cursor_on_p;
+ int cursor_on_p, mouse_face_overwritten_p;
{
if (!w->pseudo_window_p)
{
+ struct x_display_info *dpyinfo
+ = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
+
BLOCK_INPUT;
+
+ /* If a row with mouse-face was overwritten, arrange for
+ XTframe_up_to_date to redisplay the mouse highlight. */
+ if (mouse_face_overwritten_p)
+ {
+ dpyinfo->mouse_face_beg_row = dpyinfo->mouse_face_beg_col = -1;
+ dpyinfo->mouse_face_end_row = dpyinfo->mouse_face_end_col = -1;
+ dpyinfo->mouse_face_window = Qnil;
+ }
+
if (cursor_on_p)
x_display_and_set_cursor (w, 1, output_cursor.hpos,
output_cursor.vpos,
output_cursor.x, output_cursor.y);
+
x_draw_vertical_border (w);
UNBLOCK_INPUT;
}
if (FRAME_X_P (f))
{
struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+
if (dpyinfo->mouse_face_deferred_gc
|| f == dpyinfo->mouse_face_mouse_frame)
{
XSETINT (result->x, event->x);
XSETINT (result->y, event->y);
XSETFRAME (result->frame_or_window, f);
+ result->arg = Qnil;
return Qnil;
}
-#if 0 /* This function isn't called. --gerd */
-
-/* Prepare a menu-event in *RESULT for placement in the input queue. */
-
-static Lisp_Object
-construct_menu_click (result, event, f)
- struct input_event *result;
- XButtonEvent *event;
- struct frame *f;
-{
- /* Make the event type no_event; we'll change that when we decide
- otherwise. */
- result->kind = mouse_click;
- result->code = event->button - Button1;
- result->timestamp = event->time;
- result->modifiers = (x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f),
- event->state)
- | (event->type == ButtonRelease
- ? up_modifier
- : down_modifier));
-
- XSETINT (result->x, event->x);
- XSETINT (result->y, -1);
- XSETFRAME (result->frame_or_window, f);
-}
-
-#endif /* 0 */
-
\f
/* Function to report a mouse movement to the mainstream Emacs code.
The input handler calls this.
help = Fget_text_property (make_number (glyph->charpos),
Qhelp_echo, glyph->object);
if (!NILP (help))
- help_echo = help;
+ {
+ help_echo = help;
+ XSETWINDOW (help_echo_window, w);
+ help_echo_object = glyph->object;
+ help_echo_pos = glyph->charpos;
+ }
/* Change the mouse pointer according to what is under X/Y. */
map = Fget_text_property (make_number (glyph->charpos),
Qlocal_map, glyph->object);
if (!NILP (Fkeymapp (map)))
cursor = f->output_data.x->nontext_cursor;
+ else
+ {
+ map = Fget_text_property (make_number (glyph->charpos),
+ Qkeymap, glyph->object);
+ if (!NILP (Fkeymapp (map)))
+ cursor = f->output_data.x->nontext_cursor;
+ }
}
}
overlay_vec = (Lisp_Object *) alloca (len * sizeof (Lisp_Object));
noverlays = overlays_at (pos, 0, &overlay_vec, &len, NULL, NULL);
}
-
+
+ /* Sort overlays into increasing priority order. */
noverlays = sort_overlays (overlay_vec, noverlays, w);
/* Check mouse-face highlighting. */
/* Find the highest priority overlay that has a mouse-face prop. */
overlay = Qnil;
- for (i = 0; i < noverlays; i++)
+ for (i = noverlays - 1; i >= 0; --i)
{
mouse_face = Foverlay_get (overlay_vec[i], Qmouse_face);
if (!NILP (mouse_face))
/* Look for a `help-echo' property. */
{
- Lisp_Object help;
+ Lisp_Object help, overlay;
/* Check overlays first. */
help = Qnil;
- for (i = 0; i < noverlays && NILP (help); ++i)
- help = Foverlay_get (overlay_vec[i], Qhelp_echo);
-
- /* Try text properties. */
- if (NILP (help)
- && ((STRINGP (glyph->object)
+ for (i = noverlays - 1; i >= 0 && NILP (help); --i)
+ {
+ overlay = overlay_vec[i];
+ help = Foverlay_get (overlay, Qhelp_echo);
+ }
+
+ if (!NILP (help))
+ {
+ help_echo = help;
+ help_echo_window = window;
+ help_echo_object = overlay;
+ help_echo_pos = pos;
+ }
+ else
+ {
+ /* Try text properties. */
+ if ((STRINGP (glyph->object)
&& glyph->charpos >= 0
&& glyph->charpos < XSTRING (glyph->object)->size)
|| (BUFFERP (glyph->object)
&& glyph->charpos >= BEGV
- && glyph->charpos < ZV)))
- help = Fget_text_property (make_number (glyph->charpos),
- Qhelp_echo, glyph->object);
+ && glyph->charpos < ZV))
+ help = Fget_text_property (make_number (glyph->charpos),
+ Qhelp_echo, glyph->object);
- if (!NILP (help))
- help_echo = help;
+ if (!NILP (help))
+ {
+ help_echo = help;
+ help_echo_window = window;
+ help_echo_object = glyph->object;
+ help_echo_pos = glyph->charpos;
+ }
+ }
}
BEGV = obegv;
XSETFRAME (frame, f);
event.kind = TOOL_BAR_EVENT;
- event.frame_or_window = Fcons (frame, Fcons (Qtool_bar, Qnil));
+ event.frame_or_window = frame;
+ event.arg = frame;
kbd_buffer_store_event (&event);
event.kind = TOOL_BAR_EVENT;
- event.frame_or_window = Fcons (frame, key);
+ event.frame_or_window = frame;
+ event.arg = key;
event.modifiers = x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f),
button_event->state);
kbd_buffer_store_event (&event);
/* Set help_echo to a help string.to display for this tool-bar item.
XTread_socket does the rest. */
+ help_echo_object = help_echo_window = Qnil;
+ help_echo_pos = -1;
help_echo = (XVECTOR (f->current_tool_bar_items)
->contents[prop_idx + TOOL_BAR_ITEM_HELP]);
if (NILP (help_echo))
dpyinfo->mouse_face_window = Qnil;
}
+
+/* Clear any mouse-face on window W. This function is part of the
+ redisplay interface, and is called from try_window_id and similar
+ functions to ensure the mouse-highlight is off. */
+
+static void
+x_clear_mouse_face (w)
+ struct window *w;
+{
+ struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (XFRAME (w->frame));
+ Lisp_Object window;
+
+ XSETWINDOW (window, w);
+ if (EQ (window, dpyinfo->mouse_face_window))
+ clear_mouse_face (dpyinfo);
+}
+
+
/* Just discard the mouse face information for frame F, if any.
This is used when the size of F is changed. */
ievent->kind = scroll_bar_click;
ievent->frame_or_window = window;
+ ievent->arg = Qnil;
ievent->timestamp = XtLastTimestampProcessed (FRAME_X_DISPLAY (f));
ievent->part = ev->data.l[1];
ievent->code = ev->data.l[2];
? up_modifier
: down_modifier));
emacs_event->frame_or_window = bar->window;
+ emacs_event->arg = Qnil;
emacs_event->timestamp = event->xbutton.time;
{
#if 0
{ \
bufp->kind = menu_bar_activate_event; \
XSETFRAME (bufp->frame_or_window, f); \
+ bufp->arg = Qnil; \
bufp++; \
count++; \
numchars--; \
bufp->kind = delete_window_event;
XSETFRAME (bufp->frame_or_window, f);
+ bufp->arg = Qnil;
bufp++;
count += 1;
SELECTION_EVENT_SELECTION (bufp) = eventp->selection;
SELECTION_EVENT_TIME (bufp) = eventp->time;
bufp->frame_or_window = Qnil;
+ bufp->arg = Qnil;
bufp++;
count += 1;
SELECTION_EVENT_PROPERTY (bufp) = eventp->property;
SELECTION_EVENT_TIME (bufp) = eventp->time;
bufp->frame_or_window = Qnil;
+ bufp->arg = Qnil;
bufp++;
count += 1;
bufp->kind = iconify_event;
XSETFRAME (bufp->frame_or_window, f);
+ bufp->arg = Qnil;
bufp++;
count++;
numchars--;
{
bufp->kind = deiconify_event;
XSETFRAME (bufp->frame_or_window, f);
+ bufp->arg = Qnil;
bufp++;
count++;
numchars--;
bufp->kind = non_ascii_keystroke;
bufp->code = keysym;
XSETFRAME (bufp->frame_or_window, f);
+ bufp->arg = Qnil;
bufp->modifiers
= x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f),
modifiers);
bufp->kind = ascii_keystroke;
bufp->code = copy_buffer[i];
XSETFRAME (bufp->frame_or_window, f);
+ bufp->arg = Qnil;
bufp->modifiers
= x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f),
modifiers);
{
bufp->kind = FOCUS_IN_EVENT;
XSETFRAME (bufp->frame_or_window, f);
+ bufp->arg = Qnil;
++bufp, ++count, --numchars;
}
}
the mouse leaves the frame. */
if (any_help_event_p)
{
+ Lisp_Object frame;
+ int n;
+
XSETFRAME (frame, f);
- bufp->kind = HELP_EVENT;
- bufp->frame_or_window = Fcons (frame, Qnil);
- ++bufp, ++count, --numchars;
+ n = gen_help_event (bufp, Qnil, frame, Qnil, Qnil, 0);
+ bufp += n, count += n, numchars -= n;
}
#ifdef LESSTIF_VERSION
case MotionNotify:
{
previous_help_echo = help_echo;
- help_echo = Qnil;
+ help_echo = help_echo_object = help_echo_window = Qnil;
+ help_echo_pos = -1;
if (dpyinfo->grabbed && last_mouse_frame
&& FRAME_LIVE_P (last_mouse_frame))
|| !NILP (previous_help_echo))
{
Lisp_Object frame;
+ int n;
if (f)
XSETFRAME (frame, f);
frame = Qnil;
any_help_event_p = 1;
- bufp->kind = HELP_EVENT;
- bufp->frame_or_window = Fcons (frame, help_echo);
- ++bufp, ++count, --numchars;
+ n = gen_help_event (bufp, help_echo, frame,
+ help_echo_window, help_echo_object,
+ help_echo_pos);
+ bufp += n, count += n, numchars -= n;
}
goto OTHER;
x_update_window_end,
XTcursor_to,
x_flush,
+ x_clear_mouse_face,
x_get_glyph_overhangs,
x_fix_overlapping_area
};
staticpro (&last_mouse_press_frame);
last_mouse_press_frame = Qnil;
- staticpro (&help_echo);
help_echo = Qnil;
- staticpro (&previous_help_echo);
+ staticpro (&help_echo);
+ help_echo_object = Qnil;
+ staticpro (&help_echo_object);
+ help_echo_window = Qnil;
+ staticpro (&help_echo_window);
previous_help_echo = Qnil;
+ staticpro (&previous_help_echo);
+ help_echo_pos = -1;
DEFVAR_BOOL ("x-stretch-cursor", &x_stretch_cursor_p,
"*Non-nil means draw block cursor as wide as the glyph under it.\n\