# HG changeset patch # User Steve Losh # Date 1486774344 0 # Node ID f61929db839b6c5a574e8baa38742636b848971b Initial commit diff -r 000000000000 -r f61929db839b .ffignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.ffignore Sat Feb 11 00:52:24 2017 +0000 @@ -0,0 +1,1 @@ +docs/build diff -r 000000000000 -r f61929db839b .hgignore --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.hgignore Sat Feb 11 00:52:24 2017 +0000 @@ -0,0 +1,6 @@ +syntax: glob + +scratch.lisp +*.png +docs/build +lib/ diff -r 000000000000 -r f61929db839b .hgtags diff -r 000000000000 -r f61929db839b .lispwords --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/.lispwords Sat Feb 11 00:52:24 2017 +0000 @@ -0,0 +1,1 @@ +(1 key-case) diff -r 000000000000 -r f61929db839b Makefile --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/Makefile Sat Feb 11 00:52:24 2017 +0000 @@ -0,0 +1,32 @@ +.PHONY: vendor docs pubdocs swig + +sourcefiles = $(shell ffind --full-path --literal .lisp) +docfiles = $(shell ls docs/*.markdown) +apidocs = $(shell ls docs/*reference*.markdown) + +# Vendor ---------------------------------------------------------------------- +vendor/quickutils.lisp: vendor/make-quickutils.lisp + cd vendor && sbcl --noinform --load make-quickutils.lisp --eval '(quit)' + +vendor: vendor/quickutils.lisp + +# SWIG ------------------------------------------------------------------------ +src/low-level/bearlibterminal.lisp: src/low-level/bearlibterminal.swig src/low-level/include/BearLibTerminal.h package.lisp + swig -cffi -module bearlibterminal src/low-level/bearlibterminal.swig + +swig: src/low-level/bearlibterminal.lisp + +# Documentation --------------------------------------------------------------- +$(apidocs): $(sourcefiles) + sbcl --noinform --load docs/api.lisp --eval '(quit)' + +docs/build/index.html: $(docfiles) $(apidocs) docs/title + cd docs && ~/.virtualenvs/d/bin/d + +docs: docs/build/index.html + +pubdocs: docs + hg -R ~/src/sjl.bitbucket.org pull -u + rsync --delete -a ./docs/build/ ~/src/sjl.bitbucket.org/cl-blt + hg -R ~/src/sjl.bitbucket.org commit -Am 'cl-blt: Update site.' + hg -R ~/src/sjl.bitbucket.org push diff -r 000000000000 -r f61929db839b README.markdown --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/README.markdown Sat Feb 11 00:52:24 2017 +0000 @@ -0,0 +1,8 @@ +`cl-blt` is a Common Lisp wrapper for bearlibterminal. It uses CFFI and SWIG to +generate low-level bindings and provides a higher-level, Lispier interface on +top of them. + +* **License:** MIT/X11 +* **Documentation:** +* **Mercurial:** +* **Git:** diff -r 000000000000 -r f61929db839b cl-blt.asd --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/cl-blt.asd Sat Feb 11 00:52:24 2017 +0000 @@ -0,0 +1,21 @@ +(asdf:defsystem :cl-blt + :description "Common Lisp wrapper for bearlibterminal" + + :author "Steve Losh " + + :license "MIT/X11" + :version "1.0.0" + + :depends-on (:cffi :trivial-main-thread) + + :serial t + :components ((:module "vendor" :serial t + :components ((:file "quickutils-package") + (:file "quickutils"))) + (:file "package") + (:module "src" :serial t + :components + ((:module "low-level" :serial t + :components ((:file "bearlibterminal"))) + (:module "high-level" :serial t + :components ((:file "bearlibterminal"))))))) diff -r 000000000000 -r f61929db839b docs/01-installation.markdown --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/01-installation.markdown Sat Feb 11 00:52:24 2017 +0000 @@ -0,0 +1,11 @@ +Installation +============ + +`cl-blt` is compatible with Quicklisp, but not *in* Quicklisp (yet?). You can +clone the repository into your [Quicklisp local-projects][local] directory for +now. + +You'll need to install [bearlibterminal][] yourself. + +[bearlibterminal]: https://bitbucket.org/cfyzium/bearlibterminal +[local]: https://www.quicklisp.org/beta/faq.html#local-project diff -r 000000000000 -r f61929db839b docs/02-usage.markdown --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/02-usage.markdown Sat Feb 11 00:52:24 2017 +0000 @@ -0,0 +1,7 @@ +Usage +===== + +cl-blt is... + +[TOC] + diff -r 000000000000 -r f61929db839b docs/03-reference.markdown --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/03-reference.markdown Sat Feb 11 00:52:24 2017 +0000 @@ -0,0 +1,14 @@ +# API Reference + +The following is a list of all user-facing parts of `cl-pcg`. + +If there are backwards-incompatible changes to anything listed here, they will +be noted in the changelog and the author will feel bad. + +Anything not listed here is subject to change at any time with no warning, so +don't touch it. + +[TOC] + +## Package `PCG` + diff -r 000000000000 -r f61929db839b docs/04-changelog.markdown --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/04-changelog.markdown Sat Feb 11 00:52:24 2017 +0000 @@ -0,0 +1,11 @@ +Changelog +========= + +Here's the list of changes in each released version. + +[TOC] + +v1.0.0 +------ + +Initial release. diff -r 000000000000 -r f61929db839b docs/api.lisp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/api.lisp Sat Feb 11 00:52:24 2017 +0000 @@ -0,0 +1,20 @@ +(ql:quickload "cl-d-api") + +(defparameter *header* + "The following is a list of all user-facing parts of `cl-blt`. + +If there are backwards-incompatible changes to anything listed here, they will +be noted in the changelog and the author will feel bad. + +Anything not listed here is subject to change at any time with no warning, so +don't touch it. + +") + +(d-api:generate-documentation + :cl-blt + #p"docs/03-reference.markdown" + (list "BEARLIBTERMINAL/HIGH-LEVEL" "BEARLIBTERMINAL/LOW-LEVEL") + *header* + :title "API Reference") + diff -r 000000000000 -r f61929db839b docs/footer.markdown --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/footer.markdown Sat Feb 11 00:52:24 2017 +0000 @@ -0,0 +1,14 @@ +Made with Lisp and love by [Steve Losh][] in Reykjavík, Iceland. + +[Steve Losh]: http://stevelosh.com/ + + diff -r 000000000000 -r f61929db839b docs/index.markdown --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/index.markdown Sat Feb 11 00:52:24 2017 +0000 @@ -0,0 +1,8 @@ +`cl-blt` is a Common Lisp wrapper for bearlibterminal. It uses CFFI and SWIG to +generate low-level bindings and provides a higher-level, Lispier interface on +top of them. + +* **License:** MIT/X11 +* **Documentation:** +* **Mercurial:** +* **Git:** diff -r 000000000000 -r f61929db839b docs/title --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/docs/title Sat Feb 11 00:52:24 2017 +0000 @@ -0,0 +1,1 @@ +cl-blt diff -r 000000000000 -r f61929db839b package.lisp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/package.lisp Sat Feb 11 00:52:24 2017 +0000 @@ -0,0 +1,14 @@ +(defpackage :bearlibterminal/low-level + (:use) + (:export) + (:import-from :cl + :&rest) + (:nicknames :blt/ll) + (:documentation "This package contains the low-level, SWIG-generated wrapper functions for bearlibterminal.")) + +(defpackage :bearlibterminal/high-level + (:use :cl + :bearlibterminal.quickutils) + (:export) + (:nicknames :blt/hl :blt) + (:documentation "This package contains a high-level, lispy interface to bearlibterminal. It has the nickname `blt` for easy prefixing.")) diff -r 000000000000 -r f61929db839b src/high-level/bearlibterminal.lisp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/high-level/bearlibterminal.lisp Sat Feb 11 00:52:24 2017 +0000 @@ -0,0 +1,315 @@ +(in-package :bearlibterminal/high-level) + +; (sb-int:set-floating-point-modes :traps nil) + +;;;; Utils -------------------------------------------------------------------- +(defun pr (val) + (format t "~S~%" val) + (finish-output) + (values)) + +(defmacro -<> (expr &rest forms) + "Thread the given forms, with `<>` as a placeholder." + ;; I am going to lose my fucking mind if I have to program lisp without + ;; a threading macro, but I don't want to add another dep to this library, so + ;; here we are. + `(let* ((<> ,expr) + ,@(mapcar (lambda (form) + (if (symbolp form) + `(<> (,form <>)) + `(<> ,form))) + forms)) + <>)) + + +(defun rgba (r g b a) + (-<> 0 + (dpb a (byte 2 6) <>) + (dpb r (byte 2 4) <>) + (dpb g (byte 2 2) <>) + (dpb b (byte 2 0) <>))) + +(defun name (color-name) + (blt/ll:color-from-name color-name)) + + +(defun boolean-to-onoff (boolean) + (if boolean + blt/ll:+tk-on+ + blt/ll:+tk-off+)) + +(defun onoff-to-boolean (onoff) + (ecase onoff + (blt/ll:+tk-on+ t) + (blt/ll:+tk-off+ nil))) + +(defun int-to-boolean (int) + (not (zerop int))) + + +(defun state-boolean (state) + (int-to-boolean (blt/ll:terminal-state state))) + + +;;;; Error Checking ----------------------------------------------------------- +(define-condition bearlibterminal-error (error) ()) + +(defun check (return-value) + (if (zerop return-value) + (error 'bearlibterminal-error))) + + +;;;; Wrappers ----------------------------------------------------------------- +(defun terminal-open () + (check (blt/ll:terminal-open))) + +(defun terminal-close () + (blt/ll:terminal-close)) + +(defun terminal-set (configuration-string) + (check (blt/ll:terminal-set-8 configuration-string))) + + +(defun terminal-refresh () + (blt/ll:terminal-refresh)) + +(defun terminal-clear () + (blt/ll:terminal-clear)) + +(defun terminal-clear-area (x y width height) + (blt/ll:terminal-clear-area x y width height)) + +(defun terminal-crop (x y width height) + (blt/ll:terminal-crop x y width height)) + + +(defun terminal-layer () + (blt/ll:terminal-state blt/ll:+tk-layer+)) + +(defun (setf terminal-layer) (new-value) + (blt/ll:terminal-layer new-value) + new-value) + + +(defun terminal-color () + (blt/ll:terminal-state blt/ll:+tk-color+)) + +(defun (setf terminal-color) (color) + (blt/ll:terminal-color color)) + + +(defun terminal-background-color () + (blt/ll:terminal-state blt/ll:+tk-bkcolor+)) + +(defun (setf terminal-background-color) (color) + (blt/ll:terminal-bkcolor color)) + + +(defun terminal-composition () + (onoff-to-boolean (blt/ll:terminal-state blt/ll:+tk-composition+))) + +(defun (setf terminal-composition) (new-value) + (blt/ll:terminal-composition (boolean-to-onoff new-value)) + new-value) + + +(defun terminal-has-input-p () + (int-to-boolean (blt/ll:terminal-has-input))) + +(defun terminal-read () + (blt/ll:terminal-read)) + +(defun terminal-peek () + (blt/ll:terminal-peek)) + +(defun terminal-delay (seconds) + (blt/ll:terminal-delay (truncate (* seconds 1000)))) + + +;;;; Higher-Level API --------------------------------------------------------- +(defmacro defuck-floats (&body body) + #+sbcl + `(sb-int:with-float-traps-masked + (:inexact :underflow :overflow :invalid :divide-by-zero) + ,@body) + #-(or sbcl) + `(progn ,@body)) + +(defmacro with-terminal (&body body) + `(defuck-floats + (terminal-open) + (unwind-protect + (progn ,@body) + (terminal-close)))) + + +(eval-when (:compile-toplevel :load-toplevel :execute) + (defun find-integer (event) + (ecase event + (:A blt/ll:+tk-a+) + (:B blt/ll:+tk-b+) + (:C blt/ll:+tk-c+) + (:D blt/ll:+tk-d+) + (:E blt/ll:+tk-e+) + (:F blt/ll:+tk-f+) + (:G blt/ll:+tk-g+) + (:H blt/ll:+tk-h+) + (:I blt/ll:+tk-i+) + (:J blt/ll:+tk-j+) + (:K blt/ll:+tk-k+) + (:L blt/ll:+tk-l+) + (:m blt/ll:+tk-m+) + (:n blt/ll:+tk-n+) + (:o blt/ll:+tk-o+) + (:p blt/ll:+tk-p+) + (:q blt/ll:+tk-q+) + (:r blt/ll:+tk-r+) + (:s blt/ll:+tk-s+) + (:t blt/ll:+tk-t+) + (:u blt/ll:+tk-u+) + (:v blt/ll:+tk-v+) + (:w blt/ll:+tk-w+) + (:x blt/ll:+tk-x+) + (:y blt/ll:+tk-y+) + (:z blt/ll:+tk-z+) + (:1 blt/ll:+tk-1+) + (:2 blt/ll:+tk-2+) + (:3 blt/ll:+tk-3+) + (:4 blt/ll:+tk-4+) + (:5 blt/ll:+tk-5+) + (:6 blt/ll:+tk-6+) + (:7 blt/ll:+tk-7+) + (:8 blt/ll:+tk-8+) + (:9 blt/ll:+tk-9+) + (:0 blt/ll:+tk-0+) + (:return blt/ll:+tk-return+) + (:enter blt/ll:+tk-enter+) + (:escape blt/ll:+tk-escape+) + (:backspace blt/ll:+tk-backspace+) + (:tab blt/ll:+tk-tab+) + (:space blt/ll:+tk-space+) + (:minus blt/ll:+tk-minus+) + (:equals blt/ll:+tk-equals+) + (:lbracket blt/ll:+tk-lbracket+) + (:rbracket blt/ll:+tk-rbracket+) + (:backslash blt/ll:+tk-backslash+) + (:semicolon blt/ll:+tk-semicolon+) + (:apostrophe blt/ll:+tk-apostrophe+) + (:grave blt/ll:+tk-grave+) + (:comma blt/ll:+tk-comma+) + (:period blt/ll:+tk-period+) + (:slash blt/ll:+tk-slash+) + (:f1 blt/ll:+tk-f-1+) + (:f2 blt/ll:+tk-f-2+) + (:f3 blt/ll:+tk-f-3+) + (:f4 blt/ll:+tk-f-4+) + (:f5 blt/ll:+tk-f-5+) + (:f6 blt/ll:+tk-f-6+) + (:f7 blt/ll:+tk-f-7+) + (:f8 blt/ll:+tk-f-8+) + (:f9 blt/ll:+tk-f-9+) + (:f10 blt/ll:+tk-f-10+) + (:f11 blt/ll:+tk-f-11+) + (:f12 blt/ll:+tk-f-12+) + (:pause blt/ll:+tk-pause+) + (:insert blt/ll:+tk-insert+) + (:home blt/ll:+tk-home+) + (:page-up blt/ll:+tk-pageup+) + (:delete blt/ll:+tk-delete+) + (:end blt/ll:+tk-end+) + (:page-down blt/ll:+tk-pagedown+) + (:right blt/ll:+tk-right+) + (:left blt/ll:+tk-left+) + (:down blt/ll:+tk-down+) + (:up blt/ll:+tk-up+) + (:numpad-divide blt/ll:+tk-kp-divide+) + (:numpad-multiply blt/ll:+tk-kp-multiply+) + (:numpad-minus blt/ll:+tk-kp-minus+) + (:numpad-plus blt/ll:+tk-kp-plus+) + (:numpad-enter blt/ll:+tk-kp-enter+) + (:numpad-1 blt/ll:+tk-kp-1+) + (:numpad-2 blt/ll:+tk-kp-2+) + (:numpad-3 blt/ll:+tk-kp-3+) + (:numpad-4 blt/ll:+tk-kp-4+) + (:numpad-5 blt/ll:+tk-kp-5+) + (:numpad-6 blt/ll:+tk-kp-6+) + (:numpad-7 blt/ll:+tk-kp-7+) + (:numpad-8 blt/ll:+tk-kp-8+) + (:numpad-9 blt/ll:+tk-kp-9+) + (:numpad-0 blt/ll:+tk-kp-0+) + (:numpad-period blt/ll:+tk-kp-period+) + (:shift blt/ll:+tk-shift+) + (:control blt/ll:+tk-control+) + (:alt blt/ll:+tk-alt+) + (:mouse-left blt/ll:+tk-mouse-left+) + (:mouse-right blt/ll:+tk-mouse-right+) + (:mouse-middle blt/ll:+tk-mouse-middle+) + (:mouse-x1 blt/ll:+tk-mouse-x-1+) + (:mouse-x2 blt/ll:+tk-mouse-x-2+) + (:mouse-move blt/ll:+tk-mouse-move+) + (:mouse-scroll blt/ll:+tk-mouse-scroll+) + (:close blt/ll:+tk-close+) + (:resize blt/ll:+tk-resized+) + (:none blt/ll:+tk-input-none+) + (:cancelled blt/ll:+tk-input-cancelled+)))) + +(eval-when (:compile-toplevel :load-toplevel :execute) + (defun parse-key-case-head (head data-symbol) + (if (eq t head) + t + (destructuring-bind (event &rest modifiers) + (ensure-list head) + (let* ((up (member :up modifiers)) + (down (member :down modifiers)) + (up/down (cond ((and up down) :both) + (up :up) + (down :down) + (t :down))) + (shift (ensure-boolean + (member :shift modifiers))) + (alt (ensure-boolean + (intersection modifiers + '(:alt :option :meta)))) + (control (ensure-boolean + (intersection modifiers + '(:control :command))))) + `(and + ,(ecase up/down + (:both `(eql (logand ,data-symbol + ,(lognot blt/ll:+tk-key-released+)) + ,(find-integer event))) + (:up `(eql ,data-symbol + ,(logior (find-integer event) + blt/ll:+tk-key-released+))) + (:down `(eql ,data-symbol + ,(find-integer event)))) + (,(if shift 'progn 'not) + (state-boolean blt/ll:+tk-shift+)) + (,(if control 'progn 'not) + (state-boolean blt/ll:+tk-control+)) + (,(if alt 'progn 'not) + (state-boolean blt/ll:+tk-alt+)))))))) + +(defmacro key-case (data &rest clauses) + (once-only (data) + `(cond ,@(loop :for (head . body) :in clauses + :collect `(,(parse-key-case-head head data) ,@body))))) + + +;;;; Scratch ------------------------------------------------------------------ +(defun test () + (trivial-main-thread:with-body-in-main-thread (:blocking t) + (with-terminal + (terminal-refresh) + (terminal-set "input.filter = [keyboard+, mouse+]") + (loop + :for data = (terminal-read) + :do (pr data) + :while (key-case data + ((:a :down) (pr "A down") t) + ((:a :up) (pr "A up") t) + ((:a :control) (pr "ctrl a") t) + ((:b :control :shift) (pr "shift-ctrl b") t) + ((:b :down :up) (pr "B down or up") t) + (:escape nil) + (t (pr "something else") t)))))) diff -r 000000000000 -r f61929db839b src/low-level/bearlibterminal.lisp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/low-level/bearlibterminal.lisp Sat Feb 11 00:52:24 2017 +0000 @@ -0,0 +1,1079 @@ +;;; This file was automatically generated by SWIG (http://www.swig.org). +;;; Version 3.0.10 +;;; +;;; Do not make changes to this file unless you know what you are doing--modify +;;; the SWIG interface file instead. + +(cl:in-package :bearlibterminal/low-level) + +(cffi:defctype color :uint) + +(cffi:define-foreign-library bearlibterminal + (:darwin "lib/libBearLibTerminal.dylib")) + +(cffi:use-foreign-library bearlibterminal) + + + +;;;SWIG wrapper code starts here + +(cl:defmacro defanonenum (cl:&body enums) + "Converts anonymous enums to defconstants." + `(cl:progn ,@(cl:loop for value in enums + for index = 0 then (cl:1+ index) + when (cl:listp value) do (cl:setf index (cl:second value) + value (cl:first value)) + collect `(cl:defconstant ,value ,index)))) + +(cl:eval-when (:compile-toplevel :load-toplevel) + (cl:unless (cl:fboundp 'swig-lispify) + (cl:defun swig-lispify (name flag cl:&optional (package cl:*package*)) + (cl:labels ((helper (lst last rest cl:&aux (c (cl:car lst))) + (cl:cond + ((cl:null lst) + rest) + ((cl:upper-case-p c) + (helper (cl:cdr lst) 'upper + (cl:case last + ((lower digit) (cl:list* c #\- rest)) + (cl:t (cl:cons c rest))))) + ((cl:lower-case-p c) + (helper (cl:cdr lst) 'lower (cl:cons (cl:char-upcase c) rest))) + ((cl:digit-char-p c) + (helper (cl:cdr lst) 'digit + (cl:case last + ((upper lower) (cl:list* c #\- rest)) + (cl:t (cl:cons c rest))))) + ((cl:char-equal c #\_) + (helper (cl:cdr lst) '_ (cl:cons #\- rest))) + (cl:t + (cl:error "Invalid character: ~A" c))))) + (cl:let ((fix (cl:case flag + ((constant enumvalue) "+") + (variable "*") + (cl:t "")))) + (cl:intern + (cl:concatenate + 'cl:string + fix + (cl:nreverse (helper (cl:concatenate 'cl:list name) cl:nil cl:nil)) + fix) + package)))))) + +;;;SWIG wrapper code ends here + + +(cl:defconstant #.(swig-lispify "TK_A" 'constant) #x04) + +(cl:export '#.(swig-lispify "TK_A" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_B" 'constant) #x05) + +(cl:export '#.(swig-lispify "TK_B" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_C" 'constant) #x06) + +(cl:export '#.(swig-lispify "TK_C" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_D" 'constant) #x07) + +(cl:export '#.(swig-lispify "TK_D" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_E" 'constant) #x08) + +(cl:export '#.(swig-lispify "TK_E" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_F" 'constant) #x09) + +(cl:export '#.(swig-lispify "TK_F" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_G" 'constant) #x0A) + +(cl:export '#.(swig-lispify "TK_G" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_H" 'constant) #x0B) + +(cl:export '#.(swig-lispify "TK_H" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_I" 'constant) #x0C) + +(cl:export '#.(swig-lispify "TK_I" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_J" 'constant) #x0D) + +(cl:export '#.(swig-lispify "TK_J" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_K" 'constant) #x0E) + +(cl:export '#.(swig-lispify "TK_K" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_L" 'constant) #x0F) + +(cl:export '#.(swig-lispify "TK_L" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_M" 'constant) #x10) + +(cl:export '#.(swig-lispify "TK_M" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_N" 'constant) #x11) + +(cl:export '#.(swig-lispify "TK_N" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_O" 'constant) #x12) + +(cl:export '#.(swig-lispify "TK_O" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_P" 'constant) #x13) + +(cl:export '#.(swig-lispify "TK_P" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_Q" 'constant) #x14) + +(cl:export '#.(swig-lispify "TK_Q" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_R" 'constant) #x15) + +(cl:export '#.(swig-lispify "TK_R" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_S" 'constant) #x16) + +(cl:export '#.(swig-lispify "TK_S" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_T" 'constant) #x17) + +(cl:export '#.(swig-lispify "TK_T" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_U" 'constant) #x18) + +(cl:export '#.(swig-lispify "TK_U" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_V" 'constant) #x19) + +(cl:export '#.(swig-lispify "TK_V" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_W" 'constant) #x1A) + +(cl:export '#.(swig-lispify "TK_W" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_X" 'constant) #x1B) + +(cl:export '#.(swig-lispify "TK_X" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_Y" 'constant) #x1C) + +(cl:export '#.(swig-lispify "TK_Y" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_Z" 'constant) #x1D) + +(cl:export '#.(swig-lispify "TK_Z" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_1" 'constant) #x1E) + +(cl:export '#.(swig-lispify "TK_1" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_2" 'constant) #x1F) + +(cl:export '#.(swig-lispify "TK_2" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_3" 'constant) #x20) + +(cl:export '#.(swig-lispify "TK_3" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_4" 'constant) #x21) + +(cl:export '#.(swig-lispify "TK_4" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_5" 'constant) #x22) + +(cl:export '#.(swig-lispify "TK_5" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_6" 'constant) #x23) + +(cl:export '#.(swig-lispify "TK_6" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_7" 'constant) #x24) + +(cl:export '#.(swig-lispify "TK_7" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_8" 'constant) #x25) + +(cl:export '#.(swig-lispify "TK_8" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_9" 'constant) #x26) + +(cl:export '#.(swig-lispify "TK_9" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_0" 'constant) #x27) + +(cl:export '#.(swig-lispify "TK_0" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_RETURN" 'constant) #x28) + +(cl:export '#.(swig-lispify "TK_RETURN" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_ENTER" 'constant) #x28) + +(cl:export '#.(swig-lispify "TK_ENTER" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_ESCAPE" 'constant) #x29) + +(cl:export '#.(swig-lispify "TK_ESCAPE" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_BACKSPACE" 'constant) #x2A) + +(cl:export '#.(swig-lispify "TK_BACKSPACE" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_TAB" 'constant) #x2B) + +(cl:export '#.(swig-lispify "TK_TAB" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_SPACE" 'constant) #x2C) + +(cl:export '#.(swig-lispify "TK_SPACE" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_MINUS" 'constant) #x2D) + +(cl:export '#.(swig-lispify "TK_MINUS" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_EQUALS" 'constant) #x2E) + +(cl:export '#.(swig-lispify "TK_EQUALS" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_LBRACKET" 'constant) #x2F) + +(cl:export '#.(swig-lispify "TK_LBRACKET" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_RBRACKET" 'constant) #x30) + +(cl:export '#.(swig-lispify "TK_RBRACKET" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_BACKSLASH" 'constant) #x31) + +(cl:export '#.(swig-lispify "TK_BACKSLASH" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_SEMICOLON" 'constant) #x33) + +(cl:export '#.(swig-lispify "TK_SEMICOLON" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_APOSTROPHE" 'constant) #x34) + +(cl:export '#.(swig-lispify "TK_APOSTROPHE" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_GRAVE" 'constant) #x35) + +(cl:export '#.(swig-lispify "TK_GRAVE" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_COMMA" 'constant) #x36) + +(cl:export '#.(swig-lispify "TK_COMMA" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_PERIOD" 'constant) #x37) + +(cl:export '#.(swig-lispify "TK_PERIOD" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_SLASH" 'constant) #x38) + +(cl:export '#.(swig-lispify "TK_SLASH" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_F1" 'constant) #x3A) + +(cl:export '#.(swig-lispify "TK_F1" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_F2" 'constant) #x3B) + +(cl:export '#.(swig-lispify "TK_F2" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_F3" 'constant) #x3C) + +(cl:export '#.(swig-lispify "TK_F3" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_F4" 'constant) #x3D) + +(cl:export '#.(swig-lispify "TK_F4" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_F5" 'constant) #x3E) + +(cl:export '#.(swig-lispify "TK_F5" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_F6" 'constant) #x3F) + +(cl:export '#.(swig-lispify "TK_F6" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_F7" 'constant) #x40) + +(cl:export '#.(swig-lispify "TK_F7" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_F8" 'constant) #x41) + +(cl:export '#.(swig-lispify "TK_F8" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_F9" 'constant) #x42) + +(cl:export '#.(swig-lispify "TK_F9" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_F10" 'constant) #x43) + +(cl:export '#.(swig-lispify "TK_F10" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_F11" 'constant) #x44) + +(cl:export '#.(swig-lispify "TK_F11" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_F12" 'constant) #x45) + +(cl:export '#.(swig-lispify "TK_F12" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_PAUSE" 'constant) #x48) + +(cl:export '#.(swig-lispify "TK_PAUSE" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_INSERT" 'constant) #x49) + +(cl:export '#.(swig-lispify "TK_INSERT" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_HOME" 'constant) #x4A) + +(cl:export '#.(swig-lispify "TK_HOME" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_PAGEUP" 'constant) #x4B) + +(cl:export '#.(swig-lispify "TK_PAGEUP" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_DELETE" 'constant) #x4C) + +(cl:export '#.(swig-lispify "TK_DELETE" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_END" 'constant) #x4D) + +(cl:export '#.(swig-lispify "TK_END" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_PAGEDOWN" 'constant) #x4E) + +(cl:export '#.(swig-lispify "TK_PAGEDOWN" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_RIGHT" 'constant) #x4F) + +(cl:export '#.(swig-lispify "TK_RIGHT" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_LEFT" 'constant) #x50) + +(cl:export '#.(swig-lispify "TK_LEFT" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_DOWN" 'constant) #x51) + +(cl:export '#.(swig-lispify "TK_DOWN" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_UP" 'constant) #x52) + +(cl:export '#.(swig-lispify "TK_UP" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_KP_DIVIDE" 'constant) #x54) + +(cl:export '#.(swig-lispify "TK_KP_DIVIDE" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_KP_MULTIPLY" 'constant) #x55) + +(cl:export '#.(swig-lispify "TK_KP_MULTIPLY" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_KP_MINUS" 'constant) #x56) + +(cl:export '#.(swig-lispify "TK_KP_MINUS" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_KP_PLUS" 'constant) #x57) + +(cl:export '#.(swig-lispify "TK_KP_PLUS" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_KP_ENTER" 'constant) #x58) + +(cl:export '#.(swig-lispify "TK_KP_ENTER" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_KP_1" 'constant) #x59) + +(cl:export '#.(swig-lispify "TK_KP_1" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_KP_2" 'constant) #x5A) + +(cl:export '#.(swig-lispify "TK_KP_2" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_KP_3" 'constant) #x5B) + +(cl:export '#.(swig-lispify "TK_KP_3" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_KP_4" 'constant) #x5C) + +(cl:export '#.(swig-lispify "TK_KP_4" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_KP_5" 'constant) #x5D) + +(cl:export '#.(swig-lispify "TK_KP_5" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_KP_6" 'constant) #x5E) + +(cl:export '#.(swig-lispify "TK_KP_6" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_KP_7" 'constant) #x5F) + +(cl:export '#.(swig-lispify "TK_KP_7" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_KP_8" 'constant) #x60) + +(cl:export '#.(swig-lispify "TK_KP_8" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_KP_9" 'constant) #x61) + +(cl:export '#.(swig-lispify "TK_KP_9" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_KP_0" 'constant) #x62) + +(cl:export '#.(swig-lispify "TK_KP_0" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_KP_PERIOD" 'constant) #x63) + +(cl:export '#.(swig-lispify "TK_KP_PERIOD" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_SHIFT" 'constant) #x70) + +(cl:export '#.(swig-lispify "TK_SHIFT" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_CONTROL" 'constant) #x71) + +(cl:export '#.(swig-lispify "TK_CONTROL" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_ALT" 'constant) #x72) + +(cl:export '#.(swig-lispify "TK_ALT" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_MOUSE_LEFT" 'constant) #x80) + +(cl:export '#.(swig-lispify "TK_MOUSE_LEFT" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_MOUSE_RIGHT" 'constant) #x81) + +(cl:export '#.(swig-lispify "TK_MOUSE_RIGHT" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_MOUSE_MIDDLE" 'constant) #x82) + +(cl:export '#.(swig-lispify "TK_MOUSE_MIDDLE" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_MOUSE_X1" 'constant) #x83) + +(cl:export '#.(swig-lispify "TK_MOUSE_X1" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_MOUSE_X2" 'constant) #x84) + +(cl:export '#.(swig-lispify "TK_MOUSE_X2" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_MOUSE_MOVE" 'constant) #x85) + +(cl:export '#.(swig-lispify "TK_MOUSE_MOVE" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_MOUSE_SCROLL" 'constant) #x86) + +(cl:export '#.(swig-lispify "TK_MOUSE_SCROLL" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_MOUSE_X" 'constant) #x87) + +(cl:export '#.(swig-lispify "TK_MOUSE_X" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_MOUSE_Y" 'constant) #x88) + +(cl:export '#.(swig-lispify "TK_MOUSE_Y" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_MOUSE_PIXEL_X" 'constant) #x89) + +(cl:export '#.(swig-lispify "TK_MOUSE_PIXEL_X" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_MOUSE_PIXEL_Y" 'constant) #x8A) + +(cl:export '#.(swig-lispify "TK_MOUSE_PIXEL_Y" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_MOUSE_WHEEL" 'constant) #x8B) + +(cl:export '#.(swig-lispify "TK_MOUSE_WHEEL" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_MOUSE_CLICKS" 'constant) #x8C) + +(cl:export '#.(swig-lispify "TK_MOUSE_CLICKS" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_KEY_RELEASED" 'constant) #x100) + +(cl:export '#.(swig-lispify "TK_KEY_RELEASED" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_WIDTH" 'constant) #xC0) + +(cl:export '#.(swig-lispify "TK_WIDTH" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_HEIGHT" 'constant) #xC1) + +(cl:export '#.(swig-lispify "TK_HEIGHT" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_CELL_WIDTH" 'constant) #xC2) + +(cl:export '#.(swig-lispify "TK_CELL_WIDTH" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_CELL_HEIGHT" 'constant) #xC3) + +(cl:export '#.(swig-lispify "TK_CELL_HEIGHT" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_COLOR" 'constant) #xC4) + +(cl:export '#.(swig-lispify "TK_COLOR" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_BKCOLOR" 'constant) #xC5) + +(cl:export '#.(swig-lispify "TK_BKCOLOR" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_LAYER" 'constant) #xC6) + +(cl:export '#.(swig-lispify "TK_LAYER" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_COMPOSITION" 'constant) #xC7) + +(cl:export '#.(swig-lispify "TK_COMPOSITION" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_CHAR" 'constant) #xC8) + +(cl:export '#.(swig-lispify "TK_CHAR" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_WCHAR" 'constant) #xC9) + +(cl:export '#.(swig-lispify "TK_WCHAR" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_EVENT" 'constant) #xCA) + +(cl:export '#.(swig-lispify "TK_EVENT" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_FULLSCREEN" 'constant) #xCB) + +(cl:export '#.(swig-lispify "TK_FULLSCREEN" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_CLOSE" 'constant) #xE0) + +(cl:export '#.(swig-lispify "TK_CLOSE" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_RESIZED" 'constant) #xE1) + +(cl:export '#.(swig-lispify "TK_RESIZED" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_OFF" 'constant) 0) + +(cl:export '#.(swig-lispify "TK_OFF" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_ON" 'constant) 1) + +(cl:export '#.(swig-lispify "TK_ON" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_INPUT_NONE" 'constant) 0) + +(cl:export '#.(swig-lispify "TK_INPUT_NONE" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_INPUT_CANCELLED" 'constant) -1) + +(cl:export '#.(swig-lispify "TK_INPUT_CANCELLED" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_ALIGN_DEFAULT" 'constant) 0) + +(cl:export '#.(swig-lispify "TK_ALIGN_DEFAULT" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_ALIGN_LEFT" 'constant) 1) + +(cl:export '#.(swig-lispify "TK_ALIGN_LEFT" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_ALIGN_RIGHT" 'constant) 2) + +(cl:export '#.(swig-lispify "TK_ALIGN_RIGHT" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_ALIGN_CENTER" 'constant) 3) + +(cl:export '#.(swig-lispify "TK_ALIGN_CENTER" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_ALIGN_TOP" 'constant) 4) + +(cl:export '#.(swig-lispify "TK_ALIGN_TOP" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_ALIGN_BOTTOM" 'constant) 8) + +(cl:export '#.(swig-lispify "TK_ALIGN_BOTTOM" 'constant)) + +(cl:defconstant #.(swig-lispify "TK_ALIGN_MIDDLE" 'constant) 12) + +(cl:export '#.(swig-lispify "TK_ALIGN_MIDDLE" 'constant)) + +(cffi:defcstruct #.(swig-lispify "dimensions_t" 'classname) + (#.(swig-lispify "width" 'slotname) :int) + (#.(swig-lispify "height" 'slotname) :int)) + +(cl:export '#.(swig-lispify "dimensions_t" 'classname)) + +(cl:export '#.(swig-lispify "width" 'slotname)) + +(cl:export '#.(swig-lispify "height" 'slotname)) + +(cffi:defcfun ("terminal_open" #.(swig-lispify "terminal_open" 'function)) :int) + +(cl:export '#.(swig-lispify "terminal_open" 'function)) + +(cffi:defcfun ("terminal_close" #.(swig-lispify "terminal_close" 'function)) :void) + +(cl:export '#.(swig-lispify "terminal_close" 'function)) + +(cffi:defcfun ("terminal_set8" #.(swig-lispify "terminal_set8" 'function)) :int + (value :string)) + +(cl:export '#.(swig-lispify "terminal_set8" 'function)) + +(cffi:defcfun ("terminal_set16" #.(swig-lispify "terminal_set16" 'function)) :int + (value :pointer)) + +(cl:export '#.(swig-lispify "terminal_set16" 'function)) + +(cffi:defcfun ("terminal_set32" #.(swig-lispify "terminal_set32" 'function)) :int + (value :pointer)) + +(cl:export '#.(swig-lispify "terminal_set32" 'function)) + +(cffi:defcfun ("terminal_refresh" #.(swig-lispify "terminal_refresh" 'function)) :void) + +(cl:export '#.(swig-lispify "terminal_refresh" 'function)) + +(cffi:defcfun ("terminal_clear" #.(swig-lispify "terminal_clear" 'function)) :void) + +(cl:export '#.(swig-lispify "terminal_clear" 'function)) + +(cffi:defcfun ("terminal_clear_area" #.(swig-lispify "terminal_clear_area" 'function)) :void + (x :int) + (y :int) + (w :int) + (h :int)) + +(cl:export '#.(swig-lispify "terminal_clear_area" 'function)) + +(cffi:defcfun ("terminal_crop" #.(swig-lispify "terminal_crop" 'function)) :void + (x :int) + (y :int) + (w :int) + (h :int)) + +(cl:export '#.(swig-lispify "terminal_crop" 'function)) + +(cffi:defcfun ("terminal_layer" #.(swig-lispify "terminal_layer" 'function)) :void + (index :int)) + +(cl:export '#.(swig-lispify "terminal_layer" 'function)) + +(cffi:defcfun ("terminal_color" #.(swig-lispify "terminal_color" 'function)) :void + (color color)) + +(cl:export '#.(swig-lispify "terminal_color" 'function)) + +(cffi:defcfun ("terminal_bkcolor" #.(swig-lispify "terminal_bkcolor" 'function)) :void + (color color)) + +(cl:export '#.(swig-lispify "terminal_bkcolor" 'function)) + +(cffi:defcfun ("terminal_composition" #.(swig-lispify "terminal_composition" 'function)) :void + (mode :int)) + +(cl:export '#.(swig-lispify "terminal_composition" 'function)) + +(cffi:defcfun ("terminal_put" #.(swig-lispify "terminal_put" 'function)) :void + (x :int) + (y :int) + (code :int)) + +(cl:export '#.(swig-lispify "terminal_put" 'function)) + +(cffi:defcfun ("terminal_put_ext" #.(swig-lispify "terminal_put_ext" 'function)) :void + (x :int) + (y :int) + (dx :int) + (dy :int) + (code :int) + (corners :pointer)) + +(cl:export '#.(swig-lispify "terminal_put_ext" 'function)) + +(cffi:defcfun ("terminal_pick" #.(swig-lispify "terminal_pick" 'function)) :int + (x :int) + (y :int) + (index :int)) + +(cl:export '#.(swig-lispify "terminal_pick" 'function)) + +(cffi:defcfun ("terminal_pick_color" #.(swig-lispify "terminal_pick_color" 'function)) color + (x :int) + (y :int) + (index :int)) + +(cl:export '#.(swig-lispify "terminal_pick_color" 'function)) + +(cffi:defcfun ("terminal_pick_bkcolor" #.(swig-lispify "terminal_pick_bkcolor" 'function)) color + (x :int) + (y :int)) + +(cl:export '#.(swig-lispify "terminal_pick_bkcolor" 'function)) + +(cffi:defcfun ("terminal_print_ext8" #.(swig-lispify "terminal_print_ext8" 'function)) :void + (x :int) + (y :int) + (w :int) + (h :int) + (align :int) + (s :pointer) + (out_w :pointer) + (out_h :pointer)) + +(cl:export '#.(swig-lispify "terminal_print_ext8" 'function)) + +(cffi:defcfun ("terminal_print_ext16" #.(swig-lispify "terminal_print_ext16" 'function)) :void + (x :int) + (y :int) + (w :int) + (h :int) + (align :int) + (s :pointer) + (out_w :pointer) + (out_h :pointer)) + +(cl:export '#.(swig-lispify "terminal_print_ext16" 'function)) + +(cffi:defcfun ("terminal_print_ext32" #.(swig-lispify "terminal_print_ext32" 'function)) :void + (x :int) + (y :int) + (w :int) + (h :int) + (align :int) + (s :pointer) + (out_w :pointer) + (out_h :pointer)) + +(cl:export '#.(swig-lispify "terminal_print_ext32" 'function)) + +(cffi:defcfun ("terminal_measure_ext8" #.(swig-lispify "terminal_measure_ext8" 'function)) :void + (w :int) + (h :int) + (s :pointer) + (out_w :pointer) + (out_h :pointer)) + +(cl:export '#.(swig-lispify "terminal_measure_ext8" 'function)) + +(cffi:defcfun ("terminal_measure_ext16" #.(swig-lispify "terminal_measure_ext16" 'function)) :void + (w :int) + (h :int) + (s :pointer) + (out_w :pointer) + (out_h :pointer)) + +(cl:export '#.(swig-lispify "terminal_measure_ext16" 'function)) + +(cffi:defcfun ("terminal_measure_ext32" #.(swig-lispify "terminal_measure_ext32" 'function)) :void + (w :int) + (h :int) + (s :pointer) + (out_w :pointer) + (out_h :pointer)) + +(cl:export '#.(swig-lispify "terminal_measure_ext32" 'function)) + +(cffi:defcfun ("terminal_has_input" #.(swig-lispify "terminal_has_input" 'function)) :int) + +(cl:export '#.(swig-lispify "terminal_has_input" 'function)) + +(cffi:defcfun ("terminal_state" #.(swig-lispify "terminal_state" 'function)) :int + (code :int)) + +(cl:export '#.(swig-lispify "terminal_state" 'function)) + +(cffi:defcfun ("terminal_read" #.(swig-lispify "terminal_read" 'function)) :int) + +(cl:export '#.(swig-lispify "terminal_read" 'function)) + +(cffi:defcfun ("terminal_read_str8" #.(swig-lispify "terminal_read_str8" 'function)) :int + (x :int) + (y :int) + (buffer :pointer) + (max :int)) + +(cl:export '#.(swig-lispify "terminal_read_str8" 'function)) + +(cffi:defcfun ("terminal_read_str16" #.(swig-lispify "terminal_read_str16" 'function)) :int + (x :int) + (y :int) + (buffer :pointer) + (max :int)) + +(cl:export '#.(swig-lispify "terminal_read_str16" 'function)) + +(cffi:defcfun ("terminal_read_str32" #.(swig-lispify "terminal_read_str32" 'function)) :int + (x :int) + (y :int) + (buffer :pointer) + (max :int)) + +(cl:export '#.(swig-lispify "terminal_read_str32" 'function)) + +(cffi:defcfun ("terminal_peek" #.(swig-lispify "terminal_peek" 'function)) :int) + +(cl:export '#.(swig-lispify "terminal_peek" 'function)) + +(cffi:defcfun ("terminal_delay" #.(swig-lispify "terminal_delay" 'function)) :void + (period :int)) + +(cl:export '#.(swig-lispify "terminal_delay" 'function)) + +(cffi:defcfun ("terminal_get8" #.(swig-lispify "terminal_get8" 'function)) :pointer + (key :pointer) + (default_ :pointer)) + +(cl:export '#.(swig-lispify "terminal_get8" 'function)) + +(cffi:defcfun ("terminal_get16" #.(swig-lispify "terminal_get16" 'function)) :pointer + (key :pointer) + (default_ :pointer)) + +(cl:export '#.(swig-lispify "terminal_get16" 'function)) + +(cffi:defcfun ("terminal_get32" #.(swig-lispify "terminal_get32" 'function)) :pointer + (key :pointer) + (default_ :pointer)) + +(cl:export '#.(swig-lispify "terminal_get32" 'function)) + +(cffi:defcfun ("color_from_name8" #.(swig-lispify "color_from_name8" 'function)) color + (name :pointer)) + +(cl:export '#.(swig-lispify "color_from_name8" 'function)) + +(cffi:defcfun ("color_from_name16" #.(swig-lispify "color_from_name16" 'function)) color + (name :pointer)) + +(cl:export '#.(swig-lispify "color_from_name16" 'function)) + +(cffi:defcfun ("color_from_name32" #.(swig-lispify "color_from_name32" 'function)) color + (name :pointer)) + +(cl:export '#.(swig-lispify "color_from_name32" 'function)) + +(cl:defconstant #.(swig-lispify "__SIZEOF_WCHAR_T__" 'constant) 4) + +(cl:export '#.(swig-lispify "__SIZEOF_WCHAR_T__" 'constant)) + +(cl:defconstant #.(swig-lispify "TERMINAL_WCHAR_SUFFIX" 'constant) 32) + +(cl:export '#.(swig-lispify "TERMINAL_WCHAR_SUFFIX" 'constant)) + +(cl:defconstant #.(swig-lispify "TERMINAL_VSPRINTF_MAXIMUM_BUFFER_SIZE" 'constant) 65536) + +(cl:export '#.(swig-lispify "TERMINAL_VSPRINTF_MAXIMUM_BUFFER_SIZE" 'constant)) + +(cffi:defcfun ("terminal_vsprintf" #.(swig-lispify "terminal_vsprintf" 'function)) :string + (s :string) + (args :pointer)) + +(cl:export '#.(swig-lispify "terminal_vsprintf" 'function)) + +(cffi:defcfun ("terminal_vswprintf" #.(swig-lispify "terminal_vswprintf" 'function)) :pointer + (s :pointer) + (args :pointer)) + +(cl:export '#.(swig-lispify "terminal_vswprintf" 'function)) + +(cffi:defcfun ("terminal_set" #.(swig-lispify "terminal_set" 'function)) :int + (s :string)) + +(cl:export '#.(swig-lispify "terminal_set" 'function)) + +(cffi:defcfun ("terminal_setf" #.(swig-lispify "terminal_setf" 'function)) :int + (s :string) + &rest) + +(cl:export '#.(swig-lispify "terminal_setf" 'function)) + +(cffi:defcfun ("terminal_wset" #.(swig-lispify "terminal_wset" 'function)) :int + (s :pointer)) + +(cl:export '#.(swig-lispify "terminal_wset" 'function)) + +(cffi:defcfun ("terminal_wsetf" #.(swig-lispify "terminal_wsetf" 'function)) :int + (s :pointer) + &rest) + +(cl:export '#.(swig-lispify "terminal_wsetf" 'function)) + +(cffi:defcfun ("terminal_print" #.(swig-lispify "terminal_print" 'function)) #.(swig-lispify "dimensions_t" 'classname) + (x :int) + (y :int) + (s :string)) + +(cl:export '#.(swig-lispify "terminal_print" 'function)) + +(cffi:defcfun ("terminal_printf" #.(swig-lispify "terminal_printf" 'function)) #.(swig-lispify "dimensions_t" 'classname) + (x :int) + (y :int) + (s :string) + &rest) + +(cl:export '#.(swig-lispify "terminal_printf" 'function)) + +(cffi:defcfun ("terminal_wprint" #.(swig-lispify "terminal_wprint" 'function)) #.(swig-lispify "dimensions_t" 'classname) + (x :int) + (y :int) + (s :pointer)) + +(cl:export '#.(swig-lispify "terminal_wprint" 'function)) + +(cffi:defcfun ("terminal_wprintf" #.(swig-lispify "terminal_wprintf" 'function)) #.(swig-lispify "dimensions_t" 'classname) + (x :int) + (y :int) + (s :pointer) + &rest) + +(cl:export '#.(swig-lispify "terminal_wprintf" 'function)) + +(cffi:defcfun ("terminal_print_ext" #.(swig-lispify "terminal_print_ext" 'function)) #.(swig-lispify "dimensions_t" 'classname) + (x :int) + (y :int) + (w :int) + (h :int) + (align :int) + (s :string)) + +(cl:export '#.(swig-lispify "terminal_print_ext" 'function)) + +(cffi:defcfun ("terminal_printf_ext" #.(swig-lispify "terminal_printf_ext" 'function)) #.(swig-lispify "dimensions_t" 'classname) + (x :int) + (y :int) + (w :int) + (h :int) + (align :int) + (s :string) + &rest) + +(cl:export '#.(swig-lispify "terminal_printf_ext" 'function)) + +(cffi:defcfun ("terminal_wprint_ext" #.(swig-lispify "terminal_wprint_ext" 'function)) #.(swig-lispify "dimensions_t" 'classname) + (x :int) + (y :int) + (w :int) + (h :int) + (align :int) + (s :pointer)) + +(cl:export '#.(swig-lispify "terminal_wprint_ext" 'function)) + +(cffi:defcfun ("terminal_wprintf_ext" #.(swig-lispify "terminal_wprintf_ext" 'function)) #.(swig-lispify "dimensions_t" 'classname) + (x :int) + (y :int) + (w :int) + (h :int) + (align :int) + (s :pointer) + &rest) + +(cl:export '#.(swig-lispify "terminal_wprintf_ext" 'function)) + +(cffi:defcfun ("terminal_measure" #.(swig-lispify "terminal_measure" 'function)) #.(swig-lispify "dimensions_t" 'classname) + (s :string)) + +(cl:export '#.(swig-lispify "terminal_measure" 'function)) + +(cffi:defcfun ("terminal_measuref" #.(swig-lispify "terminal_measuref" 'function)) #.(swig-lispify "dimensions_t" 'classname) + (s :string) + &rest) + +(cl:export '#.(swig-lispify "terminal_measuref" 'function)) + +(cffi:defcfun ("terminal_wmeasure" #.(swig-lispify "terminal_wmeasure" 'function)) #.(swig-lispify "dimensions_t" 'classname) + (s :pointer)) + +(cl:export '#.(swig-lispify "terminal_wmeasure" 'function)) + +(cffi:defcfun ("terminal_wmeasuref" #.(swig-lispify "terminal_wmeasuref" 'function)) #.(swig-lispify "dimensions_t" 'classname) + (s :pointer) + &rest) + +(cl:export '#.(swig-lispify "terminal_wmeasuref" 'function)) + +(cffi:defcfun ("terminal_measure_ext" #.(swig-lispify "terminal_measure_ext" 'function)) #.(swig-lispify "dimensions_t" 'classname) + (w :int) + (h :int) + (s :string)) + +(cl:export '#.(swig-lispify "terminal_measure_ext" 'function)) + +(cffi:defcfun ("terminal_measuref_ext" #.(swig-lispify "terminal_measuref_ext" 'function)) #.(swig-lispify "dimensions_t" 'classname) + (w :int) + (h :int) + (s :string) + &rest) + +(cl:export '#.(swig-lispify "terminal_measuref_ext" 'function)) + +(cffi:defcfun ("terminal_wmeasure_ext" #.(swig-lispify "terminal_wmeasure_ext" 'function)) #.(swig-lispify "dimensions_t" 'classname) + (w :int) + (h :int) + (s :pointer)) + +(cl:export '#.(swig-lispify "terminal_wmeasure_ext" 'function)) + +(cffi:defcfun ("terminal_wmeasuref_ext" #.(swig-lispify "terminal_wmeasuref_ext" 'function)) #.(swig-lispify "dimensions_t" 'classname) + (w :int) + (h :int) + (s :pointer) + &rest) + +(cl:export '#.(swig-lispify "terminal_wmeasuref_ext" 'function)) + +(cffi:defcfun ("terminal_read_str" #.(swig-lispify "terminal_read_str" 'function)) :int + (x :int) + (y :int) + (buffer :string) + (max :int)) + +(cl:export '#.(swig-lispify "terminal_read_str" 'function)) + +(cffi:defcfun ("terminal_read_wstr" #.(swig-lispify "terminal_read_wstr" 'function)) :int + (x :int) + (y :int) + (buffer :pointer) + (max :int)) + +(cl:export '#.(swig-lispify "terminal_read_wstr" 'function)) + +(cffi:defcfun ("terminal_get" #.(swig-lispify "terminal_get" 'function)) :string + (key :string) + (default_ :string)) + +(cl:export '#.(swig-lispify "terminal_get" 'function)) + +(cffi:defcfun ("terminal_wget" #.(swig-lispify "terminal_wget" 'function)) :pointer + (key :pointer) + (default_ :pointer)) + +(cl:export '#.(swig-lispify "terminal_wget" 'function)) + +(cffi:defcfun ("color_from_name" #.(swig-lispify "color_from_name" 'function)) color + (name :string)) + +(cl:export '#.(swig-lispify "color_from_name" 'function)) + +(cffi:defcfun ("color_from_wname" #.(swig-lispify "color_from_wname" 'function)) color + (name :pointer)) + +(cl:export '#.(swig-lispify "color_from_wname" 'function)) + +(cffi:defcfun ("color_from_argb" #.(swig-lispify "color_from_argb" 'function)) color + (a :pointer) + (r :pointer) + (g :pointer) + (b :pointer)) + +(cl:export '#.(swig-lispify "color_from_argb" 'function)) + +(cffi:defcfun ("terminal_check" #.(swig-lispify "terminal_check" 'function)) :int + (code :int)) + +(cl:export '#.(swig-lispify "terminal_check" 'function)) + + diff -r 000000000000 -r f61929db839b src/low-level/bearlibterminal.swig --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/low-level/bearlibterminal.swig Sat Feb 11 00:52:24 2017 +0000 @@ -0,0 +1,20 @@ +%module bearlibterminal + +%insert("lisphead") %{ +(cl:in-package :bearlibterminal/low-level) + +(cffi:defctype color :uint) + +(cffi:define-foreign-library bearlibterminal + (:darwin "lib/libBearLibTerminal.dylib")) + +(cffi:use-foreign-library bearlibterminal) +%} + +%feature("intern_function","1"); +%feature("export"); + +%typemap(cin) color_t "color"; +%typemap(cout) color_t "color"; + +%include "src/low-level/include/BearLibTerminal.h" diff -r 000000000000 -r f61929db839b src/low-level/include/BearLibTerminal.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/low-level/include/BearLibTerminal.h Sat Feb 11 00:52:24 2017 +0000 @@ -0,0 +1,747 @@ +/* +* BearLibTerminal +* Copyright (C) 2013-2017 Cfyz +* +* Permission is hereby granted, free of charge, to any person obtaining a copy +* of this software and associated documentation files (the "Software"), to deal +* in the Software without restriction, including without limitation the rights +* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies +* of the Software, and to permit persons to whom the Software is furnished to do +* so, subject to the following conditions: +* +* The above copyright notice and this permission notice shall be included in all +* copies or substantial portions of the Software. +* +* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS +* FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR +* COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +* IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +* CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. +*/ + +#ifndef BEARLIBTERMINAL_H +#define BEARLIBTERMINAL_H + +#if defined(_MSC_VER) && !defined(_CRT_SECURE_NO_WARNINGS) +#define _CRT_SECURE_NO_WARNINGS +#endif + +#ifdef __GNUC__ +#if __GNUC__ > 4 || (__GNUC__ == 4 && __GNUC_MINOR__ > 1) +#pragma GCC diagnostic ignored "-Wformat-nonliteral" /* False-positive when wrapping vsnprintf. */ +#endif /* __GNUC__ >= 4.1 */ +#endif + +#include +#include +#include +#include +#include +#include +#if defined(__cplusplus) +#include +#endif + +/* + * Keyboard scancodes for events/states + */ +#define TK_A 0x04 +#define TK_B 0x05 +#define TK_C 0x06 +#define TK_D 0x07 +#define TK_E 0x08 +#define TK_F 0x09 +#define TK_G 0x0A +#define TK_H 0x0B +#define TK_I 0x0C +#define TK_J 0x0D +#define TK_K 0x0E +#define TK_L 0x0F +#define TK_M 0x10 +#define TK_N 0x11 +#define TK_O 0x12 +#define TK_P 0x13 +#define TK_Q 0x14 +#define TK_R 0x15 +#define TK_S 0x16 +#define TK_T 0x17 +#define TK_U 0x18 +#define TK_V 0x19 +#define TK_W 0x1A +#define TK_X 0x1B +#define TK_Y 0x1C +#define TK_Z 0x1D +#define TK_1 0x1E +#define TK_2 0x1F +#define TK_3 0x20 +#define TK_4 0x21 +#define TK_5 0x22 +#define TK_6 0x23 +#define TK_7 0x24 +#define TK_8 0x25 +#define TK_9 0x26 +#define TK_0 0x27 +#define TK_RETURN 0x28 +#define TK_ENTER 0x28 +#define TK_ESCAPE 0x29 +#define TK_BACKSPACE 0x2A +#define TK_TAB 0x2B +#define TK_SPACE 0x2C +#define TK_MINUS 0x2D /* - */ +#define TK_EQUALS 0x2E /* = */ +#define TK_LBRACKET 0x2F /* [ */ +#define TK_RBRACKET 0x30 /* ] */ +#define TK_BACKSLASH 0x31 /* \ */ +#define TK_SEMICOLON 0x33 /* ; */ +#define TK_APOSTROPHE 0x34 /* ' */ +#define TK_GRAVE 0x35 /* ` */ +#define TK_COMMA 0x36 /* , */ +#define TK_PERIOD 0x37 /* . */ +#define TK_SLASH 0x38 /* / */ +#define TK_F1 0x3A +#define TK_F2 0x3B +#define TK_F3 0x3C +#define TK_F4 0x3D +#define TK_F5 0x3E +#define TK_F6 0x3F +#define TK_F7 0x40 +#define TK_F8 0x41 +#define TK_F9 0x42 +#define TK_F10 0x43 +#define TK_F11 0x44 +#define TK_F12 0x45 +#define TK_PAUSE 0x48 /* Pause/Break */ +#define TK_INSERT 0x49 +#define TK_HOME 0x4A +#define TK_PAGEUP 0x4B +#define TK_DELETE 0x4C +#define TK_END 0x4D +#define TK_PAGEDOWN 0x4E +#define TK_RIGHT 0x4F /* Right arrow */ +#define TK_LEFT 0x50 /* Left arrow */ +#define TK_DOWN 0x51 /* Down arrow */ +#define TK_UP 0x52 /* Up arrow */ +#define TK_KP_DIVIDE 0x54 /* '/' on numpad */ +#define TK_KP_MULTIPLY 0x55 /* '*' on numpad */ +#define TK_KP_MINUS 0x56 /* '-' on numpad */ +#define TK_KP_PLUS 0x57 /* '+' on numpad */ +#define TK_KP_ENTER 0x58 +#define TK_KP_1 0x59 +#define TK_KP_2 0x5A +#define TK_KP_3 0x5B +#define TK_KP_4 0x5C +#define TK_KP_5 0x5D +#define TK_KP_6 0x5E +#define TK_KP_7 0x5F +#define TK_KP_8 0x60 +#define TK_KP_9 0x61 +#define TK_KP_0 0x62 +#define TK_KP_PERIOD 0x63 /* '.' on numpad */ +#define TK_SHIFT 0x70 +#define TK_CONTROL 0x71 +#define TK_ALT 0x72 + +/* + * Mouse events/states + */ +#define TK_MOUSE_LEFT 0x80 /* Buttons */ +#define TK_MOUSE_RIGHT 0x81 +#define TK_MOUSE_MIDDLE 0x82 +#define TK_MOUSE_X1 0x83 +#define TK_MOUSE_X2 0x84 +#define TK_MOUSE_MOVE 0x85 /* Movement event */ +#define TK_MOUSE_SCROLL 0x86 /* Mouse scroll event */ +#define TK_MOUSE_X 0x87 /* Cusor position in cells */ +#define TK_MOUSE_Y 0x88 +#define TK_MOUSE_PIXEL_X 0x89 /* Cursor position in pixels */ +#define TK_MOUSE_PIXEL_Y 0x8A +#define TK_MOUSE_WHEEL 0x8B /* Scroll direction and amount */ +#define TK_MOUSE_CLICKS 0x8C /* Number of consecutive clicks */ + +/* + * If key was released instead of pressed, it's code will be OR'ed with TK_KEY_RELEASED: + * a) pressed 'A': 0x04 + * b) released 'A': 0x04|VK_KEY_RELEASED = 0x104 + */ +#define TK_KEY_RELEASED 0x100 + +/* + * Virtual key-codes for internal terminal states/variables. + * These can be accessed via terminal_state function. + */ +#define TK_WIDTH 0xC0 /* Terminal window size in cells */ +#define TK_HEIGHT 0xC1 +#define TK_CELL_WIDTH 0xC2 /* Character cell size in pixels */ +#define TK_CELL_HEIGHT 0xC3 +#define TK_COLOR 0xC4 /* Current foregroung color */ +#define TK_BKCOLOR 0xC5 /* Current background color */ +#define TK_LAYER 0xC6 /* Current layer */ +#define TK_COMPOSITION 0xC7 /* Current composition state */ +#define TK_CHAR 0xC8 /* Translated ANSI code of last produced character */ +#define TK_WCHAR 0xC9 /* Unicode codepoint of last produced character */ +#define TK_EVENT 0xCA /* Last dequeued event */ +#define TK_FULLSCREEN 0xCB /* Fullscreen state */ + +/* + * Other events + */ +#define TK_CLOSE 0xE0 +#define TK_RESIZED 0xE1 + +/* + * Generic mode enum. + * Right now it is used for composition option only. + */ +#define TK_OFF 0 +#define TK_ON 1 + +/* + * Input result codes for terminal_read function. + */ +#define TK_INPUT_NONE 0 +#define TK_INPUT_CANCELLED -1 + +/* + * Text printing alignment. + */ +#define TK_ALIGN_DEFAULT 0 +#define TK_ALIGN_LEFT 1 +#define TK_ALIGN_RIGHT 2 +#define TK_ALIGN_CENTER 3 +#define TK_ALIGN_TOP 4 +#define TK_ALIGN_BOTTOM 8 +#define TK_ALIGN_MIDDLE 12 + +/* + * Terminal uses unsigned 32-bit value for color representation in ARGB order (0xAARRGGBB), e. g. + * a) solid red is 0xFFFF0000 + * b) half-transparent green is 0x8000FF00 + */ +typedef uint32_t color_t; + +typedef struct dimensions_t_ +{ + int width; + int height; +} +dimensions_t; + +#if defined(BEARLIBTERMINAL_STATIC_BUILD) +# define TERMINAL_API +#elif defined(_WIN32) +# if defined(BEARLIBTERMINAL_BUILDING_LIBRARY) +# define TERMINAL_API __declspec(dllexport) +# else +# define TERMINAL_API __declspec(dllimport) +# endif +#else +# if defined(BEARLIBTERMINAL_BUILDING_LIBRARY) && __GNUC__ >= 4 +# define TERMINAL_API __attribute__ ((visibility ("default"))) +# else +# define TERMINAL_API +# endif +#endif + +#ifdef __cplusplus +extern "C" { +#endif + +TERMINAL_API int terminal_open(); +TERMINAL_API void terminal_close(); +TERMINAL_API int terminal_set8(const int8_t* value); +TERMINAL_API int terminal_set16(const int16_t* value); +TERMINAL_API int terminal_set32(const int32_t* value); +TERMINAL_API void terminal_refresh(); +TERMINAL_API void terminal_clear(); +TERMINAL_API void terminal_clear_area(int x, int y, int w, int h); +TERMINAL_API void terminal_crop(int x, int y, int w, int h); +TERMINAL_API void terminal_layer(int index); +TERMINAL_API void terminal_color(color_t color); +TERMINAL_API void terminal_bkcolor(color_t color); +TERMINAL_API void terminal_composition(int mode); +TERMINAL_API void terminal_put(int x, int y, int code); +TERMINAL_API void terminal_put_ext(int x, int y, int dx, int dy, int code, color_t* corners); +TERMINAL_API int terminal_pick(int x, int y, int index); +TERMINAL_API color_t terminal_pick_color(int x, int y, int index); +TERMINAL_API color_t terminal_pick_bkcolor(int x, int y); +TERMINAL_API void terminal_print_ext8(int x, int y, int w, int h, int align, const int8_t* s, int* out_w, int* out_h); +TERMINAL_API void terminal_print_ext16(int x, int y, int w, int h, int align, const int16_t* s, int* out_w, int* out_h); +TERMINAL_API void terminal_print_ext32(int x, int y, int w, int h, int align, const int32_t* s, int* out_w, int* out_h); +TERMINAL_API void terminal_measure_ext8(int w, int h, const int8_t* s, int* out_w, int* out_h); +TERMINAL_API void terminal_measure_ext16(int w, int h, const int16_t* s, int* out_w, int* out_h); +TERMINAL_API void terminal_measure_ext32(int w, int h, const int32_t* s, int* out_w, int* out_h); +TERMINAL_API int terminal_has_input(); +TERMINAL_API int terminal_state(int code); +TERMINAL_API int terminal_read(); +TERMINAL_API int terminal_read_str8(int x, int y, int8_t* buffer, int max); +TERMINAL_API int terminal_read_str16(int x, int y, int16_t* buffer, int max); +TERMINAL_API int terminal_read_str32(int x, int y, int32_t* buffer, int max); +TERMINAL_API int terminal_peek(); +TERMINAL_API void terminal_delay(int period); +TERMINAL_API const int8_t* terminal_get8(const int8_t* key, const int8_t* default_); +TERMINAL_API const int16_t* terminal_get16(const int16_t* key, const int16_t* default_); +TERMINAL_API const int32_t* terminal_get32(const int32_t* key, const int32_t* default_); +TERMINAL_API color_t color_from_name8(const int8_t* name); +TERMINAL_API color_t color_from_name16(const int16_t* name); +TERMINAL_API color_t color_from_name32(const int32_t* name); + +#ifdef __cplusplus +} /* End of extern "C" */ +#endif + +/* + * Utility macro trick which allows macro-in-macro expansion + */ +#define TERMINAL_CAT(a, b) TERMINAL_PRIMITIVE_CAT(a, b) +#define TERMINAL_PRIMITIVE_CAT(a, b) a ## b + +/* + * wchar_t has different sized depending on platform. Furthermore, it's size + * can be changed for GCC compiler. + */ +#if !defined(__SIZEOF_WCHAR_T__) +# if defined(_WIN32) +# define __SIZEOF_WCHAR_T__ 2 +# else +# define __SIZEOF_WCHAR_T__ 4 +# endif +#endif + +#if __SIZEOF_WCHAR_T__ == 2 +#define TERMINAL_WCHAR_SUFFIX 16 +#define TERMINAL_WCHAR_TYPE int16_t +#else // 4 +#define TERMINAL_WCHAR_SUFFIX 32 +#define TERMINAL_WCHAR_TYPE int32_t +#endif + +#if defined(__cplusplus) +#define TERMINAL_INLINE inline +#define TERMINAL_DEFAULT(value) = value +#else +#define TERMINAL_INLINE static inline +#define TERMINAL_DEFAULT(value) +#endif + +/* + * These functions provide inline string formatting support + * for terminal_setf, terminal_printf, etc. + * + * Using static termporary buffer is okay because terminal API is not + * required to be multiple-thread safe by design. + */ + +#define TERMINAL_VSPRINTF_MAXIMUM_BUFFER_SIZE 65536 + +TERMINAL_INLINE const char* terminal_vsprintf(const char* s, va_list args) +{ + static int buffer_size = 512; + static char* buffer = NULL; + int rc = 0; + + if (!s) + return NULL; + else if (!buffer) + buffer = (char*)malloc(buffer_size); + + while (true) + { + buffer[buffer_size-1] = '\0'; + rc = vsnprintf(buffer, buffer_size, s, args); + if (rc >= buffer_size || buffer[buffer_size-1] != '\0') + { + if (buffer_size >= TERMINAL_VSPRINTF_MAXIMUM_BUFFER_SIZE) + return NULL; + + buffer_size *= 2; + buffer = (char*)realloc(buffer, buffer_size); + } + else + { + break; + } + } + + return rc >= 0? buffer: NULL; +} + +TERMINAL_INLINE const wchar_t* terminal_vswprintf(const wchar_t* s, va_list args) +{ + static int buffer_size = 512; + static wchar_t* buffer = NULL; + int rc = 0; + + if (!s) + return NULL; + else if (!buffer) + buffer = (wchar_t*)malloc(buffer_size * sizeof(wchar_t)); + + while (true) + { + buffer[buffer_size-1] = L'\0'; +#if defined(_WIN32) + rc = _vsnwprintf(buffer, buffer_size, s, args); +#else + rc = vswprintf(buffer, buffer_size, s, args); +#endif + if (rc >= buffer_size || buffer[buffer_size-1] != L'\0') + { + if (buffer_size >= TERMINAL_VSPRINTF_MAXIMUM_BUFFER_SIZE) + return NULL; + + buffer_size *= 2; + buffer = (wchar_t*)realloc(buffer, buffer_size * sizeof(wchar_t)); + } + else + { + break; + } + } + + return rc >= 0? buffer: NULL; +} + +#define TERMINAL_FORMATTED_WRAP(type, call) \ + type ret; \ + va_list args; \ + va_start(args, s); \ + ret = call; \ + va_end(args); \ + return ret; + +#define TERMINAL_FORMATTED_WRAP_V(call) \ + va_list args; \ + va_start(args, s); \ + call; \ + va_end(args); + +/* + * This set of inline functions define basic name substitution + type cast: + * terminal_[w]xxxx -> terminal_xxxx{8|16|32} + */ + +TERMINAL_INLINE int terminal_set(const char* s) +{ + return terminal_set8((const int8_t*)s); +} + +TERMINAL_INLINE int terminal_setf(const char* s, ...) +{ + TERMINAL_FORMATTED_WRAP(int, terminal_set(terminal_vsprintf(s, args))) +} + +TERMINAL_INLINE int terminal_wset(const wchar_t* s) +{ + return TERMINAL_CAT(terminal_set, TERMINAL_WCHAR_SUFFIX)((const TERMINAL_WCHAR_TYPE*)s); +} + +TERMINAL_INLINE int terminal_wsetf(const wchar_t* s, ...) +{ + TERMINAL_FORMATTED_WRAP(int, terminal_wset(terminal_vswprintf(s, args))) +} + +TERMINAL_INLINE dimensions_t terminal_print(int x, int y, const char* s) +{ + dimensions_t ret; + terminal_print_ext8(x, y, 0, 0, TK_ALIGN_DEFAULT, (const int8_t*)s, &ret.width, &ret.height); + return ret; +} + +TERMINAL_INLINE dimensions_t terminal_printf(int x, int y, const char* s, ...) +{ + TERMINAL_FORMATTED_WRAP(dimensions_t, terminal_print(x, y, terminal_vsprintf(s, args))) +} + +TERMINAL_INLINE dimensions_t terminal_wprint(int x, int y, const wchar_t* s) +{ + dimensions_t ret; + TERMINAL_CAT(terminal_print_ext, TERMINAL_WCHAR_SUFFIX)(x, y, 0, 0, TK_ALIGN_DEFAULT, (const TERMINAL_WCHAR_TYPE*)s, &ret.width, &ret.height); + return ret; +} + +TERMINAL_INLINE dimensions_t terminal_wprintf(int x, int y, const wchar_t* s, ...) +{ + TERMINAL_FORMATTED_WRAP(dimensions_t, terminal_wprint(x, y, terminal_vswprintf(s, args))) +} + +TERMINAL_INLINE dimensions_t terminal_print_ext(int x, int y, int w, int h, int align, const char* s) +{ + dimensions_t ret; + terminal_print_ext8(x, y, w, h, align, (const int8_t*)s, &ret.width, &ret.height); + return ret; +} + +TERMINAL_INLINE dimensions_t terminal_printf_ext(int x, int y, int w, int h, int align, const char* s, ...) +{ + TERMINAL_FORMATTED_WRAP(dimensions_t, terminal_print_ext(x, y, w, h, align, terminal_vsprintf(s, args))); +} + +TERMINAL_INLINE dimensions_t terminal_wprint_ext(int x, int y, int w, int h, int align, const wchar_t* s) +{ + dimensions_t ret; + TERMINAL_CAT(terminal_print_ext, TERMINAL_WCHAR_SUFFIX)(x, y, w, h, align, (const TERMINAL_WCHAR_TYPE*)s, &ret.width, &ret.height); + return ret; +} + +TERMINAL_INLINE dimensions_t terminal_wprintf_ext(int x, int y, int w, int h, int align, const wchar_t* s, ...) +{ + TERMINAL_FORMATTED_WRAP(dimensions_t, terminal_wprint_ext(x, y, w, h, align, terminal_vswprintf(s, args))) +} + +TERMINAL_INLINE dimensions_t terminal_measure(const char* s) +{ + dimensions_t ret; + terminal_measure_ext8(0, 0, (const int8_t*)s, &ret.width, &ret.height); + return ret; +} + +TERMINAL_INLINE dimensions_t terminal_measuref(const char* s, ...) +{ + TERMINAL_FORMATTED_WRAP(dimensions_t, terminal_measure(terminal_vsprintf(s, args))) +} + +TERMINAL_INLINE dimensions_t terminal_wmeasure(const wchar_t* s) +{ + dimensions_t ret; + TERMINAL_CAT(terminal_measure_ext, TERMINAL_WCHAR_SUFFIX)(0, 0, (const TERMINAL_WCHAR_TYPE*)s, &ret.width, &ret.height); + return ret; +} + +TERMINAL_INLINE dimensions_t terminal_wmeasuref(const wchar_t* s, ...) +{ + TERMINAL_FORMATTED_WRAP(dimensions_t, terminal_wmeasure(terminal_vswprintf(s, args))) +} + +TERMINAL_INLINE dimensions_t terminal_measure_ext(int w, int h, const char* s) +{ + dimensions_t ret; + terminal_measure_ext8(w, h, (const int8_t*)s, &ret.width, &ret.height); + return ret; +} + +TERMINAL_INLINE dimensions_t terminal_measuref_ext(int w, int h, const char* s, ...) +{ + TERMINAL_FORMATTED_WRAP(dimensions_t, terminal_measure_ext(w, h, terminal_vsprintf(s, args))) +} + +TERMINAL_INLINE dimensions_t terminal_wmeasure_ext(int w, int h, const wchar_t* s) +{ + dimensions_t ret; + TERMINAL_CAT(terminal_measure_ext, TERMINAL_WCHAR_SUFFIX)(w, h, (const TERMINAL_WCHAR_TYPE*)s, &ret.width, &ret.height); + return ret; +} + +TERMINAL_INLINE dimensions_t terminal_wmeasuref_ext(int w, int h, const wchar_t* s, ...) +{ + TERMINAL_FORMATTED_WRAP(dimensions_t, terminal_wmeasure_ext(w, h, terminal_vswprintf(s, args))) +} + +TERMINAL_INLINE int terminal_read_str(int x, int y, char* buffer, int max) +{ + return terminal_read_str8(x, y, (int8_t*)buffer, max); +} + +TERMINAL_INLINE int terminal_read_wstr(int x, int y, wchar_t* buffer, int max) +{ + return TERMINAL_CAT(terminal_read_str, TERMINAL_WCHAR_SUFFIX)(x, y, (TERMINAL_WCHAR_TYPE*)buffer, max); +} + +TERMINAL_INLINE const char* terminal_get(const char* key, const char* default_ TERMINAL_DEFAULT((const char*)0)) +{ + return (const char*)terminal_get8((const int8_t*)key, (const int8_t*)default_); +} + +TERMINAL_INLINE const wchar_t* terminal_wget(const wchar_t* key, const wchar_t* default_ TERMINAL_DEFAULT((const wchar_t*)0)) +{ + return (const wchar_t*)TERMINAL_CAT(terminal_get, TERMINAL_WCHAR_SUFFIX)((const TERMINAL_WCHAR_TYPE*)key, (const TERMINAL_WCHAR_TYPE*)default_); +} + +TERMINAL_INLINE color_t color_from_name(const char* name) +{ + return color_from_name8((const int8_t*)name); +} + +TERMINAL_INLINE color_t color_from_wname(const wchar_t* name) +{ + return TERMINAL_CAT(color_from_name, TERMINAL_WCHAR_SUFFIX)((const TERMINAL_WCHAR_TYPE*)name); +} + +#ifdef __cplusplus +/* + * C++ supports function overloading, should take advantage of it. + */ + +TERMINAL_INLINE int terminal_set(const wchar_t* s) +{ + return terminal_wset(s); +} + +TERMINAL_INLINE int terminal_setf(const wchar_t* s, ...) +{ + TERMINAL_FORMATTED_WRAP(int, terminal_wset(terminal_vswprintf(s, args))); +} + +TERMINAL_INLINE void terminal_color(const char* name) +{ + terminal_color(color_from_name(name)); +} + +TERMINAL_INLINE void terminal_color(const wchar_t* name) +{ + terminal_color(color_from_wname(name)); +} + +TERMINAL_INLINE void terminal_bkcolor(const char* name) +{ + terminal_bkcolor(color_from_name(name)); +} + +TERMINAL_INLINE void terminal_bkcolor(const wchar_t* name) +{ + terminal_bkcolor(color_from_wname(name)); +} + +TERMINAL_INLINE void terminal_put_ext(int x, int y, int dx, int dy, int code) +{ + terminal_put_ext(x, y, dx, dy, code, 0); +} + +TERMINAL_INLINE dimensions_t terminal_print(int x, int y, const wchar_t* s) +{ + return terminal_wprint(x, y, s); +} + +TERMINAL_INLINE dimensions_t terminal_printf(int x, int y, const wchar_t* s, ...) +{ + TERMINAL_FORMATTED_WRAP(dimensions_t, terminal_wprint(x, y, terminal_vswprintf(s, args))) +} + +TERMINAL_INLINE dimensions_t terminal_print_ext(int x, int y, int w, int h, int align, const wchar_t* s) +{ + return terminal_wprint_ext(x, y, w, h, align, s); +} + +TERMINAL_INLINE dimensions_t terminal_printf_ext(int x, int y, int w, int h, int align, const wchar_t* s, ...) +{ + TERMINAL_FORMATTED_WRAP(dimensions_t, terminal_wprint_ext(x, y, w, h, align, terminal_vswprintf(s, args))) +} + +TERMINAL_INLINE dimensions_t terminal_measure(const wchar_t* s) +{ + return terminal_wmeasure(s); +} + +TERMINAL_INLINE dimensions_t terminal_measuref(const wchar_t* s, ...) +{ + TERMINAL_FORMATTED_WRAP(dimensions_t, terminal_wmeasure(terminal_vswprintf(s, args))) +} + +TERMINAL_INLINE dimensions_t terminal_measure_ext(int w, int h, const wchar_t* s) +{ + return terminal_wmeasure_ext(w, h, s); +} + +TERMINAL_INLINE dimensions_t terminal_measuref_ext(int w, int h, const wchar_t* s, ...) +{ + TERMINAL_FORMATTED_WRAP(dimensions_t, terminal_wmeasure_ext(w, h, terminal_vswprintf(s, args))) +} + +TERMINAL_INLINE int terminal_read_str(int x, int y, wchar_t* buffer, int max) +{ + return terminal_read_wstr(x, y, buffer, max); +} + +TERMINAL_INLINE color_t color_from_name(const wchar_t* name) +{ + return color_from_wname(name); +} + +TERMINAL_INLINE int terminal_pick(int x, int y) +{ + return terminal_pick(x, y, 0); +} + +TERMINAL_INLINE color_t terminal_pick_color(int x, int y) +{ + return terminal_pick_color(x, y, 0); +} + +TERMINAL_INLINE const wchar_t* terminal_get(const wchar_t* key, const wchar_t* default_ = (const wchar_t*)0) +{ + return terminal_wget(key, default_); +} + +template T terminal_get(const C* key, const T& default_ = T()) +{ + const C* result_str = terminal_get(key, (const C*)0); + if (result_str[0] == C(0)) + return default_; + T result; + return (bool)(std::basic_istringstream(result_str) >> result)? result: default_; +} + +#endif /* __cplusplus */ + +/* + * Color routines + */ +TERMINAL_INLINE color_t color_from_argb(uint8_t a, uint8_t r, uint8_t g, uint8_t b) +{ + return ((color_t)a << 24) | (r << 16) | (g << 8) | b; +} + +/* + * Other functional sugar + */ +TERMINAL_INLINE int terminal_check(int code) +{ + return terminal_state(code) > 0; +} + +/* + * WinMain entry point handling macro. This allows easier entry point definition. + * The macro will expand to proper WinMain stub regardless of header include order. + */ +#if defined(_WIN32) + +/* + * WinMain probe macro. It will expand to either X or X_WINDOWS_ depending on + * Windows.h header inclusion. + */ +#define TERMINAL_TAKE_CARE_OF_WINMAIN TERMINAL_WINMAIN_PROBE_IMPL(_WINDOWS_) +#define TERMINAL_WINMAIN_PROBE_IMPL(DEF) TERMINAL_PRIMITIVE_CAT(TERMINAL_WINMAIN_IMPL, DEF) + +/* + * Trivial no-arguments WinMain implementation. It just calls main. + */ +#define TERMINAL_WINMAIN_IMPL_BASE(INSTANCE_T, STRING_T)\ + extern "C" int main();\ + extern "C" int __stdcall WinMain(INSTANCE_T hInstance, INSTANCE_T hPrevInstance, STRING_T lpCmdLine, int nCmdShow)\ + {\ + return main();\ + } + +/* + * Macro expands to empty string. Windows.h is included thus code MUST use + * predefined types or else MSVC will complain. + */ +#define TERMINAL_WINMAIN_IMPL TERMINAL_WINMAIN_IMPL_BASE(HINSTANCE, LPSTR) + +/* + * Macro expands to macro name. Windows.h wasn't included, so WinMain will be + * defined with fundamental types (enough for linker to find it). + */ +#define TERMINAL_WINMAIN_IMPL_WINDOWS_ TERMINAL_WINMAIN_IMPL_BASE(void*, char*) + +#else + +/* + * Only Windows has WinMain but macro still must be defined for cross-platform + * applications. + */ +#define TERMINAL_TAKE_CARE_OF_WINMAIN + +#endif + +#endif // BEARLIBTERMINAL_H diff -r 000000000000 -r f61929db839b vendor/make-quickutils.lisp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/make-quickutils.lisp Sat Feb 11 00:52:24 2017 +0000 @@ -0,0 +1,18 @@ +(ql:quickload 'quickutil) + +(qtlc:save-utils-as + "quickutils.lisp" + :utilities '( + + :compose + :curry + :ensure-boolean + :ensure-list + :mkstr + :once-only + :rcurry + :symb + :with-gensyms + + ) + :package "BEARLIBTERMINAL.QUICKUTILS") diff -r 000000000000 -r f61929db839b vendor/quickutils-package.lisp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/quickutils-package.lisp Sat Feb 11 00:52:24 2017 +0000 @@ -0,0 +1,12 @@ +(eval-when (:compile-toplevel :load-toplevel :execute) + (unless (find-package "BEARLIBTERMINAL.QUICKUTILS") + (defpackage "BEARLIBTERMINAL.QUICKUTILS" + (:documentation "Package that contains Quickutil utility functions.") + (:use :cl)))) + +(in-package "BEARLIBTERMINAL.QUICKUTILS") + +;; need to define this here so sbcl will shut the hell up about it being +;; undefined when compiling quickutils.lisp. computers are trash. +(defparameter *utilities* nil) + diff -r 000000000000 -r f61929db839b vendor/quickutils.lisp --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/vendor/quickutils.lisp Sat Feb 11 00:52:24 2017 +0000 @@ -0,0 +1,218 @@ +;;;; This file was automatically generated by Quickutil. +;;;; See http://quickutil.org for details. + +;;;; To regenerate: +;;;; (qtlc:save-utils-as "quickutils.lisp" :utilities '(:COMPOSE :CURRY :ENSURE-BOOLEAN :ENSURE-LIST :MKSTR :ONCE-ONLY :RCURRY :SYMB :WITH-GENSYMS) :ensure-package T :package "BEARLIBTERMINAL.QUICKUTILS") + +(eval-when (:compile-toplevel :load-toplevel :execute) + (unless (find-package "BEARLIBTERMINAL.QUICKUTILS") + (defpackage "BEARLIBTERMINAL.QUICKUTILS" + (:documentation "Package that contains Quickutil utility functions.") + (:use #:cl)))) + +(in-package "BEARLIBTERMINAL.QUICKUTILS") + +(when (boundp '*utilities*) + (setf *utilities* (union *utilities* '(:MAKE-GENSYM-LIST :ENSURE-FUNCTION + :COMPOSE :CURRY :ENSURE-BOOLEAN + :ENSURE-LIST :MKSTR :ONCE-ONLY :RCURRY + :SYMB :STRING-DESIGNATOR :WITH-GENSYMS)))) +(eval-when (:compile-toplevel :load-toplevel :execute) + (defun make-gensym-list (length &optional (x "G")) + "Returns a list of `length` gensyms, each generated as if with a call to `make-gensym`, +using the second (optional, defaulting to `\"G\"`) argument." + (let ((g (if (typep x '(integer 0)) x (string x)))) + (loop repeat length + collect (gensym g)))) + ) ; eval-when +(eval-when (:compile-toplevel :load-toplevel :execute) + ;;; To propagate return type and allow the compiler to eliminate the IF when + ;;; it is known if the argument is function or not. + (declaim (inline ensure-function)) + + (declaim (ftype (function (t) (values function &optional)) + ensure-function)) + (defun ensure-function (function-designator) + "Returns the function designated by `function-designator`: +if `function-designator` is a function, it is returned, otherwise +it must be a function name and its `fdefinition` is returned." + (if (functionp function-designator) + function-designator + (fdefinition function-designator))) + ) ; eval-when + + (defun compose (function &rest more-functions) + "Returns a function composed of `function` and `more-functions` that applies its ; +arguments to to each in turn, starting from the rightmost of `more-functions`, +and then calling the next one with the primary value of the last." + (declare (optimize (speed 3) (safety 1) (debug 1))) + (reduce (lambda (f g) + (let ((f (ensure-function f)) + (g (ensure-function g))) + (lambda (&rest arguments) + (declare (dynamic-extent arguments)) + (funcall f (apply g arguments))))) + more-functions + :initial-value function)) + + (define-compiler-macro compose (function &rest more-functions) + (labels ((compose-1 (funs) + (if (cdr funs) + `(funcall ,(car funs) ,(compose-1 (cdr funs))) + `(apply ,(car funs) arguments)))) + (let* ((args (cons function more-functions)) + (funs (make-gensym-list (length args) "COMPOSE"))) + `(let ,(loop for f in funs for arg in args + collect `(,f (ensure-function ,arg))) + (declare (optimize (speed 3) (safety 1) (debug 1))) + (lambda (&rest arguments) + (declare (dynamic-extent arguments)) + ,(compose-1 funs)))))) + + + (defun curry (function &rest arguments) + "Returns a function that applies `arguments` and the arguments +it is called with to `function`." + (declare (optimize (speed 3) (safety 1) (debug 1))) + (let ((fn (ensure-function function))) + (lambda (&rest more) + (declare (dynamic-extent more)) + ;; Using M-V-C we don't need to append the arguments. + (multiple-value-call fn (values-list arguments) (values-list more))))) + + (define-compiler-macro curry (function &rest arguments) + (let ((curries (make-gensym-list (length arguments) "CURRY")) + (fun (gensym "FUN"))) + `(let ((,fun (ensure-function ,function)) + ,@(mapcar #'list curries arguments)) + (declare (optimize (speed 3) (safety 1) (debug 1))) + (lambda (&rest more) + (apply ,fun ,@curries more))))) + + + (defun ensure-boolean (x) + "Convert `x` into a Boolean value." + (and x t)) + + + (defun ensure-list (list) + "If `list` is a list, it is returned. Otherwise returns the list designated by `list`." + (if (listp list) + list + (list list))) + + + (defun mkstr (&rest args) + "Receives any number of objects (string, symbol, keyword, char, number), extracts all printed representations, and concatenates them all into one string. + +Extracted from _On Lisp_, chapter 4." + (with-output-to-string (s) + (dolist (a args) (princ a s)))) + + + (defmacro once-only (specs &body forms) + "Evaluates `forms` with symbols specified in `specs` rebound to temporary +variables, ensuring that each initform is evaluated only once. + +Each of `specs` must either be a symbol naming the variable to be rebound, or of +the form: + + (symbol initform) + +Bare symbols in `specs` are equivalent to + + (symbol symbol) + +Example: + + (defmacro cons1 (x) (once-only (x) `(cons ,x ,x))) + (let ((y 0)) (cons1 (incf y))) => (1 . 1)" + (let ((gensyms (make-gensym-list (length specs) "ONCE-ONLY")) + (names-and-forms (mapcar (lambda (spec) + (etypecase spec + (list + (destructuring-bind (name form) spec + (cons name form))) + (symbol + (cons spec spec)))) + specs))) + ;; bind in user-macro + `(let ,(mapcar (lambda (g n) (list g `(gensym ,(string (car n))))) + gensyms names-and-forms) + ;; bind in final expansion + `(let (,,@(mapcar (lambda (g n) + ``(,,g ,,(cdr n))) + gensyms names-and-forms)) + ;; bind in user-macro + ,(let ,(mapcar (lambda (n g) (list (car n) g)) + names-and-forms gensyms) + ,@forms))))) + + + (defun rcurry (function &rest arguments) + "Returns a function that applies the arguments it is called +with and `arguments` to `function`." + (declare (optimize (speed 3) (safety 1) (debug 1))) + (let ((fn (ensure-function function))) + (lambda (&rest more) + (declare (dynamic-extent more)) + (multiple-value-call fn (values-list more) (values-list arguments))))) + + + (defun symb (&rest args) + "Receives any number of objects, concatenates all into one string with `#'mkstr` and converts them to symbol. + +Extracted from _On Lisp_, chapter 4. + +See also: `symbolicate`" + (values (intern (apply #'mkstr args)))) + + + (deftype string-designator () + "A string designator type. A string designator is either a string, a symbol, +or a character." + `(or symbol string character)) + + + (defmacro with-gensyms (names &body forms) + "Binds each variable named by a symbol in `names` to a unique symbol around +`forms`. Each of `names` must either be either a symbol, or of the form: + + (symbol string-designator) + +Bare symbols appearing in `names` are equivalent to: + + (symbol symbol) + +The string-designator is used as the argument to `gensym` when constructing the +unique symbol the named variable will be bound to." + `(let ,(mapcar (lambda (name) + (multiple-value-bind (symbol string) + (etypecase name + (symbol + (values name (symbol-name name))) + ((cons symbol (cons string-designator null)) + (values (first name) (string (second name))))) + `(,symbol (gensym ,string)))) + names) + ,@forms)) + + (defmacro with-unique-names (names &body forms) + "Binds each variable named by a symbol in `names` to a unique symbol around +`forms`. Each of `names` must either be either a symbol, or of the form: + + (symbol string-designator) + +Bare symbols appearing in `names` are equivalent to: + + (symbol symbol) + +The string-designator is used as the argument to `gensym` when constructing the +unique symbol the named variable will be bound to." + `(with-gensyms ,names ,@forms)) + +(eval-when (:compile-toplevel :load-toplevel :execute) + (export '(compose curry ensure-boolean ensure-list mkstr once-only rcurry + symb with-gensyms with-unique-names))) + +;;;; END OF quickutils.lisp ;;;;