int x_use_underline_position_properties;
+/* Non-zero means to draw the underline at the same place as the descent line. */
+
+int x_underline_at_descent_line;
+
/* This is a chain of structures for all the X displays currently in
use. */
static void x_set_window_size_1 P_ ((struct frame *, int, int, int));
static const XColor *x_color_cells P_ ((Display *, int *));
static void x_update_window_end P_ ((struct window *, int, int));
-void x_delete_display P_ ((struct x_display_info *));
static int x_io_error_quitter P_ ((Display *));
-void x_catch_errors P_ ((Display *));
-void x_uncatch_errors P_ ((void));
-void x_lower_frame P_ ((struct frame *));
-void x_scroll_bar_clear P_ ((struct frame *));
-int x_had_errors_p P_ ((Display *));
-void x_wm_set_size_hint P_ ((struct frame *, long, int));
-void x_raise_frame P_ ((struct frame *));
-void x_set_window_size P_ ((struct frame *, int, int, int));
-void x_wm_set_window_state P_ ((struct frame *, int));
-void x_wm_set_icon_pixmap P_ ((struct frame *, int));
-void x_initialize P_ ((void));
static void x_font_min_bounds P_ ((XFontStruct *, int *, int *));
static int x_compute_min_glyph_bounds P_ ((struct frame *));
static void x_update_end P_ ((struct frame *));
Lisp_Object *, Lisp_Object *,
unsigned long *));
static void x_check_fullscreen P_ ((struct frame *));
-static void x_check_expected_move P_ ((struct frame *));
+static void x_check_expected_move P_ ((struct frame *, int, int));
+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;
/* Flush display of frame F, or of all frames if F is null. */
{
/* If `x-stretch-block-cursor' is nil, don't draw a block cursor
as wide as the stretch glyph. */
- int width = min (FRAME_COLUMN_WIDTH (s->f), s->background_width);
+ int width, background_width = s->background_width;
+ int x = s->x, left_x = window_box_left_offset (s->w, TEXT_AREA);
+
+ if (x < left_x)
+ {
+ background_width -= left_x - x;
+ x = left_x;
+ }
+ width = min (FRAME_COLUMN_WIDTH (s->f), background_width);
/* Draw cursor. */
- x_draw_glyph_string_bg_rect (s, s->x, s->y, width, s->height);
+ x_draw_glyph_string_bg_rect (s, x, s->y, width, s->height);
/* Clear rest using the GC of the original non-cursor face. */
- if (width < s->background_width)
+ if (width < background_width)
{
- int x = s->x + width, y = s->y;
- int w = s->background_width - width, h = s->height;
+ int y = s->y;
+ int w = background_width - width, h = s->height;
XRectangle r;
GC gc;
+ x += width;
if (s->row->mouse_face_p
&& cursor_in_mouse_face_p (s->w))
{
}
}
else if (!s->background_filled_p)
- x_draw_glyph_string_bg_rect (s, s->x, s->y, s->background_width,
- s->height);
+ {
+ int background_width = s->background_width;
+ int x = s->x, left_x = window_box_left_offset (s->w, TEXT_AREA);
+
+ /* Don't draw into left margin, fringe or scrollbar area
+ except for header line and mode line. */
+ if (x < left_x && !s->row->mode_line_p)
+ {
+ background_width -= left_x - x;
+ x = left_x;
+ }
+ if (background_width > 0)
+ x_draw_glyph_string_bg_rect (s, x, s->y, background_width, s->height);
+ }
s->background_filled_p = 1;
}
if (!XGetFontProperty (s->font, XA_UNDERLINE_THICKNESS, &h))
h = 1;
- /* Get the underline position. This is the recommended
- vertical offset in pixels from the baseline to the top of
- the underline. This is a signed value according to the
- specs, and its default is
-
- ROUND ((maximum descent) / 2), with
- ROUND(x) = floor (x + 0.5) */
-
- if (x_use_underline_position_properties
- && XGetFontProperty (s->font, XA_UNDERLINE_POSITION, &tem))
- y = s->ybase + (long) tem;
- else if (s->face->font)
- y = s->ybase + (s->face->font->max_bounds.descent + 1) / 2;
- else
- y = s->y + s->height - h;
+ y = s->y + s->height - h;
+ if (!x_underline_at_descent_line)
+ {
+ /* Get the underline position. This is the recommended
+ vertical offset in pixels from the baseline to the top of
+ the underline. This is a signed value according to the
+ specs, and its default is
+
+ ROUND ((maximum descent) / 2), with
+ ROUND(x) = floor (x + 0.5) */
+
+ if (x_use_underline_position_properties
+ && XGetFontProperty (s->font, XA_UNDERLINE_POSITION, &tem))
+ y = s->ybase + (long) tem;
+ else if (s->face->font)
+ y = s->ybase + (s->face->font->max_bounds.descent + 1) / 2;
+ }
if (s->face->underline_defaulted_p)
XFillRectangle (s->display, s->window, s->gc,
- s->x, y, s->width, h);
+ s->x, y, s->background_width, h);
else
{
XGCValues xgcv;
XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
XSetForeground (s->display, s->gc, s->face->underline_color);
XFillRectangle (s->display, s->window, s->gc,
- s->x, y, s->width, h);
+ s->x, y, s->background_width, h);
XSetForeground (s->display, s->gc, xgcv.foreground);
}
}
if (s->face->overline_color_defaulted_p)
XFillRectangle (s->display, s->window, s->gc, s->x, s->y + dy,
- s->width, h);
+ s->background_width, h);
else
{
XGCValues xgcv;
XGetGCValues (s->display, s->gc, GCForeground, &xgcv);
XSetForeground (s->display, s->gc, s->face->overline_color);
XFillRectangle (s->display, s->window, s->gc, s->x, s->y + dy,
- s->width, h);
+ s->background_width, h);
XSetForeground (s->display, s->gc, xgcv.foreground);
}
}
/* Make Xt timeouts work while the scroll bar is active. */
toolkit_scroll_bar_interaction = 1;
+#ifdef USE_X_TOOLKIT
+ x_activate_timeout_atimer ();
+#endif
/* Setting the event mask to zero means that the message will
be sent to the client that created the window, and if that
== dpyinfo->Xatom_editres)
{
f = x_any_window_to_frame (dpyinfo, event.xclient.window);
- _XEditResCheckMessages (f->output_data.x->widget, NULL,
- &event, NULL);
+ if (f)
+ _XEditResCheckMessages (f->output_data.x->widget, NULL,
+ &event, NULL);
goto done;
}
#endif /* HACK_EDITRES */
images, only, which should have 1 page. */
Pixmap pixmap = (Pixmap) event.xclient.data.l[1];
f = x_window_to_frame (dpyinfo, event.xclient.window);
+ if (!f)
+ goto OTHER;
x_kill_gs_process (pixmap, f);
expose_frame (f, 0, 0, 0, 0);
goto done;
#endif /* USE_TOOLKIT_SCROLL_BARS */
f = x_any_window_to_frame (dpyinfo, event.xclient.window);
-
if (!f)
goto OTHER;
-
if (x_handle_dnd_message (f, &event.xclient, dpyinfo, &inev.ie))
*finish = X_EVENT_DROP;
}
f = x_any_window_to_frame (dpyinfo, event.xkey.window);
- if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight))
+ /* If mouse-highlight is an integer, input clears out
+ mouse highlighting. */
+ if (!dpyinfo->mouse_face_hidden && INTEGERP (Vmouse_highlight)
+ && (f == 0
+ || !EQ (f->tool_bar_window, dpyinfo->mouse_face_window)))
{
clear_mouse_face (dpyinfo);
dpyinfo->mouse_face_hidden = 1;
{
/* Generate SELECT_WINDOW_EVENTs when needed. */
- if (mouse_autoselect_window)
+ if (!NILP (Vmouse_autoselect_window))
{
Lisp_Object window;
&& GTK_WIDGET_MAPPED (FRAME_GTK_OUTER_WIDGET (f)))
#endif
{
- /* What we have now is the position of Emacs's own window.
- Convert that to the position of the window manager window. */
x_real_positions (f, &f->left_pos, &f->top_pos);
- x_check_expected_move (f);
if (f->want_fullscreen & FULLSCREEN_WAIT)
f->want_fullscreen &= ~(FULLSCREEN_WAIT|FULLSCREEN_BOTH);
}
return;
/* Compute frame-relative coordinates for phys cursor. */
- x = WINDOW_TEXT_TO_FRAME_PIXEL_X (w, w->phys_cursor.x);
- y = get_phys_cursor_geometry (w, row, cursor_glyph, &h);
+ get_phys_cursor_geometry (w, row, cursor_glyph, &x, &y, &h);
wd = w->phys_cursor_width;
/* The foreground of cursor_gc is typically the same as the normal
/* Set clipping, draw the rectangle, and reset clipping again. */
x_clip_to_row (w, row, TEXT_AREA, gc);
- XDrawRectangle (dpy, FRAME_X_WINDOW (f), gc, x, y, wd, h);
+ XDrawRectangle (dpy, FRAME_X_WINDOW (f), gc, x, y, wd, h - 1);
XSetClipMask (dpy, gc, None);
}
static struct x_error_message_stack *x_error_message;
/* An X error handler which stores the error message in
- x_error_message_string. This is called from x_error_handler if
+ *x_error_message. This is called from x_error_handler if
x_catch_errors is in effect. */
static void
After calling this function, X protocol errors no longer cause
Emacs to exit; instead, they are recorded in the string
- stored in x_error_message_string.
+ stored in *x_error_message.
Calling x_check_errors signals an Emacs error if an X error has
occurred since the last call to x_catch_errors or x_check_errors.
{
struct x_error_message_stack *tmp;
+ BLOCK_INPUT;
+
/* The display may have been closed before this function is called.
Check if it is still open before calling XSync. */
if (x_display_info_for_display (x_error_message->dpy) != 0)
- {
- BLOCK_INPUT;
- XSync (x_error_message->dpy, False);
- UNBLOCK_INPUT;
- }
+ XSync (x_error_message->dpy, False);
tmp = x_error_message;
x_error_message = x_error_message->prev;
xfree (tmp);
+ UNBLOCK_INPUT;
}
/* If any X protocol errors have arrived since the last call to
x_error_message->string[0] = 0;
}
+/* Close off all unclosed x_catch_errors calls. */
+
+void
+x_fully_uncatch_errors ()
+{
+ while (x_error_message)
+ x_uncatch_errors ();
+}
+
+/* Nonzero if x_catch_errors has been done and not yet canceled. */
+
+int
+x_catching_errors ()
+{
+ return x_error_message != 0;
+}
+
#if 0
static unsigned int x_wire_count;
x_trace_wire ()
/* 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);
+static void x_error_quitter P_ ((Display *, XErrorEvent *));
/* This is the first-level handler for X protocol errors.
It calls x_error_quitter or x_error_catcher. */
{
char buf[256], buf1[356];
+ /* Ignore BadName errors. They can happen because of fonts
+ or colors that are not defined. */
+
+ if (error->error_code == BadName)
+ return;
+
/* Note that there is no real way portable across R3/R4 to get the
original error handler. */
{
int modified_top, modified_left;
- if (change_gravity > 0)
+ if (change_gravity != 0)
{
+ FRAME_X_OUTPUT (f)->left_before_move = f->left_pos;
+ FRAME_X_OUTPUT (f)->top_before_move = f->top_pos;
+
f->top_pos = yoff;
f->left_pos = xoff;
f->size_hint_flags &= ~ (XNegative | YNegative);
modified_left = f->left_pos;
modified_top = f->top_pos;
- if (FRAME_X_DISPLAY_INFO (f)->wm_type == X_WMTYPE_A)
+ if (change_gravity != 0 && FRAME_X_DISPLAY_INFO (f)->wm_type == X_WMTYPE_A)
{
/* Some WMs (twm, wmaker at least) has an offset that is smaller
than the WM decorations. So we use the calculated offset instead
XMoveWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
modified_left, modified_top);
- if (FRAME_VISIBLE_P (f)
- && FRAME_X_DISPLAY_INFO (f)->wm_type == X_WMTYPE_UNKNOWN)
- {
- FRAME_X_OUTPUT (f)->check_expected_move = 1;
- FRAME_X_OUTPUT (f)->expected_top = f->top_pos;
- FRAME_X_OUTPUT (f)->expected_left = f->left_pos;
- }
+ x_sync_with_move (f, f->left_pos, f->top_pos,
+ FRAME_X_DISPLAY_INFO (f)->wm_type == X_WMTYPE_UNKNOWN
+ ? 1 : 0);
+
+ /* change_gravity is non-zero when this function is called from Lisp to
+ programmatically move a frame. In that case, we call
+ x_check_expected_move to discover if we have a "Type A" or "Type B"
+ window manager, and, for a "Type A" window manager, adjust the position
+ of the frame.
+
+ We call x_check_expected_move if a programmatic move occurred, and
+ either the window manager type (A/B) is unknown or it is Type A but we
+ need to compute the top/left offset adjustment for this frame. */
+
+ if (change_gravity != 0 &&
+ (FRAME_X_DISPLAY_INFO (f)->wm_type == X_WMTYPE_UNKNOWN
+ || (FRAME_X_DISPLAY_INFO (f)->wm_type == X_WMTYPE_A
+ && (FRAME_X_OUTPUT (f)->move_offset_left == 0
+ && FRAME_X_OUTPUT (f)->move_offset_top == 0))))
+ x_check_expected_move (f, modified_left, modified_top);
UNBLOCK_INPUT;
}
}
}
-/* If frame parameters are set after the frame is mapped, we need to move
- the window.
- Some window managers moves the window to the right position, some
- moves the outer window manager window to the specified position.
- Here we check that we are in the right spot. If not, make a second
- move, assuming we are dealing with the second kind of window manager. */
+/* This function is called by x_set_offset to determine whether the window
+ manager interfered with the positioning of the frame. Type A window
+ managers position the surrounding window manager decorations a small
+ amount above and left of the user-supplied position. Type B window
+ managers position the surrounding window manager decorations at the
+ user-specified position. If we detect a Type A window manager, we
+ compensate by moving the window right and down by the proper amount. */
+
static void
-x_check_expected_move (f)
+x_check_expected_move (f, expected_left, expected_top)
struct frame *f;
+ int expected_left;
+ int expected_top;
{
- if (FRAME_X_OUTPUT (f)->check_expected_move)
- {
- int expect_top = FRAME_X_OUTPUT (f)->expected_top;
- int expect_left = FRAME_X_OUTPUT (f)->expected_left;
+ int current_left = 0, current_top = 0;
- if (expect_top != f->top_pos || expect_left != f->left_pos)
+ /* x_real_positions returns the left and top offsets of the outermost
+ window manager window around the frame. */
+
+ x_real_positions (f, ¤t_left, ¤t_top);
+
+ if (current_left != expected_left || current_top != expected_top)
{
+ /* It's a "Type A" window manager. */
+
+ int adjusted_left;
+ int adjusted_top;
+
FRAME_X_DISPLAY_INFO (f)->wm_type = X_WMTYPE_A;
- FRAME_X_OUTPUT (f)->move_offset_left = expect_left - f->left_pos;
- FRAME_X_OUTPUT (f)->move_offset_top = expect_top - f->top_pos;
+ FRAME_X_OUTPUT (f)->move_offset_left = expected_left - current_left;
+ FRAME_X_OUTPUT (f)->move_offset_top = expected_top - current_top;
- f->left_pos = expect_left;
- f->top_pos = expect_top;
- x_set_offset (f, expect_left, expect_top, 0);
+ /* Now fix the mispositioned frame's location. */
+
+ adjusted_left = expected_left + FRAME_X_OUTPUT (f)->move_offset_left;
+ adjusted_top = expected_top + FRAME_X_OUTPUT (f)->move_offset_top;
+
+ XMoveWindow (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
+ adjusted_left, adjusted_top);
+
+ x_sync_with_move (f, expected_left, expected_top, 0);
}
- else if (FRAME_X_DISPLAY_INFO (f)->wm_type == X_WMTYPE_UNKNOWN)
+ else
+ /* It's a "Type B" window manager. We don't have to adjust the
+ frame's position. */
+
FRAME_X_DISPLAY_INFO (f)->wm_type = X_WMTYPE_B;
+}
+
- /* Just do this once */
- FRAME_X_OUTPUT (f)->check_expected_move = 0;
+/* Wait for XGetGeometry to return up-to-date position information for a
+ recently-moved frame. Call this immediately after calling XMoveWindow.
+ If FUZZY is non-zero, then LEFT and TOP are just estimates of where the
+ frame has been moved to, so we use a fuzzy position comparison instead
+ of an exact comparison. */
+
+static void
+x_sync_with_move (f, left, top, fuzzy)
+ struct frame *f;
+ int left, top, fuzzy;
+{
+ int count = 0;
+
+ while (count++ < 50)
+ {
+ int current_left = 0, current_top = 0;
+
+ /* In theory, this call to XSync only needs to happen once, but in
+ practice, it doesn't seem to work, hence the need for the surrounding
+ loop. */
+
+ XSync (FRAME_X_DISPLAY (f), False);
+ x_real_positions (f, ¤t_left, ¤t_top);
+
+ if (fuzzy)
+ {
+ /* The left fuzz-factor is 10 pixels. The top fuzz-factor is 40
+ pixels. */
+
+ if (abs (current_left - left) <= 10 && abs (current_top - top) <= 40)
+ return;
}
+ else if (current_left == left && current_top == top)
+ return;
+ }
+
+ /* As a last resort, just wait 0.5 seconds and hope that XGetGeometry
+ will then return up-to-date position info. */
+
+ wait_reading_process_output (0, 500000, 0, 0, Qnil, NULL, 0);
}
x_raise_frame (f)
struct frame *f;
{
+ Lisp_Object frame;
+ const char *atom = "_NET_ACTIVE_WINDOW";
+
+ 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));
+
+ XSETFRAME (frame, f);
+ /* See Window Manager Specification/Extended Window Manager Hints at
+ http://freedesktop.org/wiki/Standards_2fwm_2dspec */
+
+ 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 (time (NULL) * 1000),
+ Qnil)));
+ XFlush (FRAME_X_DISPLAY (f));
+ UNBLOCK_INPUT;
}
/* Lower frame F. */
for (i = 0; i < dpyinfo->n_fonts; i++)
if (dpyinfo->font_table[i].name
- && (!strcmp (dpyinfo->font_table[i].name, fontname)
- || !strcmp (dpyinfo->font_table[i].full_name, fontname)))
+ && (!strcasecmp (dpyinfo->font_table[i].name, fontname)
+ || !strcasecmp (dpyinfo->font_table[i].full_name, fontname)))
return (dpyinfo->font_table + i);
return NULL;
}
{"-mc", "*pointerColor", XrmoptionSepArg, (XtPointer) NULL},
{"-cr", "*cursorColor", XrmoptionSepArg, (XtPointer) NULL}
};
+
+/* Whether atimer for Xt timeouts is activated or not. */
+
+static int x_timeout_atimer_activated_flag;
+
#endif /* USE_X_TOOLKIT */
static int x_initialized;
+#ifdef HAVE_X_SM
+static int x_session_initialized;
+#endif
+
#ifdef MULTI_KBOARD
/* Test whether two display-name strings agree up to the dot that separates
the screen number from the server number. */
*bits = nr;
}
+int
+x_display_ok (display)
+ const char * display;
+{
+ int dpy_ok = 1;
+ Display *dpy;
+
+ dpy = XOpenDisplay (display);
+ if (dpy)
+ XCloseDisplay (dpy);
+ else
+ dpy_ok = 0;
+ return dpy_ok;
+}
+
struct x_display_info *
x_term_init (display_name, xrm_option, resource_name)
Lisp_Object display_name;
/* Load our own gtkrc if it exists. */
{
- struct gcpro gcpro1, gcpro2;
char *file = "~/.emacs.d/gtkrc";
Lisp_Object s, abs_file;
- GCPRO2 (s, abs_file);
s = make_string (file, strlen (file));
abs_file = Fexpand_file_name (s, Qnil);
if (! NILP (abs_file) && !NILP (Ffile_readable_p (abs_file)))
gtk_rc_parse (SDATA (abs_file));
-
- UNGCPRO;
}
XSetErrorHandler (x_error_handler);
dpyinfo->cut_buffers_initialized = 0;
+ dpyinfo->x_dnd_atoms_size = 8;
+ dpyinfo->x_dnd_atoms_length = 0;
+ dpyinfo->x_dnd_atoms = xmalloc (sizeof (*dpyinfo->x_dnd_atoms)
+ * dpyinfo->x_dnd_atoms_size);
+
connection = ConnectionNumber (dpyinfo->display);
dpyinfo->connection = connection;
#ifdef HAVE_X_SM
/* Only do this for the first display. */
- if (x_initialized == 1)
+ if (!x_session_initialized++)
x_session_initialize (dpyinfo);
#endif
xfree (dpyinfo->font_table[i].name);
}
- if (dpyinfo->font_table->font_encoder)
- xfree (dpyinfo->font_table->font_encoder);
-
- xfree (dpyinfo->font_table);
- xfree (dpyinfo->x_id_name);
- xfree (dpyinfo->color_cells);
+ if (dpyinfo->font_table)
+ {
+ if (dpyinfo->font_table->font_encoder)
+ xfree (dpyinfo->font_table->font_encoder);
+ xfree (dpyinfo->font_table);
+ }
+ if (dpyinfo->x_id_name)
+ xfree (dpyinfo->x_id_name);
+ if (dpyinfo->color_cells)
+ xfree (dpyinfo->color_cells);
xfree (dpyinfo);
}
x_process_timeouts (timer)
struct atimer *timer;
{
+ BLOCK_INPUT;
+ x_timeout_atimer_activated_flag = 0;
if (toolkit_scroll_bar_interaction || popup_activated ())
{
- BLOCK_INPUT;
while (XtAppPending (Xt_app_con) & XtIMTimer)
XtAppProcessEvent (Xt_app_con, XtIMTimer);
- UNBLOCK_INPUT;
+ /* Reactivate the atimer for next time. */
+ x_activate_timeout_atimer ();
+ }
+ UNBLOCK_INPUT;
+}
+
+/* Install an asynchronous timer that processes Xt timeout events
+ every 0.1s as long as either `toolkit_scroll_bar_interaction' or
+ `popup_activated_flag' (in xmenu.c) is set. Make sure to call this
+ function whenever these variables are set. This is necessary
+ because some widget sets use timeouts internally, for example the
+ LessTif menu bar, or the Xaw3d scroll bar. When Xt timeouts aren't
+ processed, these widgets don't behave normally. */
+
+void
+x_activate_timeout_atimer ()
+{
+ BLOCK_INPUT;
+ if (!x_timeout_atimer_activated_flag)
+ {
+ EMACS_TIME interval;
+
+ EMACS_SET_SECS_USECS (interval, 0, 100000);
+ start_atimer (ATIMER_RELATIVE, interval, x_process_timeouts, 0);
+ x_timeout_atimer_activated_flag = 1;
}
+ UNBLOCK_INPUT;
}
#endif /* USE_X_TOOLKIT */
last_tool_bar_item = -1;
any_help_event_p = 0;
ignore_next_mouse_click_timeout = 0;
+#ifdef HAVE_X_SM
+ x_session_initialized = 0;
+#endif
#ifdef USE_GTK
current_count = -1;
XtCacheByDisplay, cvt_pixel_dtor);
XtAppSetFallbackResources (Xt_app_con, Xt_default_resources);
-
- /* Install an asynchronous timer that processes Xt timeout events
- every 0.1s. This is necessary because some widget sets use
- timeouts internally, for example the LessTif menu bar, or the
- Xaw3d scroll bar. When Xt timouts aren't processed, these
- widgets don't behave normally. */
- {
- EMACS_TIME interval;
- EMACS_SET_SECS_USECS (interval, 0, 100000);
- start_atimer (ATIMER_CONTINUOUS, interval, x_process_timeouts, 0);
- }
#endif
#ifdef USE_TOOLKIT_SCROLL_BARS
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. */);
+ x_underline_at_descent_line = 0;
+
DEFVAR_BOOL ("x-mouse-click-focus-ignore-position",
&x_mouse_click_focus_ignore_position,
doc: /* Non-nil means that a mouse click to focus a frame does not move point.