1 /* $Id: sample_server2.c,v 1.2 2003/08/23 01:28:59 jonsmirl Exp $ */
4 * Sample server that just keeps first available window mapped.
6 * It also reads and echos anything that happens on stdin as an
7 * example of tracking events from sources other than miniglx clients.
9 * It reads & writes without blocking, so that eg. piping a lot of
10 * text to stdin and then hitting 'ctrl-S' on the output stream won't
11 * cause it to stop handling miniglx events.
13 * See select_tut in the linux manual pages for a good overview of the
14 * select(2) system call.
23 #include <GL/miniglx.h>
33 struct client
*clients
= 0, *mapped_client
= 0;
40 static struct client
*find_client( Window id
)
44 for (c
= clients
; c
; c
= c
->next
)
45 if (c
->windowid
== id
)
51 int main( int argc
, char *argv
[] )
57 if (argc
== 2 && strcmp(argv
[1], "-autostart") == 0)
60 dpy
= __miniglx_StartServer(NULL
);
62 fprintf(stderr
, "Error: __miniglx_StartServer failed\n");
66 /* How is vt switching communicated through the XNextEvent interface?
80 FD_SET( 1, &wfds
); /* notify when we can write out buffer */
84 FD_SET( 0, &rfds
); /* else notify when new data to read */
88 /* __miniglx_Select waits until any of these file groups becomes
89 * readable/writable/etc (like regular select), until timeout
90 * expires (like regular select), until a signal is received
91 * (like regular select) or until an event is available for
94 r
= __miniglx_Select( dpy
, n
+1, &rfds
, &wfds
, 0, &tv
);
96 /* This can happen if select() is interrupted by a signal:
98 if (r
< 0 && errno
!= EINTR
&& errno
!= EAGAIN
) {
103 if (tv
.tv_sec
== 0 && tv
.tv_usec
== 0)
106 /* Check and handle events on our local file descriptors
108 if (FD_ISSET( 0, &rfds
)) {
109 /* Something on stdin */
110 assert(rbuf_count
== 0);
111 r
= read(0, rbuf
, BUFSZ
);
119 if (FD_ISSET( 1, &wfds
)) {
120 /* Can write to stdout */
121 assert(rbuf_count
> 0);
122 r
= write(1, rbuf
, rbuf_count
);
129 memmove(rbuf
+ r
, rbuf
, rbuf_count
);
133 /* Check and handle events generated by miniglx:
135 while (XCheckMaskEvent( dpy
, ~0, &ev
)) {
139 fprintf(stderr
, "Received event %d\n", ev
.type
);
143 fprintf(stderr
, "CreateNotify -- new client\n");
144 c
= malloc(sizeof(*c
));
146 c
->windowid
= ev
.xcreatewindow
.window
;
152 fprintf(stderr
, "DestroyNotify\n");
153 c
= find_client(ev
.xdestroywindow
.window
);
159 for (t
= clients
; t
->next
!= c
; t
= t
->next
)
164 if (c
== mapped_client
)
171 fprintf(stderr
, "MapRequest\n");
172 c
= find_client(ev
.xmaprequest
.window
);
178 fprintf(stderr
, "UnmapNotify\n");
179 c
= find_client(ev
.xunmap
.window
);
182 if (c
== mapped_client
)
192 /* Search for first mappable client if none already mapped.
194 if (!mapped_client
) {
196 for (c
= clients
; c
; c
= c
->next
) {
198 XMapWindow( dpy
, c
->windowid
);
203 if (!clients
&& autostart
) {
204 system("nohup ./texline &");
205 system("nohup ./manytex &");
210 /* bored of mapped client now, let's try & find another one */
211 for (c
= mapped_client
->next
; c
&& !c
->mappable
; c
= c
->next
)
214 for (c
= clients
; c
&& !c
->mappable
; c
= c
->next
)
216 if (c
&& c
!= mapped_client
) {
217 XUnmapWindow( dpy
, mapped_client
->windowid
);
218 XMapWindow( dpy
, c
->windowid
);
222 fprintf(stderr
, "I'm bored!\n");
226 XCloseDisplay( dpy
);