aboutsummaryrefslogtreecommitdiff
path: root/src/libdraw/x11-mouse.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/libdraw/x11-mouse.c')
-rw-r--r--src/libdraw/x11-mouse.c107
1 files changed, 107 insertions, 0 deletions
diff --git a/src/libdraw/x11-mouse.c b/src/libdraw/x11-mouse.c
new file mode 100644
index 00000000..c6a26851
--- /dev/null
+++ b/src/libdraw/x11-mouse.c
@@ -0,0 +1,107 @@
+#include "x11-inc.h"
+#include <u.h>
+#include <libc.h>
+#include <draw.h>
+#include <thread.h>
+#include <cursor.h>
+#include <mouse.h>
+#include <memdraw.h>
+#include "x11-memdraw.h"
+
+void
+moveto(Mousectl *m, Point pt)
+{
+ xmoveto(pt);
+}
+
+void
+closemouse(Mousectl *mc)
+{
+ if(mc == nil)
+ return;
+
+/* postnote(PNPROC, mc->pid, "kill");
+*/
+ do; while(nbrecv(mc->c, &mc->m) > 0);
+ close(mc->mfd);
+ close(mc->cfd);
+ free(mc->file);
+ chanfree(mc->c);
+ chanfree(mc->resizec);
+ free(mc);
+}
+
+int
+readmouse(Mousectl *mc)
+{
+ if(mc->display)
+ flushimage(mc->display, 1);
+ if(recv(mc->c, &mc->m) < 0){
+ fprint(2, "readmouse: %r\n");
+ return -1;
+ }
+ return 0;
+}
+
+static
+void
+_ioproc(void *arg)
+{
+ int one;
+ Mouse m;
+ Mousectl *mc;
+ XEvent xevent;
+
+ one = 1;
+ mc = arg;
+ threadsetname("mouseproc");
+ memset(&m, 0, sizeof m);
+ mc->pid = getpid();
+ for(;;){
+ XSelectInput(_x.mousecon, _x.drawable, MouseMask|ExposureMask|StructureNotifyMask);
+ XWindowEvent(_x.mousecon, _x.drawable, MouseMask|ExposureMask|StructureNotifyMask, &xevent);
+ switch(xevent.type){
+ case Expose:
+ xexpose(&xevent, _x.mousecon);
+ continue;
+ case ConfigureNotify:
+ if(xconfigure(&xevent, _x.mousecon))
+ nbsend(mc->resizec, &one);
+ continue;
+ case ButtonPress:
+ case ButtonRelease:
+ case MotionNotify:
+ if(xtoplan9mouse(&xevent, &m) < 0)
+ continue;
+ send(mc->c, &m);
+ /*
+ * mc->Mouse is updated after send so it doesn't have wrong value if we block during send.
+ * This means that programs should receive into mc->Mouse (see readmouse() above) if
+ * they want full synchrony.
+ */
+ mc->m = m;
+ break;
+ }
+ }
+}
+
+Mousectl*
+initmouse(char *file, Image *i)
+{
+ Mousectl *mc;
+
+ mc = mallocz(sizeof(Mousectl), 1);
+ if(i)
+ mc->display = i->display;
+ mc->c = chancreate(sizeof(Mouse), 0);
+ mc->resizec = chancreate(sizeof(int), 2);
+ proccreate(_ioproc, mc, 16384);
+ return mc;
+}
+
+void
+setcursor(Mousectl *mc, Cursor *c)
+{
+ xsetcursor(c);
+}
+