3 * Sample server that just keeps first available window mapped.
5 * It also reads and echos anything that happens on stdin as an
6 * example of tracking events from sources other than miniglx clients.
8 * It reads & writes without blocking, so that eg. piping a lot of
9 * text to stdin and then hitting 'ctrl-S' on the output stream won't
10 * cause it to stop handling miniglx events.
12 * See select_tut in the linux manual pages for a good overview of the
13 * select(2) system call.
22 #include <GL/miniglx.h>
32 struct client *clients = 0, *mapped_client = 0;
39 static struct client *find_client( Window id )
43 for (c = clients ; c ; c = c->next)
44 if (c->windowid == id)
50 int main( int argc, char *argv[] )
56 if (argc == 2 && strcmp(argv[1], "-autostart") == 0)
59 dpy = __miniglx_StartServer(NULL);
61 fprintf(stderr, "Error: __miniglx_StartServer failed\n");
65 /* How is vt switching communicated through the XNextEvent interface?
79 FD_SET( 1, &wfds ); /* notify when we can write out buffer */
83 FD_SET( 0, &rfds ); /* else notify when new data to read */
87 /* __miniglx_Select waits until any of these file groups becomes
88 * readable/writable/etc (like regular select), until timeout
89 * expires (like regular select), until a signal is received
90 * (like regular select) or until an event is available for
93 r = __miniglx_Select( dpy, n+1, &rfds, &wfds, 0, &tv );
95 /* This can happen if select() is interrupted by a signal:
97 if (r < 0 && errno != EINTR && errno != EAGAIN) {
102 if (tv.tv_sec == 0 && tv.tv_usec == 0)
105 /* Check and handle events on our local file descriptors
107 if (FD_ISSET( 0, &rfds )) {
108 /* Something on stdin */
109 assert(rbuf_count == 0);
110 r = read(0, rbuf, BUFSZ);
118 if (FD_ISSET( 1, &wfds )) {
119 /* Can write to stdout */
120 assert(rbuf_count > 0);
121 r = write(1, rbuf, rbuf_count);
128 memmove(rbuf + r, rbuf, rbuf_count);
132 /* Check and handle events generated by miniglx:
134 while (XCheckMaskEvent( dpy, ~0, &ev )) {
138 fprintf(stderr, "Received event %d\n", ev.type);
142 fprintf(stderr, "CreateNotify -- new client\n");
143 c = malloc(sizeof(*c));
145 c->windowid = ev.xcreatewindow.window;
151 fprintf(stderr, "DestroyNotify\n");
152 c = find_client(ev.xdestroywindow.window);
158 for (t = clients ; t->next != c ; t = t->next)
163 if (c == mapped_client)
170 fprintf(stderr, "MapRequest\n");
171 c = find_client(ev.xmaprequest.window);
177 fprintf(stderr, "UnmapNotify\n");
178 c = find_client(ev.xunmap.window);
181 if (c == mapped_client)
191 /* Search for first mappable client if none already mapped.
193 if (!mapped_client) {
195 for (c = clients ; c ; c = c->next) {
197 XMapWindow( dpy, c->windowid );
202 if (!clients && autostart) {
203 system("nohup ./texline &");
204 system("nohup ./manytex &");
209 /* bored of mapped client now, let's try & find another one */
210 for (c = mapped_client->next ; c && !c->mappable ; c = c->next)
213 for (c = clients ; c && !c->mappable ; c = c->next)
215 if (c && c != mapped_client) {
216 XUnmapWindow( dpy, mapped_client->windowid );
217 XMapWindow( dpy, c->windowid );
221 fprintf(stderr, "I'm bored!\n");
225 XCloseDisplay( dpy );