summaryrefslogtreecommitdiffstats
path: root/pkgs/simple/mpvterm/mpvterm.patch
blob: 12636880dcef0d976c923797e46d1d8b5442dc0b (plain)
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
139
140
141
142
143
144
145
146
commit 5ded4dac370ce5d8d727c5d3891448f942edbfdf
Author: tv <tv@krebsco.de>
Date:   Sat Feb 27 22:54:55 2021 +0100

    x11: add input forwarding support

diff --git a/video/out/x11_common.c b/video/out/x11_common.c
index ac551fae8e..2e95451d7f 100644
--- a/video/out/x11_common.c
+++ b/video/out/x11_common.c
@@ -25,6 +25,10 @@
 #include <string.h>
 #include <assert.h>
 
+#include <stdarg.h>
+#include <sys/socket.h>
+#include <sys/un.h>
+
 #include <X11/Xmd.h>
 #include <X11/Xlib.h>
 #include <X11/Xutil.h>
@@ -1097,6 +1101,73 @@ static void release_all_keys(struct vo *vo)
     x11->win_drag_button1_down = false;
 }
 
+
+#define FORWARD_START 1
+#define FORWARD_READY 2
+#define FORWARD_ERROR 3
+static int forward_state = FORWARD_START;
+static int forward_fd, forward_len;
+static struct sockaddr_un forward_un;
+static char forward_buf[BUFSIZ];
+
+static void forward_start(void) {
+  const char *socket_path = getenv("FORWARD_SOCKET");
+  if (socket_path == NULL) {
+    fprintf(stderr, "forward_start: environment variable FORWARD_SOCKET not set\n");
+    forward_state = FORWARD_ERROR;
+    return;
+  }
+
+  if ((forward_fd = socket(AF_UNIX, SOCK_DGRAM, 0)) < 0) {
+    perror("socket");
+  } else {
+    memset(&forward_un, 0, sizeof(forward_un));
+    forward_un.sun_family = AF_UNIX;
+    strcpy(forward_un.sun_path, socket_path);
+    forward_len = offsetof(struct sockaddr_un, sun_path) + strlen(socket_path);
+    forward_state = FORWARD_READY;
+  }
+}
+static void forward_send(const char *fmt, ...) {
+  if (forward_state != FORWARD_READY) return;
+
+  va_list argp;
+  va_start(argp, fmt);
+  int n1 = vsnprintf(forward_buf, BUFSIZ, fmt, argp);
+  if (n1 < BUFSIZ + 1) {
+    forward_buf[n1++] = '\n';
+    forward_buf[n1] = '\0';
+    int n2 = sendto(forward_fd, forward_buf, n1, 0, (struct sockaddr *)&forward_un, forward_len);
+    if (n2 < 0) {
+      perror("sendto");
+    }
+  }
+}
+static const char *forward_keyname(KeySym keySym) {
+  const char *name;
+  if (keySym == NoSymbol) {
+    name = "NoSymbol";
+  } else if (!(name = XKeysymToString(keySym))) {
+    name = "NoName";
+  }
+  return name;
+}
+static void forward_keydown(KeySym keySym) {
+  forward_send("xdotool keydown %s", forward_keyname(keySym));
+}
+static void forward_keyup(KeySym keySym) {
+  forward_send("xdotool keyup %s", forward_keyname(keySym));
+}
+static void forward_mousedown(int button) {
+  forward_send("xdotool mousedown %d", button);
+}
+static void forward_mouseup(int button) {
+  forward_send("xdotool mouseup %d", button);
+}
+static void forward_mousemove(int x, int y) {
+  forward_send("xdotool mousemove %d %d", x, y);
+}
+
 void vo_x11_check_events(struct vo *vo)
 {
     struct vo_x11_state *x11 = vo->x11;
@@ -1105,6 +1176,10 @@ void vo_x11_check_events(struct vo *vo)
 
     xscreensaver_heartbeat(vo->x11);
 
+    if (forward_state == FORWARD_START) {
+      forward_start();
+    }
+
     while (XPending(display)) {
         XNextEvent(display, &Event);
         MP_TRACE(x11, "XEvent: %d\n", Event.type);
@@ -1146,6 +1221,7 @@ void vo_x11_check_events(struct vo *vo)
                 if (mpkey)
                     mp_input_put_key(x11->input_ctx, mpkey | modifiers);
             }
+            forward_keydown(XLookupKeysym(&Event.xkey, 0));
             break;
         }
         case FocusIn:
@@ -1161,6 +1237,7 @@ void vo_x11_check_events(struct vo *vo)
             break;
         case KeyRelease:
             release_all_keys(vo);
+            forward_keyup(XLookupKeysym(&Event.xkey, 0));
             break;
         case MotionNotify:
             if (x11->win_drag_button1_down && !x11->fs &&
@@ -1182,6 +1259,7 @@ void vo_x11_check_events(struct vo *vo)
                                                        Event.xmotion.y);
             }
             x11->win_drag_button1_down = false;
+            forward_mousemove(Event.xmotion.x, Event.xmotion.y);
             break;
         case LeaveNotify:
             if (Event.xcrossing.mode != NotifyNormal)
@@ -1204,6 +1282,7 @@ void vo_x11_check_events(struct vo *vo)
                              get_mods(Event.xbutton.state) | MP_KEY_STATE_DOWN);
             long msg[4] = {XEMBED_REQUEST_FOCUS};
             vo_x11_xembed_send_message(x11, msg);
+            forward_mousedown(Event.xbutton.button);
             break;
         case ButtonRelease:
             if (Event.xbutton.button - 1 >= MP_KEY_MOUSE_BTN_COUNT)
@@ -1213,6 +1292,7 @@ void vo_x11_check_events(struct vo *vo)
             mp_input_put_key(x11->input_ctx,
                              (MP_MBTN_BASE + Event.xbutton.button - 1) |
                              get_mods(Event.xbutton.state) | MP_KEY_STATE_UP);
+            forward_mouseup(Event.xbutton.button);
             break;
         case MapNotify:
             x11->window_hidden = false;