ref: d180b70c6c69ffe8168cc8571772ad6e15ac6aba
dir: /event.myr/
use std
use sys
use thread
use "types"
pkg draw =
const event : (dpy : display# -> event#)
pkglocal const mouseproc : (dpy : display# -> void)
pkglocal const kbdproc : (dpy : display# -> void)
pkglocal const refrproc : (dpy : display# -> void)
;;
const mouseproc = {dpy
var buf : byte[49]
var sp : byte[:][5]
var ev : event#
var x, y, b, o
o = -1
while true
match std.read(dpy.mousefd, buf[:])
| `std.Ok 49: /* got the message */
| `std.Ok _: break
| `std.Err _: break
;;
std.bstrtok(sp[:], buf[:])
x = std.getv(std.intparse(sp[1]), 0)
y = std.getv(std.intparse(sp[2]), 0)
b = std.getv(std.intparse(sp[3]), 0)
if o < 0
o = b
;;
match sp[0]
| "r": ev = std.mk(`Resize)
| "m": ev = std.mk(`Mmove (x, y))
| chr: std.fatal("garbled mouse message")
;;
send(dpy, &dpy.mousep, ev)
if b > o
ev = std.mk(`Mdown (x, y, b))
send(dpy, &dpy.mousep, ev)
elif b < o
ev = std.mk(`Mup (x, y, b))
send(dpy, &dpy.mousep, ev)
;;
o = b
;;
}
const kbdproc = {dpy
var buf : byte[128]
var ev : event#
var k, c, s
while true
match std.read(dpy.kbdfd, buf[:])
| `std.Err e: break
| `std.Ok 0: break
| `std.Ok n:
c = -1
s = std.cstrconv(buf[:n])
(k, s) = std.charstep(s)
match k
| 'k': /* drop */
while s.len > 0 && c != 0
(c, s) = std.charstep(s)
if dpy.rawevt
send(dpy, &dpy.kbdp, std.mk(`Kp c))
;;
;;
| 'K':
while s.len > 0 && c != 0
(c, s) = std.charstep(s)
if dpy.rawevt
send(dpy, &dpy.kbdp, std.mk(`Kr c))
;;
;;
| 'c':
while s.len > 0 && c != 0
(c, s) = std.charstep(s)
send(dpy, &dpy.kbdp, std.mk(`Kp c))
;;
| _:
std.die("fail")
;;
;;
;;
:fail
}
const refrproc = {dpy
var buf : byte[128]
var ev : event#
while true
std.read(dpy.refrfd, buf[:])
ev = std.mk(`Refresh)
send(dpy, &dpy.refrp, ev)
;;
}
const event = {dpy
var p, r
thread.mtxlock(&dpy.qmtx)
/* find tag for rendezvous */
for evp : [dpy.refrp, dpy.mousep, dpy.kbdp][:]
if evp != (0 : void#)
p = evp
goto found
;;
;;
/* if we couldn't find a tag, enqueue ourselves */
p = (dpy : void#)
for qp : [&dpy.refrp, &dpy.mousep, &dpy.kbdp][:]
qp# = p
;;
:found
thread.mtxunlock(&dpy.qmtx)
r = (-1 : void#)
while r == (-1 : void#)
r = sys.rendezvous(p, (0 : void#))
;;
/* now dequeue */
thread.mtxlock(&dpy.qmtx)
for qp : [&dpy.refrp, &dpy.mousep, &dpy.kbdp][:]
if qp# == (dpy : void#)
qp# = (0 : void#)
;;
;;
thread.mtxunlock(&dpy.qmtx)
-> (r : event#)
}
const send = {dpy, qp, evp
var p, r
thread.mtxlock(&dpy.qmtx)
if qp# == (0 : void#)
/* nobody is queued; we enquue ourselves */
p = (qp : void#)
qp# = p
else
/* somebody is waiting, use their tag */
p = qp#
qp# = (0 : void#)
;;
thread.mtxunlock(&dpy.qmtx)
r = (-1 : void#)
while r == (-1 : void#)
r = sys.rendezvous(p, (evp : void#))
;;
/* now dequeue */
thread.mtxlock(&dpy.qmtx)
if qp# == (qp : void#)
qp# = (0 : void#)
;;
thread.mtxunlock(&dpy.qmtx)
}