This commit is contained in:
retropikzel 2025-12-11 08:48:19 +02:00
parent 060c8fc443
commit 9db67bf049
6 changed files with 895 additions and 0 deletions

1
.gitignore vendored
View File

@ -18,4 +18,5 @@ test-r6rs
test-r7rs.scm
test-r7rs
*.html
*.rkt

692
retropikzel/pstk.scm Normal file
View File

@ -0,0 +1,692 @@
(define-c-library libc
'("stdlib.h" "stdio.h" "unistd.h")
libc-name
'((additional-versions ("0" "6"))))
(define-c-procedure c-tempnam libc 'tempnam 'pointer '(pointer pointer))
(define-c-procedure c-system libc 'system 'int '(pointer))
(define wish-display pipe-write-string)
(define wish-read (lambda (pipe)
(let ((result (pipe-read pipe)))
(if (eof-object? result)
result
(read (open-input-string result))))))
(define wish-newline
(lambda (pipe)
(pipe-write-char #\newline pipe)))
(define wish-flush (lambda () #t)) ; No need to do anything
(define wish-read-line pipe-read-line)
(define (run-program program)
(let* ((temp-prefix (string->c-utf8 "npcmd"))
(temp-name (lambda ()
(c-utf8->string (c-tempnam (make-c-null)
temp-prefix))))
(input-path (temp-name))
(output-path (temp-name))
(shell-command (string-append program
" < "
output-path
" 1> "
input-path
" 2> "
input-path
" & ")))
(create-pipe input-path 0777)
(create-pipe output-path 0777)
(c-system (string->c-utf8 shell-command))
(list (open-input-pipe input-path)
(open-output-pipe output-path))))
(define *wish-program* "tclsh")
(define *wish-debug-input* #f)
(define *wish-debug-output* #f)
(define *use-keywords?*
(cond-expand (chicken #t)
(else (or (not (symbol? 'text:))
(not (symbol? ':text))
(string=? "text" (symbol->string 'text:))
(string=? "text" (symbol->string ':text))))))
(define (keyword? x) #f) ;; TODO: handle keywords?
(define (keyword->string x) x)
(define nl (string #\newline))
(define wish-input #f)
(define wish-output #f)
(define tk-is-running #f)
(define tk-ids+widgets '())
(define tk-widgets '())
(define commands-invoked-by-tk '())
(define inverse-commands-invoked-by-tk '())
(define in-callback #f)
(define callback-mutex #t)
(define ttk-widget-map '())
(define tk-init-string
(let ((start-str '("package require Tk"
"if {[package version tile] != \"\"} {"
" package require tile"
"}"
""
"namespace eval AutoName {"
" variable c 0"
" proc autoName {{result \\#\\#}} {"
" variable c"
" append result [incr c]"
" }"
" namespace export *"
"}"
""
"namespace import AutoName::*"
""
"proc callToScm {callKey args} {"
" global scmVar"
" set resultKey [autoName]"
" puts \"(call $callKey \\\"$resultKey\\\" $args)\""
" flush stdout"
" vwait scmVar($resultKey)"
" set result $scmVar($resultKey)"
" unset scmVar($resultKey)"
" set result"
"}"
""
"proc tclListToScmList {l} {"
" switch [llength $l] {"
" 0 {"
" return ()"
" }"
" 1 {"
" if {[string range $l 0 0] eq \"\\#\"} {"
" return $l"
" }"
" if {[regexp {^[0-9]+$} $l]} {"
" return $l"
" }"
" if {[regexp {^[.[:alpha:]][^ ,\\\"\\'\\[\\]\\\\;]*$} $l]} {"
" return $l"
" }"
" set result \\\""
" append result\\"
" [string map [list \\\" \\\\\\\" \\\\ \\\\\\\\] $l]"
" append result \\\""
""
" }"
" default {"
" set result {}"
" foreach el $l {"
" append result \" \" [tclListToScmList $el]"
" }"
" set result [string range $result 1 end]"
" return \"($result)\""
" }"
" }"
"}"
""
"proc evalCmdFromScm {cmd {properly 0}} {"
" if {[catch {"
" set result [uplevel \\#0 $cmd]"
" } err]} {"
" puts \"(error \\\"[string map [list \\\\ \\\\\\\\ \\\" \\\\\\\"] $err]\\\")\""
" } elseif $properly {"
" puts \"(return [tclListToScmList $result])\""
" } else {"
" puts \"(return \\\"[string map [list \\\\ \\\\\\\\ \\\" \\\\\\\"] $result]\\\")\""
" }"
" flush stdout"
"}")))
(do ((str start-str (cdr str)) ; turn into one string with \n between each line
(res "" (string-append res (car str) nl)))
((null? str) res))))
(define report-error
(lambda (x)
(newline)
(display x)
(newline)
; (bottom x)
))
(define option?
(lambda (x)
(or (and *use-keywords?*
(keyword? x))
(and (symbol? x)
(let* ((s (symbol->string x))
(n (string-length s)))
(char=? #\: (string-ref s (- n 1))))))))
(define make-option-string
(lambda (x)
(if (and *use-keywords?*
(keyword? x))
(string-append " -" (keyword->string x))
(let ((s (symbol->string x)))
(string-append " -"
(substring s 0 (- (string-length s) 1)))))))
(define improper-list->string
(lambda (a first)
(cond ((pair? a)
(cons (string-append (if first "" " ")
(form->string (car a)))
(improper-list->string (cdr a) #f)))
((null? a) '())
(else (list (string-append " . " (form->string a)))))))
(define form->string
(lambda (x)
(cond ((eq? #t x) "#t")
((eq? #f x) "#f")
((number? x) (number->string x))
((symbol? x) (symbol->string x))
((string? x) x)
((null? x) "()")
((pair? x)
(string-append "("
(apply string-append
(improper-list->string x #t))
")"))
((eof-object? x) "#<eof>")
(else "#<other>"))))
(define string-translate
(lambda (s map)
(letrec
((s-prepend (lambda (s1 s2)
(cond ((null? s1) s2)
(else (s-prepend (cdr s1) (cons (car s1) s2))))))
(s-xlate (lambda (s r)
(cond ((null? s) (reverse r))
(else (let ((n (assv (car s) map)))
(cond (n (s-xlate (cdr s)
(s-prepend (string->list (cdr n)) r)))
(else (s-xlate (cdr s)
(cons (car s) r))))))))))
(list->string
(s-xlate (string->list s) '())))))
(define string-trim-left
(lambda (str)
(cond ((string=? str "") "")
((string=? (substring str 0 1) " ")
(string-trim-left (substring str 1
(string-length str))))
(else str))))
(define get-property
(lambda (key args . thunk)
(cond ((null? args)
(cond ((null? thunk) #f)
(else ((car thunk)))))
((eq? key (car args))
(cond ((pair? (cdr args)) (cadr args))
(else (report-error (list 'get-property key args)))))
((or (not (pair? (cdr args)))
(not (pair? (cddr args))))
(report-error (list 'get-property key args)))
(else (apply get-property key (cddr args) thunk)))))
(define tcl-true?
(let ((false-values
`(0 "0" 'false "false" ,(string->symbol "0"))))
(lambda (obj) (not (memv obj false-values)))))
(define widget?
(lambda (x)
(and (memq x tk-widgets) #t)))
(define call-by-key
(lambda (key resultvar . args)
(cond ((and in-callback (pair? callback-mutex)) #f)
(else (set! in-callback (cons #t in-callback))
(let* ((cmd (get-property key commands-invoked-by-tk))
(result (apply cmd args))
(str (string-trim-left
(scheme-arglist->tk-argstring
(list result)))))
(tk-set-var! resultvar str)
(set! in-callback (cdr in-callback))
result)))))
(define gen-symbol
(let ((counter 0))
(lambda ()
(let ((sym (string-append "g" (number->string counter))))
(set! counter (+ counter 1))
(string->symbol sym)))))
(define widget-name
(lambda (x)
(let ((name (form->string x)))
(cond ((member name ttk-widget-map)
(string-append "ttk::" name))
(else name)))))
(define make-widget-by-id
(lambda (type id . options)
(let
((result
(lambda (command . args)
(case command
((get-id) id)
((create-widget)
(let* ((widget-type (widget-name (car args)))
(id-prefix (if (string=? id ".") "" id))
(id-suffix (form->string (gen-symbol)))
(new-id (string-append id-prefix "." id-suffix))
(options (cdr args)))
(tk-eval
(string-append
widget-type
" "
new-id
(scheme-arglist->tk-argstring options)))
(apply make-widget-by-id
(append (list widget-type new-id)
options))))
((configure)
(cond ((null? args)
(tk-eval
(string-append id " " (form->string command))))
((null? (cdr args))
(tk-eval
(string-append
id
" "
(form->string command)
(scheme-arglist->tk-argstring args))))
(else
(tk-eval
(string-append
id
" "
(form->string command)
(scheme-arglist->tk-argstring args)))
(do ((args args (cddr args)))
((null? args) '())
(let ((key (car args)) (val (cadr args)))
(cond ((null? options)
(set! options (list key val)))
((not (memq key options))
(set! options
(cons key (cons val options))))
(else (set-car! (cdr (memq key options))
val))))))))
((cget)
(let ((key (car args)))
(get-property
key
options
(lambda ()
(tk-eval
(string-append
id
" cget"
(scheme-arglist->tk-argstring args)))))))
((call exec)
(tk-eval
(string-trim-left
(scheme-arglist->tk-argstring args))))
(else
(tk-eval
(string-append
id
" "
(form->string command)
(scheme-arglist->tk-argstring args))))))))
(set! tk-widgets (cons result tk-widgets))
(set! tk-ids+widgets
(cons (string->symbol id)
(cons result tk-ids+widgets)))
result)))
(define scheme-arg->tk-arg
(lambda (x)
(cond ((eq? x #f) " 0")
((eq? x #t) " 1")
((eq? x '()) " {}")
((option? x) (make-option-string x))
((widget? x) (string-append " " (x 'get-id)))
((and (pair? x) (procedure? (car x)))
(let* ((lambda-term (car x))
(rest (cdr x))
(l (memq lambda-term
inverse-commands-invoked-by-tk))
(keystr (if l (form->string (cadr l))
(symbol->string (gen-symbol)))))
(if (not l)
(let ((key (string->symbol keystr)))
(set! inverse-commands-invoked-by-tk
(cons lambda-term
(cons key
inverse-commands-invoked-by-tk)))
(set! commands-invoked-by-tk
(cons key
(cons lambda-term
commands-invoked-by-tk)))))
(string-append " {callToScm "
keystr
(scheme-arglist->tk-argstring rest)
"}")))
((procedure? x)
(scheme-arglist->tk-argstring `((,x))))
((list? x)
(cond ((eq? (car x) '+)
(let ((result (string-trim-left
(scheme-arglist->tk-argstring
(cdr x)))))
(cond ((string=? result "") " +")
((string=? "{" (substring result 0 1))
(string-append
" {+ "
(substring result 1
(string-length result))))
(else (string-append " +" result)))))
((and (= (length x) 3)
(equal? (car x) (string->symbol "@"))
(number? (cadr x))
(number? (caddr x)))
(string-append
"@"
(number->string (cadr x))
","
(number->string (caddr x))))
(else
(string-append
" {"
(string-trim-left
(scheme-arglist->tk-argstring x))
"}"))))
((pair? x)
(string-append
" "
(form->string (car x))
"."
(form->string (cdr x))))
((string? x)
(if (string->number x)
(string-append " " x)
(string-append
" \""
(string-translate x
'((#\\ . "\\\\") (#\" . "\\\"")
(#\[ . "\\u005b") (#\] . "\\]")
(#\$ . "\\u0024")
(#\{ . "\\{") (#\} . "\\}")))
"\"")))
(else (string-append " " (form->string x))))))
(define scheme-arglist->tk-argstring
(lambda (args)
(apply string-append
(map scheme-arg->tk-arg
args))))
(define make-wish-func
(lambda (tkname)
(let ((name (form->string tkname)))
(lambda args
(tk-eval
(string-append
name
(scheme-arglist->tk-argstring args)))))))
(define read-wish
(lambda ()
(let ((term (wish-read wish-output)))
(cond ((and *wish-debug-output*
(not (eof-object? term)))
(display "wish->scheme: ")
(write term)
(newline)))
term)))
(define wish
(lambda arguments
(for-each
(lambda (argument)
(cond (*wish-debug-input*
(display "scheme->wish: ")
(display argument)
(newline)))
(wish-display argument wish-input)
(wish-newline wish-input)
(wish-flush))
arguments)))
(define start-wish
(lambda ()
(let ((result (run-program *wish-program*)))
(set! wish-input (cadr result))
(set! wish-output (car result)))))
(define tk-eval
(lambda (cmd)
(wish (string-append
"evalCmdFromScm \""
(string-translate cmd
'((#\\ . "\\\\") (#\" . "\\\"")))
"\""))
(let again ((result (read-wish)))
(cond ((eof-object? result) #t)
((not (pair? result))
(report-error (string-append
"An error occurred inside Tcl/Tk" nl
" --> " (form->string result)
" " (wish-read-line wish-output)
)))
((eq? (car result) 'return)
(cadr result))
((eq? (car result) 'call)
(apply call-by-key (cdr result))
(again (read-wish)))
((eq? (car result) 'error)
(report-error (string-append
"An error occurred inside Tcl/Tk" nl
" " cmd nl
" --> " (cadr result))))
(else (report-error result))))))
(define tk-id->widget
(lambda (id)
(get-property
(string->symbol (form->string id))
tk-ids+widgets
(lambda ()
(if (tcl-true? (tk/winfo 'exists id))
(make-widget-by-id
(tk/winfo 'class id)
(form->string id))
#f)))))
(define tk-var
(lambda (varname)
(tk-set-var! varname "")
(string-append
"::scmVar("
(form->string varname)
")")))
(define tk-get-var
(lambda (varname)
(tk-eval
(string-append
"set ::scmVar("
(form->string varname)
")"))))
(define tk-set-var!
(lambda (varname value)
(tk-eval
(string-append
"set ::scmVar("
(form->string varname)
") {"
(form->string value)
"}"))))
; start: void -> tk
(define tk-start
(lambda args ; optional argument for name of wish program
(when (and (not (null? args))
(= 1 (length args)))
(set! *wish-program* (car args)))
(start-wish)
(wish tk-init-string)
(set! tk-ids+widgets '())
(set! tk-widgets '())
(set! in-callback #f)
(let ((tk (make-widget-by-id 'toplevel "." 'class: 'Wish)))
(set! commands-invoked-by-tk '())
(set! inverse-commands-invoked-by-tk '())
(tk/wm 'protocol tk 'WM_DELETE_WINDOW tk-end)
tk)))
(define tk-end
(lambda ()
(set! tk-is-running #f)
(wish "after 200 exit")))
(define tk-dispatch-event
(lambda ()
(let ((tk-statement (read-wish)))
(if (and (list? tk-statement)
(eq? (car tk-statement) 'call))
(apply call-by-key (cdr tk-statement))))))
(define loop
(lambda (tk)
(cond ((not tk-is-running)
(if wish-output
(tk/wm 'protocol tk 'WM_DELETE_WINDOW '())))
(else (tk-dispatch-event)
(loop tk)))))
(define tk-event-loop
(lambda (tk)
(set! tk-is-running #t)
(loop tk)))
(define ttk-map-widgets
(lambda (x)
(cond ((eq? x 'all)
(set! ttk-widget-map '("button" "checkbutton" "radiobutton"
"menubutton" "label" "entry" "frame"
"labelframe" "scrollbar" "notebook"
"progressbar" "combobox" "separator"
"scale" "sizegrip" "treeview")))
((eq? x 'none)
(set! ttk-widget-map '()))
((pair? x) (set! ttk-widget-map
(map form->string x)))
(else (report-error
(string-append
"Argument to TTK-MAP-WIDGETS must be "
"ALL, NONE or a list of widget types."))))))
(define string-split
(lambda (c s)
(letrec
((split (lambda (i k tmp res)
(cond ((= i k)
(if (null? tmp) res (cons tmp res)))
((char=? (string-ref s i) c)
(split (+ i 1) k "" (cons tmp res)))
(else (split (+ i 1) k
(string-append tmp
(string (string-ref s i)))
res))))))
(reverse (split 0 (string-length s) "" '())))))
(define ttk-available-themes
(lambda ()
(string-split #\space (tk-eval "ttk::style theme names"))))
(define do-wait-for-window
(lambda (w)
(tk-dispatch-event)
(cond ((equal? (tk/winfo 'exists w) "0") '())
(else (do-wait-for-window w)))))
(define tk-wait-for-window
(lambda (w)
(let ((outer-allow callback-mutex))
(set! callback-mutex #t)
(do-wait-for-window w)
(set! callback-mutex outer-allow))))
(define tk-wait-until-visible
(lambda (w)
(tk/wait 'visibility w)))
(define lock!
(lambda ()
(set! callback-mutex
(cons callback-mutex #t))))
(define unlock!
(lambda ()
(if (pair? callback-mutex)
(set! callback-mutex
(cdr callback-mutex)))))
(define tk-with-lock
(lambda (thunk)
(lock!)
(thunk)
(unlock!)))
(define tk/after (make-wish-func 'after))
(define tk/bell (make-wish-func 'bell))
(define tk/update (make-wish-func 'update))
(define tk/clipboard (make-wish-func 'clipboard))
(define tk/bgerror (make-wish-func 'bgerror))
(define tk/bind (make-wish-func 'bind))
(define tk/bindtags (make-wish-func 'bindtags))
(define tk/destroy (make-wish-func 'destroy))
(define tk/event (make-wish-func 'event))
(define tk/focus (make-wish-func 'focus))
(define tk/grab (make-wish-func 'grab))
(define tk/grid (make-wish-func 'grid))
(define tk/image (make-wish-func 'image))
(define tk/lower (make-wish-func 'lower))
(define tk/option (make-wish-func 'option))
(define tk/pack (make-wish-func 'pack))
(define tk/place (make-wish-func 'place))
(define tk/raise (make-wish-func 'raise))
(define tk/selection (make-wish-func 'selection))
(define tk/winfo (make-wish-func 'winfo))
(define tk/wm (make-wish-func 'wm))
(define tk/choose-color (make-wish-func "tk_chooseColor"))
(define tk/choose-directory (make-wish-func "tk_chooseDirectory"))
(define tk/dialog (make-wish-func "tk_dialog"))
(define tk/get-open-file (make-wish-func "tk_getOpenFile"))
(define tk/get-save-file (make-wish-func "tk_getSaveFile"))
(define tk/message-box (make-wish-func "tk_messageBox"))
(define tk/focus-follows-mouse (make-wish-func "tk_focusFollowsMouse"))
(define tk/focus-next (make-wish-func "tk_focusNext"))
(define tk/focus-prev (make-wish-func "tk_focusPrev"))
(define tk/popup (make-wish-func "tk_popup"))
(define tk/wait (lambda args (make-wish-func 'tkwait)))
(define tk/appname (make-wish-func "tk appname"))
(define tk/caret (make-wish-func "tk caret"))
(define tk/scaling (make-wish-func "tk scaling"))
(define tk/useinputmethods (make-wish-func "tk useinputmethods"))
(define tk/windowingsystem (make-wish-func "tk windowingsystem"))
(define ttk/available-themes ttk-available-themes)
(define ttk/set-theme (make-wish-func "ttk::style theme use"))
(define ttk/style (make-wish-func "ttk::style"))

163
retropikzel/pstk.sld Normal file
View File

@ -0,0 +1,163 @@
; PS/Tk -- A Portable Scheme Interface to the Tk GUI Toolkit
; Copyright (C) 2008 Kenneth A Dickey
; Copyright (C) 2006-2008 Nils M Holm
; Copyright (C) 2004 Wolf-Dieter Busch
; Copyright (C) 2025 Retropikzel
; All rights reserved.
;
; Redistribution and use in source and binary forms, with or without
; modification, are permitted provided that the following conditions
; are met:
; 1. Redistributions of source code must retain the above copyright
; notice, this list of conditions and the following disclaimer.
; 2. Redistributions in binary form must reproduce the above copyright
; notice, this list of conditions and the following disclaimer in the
; documentation and/or other materials provided with the distribution.
;
; THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
; ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
; IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
; ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
; FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
; DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
; OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
; HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
; LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
; OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
; SUCH DAMAGE.
;
; PS/Tk is based on Chicken/Tk by Wolf-Dieter Busch (2004):
; http://wolf-dieter-busch.de/html/Software/Tools/ChickenTk.htm
; which is in turn based on Scheme_wish by Sven Hartrumpf (1997, 1998):
; http://pi7.fernuni-hagen.de/hartrumpf/scheme_wish.scm
;
; These are the changes that I (Nils) made to turn Chicken/Tk into PS/Tk:
;
; - Removed all Chicken-isms except for PROCESS.
; - All PS/Tk function names begin with TK/ or TK-:
; EVAL-WISH --> TK-EVAL-WISH
; GET-TK-VAR --> TK-GET-VAR
; SET-TK-VAR! --> TK-SET-VAR!
; START-TK --> TK-START
; END-TK --> TK-END
; EVENT-LOOP --> TK-EVENT-LOOP
; - Added TK-DISPATCH-EVENT.
; - Added TK-WAIT-FOR-WINDOW because TK/WAIT returned too early.
; - Removed some unused functions and variables.
; - Replaced keyword lists with property lists.
; - Removed ScrolledText compound widget.
; - Removed :WIDGET-NAME option.
; - Added a PLT Scheme version of RUN-PROGRAM.
;
; Contributions (in order of appearance):
; - Jens Axel Soegaard: PLT Scheme/Windows RUN-PROGRAM.
; - Taylor R Campbell: Scheme48 RUN-PROGRAM, portable GENSYM, and some R5RS
; portability fixes.
; - Jeffrey T. Read: Gambit hacks (RUN-PROGRAM, keyword hack).
; - Marc Feeley: Various versions of RUN-PROGRAM (Bigloo, Gauche, Guile,
; Kawa, Scsh, Stklos), SRFI-88 keyword auto-detection, some bug fixes.
; - David St-Hilaire: suggested catching unspecific value in form->string.
; - Ken Dickey: added Ikarus Scheme
; - Ken Dickey: added Larceny Scheme
; - Peter Lane: R7RS support
; Thank you!
;
; Change Log:
; 2025-06-08 MAde to work with named pipes and foreign-c library
; 2017-05-11 Optional argument to 'start' for input of wish/tclsh program name.
; 2017-05-11 Converted into an R7RS library with Chibi, Gauche and Sagittarius support.
; 2008-06-22 Added Larceny Scheme support.
; 2008-02-29 Added R6RS (Ikarus Scheme) support, added TTK/STYLE.
; 2007-06-27 Renamed source file to pstk.scm.
; 2007-06-27 Re-factored some large procedures, applied some cosmetics.
; 2007-06-26 FORM->STRING catches unspecific values now, so event handlers
; no longer have to return specific values.
; 2007-06-26 Re-imported the following ports from the processio/v1 snowball:
; Bigloo, Gauche, Guile, Kawa, Scsh, Stklos.
; 2007-06-26 Added auto-detection of SRFI-88 keywords.
; 2007-03-03 Removed callback mutex, because it blocked some redraw
; operations. Use TK-WITH-LOCK to protect critical sections.
; 2007-02-03 Added Tile support: TTK-MAP-WIDGETS, TTK/AVAILABLE-THEMES,
; TTK/SET-THEME.
; 2007-01-20 Added (Petite) Chez Scheme port.
; 2007-01-06 Fix: TK-WAIT-FOR-WINDOW requires nested callbacks.
; 2007-01-05 Added code to patch through fatal TCL messages.
; 2007-01-05 Protected call-backs by a mutex, so accidental double
; clicks, etc cannot mess up program state.
; 2006-12-21 Made FORM->STRING accept '().
; 2006-12-18 Installing WM_DELETE_WINDOW handler in TK-START now, so it does
; not get reset in TK-EVENT-LOOP.
; 2006-12-18 Made TK-START and TK-END return () instead of #<unspecific>
; (which crashes FORM->STRING).
; 2006-12-12 Fixed some wrong Tcl quotation (introduced by myself).
; 2006-12-09 Added TK/BELL procedure.
; 2006-12-08 Replaced ATOM->STRING by FORM->STRING.
; 2006-12-06 Added TK-WAIT-UNTIL-VISIBLE.
; 2006-12-03 Made more variables local to outer LETREC.
; 2006-12-03 Added Gambit port and keywords hack.
; 2006-12-02 Added Scheme 48 port, portable GENSYM, R5RS fixes.
; 2006-12-02 Added PLT/Windows port.
(define-library
(retropikzel pstk)
(export tk-eval
tk-id->widget
tk-var
tk-get-var
tk-start
tk-end
tk-dispatch-event
tk-event-loop
tk-wait-for-window
tk-wait-until-visible
tk-with-lock
ttk-map-widgets
tk/after
tk/bell
tk/update
tk/clipboard
tk/bgerror
tk/bind
tk/bindtags
tk/destroy
tk/event
tk/focus
tk/grab
tk/grid
tk/image
tk/lower
tk/option
tk/pack
tk/place
tk/raise
tk/selection
tk/winfo
tk/wm
tk/choose-color
tk/choose-directory
tk/dialog
tk/get-open-file
tk/get-save-file
tk/message-box
tk/focus-follows-mouse
tk/focus-next
tk/focus-prev
tk/popup
tk/wait
tk/appname
tk/caret
tk/scaling
tk/useinputmethods
tk/windowingsystem
ttk/available-themes
ttk/set-theme
ttk/style)
(import (scheme base)
(scheme cxr)
(scheme read)
(scheme file)
(scheme write)
(foreign c)
(retropikzel named-pipes))
(include "pstk.scm"))

28
retropikzel/pstk/LICENSE Normal file
View File

@ -0,0 +1,28 @@
Copyright (C) 2008 Kenneth A Dickey
Copyright (C) 2006-2008 Nils M Holm
Copyright (C) 2004 Wolf-Dieter Busch
Copyright (C) 2017 Peter Lane
Copyright (C) 2025 Retropikzel
All rights reserved.
Redistribution and use in source and binary forms, with or without
modification, are permitted provided that the following conditions
are met:
1. Redistributions of source code must retain the above copyright
notice, this list of conditions and the following disclaimer.
2. Redistributions in binary form must reproduce the above copyright
notice, this list of conditions and the following disclaimer in the
documentation and/or other materials provided with the distribution.
THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
SUCH DAMAGE.

1
retropikzel/pstk/VERSION Normal file
View File

@ -0,0 +1 @@
1.0.1

10
retropikzel/pstk/test.scm Normal file
View File

@ -0,0 +1,10 @@
(import (scheme base)
(scheme write)
(retropikzel pstk))
(let ((tk (tk-start)))
(tk/pack (tk 'create-widget
'button 'text: "Hello"
'command: (lambda () (display "Hello world") (newline)))
'padx: 20 'pady: 20)
(tk-event-loop tk))