#endif
#ifdef USE_LUCID
-extern int xlwmenu_window_p (Widget w, Window window);
+extern int xlwmenu_window_p P_ ((Widget w, Window window));
extern void xlwmenu_redisplay P_ ((Widget));
#endif
static void frame_highlight P_ ((struct frame *));
static void frame_unhighlight P_ ((struct frame *));
static void x_new_focus_frame P_ ((struct x_display_info *, struct frame *));
+static int x_focus_changed P_ ((int,
+ int,
+ struct x_display_info *,
+ struct frame *,
+ struct input_event *,
+ int));
+static int x_detect_focus_change P_ ((struct x_display_info *,
+ XEvent *,
+ struct input_event *,
+ int));
static void XTframe_rehighlight P_ ((struct frame *));
static void x_frame_rehighlight P_ ((struct x_display_info *));
static void x_draw_hollow_cursor P_ ((struct window *, struct glyph_row *));
XRectangle *));
static void expose_frame P_ ((struct frame *, int, int, int, int));
static int expose_window_tree P_ ((struct window *, XRectangle *));
+static void expose_overlaps P_ ((struct window *, struct glyph_row *,
+ struct glyph_row *));
static int expose_window P_ ((struct window *, XRectangle *));
static void expose_area P_ ((struct window *, struct glyph_row *,
XRectangle *, enum glyph_row_area));
the image. I believe it's looking better if we do
nothing here for mouse-face. */
if (s->hl == DRAW_CURSOR)
- XDrawRectangle (s->display, s->window, s->gc, x, y,
- s->img->width - 1, s->img->height - 1);
+ {
+ int r = s->img->relief;
+ if (r < 0) r = -r;
+ XDrawRectangle (s->display, s->window, s->gc, x - r, y - r,
+ s->img->width + r*2 - 1, s->img->height + r*2 - 1);
+ }
}
}
else
the image. I believe it's looking better if we do
nothing here for mouse-face. */
if (s->hl == DRAW_CURSOR)
- XDrawRectangle (s->display, pixmap, s->gc, x, y,
- s->img->width - 1, s->img->height - 1);
+ {
+ int r = s->img->relief;
+ if (r < 0) r = -r;
+ XDrawRectangle (s->display, s->window, s->gc, x - r, y - r,
+ s->img->width + r*2 - 1, s->img->height + r*2 - 1);
+ }
}
}
else
hpos, hpos + len,
DRAW_NORMAL_TEXT, 0);
+ /* Invalidate old phys cursor if the glyph at its hpos is redrawn. */
+ if (updated_area == TEXT_AREA
+ && updated_window->phys_cursor_on_p
+ && updated_window->phys_cursor.vpos == output_cursor.vpos
+ && updated_window->phys_cursor.hpos >= hpos
+ && updated_window->phys_cursor.hpos < hpos + len)
+ updated_window->phys_cursor_on_p = 0;
+
UNBLOCK_INPUT;
/* Advance the output cursor. */
}
+/* Redraw those parts of glyphs rows during expose event handling that
+ overlap other rows. Redrawing of an exposed line writes over parts
+ of lines overlapping that exposed line; this function fixes that.
+
+ W is the window being exposed. FIRST_OVERLAPPING_ROW is the first
+ row in W's current matrix that is exposed and overlaps other rows.
+ LAST_OVERLAPPING_ROW is the last such row. */
+
+static void
+expose_overlaps (w, first_overlapping_row, last_overlapping_row)
+ struct window *w;
+ struct glyph_row *first_overlapping_row;
+ struct glyph_row *last_overlapping_row;
+{
+ struct glyph_row *row;
+
+ for (row = first_overlapping_row; row <= last_overlapping_row; ++row)
+ if (row->overlapping_p)
+ {
+ xassert (row->enabled_p && !row->mode_line_p);
+
+ if (row->used[LEFT_MARGIN_AREA])
+ x_fix_overlapping_area (w, row, LEFT_MARGIN_AREA);
+
+ if (row->used[TEXT_AREA])
+ x_fix_overlapping_area (w, row, TEXT_AREA);
+
+ if (row->used[RIGHT_MARGIN_AREA])
+ x_fix_overlapping_area (w, row, RIGHT_MARGIN_AREA);
+ }
+}
+
+
/* Redraw the part of window W intersection rectangle FR. Pixel
coordinates in FR are frame-relative. Call this function with
input blocked. Value is non-zero if the exposure overwrites
int yb = window_text_bottom_y (w);
struct glyph_row *row;
int cursor_cleared_p;
+ struct glyph_row *first_overlapping_row, *last_overlapping_row;
TRACE ((stderr, "expose_window (%d, %d, %d, %d)\n",
r.x, r.y, r.width, r.height));
else
cursor_cleared_p = 0;
- /* Find the first row intersecting the rectangle R. */
+ /* Update lines intersecting rectangle R. */
+ first_overlapping_row = last_overlapping_row = NULL;
for (row = w->current_matrix->rows;
row->enabled_p;
++row)
|| (r.y >= y0 && r.y < y1)
|| (r.y + r.height > y0 && r.y + r.height < y1))
{
+ if (row->overlapping_p)
+ {
+ if (first_overlapping_row == NULL)
+ first_overlapping_row = row;
+ last_overlapping_row = row;
+ }
+
if (expose_line (w, row, &r))
mouse_face_overwritten_p = 1;
}
if (!w->pseudo_window_p)
{
+ /* Fix the display of overlapping rows. */
+ if (first_overlapping_row)
+ expose_overlaps (w, first_overlapping_row, last_overlapping_row);
+
/* Draw border between windows. */
x_draw_vertical_border (w);
x_frame_rehighlight (dpyinfo);
}
+/* Handle FocusIn and FocusOut state changes for FRAME.
+ If FRAME has focus and there exists more than one frame, puts
+ an FOCUS_IN_EVENT into BUFP.
+ Returns number of events inserted into BUFP. */
+
+static int
+x_focus_changed (type, state, dpyinfo, frame, bufp, numchars)
+ int type;
+ int state;
+ struct x_display_info *dpyinfo;
+ struct frame *frame;
+ struct input_event *bufp;
+ int numchars;
+{
+ int nr_events = 0;
+
+ if (type == FocusIn)
+ {
+ if (dpyinfo->x_focus_event_frame != frame)
+ {
+ x_new_focus_frame (dpyinfo, frame);
+ dpyinfo->x_focus_event_frame = frame;
+
+ /* Don't stop displaying the initial startup message
+ for a switch-frame event we don't need. */
+ if (numchars > 0
+ && GC_NILP (Vterminal_frame)
+ && GC_CONSP (Vframe_list)
+ && !GC_NILP (XCDR (Vframe_list)))
+ {
+ bufp->kind = FOCUS_IN_EVENT;
+ XSETFRAME (bufp->frame_or_window, frame);
+ bufp->arg = Qnil;
+ ++bufp;
+ numchars--;
+ ++nr_events;
+ }
+ }
+
+ frame->output_data.x->focus_state |= state;
+
+#ifdef HAVE_X_I18N
+ if (FRAME_XIC (frame))
+ XSetICFocus (FRAME_XIC (frame));
+#endif
+ }
+ else if (type == FocusOut)
+ {
+ frame->output_data.x->focus_state &= ~state;
+
+ if (dpyinfo->x_focus_event_frame == frame)
+ {
+ dpyinfo->x_focus_event_frame = 0;
+ x_new_focus_frame (dpyinfo, 0);
+ }
+
+#ifdef HAVE_X_I18N
+ if (FRAME_XIC (frame))
+ XUnsetICFocus (FRAME_XIC (frame));
+#endif
+ }
+
+ return nr_events;
+}
+
+/* The focus may have changed. Figure out if it is a real focus change,
+ by checking both FocusIn/Out and Enter/LeaveNotify events.
+
+ Returns number of events inserted into BUFP. */
+
+static int
+x_detect_focus_change (dpyinfo, event, bufp, numchars)
+ struct x_display_info *dpyinfo;
+ XEvent *event;
+ struct input_event *bufp;
+ int numchars;
+{
+ struct frame *frame;
+ int nr_events = 0;
+
+ frame = x_top_window_to_frame (dpyinfo, event->xany.window);
+ if (! frame) return nr_events;
+
+ switch (event->type)
+ {
+ case EnterNotify:
+ case LeaveNotify:
+ if (event->xcrossing.detail != NotifyInferior
+ && event->xcrossing.focus
+ && ! (frame->output_data.x->focus_state & FOCUS_EXPLICIT))
+ nr_events = x_focus_changed ((event->type == EnterNotify
+ ? FocusIn : FocusOut),
+ FOCUS_IMPLICIT,
+ dpyinfo,
+ frame,
+ bufp,
+ numchars);
+ break;
+
+ case FocusIn:
+ case FocusOut:
+ nr_events = x_focus_changed (event->type,
+ (event->xfocus.detail == NotifyPointer
+ ? FOCUS_IMPLICIT : FOCUS_EXPLICIT),
+ dpyinfo,
+ frame,
+ bufp,
+ numchars);
+ break;
+ }
+
+ return nr_events;
+}
+
+
/* Handle an event saying the mouse has moved out of an Emacs frame. */
void
XButtonEvent *event;
struct frame *f;
{
- /* Make the event type no_event; we'll change that when we decide
+ /* Make the event type NO_EVENT; we'll change that when we decide
otherwise. */
- result->kind = mouse_click;
+ result->kind = MOUSE_CLICK_EVENT;
result->code = event->button - Button1;
result->timestamp = event->time;
result->modifiers = (x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO (f),
struct frame *f = XFRAME (w->frame);
struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
Cursor cursor = dpyinfo->vertical_scroll_bar_cursor;
- struct glyph_row *row;
- int i, area, charpos;
+ int charpos;
Lisp_Object string, help, map, pos;
if (portion == 1 || portion == 3)
if (NILP (b))
b = make_number (0);
if (NILP (e))
- e = make_number (XSTRING (object)->size - 1);
+ e = make_number (SCHARS (object) - 1);
fast_find_string_pos (w, XINT (b), object,
&dpyinfo->mouse_face_beg_col,
&dpyinfo->mouse_face_beg_row,
/* Try text properties. */
if (STRINGP (object)
&& charpos >= 0
- && charpos < XSTRING (object)->size)
+ && charpos < SCHARS (object))
{
help = Fget_text_property (make_number (charpos),
Qhelp_echo, object);
/* Action hook installed via XtAppAddActionHook when toolkit scroll
bars are used.. The hook is responsible for detecting when
the user ends an interaction with the scroll bar, and generates
- a `end-scroll' scroll_bar_click' event if so. */
+ a `end-scroll' SCROLL_BAR_CLICK_EVENT' event if so. */
static void
xt_action_hook (widget, client_data, action_name, event, params,
XSETWINDOW (window, w);
f = XFRAME (w->frame);
- ievent->kind = scroll_bar_click;
+ ievent->kind = SCROLL_BAR_CLICK_EVENT;
ievent->frame_or_window = window;
ievent->arg = Qnil;
ievent->timestamp = XtLastTimestampProcessed (FRAME_X_DISPLAY (f));
/* Scroll bar callback for Motif scroll bars. WIDGET is the scroll
bar widget. CLIENT_DATA is a pointer to the scroll_bar structure.
- CALL_DATA is a pointer a a XmScrollBarCallbackStruct. */
+ CALL_DATA is a pointer to a XmScrollBarCallbackStruct. */
static void
xm_scroll_callback (widget, client_data, call_data)
#endif /* !USE_MOTIF */
- /* Install an action hook that let's us detect when the user
+ /* Install an action hook that lets us detect when the user
finishes interacting with a scroll bar. */
if (action_hook_id == 0)
action_hook_id = XtAppAddActionHook (Xt_app_con, xt_action_hook, 0);
}
/* Handle a mouse click on the scroll bar BAR. If *EMACS_EVENT's kind
- is set to something other than no_event, it is enqueued.
+ is set to something other than NO_EVENT, it is enqueued.
This may be called from a signal handler, so we have to ignore GC
mark bits. */
if (! GC_WINDOWP (bar->window))
abort ();
- emacs_event->kind = scroll_bar_click;
+ emacs_event->kind = SCROLL_BAR_CLICK_EVENT;
emacs_event->code = event->xbutton.button - Button1;
emacs_event->modifiers
= (x_x_to_emacs_modifiers (FRAME_X_DISPLAY_INFO
bcopy (&event, f->output_data.x->saved_menu_event, size); \
if (numchars >= 1) \
{ \
- bufp->kind = menu_bar_activate_event; \
+ bufp->kind = MENU_BAR_ACTIVATE_EVENT; \
XSETFRAME (bufp->frame_or_window, f); \
bufp->arg = Qnil; \
bufp++; \
if (numchars == 0)
abort ();
- bufp->kind = delete_window_event;
+ bufp->kind = DELETE_WINDOW_EVENT;
XSETFRAME (bufp->frame_or_window, f);
bufp->arg = Qnil;
bufp++;
if (numchars == 0)
abort ();
- bufp->kind = selection_clear_event;
+ bufp->kind = SELECTION_CLEAR_EVENT;
SELECTION_EVENT_DISPLAY (bufp) = eventp->display;
SELECTION_EVENT_SELECTION (bufp) = eventp->selection;
SELECTION_EVENT_TIME (bufp) = eventp->time;
if (numchars == 0)
abort ();
- bufp->kind = selection_request_event;
+ bufp->kind = SELECTION_REQUEST_EVENT;
SELECTION_EVENT_DISPLAY (bufp) = eventp->display;
SELECTION_EVENT_REQUESTOR (bufp) = eventp->requestor;
SELECTION_EVENT_SELECTION (bufp) = eventp->selection;
{
f->async_iconified = 1;
- bufp->kind = iconify_event;
+ bufp->kind = ICONIFY_EVENT;
XSETFRAME (bufp->frame_or_window, f);
bufp->arg = Qnil;
bufp++;
if (f->iconified)
{
- bufp->kind = deiconify_event;
+ bufp->kind = DEICONIFY_EVENT;
XSETFRAME (bufp->frame_or_window, f);
bufp->arg = Qnil;
bufp++;
goto OTHER;
case KeyPress:
+
+ /* Dispatch KeyPress events when in menu. */
+ if (popup_activated_flag)
+ goto OTHER;
+
f = x_any_window_to_frame (dpyinfo, event.xkey.window);
if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight))
copy_bufsiz, &keysym,
&status_return);
}
-#ifdef X_HAVE_UTF8_STRING
+/* Xutf8LookupString is a new but already deprecated interface. -stef */
+#if 0 && defined X_HAVE_UTF8_STRING
else if (status_return == XLookupKeySym)
{ /* Try again but with utf-8. */
coding_system = Qutf_8;
if (temp_index == sizeof temp_buffer / sizeof (short))
temp_index = 0;
temp_buffer[temp_index++] = keysym;
- bufp->kind = non_ascii_keystroke;
+ bufp->kind = NON_ASCII_KEYSTROKE_EVENT;
bufp->code = keysym;
XSETFRAME (bufp->frame_or_window, f);
bufp->arg = Qnil;
require = decoding_buffer_size (&coding, nbytes);
p = (unsigned char *) alloca (require);
coding.mode |= CODING_MODE_LAST_BLOCK;
+ /* We explicitely disable composition
+ handling because key data should
+ not contain any composition
+ sequence. */
+ coding.composing = COMPOSITION_DISABLED;
decode_coding (&coding, copy_bufptr, p,
nbytes, require);
nbytes = coding.produced;
nbytes - i, len);
bufp->kind = (SINGLE_BYTE_CHAR_P (c)
- ? ascii_keystroke
- : multibyte_char_keystroke);
+ ? ASCII_KEYSTROKE_EVENT
+ : MULTIBYTE_CHAR_KEYSTROKE_EVENT);
bufp->code = c;
XSETFRAME (bufp->frame_or_window, f);
bufp->arg = Qnil;
goto OTHER;
#endif
- /* Here's a possible interpretation of the whole
- FocusIn-EnterNotify FocusOut-LeaveNotify mess. If
- you get a FocusIn event, you have to get a FocusOut
- event before you relinquish the focus. If you
- haven't received a FocusIn event, then a mere
- LeaveNotify is enough to free you. */
-
case EnterNotify:
{
+ int n;
+
+ n = x_detect_focus_change (dpyinfo, &event, bufp, numchars);
+ if (n > 0)
+ {
+ bufp += n, count += n, numchars -= n;
+ }
+
f = x_any_window_to_frame (dpyinfo, event.xcrossing.window);
#if 0
}
case FocusIn:
- f = x_any_window_to_frame (dpyinfo, event.xfocus.window);
- if (event.xfocus.detail != NotifyPointer)
- dpyinfo->x_focus_event_frame = f;
- if (f)
- {
- x_new_focus_frame (dpyinfo, f);
-
- /* Don't stop displaying the initial startup message
- for a switch-frame event we don't need. */
- if (GC_NILP (Vterminal_frame)
- && GC_CONSP (Vframe_list)
- && !GC_NILP (XCDR (Vframe_list)))
- {
- bufp->kind = FOCUS_IN_EVENT;
- XSETFRAME (bufp->frame_or_window, f);
- bufp->arg = Qnil;
- ++bufp, ++count, --numchars;
- }
- }
+ {
+ int n;
-#ifdef HAVE_X_I18N
- if (f && FRAME_XIC (f))
- XSetICFocus (FRAME_XIC (f));
-#endif
+ n = x_detect_focus_change (dpyinfo, &event, bufp, numchars);
+ if (n > 0)
+ {
+ bufp += n, count += n, numchars -= n;
+ }
+ }
goto OTHER;
case LeaveNotify:
+ {
+ int n;
+
+ n = x_detect_focus_change (dpyinfo, &event, bufp, numchars);
+ if (n > 0)
+ {
+ bufp += n, count += n, numchars -= n;
+ }
+ }
+
f = x_top_window_to_frame (dpyinfo, event.xcrossing.window);
if (f)
{
bufp += n, count += n, numchars -= n;
}
-#if 0
- if (event.xcrossing.focus)
- x_mouse_leave (dpyinfo);
- else
- {
- if (f == dpyinfo->x_focus_event_frame)
- dpyinfo->x_focus_event_frame = 0;
- if (f == dpyinfo->x_focus_frame)
- x_new_focus_frame (dpyinfo, 0);
- }
-#endif
}
goto OTHER;
case FocusOut:
- f = x_any_window_to_frame (dpyinfo, event.xfocus.window);
- if (event.xfocus.detail != NotifyPointer
- && f == dpyinfo->x_focus_event_frame)
- dpyinfo->x_focus_event_frame = 0;
- if (f && f == dpyinfo->x_focus_frame)
- x_new_focus_frame (dpyinfo, 0);
+ {
+ int n;
-#ifdef HAVE_X_I18N
- if (f && FRAME_XIC (f))
- XUnsetICFocus (FRAME_XIC (f));
-#endif
+ n = x_detect_focus_change (dpyinfo, &event, bufp, numchars);
+ if (n > 0)
+ {
+ bufp += n, count += n, numchars -= n;
+ }
+ }
goto OTHER;
struct input_event emacs_event;
int tool_bar_p = 0;
- emacs_event.kind = no_event;
+ emacs_event.kind = NO_EVENT;
bzero (&compose_status, sizeof (compose_status));
if (dpyinfo->grabbed
dpyinfo->grabbed &= ~(1 << event.xbutton.button);
}
- if (numchars >= 1 && emacs_event.kind != no_event)
+ if (numchars >= 1 && emacs_event.kind != NO_EVENT)
{
bcopy (&emacs_event, bufp, sizeof (struct input_event));
bufp++;
enum glyph_row_area area;
int x0, y0, x1, y1;
{
- if (area == TEXT_AREA
- && w->phys_cursor_on_p
- && y0 <= w->phys_cursor.y
- && y1 >= w->phys_cursor.y + w->phys_cursor_height
- && x0 <= w->phys_cursor.x
- && (x1 < 0 || x1 > w->phys_cursor.x))
- w->phys_cursor_on_p = 0;
+ if (area == TEXT_AREA && w->phys_cursor_on_p)
+ {
+ int cx0 = w->phys_cursor.x;
+ int cx1 = cx0 + w->phys_cursor_width;
+ int cy0 = w->phys_cursor.y;
+ int cy1 = cy0 + w->phys_cursor_height;
+
+ if (x0 <= cx0 && (x1 < 0 || x1 >= cx1))
+ {
+ /* The cursor image will be completely removed from the
+ screen if the output area intersects the cursor area in
+ y-direction. When we draw in [y0 y1[, and some part of
+ the cursor is at y < y0, that part must have been drawn
+ before. When scrolling, the cursor is erased before
+ actually scrolling, so we don't come here. When not
+ scrolling, the rows above the old cursor row must have
+ changed, and in this case these rows must have written
+ over the cursor image.
+
+ Likewise if part of the cursor is below y1, with the
+ exception of the cursor being in the first blank row at
+ the buffer and window end because update_text_area
+ doesn't draw that row. (Except when it does, but
+ that's handled in update_text_area.) */
+
+ if (((y0 >= cy0 && y0 < cy1) || (y1 > cy0 && y1 < cy1))
+ && w->current_matrix->rows[w->phys_cursor.vpos].displays_text_p)
+ w->phys_cursor_on_p = 0;
+ }
+ }
}
if (cursor_glyph->type == STRETCH_GLYPH
&& !x_stretch_cursor_p)
wd = min (CANON_X_UNIT (f), wd);
+ w->phys_cursor_width = wd;
/* The foreground of cursor_gc is typically the same as the normal
background color, which can cause the cursor box to be invisible. */
width = f->output_data.x->cursor_width;
width = min (cursor_glyph->pixel_width, width);
+ w->phys_cursor_width = width;
x_clip_to_row (w, row, gc, 0);
+
if (kind == BAR_CURSOR)
XFillRectangle (dpy, window, gc,
WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x),
if (w->phys_cursor.hpos < row->used[TEXT_AREA])
{
int on_p = w->phys_cursor_on_p;
+ int x1;
- x_draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
- w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
- hl, 0);
+ x1 = x_draw_glyphs (w, w->phys_cursor.x, row, TEXT_AREA,
+ w->phys_cursor.hpos, w->phys_cursor.hpos + 1,
+ hl, 0);
w->phys_cursor_on_p = on_p;
+ if (hl == DRAW_CURSOR)
+ w->phys_cursor_width = x1 - w->phys_cursor.x;
+
/* When we erase the cursor, and ROW is overlapped by other
rows, make sure that these overlapping parts of other rows
are redrawn. */
- if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
+ else if (hl == DRAW_NORMAL_TEXT && row->overlapped_p)
{
if (row > w->current_matrix->rows
&& MATRIX_ROW_OVERLAPS_SUCC_P (row - 1))
struct frame *f = XFRAME (w->frame);
int new_cursor_type;
int new_cursor_width;
+ int cursor_off_state = 0;
struct glyph_matrix *current_glyphs;
struct glyph_row *glyph_row;
struct glyph *glyph;
- int cursor_non_selected;
/* This is pointless on invisible frames, and dangerous on garbaged
windows and frames; in the latter case, the frame or window may
the cursor type given by the frame parameter. If explicitly
marked off, draw no cursor. In all other cases, we want a hollow
box cursor. */
- cursor_non_selected
- = !NILP (Fbuffer_local_value (Qcursor_in_non_selected_windows,
- w->buffer));
new_cursor_width = -1;
+ new_cursor_type = -2;
+
+ /* Echo area */
if (cursor_in_echo_area
&& FRAME_HAS_MINIBUF_P (f)
&& EQ (FRAME_MINIBUF_WINDOW (f), echo_area_window))
{
if (w == XWINDOW (echo_area_window))
new_cursor_type = FRAME_DESIRED_CURSOR (f);
- else if (cursor_non_selected)
- new_cursor_type = HOLLOW_BOX_CURSOR;
+ else if (NILP (Fbuffer_local_value (Qcursor_in_non_selected_windows,
+ w->buffer)))
+ new_cursor_type = NO_CURSOR;
else
+ cursor_off_state = 1;
+ }
+
+ /* Nonselected window or nonselected frame. */
+ else if (f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame
+ || w != XWINDOW (f->selected_window))
+ {
+ if ((MINI_WINDOW_P (w) && minibuf_level == 0)
+ || NILP (Fbuffer_local_value (Qcursor_in_non_selected_windows,
+ w->buffer))
+ || NILP (XBUFFER (w->buffer)->cursor_type))
new_cursor_type = NO_CURSOR;
+ else
+ cursor_off_state = 1;
}
- else
+
+ /* If new_cursor_type isn't decided yet, decide it now. */
+ if (new_cursor_type == -2)
{
- if (f != FRAME_X_DISPLAY_INFO (f)->x_highlight_frame
- || w != XWINDOW (f->selected_window))
+ struct buffer *b = XBUFFER (w->buffer);
+
+ if (EQ (b->cursor_type, Qt))
{
- if ((MINI_WINDOW_P (w) && minibuf_level == 0)
- || !cursor_non_selected
- || NILP (XBUFFER (w->buffer)->cursor_type))
- new_cursor_type = NO_CURSOR;
- else
- new_cursor_type = HOLLOW_BOX_CURSOR;
+ new_cursor_type = FRAME_DESIRED_CURSOR (f);
+ new_cursor_width = FRAME_CURSOR_WIDTH (f);
}
else
- {
- struct buffer *b = XBUFFER (w->buffer);
+ new_cursor_type = x_specified_cursor_type (b->cursor_type,
+ &new_cursor_width);
+ }
- if (EQ (b->cursor_type, Qt))
- new_cursor_type = FRAME_DESIRED_CURSOR (f);
- else
- new_cursor_type = x_specified_cursor_type (b->cursor_type,
- &new_cursor_width);
- if (w->cursor_off_p)
- {
- if (new_cursor_type == FILLED_BOX_CURSOR)
- new_cursor_type = HOLLOW_BOX_CURSOR;
- else if (new_cursor_type == BAR_CURSOR && new_cursor_width > 1)
- new_cursor_width = 1;
- else
- new_cursor_type = NO_CURSOR;
- }
- }
+ /* Dim out or hollow out the cursor,
+ if it has blinked off or for nonselected windows. */
+ if (w->cursor_off_p || cursor_off_state)
+ {
+ if (new_cursor_type == FILLED_BOX_CURSOR)
+ new_cursor_type = HOLLOW_BOX_CURSOR;
+ else if (new_cursor_type == BAR_CURSOR && new_cursor_width > 1)
+ new_cursor_width = 1;
+ else
+ new_cursor_type = NO_CURSOR;
}
+ /* Now new_cursor_type is correct. */
+
/* If cursor is currently being shown and we don't want it to be or
it is in the wrong place, or the cursor type is not what we want,
erase it. */
&& new_cursor_width != w->phys_cursor_width)))
x_erase_phys_cursor (w);
- /* If the cursor is now invisible and we want it to be visible,
- display it. */
- if (on && !w->phys_cursor_on_p)
+ /* Don't check phys_cursor_on_p here because that flag is only set
+ to zero in some cases where we know that the cursor has been
+ completely erased, to avoid the extra work of erasing the cursor
+ twice. In other words, phys_cursor_on_p can be 1 and the cursor
+ still not be visible, or it has only been partly erased. */
+ if (on)
{
w->phys_cursor_ascent = glyph_row->ascent;
w->phys_cursor_height = glyph_row->height;
w->phys_cursor.hpos = hpos;
w->phys_cursor.vpos = vpos;
w->phys_cursor_type = new_cursor_type;
- w->phys_cursor_width = new_cursor_width;
w->phys_cursor_on_p = 1;
switch (new_cursor_type)
break;
case HBAR_CURSOR:
- x_draw_bar_cursor (w, glyph_row, new_cursor_width, HBAR_CURSOR);
+ x_draw_bar_cursor (w, glyph_row, new_cursor_width, HBAR_CURSOR);
break;
case NO_CURSOR:
+ w->phys_cursor_width = 0;
break;
default:
XErrorEvent *error;
{
XGetErrorText (display, error->error_code,
- XSTRING (x_error_message_string)->data,
+ SDATA (x_error_message_string),
X_ERROR_MESSAGE_SIZE);
}
x_catch_errors (dpy)
Display *dpy;
{
- int count = specpdl_ptr - specpdl;
+ int count = SPECPDL_INDEX ();
/* Make sure any errors from previous requests have been dealt with. */
XSync (dpy, False);
record_unwind_protect (x_catch_errors_unwind, x_error_message_string);
x_error_message_string = make_uninit_string (X_ERROR_MESSAGE_SIZE);
- XSTRING (x_error_message_string)->data[0] = 0;
+ SSET (x_error_message_string, 0, 0);
return count;
}
/* Make sure to catch any errors incurred so far. */
XSync (dpy, False);
- if (XSTRING (x_error_message_string)->data[0])
- error (format, XSTRING (x_error_message_string)->data);
+ if (SREF (x_error_message_string, 0))
+ error (format, SDATA (x_error_message_string));
}
/* Nonzero if we had any X protocol errors
/* Make sure to catch any errors incurred so far. */
XSync (dpy, False);
- return XSTRING (x_error_message_string)->data[0] != 0;
+ return SREF (x_error_message_string, 0) != 0;
}
/* Forget about any errors we have had, since we did x_catch_errors on DPY. */
x_clear_errors (dpy)
Display *dpy;
{
- XSTRING (x_error_message_string)->data[0] = 0;
+ SSET (x_error_message_string, 0, 0);
}
/* Stop catching X protocol errors and let them make Emacs die.
to do. */
return fontset_name (fontset);
- result = x_new_font (f, (XSTRING (fontset_ascii (fontset))->data));
+ result = x_new_font (f, (SDATA (fontset_ascii (fontset))));
if (!STRINGP (result))
/* Can't load ASCII font. */
#ifdef HAVE_X_I18N
if (FRAME_XIC (f)
&& (FRAME_XIC_STYLE (f) & (XIMPreeditPosition | XIMStatusArea)))
- xic_set_xfontset (f, XSTRING (fontset_ascii (fontset))->data);
+ xic_set_xfontset (f, SDATA (fontset_ascii (fontset)));
#endif
return build_string (fontsetname);
XFontStruct *font;
unsigned long value;
- font = XLoadQueryFont (dpy, XSTRING (pattern)->data);
+ font = XLoadQueryFont (dpy, SDATA (pattern));
if (x_had_errors_p (dpy))
{
/* This error is perhaps due to insufficient memory on X
{
/* We try at least 10 fonts because XListFonts will return
auto-scaled fonts at the head. */
- names = XListFonts (dpy, XSTRING (pattern)->data, max (maxnames, 10),
+ names = XListFonts (dpy, SDATA (pattern), max (maxnames, 10),
&num_fonts);
if (x_had_errors_p (dpy))
{
BLOCK_INPUT;
count = x_catch_errors (dpy);
thisinfo = XLoadQueryFont (dpy,
- XSTRING (XCAR (tem))->data);
+ SDATA (XCAR (tem)));
if (x_had_errors_p (dpy))
{
/* This error is perhaps due to insufficient memory on X
for (tail = font_names; CONSP (tail); tail = XCDR (tail))
if (dpyinfo->font_table[i].name
&& (!strcmp (dpyinfo->font_table[i].name,
- XSTRING (XCAR (tail))->data)
+ SDATA (XCAR (tail)))
|| !strcmp (dpyinfo->font_table[i].full_name,
- XSTRING (XCAR (tail))->data)))
+ SDATA (XCAR (tail)))))
return (dpyinfo->font_table + i);
}
a bug of not finding a font even if the font surely exists and
is loadable by XLoadQueryFont. */
if (size > 0 && !NILP (font_names))
- fontname = (char *) XSTRING (XCAR (font_names))->data;
+ fontname = (char *) SDATA (XCAR (font_names));
BLOCK_INPUT;
count = x_catch_errors (FRAME_X_DISPLAY (f));
the screen number from the server number. */
static int
same_x_server (name1, name2)
- char *name1, *name2;
+ const char *name1, *name2;
{
int seen_colon = 0;
- unsigned char *system_name = XSTRING (Vsystem_name)->data;
+ const unsigned char *system_name = SDATA (Vsystem_name);
int system_name_length = strlen (system_name);
int length_until_period = 0;
argv[argc++] = "-xrm";
argv[argc++] = xrm_option;
}
- dpy = XtOpenDisplay (Xt_app_con, XSTRING (display_name)->data,
+ stop_polling ();
+ dpy = XtOpenDisplay (Xt_app_con, SDATA (display_name),
resource_name, EMACS_CLASS,
emacs_options, XtNumber (emacs_options),
&argc, argv);
+ start_polling ();
#ifdef HAVE_X11XTR6
/* I think this is to compensate for XtSetLanguageProc. */
#ifdef HAVE_X11R5
XSetLocaleModifiers ("");
#endif
- dpy = XOpenDisplay (XSTRING (display_name)->data);
+ dpy = XOpenDisplay (SDATA (display_name));
#endif /* not USE_X_TOOLKIT */
/* Detect failure. */
for (share = x_display_list, tail = x_display_name_list; share;
share = share->next, tail = XCDR (tail))
- if (same_x_server (XSTRING (XCAR (XCAR (tail)))->data,
- XSTRING (display_name)->data))
+ if (same_x_server (SDATA (XCAR (XCAR (tail))),
+ SDATA (display_name)))
break;
if (share)
dpyinfo->kboard = share->kboard;
#endif /* ! 0 */
dpyinfo->x_id_name
- = (char *) xmalloc (STRING_BYTES (XSTRING (Vinvocation_name))
- + STRING_BYTES (XSTRING (Vsystem_name))
+ = (char *) xmalloc (SBYTES (Vinvocation_name)
+ + SBYTES (Vsystem_name)
+ 2);
sprintf (dpyinfo->x_id_name, "%s@%s",
- XSTRING (Vinvocation_name)->data, XSTRING (Vsystem_name)->data);
+ SDATA (Vinvocation_name), SDATA (Vsystem_name));
/* Figure out which modifier bits mean what. */
x_find_modifier_meanings (dpyinfo);
build_string ("PrivateColormap"),
Qnil, Qnil);
if (STRINGP (value)
- && (!strcmp (XSTRING (value)->data, "true")
- || !strcmp (XSTRING (value)->data, "on")))
+ && (!strcmp (SDATA (value), "true")
+ || !strcmp (SDATA (value), "on")))
dpyinfo->cmap = XCopyColormapAndFree (dpyinfo->display, dpyinfo->cmap);
}
}
build_string ("Synchronous"),
Qnil, Qnil);
if (STRINGP (value)
- && (!strcmp (XSTRING (value)->data, "true")
- || !strcmp (XSTRING (value)->data, "on")))
+ && (!strcmp (SDATA (value), "true")
+ || !strcmp (SDATA (value), "on")))
XSynchronize (dpyinfo->display, True);
}
/* Disable Window Change signals; they are handled by X events. */
#ifdef SIGWINCH
signal (SIGWINCH, SIG_DFL);
-#endif /* ! defined (SIGWINCH) */
+#endif /* SIGWINCH */
signal (SIGPIPE, x_connection_signal);