1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17 #define _GNU_SOURCE
18 #include <stdio.h>
19 #include <stdlib.h>
20 #include <fcntl.h>
21 #include <sys/types.h>
22 #include <sys/ipc.h>
23 #include <sys/socket.h>
24 #include <sys/file.h>
25 #include <netinet/in.h>
26 #include <netdb.h>
27 #include <stdio.h>
28 #include <stdlib.h>
29 #include <fcntl.h>
30 #include <inttypes.h>
31 #include <unistd.h>
32 #include <string.h>
33 #include <stdbool.h>
34 #include <pthread.h>
35
36 #include <X11/Xlib.h>
37 #include <X11/Xatom.h>
38
39 uint32_t listenaddr =
0;
40 short srvport =
9302;
41 uint32_t *allowedaddr =
NULL;
42 size_t numallowedaddr =
0;
43
44 int srvloop =
1;
45
46 Display *dp;
47
48 typedef struct Client {
49 int fd;
50 struct sockaddr_in addr;
51 } Client;
52
53 #define XPROP_MAX_LENGTH 4096/
4
54 int get_desktop() {
55 Atom curdesktop = XInternAtom(dp,
"_NET_CURRENT_DESKTOP", False);
56 Atom type;
57 int format;
58 unsigned long nitems;
59 unsigned long size;
60 unsigned long bytes_after;
61 unsigned char *value;
62 if(XGetWindowProperty(dp, DefaultRootWindow(dp), curdesktop,
0,
XPROP_MAX_LENGTH, False,
XA_CARDINAL, &type, &format, &nitems, &bytes_after, &value) != Success) {
63 return 0;
64 }
65
66 int *desktop = (
int*)value;
67 return *desktop;
68 }
69
70 void switch_desktop(
int desktop) {
71 XEvent event;
72 event.xclient.type = ClientMessage;
73 event.xclient.serial =
0;
74 event.xclient.send_event = True;
75 event.xclient.message_type = XInternAtom(dp,
"_NET_CURRENT_DESKTOP", False);
76 event.xclient.window = DefaultRootWindow(dp);
77 event.xclient.format =
32;
78 event.xclient.data.l[
0] = desktop;
79
80 if(!XSendEvent(dp, DefaultRootWindow(dp), False, SubstructureRedirectMask | SubstructureNotifyMask, &event)) {
81 fprintf(stderr,
"XSendEvent failed\n");
82 }
83 }
84
85
86 int load_config() {
87
88
89 return 0;
90 }
91
92 int create_server_socket(
uint32_t addr,
short port) {
93 int ssock = -
1;
94
95 struct sockaddr_in servaddr;
96 memset(&servaddr,
0,
sizeof(servaddr));
97 servaddr.sin_family =
AF_INET;
98 servaddr.sin_addr.s_addr = htonl(addr);
99 servaddr.sin_port = htons(port);
100
101 if((ssock = socket(
AF_INET,
SOCK_STREAM,
0)) == -
1) {
102 perror(
"socket");
103 return -
1;
104 }
105
106 int o =
1;
107 setsockopt(
108 ssock,
109 SOL_SOCKET,
SO_REUSEADDR,
110 &o,
111 sizeof(
int));
112
113 if(bind(ssock, (
struct sockaddr*)&servaddr,
sizeof(servaddr))) {
114 perror(
"bind");
115 return -
1;
116 }
117
118 return ssock;
119 }
120
121 void* client_thread(
void *data) {
122 Client *client = data;
123
124 FILE *stream = fdopen(client->fd,
"r");
125 char *line =
NULL;
126 size_t len =
0;
127
128 ssize_t n;
129 while((n = getline(&line, &len, stream)) >
0) {
130 if(line[n-
1] ==
'\n') {
131 line[n-
1] =
'\0';
132 }
133 int desktop = get_desktop();
134
135 if(!strcmp(line,
"up")) {
136 printf(
"up\n");
137 switch_desktop(desktop -
1);
138 }
else if(!strcmp(line,
"down")) {
139 printf(
"down\n");
140 switch_desktop(desktop +
1);
141 }
else if(!strcmp(line,
"left")) {
142 printf(
"left\n");
143 switch_desktop(desktop -
1);
144 }
else if(!strcmp(line,
"right")) {
145 printf(
"right\n");
146 switch_desktop(desktop +
1);
147 }
else {
148 int desktop = atoi(line);
149 printf(
"desktop: %d\n", desktop);
150 switch_desktop(desktop);
151 }
152
153 XFlush(dp);
154 }
155
156 fclose(stream);
157 free(client);
158
159 XFlush(dp);
160
161 return NULL;
162 }
163
164 int main(
int argc,
char** argv) {
165 if(load_config()) {
166 fprintf(stderr,
"Cannot load config\n");
167 return 1;
168 }
169 dp = XOpenDisplay(
NULL);
170 if(!dp) {
171 fprintf(stderr,
"Cannot open X Display\n");
172 return 1;
173 }
174
175 int ssock = create_server_socket(listenaddr, srvport);
176 if(ssock <
0) {
177 return 1;
178 }
179 if(listen(ssock,
16)) {
180 perror(
"listen");
181 }
182
183 while(srvloop) {
184 struct sockaddr_in ca;
185 socklen_t length =
sizeof(ca);
186 int clientfd;
187
188 clientfd = accept(
189 ssock,
190 (
struct sockaddr*)&ca,
191 &length);
192 if (clientfd == -
1) {
193 perror(
"accept");
194 break;
195 }
196
197 Client *client = malloc(
sizeof(Client));
198 client->fd = clientfd;
199 client->addr = ca;
200
201 pthread_t t;
202 if(pthread_create(&t,
NULL, client_thread, client)) {
203 perror(
"pthread_create");
204 close(clientfd);
205 free(client);
206 }
207 pthread_detach(t);
208 }
209
210 close(ssock);
211 return 0;
212 }
213