From bd293398599beae694bd3f862c374489067a9f53 Mon Sep 17 00:00:00 2001 From: Sylvain BERTRAND Date: Fri, 29 May 2020 21:06:00 +0000 Subject: [PATCH] npv:x11/xcb screensaver heartbeat --- npv/TODO | 5 ++--- npv/local/code.frag.c | 26 +++++++++++++++++++++++--- npv/xcb/local/code.frag.c | 9 +++++++++ npv/xcb/local/state.frag.c | 2 ++ npv/xcb/public.h | 2 ++ npv/xcb/public/code.frag.c | 29 ++++++++++++++++++++++++++++- npv/xcb/public/state.frag.h | 5 +++++ 7 files changed, 71 insertions(+), 7 deletions(-) diff --git a/npv/TODO b/npv/TODO index 704af8e..67827cc 100644 --- a/npv/TODO +++ b/npv/TODO @@ -1,7 +1,6 @@ not ordered: -- disable the x11 screensaver, but we are more likely to go "manual gear" with a - separate command -- hide the mouse cursor or, if possible, a separate command for "manual gear"? +- hide the mouse cursor or, if possible, a separate command for "manual gear": + x11 xfixes4 protocol should have the required requests. - better/smoother/less drop/(correct?) video frame display strategy ? - xcb(resize)/vulkan swapchain loss or "not optimal" ? (state re-factoring) - x11 map/unmap handling to: diff --git a/npv/local/code.frag.c b/npv/local/code.frag.c index 57027b5..d51c520 100644 --- a/npv/local/code.frag.c +++ b/npv/local/code.frag.c @@ -154,6 +154,14 @@ static void evt_add_all_fds(void) r = epoll_ctl(ep_fd_p, EPOLL_CTL_ADD, audio_draining_timer_fd_p, &evt); if (r == -1) FATAL("unable to add the draining timer file descriptor\n"); + /*--------------------------------------------------------------------*/ + /* the xcb screensaver heartbeat timer */ + evt.events = EPOLLIN; + evt.data.fd = npv_xcb_p.screensaver_heartbeat_timer_fd; + r = epoll_ctl(ep_fd_p, EPOLL_CTL_ADD, + npv_xcb_p.screensaver_heartbeat_timer_fd, &evt); + if (r == -1) + FATAL("unable to add the xcb screensaver heartbeat timer file descriptor\n"); } /*NSPC*/ static void evt_sigs(void) @@ -178,7 +186,7 @@ static void evt_sigs(void) /*NSPC*/ static void evt_accumulate(struct epoll_event *evt, bool *have_evt_sigs, bool *have_evt_pcm, bool *have_evt_video, bool *have_evt_pcm_draining, - bool *have_evt_x11) + bool *have_evt_x11, bool *have_evt_xcb_screensaver_heartbeat) { u8 i; @@ -224,6 +232,14 @@ static void evt_accumulate(struct epoll_event *evt, bool *have_evt_sigs, } FATAL("event loop wait:audio draining timer:unexpected event\n"); } + /*-------------------------------------------------------------------*/ + if (evt->data.fd == npv_xcb_p.screensaver_heartbeat_timer_fd) { + if ((evt->events & EPOLLIN) != 0) { + *have_evt_xcb_screensaver_heartbeat = true; + return; + } + FATAL("event loop wait:xcb screensaver heartbeat timer:unexpected event\n"); + } } /* * XXX: remember that all heavy lifting should be done in other threads. @@ -242,6 +258,7 @@ static void evts_loop(void) bool have_evt_video; bool have_evt_pcm_draining; bool have_evt_x11; + bool have_evt_xcb_screensaver_heartbeat; int r; short pcm_evts; @@ -261,14 +278,15 @@ static void evts_loop(void) have_evt_video = false; have_evt_pcm_draining = false; have_evt_x11 = false; + have_evt_xcb_screensaver_heartbeat = false; fd_idx = 0; loop { if (fd_idx == fds_n) break; evt_accumulate(&evts[fd_idx], &have_evt_sigs, &have_evt_pcm, - &have_evt_video, &have_evt_pcm_draining, - &have_evt_x11); + &have_evt_video, &have_evt_pcm_draining, + &have_evt_x11,&have_evt_xcb_screensaver_heartbeat); ++fd_idx; } @@ -308,6 +326,8 @@ static void evts_loop(void) /* while audio is draining, video fr may need to be displayed */ if (have_evt_pcm_draining) audio_draining_state_evt(); + if (have_evt_xcb_screensaver_heartbeat) + npv_xcb_screensaver_heartbeat_timer_evt(); } #undef EPOLL_EVTS_N /*NSPC*/ diff --git a/npv/xcb/local/code.frag.c b/npv/xcb/local/code.frag.c index f690c3b..248c893 100644 --- a/npv/xcb/local/code.frag.c +++ b/npv/xcb/local/code.frag.c @@ -36,6 +36,7 @@ static void npv_xcb_syms(void) XCB_DLSYM(xcb_poll_for_event); XCB_DLSYM(xcb_change_property); XCB_DLSYM(xcb_disconnect); + XCB_DLSYM(xcb_force_screen_saver); } #undef XCB_DLSYM static void npv_xcb_win_create(void) @@ -211,3 +212,11 @@ static void npv_xcb_evt_handle(xcb_generic_event_t *evt) break; } } +static void npv_xcb_screensaver_heartbeat_timer_init_once(void) +{ + errno = 0; + npv_xcb_p.screensaver_heartbeat_timer_fd = timerfd_create( + CLOCK_MONOTONIC, TFD_NONBLOCK); + if (npv_xcb_p.screensaver_heartbeat_timer_fd == -1) + FATALX("unable to get a timer file descriptor for the screensaver heartbeat:%s\n", strerror(errno)); +} diff --git a/npv/xcb/local/state.frag.c b/npv/xcb/local/state.frag.c index 775869e..7d46901 100644 --- a/npv/xcb/local/state.frag.c +++ b/npv/xcb/local/state.frag.c @@ -25,3 +25,5 @@ static void (*dl_xcb_disconnect)(xcb_connection_t *c); static xcb_void_cookie_t (*dl_xcb_change_property)(xcb_connection_t *c, u8 mode, xcb_window_t window, xcb_atom_t property, xcb_atom_t type, u8 format, u32 data_len, void *data); +static xcb_void_cookie_t (*dl_xcb_force_screen_saver)(xcb_connection_t *c, + u8 mode); diff --git a/npv/xcb/public.h b/npv/xcb/public.h index b81d19e..12bef2f 100644 --- a/npv/xcb/public.h +++ b/npv/xcb/public.h @@ -11,4 +11,6 @@ /*----------------------------------------------------------------------------*/ static void npv_xcb_init_once(u16 width, u16 height); static void npv_xcb_evt(void); +static void npv_xcb_screensaver_heartbeat_timer_start(void); +static void npv_xcb_screensaver_heartbeat_timer_evt(void); #endif diff --git a/npv/xcb/public/code.frag.c b/npv/xcb/public/code.frag.c index ab98d1b..fc2a033 100644 --- a/npv/xcb/public/code.frag.c +++ b/npv/xcb/public/code.frag.c @@ -22,11 +22,38 @@ static void npv_xcb_init_once(u16 win_width, u16 win_height) npv_xcb_connect(); npv_xcb_scr_get(); + npv_xcb_screensaver_heartbeat_timer_init_once(); npv_xcb_win_create(); - //npv_xcb_wm_hints(); +#if 0 + npv_xcb_wm_hints(); +#endif r = dl_xcb_flush(npv_xcb_p.c); if (r <= 0) FATALX("%d:xcb:'%s':connection:%p:screen:%d:root window id:%#x:window id:%#x:unable to flush the connection\n", r, npv_xcb_p.disp_env, npv_xcb_p.c, npv_xcb_p.scr_idx, npv_xcb_p.scr->root, npv_xcb_p.win_id); POUTX("'%s':connection:%p:connection flushed\n", npv_xcb_p.disp_env, npv_xcb_p.c); } +static void npv_xcb_screensaver_heartbeat_timer_start(void) +{ + struct itimerspec t; + int r; + + memset(&t, 0, sizeof(t)); + t.it_interval.tv_sec = npv_xcb_screensaver_heartbeat_timeout_s; + r = timerfd_settime(npv_xcb_p.screensaver_heartbeat_timer_fd, 0, &t, 0); + if (r == -1) + FATALX("unable to arm the screensaver heartbeat timer to %u seconds\n", npv_xcb_screensaver_heartbeat_timeout_s); +} +static void npv_xcb_screensaver_heartbeat_timer_evt(void) +{ + int r; + uint64_t exps_n; + + exps_n = 0; + r = read(npv_xcb_p.screensaver_heartbeat_timer_fd, &exps_n, + sizeof(exps_n)); + if (r == -1) + FATALX("unable to read the number of timer expirations related to the xcb screensaver heartbeat\n"); + if (!npv_paused_p) + xcb_force_screen_saver(npv_xcb_p.c, XCB_SCREEN_SAVER_RESET); +} diff --git a/npv/xcb/public/state.frag.h b/npv/xcb/public/state.frag.h index c7d7b1f..e31f109 100644 --- a/npv/xcb/public/state.frag.h +++ b/npv/xcb/public/state.frag.h @@ -1,3 +1,6 @@ +constant_u32 { + npv_xcb_screensaver_heartbeat_timeout_s = 30 +}; static struct { u8 *disp_env; xcb_connection_t *c; @@ -8,4 +11,6 @@ static struct { u32 win_id; u16 width; u16 height; + + int screensaver_heartbeat_timer_fd; } npv_xcb_p; -- 2.11.4.GIT