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
);