Blame


1 c66b5250 2006-06-25 devnull /*
2 c66b5250 2006-06-25 devnull * Window system protocol server.
3 c66b5250 2006-06-25 devnull * Use select and a single proc and single stack
4 c66b5250 2006-06-25 devnull * to avoid aggravating the X11 library, which is
5 c66b5250 2006-06-25 devnull * subtle and quick to anger.
6 c66b5250 2006-06-25 devnull */
7 c66b5250 2006-06-25 devnull
8 35288690 2008-01-30 rsc // #define SHOWEVENT
9 35288690 2008-01-30 rsc
10 c66b5250 2006-06-25 devnull #include <u.h>
11 c66b5250 2006-06-25 devnull #include <sys/select.h>
12 c66b5250 2006-06-25 devnull #include <errno.h>
13 35288690 2008-01-30 rsc #ifdef SHOWEVENT
14 35288690 2008-01-30 rsc #include <stdio.h>
15 35288690 2008-01-30 rsc #endif
16 c66b5250 2006-06-25 devnull #include "x11-inc.h"
17 35288690 2008-01-30 rsc
18 c66b5250 2006-06-25 devnull #include <libc.h>
19 c66b5250 2006-06-25 devnull #include <draw.h>
20 c66b5250 2006-06-25 devnull #include <memdraw.h>
21 c66b5250 2006-06-25 devnull #include <memlayer.h>
22 c66b5250 2006-06-25 devnull #include <keyboard.h>
23 c66b5250 2006-06-25 devnull #include <mouse.h>
24 c66b5250 2006-06-25 devnull #include <cursor.h>
25 c66b5250 2006-06-25 devnull #include <drawfcall.h>
26 c66b5250 2006-06-25 devnull #include "x11-memdraw.h"
27 c66b5250 2006-06-25 devnull #include "devdraw.h"
28 c66b5250 2006-06-25 devnull
29 c66b5250 2006-06-25 devnull #undef time
30 c66b5250 2006-06-25 devnull
31 c66b5250 2006-06-25 devnull #define MouseMask (\
32 c66b5250 2006-06-25 devnull ButtonPressMask|\
33 c66b5250 2006-06-25 devnull ButtonReleaseMask|\
34 c66b5250 2006-06-25 devnull PointerMotionMask|\
35 c66b5250 2006-06-25 devnull Button1MotionMask|\
36 c66b5250 2006-06-25 devnull Button2MotionMask|\
37 c66b5250 2006-06-25 devnull Button3MotionMask)
38 c66b5250 2006-06-25 devnull
39 36bb28dc 2013-03-08 rsc #define Mask MouseMask|ExposureMask|StructureNotifyMask|KeyPressMask|KeyReleaseMask|EnterWindowMask|LeaveWindowMask|FocusChangeMask
40 c66b5250 2006-06-25 devnull
41 c66b5250 2006-06-25 devnull typedef struct Kbdbuf Kbdbuf;
42 c66b5250 2006-06-25 devnull typedef struct Mousebuf Mousebuf;
43 c66b5250 2006-06-25 devnull typedef struct Fdbuf Fdbuf;
44 c66b5250 2006-06-25 devnull typedef struct Tagbuf Tagbuf;
45 c66b5250 2006-06-25 devnull
46 c66b5250 2006-06-25 devnull struct Kbdbuf
47 c66b5250 2006-06-25 devnull {
48 c66b5250 2006-06-25 devnull Rune r[32];
49 c66b5250 2006-06-25 devnull int ri;
50 c66b5250 2006-06-25 devnull int wi;
51 c66b5250 2006-06-25 devnull int stall;
52 c66b5250 2006-06-25 devnull };
53 c66b5250 2006-06-25 devnull
54 c66b5250 2006-06-25 devnull struct Mousebuf
55 c66b5250 2006-06-25 devnull {
56 c66b5250 2006-06-25 devnull Mouse m[32];
57 c66b5250 2006-06-25 devnull int ri;
58 c66b5250 2006-06-25 devnull int wi;
59 c66b5250 2006-06-25 devnull int stall;
60 2bdefab1 2006-07-05 devnull int resized;
61 c66b5250 2006-06-25 devnull };
62 c66b5250 2006-06-25 devnull
63 c66b5250 2006-06-25 devnull struct Tagbuf
64 c66b5250 2006-06-25 devnull {
65 c66b5250 2006-06-25 devnull int t[32];
66 c66b5250 2006-06-25 devnull int ri;
67 c66b5250 2006-06-25 devnull int wi;
68 c66b5250 2006-06-25 devnull };
69 c66b5250 2006-06-25 devnull
70 c66b5250 2006-06-25 devnull struct Fdbuf
71 c66b5250 2006-06-25 devnull {
72 c66b5250 2006-06-25 devnull uchar buf[2*MAXWMSG];
73 c66b5250 2006-06-25 devnull uchar *rp;
74 c66b5250 2006-06-25 devnull uchar *wp;
75 c66b5250 2006-06-25 devnull uchar *ep;
76 c66b5250 2006-06-25 devnull };
77 c66b5250 2006-06-25 devnull
78 c66b5250 2006-06-25 devnull Kbdbuf kbd;
79 c66b5250 2006-06-25 devnull Mousebuf mouse;
80 c66b5250 2006-06-25 devnull Fdbuf fdin;
81 c66b5250 2006-06-25 devnull Fdbuf fdout;
82 c66b5250 2006-06-25 devnull Tagbuf kbdtags;
83 c66b5250 2006-06-25 devnull Tagbuf mousetags;
84 c66b5250 2006-06-25 devnull
85 c66b5250 2006-06-25 devnull void fdslide(Fdbuf*);
86 c66b5250 2006-06-25 devnull void runmsg(Wsysmsg*);
87 c66b5250 2006-06-25 devnull void replymsg(Wsysmsg*);
88 c66b5250 2006-06-25 devnull void runxevent(XEvent*);
89 c66b5250 2006-06-25 devnull void matchkbd(void);
90 c66b5250 2006-06-25 devnull void matchmouse(void);
91 c66b5250 2006-06-25 devnull int fdnoblock(int);
92 c66b5250 2006-06-25 devnull
93 c66b5250 2006-06-25 devnull int chatty;
94 f936548b 2006-06-26 devnull int drawsleep;
95 35288690 2008-01-30 rsc int fullscreen;
96 35288690 2008-01-30 rsc
97 35288690 2008-01-30 rsc Rectangle windowrect;
98 35288690 2008-01-30 rsc Rectangle screenrect;
99 c66b5250 2006-06-25 devnull
100 c66b5250 2006-06-25 devnull void
101 c66b5250 2006-06-25 devnull usage(void)
102 c66b5250 2006-06-25 devnull {
103 35288690 2008-01-30 rsc fprint(2, "usage: devdraw (don't run directly)\n");
104 c66b5250 2006-06-25 devnull exits("usage");
105 c66b5250 2006-06-25 devnull }
106 c66b5250 2006-06-25 devnull
107 c66b5250 2006-06-25 devnull void
108 f936548b 2006-06-26 devnull bell(void *v, char *msg)
109 f936548b 2006-06-26 devnull {
110 f936548b 2006-06-26 devnull if(strcmp(msg, "alarm") == 0)
111 f936548b 2006-06-26 devnull drawsleep = drawsleep ? 0 : 1000;
112 f936548b 2006-06-26 devnull noted(NCONT);
113 f936548b 2006-06-26 devnull }
114 f936548b 2006-06-26 devnull
115 f936548b 2006-06-26 devnull void
116 c66b5250 2006-06-25 devnull main(int argc, char **argv)
117 c66b5250 2006-06-25 devnull {
118 c66b5250 2006-06-25 devnull int n, top, firstx;
119 c66b5250 2006-06-25 devnull fd_set rd, wr, xx;
120 c66b5250 2006-06-25 devnull Wsysmsg m;
121 c66b5250 2006-06-25 devnull XEvent event;
122 c66b5250 2006-06-25 devnull
123 2bdefab1 2006-07-05 devnull /*
124 2bdefab1 2006-07-05 devnull * Move the protocol off stdin/stdout so that
125 2bdefab1 2006-07-05 devnull * any inadvertent prints don't screw things up.
126 2bdefab1 2006-07-05 devnull */
127 2bdefab1 2006-07-05 devnull dup(0, 3);
128 2bdefab1 2006-07-05 devnull dup(1, 4);
129 2bdefab1 2006-07-05 devnull close(0);
130 2bdefab1 2006-07-05 devnull close(1);
131 2bdefab1 2006-07-05 devnull open("/dev/null", OREAD);
132 2bdefab1 2006-07-05 devnull open("/dev/null", OWRITE);
133 35288690 2008-01-30 rsc
134 35288690 2008-01-30 rsc /* reopens stdout if debugging */
135 35288690 2008-01-30 rsc runxevent(0);
136 2bdefab1 2006-07-05 devnull
137 2bdefab1 2006-07-05 devnull fmtinstall('W', drawfcallfmt);
138 2bdefab1 2006-07-05 devnull
139 c66b5250 2006-06-25 devnull ARGBEGIN{
140 c66b5250 2006-06-25 devnull case 'D':
141 c66b5250 2006-06-25 devnull chatty++;
142 c66b5250 2006-06-25 devnull break;
143 c66b5250 2006-06-25 devnull default:
144 c66b5250 2006-06-25 devnull usage();
145 c66b5250 2006-06-25 devnull }ARGEND
146 f936548b 2006-06-26 devnull
147 f936548b 2006-06-26 devnull /*
148 f936548b 2006-06-26 devnull * Ignore arguments. They're only for good ps -a listings.
149 f936548b 2006-06-26 devnull */
150 c66b5250 2006-06-25 devnull
151 f936548b 2006-06-26 devnull notify(bell);
152 c66b5250 2006-06-25 devnull
153 c66b5250 2006-06-25 devnull fdin.rp = fdin.wp = fdin.buf;
154 c66b5250 2006-06-25 devnull fdin.ep = fdin.buf+sizeof fdin.buf;
155 c66b5250 2006-06-25 devnull
156 c66b5250 2006-06-25 devnull fdout.rp = fdout.wp = fdout.buf;
157 c66b5250 2006-06-25 devnull fdout.ep = fdout.buf+sizeof fdout.buf;
158 c66b5250 2006-06-25 devnull
159 2bdefab1 2006-07-05 devnull fdnoblock(3);
160 2bdefab1 2006-07-05 devnull fdnoblock(4);
161 c66b5250 2006-06-25 devnull
162 c66b5250 2006-06-25 devnull firstx = 1;
163 c66b5250 2006-06-25 devnull _x.fd = -1;
164 c66b5250 2006-06-25 devnull for(;;){
165 c66b5250 2006-06-25 devnull /* set up file descriptors */
166 c66b5250 2006-06-25 devnull FD_ZERO(&rd);
167 c66b5250 2006-06-25 devnull FD_ZERO(&wr);
168 c66b5250 2006-06-25 devnull FD_ZERO(&xx);
169 c66b5250 2006-06-25 devnull /*
170 c66b5250 2006-06-25 devnull * Don't read unless there's room *and* we haven't
171 c66b5250 2006-06-25 devnull * already filled the output buffer too much.
172 c66b5250 2006-06-25 devnull */
173 c66b5250 2006-06-25 devnull if(fdout.wp < fdout.buf+MAXWMSG && fdin.wp < fdin.ep)
174 2bdefab1 2006-07-05 devnull FD_SET(3, &rd);
175 c66b5250 2006-06-25 devnull if(fdout.wp > fdout.rp)
176 2bdefab1 2006-07-05 devnull FD_SET(4, &wr);
177 2bdefab1 2006-07-05 devnull FD_SET(3, &xx);
178 2bdefab1 2006-07-05 devnull FD_SET(4, &xx);
179 2bdefab1 2006-07-05 devnull top = 4;
180 c66b5250 2006-06-25 devnull if(_x.fd >= 0){
181 c66b5250 2006-06-25 devnull if(firstx){
182 c66b5250 2006-06-25 devnull firstx = 0;
183 c66b5250 2006-06-25 devnull XSelectInput(_x.display, _x.drawable, Mask);
184 c66b5250 2006-06-25 devnull }
185 c66b5250 2006-06-25 devnull FD_SET(_x.fd, &rd);
186 c66b5250 2006-06-25 devnull FD_SET(_x.fd, &xx);
187 c66b5250 2006-06-25 devnull XFlush(_x.display);
188 2bdefab1 2006-07-05 devnull if(_x.fd > top)
189 2bdefab1 2006-07-05 devnull top = _x.fd;
190 c66b5250 2006-06-25 devnull }
191 c66b5250 2006-06-25 devnull
192 c66b5250 2006-06-25 devnull if(chatty)
193 c66b5250 2006-06-25 devnull fprint(2, "select %d...\n", top+1);
194 c66b5250 2006-06-25 devnull /* wait for something to happen */
195 f936548b 2006-06-26 devnull again:
196 c66b5250 2006-06-25 devnull if(select(top+1, &rd, &wr, &xx, NULL) < 0){
197 f936548b 2006-06-26 devnull if(errno == EINTR)
198 f936548b 2006-06-26 devnull goto again;
199 c66b5250 2006-06-25 devnull if(chatty)
200 c66b5250 2006-06-25 devnull fprint(2, "select failure\n");
201 c66b5250 2006-06-25 devnull exits(0);
202 c66b5250 2006-06-25 devnull }
203 c66b5250 2006-06-25 devnull if(chatty)
204 c66b5250 2006-06-25 devnull fprint(2, "got select...\n");
205 c66b5250 2006-06-25 devnull
206 c66b5250 2006-06-25 devnull {
207 c66b5250 2006-06-25 devnull /* read what we can */
208 c66b5250 2006-06-25 devnull n = 1;
209 2bdefab1 2006-07-05 devnull while(fdin.wp < fdin.ep && (n = read(3, fdin.wp, fdin.ep-fdin.wp)) > 0)
210 c66b5250 2006-06-25 devnull fdin.wp += n;
211 c66b5250 2006-06-25 devnull if(n == 0){
212 c66b5250 2006-06-25 devnull if(chatty)
213 c66b5250 2006-06-25 devnull fprint(2, "eof\n");
214 c66b5250 2006-06-25 devnull exits(0);
215 c66b5250 2006-06-25 devnull }
216 c66b5250 2006-06-25 devnull if(n < 0 && errno != EAGAIN)
217 c66b5250 2006-06-25 devnull sysfatal("reading wsys msg: %r");
218 c66b5250 2006-06-25 devnull
219 c66b5250 2006-06-25 devnull /* pick off messages one by one */
220 c66b5250 2006-06-25 devnull while((n = convM2W(fdin.rp, fdin.wp-fdin.rp, &m)) > 0){
221 2bdefab1 2006-07-05 devnull /* fprint(2, "<- %W\n", &m); */
222 c66b5250 2006-06-25 devnull runmsg(&m);
223 c66b5250 2006-06-25 devnull fdin.rp += n;
224 c66b5250 2006-06-25 devnull }
225 c66b5250 2006-06-25 devnull
226 c66b5250 2006-06-25 devnull /* slide data to beginning of buf */
227 c66b5250 2006-06-25 devnull fdslide(&fdin);
228 c66b5250 2006-06-25 devnull }
229 c66b5250 2006-06-25 devnull {
230 c66b5250 2006-06-25 devnull /* write what we can */
231 c66b5250 2006-06-25 devnull n = 1;
232 2bdefab1 2006-07-05 devnull while(fdout.rp < fdout.wp && (n = write(4, fdout.rp, fdout.wp-fdout.rp)) > 0)
233 c66b5250 2006-06-25 devnull fdout.rp += n;
234 c66b5250 2006-06-25 devnull if(n == 0)
235 c66b5250 2006-06-25 devnull sysfatal("short write writing wsys");
236 c66b5250 2006-06-25 devnull if(n < 0 && errno != EAGAIN)
237 c66b5250 2006-06-25 devnull sysfatal("writing wsys msg: %r");
238 c66b5250 2006-06-25 devnull
239 c66b5250 2006-06-25 devnull /* slide data to beginning of buf */
240 c66b5250 2006-06-25 devnull fdslide(&fdout);
241 c66b5250 2006-06-25 devnull }
242 c66b5250 2006-06-25 devnull {
243 c66b5250 2006-06-25 devnull /*
244 c66b5250 2006-06-25 devnull * Read an X message if we can.
245 c66b5250 2006-06-25 devnull * (XPending actually calls select to make sure
246 c66b5250 2006-06-25 devnull * the display's fd is readable and then reads
247 c66b5250 2006-06-25 devnull * in any waiting data before declaring whether
248 c66b5250 2006-06-25 devnull * there are events on the queue.)
249 c66b5250 2006-06-25 devnull */
250 c66b5250 2006-06-25 devnull while(XPending(_x.display)){
251 c66b5250 2006-06-25 devnull XNextEvent(_x.display, &event);
252 c66b5250 2006-06-25 devnull runxevent(&event);
253 c66b5250 2006-06-25 devnull }
254 c66b5250 2006-06-25 devnull }
255 c66b5250 2006-06-25 devnull }
256 c66b5250 2006-06-25 devnull }
257 c66b5250 2006-06-25 devnull
258 c66b5250 2006-06-25 devnull int
259 c66b5250 2006-06-25 devnull fdnoblock(int fd)
260 c66b5250 2006-06-25 devnull {
261 c66b5250 2006-06-25 devnull return fcntl(fd, F_SETFL, fcntl(fd, F_GETFL)|O_NONBLOCK);
262 c66b5250 2006-06-25 devnull }
263 c66b5250 2006-06-25 devnull
264 c66b5250 2006-06-25 devnull void
265 c66b5250 2006-06-25 devnull fdslide(Fdbuf *fb)
266 c66b5250 2006-06-25 devnull {
267 c66b5250 2006-06-25 devnull int n;
268 c66b5250 2006-06-25 devnull
269 c66b5250 2006-06-25 devnull n = fb->wp - fb->rp;
270 c66b5250 2006-06-25 devnull if(n > 0)
271 c66b5250 2006-06-25 devnull memmove(fb->buf, fb->rp, n);
272 c66b5250 2006-06-25 devnull fb->rp = fb->buf;
273 c66b5250 2006-06-25 devnull fb->wp = fb->rp+n;
274 c66b5250 2006-06-25 devnull }
275 c66b5250 2006-06-25 devnull
276 c66b5250 2006-06-25 devnull void
277 c66b5250 2006-06-25 devnull replyerror(Wsysmsg *m)
278 c66b5250 2006-06-25 devnull {
279 c66b5250 2006-06-25 devnull char err[256];
280 c66b5250 2006-06-25 devnull
281 c66b5250 2006-06-25 devnull rerrstr(err, sizeof err);
282 c66b5250 2006-06-25 devnull m->type = Rerror;
283 c66b5250 2006-06-25 devnull m->error = err;
284 c66b5250 2006-06-25 devnull replymsg(m);
285 c66b5250 2006-06-25 devnull }
286 c66b5250 2006-06-25 devnull
287 35288690 2008-01-30 rsc
288 35288690 2008-01-30 rsc
289 c66b5250 2006-06-25 devnull /*
290 c66b5250 2006-06-25 devnull * Handle a single wsysmsg.
291 c66b5250 2006-06-25 devnull * Might queue for later (kbd, mouse read)
292 c66b5250 2006-06-25 devnull */
293 c66b5250 2006-06-25 devnull void
294 c66b5250 2006-06-25 devnull runmsg(Wsysmsg *m)
295 c66b5250 2006-06-25 devnull {
296 c66b5250 2006-06-25 devnull uchar buf[65536];
297 c66b5250 2006-06-25 devnull int n;
298 c66b5250 2006-06-25 devnull Memimage *i;
299 c66b5250 2006-06-25 devnull
300 c66b5250 2006-06-25 devnull switch(m->type){
301 c66b5250 2006-06-25 devnull case Tinit:
302 c66b5250 2006-06-25 devnull memimageinit();
303 c66b5250 2006-06-25 devnull i = _xattach(m->label, m->winsize);
304 c66b5250 2006-06-25 devnull _initdisplaymemimage(i);
305 c66b5250 2006-06-25 devnull replymsg(m);
306 c66b5250 2006-06-25 devnull break;
307 c66b5250 2006-06-25 devnull
308 c66b5250 2006-06-25 devnull case Trdmouse:
309 c66b5250 2006-06-25 devnull mousetags.t[mousetags.wi++] = m->tag;
310 c66b5250 2006-06-25 devnull if(mousetags.wi == nelem(mousetags.t))
311 c66b5250 2006-06-25 devnull mousetags.wi = 0;
312 c66b5250 2006-06-25 devnull if(mousetags.wi == mousetags.ri)
313 c66b5250 2006-06-25 devnull sysfatal("too many queued mouse reads");
314 2bdefab1 2006-07-05 devnull /* fprint(2, "mouse unstall\n"); */
315 c66b5250 2006-06-25 devnull mouse.stall = 0;
316 c66b5250 2006-06-25 devnull matchmouse();
317 c66b5250 2006-06-25 devnull break;
318 c66b5250 2006-06-25 devnull
319 c66b5250 2006-06-25 devnull case Trdkbd:
320 c66b5250 2006-06-25 devnull kbdtags.t[kbdtags.wi++] = m->tag;
321 c66b5250 2006-06-25 devnull if(kbdtags.wi == nelem(kbdtags.t))
322 c66b5250 2006-06-25 devnull kbdtags.wi = 0;
323 c66b5250 2006-06-25 devnull if(kbdtags.wi == kbdtags.ri)
324 c66b5250 2006-06-25 devnull sysfatal("too many queued keyboard reads");
325 c66b5250 2006-06-25 devnull kbd.stall = 0;
326 c66b5250 2006-06-25 devnull matchkbd();
327 c66b5250 2006-06-25 devnull break;
328 c66b5250 2006-06-25 devnull
329 c66b5250 2006-06-25 devnull case Tmoveto:
330 c66b5250 2006-06-25 devnull _xmoveto(m->mouse.xy);
331 c66b5250 2006-06-25 devnull replymsg(m);
332 c66b5250 2006-06-25 devnull break;
333 c66b5250 2006-06-25 devnull
334 c66b5250 2006-06-25 devnull case Tcursor:
335 c66b5250 2006-06-25 devnull if(m->arrowcursor)
336 c66b5250 2006-06-25 devnull _xsetcursor(nil);
337 c66b5250 2006-06-25 devnull else
338 c66b5250 2006-06-25 devnull _xsetcursor(&m->cursor);
339 c66b5250 2006-06-25 devnull replymsg(m);
340 c66b5250 2006-06-25 devnull break;
341 c66b5250 2006-06-25 devnull
342 c66b5250 2006-06-25 devnull case Tbouncemouse:
343 c66b5250 2006-06-25 devnull _xbouncemouse(&m->mouse);
344 c66b5250 2006-06-25 devnull replymsg(m);
345 c66b5250 2006-06-25 devnull break;
346 c66b5250 2006-06-25 devnull
347 c66b5250 2006-06-25 devnull case Tlabel:
348 c66b5250 2006-06-25 devnull _xsetlabel(m->label);
349 c66b5250 2006-06-25 devnull replymsg(m);
350 c66b5250 2006-06-25 devnull break;
351 c66b5250 2006-06-25 devnull
352 c66b5250 2006-06-25 devnull case Trdsnarf:
353 c66b5250 2006-06-25 devnull m->snarf = _xgetsnarf();
354 c66b5250 2006-06-25 devnull replymsg(m);
355 c66b5250 2006-06-25 devnull free(m->snarf);
356 c66b5250 2006-06-25 devnull break;
357 c66b5250 2006-06-25 devnull
358 c66b5250 2006-06-25 devnull case Twrsnarf:
359 c66b5250 2006-06-25 devnull _xputsnarf(m->snarf);
360 c66b5250 2006-06-25 devnull replymsg(m);
361 c66b5250 2006-06-25 devnull break;
362 c66b5250 2006-06-25 devnull
363 c66b5250 2006-06-25 devnull case Trddraw:
364 c66b5250 2006-06-25 devnull n = m->count;
365 c66b5250 2006-06-25 devnull if(n > sizeof buf)
366 c66b5250 2006-06-25 devnull n = sizeof buf;
367 c66b5250 2006-06-25 devnull n = _drawmsgread(buf, n);
368 c66b5250 2006-06-25 devnull if(n < 0)
369 c66b5250 2006-06-25 devnull replyerror(m);
370 c66b5250 2006-06-25 devnull else{
371 c66b5250 2006-06-25 devnull m->count = n;
372 c66b5250 2006-06-25 devnull m->data = buf;
373 c66b5250 2006-06-25 devnull replymsg(m);
374 c66b5250 2006-06-25 devnull }
375 c66b5250 2006-06-25 devnull break;
376 c66b5250 2006-06-25 devnull
377 c66b5250 2006-06-25 devnull case Twrdraw:
378 c66b5250 2006-06-25 devnull if(_drawmsgwrite(m->data, m->count) < 0)
379 c66b5250 2006-06-25 devnull replyerror(m);
380 c66b5250 2006-06-25 devnull else
381 c66b5250 2006-06-25 devnull replymsg(m);
382 c66b5250 2006-06-25 devnull break;
383 c66b5250 2006-06-25 devnull
384 c66b5250 2006-06-25 devnull case Ttop:
385 c66b5250 2006-06-25 devnull _xtopwindow();
386 c66b5250 2006-06-25 devnull replymsg(m);
387 c66b5250 2006-06-25 devnull break;
388 c66b5250 2006-06-25 devnull
389 c66b5250 2006-06-25 devnull case Tresize:
390 c66b5250 2006-06-25 devnull _xresizewindow(m->rect);
391 c66b5250 2006-06-25 devnull replymsg(m);
392 c66b5250 2006-06-25 devnull break;
393 c66b5250 2006-06-25 devnull }
394 c66b5250 2006-06-25 devnull }
395 c66b5250 2006-06-25 devnull
396 c66b5250 2006-06-25 devnull /*
397 c66b5250 2006-06-25 devnull * Reply to m.
398 c66b5250 2006-06-25 devnull */
399 c66b5250 2006-06-25 devnull void
400 c66b5250 2006-06-25 devnull replymsg(Wsysmsg *m)
401 c66b5250 2006-06-25 devnull {
402 c66b5250 2006-06-25 devnull int n;
403 c66b5250 2006-06-25 devnull
404 c66b5250 2006-06-25 devnull /* T -> R msg */
405 c66b5250 2006-06-25 devnull if(m->type%2 == 0)
406 c66b5250 2006-06-25 devnull m->type++;
407 c66b5250 2006-06-25 devnull
408 2bdefab1 2006-07-05 devnull /* fprint(2, "-> %W\n", m); */
409 c66b5250 2006-06-25 devnull /* copy to output buffer */
410 c66b5250 2006-06-25 devnull n = sizeW2M(m);
411 c66b5250 2006-06-25 devnull if(fdout.wp+n > fdout.ep)
412 c66b5250 2006-06-25 devnull sysfatal("out of space for reply message");
413 c66b5250 2006-06-25 devnull convW2M(m, fdout.wp, n);
414 c66b5250 2006-06-25 devnull fdout.wp += n;
415 c66b5250 2006-06-25 devnull }
416 c66b5250 2006-06-25 devnull
417 c66b5250 2006-06-25 devnull /*
418 c66b5250 2006-06-25 devnull * Match queued kbd reads with queued kbd characters.
419 c66b5250 2006-06-25 devnull */
420 c66b5250 2006-06-25 devnull void
421 c66b5250 2006-06-25 devnull matchkbd(void)
422 c66b5250 2006-06-25 devnull {
423 c66b5250 2006-06-25 devnull Wsysmsg m;
424 c66b5250 2006-06-25 devnull
425 c66b5250 2006-06-25 devnull if(kbd.stall)
426 c66b5250 2006-06-25 devnull return;
427 c66b5250 2006-06-25 devnull while(kbd.ri != kbd.wi && kbdtags.ri != kbdtags.wi){
428 c66b5250 2006-06-25 devnull m.type = Rrdkbd;
429 c66b5250 2006-06-25 devnull m.tag = kbdtags.t[kbdtags.ri++];
430 c66b5250 2006-06-25 devnull if(kbdtags.ri == nelem(kbdtags.t))
431 c66b5250 2006-06-25 devnull kbdtags.ri = 0;
432 c66b5250 2006-06-25 devnull m.rune = kbd.r[kbd.ri++];
433 c66b5250 2006-06-25 devnull if(kbd.ri == nelem(kbd.r))
434 c66b5250 2006-06-25 devnull kbd.ri = 0;
435 c66b5250 2006-06-25 devnull replymsg(&m);
436 c66b5250 2006-06-25 devnull }
437 c66b5250 2006-06-25 devnull }
438 c66b5250 2006-06-25 devnull
439 c66b5250 2006-06-25 devnull /*
440 c66b5250 2006-06-25 devnull * Match queued mouse reads with queued mouse events.
441 c66b5250 2006-06-25 devnull */
442 c66b5250 2006-06-25 devnull void
443 c66b5250 2006-06-25 devnull matchmouse(void)
444 c66b5250 2006-06-25 devnull {
445 c66b5250 2006-06-25 devnull Wsysmsg m;
446 c66b5250 2006-06-25 devnull
447 c66b5250 2006-06-25 devnull while(mouse.ri != mouse.wi && mousetags.ri != mousetags.wi){
448 c66b5250 2006-06-25 devnull m.type = Rrdmouse;
449 c66b5250 2006-06-25 devnull m.tag = mousetags.t[mousetags.ri++];
450 c66b5250 2006-06-25 devnull if(mousetags.ri == nelem(mousetags.t))
451 c66b5250 2006-06-25 devnull mousetags.ri = 0;
452 c66b5250 2006-06-25 devnull m.mouse = mouse.m[mouse.ri];
453 2bdefab1 2006-07-05 devnull m.resized = mouse.resized;
454 2bdefab1 2006-07-05 devnull /*
455 2bdefab1 2006-07-05 devnull if(m.resized)
456 2bdefab1 2006-07-05 devnull fprint(2, "sending resize\n");
457 2bdefab1 2006-07-05 devnull */
458 2bdefab1 2006-07-05 devnull mouse.resized = 0;
459 c66b5250 2006-06-25 devnull mouse.ri++;
460 c66b5250 2006-06-25 devnull if(mouse.ri == nelem(mouse.m))
461 c66b5250 2006-06-25 devnull mouse.ri = 0;
462 c66b5250 2006-06-25 devnull replymsg(&m);
463 36bb28dc 2013-03-08 rsc }
464 36bb28dc 2013-03-08 rsc }
465 36bb28dc 2013-03-08 rsc
466 36bb28dc 2013-03-08 rsc static int kbuttons;
467 36bb28dc 2013-03-08 rsc static int altdown;
468 36bb28dc 2013-03-08 rsc static int kstate;
469 36bb28dc 2013-03-08 rsc
470 36bb28dc 2013-03-08 rsc static void
471 36bb28dc 2013-03-08 rsc sendmouse(Mouse m)
472 36bb28dc 2013-03-08 rsc {
473 36bb28dc 2013-03-08 rsc m.buttons |= kbuttons;
474 36bb28dc 2013-03-08 rsc mouse.m[mouse.wi] = m;
475 36bb28dc 2013-03-08 rsc mouse.wi++;
476 36bb28dc 2013-03-08 rsc if(mouse.wi == nelem(mouse.m))
477 36bb28dc 2013-03-08 rsc mouse.wi = 0;
478 36bb28dc 2013-03-08 rsc if(mouse.wi == mouse.ri){
479 36bb28dc 2013-03-08 rsc mouse.stall = 1;
480 36bb28dc 2013-03-08 rsc mouse.ri = 0;
481 36bb28dc 2013-03-08 rsc mouse.wi = 1;
482 36bb28dc 2013-03-08 rsc mouse.m[0] = m;
483 36bb28dc 2013-03-08 rsc /* fprint(2, "mouse stall\n"); */
484 c66b5250 2006-06-25 devnull }
485 36bb28dc 2013-03-08 rsc matchmouse();
486 c66b5250 2006-06-25 devnull }
487 c66b5250 2006-06-25 devnull
488 c66b5250 2006-06-25 devnull /*
489 c66b5250 2006-06-25 devnull * Handle an incoming X event.
490 c66b5250 2006-06-25 devnull */
491 c66b5250 2006-06-25 devnull void
492 c66b5250 2006-06-25 devnull runxevent(XEvent *xev)
493 c66b5250 2006-06-25 devnull {
494 c66b5250 2006-06-25 devnull int c;
495 35288690 2008-01-30 rsc KeySym k;
496 c66b5250 2006-06-25 devnull static Mouse m;
497 36bb28dc 2013-03-08 rsc XButtonEvent *be;
498 36bb28dc 2013-03-08 rsc XKeyEvent *ke;
499 c66b5250 2006-06-25 devnull
500 35288690 2008-01-30 rsc #ifdef SHOWEVENT
501 35288690 2008-01-30 rsc static int first = 1;
502 35288690 2008-01-30 rsc if(first){
503 35288690 2008-01-30 rsc dup(create("/tmp/devdraw.out", OWRITE, 0666), 1);
504 35288690 2008-01-30 rsc setbuf(stdout, 0);
505 35288690 2008-01-30 rsc first = 0;
506 35288690 2008-01-30 rsc }
507 35288690 2008-01-30 rsc #endif
508 35288690 2008-01-30 rsc
509 35288690 2008-01-30 rsc if(xev == 0)
510 35288690 2008-01-30 rsc return;
511 35288690 2008-01-30 rsc
512 35288690 2008-01-30 rsc #ifdef SHOWEVENT
513 35288690 2008-01-30 rsc print("\n");
514 35288690 2008-01-30 rsc ShowEvent(xev);
515 35288690 2008-01-30 rsc #endif
516 35288690 2008-01-30 rsc
517 c66b5250 2006-06-25 devnull switch(xev->type){
518 c66b5250 2006-06-25 devnull case Expose:
519 c66b5250 2006-06-25 devnull _xexpose(xev);
520 c66b5250 2006-06-25 devnull break;
521 c66b5250 2006-06-25 devnull
522 c66b5250 2006-06-25 devnull case DestroyNotify:
523 c66b5250 2006-06-25 devnull if(_xdestroy(xev))
524 c66b5250 2006-06-25 devnull exits(0);
525 c66b5250 2006-06-25 devnull break;
526 c66b5250 2006-06-25 devnull
527 c66b5250 2006-06-25 devnull case ConfigureNotify:
528 c66b5250 2006-06-25 devnull if(_xconfigure(xev)){
529 2bdefab1 2006-07-05 devnull mouse.resized = 1;
530 c66b5250 2006-06-25 devnull _xreplacescreenimage();
531 36bb28dc 2013-03-08 rsc sendmouse(m);
532 c66b5250 2006-06-25 devnull }
533 c66b5250 2006-06-25 devnull break;
534 c66b5250 2006-06-25 devnull
535 c66b5250 2006-06-25 devnull case ButtonPress:
536 36bb28dc 2013-03-08 rsc be = (XButtonEvent*)xev;
537 36bb28dc 2013-03-08 rsc if(be->button == 1) {
538 36bb28dc 2013-03-08 rsc if(kstate & ControlMask)
539 36bb28dc 2013-03-08 rsc be->button = 2;
540 36bb28dc 2013-03-08 rsc else if(kstate & Mod1Mask)
541 36bb28dc 2013-03-08 rsc be->button = 3;
542 36bb28dc 2013-03-08 rsc }
543 36bb28dc 2013-03-08 rsc // fall through
544 c66b5250 2006-06-25 devnull case ButtonRelease:
545 36bb28dc 2013-03-08 rsc altdown = 0;
546 36bb28dc 2013-03-08 rsc // fall through
547 c66b5250 2006-06-25 devnull case MotionNotify:
548 c66b5250 2006-06-25 devnull if(mouse.stall)
549 c66b5250 2006-06-25 devnull return;
550 c66b5250 2006-06-25 devnull if(_xtoplan9mouse(xev, &m) < 0)
551 c66b5250 2006-06-25 devnull return;
552 36bb28dc 2013-03-08 rsc sendmouse(m);
553 c66b5250 2006-06-25 devnull break;
554 c66b5250 2006-06-25 devnull
555 36bb28dc 2013-03-08 rsc case KeyRelease:
556 c66b5250 2006-06-25 devnull case KeyPress:
557 36bb28dc 2013-03-08 rsc ke = (XKeyEvent*)xev;
558 36bb28dc 2013-03-08 rsc XLookupString(ke, NULL, 0, &k, NULL);
559 36bb28dc 2013-03-08 rsc c = ke->state;
560 36bb28dc 2013-03-08 rsc switch(k) {
561 36bb28dc 2013-03-08 rsc case XK_Alt_L:
562 36bb28dc 2013-03-08 rsc case XK_Meta_L: /* Shift Alt on PCs */
563 36bb28dc 2013-03-08 rsc case XK_Alt_R:
564 36bb28dc 2013-03-08 rsc case XK_Meta_R: /* Shift Alt on PCs */
565 36bb28dc 2013-03-08 rsc case XK_Multi_key:
566 36bb28dc 2013-03-08 rsc if(xev->type == KeyPress)
567 36bb28dc 2013-03-08 rsc altdown = 1;
568 36bb28dc 2013-03-08 rsc else if(altdown) {
569 36bb28dc 2013-03-08 rsc altdown = 0;
570 36bb28dc 2013-03-08 rsc sendalt();
571 36bb28dc 2013-03-08 rsc }
572 36bb28dc 2013-03-08 rsc break;
573 36bb28dc 2013-03-08 rsc }
574 36bb28dc 2013-03-08 rsc
575 36bb28dc 2013-03-08 rsc switch(k) {
576 36bb28dc 2013-03-08 rsc case XK_Control_L:
577 36bb28dc 2013-03-08 rsc if(xev->type == KeyPress)
578 36bb28dc 2013-03-08 rsc c |= ControlMask;
579 36bb28dc 2013-03-08 rsc else
580 36bb28dc 2013-03-08 rsc c &= ~ControlMask;
581 36bb28dc 2013-03-08 rsc goto kbutton;
582 36bb28dc 2013-03-08 rsc case XK_Alt_L:
583 36bb28dc 2013-03-08 rsc case XK_Shift_L:
584 36bb28dc 2013-03-08 rsc if(xev->type == KeyPress)
585 36bb28dc 2013-03-08 rsc c |= Mod1Mask;
586 36bb28dc 2013-03-08 rsc else
587 36bb28dc 2013-03-08 rsc c &= ~Mod1Mask;
588 36bb28dc 2013-03-08 rsc kbutton:
589 36bb28dc 2013-03-08 rsc kstate = c;
590 36bb28dc 2013-03-08 rsc if(m.buttons || kbuttons) {
591 36bb28dc 2013-03-08 rsc altdown = 0; // used alt
592 36bb28dc 2013-03-08 rsc kbuttons = 0;
593 36bb28dc 2013-03-08 rsc if(c & ControlMask)
594 36bb28dc 2013-03-08 rsc kbuttons |= 2;
595 36bb28dc 2013-03-08 rsc if(c & Mod1Mask)
596 36bb28dc 2013-03-08 rsc kbuttons |= 4;
597 36bb28dc 2013-03-08 rsc sendmouse(m);
598 36bb28dc 2013-03-08 rsc break;
599 36bb28dc 2013-03-08 rsc }
600 36bb28dc 2013-03-08 rsc }
601 36bb28dc 2013-03-08 rsc
602 36bb28dc 2013-03-08 rsc if(xev->type != KeyPress)
603 36bb28dc 2013-03-08 rsc break;
604 35288690 2008-01-30 rsc if(k == XK_F11){
605 35288690 2008-01-30 rsc fullscreen = !fullscreen;
606 c155dcfe 2008-01-30 rsc _xmovewindow(fullscreen ? screenrect : windowrect);
607 35288690 2008-01-30 rsc return;
608 35288690 2008-01-30 rsc }
609 36bb28dc 2013-03-08 rsc if(kbd.stall)
610 36bb28dc 2013-03-08 rsc return;
611 c66b5250 2006-06-25 devnull if((c = _xtoplan9kbd(xev)) < 0)
612 c66b5250 2006-06-25 devnull return;
613 c66b5250 2006-06-25 devnull kbd.r[kbd.wi++] = c;
614 c66b5250 2006-06-25 devnull if(kbd.wi == nelem(kbd.r))
615 c66b5250 2006-06-25 devnull kbd.wi = 0;
616 c66b5250 2006-06-25 devnull if(kbd.ri == kbd.wi)
617 c66b5250 2006-06-25 devnull kbd.stall = 1;
618 c66b5250 2006-06-25 devnull matchkbd();
619 4b58d457 2011-09-28 rsc break;
620 4b58d457 2011-09-28 rsc
621 4b58d457 2011-09-28 rsc case FocusOut:
622 d74fdb6e 2013-07-17 rogpeppe /*
623 d74fdb6e 2013-07-17 rogpeppe * Some key combinations (e.g. Alt-Tab) can cause us
624 d74fdb6e 2013-07-17 rogpeppe * to see the key down event without the key up event,
625 d74fdb6e 2013-07-17 rogpeppe * so clear out the keyboard state when we lose the focus.
626 d74fdb6e 2013-07-17 rogpeppe */
627 d74fdb6e 2013-07-17 rogpeppe kstate = 0;
628 042a0698 2014-01-22 rsc altdown = 0;
629 4b58d457 2011-09-28 rsc abortcompose();
630 c66b5250 2006-06-25 devnull break;
631 c66b5250 2006-06-25 devnull
632 c66b5250 2006-06-25 devnull case SelectionRequest:
633 c66b5250 2006-06-25 devnull _xselect(xev);
634 c66b5250 2006-06-25 devnull break;
635 c66b5250 2006-06-25 devnull }
636 c66b5250 2006-06-25 devnull }
637 c66b5250 2006-06-25 devnull