unofficial mirror of bug-gnu-emacs@gnu.org 
 help / color / mirror / code / Atom feed
* bug#36362: New feature-x-check-server
@ 2019-06-24 17:05 otadmor .
  2019-06-27  9:57 ` bug#36362: Patch for the current 26.2 version otadmor .
                   ` (4 more replies)
  0 siblings, 5 replies; 16+ messages in thread
From: otadmor . @ 2019-06-24 17:05 UTC (permalink / raw)
  To: 36362


[-- Attachment #1.1: Type: text/plain, Size: 117 bytes --]

A new native method to check connectivity of xserver.

-- 
Gretz,
Ofir Tadmor

ICQ: 77685691
Mail: otadmor@gmail.com

[-- Attachment #1.2: Type: text/html, Size: 316 bytes --]

[-- Attachment #2: 0001-Add-x-check-frame-lisp-method-to-check-frame-x-serve.patch --]
[-- Type: application/octet-stream, Size: 3918 bytes --]

From 4449281873f139055fde82a8a55310a274c7e5a7 Mon Sep 17 00:00:00 2001
From: otadmor <otadmor@gmail.com>
Date: Mon, 24 Jun 2019 19:43:50 +0300
Subject: [PATCH] Add x-check-frame lisp method to check frame x-server's
 connection.

---
 src/xterm.c | 118 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 1 file changed, 118 insertions(+)

diff --git a/src/xterm.c b/src/xterm.c
index 1acff2af0d..01ff790831 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -235,6 +235,117 @@ #define XtNinitialState "initialState"
 
 static bool x_get_current_wm_state (struct frame *, Window, int *, bool *);
 
+
+#define CLOCKID CLOCK_REALTIME
+#define CONN_SIG (SIGRTMAX-1)
+#include <signal.h>
+#include "X11/Xlibint.h"
+
+static int connection_fd = -1;
+void
+connection_timeout_handler (int signum)
+{
+    if (connection_fd != -1) {
+        close(connection_fd);
+        connection_fd = -1;
+    }
+}
+Status
+XCheckConnection (
+    register Display *dpy,
+    Drawable d, int fd, double timeout)
+{
+
+    xGetGeometryReply rep;
+    register xResourceReq *req;
+    LockDisplay(dpy);
+    GetResReq(GetGeometry, d, req);
+    Status res = 0;
+
+    sigset_t origmask;
+    sigset_t sigmask;
+    sigemptyset(&sigmask);
+    pthread_sigmask(SIG_SETMASK, &sigmask, &origmask);
+
+    // Create the timer
+    timer_t timerid;
+    struct sigevent sev;
+    struct itimerspec its;
+    long long freq_nanosecs;
+
+    struct sigaction new_action, old_action;
+
+    new_action.sa_handler = connection_timeout_handler;
+    sigemptyset (&new_action.sa_mask);
+    new_action.sa_flags = 0;
+
+    sigaction (CONN_SIG, &new_action, &old_action);
+
+    sev.sigev_notify = SIGEV_SIGNAL;
+    sev.sigev_signo = CONN_SIG;
+    sev.sigev_value.sival_ptr = &timerid;
+    (void) timer_create(CLOCKID, &sev, &timerid);
+
+    freq_nanosecs  = (long long)(timeout * 1000000000);
+    its.it_value.tv_sec  = freq_nanosecs / 1000000000;
+    its.it_value.tv_nsec = freq_nanosecs % 1000000000;
+    its.it_interval.tv_sec = 0;
+    its.it_interval.tv_nsec = 0;
+
+    (void) timer_settime(timerid, 0, &its, NULL);
+    connection_fd = fd;
+
+    res = _XReply (dpy, (xReply *)&rep, 0, xTrue);
+
+    connection_fd = -1;
+    (void) timer_delete(timerid);
+    pthread_sigmask(SIG_SETMASK, &origmask, NULL);
+    sigaction (CONN_SIG, &old_action, NULL);
+
+    UnlockDisplay(dpy);
+    SyncHandle();
+    return (int)res;
+}
+
+int check_frame_connection(struct frame * frame, double timeout)
+{
+    block_input ();
+    int fd = ConnectionNumber (FRAME_X_DISPLAY (frame));
+    int res = XCheckConnection (
+        FRAME_X_DISPLAY (frame), FRAME_OUTER_WINDOW (frame), fd, timeout);
+    unblock_input ();
+    return res;
+}
+
+DEFUN ("x-check-frame", Fx_check_frame,
+       Sx_check_frame, 1, 1, 0,
+       doc: /* check the connection with the display of the given frame.  */)
+  (Lisp_Object f)
+{
+    if (!f)
+        return Qnil;
+
+    if (NILP (f))
+        return Qnil;
+
+    if (Fframep(f) != Qx)
+        return Qnil;
+
+    if (!FLOATP (Vx_check_frame_timeout))
+        return Qnil;
+
+    /* Default timeout is 0.5 second. This timeout will occur
+       only when the libx11 did not noticed the frame was
+       disconnected. */
+    double timeout = XFLOAT_DATA (Vx_check_frame_timeout);
+
+    struct frame *frame = XFRAME (f);
+    int ret = check_frame_connection (frame, timeout);
+    return ret ? Qt : Qnil;
+}
+
+
+
 /* Flush display of frame F.  */
 
 static void
@@ -13641,4 +13752,11 @@ syms_of_xterm (void)
 consuming frame position adjustments.  In newer versions of GTK, Emacs
 always uses gtk_window_move and ignores the value of this variable.  */);
   x_gtk_use_window_move = true;
+
+  defsubr (&Sx_check_frame);
+
+  DEFVAR_LISP ("x-check-frame-timeout", Vx_check_frame_timeout,
+    doc: /* How long to wait a display to response. */);
+  Vx_check_frame_timeout = make_float (0.5);
+
 }
-- 
2.17.1


^ permalink raw reply related	[flat|nested] 16+ messages in thread

end of thread, other threads:[~2022-02-12 11:17 UTC | newest]

Thread overview: 16+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2019-06-24 17:05 bug#36362: New feature-x-check-server otadmor .
2019-06-27  9:57 ` bug#36362: Patch for the current 26.2 version otadmor .
2019-06-27 15:10 ` bug#36362: New feature-x-check-server Noam Postavsky
2019-06-28  0:34 ` Noam Postavsky
2022-02-12  8:18   ` Lars Ingebrigtsen
2022-02-12  9:13     ` otadmor
2022-02-12  9:56       ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
2022-02-12 10:54         ` otadmor
2022-02-12 11:17           ` Po Lu via Bug reports for GNU Emacs, the Swiss army knife of text editors
2019-06-30 20:41 ` bug#36362: The elisp timer otadmor .
2019-07-30 19:54 ` bug#36362: Tag this report as bug otadmor .
2019-07-31  2:27   ` Eli Zaretskii
2019-07-31  7:01     ` otadmor .
2019-07-31 11:50       ` Noam Postavsky
2019-07-31 17:00         ` otadmor .
2019-07-31 17:18           ` Noam Postavsky

Code repositories for project(s) associated with this public inbox

	https://git.savannah.gnu.org/cgit/emacs.git

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).