Blame


1 76193d7c 2003-09-30 devnull #include <u.h>
2 be22ae2d 2004-03-26 devnull #include "x11-inc.h"
3 76193d7c 2003-09-30 devnull #include <libc.h>
4 76193d7c 2003-09-30 devnull #include <draw.h>
5 76193d7c 2003-09-30 devnull #include <thread.h>
6 76193d7c 2003-09-30 devnull #include <cursor.h>
7 76193d7c 2003-09-30 devnull #include <mouse.h>
8 76193d7c 2003-09-30 devnull #include <memdraw.h>
9 76193d7c 2003-09-30 devnull #include "x11-memdraw.h"
10 76193d7c 2003-09-30 devnull
11 4f30f3b4 2004-03-30 devnull int _windowhasfocus = 1;
12 4f30f3b4 2004-03-30 devnull int _wantfocuschanges;
13 4f30f3b4 2004-03-30 devnull
14 76193d7c 2003-09-30 devnull void
15 76193d7c 2003-09-30 devnull moveto(Mousectl *m, Point pt)
16 76193d7c 2003-09-30 devnull {
17 32f69c36 2003-12-11 devnull _xmoveto(pt);
18 76193d7c 2003-09-30 devnull }
19 76193d7c 2003-09-30 devnull
20 76193d7c 2003-09-30 devnull void
21 76193d7c 2003-09-30 devnull closemouse(Mousectl *mc)
22 76193d7c 2003-09-30 devnull {
23 76193d7c 2003-09-30 devnull if(mc == nil)
24 76193d7c 2003-09-30 devnull return;
25 76193d7c 2003-09-30 devnull
26 76193d7c 2003-09-30 devnull /* postnote(PNPROC, mc->pid, "kill");
27 76193d7c 2003-09-30 devnull */
28 76193d7c 2003-09-30 devnull do; while(nbrecv(mc->c, &mc->m) > 0);
29 76193d7c 2003-09-30 devnull close(mc->mfd);
30 76193d7c 2003-09-30 devnull close(mc->cfd);
31 76193d7c 2003-09-30 devnull free(mc->file);
32 76193d7c 2003-09-30 devnull chanfree(mc->c);
33 76193d7c 2003-09-30 devnull chanfree(mc->resizec);
34 76193d7c 2003-09-30 devnull free(mc);
35 76193d7c 2003-09-30 devnull }
36 76193d7c 2003-09-30 devnull
37 76193d7c 2003-09-30 devnull int
38 76193d7c 2003-09-30 devnull readmouse(Mousectl *mc)
39 76193d7c 2003-09-30 devnull {
40 76193d7c 2003-09-30 devnull if(mc->display)
41 76193d7c 2003-09-30 devnull flushimage(mc->display, 1);
42 76193d7c 2003-09-30 devnull if(recv(mc->c, &mc->m) < 0){
43 76193d7c 2003-09-30 devnull fprint(2, "readmouse: %r\n");
44 76193d7c 2003-09-30 devnull return -1;
45 76193d7c 2003-09-30 devnull }
46 76193d7c 2003-09-30 devnull return 0;
47 76193d7c 2003-09-30 devnull }
48 76193d7c 2003-09-30 devnull
49 76193d7c 2003-09-30 devnull static
50 76193d7c 2003-09-30 devnull void
51 76193d7c 2003-09-30 devnull _ioproc(void *arg)
52 76193d7c 2003-09-30 devnull {
53 b20f06ab 2004-12-26 devnull int fd, one, buttons;
54 4f30f3b4 2004-03-30 devnull Atom a;
55 161060a4 2003-10-11 devnull ulong mask;
56 76193d7c 2003-09-30 devnull Mouse m;
57 76193d7c 2003-09-30 devnull Mousectl *mc;
58 76193d7c 2003-09-30 devnull XEvent xevent;
59 76193d7c 2003-09-30 devnull
60 76193d7c 2003-09-30 devnull one = 1;
61 76193d7c 2003-09-30 devnull mc = arg;
62 76193d7c 2003-09-30 devnull threadsetname("mouseproc");
63 76193d7c 2003-09-30 devnull memset(&m, 0, sizeof m);
64 76193d7c 2003-09-30 devnull mc->pid = getpid();
65 161060a4 2003-10-11 devnull mask = MouseMask|ExposureMask|StructureNotifyMask;
66 161060a4 2003-10-11 devnull XSelectInput(_x.mousecon, _x.drawable, mask);
67 5a8e63b2 2004-02-29 devnull fd = XConnectionNumber(_x.mousecon);
68 b20f06ab 2004-12-26 devnull buttons = 0;
69 76193d7c 2003-09-30 devnull for(;;){
70 161060a4 2003-10-11 devnull XNextEvent(_x.mousecon, &xevent);
71 76193d7c 2003-09-30 devnull switch(xevent.type){
72 76193d7c 2003-09-30 devnull case Expose:
73 32f69c36 2003-12-11 devnull _xexpose(&xevent, _x.mousecon);
74 76193d7c 2003-09-30 devnull continue;
75 16a70966 2003-11-23 devnull case DestroyNotify:
76 32f69c36 2003-12-11 devnull if(_xdestroy(&xevent, _x.mousecon)){
77 16a70966 2003-11-23 devnull /* drain it before sending */
78 16a70966 2003-11-23 devnull /* apps that care can notice we sent a 0 */
79 16a70966 2003-11-23 devnull /* otherwise we'll have getwindow send SIGHUP */
80 16a70966 2003-11-23 devnull nbrecv(mc->resizec, 0);
81 16a70966 2003-11-23 devnull nbrecv(mc->resizec, 0);
82 16a70966 2003-11-23 devnull send(mc->resizec, 0);
83 16a70966 2003-11-23 devnull }
84 16a70966 2003-11-23 devnull continue;
85 76193d7c 2003-09-30 devnull case ConfigureNotify:
86 32f69c36 2003-12-11 devnull if(_xconfigure(&xevent, _x.mousecon))
87 76193d7c 2003-09-30 devnull nbsend(mc->resizec, &one);
88 76193d7c 2003-09-30 devnull continue;
89 161060a4 2003-10-11 devnull case SelectionRequest:
90 32f69c36 2003-12-11 devnull _xselect(&xevent, _x.mousecon);
91 161060a4 2003-10-11 devnull continue;
92 76193d7c 2003-09-30 devnull case ButtonPress:
93 76193d7c 2003-09-30 devnull case ButtonRelease:
94 76193d7c 2003-09-30 devnull case MotionNotify:
95 732be70c 2004-03-31 devnull /* If the motion notifications are backing up, skip over some. */
96 b20f06ab 2004-12-26 devnull if(0 && xevent.type == MotionNotify){
97 732be70c 2004-03-31 devnull while(XCheckWindowEvent(_x.mousecon, _x.drawable, MouseMask, &xevent)){
98 732be70c 2004-03-31 devnull if(xevent.type != MotionNotify)
99 732be70c 2004-03-31 devnull break;
100 732be70c 2004-03-31 devnull }
101 732be70c 2004-03-31 devnull }
102 b20f06ab 2004-12-26 devnull m.buttons = buttons;
103 32f69c36 2003-12-11 devnull if(_xtoplan9mouse(_x.mousecon, &xevent, &m) < 0)
104 76193d7c 2003-09-30 devnull continue;
105 b20f06ab 2004-12-26 devnull buttons = m.buttons;
106 76193d7c 2003-09-30 devnull send(mc->c, &m);
107 76193d7c 2003-09-30 devnull /*
108 76193d7c 2003-09-30 devnull * mc->Mouse is updated after send so it doesn't have wrong value if we block during send.
109 76193d7c 2003-09-30 devnull * This means that programs should receive into mc->Mouse (see readmouse() above) if
110 76193d7c 2003-09-30 devnull * they want full synchrony.
111 76193d7c 2003-09-30 devnull */
112 76193d7c 2003-09-30 devnull mc->m = m;
113 76193d7c 2003-09-30 devnull break;
114 4f30f3b4 2004-03-30 devnull case ClientMessage:
115 4f30f3b4 2004-03-30 devnull if(xevent.xclient.message_type == _x.wmprotos){
116 4f30f3b4 2004-03-30 devnull a = xevent.xclient.data.l[0];
117 4f30f3b4 2004-03-30 devnull if(_wantfocuschanges && a == _x.takefocus){
118 4f30f3b4 2004-03-30 devnull _windowhasfocus = 1;
119 4f30f3b4 2004-03-30 devnull _x.newscreenr = _x.screenr;
120 4f30f3b4 2004-03-30 devnull nbsend(mc->resizec, &one);
121 4f30f3b4 2004-03-30 devnull }else if(_wantfocuschanges && a == _x.losefocus){
122 4f30f3b4 2004-03-30 devnull _windowhasfocus = 0;
123 4f30f3b4 2004-03-30 devnull _x.newscreenr = _x.screenr;
124 4f30f3b4 2004-03-30 devnull nbsend(mc->resizec, &one);
125 4f30f3b4 2004-03-30 devnull }
126 4f30f3b4 2004-03-30 devnull }
127 4f30f3b4 2004-03-30 devnull break;
128 76193d7c 2003-09-30 devnull }
129 76193d7c 2003-09-30 devnull }
130 76193d7c 2003-09-30 devnull }
131 76193d7c 2003-09-30 devnull
132 76193d7c 2003-09-30 devnull Mousectl*
133 76193d7c 2003-09-30 devnull initmouse(char *file, Image *i)
134 76193d7c 2003-09-30 devnull {
135 76193d7c 2003-09-30 devnull Mousectl *mc;
136 76193d7c 2003-09-30 devnull
137 76193d7c 2003-09-30 devnull mc = mallocz(sizeof(Mousectl), 1);
138 76193d7c 2003-09-30 devnull if(i)
139 76193d7c 2003-09-30 devnull mc->display = i->display;
140 76193d7c 2003-09-30 devnull mc->c = chancreate(sizeof(Mouse), 0);
141 b20f06ab 2004-12-26 devnull chansetname(mc->c, "mousec");
142 76193d7c 2003-09-30 devnull mc->resizec = chancreate(sizeof(int), 2);
143 b20f06ab 2004-12-26 devnull chansetname(mc->resizec, "resizec");
144 b20f06ab 2004-12-26 devnull proccreate(_ioproc, mc, 32768);
145 76193d7c 2003-09-30 devnull return mc;
146 76193d7c 2003-09-30 devnull }
147 76193d7c 2003-09-30 devnull
148 76193d7c 2003-09-30 devnull void
149 76193d7c 2003-09-30 devnull setcursor(Mousectl *mc, Cursor *c)
150 76193d7c 2003-09-30 devnull {
151 32f69c36 2003-12-11 devnull _xsetcursor(c);
152 76193d7c 2003-09-30 devnull }
153 76193d7c 2003-09-30 devnull
154 78802e69 2004-04-24 devnull /*
155 78802e69 2004-04-24 devnull * Send the mouse event back to the window manager.
156 78802e69 2004-04-24 devnull * So that 9term can tell rio to pop up its button3 menu.
157 78802e69 2004-04-24 devnull * Note that we're using _x.mousecon in a few places,
158 78802e69 2004-04-24 devnull * so we have to be sure that the mouse proc isn't using it
159 78802e69 2004-04-24 devnull * when we call! This is all a bit wonky and should be
160 78802e69 2004-04-24 devnull * avoided unless you know what you're doing.
161 78802e69 2004-04-24 devnull */
162 4f30f3b4 2004-03-30 devnull void
163 4f30f3b4 2004-03-30 devnull bouncemouse(Mouse *m)
164 4f30f3b4 2004-03-30 devnull {
165 4f30f3b4 2004-03-30 devnull XButtonEvent e;
166 78802e69 2004-04-24 devnull XWindow dw;
167 4f30f3b4 2004-03-30 devnull
168 4f30f3b4 2004-03-30 devnull e.type = ButtonPress;
169 4f30f3b4 2004-03-30 devnull e.state = 0;
170 4f30f3b4 2004-03-30 devnull e.button = 0;
171 4f30f3b4 2004-03-30 devnull if(m->buttons&1)
172 4f30f3b4 2004-03-30 devnull e.button = 1;
173 4f30f3b4 2004-03-30 devnull else if(m->buttons&2)
174 4f30f3b4 2004-03-30 devnull e.button = 2;
175 4f30f3b4 2004-03-30 devnull else if(m->buttons&4)
176 4f30f3b4 2004-03-30 devnull e.button = 3;
177 78802e69 2004-04-24 devnull e.same_screen = 1;
178 78802e69 2004-04-24 devnull XTranslateCoordinates(_x.display, _x.drawable,
179 78802e69 2004-04-24 devnull DefaultRootWindow(_x.display),
180 78802e69 2004-04-24 devnull m->xy.x, m->xy.y, &e.x_root, &e.y_root, &dw);
181 78802e69 2004-04-24 devnull e.root = DefaultRootWindow(_x.mousecon);
182 78802e69 2004-04-24 devnull e.window = e.root;
183 78802e69 2004-04-24 devnull e.subwindow = None;
184 78802e69 2004-04-24 devnull e.x = e.x_root;
185 78802e69 2004-04-24 devnull e.y = e.y_root;
186 4f30f3b4 2004-03-30 devnull #undef time
187 4f30f3b4 2004-03-30 devnull e.time = CurrentTime;
188 78802e69 2004-04-24 devnull XUngrabPointer(_x.mousecon, m->msec);
189 78802e69 2004-04-24 devnull XSendEvent(_x.mousecon, e.root, True, ButtonPressMask, (XEvent*)&e);
190 78802e69 2004-04-24 devnull XFlush(_x.mousecon);
191 4f30f3b4 2004-03-30 devnull }