[plt-scheme] MzScheme: extending vs. embedding to build a text editor

From: Ben Goetter (goetter at mazama.net)
Date: Tue Jul 15 11:15:31 EDT 2008

Matthew Flatt wrote:
> At Sun, 13 Jul 2008 16:57:12 -0700, "Peter Michaux" wrote:
>   
>> First, I could write MzScheme extensions [1] for ncurses.
> I would do it this way, but probably using `scheme/foreign' instead of
> creating an extension:
>
>  http://docs.plt-scheme.org/foreign/index.html
>   
Yes, no need for an extension.  ncurses is quite straightforward to use 
with the PLT FFI.  The following uses the v360/372-era FFI syntax.

---this is curses.scm---
(module curses mzscheme

(require (lib "foreign.ss"))
(unsafe!)

(provide
 initscr cbreak noecho move addch addstr refresh wgetch getch endwin
 get-cols get-lines)

(define libcurses (ffi-lib (if (eq? (system-type) 'windows) "pdcurses" 
"libncurses")))

(define initscr
  (get-ffi-obj "initscr" libcurses (_fun -> _pointer)))
(define cbreak
  (get-ffi-obj "cbreak" libcurses (_fun -> _int)))
(define noecho
  (get-ffi-obj "noecho" libcurses (_fun -> _int)))
(define move
  (get-ffi-obj "move" libcurses (_fun _int _int -> _int)))

(define _chtype (make-ctype _int char->integer integer->char))

(define addch
  (get-ffi-obj "addch" libcurses (_fun _chtype -> _int)))
(define addstr
  (get-ffi-obj "addstr" libcurses (_fun _string/locale -> _int)))
(define refresh
  (get-ffi-obj "refresh" libcurses (_fun -> _int)))

(define _win (_cpointer "CURSES WINDOW"))

(define wgetch
  (get-ffi-obj "wgetch" libcurses (_fun _win -> _chtype)))

(define stdscr
  (make-c-parameter "stdscr" libcurses _win))
(define (getch) (wgetch (stdscr)))

(define COLS
  (make-c-parameter "COLS" libcurses _int))
(define LINES
  (make-c-parameter "LINES" libcurses _int))
; had trouble exporting these two for some reason... maybe case 
sensitivity doesn't work across module borders?
(define (get-cols) (COLS))
(define (get-lines) (LINES))

(define endwin
  (get-ffi-obj "endwin" libcurses (_fun -> _int)))

) ; module curses


---this is a trivial test of the above---

(require "curses.scm")

(define (test)
  (dynamic-wind
      (lambda ()
    (initscr)
    (cbreak)
    (noecho))
      (lambda ()
    (move 8 10)
    (addstr "Hello, World!")
    (addch #\newline)
    (addstr (number->string (get-cols)))
    (addstr " columns, ")
    (addstr (number->string (get-lines)))
    (addstr " lines.")
    (addch #\newline)
    (addstr "Press any key to continue.")
    (refresh)
    (getch)) ; where's the "any" key?
      (lambda ()
    (endwin))
    ))



Posted on the users mailing list.