wrong_choice (choice, new_value);
}
+#ifdef HAVE_XDBE
static void
x_set_inhibit_double_buffering (struct frame *f,
Lisp_Object new_value,
Lisp_Object old_value)
{
- block_input ();
+ bool want_double_buffering, was_double_buffered;
+
if (FRAME_X_WINDOW (f) && !EQ (new_value, old_value))
{
- bool want_double_buffering = NILP (new_value);
- bool was_double_buffered = FRAME_X_DOUBLE_BUFFERED_P (f);
- /* font_drop_xrender_surfaces in xftfont does something only if
- we're double-buffered, so call font_drop_xrender_surfaces before
- and after any potential change. One of the calls will end up
- being a no-op. */
+ want_double_buffering = NILP (new_value);
+ was_double_buffered = FRAME_X_DOUBLE_BUFFERED_P (f);
+
+ block_input ();
if (want_double_buffering != was_double_buffered)
{
+ /* Force XftDraw etc to be recreated with the new double
+ buffered drawable. */
font_drop_xrender_surfaces (f);
/* Scroll bars decide whether or not to use a back buffer
SET_FRAME_GARBAGED (f);
font_drop_xrender_surfaces (f);
}
+ unblock_input ();
}
- unblock_input ();
}
+#endif
/**
* x_set_undecorated:
void
x_mark_frame_dirty (struct frame *f)
{
- if (FRAME_X_DOUBLE_BUFFERED_P (f) && !FRAME_X_NEED_BUFFER_FLIP (f))
+#ifdef HAVE_XDBE
+ if (FRAME_X_DOUBLE_BUFFERED_P (f)
+ && !FRAME_X_NEED_BUFFER_FLIP (f))
FRAME_X_NEED_BUFFER_FLIP (f) = true;
+#endif
}
static void
void
initial_set_up_x_back_buffer (struct frame *f)
{
- block_input ();
eassert (FRAME_X_WINDOW (f));
FRAME_X_RAW_DRAWABLE (f) = FRAME_X_WINDOW (f);
- if (NILP (CDR (Fassq (Qinhibit_double_buffering, f->param_alist))))
+
+ if (NILP (CDR (Fassq (Qinhibit_double_buffering,
+ f->param_alist))))
set_up_x_back_buffer (f);
- unblock_input ();
}
#if defined HAVE_XINPUT2
(Lisp_Object frame)
{
struct frame *f = decode_live_frame (frame);
+
+#ifdef HAVE_XDBE
return FRAME_X_DOUBLE_BUFFERED_P (f) ? Qt : Qnil;
+#else
+ return Qnil;
+#endif
}
\f
gui_set_alpha,
x_set_sticky,
x_set_tool_bar_position,
+#ifdef HAVE_XDBE
x_set_inhibit_double_buffering,
+#else
+ NULL,
+#endif
x_set_undecorated,
x_set_parent_frame,
x_set_skip_taskbar,
return 0;
}
-/* When using X double buffering, the XftDraw structure we build
- seems to be useless once a frame is resized, so recreate it on
+/* When using X double buffering, the XRender surfaces we create seem
+ to become useless once the window acting as the front buffer is
+ resized for an unknown reason (X server bug?), so recreate it on
ConfigureNotify and in some other cases. */
+#ifdef HAVE_XDBE
static void
xftfont_drop_xrender_surfaces (struct frame *f)
{
- block_input ();
if (FRAME_X_DOUBLE_BUFFERED_P (f))
- xftfont_end_for_frame (f);
- unblock_input ();
+ {
+ block_input ();
+ xftfont_end_for_frame (f);
+ unblock_input ();
+ }
}
+#endif
static bool
xftfont_cached_font_ok (struct frame *f, Lisp_Object font_object,
struct font_driver const xftfont_driver =
{
/* We can't draw a text without device dependent functions. */
- .type = LISPSYM_INITIALLY (Qxft),
- .get_cache = xfont_get_cache,
- .list = xftfont_list,
- .match = xftfont_match,
- .list_family = ftfont_list_family,
- .open_font = xftfont_open,
- .close_font = xftfont_close,
- .prepare_face = xftfont_prepare_face,
- .done_face = xftfont_done_face,
- .has_char = xftfont_has_char,
- .encode_char = xftfont_encode_char,
- .text_extents = xftfont_text_extents,
- .draw = xftfont_draw,
- .get_bitmap = ftfont_get_bitmap,
- .anchor_point = ftfont_anchor_point,
+ .type = LISPSYM_INITIALLY (Qxft),
+ .get_cache = xfont_get_cache,
+ .list = xftfont_list,
+ .match = xftfont_match,
+ .list_family = ftfont_list_family,
+ .open_font = xftfont_open,
+ .close_font = xftfont_close,
+ .prepare_face = xftfont_prepare_face,
+ .done_face = xftfont_done_face,
+ .has_char = xftfont_has_char,
+ .encode_char = xftfont_encode_char,
+ .text_extents = xftfont_text_extents,
+ .draw = xftfont_draw,
+ .get_bitmap = ftfont_get_bitmap,
+ .anchor_point = ftfont_anchor_point,
#ifdef HAVE_LIBOTF
- .otf_capability = ftfont_otf_capability,
+ .otf_capability = ftfont_otf_capability,
#endif
- .end_for_frame = xftfont_end_for_frame,
+ .end_for_frame = xftfont_end_for_frame,
#if defined HAVE_M17N_FLT && defined HAVE_LIBOTF
- .shape = xftfont_shape,
+ .shape = xftfont_shape,
#endif
#if defined HAVE_OTF_GET_VARIATION_GLYPHS || defined HAVE_FT_FACE_GETCHARVARIANTINDEX
- .get_variation_glyphs = ftfont_variation_glyphs,
+ .get_variation_glyphs = ftfont_variation_glyphs,
+#endif
+ .filter_properties = ftfont_filter_properties,
+ .cached_font_ok = xftfont_cached_font_ok,
+ .combining_capability = ftfont_combining_capability,
+#ifdef HAVE_XDBE
+ .drop_xrender_surfaces = xftfont_drop_xrender_surfaces,
#endif
- .filter_properties = ftfont_filter_properties,
- .cached_font_ok = xftfont_cached_font_ok,
- .combining_capability = ftfont_combining_capability,
- .drop_xrender_surfaces = xftfont_drop_xrender_surfaces,
};
#ifdef HAVE_HARFBUZZ
struct font_driver xfthbfont_driver;
unblock_input ();
}
+#ifdef HAVE_XDBE
static void
x_drop_xrender_surfaces (struct frame *f)
{
}
#endif
}
+#endif
#ifdef HAVE_XRENDER
void
x_end_cr_clip (f);
#else
#ifndef USE_GTK
- if (FRAME_X_DOUBLE_BUFFERED_P (f) || (f->alpha_background != 1.0))
+ if (f->alpha_background != 1.0
+#ifdef HAVE_XDBE
+ || FRAME_X_DOUBLE_BUFFERED_P (f)
#endif
- x_clear_area (f, 0, 0, FRAME_PIXEL_WIDTH (f), FRAME_PIXEL_HEIGHT (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));
/* Show the frame back buffer. If frame is double-buffered,
atomically publish to the user's screen graphics updates made since
the last call to show_back_buffer. */
+
+#ifdef HAVE_XDBE
static void
show_back_buffer (struct frame *f)
{
block_input ();
+
if (FRAME_X_DOUBLE_BUFFERED_P (f))
{
-#ifdef HAVE_XDBE
#ifdef USE_CAIRO
cairo_t *cr = FRAME_CR_CONTEXT (f);
if (cr)
swap_info.swap_window = FRAME_X_WINDOW (f);
swap_info.swap_action = XdbeCopied;
XdbeSwapBuffers (FRAME_X_DISPLAY (f), &swap_info, 1);
-#else
- eassert (!"should have back-buffer only with XDBE");
-#endif
}
FRAME_X_NEED_BUFFER_FLIP (f) = false;
+
unblock_input ();
}
+#endif
/* Updates back buffer and flushes changes to display. Called from
minibuf read code. Note that we display the back buffer even if
x_flip_and_flush (struct frame *f)
{
block_input ();
+#ifdef HAVE_XDBE
if (FRAME_X_NEED_BUFFER_FLIP (f))
show_back_buffer (f);
+#endif
x_flush (f);
unblock_input ();
}
eassert (FRAME_X_P (f));
block_input ();
FRAME_MOUSE_UPDATE (f);
- if (!buffer_flipping_blocked_p () && FRAME_X_NEED_BUFFER_FLIP (f))
+
+#ifdef HAVE_XDBE
+ if (!buffer_flipping_blocked_p ()
+ && FRAME_X_NEED_BUFFER_FLIP (f))
show_back_buffer (f);
+#endif
#ifdef HAVE_XSYNC
#ifndef HAVE_GTK3
unblock_input ();
}
+#ifdef HAVE_XDBE
static void
XTbuffer_flipping_unblocked_hook (struct frame *f)
{
if (FRAME_X_NEED_BUFFER_FLIP (f))
show_back_buffer (f);
}
+#endif
/**
* x_clear_under_internal_border:
x_end_cr_clip (f);
#else
#ifndef USE_GTK
- if (FRAME_X_DOUBLE_BUFFERED_P (f)
- || f->alpha_background != 1.0)
+ if (f->alpha_background != 1.0
+#ifdef HAVE_XDBE
+ || FRAME_X_DOUBLE_BUFFERED_P (f)
+#endif
+ )
#endif
{
#if defined HAVE_XRENDER && \
store_frame_param (f, Qshaded, shaded ? Qt : Qnil);
}
-/* Flip back buffers on FRAME if it has undrawn content. */
+/* Flip back buffers on F if it has undrawn content. */
+
+#ifdef HAVE_XDBE
static void
flush_dirty_back_buffer_on (struct frame *f)
{
show_back_buffer (f);
unblock_input ();
}
+#endif
#ifdef HAVE_GTK3
void
SET_FRAME_ICONIFIED (f, false);
}
+#ifdef HAVE_XDBE
if (FRAME_X_DOUBLE_BUFFERED_P (f))
x_drop_xrender_surfaces (f);
+#endif
f->output_data.x->has_been_visible = true;
SET_FRAME_GARBAGED (f);
unblock_input ();
#endif
}
+#ifdef HAVE_XDBE
if (!FRAME_GARBAGED_P (f))
show_back_buffer (f);
+#endif
}
else
{
#ifdef USE_GTK
x_clear_under_internal_border (f);
#endif
+#ifdef HAVE_XDBE
show_back_buffer (f);
+#endif
}
#ifdef USE_X_TOOLKIT
else
for size changes: that's not sufficient. We miss some
surface invalidations and flicker. */
block_input ();
+#ifdef HAVE_XDBE
if (f && FRAME_X_DOUBLE_BUFFERED_P (f))
x_drop_xrender_surfaces (f);
+#endif
unblock_input ();
#if defined USE_CAIRO && !defined USE_GTK
if (f)
redisplay. To ensure that these changes become visible, draw
them here. */
+#ifdef HAVE_XDBE
if (f)
flush_dirty_back_buffer_on (f);
if (any && any != f)
flush_dirty_back_buffer_on (any);
+#endif
return count;
}
terminal->update_end_hook = x_update_end;
terminal->read_socket_hook = XTread_socket;
terminal->frame_up_to_date_hook = XTframe_up_to_date;
+#ifdef HAVE_XDBE
terminal->buffer_flipping_unblocked_hook = XTbuffer_flipping_unblocked_hook;
+#endif
terminal->defined_color_hook = x_defined_color;
terminal->query_frame_background_color = x_query_frame_background_color;
terminal->query_colors = x_query_colors;
code after any drawing command, but we can run code whenever
someone asks for the handle necessary to draw. */
#define FRAME_X_DRAWABLE(f) \
- (x_mark_frame_dirty((f)), FRAME_X_RAW_DRAWABLE ((f)))
+ (x_mark_frame_dirty ((f)), FRAME_X_RAW_DRAWABLE ((f)))
+#ifdef HAVE_XDBE
#define FRAME_X_DOUBLE_BUFFERED_P(f) \
(FRAME_X_WINDOW (f) != FRAME_X_RAW_DRAWABLE (f))
/* Return the need-buffer-flip flag for frame F. */
#define FRAME_X_NEED_BUFFER_FLIP(f) ((f)->output_data.x->need_buffer_flip)
+#endif
/* Return the outermost X window associated with the frame F. */
#ifdef USE_X_TOOLKIT