AC_SUBST(XINPUT_CFLAGS)
AC_SUBST(XINPUT_LIBS)
+XSYNC_LIBS=
+XSYNC_CFLAGS=
+HAVE_XSYNC=no
+if test "${HAVE_X11}" = "yes"; then
+ AC_CHECK_HEADER(X11/extensions/sync.h,
+ AC_CHECK_LIB(Xext, XSyncQueryExtension, HAVE_XSYNC=yes),
+ [], [#include <X11/Xlib.h>])
+
+ if test "${HAVE_XSYNC}" = "yes"; then
+ AC_DEFINE(HAVE_XSYNC, 1, [Define to 1 if the X Synchronization Extension is available.])
+ XSYNC_LIBS="-lXext"
+ fi
+fi
+AC_SUBST(XSYNC_LIBS)
+AC_SUBST(XSYNC_CFLAGS)
+
### Use Xdbe (-lXdbe) if available
HAVE_XDBE=no
if test "${HAVE_X11}" = "yes"; then
XINPUT_LIBS = @XINPUT_LIBS@
XINPUT_CFLAGS = @XINPUT_CFLAGS@
+XSYNC_LIBS = @XSYNC_LIBS@
+XSYNC_CFLAGS = @XSYNC_CFLAGS@
+
XDBE_LIBS = @XDBE_LIBS@
XDBE_CFLAGS = @XDBE_CFLAGS@
$(XINPUT_CFLAGS) $(WEBP_CFLAGS) $(WEBKIT_CFLAGS) $(LCMS2_CFLAGS) \
$(SETTINGS_CFLAGS) $(FREETYPE_CFLAGS) $(FONTCONFIG_CFLAGS) \
$(HARFBUZZ_CFLAGS) $(LIBOTF_CFLAGS) $(M17N_FLT_CFLAGS) $(DEPFLAGS) \
- $(LIBSYSTEMD_CFLAGS) $(JSON_CFLAGS) \
+ $(LIBSYSTEMD_CFLAGS) $(JSON_CFLAGS) $(XSYNC_CFLAGS) \
$(LIBGNUTLS_CFLAGS) $(NOTIFY_CFLAGS) $(CAIRO_CFLAGS) \
$(WERROR_CFLAGS) $(HAIKU_CFLAGS)
ALL_CFLAGS = $(EMACS_CFLAGS) $(WARN_CFLAGS) $(CFLAGS)
$(WEBKIT_LIBS) \
$(LIB_EACCESS) $(LIB_TIMER_TIME) $(DBUS_LIBS) \
$(LIB_EXECINFO) $(XRANDR_LIBS) $(XINERAMA_LIBS) $(XFIXES_LIBS) \
- $(XDBE_LIBS) \
+ $(XDBE_LIBS) $(XSYNC_LIBS) \
$(LIBXML2_LIBS) $(LIBGPM) $(LIBS_SYSTEM) $(CAIRO_LIBS) \
$(LIBS_TERMCAP) $(GETLOADAVG_LIBS) $(SETTINGS_LIBS) $(LIBSELINUX_LIBS) \
$(FREETYPE_LIBS) $(FONTCONFIG_LIBS) $(HARFBUZZ_LIBS) $(LIBOTF_LIBS) $(M17N_FLT_LIBS) \
Atom protos[10];
int num_protos = 0;
bool found_wm_ping = false;
+#if !defined HAVE_GTK3 && defined HAVE_XSYNC
+ bool found_wm_sync_request = false;
+#endif
unsigned long bytes_after;
block_input ();
if (existing_protocols[nitems]
== dpyinfo->Xatom_net_wm_ping)
found_wm_ping = true;
+#if !defined HAVE_GTK3 && defined HAVE_XSYNC
+ else if (existing_protocols[nitems]
+ == dpyinfo->Xatom_net_wm_sync_request)
+ found_wm_sync_request = true;
+#endif
}
}
if (!found_wm_ping)
protos[num_protos++] = dpyinfo->Xatom_net_wm_ping;
+#if !defined HAVE_GTK3 && defined HAVE_XSYNC
+ if (!found_wm_sync_request)
+ protos[num_protos++] = dpyinfo->Xatom_net_wm_sync_request;
+#endif
if (num_protos)
XChangeProperty (dpyinfo->display,
FRAME_X_VISUAL (f),
attribute_mask, &attributes);
initial_set_up_x_back_buffer (f);
- append_wm_protocols (FRAME_DISPLAY_INFO (f), f);
#ifdef HAVE_X_I18N
if (use_xim)
XSetWMProtocols (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f), protocols, 2);
}
+ append_wm_protocols (FRAME_DISPLAY_INFO (f), f);
+
/* x_set_name normally ignores requests to set the name if the
requested name is the same as the current name. This is the one
place where that assumption isn't correct; f->name is set, but
(unsigned char *) &dpyinfo->client_leader_window, 1);
}
+#ifdef HAVE_XSYNC
+ if (dpyinfo->xsync_supported_p)
+ {
+#ifndef HAVE_GTK3
+ XSyncValue initial_value;
+
+ XSyncIntToValue (&initial_value, 0);
+ FRAME_X_BASIC_COUNTER (f) = XSyncCreateCounter (FRAME_X_DISPLAY (f),
+ initial_value);
+
+ XChangeProperty (FRAME_X_DISPLAY (f), FRAME_OUTER_WINDOW (f),
+ dpyinfo->Xatom_net_wm_sync_request_counter,
+ XA_CARDINAL, 32, PropModeReplace,
+ (unsigned char *) &FRAME_X_BASIC_COUNTER (f), 1);
+#endif
+ }
+#endif
+
unblock_input ();
/* Works iff frame has been already mapped. */
#include <X11/extensions/Xrandr.h>
#endif
+#ifdef HAVE_XSYNC
+#include <X11/extensions/sync.h>
+#endif
+
/* Load sys/types.h if not already loaded.
In some systems loading it twice is suicidal. */
#ifndef makedev
FRAME_MOUSE_UPDATE (f);
if (!buffer_flipping_blocked_p () && FRAME_X_NEED_BUFFER_FLIP (f))
show_back_buffer (f);
+
+#ifdef HAVE_XSYNC
+ if (FRAME_X_OUTPUT (f)->sync_end_pending_p
+ && FRAME_X_BASIC_COUNTER (f))
+ {
+ XSyncSetCounter (FRAME_X_DISPLAY (f),
+ FRAME_X_BASIC_COUNTER (f),
+ FRAME_X_OUTPUT (f)->pending_basic_counter_value);
+ FRAME_X_OUTPUT (f)->sync_end_pending_p = false;
+ }
+#endif
unblock_input ();
}
goto done;
}
+#if defined HAVE_XSYNC && !defined HAVE_GTK3
+ if (event->xclient.data.l[0] == dpyinfo->Xatom_net_wm_sync_request
+ && event->xclient.format == 32)
+ {
+ struct frame *f
+ = x_top_window_to_frame (dpyinfo,
+ event->xclient.window);
+
+ if (f)
+ {
+ XSyncIntsToValue (&FRAME_X_OUTPUT (f)->pending_basic_counter_value,
+ event->xclient.data.l[2], event->xclient.data.l[3]);
+ FRAME_X_OUTPUT (f)->sync_end_pending_p = true;
+
+ *finish = X_EVENT_DROP;
+ goto done;
+ }
+ }
+#endif
+
goto done;
}
tear_down_x_back_buffer (f);
if (FRAME_X_WINDOW (f))
- XDestroyWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
+ XDestroyWindow (FRAME_X_DISPLAY (f), FRAME_X_WINDOW (f));
#endif /* !USE_X_TOOLKIT */
+#ifdef HAVE_XSYNC
+ if (FRAME_X_BASIC_COUNTER (f))
+ XSyncDestroyCounter (FRAME_X_DISPLAY (f),
+ FRAME_X_BASIC_COUNTER (f));
+#endif
+
unload_color (f, FRAME_FOREGROUND_PIXEL (f));
unload_color (f, FRAME_BACKGROUND_PIXEL (f));
unload_color (f, f->output_data.x->cursor_pixel);
}
#endif
+#ifdef HAVE_XSYNC
+ int xsync_event_base, xsync_error_base;
+ dpyinfo->xsync_supported_p
+ = XSyncQueryExtension (dpyinfo->display,
+ &xsync_event_base,
+ &xsync_error_base);
+
+ if (dpyinfo->xsync_supported_p)
+ dpyinfo->xsync_supported_p = XSyncInitialize (dpyinfo->display,
+ &dpyinfo->xsync_major,
+ &dpyinfo->xsync_minor);
+#endif
+
/* See if a private colormap is requested. */
if (dpyinfo->visual == DefaultVisualOfScreen (dpyinfo->screen))
{
ATOM_REFS_INIT ("ATOM", Xatom_ATOM)
ATOM_REFS_INIT ("ATOM_PAIR", Xatom_ATOM_PAIR)
ATOM_REFS_INIT ("CLIPBOARD_MANAGER", Xatom_CLIPBOARD_MANAGER)
+ ATOM_REFS_INIT ("XATOM_COUNTER", Xatom_XEMBED_INFO)
ATOM_REFS_INIT ("_XEMBED_INFO", Xatom_XEMBED_INFO)
/* For properties of font. */
ATOM_REFS_INIT ("PIXEL_SIZE", Xatom_PIXEL_SIZE)
ATOM_REFS_INIT ("_NET_FRAME_EXTENTS", Xatom_net_frame_extents)
ATOM_REFS_INIT ("_NET_CURRENT_DESKTOP", Xatom_net_current_desktop)
ATOM_REFS_INIT ("_NET_WORKAREA", Xatom_net_workarea)
+ ATOM_REFS_INIT ("_NET_WM_SYNC_REQUEST", Xatom_net_wm_sync_request)
+ ATOM_REFS_INIT ("_NET_WM_SYNC_REQUEST_COUNTER", Xatom_net_wm_sync_request_counter)
/* Session management */
ATOM_REFS_INIT ("SM_CLIENT_ID", Xatom_SM_CLIENT_ID)
ATOM_REFS_INIT ("_XSETTINGS_SETTINGS", Xatom_xsettings_prop)
#include <X11/XKBlib.h>
#endif
+#ifdef HAVE_XSYNC
+#include <X11/extensions/sync.h>
+#endif
+
#include "dispextern.h"
#include "termhooks.h"
/* More atoms, which are selection types. */
Atom Xatom_CLIPBOARD, Xatom_TIMESTAMP, Xatom_TEXT, Xatom_DELETE,
- Xatom_COMPOUND_TEXT, Xatom_UTF8_STRING,
- Xatom_MULTIPLE, Xatom_INCR, Xatom_EMACS_TMP, Xatom_TARGETS, Xatom_NULL,
- Xatom_ATOM, Xatom_ATOM_PAIR, Xatom_CLIPBOARD_MANAGER;
+ Xatom_COMPOUND_TEXT, Xatom_UTF8_STRING,
+ Xatom_MULTIPLE, Xatom_INCR, Xatom_EMACS_TMP, Xatom_TARGETS, Xatom_NULL,
+ Xatom_ATOM, Xatom_ATOM_PAIR, Xatom_CLIPBOARD_MANAGER, Xatom_COUNTER;
/* More atoms for font properties. The last three are private
properties, see the comments in src/fontset.h. */
Xatom_net_wm_state_sticky, Xatom_net_wm_state_above, Xatom_net_wm_state_below,
Xatom_net_wm_state_hidden, Xatom_net_wm_state_skip_taskbar,
Xatom_net_frame_extents, Xatom_net_current_desktop, Xatom_net_workarea,
- Xatom_net_wm_opaque_region, Xatom_net_wm_ping;
+ Xatom_net_wm_opaque_region, Xatom_net_wm_ping, Xatom_net_wm_sync_request,
+ Xatom_net_wm_sync_request_counter;
/* XSettings atoms and windows. */
Atom Xatom_xsettings_sel, Xatom_xsettings_prop, Xatom_xsettings_mgr;
int xfixes_major;
int xfixes_minor;
#endif
+
+#ifdef HAVE_XSYNC
+ bool xsync_supported_p;
+ int xsync_major;
+ int xsync_minor;
+#endif
};
#ifdef HAVE_X_I18N
XFontSet xic_xfs;
#endif
+#ifdef HAVE_XSYNC
+ XSyncCounter basic_frame_counter;
+ XSyncValue pending_basic_counter_value;
+
+ bool_bf sync_end_pending_p;
+#endif
+
/* Relief GCs, colors etc. */
struct relief
{
|| (FRAME_DISPLAY_INFO (f)->xrender_major > (major))))
#endif
+#ifdef HAVE_XSYNC
+#define FRAME_X_BASIC_COUNTER(f) FRAME_X_OUTPUT (f)->basic_frame_counter
+#endif
/* This is the Colormap which frame F uses. */
#define FRAME_X_COLORMAP(f) FRAME_DISPLAY_INFO (f)->cmap