/* X Communication module for terminals which understand the X protocol.
- Copyright (C) 1989, 93, 94, 95, 96, 97, 98, 1999, 2000,01,02,03,04
- Free Software Foundation, Inc.
+ Copyright (C) 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
+ 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
This file is part of GNU Emacs.
struct glyph *last_glyph;
XRectangle clip_rect;
- last_x = window_box_right (s->w, s->area);
- if (s->row->full_width_p
- && !s->w->pseudo_window_p)
- {
- last_x += WINDOW_RIGHT_SCROLL_BAR_AREA_WIDTH (s->w);
- if (s->area != RIGHT_MARGIN_AREA
- || WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (s->w))
- last_x += WINDOW_RIGHT_FRINGE_WIDTH (s->w);
- }
+ last_x = ((s->row->full_width_p && !s->w->pseudo_window_p)
+ ? WINDOW_RIGHT_EDGE_X (s->w)
+ : window_box_right (s->w, s->area));
/* The glyph that may have a right box line. */
last_glyph = (s->cmp || s->img
}
if (part >= 0)
- {
+ {
window_being_scrolled = bar->window;
last_scroll_bar_part = part;
x_send_scroll_bar_event (bar->window, part, portion, whole);
f->output_data.x->saved_menu_event \
= (XEvent *) xmalloc (sizeof (XEvent)); \
bcopy (&event, f->output_data.x->saved_menu_event, size); \
- inev.kind = MENU_BAR_ACTIVATE_EVENT; \
- XSETFRAME (inev.frame_or_window, f); \
+ inev.ie.kind = MENU_BAR_ACTIVATE_EVENT; \
+ XSETFRAME (inev.ie.frame_or_window, f); \
} \
while (0)
int *finish;
struct input_event *hold_quit;
{
- struct input_event inev;
+ union {
+ struct input_event ie;
+ struct selection_input_event sie;
+ } inev;
int count = 0;
int do_help = 0;
int nbytes = 0;
*finish = X_EVENT_NORMAL;
- EVENT_INIT (inev);
- inev.kind = NO_EVENT;
- inev.arg = Qnil;
+ EVENT_INIT (inev.ie);
+ inev.ie.kind = NO_EVENT;
+ inev.ie.arg = Qnil;
switch (event.type)
{
if (!f)
goto OTHER; /* May be a dialog that is to be removed */
- inev.kind = DELETE_WINDOW_EVENT;
- XSETFRAME (inev.frame_or_window, f);
+ inev.ie.kind = DELETE_WINDOW_EVENT;
+ XSETFRAME (inev.ie.frame_or_window, f);
goto done;
}
if (event.xclient.message_type
== dpyinfo->Xatom_Scrollbar)
{
- x_scroll_bar_to_input_event (&event, &inev);
+ x_scroll_bar_to_input_event (&event, &inev.ie);
*finish = X_EVENT_GOTO_OUT;
goto done;
}
if (!f)
goto OTHER;
- if (x_handle_dnd_message (f, &event.xclient, dpyinfo, &inev))
+ if (x_handle_dnd_message (f, &event.xclient, dpyinfo, &inev.ie))
*finish = X_EVENT_DROP;
}
break;
{
XSelectionClearEvent *eventp = (XSelectionClearEvent *) &event;
- inev.kind = SELECTION_CLEAR_EVENT;
- SELECTION_EVENT_DISPLAY (&inev) = eventp->display;
- SELECTION_EVENT_SELECTION (&inev) = eventp->selection;
- SELECTION_EVENT_TIME (&inev) = eventp->time;
- inev.frame_or_window = Qnil;
+ inev.ie.kind = SELECTION_CLEAR_EVENT;
+ SELECTION_EVENT_DISPLAY (&inev.sie) = eventp->display;
+ SELECTION_EVENT_SELECTION (&inev.sie) = eventp->selection;
+ SELECTION_EVENT_TIME (&inev.sie) = eventp->time;
+ inev.ie.frame_or_window = Qnil;
}
break;
XSelectionRequestEvent *eventp
= (XSelectionRequestEvent *) &event;
- inev.kind = SELECTION_REQUEST_EVENT;
- SELECTION_EVENT_DISPLAY (&inev) = eventp->display;
- SELECTION_EVENT_REQUESTOR (&inev) = eventp->requestor;
- SELECTION_EVENT_SELECTION (&inev) = eventp->selection;
- SELECTION_EVENT_TARGET (&inev) = eventp->target;
- SELECTION_EVENT_PROPERTY (&inev) = eventp->property;
- SELECTION_EVENT_TIME (&inev) = eventp->time;
- inev.frame_or_window = Qnil;
+ inev.ie.kind = SELECTION_REQUEST_EVENT;
+ SELECTION_EVENT_DISPLAY (&inev.sie) = eventp->display;
+ SELECTION_EVENT_REQUESTOR (&inev.sie) = eventp->requestor;
+ SELECTION_EVENT_SELECTION (&inev.sie) = eventp->selection;
+ SELECTION_EVENT_TARGET (&inev.sie) = eventp->target;
+ SELECTION_EVENT_PROPERTY (&inev.sie) = eventp->property;
+ SELECTION_EVENT_TIME (&inev.sie) = eventp->time;
+ inev.ie.frame_or_window = Qnil;
}
break;
{
f->async_iconified = 1;
- inev.kind = ICONIFY_EVENT;
- XSETFRAME (inev.frame_or_window, f);
+ inev.ie.kind = ICONIFY_EVENT;
+ XSETFRAME (inev.ie.frame_or_window, f);
}
}
goto OTHER;
if (f->iconified)
{
- inev.kind = DEICONIFY_EVENT;
- XSETFRAME (inev.frame_or_window, f);
+ inev.ie.kind = DEICONIFY_EVENT;
+ XSETFRAME (inev.ie.frame_or_window, f);
}
else if (! NILP (Vframe_list)
&& ! NILP (XCDR (Vframe_list)))
orig_keysym = keysym;
/* Common for all keysym input events. */
- XSETFRAME (inev.frame_or_window, f);
- inev.modifiers
+ XSETFRAME (inev.ie.frame_or_window, f);
+ inev.ie.modifiers
= x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f), modifiers);
- inev.timestamp = event.xkey.time;
+ inev.ie.timestamp = event.xkey.time;
/* First deal with keysyms which have defined
translations to characters. */
if (keysym >= 32 && keysym < 128)
/* Avoid explicitly decoding each ASCII character. */
{
- inev.kind = ASCII_KEYSTROKE_EVENT;
- inev.code = keysym;
+ inev.ie.kind = ASCII_KEYSTROKE_EVENT;
+ inev.ie.code = keysym;
goto done_keysym;
}
Vx_keysym_table,
Qnil))))
{
- inev.kind = (SINGLE_BYTE_CHAR_P (XFASTINT (c))
- ? ASCII_KEYSTROKE_EVENT
- : MULTIBYTE_CHAR_KEYSTROKE_EVENT);
- inev.code = XFASTINT (c);
+ inev.ie.kind = (SINGLE_BYTE_CHAR_P (XFASTINT (c))
+ ? ASCII_KEYSTROKE_EVENT
+ : MULTIBYTE_CHAR_KEYSTROKE_EVENT);
+ inev.ie.code = XFASTINT (c);
goto done_keysym;
}
STORE_KEYSYM_FOR_DEBUG (keysym);
/* make_lispy_event will convert this to a symbolic
key. */
- inev.kind = NON_ASCII_KEYSTROKE_EVENT;
- inev.code = keysym;
+ inev.ie.kind = NON_ASCII_KEYSTROKE_EVENT;
+ inev.ie.code = keysym;
goto done_keysym;
}
else
c = STRING_CHAR_AND_LENGTH (copy_bufptr + i,
nbytes - i, len);
- inev.kind = (SINGLE_BYTE_CHAR_P (c)
+ inev.ie.kind = (SINGLE_BYTE_CHAR_P (c)
? ASCII_KEYSTROKE_EVENT
: MULTIBYTE_CHAR_KEYSTROKE_EVENT);
- inev.code = c;
- kbd_buffer_store_event_hold (&inev, hold_quit);
+ inev.ie.code = c;
+ kbd_buffer_store_event_hold (&inev.ie, hold_quit);
}
/* Previous code updated count by nchars rather than nbytes,
but that seems bogus to me. ++kfs */
count += nbytes;
- inev.kind = NO_EVENT; /* Already stored above. */
+ inev.ie.kind = NO_EVENT; /* Already stored above. */
if (keysym == NoSymbol)
break;
#endif
case EnterNotify:
- x_detect_focus_change (dpyinfo, &event, &inev);
+ x_detect_focus_change (dpyinfo, &event, &inev.ie);
f = x_any_window_to_frame (dpyinfo, event.xcrossing.window);
goto OTHER;
case FocusIn:
- x_detect_focus_change (dpyinfo, &event, &inev);
+ x_detect_focus_change (dpyinfo, &event, &inev.ie);
goto OTHER;
case LeaveNotify:
- x_detect_focus_change (dpyinfo, &event, &inev);
+ x_detect_focus_change (dpyinfo, &event, &inev.ie);
f = x_top_window_to_frame (dpyinfo, event.xcrossing.window);
if (f)
goto OTHER;
case FocusOut:
- x_detect_focus_change (dpyinfo, &event, &inev);
+ x_detect_focus_change (dpyinfo, &event, &inev.ie);
goto OTHER;
case MotionNotify:
&& !EQ (window, last_window)
&& !EQ (window, selected_window))
{
- inev.kind = SELECT_WINDOW_EVENT;
- inev.frame_or_window = window;
+ inev.ie.kind = SELECT_WINDOW_EVENT;
+ inev.ie.frame_or_window = window;
}
last_window=window;
&& (int)(event.xbutton.time - ignore_next_mouse_click_timeout) > 0)
{
ignore_next_mouse_click_timeout = 0;
- construct_mouse_click (&inev, &event, f);
+ construct_mouse_click (&inev.ie, &event, f);
}
if (event.type == ButtonRelease)
ignore_next_mouse_click_timeout = 0;
}
else
- construct_mouse_click (&inev, &event, f);
+ construct_mouse_click (&inev.ie, &event, f);
}
}
}
scroll bars. */
if (bar && event.xbutton.state & ControlMask)
{
- x_scroll_bar_handle_click (bar, &event, &inev);
+ x_scroll_bar_handle_click (bar, &event, &inev.ie);
*finish = X_EVENT_DROP;
}
#else /* not USE_TOOLKIT_SCROLL_BARS */
if (bar)
- x_scroll_bar_handle_click (bar, &event, &inev);
+ x_scroll_bar_handle_click (bar, &event, &inev.ie);
#endif /* not USE_TOOLKIT_SCROLL_BARS */
}
}
done:
- if (inev.kind != NO_EVENT)
+ if (inev.ie.kind != NO_EVENT)
{
- kbd_buffer_store_event_hold (&inev, hold_quit);
+ kbd_buffer_store_event_hold (&inev.ie, hold_quit);
count++;
}
window_box (w, area, &window_x, &window_y, &window_width, 0);
clip_rect.x = window_x;
- clip_rect.y = WINDOW_TO_FRAME_PIXEL_Y (w, row->y);
+ clip_rect.y = WINDOW_TO_FRAME_PIXEL_Y (w, max (0, row->y));
clip_rect.y = max (clip_rect.y, window_y);
clip_rect.width = window_width;
clip_rect.height = row->visible_height;
if (cursor_glyph == NULL)
return;
- /* Compute the width of the rectangle to draw. If on a stretch
- glyph, and `x-stretch-block-cursor' is nil, don't draw a
- rectangle as wide as the glyph, but use a canonical character
- width instead. */
- wd = cursor_glyph->pixel_width - 1;
- if (cursor_glyph->type == STRETCH_GLYPH
- && !x_stretch_cursor_p)
- wd = min (FRAME_COLUMN_WIDTH (f), wd);
- w->phys_cursor_width = wd;
-
- /* Compute frame-relative coordinates from window-relative
- coordinates. */
+ /* Compute frame-relative coordinates for phys cursor. */
x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
- y = WINDOW_TO_FRAME_PIXEL_Y (w, w->phys_cursor.y);
-
- /* Compute the proper height and ascent of the rectangle, based
- on the actual glyph. Using the full height of the row looks
- bad when there are tall images on that row. */
- h = max (min (FRAME_LINE_HEIGHT (f), row->height),
- cursor_glyph->ascent + cursor_glyph->descent);
- if (h < row->height)
- y += row->ascent /* - w->phys_cursor_ascent */ + cursor_glyph->descent - h;
- h--;
+ y = get_phys_cursor_geometry (w, row, cursor_glyph, &h);
+ wd = w->phys_cursor_width;
/* The foreground of cursor_gc is typically the same as the normal
background color, which can cause the cursor box to be invisible. */
error ("%s", error_msg);
}
+/* We specifically use it before defining it, so that gcc doesn't inline it,
+ otherwise gdb doesn't know how to properly put a breakpoint on it. */
+static void x_error_quitter (Display *display, XErrorEvent *error);
+
+/* This is the first-level handler for X protocol errors.
+ It calls x_error_quitter or x_error_catcher. */
+
+static int
+x_error_handler (display, error)
+ Display *display;
+ XErrorEvent *error;
+{
+ if (! NILP (x_error_message_string))
+ x_error_catcher (display, error);
+ else
+ x_error_quitter (display, error);
+ return 0;
+}
/* This is the usual handler for X protocol errors.
It kills all frames on the display that we got the error for.
If that was the only one, it prints an error message and kills Emacs. */
-static void
+/* .gdbinit puts a breakpoint here, so make sure it is not inlined. */
+
+#if __GNUC__ >= 3 /* On GCC 3.0 we might get a warning. */
+#define NO_INLINE __attribute__((noinline))
+#else
+#define NO_INLINE
+#endif
+
+/* On older GCC versions, just putting x_error_quitter
+ after x_error_handler prevents inlining into the former. */
+
+static void NO_INLINE
x_error_quitter (display, error)
Display *display;
XErrorEvent *error;
}
-/* This is the first-level handler for X protocol errors.
- It calls x_error_quitter or x_error_catcher. */
-
-static int
-x_error_handler (display, error)
- Display *display;
- XErrorEvent *error;
-{
- if (! NILP (x_error_message_string))
- x_error_catcher (display, error);
- else
- x_error_quitter (display, error);
- return 0;
-}
-
/* This is the handler for X IO errors, always.
It kills all frames on the display that we lost touch with.
If that was the only one, it prints an error message and kills Emacs. */