@ -489,6 +489,9 @@ win_build_shadow(session_t *ps, win *w, double opacity) {
w - > shadow_paint . pixmap = shadow_pixmap_argb ;
w - > shadow_paint . pict = shadow_picture_argb ;
// Sync it once and only once
xr_sync ( ps , w - > shadow_paint . pixmap , NULL ) ;
bool success = paint_bind_tex ( ps , & w - > shadow_paint , shadow_image - > width , shadow_image - > height , 32 , true ) ;
XFreeGC ( ps - > dpy , gc ) ;
@ -1513,12 +1516,16 @@ win_paint_win(session_t *ps, win *w, XserverRegion reg_paint,
if ( ! w - > paint . pixmap & & ps - > has_name_pixmap ) {
set_ignore_next ( ps ) ;
w - > paint . pixmap = XCompositeNameWindowPixmap ( ps - > dpy , w - > id ) ;
if ( w - > paint . pixmap )
free_fence ( ps , & w - > fence ) ;
}
Drawable draw = w - > paint . pixmap ;
if ( ! draw )
draw = w - > id ;
// XRender: Build picture
if ( bkend_use_xrender ( ps ) & & ! w - > paint . pict ) {
Drawable draw = w - > paint . pixmap ;
if ( ! draw )
draw = w - > id ;
{
XRenderPictureAttributes pa = {
. subwindow_mode = IncludeInferiors ,
@ -1528,6 +1535,10 @@ win_paint_win(session_t *ps, win *w, XserverRegion reg_paint,
CPSubwindowMode , & pa ) ;
}
}
if ( IsViewable = = w - > a . map_state )
xr_sync ( ps , draw , & w - > fence ) ;
// GLX: Build texture
// Let glx_bind_pixmap() determine pixmap size, because if the user
// is resizing windows, the width and height we get may not be up-to-date,
@ -1948,11 +1959,13 @@ paint_all(session_t *ps, XserverRegion region, XserverRegion region_real, win *t
else
glFlush ( ) ;
glXWaitX ( ) ;
assert ( ps - > tgt_buffer . pixmap ) ;
xr_sync ( ps , ps - > tgt_buffer . pixmap , & ps - > tgt_buffer_fence ) ;
paint_bind_tex_real ( ps , & ps - > tgt_buffer ,
ps - > root_width , ps - > root_height , ps - > depth ,
! ps - > o . glx_no_rebind_pixmap ) ;
// See #163
XSync( ps - > dpy , Fals e) ;
xr_sync( ps , ps - > tgt_buffer . pixmap , & ps - > tgt_buffer_fenc e) ;
if ( ps - > o . vsync_use_glfinish )
glFinish ( ) ;
else
@ -2116,7 +2129,7 @@ map_win(session_t *ps, Window id) {
}
// Make sure the XSelectInput() requests are sent
X Sync ( ps - > dpy , False ) ;
X Flush ( ps - > dpy ) ;
// Update window mode here to check for ARGB windows
win_determine_mode ( ps , w ) ;
@ -2205,7 +2218,7 @@ finish_unmap_win(session_t *ps, win *w) {
w - > extents = None ;
}
free_ paint( ps , & w - > paint ) ;
free_ w paint( ps , w ) ;
free_region ( ps , & w - > border_size ) ;
free_paint ( ps , & w - > shadow_paint ) ;
}
@ -2219,6 +2232,11 @@ static void
unmap_win ( session_t * ps , win * w ) {
if ( ! w | | IsUnmapped = = w - > a . map_state ) return ;
// One last synchronization
if ( w - > paint . pixmap )
xr_sync ( ps , w - > paint . pixmap , & w - > fence ) ;
free_fence ( ps , & w - > fence ) ;
// Set focus out
win_set_focused ( ps , w , false ) ;
@ -2654,7 +2672,7 @@ win_mark_client(session_t *ps, win *w, Window client) {
determine_evmask ( ps , client , WIN_EVMODE_CLIENT ) ) ;
// Make sure the XSelectInput() requests are sent
X Sync ( ps - > dpy , False ) ;
X Flush ( ps - > dpy ) ;
win_upd_wintype ( ps , w ) ;
@ -3037,7 +3055,7 @@ configure_win(session_t *ps, XConfigureEvent *ce) {
if ( w - > a . width ! = ce - > width | | w - > a . height ! = ce - > height
| | w - > a . border_width ! = ce - > border_width )
free_ paint( ps , & w - > paint ) ;
free_ w paint( ps , w ) ;
if ( w - > a . width ! = ce - > width | | w - > a . height ! = ce - > height
| | w - > a . border_width ! = ce - > border_width ) {
@ -3097,7 +3115,7 @@ finish_destroy_win(session_t *ps, Window id) {
for ( prev = & ps - > list ; ( w = * prev ) ; prev = & w - > next ) {
if ( w - > id = = id & & w - > destroyed ) {
# ifdef DEBUG_EVENTS
printf_dbgf ( " (%#010lx \" %s \" ): %p \n " , id , w - > name , w ) ;
printf_dbgf ( " (%#010lx \" %s \" ): %p \n " , id , w - > name , w ) ;
# endif
finish_unmap_win ( ps , w ) ;
@ -3188,10 +3206,10 @@ damage_win(session_t *ps, XDamageNotifyEvent *de) {
* Xlib error handler function .
*/
static int
error( Display __attribute__ ( ( unused ) ) * dpy , XErrorEvent * ev ) {
x error( Display __attribute__ ( ( unused ) ) * dpy , XErrorEvent * ev ) {
session_t * const ps = ps_g ;
int o ;
int o = 0 ;
const char * name = " Unknown " ;
if ( should_ignore ( ps , ev - > serial ) ) {
@ -3240,6 +3258,17 @@ error(Display __attribute__((unused)) *dpy, XErrorEvent *ev) {
}
# endif
# ifdef CONFIG_XSYNC
if ( ps - > xsync_exists ) {
o = ev - > error_code - ps - > xsync_error ;
switch ( o ) {
CASESTRRET2 ( XSyncBadCounter ) ;
CASESTRRET2 ( XSyncBadAlarm ) ;
CASESTRRET2 ( XSyncBadFence ) ;
}
}
# endif
switch ( ev - > error_code ) {
CASESTRRET2 ( BadAccess ) ;
CASESTRRET2 ( BadAlloc ) ;
@ -3771,18 +3800,27 @@ ev_name(session_t *ps, XEvent *ev) {
CASESTRRET ( Expose ) ;
CASESTRRET ( PropertyNotify ) ;
CASESTRRET ( ClientMessage ) ;
default :
if ( isdamagenotify ( ps , ev ) )
return " Damage " ;
}
if ( ps - > shape_exists & & ev - > type = = ps - > shape_event ) {
return " ShapeNotify " ;
}
if ( isdamagenotify ( ps , ev ) )
return " Damage " ;
sprintf ( buf , " Event %d " , ev - > type ) ;
if ( ps - > shape_exists & & ev - > type = = ps - > shape_event )
return " ShapeNotify " ;
return buf ;
# ifdef CONFIG_XSYNC
if ( ps - > xsync_exists ) {
int o = ev - > type - ps - > xsync_event ;
switch ( o ) {
CASESTRRET ( CounterNotify ) ;
CASESTRRET ( AlarmNotify ) ;
}
}
# endif
sprintf ( buf , " Event %d " , ev - > type ) ;
return buf ;
}
static Window
@ -5464,6 +5502,8 @@ get_cfg(session_t *ps, int argc, char *const *argv, bool first_pass) {
{ " unredir-if-possible-delay " , required_argument , NULL , 309 } ,
{ " write-pid-path " , required_argument , NULL , 310 } ,
{ " vsync-use-glfinish " , no_argument , NULL , 311 } ,
{ " xrender-sync " , no_argument , NULL , 312 } ,
{ " xrender-sync-fence " , no_argument , NULL , 313 } ,
// Must terminate with a NULL entry
{ NULL , 0 , NULL , 0 } ,
} ;
@ -5714,6 +5754,8 @@ get_cfg(session_t *ps, int argc, char *const *argv, bool first_pass) {
ps - > o . write_pid_path = mstrcpy ( optarg ) ;
break ;
P_CASEBOOL ( 311 , vsync_use_glfinish ) ;
P_CASEBOOL ( 312 , xrender_sync ) ;
P_CASEBOOL ( 313 , xrender_sync_fence ) ;
default :
usage ( 1 ) ;
break ;
@ -5761,6 +5803,9 @@ get_cfg(session_t *ps, int argc, char *const *argv, bool first_pass) {
if ( ps - > o . blur_background_frame )
ps - > o . blur_background = true ;
if ( ps - > o . xrender_sync_fence )
ps - > o . xrender_sync = true ;
// Other variables determined by options
// Determine whether we need to track focus changes
@ -6478,7 +6523,7 @@ redir_stop(session_t *ps) {
// If we don't destroy them here, looks like the resources are just
// kept inaccessible somehow
for ( win * w = ps - > list ; w ; w = w - > next )
free_ paint( ps , & w - > paint ) ;
free_ w paint( ps , w ) ;
XCompositeUnredirectSubwindows ( ps - > dpy , ps - > root , CompositeRedirectManual ) ;
// Unmap overlay window
@ -6852,7 +6897,7 @@ session_init(session_t *ps_old, int argc, char **argv) {
}
}
XSetErrorHandler ( error) ;
XSetErrorHandler ( x error) ;
if ( ps - > o . synchronize ) {
XSynchronize ( ps - > dpy , 1 ) ;
}
@ -6907,11 +6952,6 @@ session_init(session_t *ps_old, int argc, char **argv) {
exit ( 1 ) ;
}
// Query X Shape
if ( XShapeQueryExtension ( ps - > dpy , & ps - > shape_event , & ps - > shape_error ) ) {
ps - > shape_exists = true ;
}
// Build a safe representation of display name
{
char * display_repr = DisplayString ( ps - > dpy ) ;
@ -6936,6 +6976,32 @@ session_init(session_t *ps_old, int argc, char **argv) {
// Second pass
get_cfg ( ps , argc , argv , false ) ;
// Query X Shape
if ( XShapeQueryExtension ( ps - > dpy , & ps - > shape_event , & ps - > shape_error ) ) {
ps - > shape_exists = true ;
}
if ( ps - > o . xrender_sync_fence ) {
# ifdef CONFIG_XSYNC
// Query X Sync
if ( XSyncQueryExtension ( ps - > dpy , & ps - > xsync_event , & ps - > xsync_error ) ) {
// TODO: Fencing may require version >= 3.0?
int major_version_return = 0 , minor_version_return = 0 ;
if ( XSyncInitialize ( ps - > dpy , & major_version_return , & minor_version_return ) )
ps - > xsync_exists = true ;
}
if ( ! ps - > xsync_exists ) {
printf_errf ( " (): X Sync extension not found. No X Sync fence sync is "
" possible. " ) ;
exit ( 1 ) ;
}
# else
printf_errf ( " (): X Sync support not compiled in. --xrender-sync-fence "
" can't work. " ) ;
exit ( 1 ) ;
# endif
}
// Query X RandR
if ( ( ps - > o . sw_opti & & ! ps - > o . refresh_rate ) | | ps - > o . xinerama_shadow_crop ) {
if ( XRRQueryExtension ( ps - > dpy , & ps - > randr_event , & ps - > randr_error ) )
@ -7219,6 +7285,7 @@ session_destroy(session_t *ps) {
ps - > tgt_picture = None ;
else
free_picture ( ps , & ps - > tgt_picture ) ;
free_fence ( ps , & ps - > tgt_buffer_fence ) ;
free_picture ( ps , & ps - > root_picture ) ;
free_paint ( ps , & ps - > tgt_buffer ) ;