f61929db839b

Initial commit
[view raw] [browse files]
author Steve Losh <steve@stevelosh.com>
date Sat, 11 Feb 2017 00:52:24 +0000
parents
children eb92688beebc
branches/tags (none)
files .ffignore .hgignore .hgtags .lispwords Makefile README.markdown cl-blt.asd docs/01-installation.markdown docs/02-usage.markdown docs/03-reference.markdown docs/04-changelog.markdown docs/api.lisp docs/footer.markdown docs/index.markdown docs/title package.lisp src/high-level/bearlibterminal.lisp src/low-level/bearlibterminal.lisp src/low-level/bearlibterminal.swig src/low-level/include/BearLibTerminal.h vendor/make-quickutils.lisp vendor/quickutils-package.lisp vendor/quickutils.lisp

Changes

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:** <http://sjl.bitbucket.org/cl-blt/>
+* **Mercurial:** <http://bitbucket.org/sjl/cl-blt/>
+* **Git:** <http://github.com/sjl/cl-blt/>
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 <steve@stevelosh.com>"
+
+  :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 @@
+<i>Made with Lisp and love by [Steve Losh][] in Reykjavík, Iceland.</i>
+
+[Steve Losh]: http://stevelosh.com/
+
+<script>
+  (function(i,s,o,g,r,a,m){i['GoogleAnalyticsObject']=r;i[r]=i[r]||function(){
+  (i[r].q=i[r].q||[]).push(arguments)},i[r].l=1*new Date();a=s.createElement(o),
+  m=s.getElementsByTagName(o)[0];a.async=1;a.src=g;m.parentNode.insertBefore(a,m)
+  })(window,document,'script','//www.google-analytics.com/analytics.js','ga');
+
+  ga('create', 'UA-15328874-3', 'auto');
+  ga('send', 'pageview');
+
+</script>
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:** <http://sjl.bitbucket.org/cl-blt/>
+* **Mercurial:** <http://bitbucket.org/sjl/cl-blt/>
+* **Git:** <http://github.com/sjl/cl-blt/>
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 <stdio.h>
+#include <stddef.h>
+#include <stdint.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <wchar.h>
+#if defined(__cplusplus)
+#include <sstream>
+#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<typename T, typename C> 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<C>(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 ;;;;