-
Notifications
You must be signed in to change notification settings - Fork 3
/
Copy pathxterm.c.26.2.patch
138 lines (135 loc) · 3.6 KB
/
xterm.c.26.2.patch
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
diff --git a/src/xterm.c b/src/xterm.c
index 3cadf69..eeba08a
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -240,4 +240,115 @@ static void x_initialize (void);
static bool 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
diff --git a/src/xterm.c b/src/xterm.c
index 3cadf69..eeba08a
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -13406,4 +13517,11 @@ gtk_window_move to set or store frame positions and disables some time
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);
+
}