* fun with wayland
@ 2023-02-05 19:05 Matt Wette
2023-02-06 2:59 ` 宋文武
2023-02-06 7:25 ` Sascha Ziemann
0 siblings, 2 replies; 8+ messages in thread
From: Matt Wette @ 2023-02-05 19:05 UTC (permalink / raw)
To: Guile User
I finally got my Wayland demo in guile working. I thought I'd share
some bits.
(I started with creating FFI to libwayland, but with all the callbacks
it was
not worth it.)
Wayland is a display server for Linux (and others?), meant to replace X11.
It uses UNIX socket I/O between the "compositor" (i.e., server) and clients.
I have written a client app without using libwayland: I've coded down
to the
socket protocol in Guile Scheme.
Summary:
1) I created sendmsg/recvmsg! wrappers for Guile, in C. This allows me
to send file descriptors as shared buffer references to the server.
2) I am using my proposed mmap wrapper for Guile, in C, to create a file-
mapped shared drawing.
3) I created a "scanner" program in Guile that converts protocol specs
(e.g., wayland.xml) to scheme.
4) I created "sender", "receiver" and "monitor" tasks within Fibers to
run the client app
5) I used my ffi-helper generated code to use cairo for drawing.
prototype code is located at https://github.com/mwette/guile-wl-play
Here are some snippets:
;; auto-generated by "scanner" from wayland.xml:
(define-public encode-wl_display:sync
(lambda (obj-id bv ix callback)
(define (encode-body)
(bytevector-u32-native-set! bv (+ ix 8) callback)
(values (+ ix 12) #f))
(call-with-values
encode-body
(lambda (msg-size control)
(bytevector-u32-native-set! bv ix obj-id)
(bytevector-u16-native-set! bv (+ ix 6) msg-size)
(bytevector-u16-native-set! bv (+ ix 4) 0)
(values msg-size control)))))
;; dispatch routine to handle events from socket
(define (dispatch obj-id opcode bv ix cm)
(let* ((dec-vec (vector-ref object-decoders-vec obj-id))
(decoder (and (vector-ref dec-vec opcode)))
(hlr-vec (vector-ref object-handlers-vec obj-id))
(handler (and (vector-ref hlr-vec opcode))))
(if (and decoder handler)
(call-with-values (lambda () (decoder obj-id bv ix cm)) handler)
(begin
(sferr "dispatch: missing decoder or handler: id=~S op=~S\n"
obj-id opcode)
(sferr " dec-vec?=~S decoder?=~S hlr-vec?=~S handler?=~S\n"
(and dec-vec #t) (and decoder #t)
(and hlr-vec #t) (and handler #t))))))
(define-syntax define-wl-request
(lambda (x)
(syntax-case x ()
((_ iface meth arg ...)
#`(define (#,(gen-id x #'iface ":" #'meth) obj-id arg ...)
(when wl-debug (sferr "=> ~S:~S ...\n" 'iface 'meth))
(put-message rq-chan
(lambda ()
(#,(gen-id x "encode-" #'iface ":" #'meth)
obj-id rq-iobuf 0 arg ...))))))))
(define-wl-request wl_display sync callback)
(define (handle-wl_callback:done obj-id callback-data)
(let ((val (vector-ref object-value-vec obj-id)))
(if (condition? val) (signal-condition! val))
(vector-set! object-value-vec obj-id #f)))
(define (sync-and-wait)
(let ((id (alloc-id)) (cd (make-condition)))
(set-object! id 'wl_callback cd)
(wl_display:sync display-id id)
(wait cd)))
(define socket-path
(let ((dir (getenv "XDG_RUNTIME_DIR"))
(dpy (getenv "WAYLAND_DISPLAY")))
(and dir dpy (string-append dir "/" dpy))))
(define (connect-display)
(let* ((path socket-path)
(style (logior SOCK_STREAM SOCK_CLOEXEC))
(sock (socket PF_UNIX style 0))
(conn (connect sock AF_UNIX path)))
(fcntl sock F_SETFL (logior O_NONBLOCK (fcntl sock F_GETFL)))
(set! rq-iobuf (make-bytevector 1024))
(set! ev-iobuf (make-bytevector 1024))
sock))
(define (sender)
(let loop ((n-sent 0) (n-left 0) (cm #f) (rqq '()))
(fsleep 0.01)
(cond
((positive? n-left)
(let ((n (sendmsg wl-sock rq-iobuf n-sent n-left cm)))
(loop (+ n-sent n) (- n-left n) #f rqq)))
((pair? rqq)
(call-with-values (car rqq)
(lambda (ln cm)
(loop 0 ln cm (cdr rqq)))))
((get-message rq-chan) =>
(lambda (req)
(loop n-sent n-left cm (cons req rqq))))
(else
(sferr "sender says wtf\n")))))
(define (receiver)
(let loop ((n-have 0) (object-id #f) (msg-size 8) (opcode #f)
(control #f))
(cond
((< n-have msg-size)
(let* ((res (recvmsg! wl-sock ev-iobuf n-have))
(n-read (vector-ref res 0))
(control (or control (vector-ref res 1)))
(flags (vector-ref res 2)))
(when (zero? n-read) (fsleep 0.1)) ; SLEEP HERE
(loop (+ n-have n-read) object-id msg-size opcode control)))
((not object-id)
(let* ((object-id (bytevector-u32-native-ref ev-iobuf 0))
(word1 (bytevector-u32-native-ref ev-iobuf 4))
(msg-size (bytevector-u16-native-ref ev-iobuf
msg-size-offset))
(opcode (bytevector-u16-native-ref ev-iobuf opcode-offset)))
(loop n-have object-id msg-size opcode control)))
(else
(dispatch object-id opcode ev-iobuf 8 control)
(if (> n-have msg-size)
(bytevector-copy! ev-iobuf msg-size ev-iobuf 0 (- n-have
msg-size)))
(loop (- n-have msg-size) #f 8 opcode control)))))
(define (monitor)
(sferr "monitor starting ...\n")
(let* ((server (spawn-coop-repl-server)))
(let loop ()
(poll-coop-repl-server server)
(yield-current-task)
(fsleep 0.1)
(loop))))
(define done-cond #f)
(define (done)
(and done-cond (signal-condition! done-cond)))
(define (appl-main)
(run-fibers
(lambda ()
(set! wl-sock (connect-display))
(set! done-cond (make-condition))
(set! rq-chan (make-channel))
(install-handlers)
(init-object-pool)
;;
(spawn-fiber receiver)
(spawn-fiber sender)
(get-registry)
(sync-and-wait)
(init-globals)
(sync-and-wait)
(create-file-buffer)
(spawn-fiber monitor)
;;
(create-it)
;;(wait done-cond)
(fsleep 3.0)
(force-output (current-error-port))
(close-port wl-sock))
#:hz 0 #:install-suspendable-ports? #f))
(use-modules (ffi ffi-help-rt))
(use-modules (ffi cairo))
(define* (create-file-buffer #:optional (size #x1000000))
(let* ((port (let ((port (tmpfile))) (truncate-file port size) port))
(fd (port->fdes port))
(bv (my-mmap 0 size (logior PROT_READ PROT_WRITE) MAP_SHARED
fd 0)))
(set! my-buf-bv bv)
(set! my-buf-fd fd)
(if #f #f)))
(define (draw-buffer)
(let* ((format 'CAIRO_FORMAT_ARGB32)
(format 'CAIRO_FORMAT_RGB24)
(buffer my-buf-bv)
(width 500) (height 300) (stride (* width 4))
(srf (cairo_image_surface_create_for_data
buffer format width height stride))
(cro (cairo_create srf))
(extents (make-cairo_text_extents_t))
(text "Hello, world!"))
(bytevector-fill! buffer #xee)
(cairo_move_to cro 0.0 0.0)
(cairo_move_to cro 20.0 20.0)
(cairo_line_to cro 120.0 120.0)
(cairo_stroke cro)
(cairo_select_font_face
cro "Sans" 'CAIRO_FONT_SLANT_NORMAL 'CAIRO_FONT_WEIGHT_NORMAL)
(cairo_set_font_size cro 32.0)
(cairo_text_extents cro text (pointer-to extents))
(cairo_move_to cro 50.0 50.0)
(cairo_show_text cro text)
(if #f #f)))
(appl-main)
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: fun with wayland
2023-02-05 19:05 fun with wayland Matt Wette
@ 2023-02-06 2:59 ` 宋文武
2023-02-06 7:25 ` Sascha Ziemann
1 sibling, 0 replies; 8+ messages in thread
From: 宋文武 @ 2023-02-06 2:59 UTC (permalink / raw)
To: Matt Wette; +Cc: Guile User
Matt Wette <matt.wette@gmail.com> writes:
> I finally got my Wayland demo in guile working. I thought I'd share
> some bits.
> (I started with creating FFI to libwayland, but with all the callbacks
> it was
> not worth it.)
>
> Wayland is a display server for Linux (and others?), meant to replace X11.
> It uses UNIX socket I/O between the "compositor" (i.e., server) and clients.
> I have written a client app without using libwayland: I've coded down
> to the
> socket protocol in Guile Scheme.
>
> Summary:
> 1) I created sendmsg/recvmsg! wrappers for Guile, in C. This allows me
> to send file descriptors as shared buffer references to the server.
> 2) I am using my proposed mmap wrapper for Guile, in C, to create a file-
> mapped shared drawing.
> 3) I created a "scanner" program in Guile that converts protocol specs
> (e.g., wayland.xml) to scheme.
> 4) I created "sender", "receiver" and "monitor" tasks within Fibers to
> run the client app
> 5) I used my ffi-helper generated code to use cairo for drawing.
>
> prototype code is located at https://github.com/mwette/guile-wl-play
Cool, I will definitely play/learn with it, thank you for sharing!
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: fun with wayland
2023-02-05 19:05 fun with wayland Matt Wette
2023-02-06 2:59 ` 宋文武
@ 2023-02-06 7:25 ` Sascha Ziemann
2023-02-06 13:30 ` Matt Wette
1 sibling, 1 reply; 8+ messages in thread
From: Sascha Ziemann @ 2023-02-06 7:25 UTC (permalink / raw)
To: Guile User
Am So., 5. Feb. 2023 um 20:05 Uhr schrieb Matt Wette <matt.wette@gmail.com>:
>
> 2) I am using my proposed mmap wrapper for Guile, in C, to create a file-
> mapped shared drawing.
What is a "file-mapped shared drawing"?
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: fun with wayland
2023-02-06 7:25 ` Sascha Ziemann
@ 2023-02-06 13:30 ` Matt Wette
2023-02-07 6:09 ` Blake Shaw
0 siblings, 1 reply; 8+ messages in thread
From: Matt Wette @ 2023-02-06 13:30 UTC (permalink / raw)
To: guile-user
On 2/5/23 11:25 PM, Sascha Ziemann wrote:
> Am So., 5. Feb. 2023 um 20:05 Uhr schrieb Matt Wette <matt.wette@gmail.com>:
>> 2) I am using my proposed mmap wrapper for Guile, in C, to create a file-
>> mapped shared drawing.
> What is a "file-mapped shared drawing"?
"file-mapped shared drawing buffer" -- sorry about that.
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: fun with wayland
2023-02-06 13:30 ` Matt Wette
@ 2023-02-07 6:09 ` Blake Shaw
2023-02-11 21:50 ` Matt Wette
0 siblings, 1 reply; 8+ messages in thread
From: Blake Shaw @ 2023-02-07 6:09 UTC (permalink / raw)
To: Matt Wette; +Cc: guile-user
Wow this looks great, I currently configure my Herbstluftwm with an ad-hoc
guile edsl, but I may have to switch over to Wayland now :)
Looking forward to play with this, cheers
On Mon, Feb 6, 2023, 20:31 Matt Wette <matt.wette@gmail.com> wrote:
>
>
> On 2/5/23 11:25 PM, Sascha Ziemann wrote:
> > Am So., 5. Feb. 2023 um 20:05 Uhr schrieb Matt Wette <
> matt.wette@gmail.com>:
> >> 2) I am using my proposed mmap wrapper for Guile, in C, to create a
> file-
> >> mapped shared drawing.
> > What is a "file-mapped shared drawing"?
> "file-mapped shared drawing buffer" -- sorry about that.
>
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: fun with wayland
2023-02-07 6:09 ` Blake Shaw
@ 2023-02-11 21:50 ` Matt Wette
2023-02-12 8:25 ` Blake Shaw
0 siblings, 1 reply; 8+ messages in thread
From: Matt Wette @ 2023-02-11 21:50 UTC (permalink / raw)
To: guile-user
So, you are looking to implement a compositor?
My scanner doesn't generate that side of the protocol
(yet), but I could add it.
On 2/6/23 10:09 PM, Blake Shaw wrote:
> Wow this looks great, I currently configure my Herbstluftwm with an ad-hoc
> guile edsl, but I may have to switch over to Wayland now :)
>
> Looking forward to play with this, cheers
>
> On Mon, Feb 6, 2023, 20:31 Matt Wette <matt.wette@gmail.com> wrote:
>
>>
>> On 2/5/23 11:25 PM, Sascha Ziemann wrote:
>>> Am So., 5. Feb. 2023 um 20:05 Uhr schrieb Matt Wette <
>> matt.wette@gmail.com>:
>>>> 2) I am using my proposed mmap wrapper for Guile, in C, to create a
>> file-
>>>> mapped shared drawing.
>>> What is a "file-mapped shared drawing"?
>> "file-mapped shared drawing buffer" -- sorry about that.
>>
>>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: fun with wayland
2023-02-11 21:50 ` Matt Wette
@ 2023-02-12 8:25 ` Blake Shaw
2023-02-12 16:06 ` Matt Wette
0 siblings, 1 reply; 8+ messages in thread
From: Blake Shaw @ 2023-02-12 8:25 UTC (permalink / raw)
To: Matt Wette; +Cc: guile-user
I had just briefly browsed the email and thought it was a simple
compositor. I'll try to dig in in the near future, exciting to see someone
implementing Wayland in guile.
Perhaps a guix window manager would be be a good GSoC project suggestion 👀
On Sun, Feb 12, 2023, 04:51 Matt Wette <matt.wette@gmail.com> wrote:
> So, you are looking to implement a compositor?
> My scanner doesn't generate that side of the protocol
> (yet), but I could add it.
>
>
> On 2/6/23 10:09 PM, Blake Shaw wrote:
> > Wow this looks great, I currently configure my Herbstluftwm with an
> ad-hoc
> > guile edsl, but I may have to switch over to Wayland now :)
> >
> > Looking forward to play with this, cheers
> >
> > On Mon, Feb 6, 2023, 20:31 Matt Wette <matt.wette@gmail.com> wrote:
> >
> >>
> >> On 2/5/23 11:25 PM, Sascha Ziemann wrote:
> >>> Am So., 5. Feb. 2023 um 20:05 Uhr schrieb Matt Wette <
> >> matt.wette@gmail.com>:
> >>>> 2) I am using my proposed mmap wrapper for Guile, in C, to create a
> >> file-
> >>>> mapped shared drawing.
> >>> What is a "file-mapped shared drawing"?
> >> "file-mapped shared drawing buffer" -- sorry about that.
> >>
> >>
>
>
>
^ permalink raw reply [flat|nested] 8+ messages in thread
* Re: fun with wayland
2023-02-12 8:25 ` Blake Shaw
@ 2023-02-12 16:06 ` Matt Wette
0 siblings, 0 replies; 8+ messages in thread
From: Matt Wette @ 2023-02-12 16:06 UTC (permalink / raw)
To: guile-user
Building a compositor would be a big project:
more than a window manager, I think.
I'm adding pieces bit-by-bit. Want to experiment
with transient data structures and/or monads for this.
No GOOPS.
On 2/12/23 12:25 AM, Blake Shaw wrote:
> I had just briefly browsed the email and thought it was a simple
> compositor. I'll try to dig in in the near future, exciting to see someone
> implementing Wayland in guile.
>
> Perhaps a guix window manager would be be a good GSoC project suggestion 👀
>
> On Sun, Feb 12, 2023, 04:51 Matt Wette <matt.wette@gmail.com> wrote:
>
>> So, you are looking to implement a compositor?
>> My scanner doesn't generate that side of the protocol
>> (yet), but I could add it.
>>
>>
>> On 2/6/23 10:09 PM, Blake Shaw wrote:
>>> Wow this looks great, I currently configure my Herbstluftwm with an
>> ad-hoc
>>> guile edsl, but I may have to switch over to Wayland now :)
>>>
>>> Looking forward to play with this, cheers
>>>
>>> On Mon, Feb 6, 2023, 20:31 Matt Wette <matt.wette@gmail.com> wrote:
>>>
>>>> On 2/5/23 11:25 PM, Sascha Ziemann wrote:
>>>>> Am So., 5. Feb. 2023 um 20:05 Uhr schrieb Matt Wette <
>>>> matt.wette@gmail.com>:
>>>>>> 2) I am using my proposed mmap wrapper for Guile, in C, to create a
>>>> file-
>>>>>> mapped shared drawing.
>>>>> What is a "file-mapped shared drawing"?
>>>> "file-mapped shared drawing buffer" -- sorry about that.
>>>>
>>>>
>>
>>
^ permalink raw reply [flat|nested] 8+ messages in thread
end of thread, other threads:[~2023-02-12 16:06 UTC | newest]
Thread overview: 8+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2023-02-05 19:05 fun with wayland Matt Wette
2023-02-06 2:59 ` 宋文武
2023-02-06 7:25 ` Sascha Ziemann
2023-02-06 13:30 ` Matt Wette
2023-02-07 6:09 ` Blake Shaw
2023-02-11 21:50 ` Matt Wette
2023-02-12 8:25 ` Blake Shaw
2023-02-12 16:06 ` Matt Wette
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).