void
record_event (char *locus, int type)
{
- if (event_record_index == sizeof (event_record) / sizeof (struct record))
+ if (event_record_index == ARRAYELTS (event_record))
event_record_index = 0;
event_record[event_record_index].locus = locus;
x_draw_window_divider (struct window *w, int x0, int x1, int y0, int y1)
{
struct frame *f = XFRAME (WINDOW_FRAME (w));
- struct face *face;
-
- face = FACE_FROM_ID (f, WINDOW_DIVIDER_FACE_ID);
- if (face)
- XSetForeground (FRAME_X_DISPLAY (f), f->output_data.x->normal_gc,
- face->foreground);
+ struct face *face = FACE_FROM_ID (f, WINDOW_DIVIDER_FACE_ID);
+ struct face *face_first = FACE_FROM_ID (f, WINDOW_DIVIDER_FIRST_PIXEL_FACE_ID);
+ struct face *face_last = FACE_FROM_ID (f, WINDOW_DIVIDER_LAST_PIXEL_FACE_ID);
+ unsigned long color = face ? face->foreground : FRAME_FOREGROUND_PIXEL (f);
+ unsigned long color_first = (face_first
+ ? face_first->foreground
+ : FRAME_FOREGROUND_PIXEL (f));
+ unsigned long color_last = (face_last
+ ? face_last->foreground
+ : FRAME_FOREGROUND_PIXEL (f));
+ Display *display = FRAME_X_DISPLAY (f);
+ Window window = FRAME_X_WINDOW (f);
- XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
- f->output_data.x->normal_gc, x0, y0, x1 - x0, y1 - y0);
+ if (y1 - y0 > x1 - x0 && x1 - x0 > 2)
+ /* Vertical. */
+ {
+ XSetForeground (display, f->output_data.x->normal_gc, color_first);
+ XFillRectangle (display, window, f->output_data.x->normal_gc,
+ x0, y0, 1, y1 - y0);
+ XSetForeground (display, f->output_data.x->normal_gc, color);
+ XFillRectangle (display, window, f->output_data.x->normal_gc,
+ x0 + 1, y0, x1 - x0 - 2, y1 - y0);
+ XSetForeground (display, f->output_data.x->normal_gc, color_last);
+ XFillRectangle (display, window, f->output_data.x->normal_gc,
+ x1 - 1, y0, 1, y1 - y0);
+ }
+ else if (x1 - x0 > y1 - y0 && y1 - y0 > 3)
+ /* Horizontal. */
+ {
+ XSetForeground (display, f->output_data.x->normal_gc, color_first);
+ XFillRectangle (display, window, f->output_data.x->normal_gc,
+ x0, y0, x1 - x0, 1);
+ XSetForeground (display, f->output_data.x->normal_gc, color);
+ XFillRectangle (display, window, f->output_data.x->normal_gc,
+ x0, y0 + 1, x1 - x0, y1 - y0 - 2);
+ XSetForeground (display, f->output_data.x->normal_gc, color_last);
+ XFillRectangle (display, window, f->output_data.x->normal_gc,
+ x0, y1 - 1, x1 - x0, 1);
+ }
+ else
+ {
+ XSetForeground (display, f->output_data.x->normal_gc, color);
+ XFillRectangle (display, window, f->output_data.x->normal_gc,
+ x0, y0, x1 - x0, y1 - y0);
+ }
}
/* End update of window W.
s->stippled_p = s->face->stipple != 0;
}
else
- {
- s->gc = s->face->gc;
- s->stippled_p = s->face->stipple != 0;
- }
+ emacs_abort ();
/* GC must have been set. */
eassert (s->gc != 0);
x_draw_image_relief (struct glyph_string *s)
{
int x1, y1, thick, raised_p, top_p, bot_p, left_p, right_p;
+ int extra_x, extra_y;
XRectangle r;
int x = s->x;
int y = s->ybase - image_ascent (s->img, s->face, &s->slice);
x1 = x + s->slice.width - 1;
y1 = y + s->slice.height - 1;
+
+ extra_x = extra_y = 0;
+ if (s->face->id == TOOL_BAR_FACE_ID)
+ {
+ if (CONSP (Vtool_bar_button_margin)
+ && INTEGERP (XCAR (Vtool_bar_button_margin))
+ && INTEGERP (XCDR (Vtool_bar_button_margin)))
+ {
+ extra_x = XINT (XCAR (Vtool_bar_button_margin));
+ extra_y = XINT (XCDR (Vtool_bar_button_margin));
+ }
+ else if (INTEGERP (Vtool_bar_button_margin))
+ extra_x = extra_y = XINT (Vtool_bar_button_margin);
+ }
+
top_p = bot_p = left_p = right_p = 0;
if (s->slice.x == 0)
- x -= thick, left_p = 1;
+ x -= thick + extra_x, left_p = 1;
if (s->slice.y == 0)
- y -= thick, top_p = 1;
+ y -= thick + extra_y, top_p = 1;
if (s->slice.x + s->slice.width == s->img->width)
- x1 += thick, right_p = 1;
+ x1 += thick + extra_x, right_p = 1;
if (s->slice.y + s->slice.height == s->img->height)
- y1 += thick, bot_p = 1;
+ y1 += thick + extra_y, bot_p = 1;
x_setup_relief_colors (s);
get_glyph_string_clip_rect (s, &r);
{
int x = s->x;
int y = s->y;
+ int width = s->background_width;
if (s->first_glyph->left_box_line_p
&& s->slice.x == 0)
- x += box_line_hwidth;
+ {
+ x += box_line_hwidth;
+ width -= box_line_hwidth;
+ }
if (s->slice.y == 0)
y += box_line_vwidth;
- x_draw_glyph_string_bg_rect (s, x, y, s->background_width, height);
+ x_draw_glyph_string_bg_rect (s, x, y, width, height);
}
s->background_filled_p = 1;
XFillRectangle (s->display, s->window, gc, x, y, w, h);
XSetForeground (s->display, gc, xgcv.foreground);
}
+
+ XSetClipMask (s->display, gc, None);
}
}
else if (!s->background_filled_p)
static short temp_buffer[100];
#define STORE_KEYSYM_FOR_DEBUG(keysym) \
- if (temp_index == sizeof temp_buffer / sizeof (short)) \
+ if (temp_index == ARRAYELTS (temp_buffer)) \
temp_index = 0; \
temp_buffer[temp_index++] = (keysym)
/* This is the filter function invoked by the GTK event loop.
It is invoked before the XEvent is translated to a GdkEvent,
- so we have a chance to act on the event before GTK. */
+ so we have a chance to act on the event before GTK. */
static GdkFilterReturn
event_handler_gdk (GdkXEvent *gxev, GdkEvent *ev, gpointer data)
{
if (! dpyinfo)
current_finish = X_EVENT_NORMAL;
else
- current_count +=
- handle_one_xevent (dpyinfo, xev, ¤t_finish,
- current_hold_quit);
+ current_count
+ += handle_one_xevent (dpyinfo, xev, ¤t_finish,
+ current_hold_quit);
}
else
current_finish = x_dispatch_event (xev, xev->xany.display);
if (f)
{
bool iconified = FRAME_ICONIFIED_P (f);
- /* wait_reading_process_output will notice this and update
- the frame's display structures.
- If we where iconified, we should not set garbaged,
- because that stops redrawing on Expose events. This looks
- bad if we are called from a recursive event loop
- (x_dispatch_event), for example when a dialog is up. */
- if (!iconified)
- SET_FRAME_GARBAGED (f);
/* Check if fullscreen was specified before we where mapped the
first time, i.e. from the command line. */
#ifdef USE_GTK
/* GTK creates windows but doesn't map them.
- Only get real positions when mapped. */
+ Only get real positions when mapped. */
if (FRAME_GTK_OUTER_WIDGET (f)
&& gtk_widget_get_mapped (FRAME_GTK_OUTER_WIDGET (f)))
#endif
#ifdef USE_GTK
- if (xg_set_icon (f, xg_default_icon_file)
- || xg_set_icon_from_xpm_data (f, gnu_xpm_bits))
- return 0;
+ if (FRAME_DISPLAY_INFO (f)->icon_bitmap_id == -2
+ || xg_set_icon (f, xg_default_icon_file)
+ || xg_set_icon_from_xpm_data (f, gnu_xpm_bits))
+ {
+ FRAME_DISPLAY_INFO (f)->icon_bitmap_id = -2;
+ return 0;
+ }
#elif defined (HAVE_XPM) && defined (HAVE_X_WINDOWS)
compute_fringe_widths (f, 1);
+ /* Compute character columns occupied by scrollbar.
+
+ Don't do things differently for non-toolkit scrollbars
+ (Bug#17163). */
unit = FRAME_COLUMN_WIDTH (f);
-#ifdef USE_TOOLKIT_SCROLL_BARS
- /* The width of a toolkit scrollbar does not change with the new
- font but we have to calculate the number of columns it occupies
- anew. */
- FRAME_CONFIG_SCROLL_BAR_COLS (f)
- = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) + unit - 1) / unit;
-#else
- /* The width of a non-toolkit scrollbar is at least 14 pixels and a
- multiple of the frame's character width. */
- FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + unit - 1) / unit;
- FRAME_CONFIG_SCROLL_BAR_WIDTH (f)
- = FRAME_CONFIG_SCROLL_BAR_COLS (f) * unit;
-#endif
+ if (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) > 0)
+ FRAME_CONFIG_SCROLL_BAR_COLS (f)
+ = (FRAME_CONFIG_SCROLL_BAR_WIDTH (f) + unit - 1) / unit;
+ else
+ FRAME_CONFIG_SCROLL_BAR_COLS (f) = (14 + unit - 1) / unit;
if (FRAME_X_WINDOW (f) != 0)
{
{
#ifdef HAVE_X11R6_XIM
struct xim_inst_t *xim_inst = xmalloc (sizeof *xim_inst);
+ Bool ret;
dpyinfo->xim_callback_data = xim_inst;
xim_inst->dpyinfo = dpyinfo;
xim_inst->resource_name = xstrdup (resource_name);
- XRegisterIMInstantiateCallback (dpyinfo->display, dpyinfo->xrdb,
- resource_name, emacs_class,
- xim_instantiate_callback,
- /* This is XPointer in XFree86
- but (XPointer *) on Tru64, at
- least, hence the configure test. */
- (XRegisterIMInstantiateCallback_arg6) xim_inst);
+ ret = XRegisterIMInstantiateCallback
+ (dpyinfo->display, dpyinfo->xrdb, xim_inst->resource_name,
+ emacs_class, xim_instantiate_callback,
+ /* This is XPointer in XFree86 but (XPointer *)
+ on Tru64, at least, hence the configure test. */
+ (XRegisterIMInstantiateCallback_arg6) xim_inst);
+ eassert (ret == True);
#else /* not HAVE_X11R6_XIM */
xim_open_dpy (dpyinfo, resource_name);
#endif /* not HAVE_X11R6_XIM */
if (use_xim)
{
#ifdef HAVE_X11R6_XIM
+ struct xim_inst_t *xim_inst = dpyinfo->xim_callback_data;
+
if (dpyinfo->display)
- XUnregisterIMInstantiateCallback (dpyinfo->display, dpyinfo->xrdb,
- NULL, emacs_class,
- xim_instantiate_callback, NULL);
- xfree (dpyinfo->xim_callback_data->resource_name);
- xfree (dpyinfo->xim_callback_data);
+ {
+ Bool ret = XUnregisterIMInstantiateCallback
+ (dpyinfo->display, dpyinfo->xrdb, xim_inst->resource_name,
+ emacs_class, xim_instantiate_callback,
+ (XRegisterIMInstantiateCallback_arg6) xim_inst);
+ eassert (ret == True);
+ }
+ xfree (xim_inst->resource_name);
+ xfree (xim_inst);
#endif /* HAVE_X11R6_XIM */
if (dpyinfo->display)
XCloseIM (dpyinfo->xim);
x_make_frame_visible (struct frame *f)
{
int original_top, original_left;
+ int tries = 0;
block_input ();
/* Force processing of queued events. */
x_sync (f);
- /* This hack is still in use at least for Cygwin. See
+ /* If on another desktop, the deiconify/map may be ignored and the
+ frame never becomes visible. XMonad does this.
+ Prevent an endless loop. */
+ if (FRAME_ICONIFIED_P (f) && ++tries > 100)
+ break;
+
+ /* This hack is still in use at least for Cygwin. See
http://lists.gnu.org/archive/html/emacs-devel/2013-12/msg00351.html.
Machines that do polling rather than SIGIO have been
f->output_data.x->black_relief.gc = 0;
}
+ /* Free cursors. */
+ if (f->output_data.x->text_cursor != 0)
+ XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->text_cursor);
+ if (f->output_data.x->nontext_cursor != 0)
+ XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->nontext_cursor);
+ if (f->output_data.x->modeline_cursor != 0)
+ XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->modeline_cursor);
+ if (f->output_data.x->hand_cursor != 0)
+ XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->hand_cursor);
+ if (f->output_data.x->hourglass_cursor != 0)
+ XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->hourglass_cursor);
+ if (f->output_data.x->horizontal_drag_cursor != 0)
+ XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->horizontal_drag_cursor);
+ if (f->output_data.x->vertical_drag_cursor != 0)
+ XFreeCursor (FRAME_X_DISPLAY (f), f->output_data.x->vertical_drag_cursor);
+
XFlush (FRAME_X_DISPLAY (f));
}
}
#endif
+/* Current X display connection identifier. Incremented for each next
+ connection established. */
+static unsigned x_display_id;
+
/* Open a connection to X display DISPLAY_NAME, and return
the structure that describes the open display.
If we cannot contact the display, return null. */
lim = min (PTRDIFF_MAX, SIZE_MAX) - sizeof "@";
if (lim - SBYTES (Vinvocation_name) < SBYTES (Vsystem_name))
memory_full (SIZE_MAX);
+ dpyinfo->x_id = ++x_display_id;
dpyinfo->x_id_name = xmalloc (SBYTES (Vinvocation_name)
+ SBYTES (Vsystem_name) + 2);
strcat (strcat (strcpy (dpyinfo->x_id_name, SSDATA (Vinvocation_name)), "@"),
};
int i;
- const int atom_count = sizeof (atom_refs) / sizeof (atom_refs[0]);
+ const int atom_count = ARRAYELTS (atom_refs);
/* 1 for _XSETTINGS_SN */
const int total_atom_count = 1 + atom_count;
Atom *atoms_return = xmalloc (total_atom_count * sizeof *atoms_return);
#ifdef USE_LUCID
{
+ XFontStruct *xfont = NULL;
XrmValue d, fr, to;
Font font;
x_catch_errors (dpy);
if (!XtCallConverter (dpy, XtCvtStringToFont, &d, 1, &fr, &to, NULL))
emacs_abort ();
- if (x_had_errors_p (dpy) || !XQueryFont (dpy, font))
+ if (x_had_errors_p (dpy) || !((xfont = XQueryFont (dpy, font))))
XrmPutLineResource (&xrdb, "Emacs.dialog.*.font: 9x15");
+ if (xfont)
+ XFreeFont (dpy, xfont);
x_uncatch_errors ();
}
#endif