/* X Communication module for terminals which understand the X protocol.
Copyright (C) 1989, 1993, 1994, 1995, 1996, 1997, 1998, 1999, 2000, 2001,
- 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
+ 2002, 2003, 2004, 2005, 2006, 2007 Free Software Foundation, Inc.
This file is part of GNU Emacs.
GNU Emacs is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
-the Free Software Foundation; either version 2, or (at your option)
+the Free Software Foundation; either version 3, or (at your option)
any later version.
GNU Emacs is distributed in the hope that it will be useful,
static Time last_mouse_movement_time;
+/* Time for last user interaction as returned in X events. */
+
+static Time last_user_time;
+
/* Incremented by XTread_socket whenever it really tries to read
events. */
static void x_sync_with_move P_ ((struct frame *, int, int, int));
static int handle_one_xevent P_ ((struct x_display_info *, XEvent *,
int *, struct input_event *));
-static SIGTYPE x_connection_closed P_ ((Display *, char *)) NO_RETURN;
+/* Don't declare this NO_RETURN because we want no
+ interference with debugging failing X calls. */
+static SIGTYPE x_connection_closed P_ ((Display *, char *));
/* Flush display of frame F, or of all frames if F is null. */
else
x_clip_to_row (w, row, -1, gc);
- if (p->bx >= 0 && !p->overlay_p)
+ if (!p->overlay_p)
{
+ int bx = p->bx, by = p->by, nx = p->nx, ny = p->ny;
+
/* In case the same realized face is used for fringes and
for something displayed in the text (e.g. face `region' on
mono-displays, the fill style may have been changed to
else
XSetForeground (display, face->gc, face->background);
- XFillRectangle (display, window, face->gc,
- p->bx, p->by, p->nx, p->ny);
+#ifdef USE_TOOLKIT_SCROLL_BARS
+ /* If the fringe is adjacent to the left (right) scroll bar of a
+ leftmost (rightmost, respectively) window, then extend its
+ background to the gap between the fringe and the bar. */
+ if ((WINDOW_LEFTMOST_P (w)
+ && WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
+ || (WINDOW_RIGHTMOST_P (w)
+ && WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w)))
+ {
+ int sb_width = WINDOW_CONFIG_SCROLL_BAR_WIDTH (w);
+
+ if (sb_width > 0)
+ {
+ int left = WINDOW_SCROLL_BAR_AREA_X (w);
+ int width = (WINDOW_CONFIG_SCROLL_BAR_COLS (w)
+ * FRAME_COLUMN_WIDTH (f));
+
+ if (bx < 0)
+ {
+ /* Bitmap fills the fringe. */
+ if (left + width == p->x)
+ bx = left + sb_width;
+ else if (p->x + p->wd == left)
+ bx = left;
+ if (bx >= 0)
+ {
+ int header_line_height = WINDOW_HEADER_LINE_HEIGHT (w);
+
+ nx = width - sb_width;
+ by = WINDOW_TO_FRAME_PIXEL_Y (w, max (header_line_height,
+ row->y));
+ ny = row->visible_height;
+ }
+ }
+ else
+ {
+ if (left + width == bx)
+ {
+ bx = left + sb_width;
+ nx += width - sb_width;
+ }
+ else if (bx + nx == left)
+ nx += width - sb_width;
+ }
+ }
+ }
+#endif
+ if (bx >= 0 && nx > 0)
+ XFillRectangle (display, window, face->gc, bx, by, nx, ny);
if (!face->stipple)
XSetForeground (display, face->gc, face->foreground);
{
/* Fill background with a stipple pattern. */
XSetFillStyle (s->display, s->gc, FillOpaqueStippled);
+ XSetTSOrigin (s->display, s->gc, - s->x, - s->y);
XFillRectangle (s->display, pixmap, s->gc,
0, 0, s->background_width, s->height);
XSetFillStyle (s->display, s->gc, FillSolid);
+ XSetTSOrigin (s->display, s->gc, 0, 0);
}
else
{
XSETINT (bar->start, 0);
XSETINT (bar->end, 0);
bar->dragging = Qnil;
+#ifdef USE_TOOLKIT_SCROLL_BARS
+ bar->fringe_extended_p = Qnil;
+#endif
/* Add bar to its frame's list of scroll bars. */
bar->next = FRAME_SCROLL_BARS (f);
struct scroll_bar *bar;
int top, height, left, sb_left, width, sb_width;
int window_y, window_height;
+#ifdef USE_TOOLKIT_SCROLL_BARS
+ int fringe_extended_p;
+#endif
/* Get window dimensions. */
window_box (w, -1, 0, &window_y, 0, &window_height);
/* Compute the left edge of the scroll bar. */
#ifdef USE_TOOLKIT_SCROLL_BARS
if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
- sb_left = (left +
- (WINDOW_RIGHTMOST_P (w)
- ? width - sb_width - (width - sb_width) / 2
- : 0));
+ sb_left = left + (WINDOW_RIGHTMOST_P (w) ? width - sb_width : 0);
else
- sb_left = (left +
- (WINDOW_LEFTMOST_P (w)
- ? (width - sb_width) / 2
- : width - sb_width));
+ sb_left = left + (WINDOW_LEFTMOST_P (w) ? 0 : width - sb_width);
#else
if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_RIGHT (w))
sb_left = left + width - sb_width;
sb_left = left;
#endif
+#ifdef USE_TOOLKIT_SCROLL_BARS
+ if (WINDOW_HAS_VERTICAL_SCROLL_BAR_ON_LEFT (w))
+ fringe_extended_p = (WINDOW_LEFTMOST_P (w)
+ && WINDOW_LEFT_FRINGE_WIDTH (w)
+ && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
+ || WINDOW_LEFT_MARGIN_COLS (w) == 0));
+ else
+ fringe_extended_p = (WINDOW_RIGHTMOST_P (w)
+ && WINDOW_RIGHT_FRINGE_WIDTH (w)
+ && (WINDOW_HAS_FRINGES_OUTSIDE_MARGINS (w)
+ || WINDOW_RIGHT_MARGIN_COLS (w) == 0));
+#endif
+
/* Does the scroll bar exist yet? */
if (NILP (w->vertical_scroll_bar))
{
if (width > 0 && height > 0)
{
BLOCK_INPUT;
- x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
- left, top, width, height, False);
+#ifdef USE_TOOLKIT_SCROLL_BARS
+ if (fringe_extended_p)
+ x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
+ sb_left, top, sb_width, height, False);
+ else
+#endif
+ x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
+ left, top, width, height, False);
UNBLOCK_INPUT;
}
#ifdef USE_TOOLKIT_SCROLL_BARS
/* Move/size the scroll bar widget. */
- if (mask)
+ if (mask || !NILP (bar->fringe_extended_p) != fringe_extended_p)
{
/* Since toolkit scroll bars are smaller than the space reserved
for them on the frame, we have to clear "under" them. */
if (width > 0 && height > 0)
- x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
- left, top, width, height, False);
+ {
+ if (fringe_extended_p)
+ x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
+ sb_left, top, sb_width, height, False);
+ else
+ x_clear_area (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
+ left, top, width, height, False);
+ }
#ifdef USE_GTK
xg_update_scrollbar_pos (f,
SCROLL_BAR_X_WINDOW (bar),
}
#ifdef USE_TOOLKIT_SCROLL_BARS
+ bar->fringe_extended_p = fringe_extended_p ? Qt : Qnil;
+
x_set_toolkit_scroll_bar_thumb (bar, portion, position, whole);
#else /* not USE_TOOLKIT_SCROLL_BARS */
/* Set the scroll bar's current state, unless we're currently being
x_scroll_bar_set_handle (bar, XINT (bar->start), XINT (bar->end), 1);
+ /* Switch to scroll bar foreground color. */
+ if (f->output_data.x->scroll_bar_foreground_pixel != -1)
+ XSetForeground (FRAME_X_DISPLAY (f), gc,
+ f->output_data.x->scroll_bar_foreground_pixel);
+
/* Draw a one-pixel border just inside the edges of the scroll bar. */
XDrawRectangle (FRAME_X_DISPLAY (f), w, gc,
XINT (bar->width) - 1 - width_trim - width_trim,
XINT (bar->height) - 1);
- UNBLOCK_INPUT;
+ /* Restore the foreground color of the GC if we changed it above. */
+ if (f->output_data.x->scroll_bar_foreground_pixel != -1)
+ XSetForeground (FRAME_X_DISPLAY (f), gc,
+ FRAME_FOREGROUND_PIXEL (f));
+
+ UNBLOCK_INPUT;
}
#endif /* not USE_TOOLKIT_SCROLL_BARS */
break;
case SelectionNotify:
+ last_user_time = event.xselection.time;
#ifdef USE_X_TOOLKIT
if (! x_window_to_frame (dpyinfo, event.xselection.requestor))
goto OTHER;
break;
case SelectionClear: /* Someone has grabbed ownership. */
+ last_user_time = event.xselectionclear.time;
#ifdef USE_X_TOOLKIT
if (! x_window_to_frame (dpyinfo, event.xselectionclear.window))
goto OTHER;
break;
case SelectionRequest: /* Someone wants our selection. */
+ last_user_time = event.xselectionrequest.time;
#ifdef USE_X_TOOLKIT
if (!x_window_to_frame (dpyinfo, event.xselectionrequest.owner))
goto OTHER;
break;
case PropertyNotify:
+ last_user_time = event.xproperty.time;
#if 0 /* This is plain wrong. In the case that we are waiting for a
PropertyNotify used as an ACK in incremental selection
transfer, the property will be on the receiver's window. */
/* Perhaps reparented due to a WM restart. Reset this. */
FRAME_X_DISPLAY_INFO (f)->wm_type = X_WMTYPE_UNKNOWN;
+ FRAME_X_DISPLAY_INFO (f)->net_supported_window = 0;
}
goto OTHER;
case KeyPress:
+ last_user_time = event.xkey.time;
ignore_next_mouse_click_timeout = 0;
#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
#endif
case KeyRelease:
+ last_user_time = event.xkey.time;
#ifdef HAVE_X_I18N
/* Don't dispatch this event since XtDispatchEvent calls
XFilterEvent, and two calls in a row may freeze the
#endif
case EnterNotify:
+ last_user_time = event.xcrossing.time;
x_detect_focus_change (dpyinfo, &event, &inev.ie);
f = x_any_window_to_frame (dpyinfo, event.xcrossing.window);
goto OTHER;
case LeaveNotify:
+ last_user_time = event.xcrossing.time;
x_detect_focus_change (dpyinfo, &event, &inev.ie);
f = x_top_window_to_frame (dpyinfo, event.xcrossing.window);
case MotionNotify:
{
+ last_user_time = event.xmotion.time;
previous_help_echo_string = help_echo_string;
help_echo_string = Qnil;
/* Window will be selected only when it is not selected now and
last mouse movement event was not in it. Minibuffer window
- will be selected iff it is active. */
+ will be selected only when it is active. */
if (WINDOWP (window)
&& !EQ (window, last_window)
&& !EQ (window, selected_window))
bzero (&compose_status, sizeof (compose_status));
last_mouse_glyph_frame = 0;
+ last_user_time = event.xbutton.time;
if (dpyinfo->grabbed
&& last_mouse_frame
int y = event.xbutton.y;
window = window_from_coordinates (f, x, y, 0, 0, 0, 1);
- if (EQ (window, f->tool_bar_window))
+ tool_bar_p = EQ (window, f->tool_bar_window);
+
+ if (tool_bar_p && event.xbutton.button < 4)
{
- if (event.xbutton.type == ButtonPress)
- handle_tool_bar_click (f, x, y, 1, 0);
- else
- handle_tool_bar_click (f, x, y, 0,
- x_x_to_emacs_modifiers (dpyinfo,
+ if (event.xbutton.type == ButtonPress)
+ handle_tool_bar_click (f, x, y, 1, 0);
+ else
+ handle_tool_bar_click (f, x, y, 0,
+ x_x_to_emacs_modifiers (dpyinfo,
event.xbutton.state));
- tool_bar_p = 1;
}
}
if (!tool_bar_p)
- if (!dpyinfo->x_focus_frame
- || f == dpyinfo->x_focus_frame)
- {
#if defined (USE_X_TOOLKIT) || defined (USE_GTK)
- if (! popup_activated ())
+ if (! popup_activated ())
#endif
- {
- if (ignore_next_mouse_click_timeout)
- {
- if (event.type == ButtonPress
- && (int)(event.xbutton.time - ignore_next_mouse_click_timeout) > 0)
- {
- ignore_next_mouse_click_timeout = 0;
- construct_mouse_click (&inev.ie, &event.xbutton, f);
- }
- if (event.type == ButtonRelease)
- ignore_next_mouse_click_timeout = 0;
- }
- else
- construct_mouse_click (&inev.ie, &event.xbutton, f);
- }
+ {
+ if (ignore_next_mouse_click_timeout)
+ {
+ if (event.type == ButtonPress
+ && (int)(event.xbutton.time - ignore_next_mouse_click_timeout) > 0)
+ {
+ ignore_next_mouse_click_timeout = 0;
+ construct_mouse_click (&inev.ie, &event.xbutton, f);
+ }
+ if (event.type == ButtonRelease)
+ ignore_next_mouse_click_timeout = 0;
+ }
+ else
+ construct_mouse_click (&inev.ie, &event.xbutton, f);
}
}
else
UNBLOCK_INPUT;
}
+/* Return non-zero if _NET_SUPPORTING_WM_CHECK window exists and _NET_SUPPORTED
+ on the root window for frame F contains ATOMNAME.
+ This is how a WM check shall be done according to the Window Manager
+ Specification/Extended Window Manager Hints at
+ http://freedesktop.org/wiki/Standards_2fwm_2dspec. */
+
+static int
+wm_supports (f, atomname)
+ struct frame *f;
+ const char *atomname;
+{
+ Atom actual_type;
+ unsigned long actual_size, bytes_remaining;
+ int i, rc, actual_format;
+ Atom prop_atom;
+ Window wmcheck_window;
+ struct x_display_info *dpyinfo = FRAME_X_DISPLAY_INFO (f);
+ Window target_window = dpyinfo->root_window;
+ long max_len = 65536;
+ Display *dpy = FRAME_X_DISPLAY (f);
+ unsigned char *tmp_data = NULL;
+ Atom target_type = XA_WINDOW;
+ Atom want_atom;
+
+ BLOCK_INPUT;
+
+ prop_atom = XInternAtom (dpy, "_NET_SUPPORTING_WM_CHECK", False);
+
+ x_catch_errors (dpy);
+ rc = XGetWindowProperty (dpy, target_window,
+ prop_atom, 0, max_len, False, target_type,
+ &actual_type, &actual_format, &actual_size,
+ &bytes_remaining, &tmp_data);
+
+ if (rc != Success || actual_type != XA_WINDOW || x_had_errors_p (dpy))
+ {
+ if (tmp_data) XFree (tmp_data);
+ x_uncatch_errors ();
+ UNBLOCK_INPUT;
+ return 0;
+ }
+
+ wmcheck_window = *(Window *) tmp_data;
+ XFree (tmp_data);
+
+ /* Check if window exists. */
+ XSelectInput (dpy, wmcheck_window, StructureNotifyMask);
+ x_sync (f);
+ if (x_had_errors_p (dpy))
+ {
+ x_uncatch_errors ();
+ UNBLOCK_INPUT;
+ return 0;
+ }
+
+ if (dpyinfo->net_supported_window != wmcheck_window)
+ {
+ /* Window changed, reload atoms */
+ if (dpyinfo->net_supported_atoms != NULL)
+ XFree (dpyinfo->net_supported_atoms);
+ dpyinfo->net_supported_atoms = NULL;
+ dpyinfo->nr_net_supported_atoms = 0;
+ dpyinfo->net_supported_window = 0;
+
+ target_type = XA_ATOM;
+ prop_atom = XInternAtom (dpy, "_NET_SUPPORTED", False);
+ tmp_data = NULL;
+ rc = XGetWindowProperty (dpy, target_window,
+ prop_atom, 0, max_len, False, target_type,
+ &actual_type, &actual_format, &actual_size,
+ &bytes_remaining, &tmp_data);
+
+ if (rc != Success || actual_type != XA_ATOM || x_had_errors_p (dpy))
+ {
+ if (tmp_data) XFree (tmp_data);
+ x_uncatch_errors ();
+ UNBLOCK_INPUT;
+ return 0;
+ }
+
+ dpyinfo->net_supported_atoms = (Atom *)tmp_data;
+ dpyinfo->nr_net_supported_atoms = actual_size;
+ dpyinfo->net_supported_window = wmcheck_window;
+ }
+
+ rc = 0;
+ want_atom = XInternAtom (dpy, atomname, False);
+
+ for (i = 0; rc == 0 && i < dpyinfo->nr_net_supported_atoms; ++i)
+ rc = dpyinfo->net_supported_atoms[i] == want_atom;
+
+ x_uncatch_errors ();
+ UNBLOCK_INPUT;
+
+ return rc;
+}
+
+/* Do fullscreen as specified in extended window manager hints */
+
+static int
+do_ewmh_fullscreen (f)
+ struct frame *f;
+{
+ int have_net_atom = wm_supports (f, "_NET_WM_STATE");
+
+ /* Some window managers don't say they support _NET_WM_STATE, but they do say
+ they support _NET_WM_STATE_FULLSCREEN. Try that also. */
+ if (!have_net_atom)
+ have_net_atom = wm_supports (f, "_NET_WM_STATE_FULLSCREEN");
+
+ if (have_net_atom)
+ {
+ Lisp_Object frame;
+ const char *atom = "_NET_WM_STATE";
+ const char *fs = "_NET_WM_STATE_FULLSCREEN";
+ const char *fw = "_NET_WM_STATE_MAXIMIZED_HORZ";
+ const char *fh = "_NET_WM_STATE_MAXIMIZED_VERT";
+ const char *what = NULL;
+
+ XSETFRAME (frame, f);
+
+ /* If there are _NET_ atoms we assume we have extended window manager
+ hints. */
+ switch (f->want_fullscreen)
+ {
+ case FULLSCREEN_BOTH:
+ what = fs;
+ break;
+ case FULLSCREEN_WIDTH:
+ what = fw;
+ break;
+ case FULLSCREEN_HEIGHT:
+ what = fh;
+ break;
+ }
+
+ if (what != NULL && !wm_supports (f, what)) return 0;
+
+
+ Fx_send_client_event (frame, make_number (0), frame,
+ make_unibyte_string (atom, strlen (atom)),
+ make_number (32),
+ Fcons (make_number (0), /* Remove */
+ Fcons
+ (make_unibyte_string (fs,
+ strlen (fs)),
+ Qnil)));
+ Fx_send_client_event (frame, make_number (0), frame,
+ make_unibyte_string (atom, strlen (atom)),
+ make_number (32),
+ Fcons (make_number (0), /* Remove */
+ Fcons
+ (make_unibyte_string (fh,
+ strlen (fh)),
+ Qnil)));
+ Fx_send_client_event (frame, make_number (0), frame,
+ make_unibyte_string (atom, strlen (atom)),
+ make_number (32),
+ Fcons (make_number (0), /* Remove */
+ Fcons
+ (make_unibyte_string (fw,
+ strlen (fw)),
+ Qnil)));
+ f->want_fullscreen = FULLSCREEN_NONE;
+ if (what != NULL)
+ Fx_send_client_event (frame, make_number (0), frame,
+ make_unibyte_string (atom, strlen (atom)),
+ make_number (32),
+ Fcons (make_number (1), /* Add */
+ Fcons
+ (make_unibyte_string (what,
+ strlen (what)),
+ Qnil)));
+ }
+
+ return have_net_atom;
+}
+
+static void
+XTfullscreen_hook (f)
+ FRAME_PTR f;
+{
+ if (f->async_visible)
+ {
+ BLOCK_INPUT;
+ do_ewmh_fullscreen (f);
+ x_sync (f);
+ UNBLOCK_INPUT;
+ }
+}
+
+
/* Check if we need to resize the frame due to a fullscreen request.
If so needed, resize the frame. */
static void
{
int width, height, ign;
+ if (do_ewmh_fullscreen (f))
+ return;
+
x_real_positions (f, &f->left_pos, &f->top_pos);
x_fullscreen_adjust (f, &width, &height, &ign, &ign);
x_raise_frame (f)
struct frame *f;
{
+ BLOCK_INPUT;
if (f->async_visible)
- {
- BLOCK_INPUT;
- XRaiseWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f));
- XFlush (FRAME_X_DISPLAY (f));
- UNBLOCK_INPUT;
- }
+ XRaiseWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f));
+
+ XFlush (FRAME_X_DISPLAY (f));
+ UNBLOCK_INPUT;
}
/* Lower frame F. */
}
}
+/* Activate frame with Extended Window Manager Hints */
+
+void
+x_ewmh_activate_frame (f)
+ FRAME_PTR f;
+{
+ /* See Window Manager Specification/Extended Window Manager Hints at
+ http://freedesktop.org/wiki/Standards_2fwm_2dspec */
+
+ const char *atom = "_NET_ACTIVE_WINDOW";
+ if (f->async_visible && wm_supports (f, atom))
+ {
+ Lisp_Object frame;
+ XSETFRAME (frame, f);
+ Fx_send_client_event (frame, make_number (0), frame,
+ make_unibyte_string (atom, strlen (atom)),
+ make_number (32),
+ Fcons (make_number (1),
+ Fcons (make_number (last_user_time),
+ Qnil)));
+ }
+}
+
static void
XTframe_raise_lower (f, raise_flag)
FRAME_PTR f;
for (i = 0; i < dpyinfo->n_fonts; i++)
if (dpyinfo->font_table[i].name
- && (!strcasecmp (dpyinfo->font_table[i].name, fontname)
- || !strcasecmp (dpyinfo->font_table[i].full_name, fontname)))
+ && (!xstricmp (dpyinfo->font_table[i].name, fontname)
+ || !xstricmp (dpyinfo->font_table[i].full_name, fontname)))
return (dpyinfo->font_table + i);
return NULL;
}
than zero, we are probably on GTK 2.0, which can only handle
one display. GTK 2.2 or later can handle more than one. */
if (xg_display_open (SDATA (display_name), &dpy) < 0)
- error ("Sorry, this version of GTK can only handle one display");
-#else
- /* XXX Unfortunately, multiple display support is severely broken
- in recent GTK versions, so HAVE_GTK_MULTIDISPLAY is
- unconditionally disabled in configure.in. */
- error ("Sorry, multiple display support is broken in current GTK versions");
#endif
+ error ("Sorry, this version of GTK can only handle one display");
}
else
{
UNBLOCK_INPUT;
terminal->kboard->Vsystem_key_alist
= call1 (Qvendor_specific_keysyms,
- build_string (vendor ? vendor : ""));
+ vendor ? build_string (vendor) : empty_unibyte_string);
BLOCK_INPUT;
}
dpyinfo->x_dnd_atoms = xmalloc (sizeof (*dpyinfo->x_dnd_atoms)
* dpyinfo->x_dnd_atoms_size);
+ dpyinfo->net_supported_atoms = NULL;
+ dpyinfo->nr_net_supported_atoms = 0;
+ dpyinfo->net_supported_window = 0;
+
connection = ConnectionNumber (dpyinfo->display);
dpyinfo->connection = connection;
terminal->mouse_position_hook = XTmouse_position;
terminal->frame_rehighlight_hook = XTframe_rehighlight;
terminal->frame_raise_lower_hook = XTframe_raise_lower;
+ terminal->fullscreen_hook = XTfullscreen_hook;
terminal->set_vertical_scroll_bar_hook = XTset_vertical_scroll_bar;
terminal->condemn_scroll_bars_hook = XTcondemn_scroll_bars;
terminal->redeem_scroll_bar_hook = XTredeem_scroll_bar;
DEFVAR_BOOL ("x-use-underline-position-properties",
&x_use_underline_position_properties,
doc: /* *Non-nil means make use of UNDERLINE_POSITION font properties.
-nil means ignore them. If you encounter fonts with bogus
+A value of nil means ignore them. If you encounter fonts with bogus
UNDERLINE_POSITION font properties, for example 7x13 on XFree prior
to 4.1, set this to nil. */);
x_use_underline_position_properties = 1;
DEFVAR_BOOL ("x-underline-at-descent-line",
&x_underline_at_descent_line,
doc: /* *Non-nil means to draw the underline at the same place as the descent line.
-nil means to draw the underline according to the value of the variable
-`x-use-underline-position-properties', which is usually at the baseline
-level. The default value is nil. */);
+A value of nil means to draw the underline according to the value of the
+variable `x-use-underline-position-properties', which is usually at the
+baseline level. The default value is nil. */);
x_underline_at_descent_line = 0;
DEFVAR_BOOL ("x-mouse-click-focus-ignore-position",