summaryrefslogtreecommitdiff
path: root/src/xterm.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/xterm.c')
-rw-r--r--src/xterm.c374
1 files changed, 247 insertions, 127 deletions
diff --git a/src/xterm.c b/src/xterm.c
index ec415f5ffaf..36e0045d2ed 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -99,6 +99,12 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include "xterm.h"
#include <X11/cursorfont.h>
+#ifdef USE_XCB
+#include <xcb/xproto.h>
+#include <xcb/xcb.h>
+#include <xcb/xcb_aux.h>
+#endif
+
/* If we have Xfixes extension, use it for pointer blanking. */
#ifdef HAVE_XFIXES
#include <X11/extensions/Xfixes.h>
@@ -167,6 +173,10 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include "../lwlib/xlwmenu.h"
#endif
+#ifdef HAVE_XWIDGETS
+#include <cairo-xlib.h>
+#endif
+
#ifdef USE_X_TOOLKIT
/* Include toolkit specific headers for the scroll bar widget. */
@@ -206,6 +216,10 @@ along with GNU Emacs. If not, see <https://www.gnu.org/licenses/>. */
#include <X11/XKBlib.h>
#endif
+#if defined USE_XCB && defined USE_CAIRO_XCB
+#define USE_CAIRO_XCB_SURFACE
+#endif
+
/* Default to using XIM if available. */
#ifdef USE_XIM
bool use_xim = true;
@@ -777,11 +791,19 @@ x_begin_cr_clip (struct frame *f, GC gc)
{
int width = FRAME_CR_SURFACE_DESIRED_WIDTH (f);
int height = FRAME_CR_SURFACE_DESIRED_HEIGHT (f);
- cairo_surface_t *surface
- = cairo_xlib_surface_create (FRAME_X_DISPLAY (f),
- FRAME_X_RAW_DRAWABLE (f),
- FRAME_X_VISUAL (f),
- width, height);
+ cairo_surface_t *surface;
+#ifdef USE_CAIRO_XCB_SURFACE
+ if (FRAME_DISPLAY_INFO (f)->xcb_visual)
+ surface = cairo_xcb_surface_create (FRAME_DISPLAY_INFO (f)->xcb_connection,
+ (xcb_drawable_t) FRAME_X_RAW_DRAWABLE (f),
+ FRAME_DISPLAY_INFO (f)->xcb_visual,
+ width, height);
+ else
+#endif
+ surface = cairo_xlib_surface_create (FRAME_X_DISPLAY (f),
+ FRAME_X_RAW_DRAWABLE (f),
+ FRAME_X_VISUAL (f),
+ width, height);
cr = FRAME_CR_CONTEXT (f) = cairo_create (surface);
cairo_surface_destroy (surface);
@@ -850,6 +872,9 @@ x_try_cr_xlib_drawable (struct frame *f, GC gc)
switch (cairo_surface_get_type (surface))
{
case CAIRO_SURFACE_TYPE_XLIB:
+#ifdef USE_CAIRO_XCB_SURFACE
+ case CAIRO_SURFACE_TYPE_XCB:
+#endif
cairo_surface_flush (surface);
return true;
@@ -1262,11 +1287,15 @@ x_clear_window (struct frame *f)
cairo_paint (cr);
x_end_cr_clip (f);
#else
+#ifndef USE_GTK
if (FRAME_X_DOUBLE_BUFFERED_P (f))
+#endif
x_clear_area (f, 0, 0, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (f));
+#ifndef USE_GTK
else
XClearWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
#endif
+#endif
}
#ifdef USE_CAIRO
@@ -2768,8 +2797,9 @@ x_query_frame_background_color (struct frame *f, XColor *bgcolor)
and names we've actually looked up; list-colors-display is probably
the most color-intensive case we're likely to hit. */
-Status x_parse_color (struct frame *f, const char *color_name,
- XColor *color)
+Status
+x_parse_color (struct frame *f, const char *color_name,
+ XColor *color)
{
/* Don't pass #RGB strings directly to XParseColor, because that
follows the X convention of zero-extending each channel
@@ -2798,6 +2828,10 @@ Status x_parse_color (struct frame *f, const char *color_name,
}
}
+ /* Some X servers send BadValue on empty color names. */
+ if (!strlen (color_name))
+ return 0;
+
if (XParseColor (dpy, cmap, color_name, color) == 0)
/* No caching of negative results, currently. */
return 0;
@@ -4473,15 +4507,19 @@ x_clear_area (struct frame *f, int x, int y, int width, int height)
cairo_fill (cr);
x_end_cr_clip (f);
#else
+#ifndef USE_GTK
if (FRAME_X_DOUBLE_BUFFERED_P (f))
+#endif
XFillRectangle (FRAME_X_DISPLAY (f),
FRAME_X_DRAWABLE (f),
f->output_data.x->reverse_gc,
x, y, width, height);
+#ifndef USE_GTK
else
x_clear_area1 (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
x, y, width, height, False);
#endif
+#endif
}
@@ -4528,6 +4566,7 @@ x_show_hourglass (struct frame *f)
if (!x->hourglass_window)
{
+#ifndef USE_XCB
unsigned long mask = CWCursor;
XSetWindowAttributes attrs;
#ifdef USE_GTK
@@ -4540,12 +4579,41 @@ x_show_hourglass (struct frame *f)
x->hourglass_window = XCreateWindow
(dpy, parent, 0, 0, 32000, 32000, 0, 0,
InputOnly, CopyFromParent, mask, &attrs);
+#else
+ uint32_t cursor = (uint32_t) x->hourglass_cursor;
+#ifdef USE_GTK
+ xcb_window_t parent = (xcb_window_t) FRAME_X_WINDOW (f);
+#else
+ xcb_window_t parent = (xcb_window_t) FRAME_OUTER_WINDOW (f);
+#endif
+ x->hourglass_window
+ = (Window) xcb_generate_id (FRAME_DISPLAY_INFO (f)->xcb_connection);
+
+ xcb_create_window (FRAME_DISPLAY_INFO (f)->xcb_connection,
+ XCB_COPY_FROM_PARENT,
+ (xcb_window_t) x->hourglass_window,
+ parent, 0, 0, FRAME_PIXEL_WIDTH (f),
+ FRAME_PIXEL_HEIGHT (f), 0,
+ XCB_WINDOW_CLASS_INPUT_OUTPUT,
+ XCB_COPY_FROM_PARENT, XCB_CW_CURSOR,
+ &cursor);
+#endif
}
+#ifndef USE_XCB
XMapRaised (dpy, x->hourglass_window);
- XFlush (dpy);
/* Ensure that the spinning hourglass is shown. */
flush_frame (f);
+#else
+ uint32_t value = XCB_STACK_MODE_ABOVE;
+
+ xcb_configure_window (FRAME_DISPLAY_INFO (f)->xcb_connection,
+ (xcb_window_t) x->hourglass_window,
+ XCB_CONFIG_WINDOW_STACK_MODE, &value);
+ xcb_map_window (FRAME_DISPLAY_INFO (f)->xcb_connection,
+ (xcb_window_t) x->hourglass_window);
+ xcb_flush (FRAME_DISPLAY_INFO (f)->xcb_connection);
+#endif
}
}
}
@@ -4560,10 +4628,16 @@ x_hide_hourglass (struct frame *f)
/* Watch out for newly created frames. */
if (x->hourglass_window)
{
+#ifndef USE_XCB
XUnmapWindow (FRAME_X_DISPLAY (f), x->hourglass_window);
/* Sync here because XTread_socket looks at the
hourglass_p flag that is reset to zero below. */
XSync (FRAME_X_DISPLAY (f), False);
+#else
+ xcb_unmap_window (FRAME_DISPLAY_INFO (f)->xcb_connection,
+ (xcb_window_t) x->hourglass_window);
+ xcb_aux_sync (FRAME_DISPLAY_INFO (f)->xcb_connection);
+#endif
x->hourglass_p = false;
}
}
@@ -4576,38 +4650,6 @@ XTflash (struct frame *f)
block_input ();
{
-#ifdef USE_GTK
- /* Use Gdk routines to draw. This way, we won't draw over scroll bars
- when the scroll bars and the edit widget share the same X window. */
- GdkWindow *window = gtk_widget_get_window (FRAME_GTK_WIDGET (f));
-#ifdef HAVE_GTK3
-#if GTK_CHECK_VERSION (3, 22, 0)
- cairo_region_t *region = gdk_window_get_visible_region (window);
- GdkDrawingContext *context = gdk_window_begin_draw_frame (window, region);
- cairo_t *cr = gdk_drawing_context_get_cairo_context (context);
-#else
- cairo_t *cr = gdk_cairo_create (window);
-#endif
- cairo_set_source_rgb (cr, 1, 1, 1);
- cairo_set_operator (cr, CAIRO_OPERATOR_DIFFERENCE);
-#define XFillRectangle(d, win, gc, x, y, w, h) \
- do { \
- cairo_rectangle (cr, x, y, w, h); \
- cairo_fill (cr); \
- } \
- while (false)
-#else /* ! HAVE_GTK3 */
- GdkGCValues vals;
- GdkGC *gc;
- vals.foreground.pixel = (FRAME_FOREGROUND_PIXEL (f)
- ^ FRAME_BACKGROUND_PIXEL (f));
- vals.function = GDK_XOR;
- gc = gdk_gc_new_with_values (window,
- &vals, GDK_GC_FUNCTION | GDK_GC_FOREGROUND);
-#define XFillRectangle(d, win, gc, x, y, w, h) \
- gdk_draw_rectangle (window, gc, true, x, y, w, h)
-#endif /* ! HAVE_GTK3 */
-#else /* ! USE_GTK */
GC gc;
/* Create a GC that will use the GXxor function to flip foreground
@@ -4622,7 +4664,6 @@ XTflash (struct frame *f)
gc = XCreateGC (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f),
GCFunction | GCForeground, &values);
}
-#endif
{
/* Get the height not including a menu bar widget. */
int height = FRAME_PIXEL_HEIGHT (f);
@@ -4698,22 +4739,7 @@ XTflash (struct frame *f)
XFillRectangle (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), gc,
flash_left, FRAME_INTERNAL_BORDER_WIDTH (f),
width, height - 2 * FRAME_INTERNAL_BORDER_WIDTH (f));
-
-#ifdef USE_GTK
-#ifdef HAVE_GTK3
-#if GTK_CHECK_VERSION (3, 22, 0)
- gdk_window_end_draw_frame (window, context);
- cairo_region_destroy (region);
-#else
- cairo_destroy (cr);
-#endif
-#else
- g_object_unref (G_OBJECT (gc));
-#endif
-#undef XFillRectangle
-#else
XFreeGC (FRAME_X_DISPLAY (f), gc);
-#endif
x_flush (f);
}
}
@@ -4921,6 +4947,18 @@ x_scroll_run (struct window *w, struct run *run)
x, to_y);
cairo_surface_mark_dirty_rectangle (surface, x, to_y, width, height);
}
+#ifdef USE_CAIRO_XCB_SURFACE
+ else if (cairo_surface_get_type (surface) == CAIRO_SURFACE_TYPE_XCB)
+ {
+ cairo_surface_flush (surface);
+ xcb_copy_area (FRAME_DISPLAY_INFO (f)->xcb_connection,
+ (xcb_drawable_t) FRAME_X_DRAWABLE (f),
+ (xcb_drawable_t) FRAME_X_DRAWABLE (f),
+ (xcb_gcontext_t) XGContextFromGC (f->output_data.x->normal_gc),
+ x, from_y, x, to_y, width, height);
+ cairo_surface_mark_dirty_rectangle (surface, x, to_y, width, height);
+ }
+#endif
else
{
cairo_surface_t *s
@@ -5436,11 +5474,6 @@ x_find_modifier_meanings (struct x_display_info *dpyinfo)
int syms_per_code;
XModifierKeymap *mods;
#ifdef HAVE_XKB
- Atom meta;
- Atom super;
- Atom hyper;
- Atom shiftlock;
- Atom alt;
int i;
int found_meta_p = false;
#endif
@@ -5454,28 +5487,22 @@ x_find_modifier_meanings (struct x_display_info *dpyinfo)
#ifdef HAVE_XKB
if (dpyinfo->xkb_desc)
{
- meta = XInternAtom (dpyinfo->display, "Meta", False);
- super = XInternAtom (dpyinfo->display, "Super", False);
- hyper = XInternAtom (dpyinfo->display, "Hyper", False);
- shiftlock = XInternAtom (dpyinfo->display, "ShiftLock", False);
- alt = XInternAtom (dpyinfo->display, "Alt", False);
-
for (i = 0; i < XkbNumVirtualMods; i++)
{
uint vmodmask = dpyinfo->xkb_desc->server->vmods[i];
- if (dpyinfo->xkb_desc->names->vmods[i] == meta)
+ if (dpyinfo->xkb_desc->names->vmods[i] == dpyinfo->Xatom_Meta)
{
dpyinfo->meta_mod_mask |= vmodmask;
found_meta_p = vmodmask;
}
- else if (dpyinfo->xkb_desc->names->vmods[i] == alt)
+ else if (dpyinfo->xkb_desc->names->vmods[i] == dpyinfo->Xatom_Alt)
dpyinfo->alt_mod_mask |= vmodmask;
- else if (dpyinfo->xkb_desc->names->vmods[i] == super)
+ else if (dpyinfo->xkb_desc->names->vmods[i] == dpyinfo->Xatom_Super)
dpyinfo->super_mod_mask |= vmodmask;
- else if (dpyinfo->xkb_desc->names->vmods[i] == hyper)
+ else if (dpyinfo->xkb_desc->names->vmods[i] == dpyinfo->Xatom_Hyper)
dpyinfo->hyper_mod_mask |= vmodmask;
- else if (dpyinfo->xkb_desc->names->vmods[i] == shiftlock)
+ else if (dpyinfo->xkb_desc->names->vmods[i] == dpyinfo->Xatom_ShiftLock)
dpyinfo->shift_lock_mask |= vmodmask;
}
@@ -8373,6 +8400,7 @@ x_filter_event (struct x_display_info *dpyinfo, XEvent *event)
#ifdef USE_GTK
}
else if (f1 && (event->type == KeyPress
+ || event->type == KeyRelease
#ifdef HAVE_XINPUT2
|| xinput_event
#endif
@@ -8384,6 +8412,11 @@ x_filter_event (struct x_display_info *dpyinfo, XEvent *event)
result = xg_filter_key (f1, event);
unblock_input ();
+ if (result && f1)
+ /* There will probably be a GDK event generated soon, so
+ exercise the wire to make pselect return. */
+ XNoOp (FRAME_X_DISPLAY (f1));
+
return result;
}
@@ -8434,8 +8467,10 @@ event_handler_gdk (GdkXEvent *gxev, GdkEvent *ev, gpointer data)
&& xev->type == GenericEvent
&& (xev->xgeneric.extension
== dpyinfo->xi2_opcode)
- && (xev->xgeneric.evtype
- == XI_KeyPress))
+ && ((xev->xgeneric.evtype
+ == XI_KeyPress)
+ || (xev->xgeneric.evtype
+ == XI_KeyRelease)))
#endif
))
{
@@ -8947,12 +8982,17 @@ handle_one_xevent (struct x_display_info *dpyinfo,
if (!FRAME_VISIBLE_P (f))
{
block_input ();
- /* The following two are commented out to avoid that a
- plain invisible frame gets reported as iconified. That
- problem occurred first for Emacs 26 and is described in
- https://lists.gnu.org/archive/html/emacs-devel/2017-02/msg00133.html. */
-/** SET_FRAME_VISIBLE (f, 1); **/
-/** SET_FRAME_ICONIFIED (f, false); **/
+ /* By default, do not set the frame's visibility here, see
+ https://lists.gnu.org/archive/html/emacs-devel/2017-02/msg00133.html.
+ The default behavior can be overridden by setting
+ 'x-set-frame-visibility-more-laxly' (Bug#49955,
+ Bug#53298). */
+ if (EQ (x_set_frame_visibility_more_laxly, Qexpose)
+ || EQ (x_set_frame_visibility_more_laxly, Qt))
+ {
+ SET_FRAME_VISIBLE (f, 1);
+ SET_FRAME_ICONIFIED (f, false);
+ }
if (FRAME_X_DOUBLE_BUFFERED_P (f))
font_drop_xrender_surfaces (f);
@@ -9236,7 +9276,8 @@ handle_one_xevent (struct x_display_info *dpyinfo,
int modifiers;
Lisp_Object coding_system = Qlatin_1;
Lisp_Object c;
- /* Event will be modified. */
+ /* `xkey' will be modified, but it's not important to modify
+ `event' itself. */
XKeyEvent xkey = event->xkey;
#ifdef USE_GTK
@@ -9498,8 +9539,6 @@ handle_one_xevent (struct x_display_info *dpyinfo,
if (keysym == NoSymbol)
break;
}
- /* FIXME: check side effects and remove this. */
- ((XEvent *) event)->xkey = xkey;
}
done_keysym:
#ifdef HAVE_X_I18N
@@ -9571,26 +9610,33 @@ handle_one_xevent (struct x_display_info *dpyinfo,
goto OTHER;
case FocusIn:
-#ifndef USE_GTK
+#ifdef USE_GTK
/* Some WMs (e.g. Mutter in Gnome Shell), don't unmap
minimized/iconified windows; thus, for those WMs we won't get
- a MapNotify when unminimizing/deconifying. Check here if we
+ a MapNotify when unminimizing/deiconifying. Check here if we
are deiconizing a window (Bug42655).
- But don't do that on GTK since it may cause a plain invisible
- frame get reported as iconified, compare
+ But don't do that by default on GTK since it may cause a plain
+ invisible frame get reported as iconified, compare
https://lists.gnu.org/archive/html/emacs-devel/2017-02/msg00133.html.
- That is fixed above but bites us here again. */
- f = any;
- if (f && FRAME_ICONIFIED_P (f))
- {
- SET_FRAME_VISIBLE (f, 1);
- SET_FRAME_ICONIFIED (f, false);
- f->output_data.x->has_been_visible = true;
- inev.ie.kind = DEICONIFY_EVENT;
- XSETFRAME (inev.ie.frame_or_window, f);
- }
+ That is fixed above but bites us here again.
+
+ The option x_set_frame_visibility_more_laxly allows to override
+ the default behavior (Bug#49955, Bug#53298). */
+ if (EQ (x_set_frame_visibility_more_laxly, Qfocus_in)
+ || EQ (x_set_frame_visibility_more_laxly, Qt))
#endif /* USE_GTK */
+ {
+ f = any;
+ if (f && FRAME_ICONIFIED_P (f))
+ {
+ SET_FRAME_VISIBLE (f, 1);
+ SET_FRAME_ICONIFIED (f, false);
+ f->output_data.x->has_been_visible = true;
+ inev.ie.kind = DEICONIFY_EVENT;
+ XSETFRAME (inev.ie.frame_or_window, f);
+ }
+ }
x_detect_focus_change (dpyinfo, any, event, &inev.ie);
goto OTHER;
@@ -10194,26 +10240,33 @@ handle_one_xevent (struct x_display_info *dpyinfo,
{
case XI_FocusIn:
any = x_any_window_to_frame (dpyinfo, focusin->event);
-#ifndef USE_GTK
+#ifdef USE_GTK
/* Some WMs (e.g. Mutter in Gnome Shell), don't unmap
minimized/iconified windows; thus, for those WMs we won't get
- a MapNotify when unminimizing/deconifying. Check here if we
+ a MapNotify when unminimizing/deiconifying. Check here if we
are deiconizing a window (Bug42655).
- But don't do that on GTK since it may cause a plain invisible
- frame get reported as iconified, compare
+ But don't do that by default on GTK since it may cause a plain
+ invisible frame get reported as iconified, compare
https://lists.gnu.org/archive/html/emacs-devel/2017-02/msg00133.html.
- That is fixed above but bites us here again. */
- f = any;
- if (f && FRAME_ICONIFIED_P (f))
+ That is fixed above but bites us here again.
+
+ The option x_set_frame_visibility_more_laxly allows to override
+ the default behavior (Bug#49955, Bug#53298). */
+ if (EQ (x_set_frame_visibility_more_laxly, Qfocus_in)
+ || EQ (x_set_frame_visibility_more_laxly, Qt))
+#endif /* USE_GTK */
{
- SET_FRAME_VISIBLE (f, 1);
- SET_FRAME_ICONIFIED (f, false);
- f->output_data.x->has_been_visible = true;
- inev.ie.kind = DEICONIFY_EVENT;
- XSETFRAME (inev.ie.frame_or_window, f);
+ f = any;
+ if (f && FRAME_ICONIFIED_P (f))
+ {
+ SET_FRAME_VISIBLE (f, 1);
+ SET_FRAME_ICONIFIED (f, false);
+ f->output_data.x->has_been_visible = true;
+ inev.ie.kind = DEICONIFY_EVENT;
+ XSETFRAME (inev.ie.frame_or_window, f);
+ }
}
-#endif /* USE_GTK */
x_detect_focus_change (dpyinfo, any, event, &inev.ie);
goto XI_OTHER;
case XI_FocusOut:
@@ -10708,7 +10761,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
if (f && xev->evtype == XI_ButtonPress
&& !popup_activated ()
- && !x_window_to_scroll_bar (xev->display, xev->event, 2)
+ && !x_window_to_scroll_bar (dpyinfo->display, xev->event, 2)
&& !FRAME_NO_ACCEPT_FOCUS (f))
{
/* When clicking into a child frame or when clicking
@@ -10881,7 +10934,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
xkey.type = KeyPress;
xkey.serial = xev->serial;
xkey.send_event = xev->send_event;
- xkey.display = xev->display;
+ xkey.display = dpyinfo->display;
xkey.window = xev->event;
xkey.root = xev->root;
xkey.subwindow = xev->child;
@@ -11227,7 +11280,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
xkey.type = KeyRelease;
xkey.serial = xev->serial;
xkey.send_event = xev->send_event;
- xkey.display = xev->display;
+ xkey.display = dpyinfo->display;
xkey.window = xev->event;
xkey.root = xev->root;
xkey.subwindow = xev->child;
@@ -11523,8 +11576,6 @@ handle_one_xevent (struct x_display_info *dpyinfo,
XkbFreeKeyboard (dpyinfo->xkb_desc, XkbAllComponentsMask, True);
dpyinfo->xkb_desc = NULL;
}
-
- x_find_modifier_meanings (dpyinfo);
}
else
{
@@ -11542,6 +11593,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
}
XkbRefreshKeyboardMapping (&xkbevent->map);
+ x_find_modifier_meanings (dpyinfo);
}
}
#endif
@@ -12698,9 +12750,11 @@ xim_initialize (struct x_display_info *dpyinfo, char *resource_name)
ret = XRegisterIMInstantiateCallback
(dpyinfo->display, dpyinfo->rdb, 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);
+ /* This is XPointer in XFree86 but (XPointer *) on Tru64, at
+ least, but the configure test doesn't work because
+ xim_instantiate_callback can either be XIMProc or
+ XIDProc, so just cast to void *. */
+ (void *) xim_inst);
eassert (ret == True);
#else /* not HAVE_X11R6_XIM */
xim_open_dpy (dpyinfo, resource_name);
@@ -12725,8 +12779,7 @@ xim_close_dpy (struct x_display_info *dpyinfo)
{
Bool ret = XUnregisterIMInstantiateCallback
(dpyinfo->display, dpyinfo->rdb, xim_inst->resource_name,
- emacs_class, xim_instantiate_callback,
- (XRegisterIMInstantiateCallback_arg6) xim_inst);
+ emacs_class, xim_instantiate_callback, (void *) xim_inst);
eassert (ret == True);
}
xfree (xim_inst->resource_name);
@@ -15261,6 +15314,40 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
dpyinfo->supports_xdbe = true;
#endif
+#ifdef USE_XCB
+ xcb_screen_t *xcb_screen = NULL;
+ xcb_screen_iterator_t iter;
+ xcb_visualid_t wanted = { XVisualIDFromVisual (dpyinfo->visual) };
+ xcb_depth_iterator_t depth_iter;
+ xcb_visualtype_iterator_t visual_iter;
+
+ int screen = DefaultScreen (dpyinfo->display);
+
+ iter = xcb_setup_roots_iterator (xcb_get_setup (dpyinfo->xcb_connection));
+ for (; iter.rem; --screen, xcb_screen_next (&iter))
+ {
+ if (!screen)
+ xcb_screen = iter.data;
+ }
+
+ if (xcb_screen)
+ {
+ depth_iter = xcb_screen_allowed_depths_iterator (xcb_screen);
+ for (; depth_iter.rem; xcb_depth_next (&depth_iter))
+ {
+ visual_iter = xcb_depth_visuals_iterator (depth_iter.data);
+ for (; visual_iter.rem; xcb_visualtype_next (&visual_iter))
+ {
+ if (wanted == visual_iter.data->visual_id)
+ {
+ dpyinfo->xcb_visual = visual_iter.data;
+ break;
+ }
+ }
+ }
+ }
+#endif
+
#ifdef HAVE_XINPUT2
dpyinfo->supports_xi2 = false;
int rc;
@@ -15329,9 +15416,19 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
XkbNewKeyboardNotifyMask | XkbMapNotifyMask,
XkbNewKeyboardNotifyMask | XkbMapNotifyMask);
}
+#endif
- /* Figure out which modifier bits mean what. */
- x_find_modifier_meanings (dpyinfo);
+#ifdef HAVE_XRENDER
+ int event_base, error_base;
+ dpyinfo->xrender_supported_p
+ = XRenderQueryExtension (dpyinfo->display, &event_base, &error_base);
+
+ if (dpyinfo->xrender_supported_p)
+ {
+ if (!XRenderQueryVersion (dpyinfo->display, &dpyinfo->xrender_major,
+ &dpyinfo->xrender_minor))
+ dpyinfo->xrender_supported_p = false;
+ }
#endif
#if defined USE_CAIRO || defined HAVE_XFT
@@ -15350,11 +15447,6 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
or larger than other for other applications, even if it is the same
font name (monospace-10 for example). */
-# ifdef HAVE_XRENDER
- int event_base, error_base;
- XRenderQueryExtension (dpyinfo->display, &event_base, &error_base);
-# endif
-
char *v = XGetDefault (dpyinfo->display, "Xft", "dpi");
double d;
if (v != NULL && sscanf (v, "%lf", &d) == 1)
@@ -15447,6 +15539,13 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
ATOM_REFS_INIT ("_NET_WM_STATE_SKIP_TASKBAR", Xatom_net_wm_state_skip_taskbar)
ATOM_REFS_INIT ("_NET_WM_STATE_ABOVE", Xatom_net_wm_state_above)
ATOM_REFS_INIT ("_NET_WM_STATE_BELOW", Xatom_net_wm_state_below)
+#ifdef HAVE_XKB
+ ATOM_REFS_INIT ("Meta", Xatom_Meta)
+ ATOM_REFS_INIT ("Super", Xatom_Super)
+ ATOM_REFS_INIT ("Hyper", Xatom_Hyper)
+ ATOM_REFS_INIT ("ShiftLock", Xatom_ShiftLock)
+ ATOM_REFS_INIT ("Alt", Xatom_Alt)
+#endif
};
int i;
@@ -15477,6 +15576,11 @@ x_term_init (Lisp_Object display_name, char *xrm_option, char *resource_name)
dpyinfo->Xatom_xsettings_sel = atoms_return[i];
}
+#ifdef HAVE_XKB
+ /* Figure out which modifier bits mean what. */
+ x_find_modifier_meanings (dpyinfo);
+#endif
+
dpyinfo->x_dnd_atoms_size = 8;
dpyinfo->x_dnd_atoms = xmalloc (sizeof *dpyinfo->x_dnd_atoms
* dpyinfo->x_dnd_atoms_size);
@@ -16128,6 +16232,7 @@ always uses gtk_window_move and ignores the value of this variable. */);
This option is only effective when Emacs is built with XInput 2
support. */);
Vx_scroll_event_delta_factor = make_float (1.0);
+ DEFSYM (Qexpose, "expose");
DEFVAR_BOOL ("x-gtk-use-native-input", x_gtk_use_native_input,
doc: /* Non-nil means to use GTK for input method support.
@@ -16135,6 +16240,21 @@ This provides better support for some modern input methods, and is
only effective when Emacs is built with GTK. */);
x_gtk_use_native_input = false;
+ DEFVAR_LISP ("x-set-frame-visibility-more-laxly",
+ x_set_frame_visibility_more_laxly,
+ doc: /* Non-nil means set frame visibility more laxly.
+If this is nil, Emacs is more strict when marking a frame as visible.
+Since this may cause problems on some window managers, this variable can
+be also set as follows: The value `focus-in' means to mark a frame as
+visible also when a FocusIn event is received for it on GTK builds. The
+value `expose' means to mark a frame as visible also when an Expose
+event is received for it on any X build. The value `t' means to mark a
+frame as visible in either of these two cases.
+
+Note that any non-nil setting may cause invisible frames get erroneously
+reported as iconified. */);
+ x_set_frame_visibility_more_laxly = Qnil;
+
DEFVAR_BOOL ("x-input-grab-touch-events", x_input_grab_touch_events,
doc: /* Non-nil means to actively grab touch events.
This means touch sequences that started on an Emacs frame will