├── cocoa ├── keycodes.lisp ├── package.lisp ├── bindings.lisp └── wrapper.lisp ├── template ├── bindings.lisp ├── package.lisp └── wrapper.lisp ├── examples ├── log-events.lisp ├── package.lisp ├── gradient.lisp └── framebuffers-examples.asd ├── staple.ext.lisp ├── mezzano ├── package.lisp ├── keycodes.lisp └── wrapper.lisp ├── test └── test.lisp ├── README.md ├── LICENSE ├── linux.lisp ├── README.mess ├── package.lisp ├── framebuffers.asd ├── wayland ├── package.lisp └── keycodes.lisp ├── protocol.lisp ├── win32 ├── package.lisp └── keycodes.lisp ├── xlib ├── package.lisp ├── keycodes.lisp ├── keysyms.txt └── bindings.lisp ├── internal.lisp └── documentation.lisp /cocoa/keycodes.lisp: -------------------------------------------------------------------------------- 1 | (in-package #:org.shirakumo.framebuffers.cocoa) 2 | -------------------------------------------------------------------------------- /template/bindings.lisp: -------------------------------------------------------------------------------- 1 | (in-package #:org.shirakumo.framebuffers.BACKEND.cffi) 2 | -------------------------------------------------------------------------------- /examples/log-events.lisp: -------------------------------------------------------------------------------- 1 | (in-package #:org.shirakumo.framebuffers.examples) 2 | 3 | (defun log-events () 4 | (fb:with-window (window :size '(800 . 600)) 5 | (T (type &rest args) 6 | (print (list* type args))))) 7 | -------------------------------------------------------------------------------- /staple.ext.lisp: -------------------------------------------------------------------------------- 1 | (defmethod staple:packages ((_ (eql (asdf:find-system "framebuffers")))) 2 | '(:org.shirakumo.framebuffers)) 3 | 4 | (defmethod staple:subsystems ((_ (eql (asdf:find-system "framebuffers")))) 5 | '()) 6 | -------------------------------------------------------------------------------- /mezzano/package.lisp: -------------------------------------------------------------------------------- 1 | (defpackage #:org.shirakumo.framebuffers.mezzano 2 | (:use #:cl) 3 | (:local-nicknames 4 | (#:fb #:org.shirakumo.framebuffers) 5 | (#:fb-int #:org.shirakumo.framebuffers.int)) 6 | (:export 7 | #:window)) 8 | -------------------------------------------------------------------------------- /test/test.lisp: -------------------------------------------------------------------------------- 1 | (defpackage #:org.shirakumo.framebuffers.test 2 | (:use #:cl #:parachute) 3 | (:export #:framebuffers)) 4 | 5 | (in-package #:org.shirakumo.framebuffers.test) 6 | 7 | (define-test framebuffers 8 | (error "IMPLEMENT THE TESTS, DUMMY!!!")) 9 | -------------------------------------------------------------------------------- /examples/package.lisp: -------------------------------------------------------------------------------- 1 | (defpackage #:org.shirakumo.framebuffers.examples 2 | (:nicknames #:framebuffers-examples) 3 | (:use #:cl) 4 | (:local-nicknames 5 | (#:fb #:org.shirakumo.framebuffers) 6 | (#:fb-int #:org.shirakumo.framebuffers.int)) 7 | (:export 8 | #:gradient 9 | #:log-events)) 10 | -------------------------------------------------------------------------------- /template/package.lisp: -------------------------------------------------------------------------------- 1 | (defpackage #:org.shirakumo.framebuffers.BACKEND.cffi 2 | (:use #:cl) 3 | (:export)) 4 | 5 | (defpackage #:org.shirakumo.framebuffers.BACKEND 6 | (:use #:cl) 7 | (:local-nicknames 8 | (#:fb #:org.shirakumo.framebuffers) 9 | (#:fb-int #:org.shirakumo.framebuffers.int) 10 | (#:BACK #:org.shirakumo.framebuffers.BACKEND.cffi)) 11 | (:export 12 | #:window)) 13 | -------------------------------------------------------------------------------- /examples/gradient.lisp: -------------------------------------------------------------------------------- 1 | (in-package #:org.shirakumo.framebuffers.examples) 2 | 3 | (defun gradient () 4 | (fb:with-window (window :size '(800 . 600)) 5 | (fb:window-refreshed () 6 | (fb:do-pixels (buf i x y) window 7 | (setf (aref buf (+ 0 i)) (mod x 256)) 8 | (setf (aref buf (+ 1 i)) (mod y 256)) 9 | (setf (aref buf (+ 2 i)) 0) 10 | (setf (aref buf (+ 3 i)) 255)) 11 | (fb:swap-buffers window)))) 12 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # This repository has [moved](https://shirakumo.org/projects/framebuffers)! 2 | Due to Microsoft's continued enshittification of the platform this repository has been moved to [Codeberg](https://shirakumo.org/projects/framebuffers) in August of 2025. It will not receive further updates or patches. **Issues and pull requests will not be looked at here either**, please submit your patches and issue tickets on Codeberg, or send them directly via good old email patches to [shirakumo@tymoon.eu](mailto:shirakumo@tymoon.eu). 3 | 4 | Thanks. -------------------------------------------------------------------------------- /examples/framebuffers-examples.asd: -------------------------------------------------------------------------------- 1 | (asdf:defsystem framebuffers-examples 2 | :version "0.0.0" 3 | :license "zlib" 4 | :author "Yukari Hafner " 5 | :maintainer "Yukari Hafner " 6 | :description "Examples for the framebuffers system" 7 | :homepage "https://shirakumo.org/docs/framebuffers/" 8 | :bug-tracker "https://shirakumo.org/project/framebuffers/issues" 9 | :source-control (:git "https://shirakumo.org/project/framebuffers.git") 10 | :depends-on (:framebuffers) 11 | :serial T 12 | :components ((:file "package") 13 | (:file "gradient") 14 | (:file "log-events"))) 15 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | Copyright (c) 2024 Yukari Hafner 2 | 3 | This software is provided 'as-is', without any express or implied 4 | warranty. In no event will the authors be held liable for any damages 5 | arising from the use of this software. 6 | 7 | Permission is granted to anyone to use this software for any purpose, 8 | including commercial applications, and to alter it and redistribute it 9 | freely, subject to the following restrictions: 10 | 11 | 1. The origin of this software must not be misrepresented; you must not 12 | claim that you wrote the original software. If you use this software 13 | in a product, an acknowledgment in the product documentation would be 14 | appreciated but is not required. 15 | 2. Altered source versions must be plainly marked as such, and must not be 16 | misrepresented as being the original software. 17 | 3. This notice may not be removed or altered from any source distribution. 18 | -------------------------------------------------------------------------------- /linux.lisp: -------------------------------------------------------------------------------- 1 | (in-package #:org.shirakumo.framebuffers.int) 2 | 3 | (cffi:defcstruct (itimer :conc-name itimer-) 4 | (interval-sec :size) 5 | (interval-nsec :size) 6 | (value-sec :size) 7 | (value-nsec :size)) 8 | 9 | (cffi:defcenum clockid 10 | (:realtime 0) 11 | (:monotonic 1) 12 | (:boottime 7) 13 | (:realtime-alarm 8) 14 | (:boottime-alarm 9)) 15 | 16 | (cffi:defbitfield timerfd-flag 17 | (:cloexec #o2000000) 18 | (:nonblock #o0004000)) 19 | 20 | (cffi:defcfun (timerfd-create "timerfd_create") :int 21 | (clockid clockid) 22 | (flags timerfd-flag)) 23 | 24 | (cffi:defcfun (timerfd-set-time "timerfd_settime") :int 25 | (fd :int) 26 | (flags timerfd-flag) 27 | (new :pointer) 28 | (old :pointer)) 29 | 30 | (cffi:defcfun (timerfd-get-time "timerfd_gettime") :int 31 | (fd :int) 32 | (value :pointer)) 33 | 34 | (cffi:defcstruct (pollfd :conc-name pollfd-) 35 | (fd :int) 36 | (events :short) 37 | (revents :short)) 38 | 39 | (cffi:defcfun (%poll "poll") :int 40 | (fds :pointer) 41 | (count :int) 42 | (timeout :int)) 43 | 44 | (defun poll (fds timeout) 45 | (let ((count (length fds))) 46 | (cffi:with-foreign-objects ((pollfds '(:struct pollfd) count)) 47 | (loop for i from 0 48 | for fd in fds 49 | for pollfd = (cffi:mem-aptr pollfds '(:struct pollfd) i) 50 | do (setf (pollfd-fd pollfd) fd) 51 | (setf (pollfd-events pollfd) 1) 52 | (setf (pollfd-revents pollfd) 0)) 53 | (when (< 0 (%poll pollfds count timeout)) 54 | (loop for i from 0 below count 55 | for pollfd = (cffi:mem-aptr pollfds '(:struct pollfd) i) 56 | when (< 0 (pollfd-revents pollfd)) 57 | collect (pollfd-fd pollfd)))))) 58 | 59 | (defclass linux-window (window) 60 | ((timers :initform () :accessor timers))) 61 | 62 | (defmethod fb:set-timer ((window linux-window) delay &key repeat) 63 | (let ((fd (timerfd-create :realtime ()))) 64 | (cffi:with-foreign-objects ((itimer '(:struct itimer))) 65 | (multiple-value-bind (secs nsecs) (truncate delay) 66 | (setf nsecs (truncate (* nsecs 1000000000))) 67 | (setf (itimer-interval-sec itimer) (if repeat secs 0)) 68 | (setf (itimer-interval-nsec itimer) (if repeat nsecs 0)) 69 | (setf (itimer-value-sec itimer) secs) 70 | (setf (itimer-value-nsec itimer) nsecs)) 71 | (timerfd-set-time fd () itimer (cffi:null-pointer))) 72 | (push fd (timers window)) 73 | fd)) 74 | 75 | (defmethod fb:cancel-timer ((window linux-window) timer) 76 | (cffi:foreign-funcall "close" :int timer) 77 | (setf (timers window) (remove timer (timers window))) 78 | NIL) 79 | -------------------------------------------------------------------------------- /cocoa/package.lisp: -------------------------------------------------------------------------------- 1 | (defpackage #:org.shirakumo.framebuffers.cocoa.cffi 2 | (:use #:cl) 3 | (:local-nicknames 4 | (#:fb #:org.shirakumo.framebuffers) 5 | (#:fb-int #:org.shirakumo.framebuffers.int) 6 | (#:objc #:org.shirakumo.cocoas)) 7 | (:shadow #:close) 8 | (:export 9 | #:paste-url 10 | #:paste-collaboration-metadata 11 | #:paste-color 12 | #:paste-file-url 13 | #:paste-font 14 | #:paste-html 15 | #:paste-multiple-text-selection 16 | #:paste-pdf 17 | #:paste-png 18 | #:paste-rtf 19 | #:paste-rtfd 20 | #:paste-ruler 21 | #:paste-sound 22 | #:paste-string 23 | #:paste-tabular-text 24 | #:paste-text-finder-options 25 | #:paste-tiff 26 | #:point 27 | #:point-x 28 | #:point-y 29 | #:size 30 | #:size-w 31 | #:size-h 32 | #:rect 33 | #:rect-x 34 | #:rect-y 35 | #:rect-w 36 | #:rect-h 37 | #:nsapplication-shared-application 38 | #:nsapp-set-activation-policy 39 | #:nsapp-activate-ignoring-other-apps 40 | #:nsapp-request-user-attention 41 | #:nsscreen-main-screen 42 | #:nspasteboard-general-pasteboard 43 | #:nscolor-clear-color 44 | #:frame 45 | #:make-rect 46 | #:make-size 47 | #:init 48 | #:init-with-content-rect 49 | #:alloc 50 | #:close 51 | #:is-zoomed 52 | #:convert-rect-to-backing 53 | #:content-rect-for-frame-rect 54 | #:set-release-when-closed 55 | #:set-opaque 56 | #:set-background-color 57 | #:set-accepts-mouse-moved-events 58 | #:set-title 59 | #:set-content-view 60 | #:make-first-responder-view 61 | #:cg-display-bounds 62 | #:cg-main-display-id 63 | #:set-frame 64 | #:frame-rect-for-content-rect 65 | #:set-frame-origin 66 | #:set-miniwindow-title 67 | #:order-front 68 | #:order-out 69 | #:zoom 70 | #:miniaturize 71 | #:deminiaturize 72 | #:set-content-min-size 73 | #:set-content-max-size 74 | #:make-key-and-order-front 75 | #:style-mask 76 | #:set-style-mask 77 | #:make-first-responder 78 | #:set-collection-behavior 79 | #:set-level 80 | #:types 81 | #:string-for-type 82 | #:declare-types 83 | #:set-string 84 | #:floating-window-level 85 | #:normal-window-level 86 | #:main-menu-window-level 87 | #:cgcontext 88 | #:nsgraphicscontext-current-context 89 | #:cg-display-bounds 90 | #:cg-main-display-id 91 | #:window-level-for-key 92 | #:cg-color-space-create-device-rgb 93 | #:cg-data-provider-create-with-data 94 | #:cg-image-create 95 | #:cg-color-space-release 96 | #:cg-data-provider-release 97 | #:cg-context-draw-image 98 | #:cg-image-release 99 | #:modifier-flags 100 | #:key-code 101 | #:button-number 102 | #:scrolling-delta-x 103 | #:scrolling-delta-y 104 | #:has-precise-scrolling-deltas 105 | #:location-in-window 106 | #:set-needs-display-in-rect)) 107 | 108 | (defpackage #:org.shirakumo.framebuffers.cocoa 109 | (:use #:cl) 110 | (:local-nicknames 111 | (#:fb #:org.shirakumo.framebuffers) 112 | (#:fb-int #:org.shirakumo.framebuffers.int) 113 | (#:objc #:org.shirakumo.cocoas) 114 | (#:cocoa #:org.shirakumo.framebuffers.cocoa.cffi)) 115 | (:export 116 | #:window)) 117 | -------------------------------------------------------------------------------- /README.mess: -------------------------------------------------------------------------------- 1 | # About Framebuffers 2 | This library implements direct access to underlying operating system framebuffer mechanisms, including input handling. With it you can create native windows on Windows (win32), Linux (x11/wayland), Mac (Cocoa), and Mezzano, all without relying on external C libraries. 3 | 4 | ## How To 5 | A trivial example is as follows, assuming ``org.shirakumo.framebuffers`` is locally nicknamed to ``fb``: 6 | 7 | :: common lisp 8 | (fb:with-window (w :size '(800 . 600))) 9 | :: 10 | 11 | This will open a window and start its event loop. When the user requests a close, it'll automatically close it and clean it back up again. 12 | 13 | To watch what events are going on, we can add a catchall handler: 14 | 15 | :: common lisp 16 | (fb:with-window (w :size '(800 . 600)) 17 | (T (type &rest args) 18 | (print (list* type args)))) 19 | :: 20 | 21 | However, this being a framebuffer library, you're likely most interested in how to actually push pixels to the screen. Let's fill the window with a repeating gradient: 22 | 23 | :: common lisp 24 | (fb:with-window (w :size '(800 . 600)) 25 | (fb:window-refreshed () 26 | (fb:do-pixels (buf i x y) w 27 | (setf (aref buf (+ 0 i)) (mod x 256)) 28 | (setf (aref buf (+ 1 i)) (mod y 256)) 29 | (setf (aref buf (+ 2 i)) 0) 30 | (setf (aref buf (+ 3 i)) 255)) 31 | (fb:swap-buffers w))) 32 | :: 33 | 34 | ``do-pixels`` simply iterates over the pixels in the backing ``buffer``, using an BGRA layout. You can use whatever method you like to fill the buffer with pixel data, and call ``swap-buffers`` to display it. 35 | 36 | The API also exposes various functions to manage the window properties and let you handle events that occur. Please refer to the documentation of ``window`` and ``event-handler`` for a listing of each. 37 | 38 | ## Controlling the Event Loop 39 | The previously used ``with-window`` macro uses a dynamically established event handler to let you conveniently create an event loop. However, for larger projects you'll usually want a more decentralised code structure, in which case you'll instead want to manually manage the loop and how events are handled. To do so, you'll first want to define your own ``event-handler`` class, and methods for the events you care about: 40 | 41 | :: common lisp 42 | (defclass event-handler (fb:event-handler) ()) 43 | 44 | (defmethod fb:key-changed ((handler event-handler) key scan-code modifiers) 45 | (print key)) 46 | :: 47 | 48 | Then when you create your window using ``open``, pass an instance of your event handler as an initarg. 49 | 50 | :: common lisp 51 | (fb:open :event-handler (make-instance 'event-handler)) 52 | :: 53 | 54 | Alternatively you can set it later using the ``event-handler`` accessor. The ``window`` object returned by ``open`` is specific to the type of backend used, which is why you must use an ``event-handler`` subclass to specialise methods on, instead. 55 | 56 | In order to retrieve the associated ``window`` for the handler within a callback method, simply use the ``window`` accessor function. 57 | 58 | Once you have your window instance, you must periodically call ``process-events`` on it in order to handle whatever has been queued for it. ``process-events`` also has a couple of options to more efficiently wait for events in a loop. 59 | 60 | ## Supported Backends 61 | Currently this library supports the following backends: 62 | 63 | ; - Cocoa 64 | - Mezzano 65 | ; - Wayland 66 | - Win32 67 | - X11 68 | -------------------------------------------------------------------------------- /template/wrapper.lisp: -------------------------------------------------------------------------------- 1 | (in-package #:org.shirakumo.framebuffers.BACKEND) 2 | 3 | (pushnew :BACKEND fb-int:*available-backends*) 4 | 5 | (define-condition BACKEND-error (fb:framebuffer-error) 6 | () 7 | (:report (lambda (c s) (format s "")))) 8 | 9 | (defmethod fb-int:init-backend ((backend (eql :BACKEND))) 10 | ;; TODO: implement init-backend 11 | ) 12 | 13 | (defmethod fb-int:shutdown-backend ((backend (eql :BACKEND))) 14 | ;; TODO: implement shutdown-backend 15 | ) 16 | 17 | (defmethod fb-int:open-backend ((backend (eql :BACKEND)) &key) 18 | ;; TODO: implement list-displays-backend 19 | ) 20 | 21 | (defmethod fb-int:list-displays-backend ((backend (eql :BACKEND))) 22 | ;; TODO: implement list-displays-backend 23 | ) 24 | 25 | (defclass window (fb:window) 26 | ((buffer :initarg :buffer :initform NIL :reader fb:buffer :accessor buffer))) 27 | 28 | (defmethod fb:valid-p ((window window)) 29 | ;; TODO: implement valid-p 30 | ) 31 | 32 | (defmethod fb:close ((window window)) 33 | ;; TODO: implement close 34 | ) 35 | 36 | (defmethod (setf fb:size) (size (window window)) 37 | ;; TODO: implement size 38 | ) 39 | 40 | (defmethod (setf fb:location) (location (window window)) 41 | ;; TODO: implement location 42 | ) 43 | 44 | (defmethod (setf fb:title) (title (window window)) 45 | ;; TODO: implement title 46 | ) 47 | 48 | (defmethod (setf fb:visible-p) (state (window window)) 49 | ;; TODO: implement visible-p 50 | ) 51 | 52 | (defmethod (setf fb:maximized-p) (state (window window)) 53 | ;; TODO: implement maximized-p 54 | ) 55 | 56 | (defmethod (setf fb:iconified-p) (state (window window)) 57 | ;; TODO: implement iconified-p 58 | ) 59 | 60 | (defmethod (setf fb:minimum-size) (value (window window)) 61 | ;; TODO: implement minimum-size 62 | ) 63 | 64 | (defmethod (setf fb:maximum-size) (value (window window)) 65 | ;; TODO: implement maximum-size 66 | ) 67 | 68 | (defmethod (setf fb:focused-p) (value (window window)) 69 | ;; TODO: implement focused-p 70 | ) 71 | 72 | (defmethod (setf fb:borderless-p) (value (window window)) 73 | ;; TODO: implement borderless-p 74 | ) 75 | 76 | (defmethod (setf fb:always-on-top-p) (value (window window)) 77 | ;; TODO: implement always-on-top-p 78 | ) 79 | 80 | (defmethod (setf fb:resizable-p) (value (window window)) 81 | ;; TODO: implement resizable-p 82 | ) 83 | 84 | (defmethod (setf fb:floating-p) (value (window window)) 85 | ;; TODO: implement floating-p 86 | ) 87 | 88 | (defmethod (setf fb:fullscreen-p) ((value null) (window window)) 89 | ;; TODO: implement fullscreen-p 90 | ) 91 | 92 | (defmethod (setf fb:fullscreen-p) ((value fb:video-mode) (window window)) 93 | ;; TODO: implement fullscreen-p 94 | ) 95 | 96 | (defmethod fb:clipboard ((window window)) 97 | ;; TODO: implement clipboard fetching 98 | ) 99 | 100 | (defmethod (setf fb:clipboard) ((string string) (window window)) 101 | ;; TODO: implement clipboard setting 102 | ) 103 | 104 | (defmethod (setf fb:icon) ((value null) (window window)) 105 | ;; TODO: implement icon 106 | ) 107 | 108 | (defmethod (setf fb:icon) ((value fb:icon) (window window)) 109 | ;; TODO: implement icon 110 | ) 111 | 112 | (defmethod (setf fb:cursor-icon) ((value symbol) (window window)) 113 | ;; TODO: implement cursor-icon 114 | ) 115 | 116 | (defmethod (setf fb:cursor-icon) ((value fb:icon) (window window)) 117 | ;; TODO: implement cursor-icon 118 | ) 119 | 120 | (defmethod (setf fb:cursor-state) (value (window window)) 121 | ;; TODO: implement cursor-state 122 | ) 123 | 124 | (defmethod fb:swap-buffers ((window window) &key (x 0) (y 0) (w (fb:width window)) (h (fb:height window)) sync) 125 | ;; TODO: implement swap-buffers 126 | ) 127 | 128 | (defmethod fb:process-events ((window window) &key timeout) 129 | ;; TODO: implement process-events 130 | ) 131 | 132 | (defmethod fb:request-attention ((window window)) 133 | ;; TODO: implement request-attention 134 | ) 135 | 136 | (defmethod fb:set-timer ((window window) delay &key repeat) 137 | ;; TODO: implement set-timer 138 | ) 139 | 140 | (defmethod fb:cancel-timer ((window window) timer) 141 | ;; TODO: implement cancel-timer 142 | ) 143 | 144 | (defmethod fb:display ((window window)) 145 | ;; TODO: implement display 146 | ) 147 | 148 | (defclass display (fb:display) 149 | ()) 150 | 151 | (defstruct (video-mode (:include fb:video-mode))) 152 | 153 | (defmethod fb:video-modes ((display display)) 154 | ;; TODO: implement video-modes 155 | ) 156 | 157 | (defmethod fb:video-mode ((display display)) 158 | ;; TODO: implement video-mode 159 | ) 160 | -------------------------------------------------------------------------------- /package.lisp: -------------------------------------------------------------------------------- 1 | (defpackage #:org.shirakumo.framebuffers 2 | (:use #:cl) 3 | (:shadow #:open #:close) 4 | (:intern 5 | #:make-video-mode 6 | #:video-mode-display 7 | #:video-mode-width 8 | #:video-mode-height 9 | #:video-mode-refresh-rate 10 | #:icon-width 11 | #:icon-height 12 | #:icon-buffer 13 | #:make-touchpoint 14 | #:touchpoint-location 15 | #:touchpoint-radius 16 | #:touchpoint-angle 17 | #:touchpoint-pressure) 18 | (:export 19 | #:framebuffer-error 20 | #:window 21 | #:display 22 | #:event-handler 23 | #:dynamic-event-handler 24 | #:icon 25 | #:make-icon 26 | #:touchpoint 27 | #:radius 28 | #:angle 29 | #:pressure 30 | #:video-mode 31 | #:refresh-rate 32 | #:init 33 | #:shutdown 34 | #:open 35 | #:with-window 36 | #:do-pixels 37 | #:clear 38 | #:valid-p 39 | #:close-requested-p 40 | #:close 41 | #:width 42 | #:height 43 | #:minimum-size 44 | #:maximum-size 45 | #:size 46 | #:location 47 | #:title 48 | #:visible-p 49 | #:maximized-p 50 | #:iconified-p 51 | #:focused-p 52 | #:borderless-p 53 | #:always-on-top-p 54 | #:resizable-p 55 | #:floating-p 56 | #:mouse-entered-p 57 | #:clipboard 58 | #:content-scale 59 | #:buffer 60 | #:swap-buffers 61 | #:process-events 62 | #:request-attention 63 | #:mouse-location 64 | #:mouse-button-pressed-p 65 | #:key-pressed-p 66 | #:key-scan-code 67 | #:local-key-string 68 | #:icon 69 | #:cursor-icon 70 | #:cursor-state 71 | #:fullscreen-p 72 | #:set-timer 73 | #:cancel-timer 74 | #:display 75 | #:primary-p 76 | #:video-modes 77 | #:video-mode 78 | #:id 79 | #:list-displays 80 | #:window-moved 81 | #:window-resized 82 | #:window-refreshed 83 | #:window-focused 84 | #:window-iconified 85 | #:window-maximized 86 | #:window-closed 87 | #:mouse-button-changed 88 | #:mouse-moved 89 | #:mouse-entered 90 | #:mouse-scrolled 91 | #:key-changed 92 | #:string-entered 93 | #:file-dropped 94 | #:content-scale-changed 95 | #:touch-started 96 | #:touch-moved 97 | #:touch-ended 98 | #:touch-cancelled 99 | #:pen-moved 100 | #:timer-triggered 101 | #:display-connected)) 102 | 103 | (defpackage #:org.shirakumo.framebuffers.int 104 | (:use #:cl #:org.shirakumo.framebuffers) 105 | (:local-nicknames 106 | (#:fb #:org.shirakumo.framebuffers)) 107 | (:shadowing-import-from 108 | #:org.shirakumo.framebuffers 109 | #:open #:close 110 | #:make-video-mode 111 | #:video-mode-display 112 | #:video-mode-width 113 | #:video-mode-height 114 | #:video-mode-refresh-rate 115 | #:icon-width 116 | #:icon-height 117 | #:icon-buffer 118 | #:make-touchpoint 119 | #:touchpoint-location 120 | #:touchpoint-radius 121 | #:touchpoint-angle 122 | #:touchpoint-pressure) 123 | (:shadow 124 | #:close-requested-p 125 | #:minimum-size 126 | #:maximum-size 127 | #:size 128 | #:location 129 | #:title 130 | #:visible-p 131 | #:maximized-p 132 | #:iconified-p 133 | #:focused-p 134 | #:borderless-p 135 | #:always-on-top-p 136 | #:resizable-p 137 | #:floating-p 138 | #:mouse-entered-p 139 | #:fullscreen-p 140 | #:primary-p 141 | #:content-scale 142 | #:icon 143 | #:cursor-icon 144 | #:cursor-state 145 | #:radius 146 | #:angle 147 | #:pressure 148 | #:display 149 | #:id 150 | #:video-mode 151 | #:video-modes) 152 | (:export 153 | #:*available-backends* 154 | #:make-touchpoint 155 | #:make-video-mode 156 | #:static-file 157 | #:init-backend 158 | #:shutdown-backend 159 | #:open-backend 160 | #:list-displays-backend 161 | #:wait-for-events 162 | #:default-title 163 | #:ptr-int 164 | #:ptr-window 165 | #:list-windows 166 | #:resize-buffer 167 | #:close-requested-p 168 | #:minimum-size 169 | #:maximum-size 170 | #:size 171 | #:location 172 | #:title 173 | #:visible-p 174 | #:maximized-p 175 | #:iconified-p 176 | #:focused-p 177 | #:borderless-p 178 | #:always-on-top-p 179 | #:resizable-p 180 | #:floating-p 181 | #:mouse-entered-p 182 | #:fullscreen-p 183 | #:primary-p 184 | #:content-scale 185 | #:icon 186 | #:cursor-icon 187 | #:cursor-state 188 | #:radius 189 | #:angle 190 | #:pressure 191 | #:display 192 | #:id 193 | #:video-mode 194 | #:video-modes 195 | #:with-cleanup 196 | #:clean 197 | #:memset 198 | #:memcpy 199 | #:dbg)) 200 | 201 | (when (find-package '#:static-vectors) 202 | (push :static-vectors *features*) 203 | (ignore-errors 204 | (let ((buf (static-vectors:make-static-vector 4096 :alignment 4096))) 205 | (static-vectors:free-static-vector buf) 206 | (push :static-vectors-aligned *features*)))) 207 | -------------------------------------------------------------------------------- /mezzano/keycodes.lisp: -------------------------------------------------------------------------------- 1 | (in-package #:org.shirakumo.framebuffers.mezzano) 2 | 3 | (defvar *keytable* (make-hash-table :test 'eql)) 4 | (defvar *codetable* (make-hash-table :test 'eq)) 5 | 6 | (defun init-keytable () 7 | (loop for (char . key) in '((#\0 . :0) 8 | (#\1 . :1) 9 | (#\2 . :2) 10 | (#\3 . :3) 11 | (#\4 . :4) 12 | (#\5 . :5) 13 | (#\6 . :6) 14 | (#\7 . :7) 15 | (#\8 . :8) 16 | (#\9 . :9) 17 | (#\A . :a) 18 | (#\B . :b) 19 | (#\C . :c) 20 | (#\D . :d) 21 | (#\E . :e) 22 | (#\F . :f) 23 | (#\G . :g) 24 | (#\H . :h) 25 | (#\I . :i) 26 | (#\J . :j) 27 | (#\K . :k) 28 | (#\L . :l) 29 | (#\M . :m) 30 | (#\N . :n) 31 | (#\O . :o) 32 | (#\P . :p) 33 | (#\Q . :q) 34 | (#\R . :r) 35 | (#\S . :s) 36 | (#\T . :t) 37 | (#\U . :u) 38 | (#\V . :v) 39 | (#\W . :w) 40 | (#\X . :x) 41 | (#\Y . :y) 42 | (#\Z . :z) 43 | (#\- . :minus) 44 | (#\= . :equal) 45 | (#\[ . :left-bracket) 46 | (#\] . :right-bracket) 47 | (#\; . :semicolon) 48 | (#\' . :apostrophe) 49 | (#\, . :comma) 50 | (#\. . :period) 51 | (#\/ . :slash) 52 | (#\\ . :backslash) 53 | (#\Esc . :escape) 54 | (#\Backspace . :Backspace) 55 | (#\Tab . :Tab) 56 | (#\Newline . :enter) 57 | (#\Space . :Space) 58 | (#\F1 . :F1) 59 | (#\F2 . :F2) 60 | (#\F3 . :F3) 61 | (#\F4 . :F4) 62 | (#\F5 . :F5) 63 | (#\F6 . :F6) 64 | (#\F7 . :F7) 65 | (#\F8 . :F8) 66 | (#\F9 . :F9) 67 | (#\F10 . :F10) 68 | (#\F11 . :F11) 69 | (#\F12 . :F12) 70 | (#\KP-0 . :kp-0) 71 | (#\KP-1 . :kp-1) 72 | (#\KP-2 . :kp-2) 73 | (#\KP-3 . :kp-3) 74 | (#\KP-4 . :kp-4) 75 | (#\KP-5 . :kp-5) 76 | (#\KP-6 . :kp-6) 77 | (#\KP-7 . :kp-7) 78 | (#\KP-8 . :kp-8) 79 | (#\KP-9 . :kp-9) 80 | (#\KP-Minus . :kp-subtract) 81 | (#\KP-Plus . :kp-add) 82 | (#\KP-Period . :kp-decimal) 83 | (#\KP-Multiply . :kp-multiply) 84 | (#\KP-Divide . :kp-divide) 85 | (#\KP-Enter . :kp-enter) 86 | (#\Menu . :Menu) 87 | (#\Insert . :insert) 88 | (#\Home . :home) 89 | (#\Page-Up . :Page-Up) 90 | (#\Delete . :Delete) 91 | (#\End . :End) 92 | (#\Page-Down . :Page-Down) 93 | (#\Up-Arrow . :Up) 94 | (#\Left-Arrow . :Left) 95 | (#\Down-Arrow . :Down) 96 | (#\Right-Arrow . :Right) 97 | (#\Pause . :Pause) 98 | (#\Print-Screen . :Print-Screen) 99 | (#\Scroll-Lock . :Scroll-Lock)) 100 | do (setf (gethash (char-code char) *keytable*) key) 101 | (setf (gethash key *codetable*) (char-code char)))) 102 | 103 | (init-keytable) 104 | 105 | (defun translate-key (key) 106 | (gethash (char-code key) *keytable*)) 107 | 108 | -------------------------------------------------------------------------------- /framebuffers.asd: -------------------------------------------------------------------------------- 1 | (asdf:defsystem framebuffers 2 | :version "0.0.0" 3 | :license "zlib" 4 | :author "Yukari Hafner " 5 | :maintainer "Yukari Hafner " 6 | :description "A portable library for operating system framebuffers and windows, including IO handling" 7 | :homepage "https://shirakumo.org/docs/framebuffers/" 8 | :bug-tracker "https://shirakumo.org/project/framebuffers/issues" 9 | :source-control (:git "https://shirakumo.org/project/framebuffers.git") 10 | :defsystem-depends-on (:trivial-features) 11 | :depends-on (:framebuffers/protocol 12 | (:feature :unix :framebuffers/xlib) 13 | (:feature :windows :framebuffers/win32) 14 | (:feature :linux :framebuffers/wayland) 15 | (:feature :darwin :framebuffers/cocoa) 16 | (:feature :mezzano :framebuffers/mezzano))) 17 | 18 | (asdf:defsystem framebuffers/protocol 19 | :serial T 20 | :components ((:file "package") 21 | (:file "protocol") 22 | (:file "internal") 23 | (:file "linux" :if-feature :unix) 24 | (:file "documentation")) 25 | :depends-on (:documentation-utils 26 | :trivial-features 27 | :trivial-indent 28 | :nibbles 29 | (:feature (:not :mezzano) :static-vectors) 30 | (:feature (:not :mezzano) :cffi))) 31 | 32 | (asdf:defsystem framebuffers/win32 33 | :version "0.0.0" 34 | :license "zlib" 35 | :author "Yukari Hafner " 36 | :maintainer "Yukari Hafner " 37 | :description "Framebuffer backend for Microsoft Windows' Win32" 38 | :serial T 39 | :components ((:module "win32" 40 | :components ((:file "package") 41 | (:file "bindings") 42 | (:file "keycodes") 43 | (:file "wrapper")))) 44 | :depends-on (:framebuffers/protocol 45 | :com-on)) 46 | 47 | (asdf:defsystem framebuffers/wayland 48 | :version "0.0.0" 49 | :license "zlib" 50 | :author "Yukari Hafner " 51 | :maintainer "Yukari Hafner " 52 | :description "Framebuffer backend for Linux' Wayland system" 53 | :serial T 54 | :components ((:module "wayland" 55 | :components ((:file "package") 56 | (:file "bindings") 57 | (:file "keycodes") 58 | (:file "wrapper")))) 59 | :depends-on (:framebuffers/protocol 60 | :framebuffers/xlib 61 | :mmap)) 62 | 63 | (asdf:defsystem framebuffers/xlib 64 | :version "0.0.0" 65 | :license "zlib" 66 | :author "Yukari Hafner " 67 | :maintainer "Yukari Hafner " 68 | :description "Framebuffer backend for the X11 server using Xlib" 69 | :serial T 70 | :components ((:module "xlib" 71 | :components ((:file "package") 72 | (:file "bindings") 73 | (:file "keycodes") 74 | (:file "wrapper")))) 75 | :depends-on (:framebuffers/protocol 76 | :mmap)) 77 | 78 | (asdf:defsystem framebuffers/cocoa 79 | :version "0.0.0" 80 | :license "zlib" 81 | :author "Yukari Hafner " 82 | :maintainer "Yukari Hafner " 83 | :description "Framebuffer backend for Apple's Cocoa platform" 84 | :serial T 85 | :components ((:module "cocoa" 86 | :components ((:file "package") 87 | (:file "bindings") 88 | (:file "keycodes") 89 | (:file "wrapper")))) 90 | :depends-on (:framebuffers/protocol 91 | :cffi-libffi 92 | :cocoas)) 93 | 94 | (asdf:defsystem framebuffers/mezzano 95 | :version "0.0.0" 96 | :license "zlib" 97 | :author "Yukari Hafner " 98 | :maintainer "Yukari Hafner " 99 | :description "Framebuffer backend for Mezzano" 100 | :serial T 101 | :components ((:module "mezzano" 102 | :components ((:file "package") 103 | (:file "keycodes") 104 | (:file "wrapper")))) 105 | :depends-on (:framebuffers/protocol)) 106 | 107 | #++ 108 | (asdf:defsystem framebuffers/drm 109 | :version "0.0.0" 110 | :license "zlib" 111 | :author "Yukari Hafner " 112 | :maintainer "Yukari Hafner " 113 | :description "Framebuffer backend for Linux' Direct Rendering Manager via libdrm" 114 | :serial T 115 | :components ((:module "cocoa" 116 | :components ((:file "package") 117 | (:file "bindings") 118 | (:file "keycodes") 119 | (:file "wrapper")))) 120 | :depends-on (:framebuffers/protocol)) 121 | 122 | (asdf:defsystem framebuffers/test 123 | :components ((:module "test" 124 | :components ((:file "test")))) 125 | :depends-on (:framebuffers :parachute)) 126 | -------------------------------------------------------------------------------- /wayland/package.lisp: -------------------------------------------------------------------------------- 1 | (defpackage #:org.shirakumo.framebuffers.wayland.cffi 2 | (:use #:cl) 3 | (:shadow #:array) 4 | (:local-nicknames 5 | (#:fb-int #:org.shirakumo.framebuffers.int)) 6 | (:export 7 | #:wayland 8 | #:xkbcommon 9 | #:marshal-flag-destroy 10 | #:array-size 11 | #:array-alloc 12 | #:array-data 13 | #:message 14 | #:message-name 15 | #:message-signature 16 | #:message-types 17 | #:interface 18 | #:interface-name 19 | #:interface-version 20 | #:interface-method-count 21 | #:interface-methods 22 | #:interface-event-count 23 | #:interface-events 24 | #:argument 25 | #:event-queue-destroy 26 | #:proxy-marshal-flags 27 | #:proxy-marshal 28 | #:proxy-create 29 | #:proxy-create-wrapper 30 | #:proxy-wrapper-destroy 31 | #:proxy-marshal-constructor 32 | #:proxy-marshal-constructor-versioned 33 | #:proxy-destroy 34 | #:proxy-add-listener 35 | #:proxy-get-listener 36 | #:proxy-add-dispatcher 37 | #:proxy-set-user-data 38 | #:proxy-get-user-data 39 | #:proxy-get-version 40 | #:proxy-get-id 41 | #:proxy-set-tag 42 | #:proxy-get-tag 43 | #:proxy-get-class 44 | #:proxy-set-queue 45 | #:display-connect 46 | #:display-connect-to-fd 47 | #:display-disconnect 48 | #:display-get-fd 49 | #:display-dispatch 50 | #:display-dispatch-queue 51 | #:display-dispatch-queue-pending 52 | #:display-dispatch-pending 53 | #:display-get-error 54 | #:display-get-protocol-error 55 | #:display-flush 56 | #:display-roundtrip-queue 57 | #:display-roundtrip 58 | #:display-create-queue 59 | #:display-prepare-read-queue 60 | #:display-prepare-read 61 | #:display-cancel-read 62 | #:display-read-events 63 | #:log-set-handler-client 64 | #:define-listener 65 | #:buffer-interface 66 | #:callback-interface 67 | #:compositor-interface 68 | #:registry-interface 69 | #:seat-interface 70 | #:shell-interface 71 | #:shell-surface-interface 72 | #:shm-interface 73 | #:shm-pool-interface 74 | #:surface-interface 75 | #:touch-interface 76 | #:xdg-toplevel-interface 77 | #:keyboard-interface 78 | #:pointer-interface 79 | #:zxdg-decoration-manager-v1-interface 80 | #:xdg-wm-base-interface 81 | #:xdg-activation-v1-interface 82 | #:xdg-activation-token-v1-interface 83 | #:zwp-idle-inhibit-manager-v1-interface 84 | #:zwp-idle-inhibitor-v1-interface 85 | #:wp-fractional-scale-manager-v1-interface 86 | #:wp-fractional-scale-v1-interface 87 | #:xdg-toplevel-state 88 | #:seat-capabilities 89 | #:buffer-destroy 90 | #:compositor-create-surface 91 | #:display-get-registry 92 | #:pointer-set-cursor 93 | #:registry-bind 94 | #:seat-get-keyboard 95 | #:seat-get-pointer 96 | #:seat-get-touch 97 | #:shell-get-shell-surface 98 | #:shell-surface-pong 99 | #:shell-surface-set-title 100 | #:shell-surface-set-toplevel 101 | #:shm-create-pool 102 | #:shm-pool-create-buffer 103 | #:shm-pool-resize 104 | #:surface-attach 105 | #:surface-commit 106 | #:surface-damage 107 | #:surface-frame 108 | #:xdg-wm-base-get-xdg-surface 109 | #:xdg-wm-base-pong 110 | #:xdg-surface-get-toplevel 111 | #:xdg-surface-ack-configure 112 | #:xdg-toplevel-set-maximized 113 | #:xdg-toplevel-set-max-size 114 | #:xdg-toplevel-unset-maximized 115 | #:xdg-toplevel-set-fullscreen 116 | #:xdg-toplevel-unset-fullscreen 117 | #:xdg-toplevel-set-minimized 118 | #:xdg-toplevel-set-title 119 | #:zxdg-toplevel-decoration-v1-destroy 120 | #:xdg-activation-v1-destroy 121 | #:xdg-activation-v1-get-activation-token 122 | #:xdg-activation-v1-activate 123 | #:xdg-activation-token-v1-set-serial 124 | #:xdg-activation-token-v1-set-surface 125 | #:xdg-activation-token-v1-commit 126 | #:xdg-activation-token-v1-destroy 127 | #:zwp-idle-inhibit-manager-v1-destroy 128 | #:zwp-idle-inhibit-manager-v1-create-inhibitor 129 | #:zwp-idle-inhibitor-v1-destroy 130 | #:wp-fractional-scale-manager-v1-destroy 131 | #:wp-fractional-scale-manager-v1-get-fractional-scale 132 | #:wp-fractional-scale-v1-destroy 133 | #:xkb-context-new 134 | #:xkb-context-unref 135 | #:xkb-keymap-new-from-string 136 | #:xkb-keymap-unref 137 | #:xkb-keymap-mod-get-index 138 | #:xkb-keymap-key-repeats 139 | #:xkb-keymap-key-get-syms-by-level 140 | #:xkb-state-new 141 | #:xkb-state-unref 142 | #:xkb-state-key-get-syms 143 | #:xkb-state-update-mask 144 | #:xkb-state-key-get-layout 145 | #:xkb-state-mod-index-is-active 146 | #:xkb-compose-table-new-from-locale 147 | #:xkb-compose-table-unref 148 | #:xkb-compose-state-new 149 | #:xkb-compose-state-unref 150 | #:xkb-compose-state-feed 151 | #:xkb-compose-state-get-status 152 | #:xkb-compose-state-get-one-sym 153 | #:xkb-compose-state-get-utf8)) 154 | 155 | (defpackage #:org.shirakumo.framebuffers.wayland 156 | (:use #:cl) 157 | (:shadow #:atom) 158 | (:local-nicknames 159 | (#:fb #:org.shirakumo.framebuffers) 160 | (#:fb-int #:org.shirakumo.framebuffers.int) 161 | (#:wl #:org.shirakumo.framebuffers.wayland.cffi)) 162 | (:export 163 | #:window)) 164 | -------------------------------------------------------------------------------- /wayland/keycodes.lisp: -------------------------------------------------------------------------------- 1 | (in-package #:org.shirakumo.framebuffers.wayland) 2 | 3 | (defvar *moddef-table* '((:control -1 "Control") 4 | (:alt -1 "Mod1") 5 | (:shift -1 "Shift") 6 | (:super -1 "Mod4") 7 | (:caps-lock -1 "Lock") 8 | (:num-lock -1 "Mod2") 9 | (:scroll-lock -1 "Mod3") 10 | (:hyper -1 "Mod5"))) 11 | 12 | (defvar *keycodes* (make-array 256)) 13 | (defvar *codetable* (make-hash-table :test 'eq)) 14 | 15 | (defun init-keycodes () 16 | (loop for (i k) on '(1 :escape 17 | 2 :1 18 | 3 :2 19 | 4 :3 20 | 5 :4 21 | 6 :5 22 | 7 :6 23 | 8 :7 24 | 9 :8 25 | 10 :9 26 | 11 :0 27 | 12 :minus 28 | 13 :equal 29 | 14 :backspace 30 | 15 :tab 31 | 16 :q 32 | 17 :w 33 | 18 :e 34 | 19 :r 35 | 20 :t 36 | 21 :y 37 | 22 :u 38 | 23 :i 39 | 24 :o 40 | 25 :p 41 | 26 :left-bracket 42 | 27 :right-bracket 43 | 28 :enter 44 | 29 :left-control 45 | 30 :a 46 | 31 :s 47 | 32 :d 48 | 33 :f 49 | 34 :g 50 | 35 :h 51 | 36 :j 52 | 37 :k 53 | 38 :l 54 | 39 :semicolon 55 | 40 :apostrophe 56 | 41 :grave-accent 57 | 42 :left-shift 58 | 43 :backslash 59 | 44 :z 60 | 45 :x 61 | 46 :c 62 | 47 :v 63 | 48 :b 64 | 49 :n 65 | 50 :m 66 | 51 :comma 67 | 52 :period 68 | 53 :slash 69 | 54 :right-shift 70 | 55 :kp-multiply 71 | 56 :left-alt 72 | 57 :space 73 | 58 :caps-lock 74 | 59 :f1 75 | 60 :f2 76 | 61 :f3 77 | 62 :f4 78 | 63 :f5 79 | 64 :f6 80 | 65 :f7 81 | 66 :f8 82 | 67 :f9 83 | 68 :f10 84 | 69 :num-lock 85 | 70 :scroll-lock 86 | 71 :kp-7 87 | 72 :kp-8 88 | 73 :kp-9 89 | 74 :kp-subtract 90 | 75 :kp-4 91 | 76 :kp-5 92 | 77 :kp-6 93 | 78 :kp-add 94 | 79 :kp-1 95 | 80 :kp-2 96 | 81 :kp-3 97 | 82 :kp-0 98 | 83 :kp-decimal 99 | 86 :world-2 100 | 87 :f11 101 | 88 :f12 102 | 96 :kp-enter 103 | 97 :right-control 104 | 98 :kp-divide 105 | 100 :right-alt 106 | 102 :home 107 | 103 :up 108 | 104 :page-up 109 | 105 :left 110 | 106 :right 111 | 107 :end 112 | 108 :down 113 | 109 :page-down 114 | 110 :insert 115 | 111 :delete 116 | 117 :kp-equal 117 | 119 :pause 118 | 125 :left-super 119 | 126 :right-super 120 | 127 :menu 121 | 183 :f13 122 | 184 :f14 123 | 185 :f15 124 | 186 :f16 125 | 187 :f17 126 | 188 :f18 127 | 189 :f19 128 | 190 :f20 129 | 191 :f21 130 | 192 :f22 131 | 193 :f23 132 | 194 :f24 133 | 210 :print-screen) 134 | by #'cddr 135 | do (setf (aref *keycodes* i) k)) 136 | (loop for i from 0 below (length *keycodes*) 137 | for key = (aref *keycodes* i) 138 | do (when key (setf (gethash key *codetable*) i)))) 139 | 140 | (init-keycodes) 141 | 142 | (defun translate-key (key) 143 | (when (<= 0 key 255) 144 | (aref *keycodes* key))) 145 | 146 | (defun key-code (key) 147 | (gethash key *codetable*)) 148 | -------------------------------------------------------------------------------- /protocol.lisp: -------------------------------------------------------------------------------- 1 | (in-package #:org.shirakumo.framebuffers) 2 | 3 | (define-condition framebuffer-error (error) 4 | ((window :initarg :window :initform NIL :reader window))) 5 | 6 | ;;; Display info 7 | (defclass display () ()) 8 | 9 | (defstruct (video-mode 10 | (:constructor make-video-mode (display width height refresh-rate)) 11 | (:copier NIL) 12 | (:predicate NIL)) 13 | (display NIL) 14 | (width 0 :type (unsigned-byte 16)) 15 | (height 0 :type (unsigned-byte 16)) 16 | (refresh-rate 0 :type (unsigned-byte 16))) 17 | 18 | (defgeneric primary-p (display)) 19 | (defgeneric video-modes (display)) 20 | (defgeneric video-mode (display)) 21 | (defgeneric id (display)) 22 | 23 | ;;; Window info 24 | (defclass window () ()) 25 | 26 | (defstruct (icon 27 | (:constructor make-icon (width height buffer)) 28 | (:copier NIL) 29 | (:predicate NIL)) 30 | (width 0 :type (unsigned-byte 16)) 31 | (height 0 :type (unsigned-byte 16)) 32 | (buffer NIL :type (simple-array (unsigned-byte 8) (*)))) 33 | 34 | (defgeneric valid-p (window)) 35 | (defgeneric close (window)) 36 | (defgeneric close-requested-p (window)) 37 | (defgeneric width (window)) 38 | (defgeneric height (window)) 39 | (defgeneric size (window)) 40 | (defgeneric (setf size) (size window)) 41 | (defgeneric minimum-size (window)) 42 | (defgeneric (setf minimum-size) (value window)) 43 | (defgeneric maximum-size (window)) 44 | (defgeneric (setf maximum-size) (value window)) 45 | (defgeneric location (window)) 46 | (defgeneric (setf location) (location window)) 47 | (defgeneric title (window)) 48 | (defgeneric (setf title) (title window)) 49 | (defgeneric visible-p (window)) 50 | (defgeneric (setf visible-p) (state window)) 51 | (defgeneric maximized-p (window)) 52 | (defgeneric (setf maximized-p) (state window)) 53 | (defgeneric iconified-p (window)) 54 | (defgeneric (setf iconified-p) (state window)) 55 | (defgeneric focused-p (window)) 56 | (defgeneric (setf focused-p) (value window)) 57 | (defgeneric borderless-p (window)) 58 | (defgeneric (setf borderless-p) (value window)) 59 | (defgeneric always-on-top-p (window)) 60 | (defgeneric (setf always-on-top-p) (value window)) 61 | (defgeneric resizable-p (window)) 62 | (defgeneric (setf resizable-p) (value window)) 63 | (defgeneric floating-p (window)) 64 | (defgeneric (setf floating-p) (value window)) 65 | (defgeneric mouse-entered-p (window)) 66 | (defgeneric clipboard (window)) 67 | (defgeneric (setf clipboard) (string window)) 68 | (defgeneric content-scale (window)) 69 | (defgeneric buffer (window)) 70 | (defgeneric swap-buffers (window &key x y w h sync)) 71 | (defgeneric process-events (window &key timeout)) 72 | (defgeneric request-attention (window)) 73 | (defgeneric mouse-location (window)) 74 | (defgeneric mouse-button-pressed-p (button window)) 75 | (defgeneric key-pressed-p (key window)) 76 | (defgeneric key-scan-code (key window)) 77 | (defgeneric local-key-string (key window)) 78 | (defgeneric icon (window)) 79 | (defgeneric (setf icon) (value window)) 80 | (defgeneric cursor-icon (window)) 81 | (defgeneric (setf cursor-icon) (value window)) 82 | (defgeneric cursor-state (window)) 83 | (defgeneric (setf cursor-state) (value window)) 84 | (defgeneric fullscreen-p (window)) 85 | (defgeneric (setf fullscreen-p) (value window)) 86 | (defgeneric display (window)) 87 | (defgeneric set-timer (window delay &key repeat)) 88 | (defgeneric cancel-timer (window timer)) 89 | 90 | ;;; Event callbacks 91 | (defclass event-handler () 92 | ((window :initform NIL :initarg :window :accessor window))) 93 | 94 | (defstruct (touchpoint 95 | (:constructor make-touchpoint (&optional location radius angle pressure)) 96 | (:copier NIL) 97 | (:predicate NIL)) 98 | (location (cons 0 0) :type cons) 99 | (radius (cons 0 0) :type cons) 100 | (angle 0 :type real) 101 | (pressure 0 :type real)) 102 | 103 | (defgeneric window-moved (event-handler xpos ypos)) 104 | (defgeneric window-resized (event-handler width height)) 105 | (defgeneric window-refreshed (event-handler)) 106 | (defgeneric window-focused (event-handler focused-p)) 107 | (defgeneric window-iconified (event-handler iconified-p)) 108 | (defgeneric window-maximized (event-handler maximized-p)) 109 | (defgeneric window-closed (event-handler)) 110 | (defgeneric mouse-button-changed (event-handler button action modifiers)) 111 | (defgeneric mouse-moved (event-handler xpos ypos)) 112 | (defgeneric mouse-entered (event-handler entered-p)) 113 | (defgeneric mouse-scrolled (event-handler xoffset yoffset)) 114 | (defgeneric key-changed (event-handler key scan-code action modifiers)) 115 | (defgeneric string-entered (event-handler string)) 116 | (defgeneric file-dropped (event-handler paths)) 117 | (defgeneric content-scale-changed (window xscale yscale)) 118 | (defgeneric touch-started (event-handler points)) 119 | (defgeneric touch-moved (event-handler points)) 120 | (defgeneric touch-ended (event-handler points)) 121 | (defgeneric touch-cancelled (event-handler points)) 122 | (defgeneric pen-moved (event-handler xpos ypos mode pressure xtilt ytilt)) 123 | (defgeneric timer-triggered (event-handler timer)) 124 | (defgeneric display-connected (event-handler display connected-p)) 125 | 126 | ;;; TODO: 127 | ;;;; move-to-front 128 | ;;;; move-to-back 129 | ;;;; Input Method support 130 | ;;;; Display gamma curves 131 | ;;;; Display physical dimensions 132 | -------------------------------------------------------------------------------- /win32/package.lisp: -------------------------------------------------------------------------------- 1 | (defpackage #:org.shirakumo.framebuffers.win32.cffi 2 | (:use #:cl) 3 | (:local-nicknames 4 | (#:com #:org.shirakumo.com-on)) 5 | (:export 6 | #:user32 7 | #:gdi32 8 | #:shcore 9 | #:key 10 | #:minmax-info 11 | #:minmax-info-reserved-x 12 | #:minmax-info-reserved-y 13 | #:minmax-info-max-size-x 14 | #:minmax-info-max-size-y 15 | #:minmax-info-max-position-x 16 | #:minmax-info-max-position-y 17 | #:minmax-info-min-track-size-x 18 | #:minmax-info-min-track-size-y 19 | #:minmax-info-max-track-size-x 20 | #:minmax-info-max-track-size-y 21 | #:window-class 22 | #:window-class-style 23 | #:window-class-proc 24 | #:window-class-class-extra 25 | #:window-class-window-extra 26 | #:window-class-instance 27 | #:window-class-icon 28 | #:window-class-cursor 29 | #:window-class-background 30 | #:window-class-menu-name 31 | #:window-class-class-name 32 | #:message 33 | #:message-window 34 | #:message-type 35 | #:message-wparameter 36 | #:message-lparameter 37 | #:message-time 38 | #:message-x 39 | #:message-y 40 | #:icon-info 41 | #:icon-info-icon 42 | #:icon-info-xhotspot 43 | #:icon-info-yhotspot 44 | #:icon-info-mask 45 | #:icon-info-color 46 | #:bitmap-info 47 | #:bitmap-info-size 48 | #:bitmap-info-width 49 | #:bitmap-info-height 50 | #:bitmap-info-planes 51 | #:bitmap-info-bit-count 52 | #:bitmap-info-compression 53 | #:bitmap-info-size-image 54 | #:bitmap-info-x-per-meter 55 | #:bitmap-info-y-per-meter 56 | #:bitmap-info-clear-used 57 | #:bitmap-info-clear-important 58 | #:bitmap-info-red-mask 59 | #:bitmap-info-green-mask 60 | #:bitmap-info-blue-mask 61 | #:bitmap-info-alpha-mask 62 | #:rect 63 | #:rect-left 64 | #:rect-top 65 | #:rect-right 66 | #:rect-bottom 67 | #:track-mouse-event 68 | #:track-mouse-event-size 69 | #:track-mouse-event-flags 70 | #:track-mouse-event-track 71 | #:track-mouse-event-hover-time 72 | #:device-mode 73 | #:device-mode-device-name 74 | #:device-mode-spec-version 75 | #:device-mode-driver-version 76 | #:device-mode-size 77 | #:device-mode-driver-extra 78 | #:device-mode-fields 79 | #:device-mode-position-x 80 | #:device-mode-position-y 81 | #:device-mode-display-orientation 82 | #:device-mode-display-fixed-output 83 | #:device-mode-color 84 | #:device-mode-duplex 85 | #:device-mode-resolution 86 | #:device-mode-option 87 | #:device-mode-collate 88 | #:device-mode-form-name 89 | #:device-mode-log-pixels 90 | #:device-mode-bits-per-pel 91 | #:device-mode-pels-width 92 | #:device-mode-pels-height 93 | #:device-mode-display-flags 94 | #:device-mode-display-frequency 95 | #:device-mode-icm-method 96 | #:device-mode-icm-intent 97 | #:device-mode-media-type 98 | #:device-mode-dither-type 99 | #:device-mode-reserved-1 100 | #:device-mode-reserved-2 101 | #:device-mode-panning-width 102 | #:device-mode-panning-height 103 | #:adapter 104 | #:adapter-cb 105 | #:adapter-device-name 106 | #:adapter-device-string 107 | #:adapter-state-flags 108 | #:adapter-device-id 109 | #:adapter-device-key 110 | #:adjust-window-rect 111 | #:bit-blt 112 | #:bring-window-to-top 113 | #:change-display-settings 114 | #:create-window 115 | #:def-window-proc 116 | #:destroy-window 117 | #:dispatch-message 118 | #:enable-non-client-dpi-scaling 119 | #:enum-display-settings 120 | #:enum-display-devices 121 | #:flash-window 122 | #:get-class 123 | #:get-class-info 124 | #:get-dc 125 | #:get-device-caps 126 | #:get-dpi-for-monitor 127 | #:get-dpi-for-window 128 | #:get-message-time 129 | #:get-module-handle 130 | #:get-key-state 131 | #:get-system-metrics 132 | #:get-window 133 | #:get-window-rect 134 | #:invalidate-rect 135 | #:load-cursor 136 | #:load-cursor* 137 | #:map-virtual-key 138 | #:monitor-from-window 139 | #:move-window 140 | #:msg-wait-for-multiple-objects 141 | #:peek-message 142 | #:register-class 143 | #:unregister-class 144 | #:release-dc 145 | #:send-message 146 | #:set-focus 147 | #:set-foreground-window 148 | #:set-process-dpi-aware 149 | #:set-process-dpi-awareness-context 150 | #:set-process-dpi-awareness 151 | #:set-window 152 | #:set-window-pos 153 | #:set-window-text 154 | #:show-window 155 | #:stretch-di-bits 156 | #:to-unicode 157 | #:translate-message 158 | #:validate-rect 159 | #:create-waitable-timer 160 | #:set-waitable-timer 161 | #:cancel-waitable-timer 162 | #:close-handle 163 | #:destroy-icon 164 | #:create-dib-section 165 | #:create-bitmap 166 | #:create-icon 167 | #:destroy-object 168 | #:load-image 169 | #:set-cursor 170 | #:open-clipboard 171 | #:enum-clipboard-formats 172 | #:get-clipboard-data 173 | #:set-clipboard-data 174 | #:empty-clipboard 175 | #:close-clipboard 176 | #:global-alloc 177 | #:delete-object 178 | #:global-lock 179 | #:global-unlock 180 | #:drag-finish 181 | #:drag-query-point 182 | #:drag-query-file 183 | #:drag-accept-files 184 | #:ENUM-CURRENT-SETTINGS 185 | #:ENUM-REGISTRY-SETTINGS)) 186 | 187 | (defpackage #:org.shirakumo.framebuffers.win32 188 | (:use #:cl) 189 | (:shadow #:atom) 190 | (:local-nicknames 191 | (#:fb #:org.shirakumo.framebuffers) 192 | (#:fb-int #:org.shirakumo.framebuffers.int) 193 | (#:win32 #:org.shirakumo.framebuffers.win32.cffi) 194 | (#:com #:org.shirakumo.com-on)) 195 | (:export 196 | #:window)) 197 | -------------------------------------------------------------------------------- /win32/keycodes.lisp: -------------------------------------------------------------------------------- 1 | (in-package #:org.shirakumo.framebuffers.win32) 2 | 3 | (defvar *keycodes* (make-array 356)) 4 | (defvar *codetable* (make-hash-table :test 'eq)) 5 | (defvar *stringtable* (make-array 356)) 6 | 7 | (defun init-keycodes () 8 | (loop for (i k) on '(#x001 :escape 9 | #x002 :1 10 | #x003 :2 11 | #x004 :3 12 | #x005 :4 13 | #x006 :5 14 | #x007 :6 15 | #x008 :7 16 | #x009 :8 17 | #x00a :9 18 | #x00b :0 19 | #x00c :minus 20 | #x00d :equal 21 | #x00e :backspace 22 | #x00f :tab 23 | #x010 :q 24 | #x011 :w 25 | #x012 :e 26 | #x013 :r 27 | #x014 :t 28 | #x015 :y 29 | #x016 :u 30 | #x017 :i 31 | #x018 :o 32 | #x019 :p 33 | #x01a :left-bracket 34 | #x01b :right-bracket 35 | #x01c :enter 36 | #x01d :left-control 37 | #x01e :a 38 | #x01f :s 39 | #x020 :d 40 | #x021 :f 41 | #x022 :g 42 | #x023 :h 43 | #x024 :j 44 | #x025 :k 45 | #x026 :l 46 | #x027 :semicolon 47 | #x028 :apostrophe 48 | #x029 :grave-accent 49 | #x02a :left-shift 50 | #x02b :backslash 51 | #x02c :z 52 | #x02d :x 53 | #x02e :c 54 | #x02f :v 55 | #x030 :b 56 | #x031 :n 57 | #x032 :m 58 | #x033 :comma 59 | #x034 :period 60 | #x035 :slash 61 | #x036 :right-shift 62 | #x037 :kp-multiply 63 | #x038 :left-alt 64 | #x039 :space 65 | #x03a :caps-lock 66 | #x03b :f1 67 | #x03c :f2 68 | #x03d :f3 69 | #x03e :f4 70 | #x03f :f5 71 | #x040 :f6 72 | #x041 :f7 73 | #x042 :f8 74 | #x043 :f9 75 | #x044 :f10 76 | #x045 :pause 77 | #x046 :scroll-lock 78 | #x047 :kp-7 79 | #x048 :kp-8 80 | #x049 :kp-9 81 | #x04a :kp-subtract 82 | #x04b :kp-4 83 | #x04c :kp-5 84 | #x04d :kp-6 85 | #x04e :kp-add 86 | #x04f :kp-1 87 | #x050 :kp-2 88 | #x051 :kp-3 89 | #x052 :kp-0 90 | #x053 :kp-decimal 91 | #x056 :world-2 92 | #x057 :f11 93 | #x058 :f12 94 | #x059 :kp-equal 95 | #x064 :f13 96 | #x065 :f14 97 | #x066 :f15 98 | #x067 :f16 99 | #x068 :f17 100 | #x069 :f18 101 | #x06a :f19 102 | #x06b :f20 103 | #x06c :f21 104 | #x06d :f22 105 | #x06e :f23 106 | #x076 :f24 107 | #x11c :kp-enter 108 | #x11d :right-control 109 | #x135 :kp-divide 110 | #x137 :print-screen 111 | #x138 :right-alt 112 | #x145 :num-lock 113 | #x147 :home 114 | #x148 :up 115 | #x149 :page-up 116 | #x14b :left 117 | #x14d :right 118 | #x14f :end 119 | #x150 :down 120 | #x151 :page-down 121 | #x152 :insert 122 | #x153 :delete 123 | #x15b :left-super 124 | #x15c :right-super 125 | #x15d :menu) 126 | by #'cddr 127 | do (setf (aref *keycodes* i) k)) 128 | (loop for i from 0 below (length *keycodes*) 129 | for key = (aref *keycodes* i) 130 | do (when key (setf (gethash key *codetable*) i)))) 131 | 132 | (init-keycodes) 133 | 134 | (defun init-stringtable () 135 | (fill *stringtable* NIL) 136 | (cffi:with-foreign-objects ((state :char 256) 137 | (chars :char 32)) 138 | (cffi:foreign-funcall "memset" :pointer state :int 0 :size 256) 139 | (loop for scancode from 0 below (length *keycodes*) 140 | for key = (aref *keycodes* scancode) 141 | do (when key 142 | (let* ((vk (win32:map-virtual-key scancode 1)) 143 | (len (win32:to-unicode vk scancode state chars 16 0))) 144 | (when (= -1 len) ;; Retry for dead keys 145 | (win32:to-unicode vk scancode state chars 16 0)) 146 | (when (< 0 len) 147 | (setf (aref *stringtable* scancode) (com:wstring->string chars)))))))) 148 | 149 | (defun translate-keycode (keycode) 150 | (when (<= 0 keycode (1- 356)) 151 | (aref *keycodes* keycode))) 152 | 153 | (defun key-code (key) 154 | (gethash key *codetable*)) 155 | 156 | (defun key-string (key) 157 | (gethash key *stringtable*)) 158 | -------------------------------------------------------------------------------- /xlib/package.lisp: -------------------------------------------------------------------------------- 1 | (defpackage #:org.shirakumo.framebuffers.xlib.cffi 2 | (:use #:cl) 3 | (:shadow #:atom) 4 | (:export 5 | #:x11 6 | #:xext 7 | #:xrandr 8 | #:xinerama 9 | #:xcursor 10 | #:xi 11 | #:xid 12 | #:atom 13 | #:xrm-value 14 | #:xrm-value-size 15 | #:xrm-value-addr 16 | #:error-event 17 | #:error-event-type 18 | #:error-event-display 19 | #:error-event-resource-id 20 | #:error-event-serial 21 | #:error-event-error-code 22 | #:error-event-request-code 23 | #:error-event-minor-code 24 | #:image 25 | #:image-width 26 | #:image-height 27 | #:image-xoffset 28 | #:image-format 29 | #:image-data 30 | #:image-byte-order 31 | #:image-bitmap-unit 32 | #:image-bitmap-bit-order 33 | #:image-bitmap-pad 34 | #:image-depth 35 | #:image-bytes-per-line 36 | #:image-bits-per-pixel 37 | #:image-red-mask 38 | #:image-green-mask 39 | #:image-blue-mask 40 | #:image-obdata 41 | #:image-create-image 42 | #:image-destroy-image 43 | #:image-get-pixel 44 | #:image-put-pixel 45 | #:image-sub-image 46 | #:image-add-pixel 47 | #:set-window-attributes 48 | #:set-window-attributes-background-pixmap 49 | #:set-window-attributes-background-pixel 50 | #:set-window-attributes-border-pixmap 51 | #:set-window-attributes-border-pixel 52 | #:set-window-attributes-bit-gravity 53 | #:set-window-attributes-win-gravity 54 | #:set-window-attributes-backing-store 55 | #:set-window-attributes-backing-planes 56 | #:set-window-attributes-backing-pixel 57 | #:set-window-attributes-save-under 58 | #:set-window-attributes-event-mask 59 | #:set-window-attributes-do-not-progagate-mask 60 | #:set-window-attributes-override-redirect 61 | #:set-window-attributes-colormap 62 | #:set-window-attributes-cursor 63 | #:pixmap-format 64 | #:pixmap-format-depth 65 | #:pixmap-format-bits-per-pixel 66 | #:pixmap-format-scanline-pad 67 | #:size-hint 68 | #:size-hint-flags 69 | #:size-hint-x 70 | #:size-hint-y 71 | #:size-hint-width 72 | #:size-hint-height 73 | #:size-hint-min-width 74 | #:size-hint-min-height 75 | #:size-hint-max-width 76 | #:size-hint-max-height 77 | #:size-hint-width-inc 78 | #:size-hint-height-inc 79 | #:size-hint-min-aspect-x 80 | #:size-hint-min-aspect-y 81 | #:size-hint-max-aspect-x 82 | #:size-hint-max-aspect-y 83 | #:size-hint-base-width 84 | #:size-hint-base-height 85 | #:size-hint-win-gravity 86 | #:event 87 | #:base-event 88 | #:base-event-type 89 | #:base-event-serial 90 | #:base-event-send-event 91 | #:base-event-display 92 | #:base-event-window 93 | #:positioned-event 94 | #:positioned-event-root 95 | #:positioned-event-subwindow 96 | #:positioned-event-time 97 | #:positioned-event-x 98 | #:positioned-event-y 99 | #:positioned-event-x-root 100 | #:positioned-event-y-root 101 | #:key-event 102 | #:key-event-state 103 | #:key-event-keycode 104 | #:key-event-same-screen 105 | #:button-event 106 | #:button-event-state 107 | #:button-event-button 108 | #:button-event-same-screen 109 | #:focus-change-event 110 | #:focus-change-event-mode 111 | #:focus-change-event-detail 112 | #:configure-event 113 | #:configure-event-x 114 | #:configure-event-y 115 | #:configure-event-width 116 | #:configure-event-height 117 | #:configure-event-border-width 118 | #:configure-event-above 119 | #:configure-event-override-redirect 120 | #:property-event 121 | #:property-event-atom 122 | #:property-event-time 123 | #:property-event-state 124 | #:destroy-window-event 125 | #:client-message-event 126 | #:client-message-event-message-type 127 | #:client-message-event-format 128 | #:client-message-event-data 129 | #:net-message-event-protocol 130 | #:black-pixel 131 | #:default-depth 132 | #:default-gc 133 | #:default-root-window 134 | #:default-visual 135 | #:default-screen 136 | #:display-height 137 | #:display-width 138 | #:init-threads 139 | #:free-threads 140 | #:change-property 141 | #:delete-property 142 | #:get-window-property 143 | #:clear-window 144 | #:clear-area 145 | #:close-display 146 | #:create-image 147 | #:create-window 148 | #:destroy-image 149 | #:destroy-window 150 | #:events-queued 151 | #:flush 152 | #:sync 153 | #:free 154 | #:intern-atom 155 | #:list-pixmap-formats 156 | #:lookup-string 157 | #:map-raised 158 | #:unmap-window 159 | #:next-event 160 | #:open-display 161 | #:peek-event 162 | #:pending 163 | #:put-image 164 | #:select-input 165 | #:set-wm-normal-hints 166 | #:set-wm-protocols 167 | #:store-name 168 | #:move-window 169 | #:resize-window 170 | #:send-event 171 | #:iconify-window 172 | #:set-error-handler 173 | #:set-io-error-handler 174 | #:set-io-error-exit-handler 175 | #:get-error-text 176 | #:display-keycodes 177 | #:get-keyboard-mapping 178 | #:connection-number 179 | #:resource-manager-string 180 | #:xrm-get-string-database 181 | #:xrm-get-resource 182 | #:xrm-destroy-database 183 | #:utf8-lookup-string 184 | #:lookup-string 185 | #:xkb-desc 186 | #:xkb-desc-display 187 | #:xkb-desc-flags 188 | #:xkb-desc-device-spec 189 | #:xkb-desc-min-key-code 190 | #:xkb-desc-max-key-code 191 | #:xkb-desc-controls 192 | #:xkb-desc-server-map 193 | #:xkb-desc-client-map 194 | #:xkb-desc-indicator 195 | #:xkb-desc-names 196 | #:xkb-desc-compat-map 197 | #:xkb-desc-geometry 198 | #:xkb-key 199 | #:xkb-key-name 200 | #:xkb-alias 201 | #:xkb-alias-real 202 | #:xkb-alias-alias 203 | #:xkb-names 204 | #:xkb-names-keycodes 205 | #:xkb-names-geometry 206 | #:xkb-names-symbols 207 | #:xkb-names-types 208 | #:xkb-names-compat 209 | #:xkb-names-vmods 210 | #:xkb-names-indicators 211 | #:xkb-names-groups 212 | #:xkb-names-keys 213 | #:xkb-names-key-aliases 214 | #:xkb-names-radio-groups 215 | #:xkb-names-phys-symbols 216 | #:xkb-names-num-keys 217 | #:xkb-names-num-key-aliases 218 | #:xkb-names-num-rg 219 | #:xkb-query-extension 220 | #:xkb-keycode-to-keysym 221 | #:xkb-get-map 222 | #:xkb-get-names 223 | #:xkb-free-names 224 | #:xkb-free-keyboard 225 | #:shm-segment-info 226 | #:shm-segment-info-message 227 | #:shm-segment-info-id 228 | #:shm-segment-info-address 229 | #:shm-segment-info-read-only 230 | #:xshm-query-extension 231 | #:xshm-pixmap-format 232 | #:xshm-put-image 233 | #:xshm-create-image 234 | #:xshm-attach 235 | #:xshm-deach 236 | #:output-info 237 | #:output-info-timestamp 238 | #:output-info-crtc 239 | #:output-info-name 240 | #:output-info-name-length 241 | #:output-info-mm-width 242 | #:output-info-mm-height 243 | #:output-info-connection 244 | #:output-info-subpixel-order 245 | #:output-info-crtc-count 246 | #:output-info-crtcs 247 | #:output-info-clone-count 248 | #:output-info-clones 249 | #:output-info-mode-count 250 | #:output-info-preferred 251 | #:output-info-modes 252 | #:screen-resources 253 | #:screen-resources-timestamp 254 | #:screen-resources-config-timestamp 255 | #:screen-resources-crtc-count 256 | #:screen-resources-crtcs 257 | #:screen-resources-output-count 258 | #:screen-resources-outputs 259 | #:screen-resources-mode-count 260 | #:screen-resources-modes 261 | #:mode-info 262 | #:mode-info-id 263 | #:mode-info-width 264 | #:mode-info-height 265 | #:mode-info-dot-clock 266 | #:mode-info-hsync-start 267 | #:mode-info-hsync-end 268 | #:mode-info-htotal 269 | #:mode-info-hskew 270 | #:mode-info-vsync-start 271 | #:mode-info-vsync-end 272 | #:mode-info-vtotal 273 | #:mode-info-name 274 | #:mode-info-name-length 275 | #:mode-info-flags 276 | #:crtc-info 277 | #:crtc-info-timestamp 278 | #:crtc-info-x 279 | #:crtc-info-y 280 | #:crtc-info-width 281 | #:crtc-info-height 282 | #:crtc-info-mode 283 | #:crtc-info-rotation 284 | #:crtc-info-output-count 285 | #:crtc-info-outputs 286 | #:crtc-info-rotations 287 | #:crtc-info-possible-count 288 | #:crtc-info-possibles 289 | #:screen 290 | #:screen-number 291 | #:screen-x 292 | #:screen-y 293 | #:screen-width 294 | #:screen-height 295 | #:xrr-query-extension 296 | #:xrr-get-screen-resources-current 297 | #:xrr-get-output-primary 298 | #:xrr-get-output-info 299 | #:xrr-get-crtc-info 300 | #:xrr-free-crtc-info 301 | #:xrr-free-output-info 302 | #:xrr-free-screen-resources 303 | #:xrr-set-crtc-config 304 | #:xrr-update-configuration 305 | #:xinerama-query-extension 306 | #:xinerama-query-screens)) 307 | 308 | (defpackage #:org.shirakumo.framebuffers.xlib 309 | (:use #:cl) 310 | (:shadow #:atom) 311 | (:local-nicknames 312 | (#:fb #:org.shirakumo.framebuffers) 313 | (#:fb-int #:org.shirakumo.framebuffers.int) 314 | (#:xlib #:org.shirakumo.framebuffers.xlib.cffi)) 315 | (:export 316 | #:window)) 317 | -------------------------------------------------------------------------------- /cocoa/bindings.lisp: -------------------------------------------------------------------------------- 1 | (in-package #:org.shirakumo.framebuffers.cocoa.cffi) 2 | 3 | (cffi:defbitfield style-mask 4 | (:borderless 0) 5 | (:titled 1) 6 | (:closable 2) 7 | (:miniaturizable 4) 8 | (:resizable 8) 9 | (:utility 16) 10 | (:docmodal 32) 11 | (:icon 64) 12 | (:mini 128)) 13 | 14 | (cffi:defbitfield modifier-flags 15 | (:caps-lock #.(ash 1 16)) 16 | (:shift #.(ash 1 17)) 17 | (:control #.(ash 1 18)) 18 | (:alt #.(ash 1 19)) 19 | (:super #.(ash 1 20))) 20 | 21 | (cffi:defbitfield collection-behavior 22 | (:default 0) 23 | (:can-join-all-spaces 1) 24 | (:move-to-active-space 2) 25 | (:managed 4) 26 | (:transient 8) 27 | (:stationary 16) 28 | (:participates-in-cycle 32) 29 | (:ignores-cycle 64) 30 | (:full-screen-primary 128) 31 | (:full-screen-auxiliary 256) 32 | (:full-screen-none 512) 33 | (:full-screen-allows-tiling 2048) 34 | (:full-screen-disallows-tiling 4096)) 35 | 36 | (cffi:defbitfield bitmap-info 37 | (:alpha-info-mask 31) 38 | (:byte-order-16-big 12288) 39 | (:byte-order-16-little 4096) 40 | (:byte-order-32-big 16384) 41 | (:byte-order-32-little 8192) 42 | (:byte-order-default 0) 43 | (:byte-order-mask 28672) 44 | (:first 4) 45 | (:float-components 256) 46 | (:float-info-mask 3840) 47 | (:last 3) 48 | (:none 0) 49 | (:none-skip-first 6) 50 | (:none-skip-last 5) 51 | (:only 7) 52 | (:premultiplied-first 2) 53 | (:premultiplied-last 1)) 54 | 55 | (cffi:defcenum rendering-intent 56 | (:default 0) 57 | :absolute-colorimetric 58 | :relative-colorimetric 59 | :perceptual 60 | :saturation) 61 | 62 | (cffi:defcenum window-level-key 63 | (:base 0) 64 | :minimum 65 | :desktop 66 | :backstop-menu 67 | :normal 68 | :floating 69 | :torn-off-menu 70 | :dock 71 | :main-menu 72 | :status 73 | :modal-panel 74 | :popup-menu 75 | :dragging 76 | :screensaver 77 | :maximum 78 | :overlay 79 | :help 80 | :utility 81 | :desktop-icon 82 | :cursor 83 | :assistive-tech-high) 84 | 85 | (cffi:defcvar (paste-url "NSPasteboardTypeURL") :pointer) 86 | (cffi:defcvar (paste-collaboration-metadata "NSPasteboardTypeCollaborationMetadata") :pointer) 87 | (cffi:defcvar (paste-color "NSPasteboardTypeColor") :pointer) 88 | (cffi:defcvar (paste-file-url "NSPasteboardTypeFileURL") :pointer) 89 | (cffi:defcvar (paste-font "NSPasteboardTypeFont") :pointer) 90 | (cffi:defcvar (paste-html "NSPasteboardTypeHTML") :pointer) 91 | (cffi:defcvar (paste-multiple-text-selection "NSPasteboardTypeMultipleTextSelection") :pointer) 92 | (cffi:defcvar (paste-pdf "NSPasteboardTypePDF") :pointer) 93 | (cffi:defcvar (paste-png "NSPasteboardTypePNG") :pointer) 94 | (cffi:defcvar (paste-rtf "NSPasteboardTypeRTF") :pointer) 95 | (cffi:defcvar (paste-rtfd "NSPasteboardTypeRTFD") :pointer) 96 | (cffi:defcvar (paste-ruler "NSPasteboardTypeRuler") :pointer) 97 | (cffi:defcvar (paste-sound "NSPasteboardTypeSound") :pointer) 98 | (cffi:defcvar (paste-string "NSPasteboardTypeString") :pointer) 99 | (cffi:defcvar (paste-tabular-text "NSPasteboardTypeTabularText") :pointer) 100 | (cffi:defcvar (paste-text-finder-options "NSPasteboardTypeTextFinderOptions") :pointer) 101 | (cffi:defcvar (paste-tiff "NSPasteboardTypeTIFF") :pointer) 102 | 103 | (cffi:defcstruct (point :conc-name point-) 104 | (x objc:cgfloat) 105 | (y objc:cgfloat)) 106 | 107 | (cffi:defcstruct (size :conc-name size-) 108 | (w objc:cgfloat) 109 | (h objc:cgfloat)) 110 | 111 | (cffi:defcstruct (rect :conc-name rect-) 112 | (x objc:cgfloat) 113 | (y objc:cgfloat) 114 | (w objc:cgfloat) 115 | (h objc:cgfloat)) 116 | 117 | (objc:define-objcfun "NSApplication" (nsapplication-shared-application "sharedApplication") :void) 118 | 119 | (objc:define-objcfun "NSApp" (nsapp-set-activation-policy "setActivationPolicy:") :void 120 | (policy :pointer)) 121 | 122 | (objc:define-objcfun "NSApp" (nsapp-activate-ignoring-other-apps "activateIgnoringOtherApps:") :void 123 | (flag :bool)) 124 | 125 | (objc:define-objcfun "NSApp" (nsapp-request-user-attention "requestUserAttention:") :void 126 | (type :pointer)) 127 | 128 | (objc:define-objcfun "NSScreen" (nsscreen-main-screen "mainScreen") :pointer) 129 | 130 | (objc:define-objcfun "NSPasteboard" (nspasteboard-general-pasteboard "generalPasteboard") :pointer) 131 | 132 | (objc:define-objcfun "NSColor" (nscolor-clear-color "clearColor") :pointer) 133 | 134 | (defmacro alloc (cls) 135 | `(objc:call ,cls "alloc")) 136 | 137 | (objc:define-objcmethod (init "init") :pointer) 138 | 139 | (objc:define-objcmethod (init-with-content-rect "initWithContentRect:styleMask:backing:defer:") :pointer 140 | (rect (:struct rect)) 141 | (style-mask style-mask) 142 | (backing :pointer) 143 | (defer :boolean)) 144 | 145 | (objc:define-objcmethod (frame "frame") (:struct rect)) 146 | 147 | (objc:define-objcmethod (close "close") :void) 148 | 149 | (objc:define-objcmethod (is-zoomed "isZoomed") :boolean) 150 | 151 | (objc:define-objcmethod (convert-rect-to-backing "convertRectToBacking:") (:struct rect) 152 | (rect (:struct rect))) 153 | 154 | (objc:define-objcmethod (content-rect-for-frame-rect "contentRectForFrameRect:") (:struct rect) 155 | (frame (:struct rect))) 156 | 157 | (objc:define-objcmethod (set-release-when-closed "setReleaseWhenClosed:") :void 158 | (value :boolean)) 159 | 160 | (objc:define-objcmethod (set-opaque "setOpaque:") :void 161 | (value :boolean)) 162 | 163 | (objc:define-objcmethod (set-background-color "setBackgroundColor:") :void 164 | (value :pointer)) 165 | 166 | (objc:define-objcmethod (set-accepts-mouse-moved-events "setAcceptsMouseMovedEvents:") :void 167 | (value :boolean)) 168 | 169 | (objc:define-objcmethod (set-title "setTitle:") :void 170 | (value objc:nsstring)) 171 | 172 | (objc:define-objcmethod (set-content-view "setContentView:") :void 173 | (view :pointer)) 174 | 175 | (objc:define-objcmethod (make-first-responder-view "makeFirstResponder:") :void 176 | (view :pointer)) 177 | 178 | (objc:define-objcmethod (set-frame "setFrame:display:") :void 179 | (frame (:struct rect)) 180 | (display :boolean)) 181 | 182 | (objc:define-objcmethod (frame-rect-for-content-rect "frameRectForContentRect:") (:struct rect) 183 | (rect (:struct rect))) 184 | 185 | (objc:define-objcmethod (set-frame-origin "setFrameOrigin:") :void 186 | (point (:struct point))) 187 | 188 | (objc:define-objcmethod (set-miniwindow-title "setMiniwindowTitle") :void 189 | (title objc:nsstring)) 190 | 191 | (objc:define-objcmethod (order-front "orderFront:") :void 192 | (value :boolean)) 193 | 194 | (objc:define-objcmethod (order-out "orderOut:") :void 195 | (value :boolean)) 196 | 197 | (objc:define-objcmethod (zoom "zoom:") :void 198 | (value :boolean)) 199 | 200 | (objc:define-objcmethod (miniaturize "miniaturize:") :void 201 | (value :boolean)) 202 | 203 | (objc:define-objcmethod (deminiaturize "deminiaturize:") :void 204 | (value :boolean)) 205 | 206 | (objc:define-objcmethod (set-content-min-size "setContentMinSize:") :void 207 | (value (:struct size))) 208 | 209 | (objc:define-objcmethod (set-content-max-size "setContentMaxSize:") :void 210 | (value (:struct size))) 211 | 212 | (objc:define-objcmethod (make-key-and-order-front "makeKeyAndOrderFront:") :void 213 | (value :boolean)) 214 | 215 | (objc:define-objcmethod (style-mask "styleMask") style-mask) 216 | 217 | (objc:define-objcmethod (set-style-mask "setStyleMask:") :void 218 | (mask style-mask)) 219 | 220 | (objc:define-objcmethod (make-first-responder "makeFirstResponder:") :void 221 | (target :pointer)) 222 | 223 | (objc:define-objcmethod (set-collection-behavior "setCollectionBehavior:") :void 224 | (behavior collection-behavior)) 225 | 226 | (objc:define-objcmethod (set-level "setLevel:") :void 227 | (level :int32)) 228 | 229 | (objc:define-objcmethod (types "types") objc:cfarray) 230 | 231 | (objc:define-objcmethod (string-for-type "stringForType:") objc:nsstring 232 | (type :pointer)) 233 | 234 | (objc:define-objcmethod (declare-types "declareTypes:owner:") :void 235 | (types objc:cfarray) 236 | (owner :boolean)) 237 | 238 | (objc:define-objcmethod (set-string "setString") :void 239 | (string objc:nsstring) 240 | (for-type :pointer)) 241 | 242 | (objc:define-objcmethod (cgcontext "CGContext") :pointer) 243 | 244 | (objc:define-objcfun "NSGraphicsContext" (nsgraphicscontext-current-context "currentContext") :pointer) 245 | 246 | (cffi:defcfun (cg-display-bounds "CGDisplayBounds") (:struct rect) 247 | (display-id :uint32)) 248 | 249 | (cffi:defcfun (cg-main-display-id "CGMainDisplayID") :uint32) 250 | 251 | (cffi:defcfun (window-level-for-key "CGWindowLevelForKey") :int32 252 | (key window-level-key)) 253 | 254 | (cffi:defcfun (cg-color-space-create-device-rgb "CGColorSpaceCreateDeviceRGB") :pointer) 255 | 256 | (cffi:defcfun (cg-data-provider-create-with-data "CGDataProviderCreateWithData") :pointer 257 | (info :pointer) 258 | (data :pointer) 259 | (length :size) 260 | (release-callback :pointer)) 261 | 262 | (cffi:defcfun (cg-image-create "CGImageCreate") :pointer 263 | (width :size) 264 | (height :size) 265 | (channel-bits :size) 266 | (pixel-bits :size) 267 | (row-bytes :size) 268 | (color-space :pointer) 269 | (bitmap-info bitmap-info) 270 | (data-provider :pointer) 271 | (decoder :pointer) 272 | (should-interpolate :boolean) 273 | (intent rendering-intent)) 274 | 275 | (cffi:defcfun (cg-color-space-release "CGColorSpaceRelease") :void 276 | (space :pointer)) 277 | 278 | (cffi:defcfun (cg-data-provider-release "CGDataProviderRelease") :void 279 | (provider :pointer)) 280 | 281 | (cffi:defcfun (cg-context-draw-image "CGContextDrawImage") :void 282 | (context :pointer) 283 | (rect (:struct rect)) 284 | (image :pointer)) 285 | 286 | (cffi:defcfun (cg-image-release "CGImageRelease") :void 287 | (image :pointer)) 288 | 289 | (define-symbol-macro floating-window-level (window-level-for-key :floating)) 290 | 291 | (define-symbol-macro normal-window-level (window-level-for-key :normal)) 292 | 293 | (define-symbol-macro main-menu-window-level (window-level-for-key :main-menu)) 294 | 295 | (objc:define-objcmethod (modifier-flags "modifierFlags") modifier-flags) 296 | 297 | (objc:define-objcmethod (key-code "keyCode") :ushort) 298 | 299 | (objc:define-objcmethod (button-number "buttonNumber") objc:nsinteger) 300 | 301 | (objc:define-objcmethod (scrolling-delta-x "scrollingDeltaX") objc:cgfloat) 302 | 303 | (objc:define-objcmethod (scrolling-delta-y "scrollingDeltaY") objc:cgfloat) 304 | 305 | (objc:define-objcmethod (has-precise-scrolling-deltas "hasPreciseScrollingDeltas") :boolean) 306 | 307 | (objc:define-objcmethod (location-in-window "locationInWindow") (:struct point)) 308 | 309 | (objc:define-objcmethod (set-needs-display-in-rect "setNeedsDisplayInRect:") :void 310 | (rect (:struct rect))) 311 | -------------------------------------------------------------------------------- /xlib/keycodes.lisp: -------------------------------------------------------------------------------- 1 | (in-package #:org.shirakumo.framebuffers.xlib) 2 | 3 | (defvar *keytable* NIL) 4 | (defvar *codetable* (make-hash-table :test 'eq)) 5 | (defvar *stringtable* (make-hash-table :test 'eql)) 6 | 7 | ;; Fallback translation based on X11 keysyms 8 | (defun translate-keysym (a b) 9 | (or (case b 10 | (65456 :kp-0) 11 | (65457 :kp-1) 12 | (65458 :kp-2) 13 | (65459 :kp-3) 14 | (65460 :kp-4) 15 | (65461 :kp-5) 16 | (65462 :kp-6) 17 | (65463 :kp-7) 18 | (65464 :kp-8) 19 | (65465 :kp-9) 20 | (65452 :kp-decimal) 21 | (65454 :kp-decimal) 22 | (65469 :kp-equal) 23 | (65421 :kp-enter)) 24 | (case a 25 | (65307 :escape) 26 | (65289 :tab) 27 | (65505 :left-shift) 28 | (65506 :right-shift) 29 | (65507 :left-control) 30 | (65508 :right-control) 31 | (65511 :left-alt) 32 | (65513 :left-alt) 33 | (65406 :right-alt) 34 | (65027 :right-alt) 35 | (65512 :right-alt) 36 | (65514 :right-alt) 37 | (65515 :left-super) 38 | (65516 :right-super) 39 | (65383 :menu) 40 | (65407 :num-lock) 41 | (65509 :caps-lock) 42 | (65377 :print-screen) 43 | (65300 :scroll-lock) 44 | (65299 :pause) 45 | (65535 :delete) 46 | (65288 :backspace) 47 | (65293 :enter) 48 | (65360 :home) 49 | (65367 :end) 50 | (65365 :page-up) 51 | (65366 :page-down) 52 | (65379 :insert) 53 | (65361 :left) 54 | (65363 :right) 55 | (65364 :down) 56 | (65362 :up) 57 | (65470 :f1) 58 | (65471 :f2) 59 | (65472 :f3) 60 | (65473 :f4) 61 | (65474 :f5) 62 | (65475 :f6) 63 | (65476 :f7) 64 | (65477 :f8) 65 | (65478 :f9) 66 | (65479 :f10) 67 | (65480 :f11) 68 | (65481 :f12) 69 | (65482 :f13) 70 | (65483 :f14) 71 | (65484 :f15) 72 | (65485 :f16) 73 | (65486 :f17) 74 | (65487 :f18) 75 | (65488 :f19) 76 | (65489 :f20) 77 | (65490 :f21) 78 | (65491 :f22) 79 | (65492 :f23) 80 | (65493 :f24) 81 | (65494 :f25) 82 | (65455 :kp-divide) 83 | (65450 :kp-multiply) 84 | (65453 :kp-subtract) 85 | (65451 :kp-add) 86 | (65438 :kp-0) 87 | (65436 :kp-1) 88 | (65433 :kp-2) 89 | (65435 :kp-3) 90 | (65430 :kp-4) 91 | (65432 :kp-6) 92 | (65429 :kp-7) 93 | (65431 :kp-8) 94 | (65434 :kp-9) 95 | (65439 :kp-decimal) 96 | (65469 :kp-equal) 97 | (65421 :kp-enter) 98 | (97 :a) 99 | (98 :b) 100 | (99 :c) 101 | (100 :d) 102 | (101 :e) 103 | (102 :f) 104 | (103 :g) 105 | (104 :h) 106 | (105 :i) 107 | (106 :j) 108 | (107 :k) 109 | (108 :l) 110 | (109 :m) 111 | (110 :n) 112 | (111 :o) 113 | (112 :p) 114 | (113 :q) 115 | (114 :r) 116 | (115 :s) 117 | (116 :t) 118 | (117 :u) 119 | (118 :v) 120 | (119 :w) 121 | (120 :x) 122 | (121 :y) 123 | (122 :z) 124 | (49 :1) 125 | (50 :2) 126 | (51 :3) 127 | (52 :4) 128 | (53 :5) 129 | (54 :6) 130 | (55 :7) 131 | (56 :8) 132 | (57 :9) 133 | (48 :0) 134 | (32 :space) 135 | (45 :minus) 136 | (61 :equal) 137 | (91 :left-bracket) 138 | (93 :right-bracket) 139 | (92 :backslash) 140 | (59 :semicolon) 141 | (39 :apostrophe) 142 | (96 :grave-accent) 143 | (44 :comma) 144 | (46 :period) 145 | (47 :slash) 146 | (60 :world-1)))) 147 | 148 | (defun xkb-translate-name (name) 149 | (cond ((string= name "TLDE") :grave-accent) 150 | ((string= name "AE01") :1) 151 | ((string= name "AE02") :2) 152 | ((string= name "AE03") :3) 153 | ((string= name "AE04") :4) 154 | ((string= name "AE05") :5) 155 | ((string= name "AE06") :6) 156 | ((string= name "AE07") :7) 157 | ((string= name "AE08") :8) 158 | ((string= name "AE09") :9) 159 | ((string= name "AE10") :0) 160 | ((string= name "AE11") :minus) 161 | ((string= name "AE12") :equal) 162 | ((string= name "AD01") :q) 163 | ((string= name "AD02") :w) 164 | ((string= name "AD03") :e) 165 | ((string= name "AD04") :r) 166 | ((string= name "AD05") :t) 167 | ((string= name "AD06") :y) 168 | ((string= name "AD07") :u) 169 | ((string= name "AD08") :i) 170 | ((string= name "AD09") :o) 171 | ((string= name "AD10") :p) 172 | ((string= name "AD11") :left-bracket) 173 | ((string= name "AD12") :right-bracket) 174 | ((string= name "AC01") :a) 175 | ((string= name "AC02") :s) 176 | ((string= name "AC03") :d) 177 | ((string= name "AC04") :f) 178 | ((string= name "AC05") :g) 179 | ((string= name "AC06") :h) 180 | ((string= name "AC07") :j) 181 | ((string= name "AC08") :k) 182 | ((string= name "AC09") :l) 183 | ((string= name "AC10") :semicolon) 184 | ((string= name "AC11") :apostrophe) 185 | ((string= name "AB01") :z) 186 | ((string= name "AB02") :x) 187 | ((string= name "AB03") :c) 188 | ((string= name "AB04") :v) 189 | ((string= name "AB05") :b) 190 | ((string= name "AB06") :n) 191 | ((string= name "AB07") :m) 192 | ((string= name "AB08") :comma) 193 | ((string= name "AB09") :period) 194 | ((string= name "AB10") :slash) 195 | ((string= name "BKSL") :backslash) 196 | ((string= name "LSGT") :world-1) 197 | ((string= name "SPCE") :space) 198 | ((string= name "ESC") :escape) 199 | ((string= name "RTRN") :enter) 200 | ((string= name "TAB") :tab) 201 | ((string= name "BKSP") :backspace) 202 | ((string= name "INS") :insert) 203 | ((string= name "DELE") :delete) 204 | ((string= name "RGHT") :right) 205 | ((string= name "LEFT") :left) 206 | ((string= name "DOWN") :down) 207 | ((string= name "UP") :up) 208 | ((string= name "PGUP") :page-up) 209 | ((string= name "PGDN") :page-down) 210 | ((string= name "HOME") :home) 211 | ((string= name "END") :end) 212 | ((string= name "CAPS") :caps-lock) 213 | ((string= name "SCLK") :scroll-lock) 214 | ((string= name "NMLK") :num-lock) 215 | ((string= name "PRSC") :print-screen) 216 | ((string= name "PAUS") :pause) 217 | ((string= name "FK01") :f1) 218 | ((string= name "FK02") :f2) 219 | ((string= name "FK03") :f3) 220 | ((string= name "FK04") :f4) 221 | ((string= name "FK05") :f5) 222 | ((string= name "FK06") :f6) 223 | ((string= name "FK07") :f7) 224 | ((string= name "FK08") :f8) 225 | ((string= name "FK09") :f9) 226 | ((string= name "FK10") :f10) 227 | ((string= name "FK11") :f11) 228 | ((string= name "FK12") :f12) 229 | ((string= name "FK13") :f13) 230 | ((string= name "FK14") :f14) 231 | ((string= name "FK15") :f15) 232 | ((string= name "FK16") :f16) 233 | ((string= name "FK17") :f17) 234 | ((string= name "FK18") :f18) 235 | ((string= name "FK19") :f19) 236 | ((string= name "FK20") :f20) 237 | ((string= name "FK21") :f21) 238 | ((string= name "FK22") :f22) 239 | ((string= name "FK23") :f23) 240 | ((string= name "FK24") :f24) 241 | ((string= name "FK25") :f25) 242 | ((string= name "KP0") :kp-0) 243 | ((string= name "KP1") :kp-1) 244 | ((string= name "KP2") :kp-2) 245 | ((string= name "KP3") :kp-3) 246 | ((string= name "KP4") :kp-4) 247 | ((string= name "KP5") :kp-5) 248 | ((string= name "KP6") :kp-6) 249 | ((string= name "KP7") :kp-7) 250 | ((string= name "KP8") :kp-8) 251 | ((string= name "KP9") :kp-9) 252 | ((string= name "KPDL") :kp-decimal) 253 | ((string= name "KPDV") :kp-divide) 254 | ((string= name "KPMU") :kp-multiply) 255 | ((string= name "KPSU") :kp-subtract) 256 | ((string= name "KPAD") :kp-add) 257 | ((string= name "KPEN") :kp-enter) 258 | ((string= name "KPEQ") :kp-equal) 259 | ((string= name "LFSH") :left-shift) 260 | ((string= name "LCTL") :left-control) 261 | ((string= name "LALT") :left-alt) 262 | ((string= name "LWIN") :left-super) 263 | ((string= name "RTSH") :right-shift) 264 | ((string= name "RCTL") :right-control) 265 | ((string= name "RALT") :right-alt) 266 | ((string= name "LVL3") :right-alt) 267 | ((string= name "MDSW") :right-alt) 268 | ((string= name "RWIN") :right-super) 269 | ((string= name "MENU") :menu))) 270 | 271 | (defun xkb-lookup-key (desc i) 272 | (let* ((names (xlib:xkb-desc-names desc)) 273 | (aliases (xlib:xkb-names-key-aliases names)) 274 | (name (cffi:foreign-string-to-lisp (cffi:mem-aptr (xlib:xkb-names-keys names) '(:struct xlib:xkb-key) i) :max-chars 4))) 275 | (or (xkb-translate-name name) 276 | (dotimes (i (xlib:xkb-names-num-key-aliases names)) 277 | (let ((alias (cffi:mem-aptr aliases '(:struct xlib:xkb-alias) i))) 278 | (when (string= name (cffi:foreign-string-to-lisp alias :max-chars 4)) 279 | (let ((transl (xkb-translate-name (cffi:foreign-string-to-lisp alias :offset 4 :max-chars 4)))) 280 | (when transl (return transl))))))))) 281 | 282 | (defun init-keytable (display xkb) 283 | (let ((array (make-array 256)) 284 | (table (make-hash-table :test 'eq)) 285 | (min 0) (max 0)) 286 | (cond (xkb 287 | (let ((desc (xlib:xkb-get-map display 0 #x100))) 288 | (xlib:xkb-get-names display (logior (ash 1 9) (ash 1 10)) desc) 289 | (setf min (xlib:xkb-desc-min-key-code desc)) 290 | (setf max (xlib:xkb-desc-max-key-code desc)) 291 | (loop for i from min to max 292 | do (setf (aref array i) (xkb-lookup-key desc i))) 293 | (xlib:xkb-free-names desc (ash 1 9) T) 294 | (xlib:xkb-free-keyboard desc 0 T))) 295 | (T 296 | (cffi:with-foreign-objects ((minptr :uchar) (maxptr :uchar)) 297 | (xlib:display-keycodes display minptr maxptr) 298 | (setf min (cffi:mem-ref minptr :uchar)) 299 | (setf max (cffi:mem-ref maxptr :uchar))))) 300 | (cffi:with-foreign-objects ((widthptr :int)) 301 | (let ((keysyms (xlib:get-keyboard-mapping display min (1+ (- max min)) widthptr)) 302 | (width (cffi:mem-ref widthptr :int))) 303 | (loop for i from min to max 304 | do (unless (aref array i) 305 | (let ((base (* width (- i min)))) 306 | (setf (aref array i) (translate-keysym (cffi:mem-aref keysyms :int base) 307 | (when (< 1 width) 308 | (cffi:mem-aref keysyms :int (1+ base)))))))) 309 | (xlib:free keysyms))) 310 | (loop for i from 0 below (length array) 311 | for key = (aref array i) 312 | do (when key (setf (gethash key table) i))) 313 | (setf *keytable* array) 314 | (setf *codetable* table))) 315 | 316 | (defun make-stringtable (&optional (table (make-hash-table :test 'eql))) 317 | (with-open-file (file (fb-int:static-file "xlib/keysyms.txt")) 318 | (loop for keysym = (read file NIL) 319 | for codepoint = (read file NIL) 320 | while keysym 321 | do (setf (gethash keysym table) (string (code-char codepoint)))) 322 | table)) 323 | 324 | (make-stringtable) 325 | 326 | (defun translate-keycode (code) 327 | (when (<= 0 code 255) 328 | (aref *keytable* code))) 329 | 330 | (defun keysym-string (code) 331 | (cond ((= #x1000000 (logand code #xff000000)) 332 | (string (code-char (logand code #xffffff)))) 333 | (T 334 | (gethash code *stringtable*)))) 335 | 336 | (defun key-code (key) 337 | (gethash key *codetable*)) 338 | -------------------------------------------------------------------------------- /cocoa/wrapper.lisp: -------------------------------------------------------------------------------- 1 | (in-package #:org.shirakumo.framebuffers.cocoa) 2 | 3 | (pushnew :cocoa fb-int:*available-backends*) 4 | 5 | (define-condition cocoa-error (fb:framebuffer-error objc:foundation-error) 6 | ()) 7 | 8 | (cffi:defcallback %foundation-error :void ((exception :pointer)) 9 | (objc:foundation-error exception 'cocoa-error)) 10 | 11 | (defmethod fb-int:init-backend ((backend (eql :cocoa))) 12 | (objc:init) 13 | (org.shirakumo.cocoas.cffi:set-uncaught-exception-handler 14 | (cffi:callback '%foundation-error))) 15 | 16 | (defmethod fb-int:shutdown-backend ((backend (eql :cocoa))) 17 | (objc:shutdown)) 18 | 19 | (defmethod fb-int:open-backend ((backend (eql :cocoa)) &key size location title (visible-p T)) 20 | (cocoa:nsapplication-shared-application) 21 | (cocoa:nsapp-set-activation-policy :regular) 22 | (let* ((screen (cocoa:frame (cocoa:nsscreen-main-screen))) 23 | (w (or (car size) (cocoa:rect-w screen))) 24 | (h (or (cdr size) (cocoa:rect-h screen))) 25 | (x (or (car location) (truncate (- (cocoa:rect-w screen) w) 2))) 26 | (y (or (cdr location) (truncate (- (cocoa:rect-h screen) h) 2))) 27 | (rect (cocoa:make-rect x y w h)) 28 | (window (cocoa:init-with-content-rect (cocoa:alloc "FBWindow") rect '(:closable :titled) :buffered NIL))) 29 | (make-instance 'window :ptr window 30 | :size (cons w h) 31 | :location (cons x y) 32 | :title (or title (fb-int:default-title))))) 33 | 34 | (defmacro define-objc-class (name super &body methods) 35 | `(objc::define-objc-class ,name ,super 36 | ,@(loop for (name rettype args . body) in methods 37 | collect `(,name ,rettype ,args 38 | (let ((window (fb-int:ptr-window self))) 39 | (declare (ignorable window)) 40 | ,@body))))) 41 | 42 | (trivial-indent:define-indentation define-objc-class 43 | (4 4 &rest (&whole 2 6 6 &body))) 44 | 45 | (define-objc-class "FBWindow" "NSWindow" 46 | (can-become-key-window :bool () 47 | T) 48 | 49 | (can-become-main-window :bool () 50 | T) 51 | 52 | (window-should-close/ :bool ((sender :id)) 53 | (fb:window-closed window) 54 | NIL) 55 | 56 | (window-did-resize/ :void ((notification :pointer)) 57 | (let ((max (cocoa:is-zoomed self))) 58 | (unless (eql max (fb:maximized-p window)) 59 | (fb:window-maximized window max))) 60 | (objc:with-objects ((content-rect (cocoa:frame (view window))) 61 | (rect (cocoa:convert-rect-to-backing (view window) content-rect))) 62 | (fb:window-resized window (cocoa:rect-w rect) (cocoa:rect-h rect)))) 63 | 64 | (window-did-move/ :void ((notification :pointer)) 65 | (objc:with-objects ((rect (cocoa:content-rect-for-frame-rect self (cocoa:frame self)))) 66 | (fb:window-moved window 67 | (cocoa:rect-x rect) 68 | (tf-y (+ (cocoa:rect-y rect) (cocoa:rect-h rect) -1))))) 69 | 70 | (window-did-miniaturize/ :void ((notification :pointer)) 71 | (fb:window-iconified window T)) 72 | 73 | (window-did-deminiaturize/ :void ((notification :pointer)) 74 | (fb:window-iconified window NIL)) 75 | 76 | (window-did-become-key/ :void ((notification :pointer)) 77 | (fb:window-focused window T)) 78 | 79 | (window-did-resign-key/ :void ((notification :pointer)) 80 | (fb:window-focused window NIL))) 81 | 82 | (defun mouse-move (window event) 83 | (let ((rect (cocoa:frame (view window))) 84 | (pos (cocoa:location-in-window event))) 85 | (fb:mouse-moved window (cocoa:point-x pos) (- (cocoa:rect-h rect) (cocoa:point-y pos))))) 86 | 87 | (define-objc-class "FBContentView" "NSView" 88 | (can-become-key-view :bool () 89 | T) 90 | 91 | (accepts-first-responder :bool () 92 | T) 93 | 94 | (wants-update-layer :bool () 95 | T) 96 | 97 | (accepts-first-mouse/ :bool ((event :pointer)) 98 | T) 99 | 100 | (update-layer :void () 101 | (fb:window-refreshed window)) 102 | 103 | (cursor-update/ :void ((event :pointer))) 104 | 105 | (mouse-down/ :void ((event :pointer)) 106 | (fb:mouse-button-changed window :left :press (cocoa:modifier-flags event))) 107 | 108 | (mouse-up/ :void ((event :pointer)) 109 | (fb:mouse-button-changed window :left :release (cocoa:modifier-flags event))) 110 | 111 | (right-mouse-down/ :void ((event :pointer)) 112 | (fb:mouse-button-changed window :right :press (cocoa:modifier-flags event))) 113 | 114 | (right-mouse-up/ :void ((event :pointer)) 115 | (fb:mouse-button-changed window :right :release (cocoa:modifier-flags event))) 116 | 117 | (other-mouse-down/ :void ((event :pointer)) 118 | (fb:mouse-button-changed window (cocoa:button-number event) :press (cocoa:modifier-flags event))) 119 | 120 | (other-mouse-up/ :void ((event :pointer)) 121 | (fb:mouse-button-changed window (cocoa:button-number event) :release (cocoa:modifier-flags event))) 122 | 123 | (mouse-moved/ :void ((event :pointer)) 124 | (mouse-move window event)) 125 | 126 | (mouse-dragged/ :void ((event :pointer)) 127 | (mouse-move window event)) 128 | 129 | (right-mouse-dragged/ :void ((event :pointer)) 130 | (mouse-move window event)) 131 | 132 | (other-mouse-dragged/ :void ((event :pointer)) 133 | (mouse-move window event)) 134 | 135 | (mouse-entered/ :void ((event :pointer)) 136 | (fb:mouse-entered window T)) 137 | 138 | (mouse-exited/ :void ((event :pointer)) 139 | (fb:mouse-entered window NIL)) 140 | 141 | (scroll-wheel/ :void ((event :pointer)) 142 | (let ((dx (cocoa:scrolling-delta-x event)) 143 | (dy (cocoa:scrolling-delta-y event))) 144 | (when (cocoa:has-precise-scrolling-deltas event) 145 | (setf dx (/ dx 10)) 146 | (setf dy (/ dy 10))) 147 | (when (or (< 0 dx) (< 0 dy)) 148 | (fb:mouse-scrolled window dx dy)))) 149 | 150 | (view-did-change-backing-properties :void ()) 151 | 152 | (draw-rect/ :void ((rect :pointer)) 153 | (fb:window-refreshed window)) 154 | 155 | (key-down/ :void ((event :pointer)) 156 | (let ((code (cocoa:key-code event))) 157 | (fb:key-changed window (translate-key code) code :press (cocoa:modifier-flags event)))) 158 | 159 | (key-up/ :void ((event :pointer)) 160 | (let ((code (cocoa:key-code event))) 161 | (fb:key-changed window (translate-key code) code :release (cocoa:modifier-flags event)))) 162 | 163 | (flags-changed/ :void ((event :pointer))) 164 | 165 | (update-tracking-areas :void ()) 166 | 167 | (dragging-entered/ :id ((sender :id))) 168 | 169 | (perform-drag-operation/ :bool ((sender :id))) 170 | 171 | (has-marked-text :bool ()) 172 | 173 | (marked-range :id ()) 174 | 175 | (selected-range :id ()) 176 | 177 | (set-marked-text/selected-range/replacement-range/ :void ((string :id) (selected-range :id) (replacement-range :id))) 178 | 179 | (unmark-text :void ()) 180 | 181 | (valid-attributes-for-marked-text objc:cfarray () 182 | ()) 183 | 184 | (attributed-substring-for-proposed-range/actual-range/ :pointer ((range :id) (actual-range :pointer)) 185 | (cffi:null-pointer)) 186 | 187 | (character-index-for-point :uint ((point :id)) 188 | 0) 189 | 190 | (first-rect-for-character-range/actual-range/ :pointer ((range :id) (actual-range :pointer))) 191 | 192 | (insert-text/replacement-range/ :void ((string :id) (replacement-range :id))) 193 | 194 | (do-command-by-selector/ :void ((selector :sel)))) 195 | 196 | (defclass window (fb:window) 197 | ((ptr :initarg :ptr :initform NIL :accessor ptr) 198 | (view :initarg :view :initform NIL :accessor view) 199 | (buffer :initarg :buffer :initform NIL :reader fb:buffer :accessor buffer))) 200 | 201 | (defmethod initialize-instance :after ((window window) &key) 202 | (let ((ptr (ptr window)) 203 | (view (cocoa:init (cocoa:alloc "FBContentView")))) 204 | (setf (fb-int:ptr-window ptr) window) 205 | (setf (fb-int:ptr-window view) window) 206 | (cocoa:set-release-when-closed ptr NIL) 207 | (cocoa:set-opaque ptr T) 208 | (cocoa:set-background-color ptr (cocoa:nscolor-clear-color)) 209 | (cocoa:set-accepts-mouse-moved-events ptr T) 210 | (cocoa:set-title ptr (fb:title window)) 211 | (cocoa:set-content-view ptr view) 212 | (cocoa:make-first-responder-view ptr view) 213 | (cocoa:nsapp-activate-ignoring-other-apps T))) 214 | 215 | (defmethod fb:valid-p ((window window)) 216 | (not (null (ptr window)))) 217 | 218 | (defmethod fb:close ((window window)) 219 | (setf (fb-int:ptr-window (ptr window)) NIL) 220 | (setf (fb-int:ptr-window (view window)) NIL) 221 | (fb-int:clean window view objc:release) 222 | (fb-int:clean window ptr cocoa:close) 223 | (loop while (objc:process-event))) 224 | 225 | (defun tf-y (y) 226 | (- (cocoa:rect-h (cocoa:cg-display-bounds (cocoa:cg-main-display-id))) y 1)) 227 | 228 | (defmethod (setf fb:size) (size (window window)) 229 | (objc:with-objects ((rect (cocoa:content-rect-for-frame-rect (ptr window) (cocoa:frame (ptr window))))) 230 | (incf (cocoa:rect-y rect) (- (cocoa:rect-h rect) (cdr size))) 231 | (setf (cocoa:rect-w rect) (car size)) 232 | (setf (cocoa:rect-h rect) (cdr size)) 233 | (cocoa:set-frame (ptr window) (cocoa:frame-rect-for-content-rect (ptr window) rect) T))) 234 | 235 | (defmethod (setf fb:location) (location (window window)) 236 | (objc:with-objects ((rect (cocoa:frame (view window))) 237 | (dummy (cocoa:make-rect (car location) (tf-y (+ (cdr location) (cocoa:rect-h rect) -1)) 0 0)) 238 | (frame (cocoa:frame-rect-for-content-rect (ptr window) dummy))) 239 | (cocoa:set-frame-origin (ptr window) (cocoa:rect frame)))) 240 | 241 | (defmethod (setf fb:title) (title (window window)) 242 | (cocoa:set-title (ptr window) title) 243 | (cocoa:set-miniwindow-title (ptr window) title) 244 | (setf (fb-int:title window) title)) 245 | 246 | (defmethod (setf fb:visible-p) (state (window window)) 247 | (if state 248 | (cocoa:order-front (ptr window) NIL) 249 | (cocoa:order-out (ptr window) NIL)) 250 | (setf (fb-int:visible-p window) state)) 251 | 252 | (defmethod (setf fb:maximized-p) (state (window window)) 253 | (unless (eq state (fb-int:maximized-p window)) 254 | (cocoa:zoom (ptr window) NIL) 255 | (setf (fb-int:iconified-p window) state)) 256 | state) 257 | 258 | (defmethod (setf fb:iconified-p) (state (window window)) 259 | (when state 260 | (cocoa:miniaturize (ptr window) NIL) 261 | (setf (fb-int:iconified-p window) state)) 262 | state) 263 | 264 | (defmethod (setf fb:minimum-size) (value (window window)) 265 | (objc:with-objects ((size (cocoa:make-size (max 1 (or (car value) 0)) 266 | (max 1 (or (cdr value) 0))))) 267 | (cocoa:set-content-min-size (ptr window) size) 268 | (setf (car (fb:minimum-size window)) (max 1 (or (car value) 0))) 269 | (setf (cdr (fb:minimum-size window)) (max 1 (or (cdr value) 0))) 270 | value)) 271 | 272 | (defmethod (setf fb:maximum-size) (value (window window)) 273 | (objc:with-objects ((size (cocoa:make-size (or (car value) most-positive-double-float) 274 | (or (cdr value) most-positive-double-float)))) 275 | (cocoa:set-content-max-size (ptr window) size) 276 | (setf (car (fb:maximum-size window)) (car value)) 277 | (setf (cdr (fb:maximum-size window)) (cdr value)) 278 | value)) 279 | 280 | (defmethod (setf fb:focused-p) (value (window window)) 281 | (when value 282 | (cocoa:nsapp-activate-ignoring-other-apps T) 283 | (cocoa:make-key-and-order-front (ptr window) NIL) 284 | (setf (fb-int:focused-p window) value)) 285 | value) 286 | 287 | (defmethod (setf fb:borderless-p) (value (window window)) 288 | (let ((mask (cocoa:style-mask (ptr window)))) 289 | (setf mask (if value 290 | (set-union '(:borderless) (set-difference mask '(:titled :closable))) 291 | (set-union '(:titled :closable) (set-difference mask '(:borderless))))) 292 | (cocoa:set-style-mask (ptr window) mask)) 293 | (cocoa:make-first-responder (ptr window) (view window)) 294 | (setf (fb-int:floating-p window) value)) 295 | 296 | (defmethod (setf fb:always-on-top-p) (value (window window)) 297 | ;; TODO: implement always-on-top-p 298 | ) 299 | 300 | (defmethod (setf fb:resizable-p) (value (window window)) 301 | (let ((mask (cocoa:style-mask (ptr window)))) 302 | (setf mask (if value 303 | (set-difference mask '(:resizable)) 304 | (set-union mask '(:resizable)))) 305 | (cocoa:set-style-mask (ptr window) mask) 306 | (cocoa:set-collection-behavior (ptr window) (if value '(:full-screen-primary :managed) '(:full-screen-none))))) 307 | 308 | (defmethod (setf fb:floating-p) (value (window window)) 309 | (cocoa:set-level (ptr window) (if value :floating-window-level :normal-window-level)) 310 | (setf (fb-int:floating-p window) value)) 311 | 312 | (defmethod fb:clipboard ((window window)) 313 | (objc:with-objects ((pasteboard (cocoa:nspasteboard-general-pasteboard))) 314 | (loop for type across (cocoa:types pasteboard) 315 | do (cond ((cffi:pointer-eq type cocoa:paste-string) 316 | (return (cocoa:string-for-type pasteboard cocoa:paste-string))))))) 317 | 318 | (defmethod (setf fb:clipboard) ((string string) (window window)) 319 | (objc:with-objects ((pasteboard (cocoa:nspasteboard-general-pasteboard))) 320 | (cocoa:declare-types pasteboard (list cocoa:paste-string) NIL) 321 | (cocoa:set-string pasteboard string cocoa:paste-string))) 322 | 323 | (defmethod (setf fb:icon) ((value null) (window window)) 324 | ;; TODO: implement icon 325 | ) 326 | 327 | (defmethod (setf fb:icon) ((value fb:icon) (window window)) 328 | ;; TODO: implement icon 329 | ) 330 | 331 | (defmethod (setf fb:cursor-icon) ((value symbol) (window window)) 332 | ;; TODO: implement cursor-icon 333 | ) 334 | 335 | (defmethod (setf fb:cursor-icon) ((value fb:icon) (window window)) 336 | ;; TODO: implement cursor-icon 337 | ) 338 | 339 | (defmethod (setf fb:cursor-state) (value (window window)) 340 | ;; TODO: implement cursor-state 341 | ) 342 | 343 | (defmethod key-scan-code (key (window window)) 344 | ;; TODO: key-scan-code 345 | ) 346 | 347 | (defmethod local-key-string (key (window window)) 348 | ;; TODO: local-key-string 349 | ) 350 | 351 | (defmethod fb:swap-buffers ((window window) &key (x 0) (y 0) (w (fb:width window)) (h (fb:height window)) sync) 352 | (let ((rect (cocoa:make-rect x y w h))) 353 | (destructuring-bind (w . h) (fb:size window) 354 | (let* ((buffer (fb:buffer window)) 355 | (context (cocoa:cgcontext (cocoa:nsgraphicscontext-current-context))) 356 | (space (cocoa:cg-color-space-create-device-rgb)) 357 | (provider (cocoa:cg-data-provider-create-with-data (cffi:null-pointer) 358 | (static-vectors:static-vector-pointer buffer) 359 | (length buffer) 360 | (cffi:null-pointer))) 361 | (image (cocoa:cg-image-create w h 8 32 (* w 4) space '(:none-skip-first :byte-order-32-little) provider (cffi:null-pointer) NIL :default))) 362 | (cocoa:cg-color-space-release space) 363 | (cocoa:cg-data-provider-release provider) 364 | (cocoa:cg-context-draw-image context rect image) 365 | (cocoa:cg-image-release image) 366 | (cocoa:set-needs-display-in-rect (view window) rect))))) 367 | 368 | (defmethod fb-int:wait-for-events ((backend (eql :cocoa)) windows &key timeout) 369 | ;; TODO: implement wait-for-events 370 | ) 371 | 372 | (defmethod fb:process-events ((window window) &key timeout) 373 | (let ((s (etypecase timeout 374 | ((eql T) 1.0d0) 375 | (real (float timeout 0d0)) 376 | (null 0.0d0)))) 377 | (loop while (and (ptr window) (not (fb:close-requested-p window))) 378 | do (objc:process-event :timeout s) 379 | (loop while (objc:process-event)) 380 | (unless (eql T timeout) 381 | (return))))) 382 | 383 | (defmethod fb:request-attention ((window window)) 384 | (cocoa:nsapp-request-user-attention :informational-request)) 385 | 386 | (defmethod fb:set-timer ((window window) delay &key repeat) 387 | ;; TODO: implement set-timer 388 | ) 389 | 390 | (defmethod fb:cancel-timer ((window window) timer) 391 | ;; TODO: implement cancel-timer 392 | ) 393 | 394 | (defmethod fb:display ((window window)) 395 | (typecase (fb:fullscreen-p window) 396 | (null (call-next-method)) 397 | (display (fb:fullscreen-p window)) 398 | (video-mode (fb:display (fb:fullscreen-p window))))) 399 | 400 | (defmethod fb-int:list-displays-backend ((backend (eql :cocoa))) 401 | ;; TODO: implement list-displays-backend 402 | ) 403 | 404 | (defclass display (fb:display) 405 | ()) 406 | 407 | (defstruct (video-mode (:include fb:video-mode))) 408 | 409 | (defmethod fb:video-modes ((display display)) 410 | ;; TODO: implement video-modes 411 | ) 412 | 413 | (defmethod fb:video-mode ((display display)) 414 | ;; TODO: implement video-mode 415 | ) 416 | 417 | (defmethod (setf fb:fullscreen-p) ((value null) (window window)) 418 | ;; TODO: implement fullscreen-p 419 | ) 420 | 421 | (defmethod (setf fb:fullscreen-p) ((value fb:video-mode) (window window)) 422 | ;; TODO: implement fullscreen-p 423 | ) 424 | -------------------------------------------------------------------------------- /mezzano/wrapper.lisp: -------------------------------------------------------------------------------- 1 | (in-package #:org.shirakumo.framebuffers.mezzano) 2 | 3 | (defvar *default-display* NIL) 4 | 5 | (pushnew :mezzano fb-int:*available-backends*) 6 | 7 | (define-condition mezzano-error (fb:framebuffer-error) 8 | ((original-error :initarg :original-error :reader original-error)) 9 | (:report (lambda (c s) (format s "~a" (original-error c))))) 10 | 11 | (defmacro with-resignalling (&body body) 12 | `(handler-bind ((error 13 | (lambda (e) 14 | (error 'mezzano-error :original-error e)))) 15 | ,@body)) 16 | 17 | (defmethod fb-int:init-backend ((backend (eql :mezzano))) 18 | (unless *default-display* 19 | (multiple-value-bind (w h) (mezzano.gui.compositor::screen-dimensions) 20 | (let ((mode (make-video-mode :width w :height h :refresh-rate 60))) 21 | (setf *default-display* (make-instance 'display 22 | :primary-p T 23 | :title "Default" 24 | :id "-" 25 | :size (cons w h) 26 | :video-mode mode 27 | :video-modes (list mode))))))) 28 | 29 | (defmethod fb-int:shutdown-backend ((backend (eql :mezzano)))) 30 | 31 | (defmethod fb-int:open-backend ((backend (eql :mezzano)) &rest args &key size location &allow-other-keys) 32 | (with-resignalling 33 | (multiple-value-bind (w h) (mezzano.gui.compositor::screen-dimensions) 34 | ;; First force an update to the display to ensure we catch missing events 35 | (let ((x (or (car location) (truncate (- w (or (car size) w)) 2))) 36 | (y (or (cdr location) (truncate (- h (or (cdr size) h)) 2)))) 37 | (apply #'make-instance 'window 38 | :mailbox (mezzano.supervisor:make-fifo 50) 39 | :thread (mezzano.supervisor:current-thread) 40 | :buffer (mezzano.gui:make-surface w h) 41 | :size (or size (cons w h)) 42 | :location (cons x y) 43 | :x x :y y 44 | args))))) 45 | 46 | (defmethod fb-int:list-displays-backend ((backend (eql :mezzano))) 47 | (list *default-display*)) 48 | 49 | (defclass window (fb:window mezzano.gui.compositor:window) 50 | ((buffer :initform NIL :reader fb:buffer :accessor buffer) 51 | (original-size :initform (cons NIL NIL) :accessor original-size) 52 | (original-location :initform (cons NIL NIL) :accessor original-location) 53 | (frame :initform NIL :accessor frame) 54 | (timers :initform () :accessor timers))) 55 | 56 | (defmethod initialize-instance :after ((window window) &key title) 57 | (setf (frame window) (make-instance 'mezzano.gui.widgets:frame 58 | :framebuffer (mezzano.gui.compositor:window-buffer window) 59 | :title (or title (fb-int:default-title)) 60 | :close-button-p T 61 | :resizablep (fb:resizable-p window) 62 | :damage-function (mezzano.gui.widgets:default-damage-function window) 63 | :set-cursor-function (mezzano.gui.widgets:default-cursor-function window))) 64 | (mezzano.gui.compositor::submit-compositor-event (make-instance 'mezzano.gui.compositor:window-create-event 65 | :window window 66 | :initial-z-order :top)) 67 | (update-buffer window (fb:width window) (fb:height window)) 68 | ;; KLUDGE: Mezzano does not seem to place the window right by default, so move it now. 69 | (setf (fb:location window) (fb:location window))) 70 | 71 | (defun update-buffer (window w h) 72 | (with-resignalling 73 | (multiple-value-bind (left right top bottom) (if (or (fb:fullscreen-p window) 74 | (fb:borderless-p window)) 75 | (values 0 0 0 0) 76 | (mezzano.gui.widgets:frame-size (frame window))) 77 | (let ((new-framebuffer (mezzano.gui:make-surface (+ w left right) (+ h top bottom)))) 78 | (mezzano.gui.widgets:resize-frame (frame window) new-framebuffer) 79 | (mezzano.gui.compositor:resize-window window new-framebuffer))) 80 | (setf (buffer window) (fb-int:resize-buffer w h (buffer window) (fb:width window) (fb:height window))) 81 | (setf (car (fb-int:size window)) w) 82 | (setf (cdr (fb-int:size window)) h))) 83 | 84 | (defmethod fb:valid-p ((window window)) 85 | (not (null (frame window)))) 86 | 87 | (defmethod fb:close ((window window)) 88 | (mezzano.gui.compositor:close-window window) 89 | (setf (frame window) NIL)) 90 | 91 | (defmethod (setf fb:size) (new-size (window window)) 92 | (unless (equal new-size (fb:size window)) 93 | (update-buffer window (car new-size) (cdr new-size)) 94 | (fb:window-resized window (car new-size) (cdr new-size)) 95 | (fb:window-refreshed window)) 96 | new-size) 97 | 98 | (defmethod (setf fb:location) (location (window window)) 99 | (mezzano.gui.compositor:move-window window (car location) (cdr location))) 100 | 101 | (defmethod (setf fb:title) (title (window window)) 102 | (setf (mezzano.gui.widgets:frame-title (frame window)) title) 103 | (setf (fb-int:title window) title)) 104 | 105 | (defmethod (setf fb:visible-p) (state (window window)) 106 | ;; TODO: implement visible-p 107 | ) 108 | 109 | (defmethod (setf fb:maximized-p) (state (window window)) 110 | state) 111 | 112 | (defmethod (setf fb:iconified-p) (state (window window)) 113 | state) 114 | 115 | (defmethod (setf fb:minimum-size) (value (window window)) 116 | (setf (car (fb:minimum-size window)) (max 0 (car value))) 117 | (setf (cdr (fb:minimum-size window)) (max 0 (cdr value)))) 118 | 119 | (defmethod (setf fb:maximum-size) (value (window window)) 120 | (setf (car (fb:maximum-size window)) (car value)) 121 | (setf (cdr (fb:maximum-size window)) (cdr value))) 122 | 123 | (defmethod (setf fb:focused-p) (value (window window)) 124 | (when value 125 | (mezzano.gui.compositor::activate-window window)) 126 | value) 127 | 128 | (defmethod (setf fb:borderless-p) (value (window window)) 129 | (unless (eq value (fb:borderless-p window)) 130 | ;; FIXME: nudge the window position to keep the center frame position intact 131 | (setf (fb-int:borderless-p window) value) 132 | (update-buffer window (fb:width window) (fb:height window)) 133 | ) 134 | value) 135 | 136 | (defmethod (setf fb:always-on-top-p) (value (window window)) 137 | value) 138 | 139 | (defmethod (setf fb:resizable-p) (value (window window)) 140 | (setf (mezzano.gui.widgets::resizablep (frame window)) value) 141 | (setf (fb-int:resizable-p window) value)) 142 | 143 | (defmethod (setf fb:floating-p) (value (window window)) 144 | value) 145 | 146 | (defmethod (setf fb:fullscreen-p) ((value null) (window window)) 147 | (when (fb:fullscreen-p window) 148 | (setf (fb-int:fullscreen-p window) value) 149 | (setf (fb:size window) (original-size window)) 150 | (setf (fb:location window) (original-location window))) 151 | value) 152 | 153 | (defmethod (setf fb:fullscreen-p) ((value fb:video-mode) (window window)) 154 | (unless (fb:fullscreen-p window) 155 | (setf (fb-int:fullscreen-p window) value) 156 | (setf (car (original-location window)) (car (fb:location window))) 157 | (setf (cdr (original-location window)) (cdr (fb:location window))) 158 | (setf (fb:location window) (cons 0 0)) 159 | (setf (car (original-size window)) (car (fb:size window))) 160 | (setf (cdr (original-size window)) (cdr (fb:size window))) 161 | (setf (fb:size window) (fb:size value))) 162 | value) 163 | 164 | (defmethod fb:clipboard ((window window))) 165 | 166 | (defmethod (setf fb:clipboard) ((string string) (window window)) 167 | string) 168 | 169 | (defmethod (setf fb:icon) ((value null) (window window)) 170 | value) 171 | 172 | (defmethod (setf fb:icon) ((value fb:icon) (window window)) 173 | value) 174 | 175 | (defmethod (setf fb:cursor-icon) ((value symbol) (window window)) 176 | ;; TODO: implement cursor-icon 177 | ) 178 | 179 | (defmethod (setf fb:cursor-icon) ((value fb:icon) (window window)) 180 | ;; TODO: implement cursor-icon 181 | ) 182 | 183 | (defmethod (setf fb:cursor-state) (value (window window)) 184 | (setf (fb-int:cursor-state window) value)) 185 | 186 | (defmethod key-scan-code (key (window window)) 187 | (gethash key *codetable*)) 188 | 189 | (defmethod local-key-string (key (window window)) 190 | (string (mezzano.gui.compositor::convert-scancode-to-key 191 | mezzano.gui.compositor::*current-keymap* 192 | key ()))) 193 | 194 | (defmethod fb:swap-buffers ((window window) &key (x 0) (y 0) (w (fb:width window)) (h (fb:height window)) sync) 195 | (multiple-value-bind (left right top bottom) (if (or (fb:fullscreen-p window) 196 | (fb:borderless-p window)) 197 | (values 0 0 0 0) 198 | (mezzano.gui.widgets:frame-size (frame window))) 199 | (declare (ignore right bottom sync)) 200 | ;; We have to re-encode to copy into the framebuffer. Very sad. 201 | ;; However, we have to ignore the frame borders unless we're borderless 202 | ;; anyway so copying is kinda mandatory. OH WELL. At least let's try to 203 | ;; do it semi-intelligently. 204 | (loop with src = (fb:buffer window) 205 | with dst = (mezzano.gui:surface-pixels (mezzano.gui.compositor:window-buffer window)) 206 | with srow-gap of-type (unsigned-byte 16) = (* 4 (- (fb:width window) w)) 207 | with si of-type (unsigned-byte 16) = (+ (* 4 x) (* y srow-gap)) 208 | for yi of-type (unsigned-byte 16) from y below (+ y h) 209 | do (loop for xi of-type (unsigned-byte 16) from x below (+ x w) 210 | for px = (aref src (+ si 0)) 211 | do (setf (ldb (byte 8 8) px) (aref src (+ si 1))) 212 | (setf (ldb (byte 8 16) px) (aref src (+ si 2))) 213 | (setf (ldb (byte 8 24) px) (aref src (+ si 3))) 214 | (setf (aref dst (+ yi top) (+ xi left)) px) 215 | (incf si 4)) 216 | (incf si srow-gap)) 217 | (mezzano.gui.compositor:damage-window window (+ x left) (+ y top) w h))) 218 | 219 | (defmethod fb-int:wait-for-events ((backend (eql :mezzano)) windows &key timeout) 220 | (let ((secs (etypecase timeout 221 | (real timeout) 222 | ((eql T) 1.0) 223 | (null 0.0))) 224 | (handles (loop for window in windows 225 | append (list* (mezzano.gui.compositor::mailbox window) (timers window)))) 226 | (found ())) 227 | (loop (dolist (handle (apply #'mezzano.sync:wait-for-objects-with-timeout secs handles)) 228 | (dolist (window windows) 229 | (when (or (eql fd (mezzano.gui.compositor::mailbox window)) 230 | (find fd (timers window))) 231 | (push window found)))) 232 | (when (or found (not (eql T timeout))) 233 | (return found))))) 234 | 235 | (defmethod fb:process-events ((window window) &key timeout) 236 | (let ((fifo (mezzano.gui.compositor::mailbox window))) 237 | (labels ((poll-events () 238 | (loop for event = (mezzano.supervisor:fifo-pop fifo nil) 239 | while event do (process-event window event))) 240 | (wait (timeout) 241 | (dolist (obj (apply #'mezzano.sync:wait-for-objects-with-timeout 242 | timeout 243 | (list* fifo (timers window)))) 244 | (if (eq obj fifo) 245 | (poll-events) 246 | (fb:timer-triggered window obj))))) 247 | (etypecase timeout 248 | (real (wait (float timeout 0f0))) 249 | ((eql T) (loop until (or (not (fb:valid-p window)) (fb:close-requested-p window)) 250 | do (wait 1.0))) 251 | (null 252 | (poll-events) 253 | (dolist (timer (timers window)) 254 | (when (mezzano.supervisor:timer-expired-p timer) 255 | (fb:timer-triggered window timer)))))))) 256 | 257 | (defmethod fb:request-attention ((window window))) 258 | 259 | (defmethod fb:set-timer ((window window) delay &key repeat) 260 | ;; FIXME: timer repeats 261 | (let ((timer (mezzano.supervisor:make-timer :relative delay))) 262 | (push timer (timers window)) 263 | timer)) 264 | 265 | (defmethod fb:cancel-timer ((window window) timer) 266 | (mezzano.supervisor:timer-disarm timer) 267 | (setf (timers window) (remove timer (timers window))) 268 | NIL) 269 | 270 | (defmethod fb:display ((window window)) 271 | *default-display*) 272 | 273 | (defclass display (fb-int:display) 274 | ()) 275 | 276 | (defstruct (video-mode (:include fb:video-mode))) 277 | 278 | (defmethod process-event ((window window) (event mezzano.gui.compositor:window-create-event)) 279 | (fb:window-refreshed window)) 280 | 281 | (defmethod process-event ((window window) (event mezzano.gui.compositor:window-activation-event)) 282 | (when (not (or (fb:fullscreen-p window) 283 | (fb:borderless-p window))) 284 | (setf (mezzano.gui.widgets:activep (frame window)) (mezzano.gui.compositor:state event)) 285 | (mezzano.gui.widgets:draw-frame (frame window))) 286 | (fb:window-focused window (mezzano.gui.compositor:state event))) 287 | 288 | (defmethod process-event ((window window) (event mezzano.gui.compositor:mouse-event)) 289 | (let ((x (mezzano.gui.compositor:mouse-x-position event)) 290 | (y (mezzano.gui.compositor:mouse-y-position event))) 291 | (flet ((inner (x y) 292 | (when (or (/= 0 (mezzano.gui.compositor:mouse-x-motion event)) 293 | (/= 0 (mezzano.gui.compositor:mouse-y-motion event))) 294 | (fb:mouse-moved window x y)) 295 | (when (< 0 (mezzano.gui.compositor:mouse-button-change event)) 296 | (dotimes (i 10) 297 | (when (logbitp i (mezzano.gui.compositor:mouse-button-change event)) 298 | (fb:mouse-button-changed window (case i 299 | (0 :left) 300 | (1 :right) 301 | (2 :middle) 302 | (T i)) 303 | (if (logbitp i (mezzano.gui.compositor:mouse-button-state event)) 304 | :press :release) 305 | mezzano.gui.compositor::*keyboard-modifier-state*)))))) 306 | (cond ((or (fb:fullscreen-p window) 307 | (fb:borderless-p window)) 308 | (inner x y)) 309 | (T 310 | (handler-case (mezzano.gui.widgets:frame-mouse-event (frame window) event) 311 | (mezzano.gui.widgets:close-button-clicked () 312 | (fb:window-closed window))) 313 | (unless (mezzano.gui.widgets::in-frame-border-p (frame window) x y) 314 | (multiple-value-bind (left right top bottom) (mezzano.gui.widgets:frame-size (frame window)) 315 | (inner (- x left) (- y top))))))))) 316 | 317 | (defmethod process-event ((window window) (event mezzano.gui.compositor:window-close-event)) 318 | (fb:window-closed window)) 319 | 320 | (defmethod process-event ((window window) (event mezzano.gui.compositor:move-event)) 321 | (fb:window-moved window (mezzano.gui.compositor::new-x event) (mezzano.gui.compositor::new-y event))) 322 | 323 | (defmethod process-event ((window window) (event mezzano.gui.compositor:screen-geometry-update)) 324 | (let ((w (mezzano.gui.compositor:width event)) 325 | (h (mezzano.gui.compositor:height event))) 326 | (setf (car (fb:size *default-display*)) w) 327 | (setf (cdr (fb:size *default-display*)) h) 328 | (setf (video-mode-width (fb:video-mode *default-display*)) w) 329 | (setf (video-mode-height (fb:video-mode *default-display*)) h) 330 | (when (fb:fullscreen-p window) 331 | (setf (fb:size window) (cons w h))))) 332 | 333 | (defmethod process-event ((window window) (event mezzano.gui.compositor:quit-event)) 334 | (fb:window-closed window)) 335 | 336 | (defun adjust-size (window size) 337 | (flet ((frob (x min max) 338 | (if max 339 | (max min (min x max)) 340 | (max min x)))) 341 | (setf (car size) (frob (car size) (car (fb:minimum-size window)) (car (fb:maximum-size window)))) 342 | (setf (cdr size) (frob (cdr size) (cdr (fb:minimum-size window)) (cdr (fb:maximum-size window)))) 343 | size)) 344 | 345 | (defmethod process-event ((window window) (event mezzano.gui.compositor:resize-request-event)) 346 | (when (and (fb:resizable-p window) 347 | (not (fb:fullscreen-p window))) 348 | (multiple-value-bind (left right top bottom) (if (or (fb:fullscreen-p window) 349 | (fb:borderless-p window)) 350 | (values 0 0 0 0) 351 | (mezzano.gui.widgets:frame-size (frame window))) 352 | (setf (fb:size window) (adjust-size window (cons (- (mezzano.gui.compositor:width event) left right) 353 | (- (mezzano.gui.compositor:height event) top bottom))))))) 354 | 355 | (defmethod process-event ((window window) (event mezzano.gui.compositor:resize-event)) 356 | (fb:window-refreshed window)) 357 | 358 | (defmethod process-event ((window window) (event mezzano.gui.compositor:key-event)) 359 | (fb:key-changed window 360 | (translate-key (mezzano.gui.compositor:key-scancode event)) 361 | (char-code (mezzano.gui.compositor:key-scancode event)) 362 | (if (mezzano.gui.compositor:key-releasep event) :release :press) 363 | (mezzano.gui.compositor:key-modifier-state event))) 364 | 365 | (defmethod process-event ((window window) (event mezzano.gui.compositor:event))) 366 | 367 | ;; TODO: key repeats 368 | ;; TODO: double click 369 | -------------------------------------------------------------------------------- /xlib/keysyms.txt: -------------------------------------------------------------------------------- 1 | #x0020 #x0020 2 | #x0021 #x0021 3 | #x0022 #x0022 4 | #x0023 #x0023 5 | #x0024 #x0024 6 | #x0025 #x0025 7 | #x0026 #x0026 8 | #x0027 #x0027 9 | #x0028 #x0028 10 | #x0029 #x0029 11 | #x002A #x002A 12 | #x002B #x002B 13 | #x002C #x002C 14 | #x002D #x002D 15 | #x002E #x002E 16 | #x002F #x002F 17 | #x0030 #x0030 18 | #x0031 #x0031 19 | #x0032 #x0032 20 | #x0033 #x0033 21 | #x0034 #x0034 22 | #x0035 #x0035 23 | #x0036 #x0036 24 | #x0037 #x0037 25 | #x0038 #x0038 26 | #x0039 #x0039 27 | #x003A #x003A 28 | #x003B #x003B 29 | #x003C #x003C 30 | #x003D #x003D 31 | #x003E #x003E 32 | #x003F #x003F 33 | #x0040 #x0040 34 | #x0041 #x0041 35 | #x0042 #x0042 36 | #x0043 #x0043 37 | #x0044 #x0044 38 | #x0045 #x0045 39 | #x0046 #x0046 40 | #x0047 #x0047 41 | #x0048 #x0048 42 | #x0049 #x0049 43 | #x004A #x004A 44 | #x004B #x004B 45 | #x004C #x004C 46 | #x004D #x004D 47 | #x004E #x004E 48 | #x004F #x004F 49 | #x0050 #x0050 50 | #x0051 #x0051 51 | #x0052 #x0052 52 | #x0053 #x0053 53 | #x0054 #x0054 54 | #x0055 #x0055 55 | #x0056 #x0056 56 | #x0057 #x0057 57 | #x0058 #x0058 58 | #x0059 #x0059 59 | #x005A #x005A 60 | #x005B #x005B 61 | #x005C #x005C 62 | #x005D #x005D 63 | #x005E #x005E 64 | #x005F #x005F 65 | #x0060 #x0060 66 | #x0061 #x0061 67 | #x0062 #x0062 68 | #x0063 #x0063 69 | #x0064 #x0064 70 | #x0065 #x0065 71 | #x0066 #x0066 72 | #x0067 #x0067 73 | #x0068 #x0068 74 | #x0069 #x0069 75 | #x006A #x006A 76 | #x006B #x006B 77 | #x006C #x006C 78 | #x006D #x006D 79 | #x006E #x006E 80 | #x006F #x006F 81 | #x0070 #x0070 82 | #x0071 #x0071 83 | #x0072 #x0072 84 | #x0073 #x0073 85 | #x0074 #x0074 86 | #x0075 #x0075 87 | #x0076 #x0076 88 | #x0077 #x0077 89 | #x0078 #x0078 90 | #x0079 #x0079 91 | #x007A #x007A 92 | #x007B #x007B 93 | #x007C #x007C 94 | #x007D #x007D 95 | #x007E #x007E 96 | #x00A0 #x00A0 97 | #x00A1 #x00A1 98 | #x00A2 #x00A2 99 | #x00A3 #x00A3 100 | #x00A4 #x00A4 101 | #x00A5 #x00A5 102 | #x00A6 #x00A6 103 | #x00A7 #x00A7 104 | #x00A8 #x00A8 105 | #x00A9 #x00A9 106 | #x00AA #x00AA 107 | #x00AB #x00AB 108 | #x00AC #x00AC 109 | #x00AD #x00AD 110 | #x00AE #x00AE 111 | #x00AF #x00AF 112 | #x00B0 #x00B0 113 | #x00B1 #x00B1 114 | #x00B2 #x00B2 115 | #x00B3 #x00B3 116 | #x00B4 #x00B4 117 | #x00B5 #x00B5 118 | #x00B6 #x00B6 119 | #x00B7 #x00B7 120 | #x00B8 #x00B8 121 | #x00B9 #x00B9 122 | #x00BA #x00BA 123 | #x00BB #x00BB 124 | #x00BC #x00BC 125 | #x00BD #x00BD 126 | #x00BE #x00BE 127 | #x00BF #x00BF 128 | #x00C0 #x00C0 129 | #x00C1 #x00C1 130 | #x00C2 #x00C2 131 | #x00C3 #x00C3 132 | #x00C4 #x00C4 133 | #x00C5 #x00C5 134 | #x00C6 #x00C6 135 | #x00C7 #x00C7 136 | #x00C8 #x00C8 137 | #x00C9 #x00C9 138 | #x00CA #x00CA 139 | #x00CB #x00CB 140 | #x00CC #x00CC 141 | #x00CD #x00CD 142 | #x00CE #x00CE 143 | #x00CF #x00CF 144 | #x00D0 #x00D0 145 | #x00D1 #x00D1 146 | #x00D2 #x00D2 147 | #x00D3 #x00D3 148 | #x00D4 #x00D4 149 | #x00D5 #x00D5 150 | #x00D6 #x00D6 151 | #x00D7 #x00D7 152 | #x00D8 #x00D8 153 | #x00D9 #x00D9 154 | #x00DA #x00DA 155 | #x00DB #x00DB 156 | #x00DC #x00DC 157 | #x00DD #x00DD 158 | #x00DE #x00DE 159 | #x00DF #x00DF 160 | #x00E0 #x00E0 161 | #x00E1 #x00E1 162 | #x00E2 #x00E2 163 | #x00E3 #x00E3 164 | #x00E4 #x00E4 165 | #x00E5 #x00E5 166 | #x00E6 #x00E6 167 | #x00E7 #x00E7 168 | #x00E8 #x00E8 169 | #x00E9 #x00E9 170 | #x00EA #x00EA 171 | #x00EB #x00EB 172 | #x00EC #x00EC 173 | #x00ED #x00ED 174 | #x00EE #x00EE 175 | #x00EF #x00EF 176 | #x00F0 #x00F0 177 | #x00F1 #x00F1 178 | #x00F2 #x00F2 179 | #x00F3 #x00F3 180 | #x00F4 #x00F4 181 | #x00F5 #x00F5 182 | #x00F6 #x00F6 183 | #x00F7 #x00F7 184 | #x00F8 #x00F8 185 | #x00F9 #x00F9 186 | #x00FA #x00FA 187 | #x00FB #x00FB 188 | #x00FC #x00FC 189 | #x00FD #x00FD 190 | #x00FE #x00FE 191 | #x00FF #x00FF 192 | #x01a1 #x0104 193 | #x01a2 #x02d8 194 | #x01a3 #x0141 195 | #x01a5 #x013d 196 | #x01a6 #x015a 197 | #x01a9 #x0160 198 | #x01aa #x015e 199 | #x01ab #x0164 200 | #x01ac #x0179 201 | #x01ae #x017d 202 | #x01af #x017b 203 | #x01b1 #x0105 204 | #x01b2 #x02db 205 | #x01b3 #x0142 206 | #x01b5 #x013e 207 | #x01b6 #x015b 208 | #x01b7 #x02c7 209 | #x01b9 #x0161 210 | #x01ba #x015f 211 | #x01bb #x0165 212 | #x01bc #x017a 213 | #x01bd #x02dd 214 | #x01be #x017e 215 | #x01bf #x017c 216 | #x01c0 #x0154 217 | #x01c3 #x0102 218 | #x01c5 #x0139 219 | #x01c6 #x0106 220 | #x01c8 #x010c 221 | #x01ca #x0118 222 | #x01cc #x011a 223 | #x01cf #x010e 224 | #x01d0 #x0110 225 | #x01d1 #x0143 226 | #x01d2 #x0147 227 | #x01d5 #x0150 228 | #x01d8 #x0158 229 | #x01d9 #x016e 230 | #x01db #x0170 231 | #x01de #x0162 232 | #x01e0 #x0155 233 | #x01e3 #x0103 234 | #x01e5 #x013a 235 | #x01e6 #x0107 236 | #x01e8 #x010d 237 | #x01ea #x0119 238 | #x01ec #x011b 239 | #x01ef #x010f 240 | #x01f0 #x0111 241 | #x01f1 #x0144 242 | #x01f2 #x0148 243 | #x01f5 #x0151 244 | #x01f8 #x0159 245 | #x01f9 #x016f 246 | #x01fb #x0171 247 | #x01fe #x0163 248 | #x01ff #x02d9 249 | #x02a1 #x0126 250 | #x02a6 #x0124 251 | #x02a9 #x0130 252 | #x02ab #x011e 253 | #x02ac #x0134 254 | #x02b1 #x0127 255 | #x02b6 #x0125 256 | #x02b9 #x0131 257 | #x02bb #x011f 258 | #x02bc #x0135 259 | #x02c5 #x010a 260 | #x02c6 #x0108 261 | #x02d5 #x0120 262 | #x02d8 #x011c 263 | #x02dd #x016c 264 | #x02de #x015c 265 | #x02e5 #x010b 266 | #x02e6 #x0109 267 | #x02f5 #x0121 268 | #x02f8 #x011d 269 | #x02fd #x016d 270 | #x02fe #x015d 271 | #x03a2 #x0138 272 | #x03a3 #x0156 273 | #x03a5 #x0128 274 | #x03a6 #x013b 275 | #x03aa #x0112 276 | #x03ab #x0122 277 | #x03ac #x0166 278 | #x03b3 #x0157 279 | #x03b5 #x0129 280 | #x03b6 #x013c 281 | #x03ba #x0113 282 | #x03bb #x0123 283 | #x03bc #x0167 284 | #x03bd #x014a 285 | #x03bf #x014b 286 | #x03c0 #x0100 287 | #x03c7 #x012e 288 | #x03cc #x0116 289 | #x03cf #x012a 290 | #x03d1 #x0145 291 | #x03d2 #x014c 292 | #x03d3 #x0136 293 | #x03d9 #x0172 294 | #x03dd #x0168 295 | #x03de #x016a 296 | #x03e0 #x0101 297 | #x03e7 #x012f 298 | #x03ec #x0117 299 | #x03ef #x012b 300 | #x03f1 #x0146 301 | #x03f2 #x014d 302 | #x03f3 #x0137 303 | #x03f9 #x0173 304 | #x03fd #x0169 305 | #x03fe #x016b 306 | #x047e #x203e 307 | #x04a1 #x3002 308 | #x04a2 #x300c 309 | #x04a3 #x300d 310 | #x04a4 #x3001 311 | #x04a5 #x30fb 312 | #x04a6 #x30f2 313 | #x04a7 #x30a1 314 | #x04a8 #x30a3 315 | #x04a9 #x30a5 316 | #x04aa #x30a7 317 | #x04ab #x30a9 318 | #x04ac #x30e3 319 | #x04ad #x30e5 320 | #x04ae #x30e7 321 | #x04af #x30c3 322 | #x04b0 #x30fc 323 | #x04b1 #x30a2 324 | #x04b2 #x30a4 325 | #x04b3 #x30a6 326 | #x04b4 #x30a8 327 | #x04b5 #x30aa 328 | #x04b6 #x30ab 329 | #x04b7 #x30ad 330 | #x04b8 #x30af 331 | #x04b9 #x30b1 332 | #x04ba #x30b3 333 | #x04bb #x30b5 334 | #x04bc #x30b7 335 | #x04bd #x30b9 336 | #x04be #x30bb 337 | #x04bf #x30bd 338 | #x04c0 #x30bf 339 | #x04c1 #x30c1 340 | #x04c2 #x30c4 341 | #x04c3 #x30c6 342 | #x04c4 #x30c8 343 | #x04c5 #x30ca 344 | #x04c6 #x30cb 345 | #x04c7 #x30cc 346 | #x04c8 #x30cd 347 | #x04c9 #x30ce 348 | #x04ca #x30cf 349 | #x04cb #x30d2 350 | #x04cc #x30d5 351 | #x04cd #x30d8 352 | #x04ce #x30db 353 | #x04cf #x30de 354 | #x04d0 #x30df 355 | #x04d1 #x30e0 356 | #x04d2 #x30e1 357 | #x04d3 #x30e2 358 | #x04d4 #x30e4 359 | #x04d5 #x30e6 360 | #x04d6 #x30e8 361 | #x04d7 #x30e9 362 | #x04d8 #x30ea 363 | #x04d9 #x30eb 364 | #x04da #x30ec 365 | #x04db #x30ed 366 | #x04dc #x30ef 367 | #x04dd #x30f3 368 | #x04de #x309b 369 | #x04df #x309c 370 | #x05ac #x060c 371 | #x05bb #x061b 372 | #x05bf #x061f 373 | #x05c1 #x0621 374 | #x05c2 #x0622 375 | #x05c3 #x0623 376 | #x05c4 #x0624 377 | #x05c5 #x0625 378 | #x05c6 #x0626 379 | #x05c7 #x0627 380 | #x05c8 #x0628 381 | #x05c9 #x0629 382 | #x05ca #x062a 383 | #x05cb #x062b 384 | #x05cc #x062c 385 | #x05cd #x062d 386 | #x05ce #x062e 387 | #x05cf #x062f 388 | #x05d0 #x0630 389 | #x05d1 #x0631 390 | #x05d2 #x0632 391 | #x05d3 #x0633 392 | #x05d4 #x0634 393 | #x05d5 #x0635 394 | #x05d6 #x0636 395 | #x05d7 #x0637 396 | #x05d8 #x0638 397 | #x05d9 #x0639 398 | #x05da #x063a 399 | #x05e0 #x0640 400 | #x05e1 #x0641 401 | #x05e2 #x0642 402 | #x05e3 #x0643 403 | #x05e4 #x0644 404 | #x05e5 #x0645 405 | #x05e6 #x0646 406 | #x05e7 #x0647 407 | #x05e8 #x0648 408 | #x05e9 #x0649 409 | #x05ea #x064a 410 | #x05eb #x064b 411 | #x05ec #x064c 412 | #x05ed #x064d 413 | #x05ee #x064e 414 | #x05ef #x064f 415 | #x05f0 #x0650 416 | #x05f1 #x0651 417 | #x05f2 #x0652 418 | #x06a1 #x0452 419 | #x06a2 #x0453 420 | #x06a3 #x0451 421 | #x06a4 #x0454 422 | #x06a5 #x0455 423 | #x06a6 #x0456 424 | #x06a7 #x0457 425 | #x06a8 #x0458 426 | #x06a9 #x0459 427 | #x06aa #x045a 428 | #x06ab #x045b 429 | #x06ac #x045c 430 | #x06ae #x045e 431 | #x06af #x045f 432 | #x06b0 #x2116 433 | #x06b1 #x0402 434 | #x06b2 #x0403 435 | #x06b3 #x0401 436 | #x06b4 #x0404 437 | #x06b5 #x0405 438 | #x06b6 #x0406 439 | #x06b7 #x0407 440 | #x06b8 #x0408 441 | #x06b9 #x0409 442 | #x06ba #x040a 443 | #x06bb #x040b 444 | #x06bc #x040c 445 | #x06be #x040e 446 | #x06bf #x040f 447 | #x06c0 #x044e 448 | #x06c1 #x0430 449 | #x06c2 #x0431 450 | #x06c3 #x0446 451 | #x06c4 #x0434 452 | #x06c5 #x0435 453 | #x06c6 #x0444 454 | #x06c7 #x0433 455 | #x06c8 #x0445 456 | #x06c9 #x0438 457 | #x06ca #x0439 458 | #x06cb #x043a 459 | #x06cc #x043b 460 | #x06cd #x043c 461 | #x06ce #x043d 462 | #x06cf #x043e 463 | #x06d0 #x043f 464 | #x06d1 #x044f 465 | #x06d2 #x0440 466 | #x06d3 #x0441 467 | #x06d4 #x0442 468 | #x06d5 #x0443 469 | #x06d6 #x0436 470 | #x06d7 #x0432 471 | #x06d8 #x044c 472 | #x06d9 #x044b 473 | #x06da #x0437 474 | #x06db #x0448 475 | #x06dc #x044d 476 | #x06dd #x0449 477 | #x06de #x0447 478 | #x06df #x044a 479 | #x06e0 #x042e 480 | #x06e1 #x0410 481 | #x06e2 #x0411 482 | #x06e3 #x0426 483 | #x06e4 #x0414 484 | #x06e5 #x0415 485 | #x06e6 #x0424 486 | #x06e7 #x0413 487 | #x06e8 #x0425 488 | #x06e9 #x0418 489 | #x06ea #x0419 490 | #x06eb #x041a 491 | #x06ec #x041b 492 | #x06ed #x041c 493 | #x06ee #x041d 494 | #x06ef #x041e 495 | #x06f0 #x041f 496 | #x06f1 #x042f 497 | #x06f2 #x0420 498 | #x06f3 #x0421 499 | #x06f4 #x0422 500 | #x06f5 #x0423 501 | #x06f6 #x0416 502 | #x06f7 #x0412 503 | #x06f8 #x042c 504 | #x06f9 #x042b 505 | #x06fa #x0417 506 | #x06fb #x0428 507 | #x06fc #x042d 508 | #x06fd #x0429 509 | #x06fe #x0427 510 | #x06ff #x042a 511 | #x07a1 #x0386 512 | #x07a2 #x0388 513 | #x07a3 #x0389 514 | #x07a4 #x038a 515 | #x07a5 #x03aa 516 | #x07a7 #x038c 517 | #x07a8 #x038e 518 | #x07a9 #x03ab 519 | #x07ab #x038f 520 | #x07ae #x0385 521 | #x07af #x2015 522 | #x07b1 #x03ac 523 | #x07b2 #x03ad 524 | #x07b3 #x03ae 525 | #x07b4 #x03af 526 | #x07b5 #x03ca 527 | #x07b6 #x0390 528 | #x07b7 #x03cc 529 | #x07b8 #x03cd 530 | #x07b9 #x03cb 531 | #x07ba #x03b0 532 | #x07bb #x03ce 533 | #x07c1 #x0391 534 | #x07c2 #x0392 535 | #x07c3 #x0393 536 | #x07c4 #x0394 537 | #x07c5 #x0395 538 | #x07c6 #x0396 539 | #x07c7 #x0397 540 | #x07c8 #x0398 541 | #x07c9 #x0399 542 | #x07ca #x039a 543 | #x07cb #x039b 544 | #x07cc #x039c 545 | #x07cd #x039d 546 | #x07ce #x039e 547 | #x07cf #x039f 548 | #x07d0 #x03a0 549 | #x07d1 #x03a1 550 | #x07d2 #x03a3 551 | #x07d4 #x03a4 552 | #x07d5 #x03a5 553 | #x07d6 #x03a6 554 | #x07d7 #x03a7 555 | #x07d8 #x03a8 556 | #x07d9 #x03a9 557 | #x07e1 #x03b1 558 | #x07e2 #x03b2 559 | #x07e3 #x03b3 560 | #x07e4 #x03b4 561 | #x07e5 #x03b5 562 | #x07e6 #x03b6 563 | #x07e7 #x03b7 564 | #x07e8 #x03b8 565 | #x07e9 #x03b9 566 | #x07ea #x03ba 567 | #x07eb #x03bb 568 | #x07ec #x03bc 569 | #x07ed #x03bd 570 | #x07ee #x03be 571 | #x07ef #x03bf 572 | #x07f0 #x03c0 573 | #x07f1 #x03c1 574 | #x07f2 #x03c3 575 | #x07f3 #x03c2 576 | #x07f4 #x03c4 577 | #x07f5 #x03c5 578 | #x07f6 #x03c6 579 | #x07f7 #x03c7 580 | #x07f8 #x03c8 581 | #x07f9 #x03c9 582 | #x08a1 #x23b7 583 | #x08a2 #x250c 584 | #x08a3 #x2500 585 | #x08a4 #x2320 586 | #x08a5 #x2321 587 | #x08a6 #x2502 588 | #x08a7 #x23a1 589 | #x08a8 #x23a3 590 | #x08a9 #x23a4 591 | #x08aa #x23a6 592 | #x08ab #x239b 593 | #x08ac #x239d 594 | #x08ad #x239e 595 | #x08ae #x23a0 596 | #x08af #x23a8 597 | #x08b0 #x23ac 598 | #x08bc #x2264 599 | #x08bd #x2260 600 | #x08be #x2265 601 | #x08bf #x222b 602 | #x08c0 #x2234 603 | #x08c1 #x221d 604 | #x08c2 #x221e 605 | #x08c5 #x2207 606 | #x08c8 #x223c 607 | #x08c9 #x2243 608 | #x08cd #x21d4 609 | #x08ce #x21d2 610 | #x08cf #x2261 611 | #x08d6 #x221a 612 | #x08da #x2282 613 | #x08db #x2283 614 | #x08dc #x2229 615 | #x08dd #x222a 616 | #x08de #x2227 617 | #x08df #x2228 618 | #x08ef #x2202 619 | #x08f6 #x0192 620 | #x08fb #x2190 621 | #x08fc #x2191 622 | #x08fd #x2192 623 | #x08fe #x2193 624 | #x09e0 #x25c6 625 | #x09e1 #x2592 626 | #x09e2 #x2409 627 | #x09e3 #x240c 628 | #x09e4 #x240d 629 | #x09e5 #x240a 630 | #x09e8 #x2424 631 | #x09e9 #x240b 632 | #x09ea #x2518 633 | #x09eb #x2510 634 | #x09ec #x250c 635 | #x09ed #x2514 636 | #x09ee #x253c 637 | #x09ef #x23ba 638 | #x09f0 #x23bb 639 | #x09f1 #x2500 640 | #x09f2 #x23bc 641 | #x09f3 #x23bd 642 | #x09f4 #x251c 643 | #x09f5 #x2524 644 | #x09f6 #x2534 645 | #x09f7 #x252c 646 | #x09f8 #x2502 647 | #x0aa1 #x2003 648 | #x0aa2 #x2002 649 | #x0aa3 #x2004 650 | #x0aa4 #x2005 651 | #x0aa5 #x2007 652 | #x0aa6 #x2008 653 | #x0aa7 #x2009 654 | #x0aa8 #x200a 655 | #x0aa9 #x2014 656 | #x0aaa #x2013 657 | #x0aae #x2026 658 | #x0aaf #x2025 659 | #x0ab0 #x2153 660 | #x0ab1 #x2154 661 | #x0ab2 #x2155 662 | #x0ab3 #x2156 663 | #x0ab4 #x2157 664 | #x0ab5 #x2158 665 | #x0ab6 #x2159 666 | #x0ab7 #x215a 667 | #x0ab8 #x2105 668 | #x0abb #x2012 669 | #x0abc #x2329 670 | #x0abe #x232a 671 | #x0ac3 #x215b 672 | #x0ac4 #x215c 673 | #x0ac5 #x215d 674 | #x0ac6 #x215e 675 | #x0ac9 #x2122 676 | #x0aca #x2613 677 | #x0acc #x25c1 678 | #x0acd #x25b7 679 | #x0ace #x25cb 680 | #x0acf #x25af 681 | #x0ad0 #x2018 682 | #x0ad1 #x2019 683 | #x0ad2 #x201c 684 | #x0ad3 #x201d 685 | #x0ad4 #x211e 686 | #x0ad6 #x2032 687 | #x0ad7 #x2033 688 | #x0ad9 #x271d 689 | #x0adb #x25ac 690 | #x0adc #x25c0 691 | #x0add #x25b6 692 | #x0ade #x25cf 693 | #x0adf #x25ae 694 | #x0ae0 #x25e6 695 | #x0ae1 #x25ab 696 | #x0ae2 #x25ad 697 | #x0ae3 #x25b3 698 | #x0ae4 #x25bd 699 | #x0ae5 #x2606 700 | #x0ae6 #x2022 701 | #x0ae7 #x25aa 702 | #x0ae8 #x25b2 703 | #x0ae9 #x25bc 704 | #x0aea #x261c 705 | #x0aeb #x261e 706 | #x0aec #x2663 707 | #x0aed #x2666 708 | #x0aee #x2665 709 | #x0af0 #x2720 710 | #x0af1 #x2020 711 | #x0af2 #x2021 712 | #x0af3 #x2713 713 | #x0af4 #x2717 714 | #x0af5 #x266f 715 | #x0af6 #x266d 716 | #x0af7 #x2642 717 | #x0af8 #x2640 718 | #x0af9 #x260e 719 | #x0afa #x2315 720 | #x0afb #x2117 721 | #x0afc #x2038 722 | #x0afd #x201a 723 | #x0afe #x201e 724 | #x0ba3 #x003c 725 | #x0ba6 #x003e 726 | #x0ba8 #x2228 727 | #x0ba9 #x2227 728 | #x0bc0 #x00af 729 | #x0bc2 #x22a5 730 | #x0bc3 #x2229 731 | #x0bc4 #x230a 732 | #x0bc6 #x005f 733 | #x0bca #x2218 734 | #x0bcc #x2395 735 | #x0bce #x22a4 736 | #x0bcf #x25cb 737 | #x0bd3 #x2308 738 | #x0bd6 #x222a 739 | #x0bd8 #x2283 740 | #x0bda #x2282 741 | #x0bdc #x22a2 742 | #x0bfc #x22a3 743 | #x0cdf #x2017 744 | #x0ce0 #x05d0 745 | #x0ce1 #x05d1 746 | #x0ce2 #x05d2 747 | #x0ce3 #x05d3 748 | #x0ce4 #x05d4 749 | #x0ce5 #x05d5 750 | #x0ce6 #x05d6 751 | #x0ce7 #x05d7 752 | #x0ce8 #x05d8 753 | #x0ce9 #x05d9 754 | #x0cea #x05da 755 | #x0ceb #x05db 756 | #x0cec #x05dc 757 | #x0ced #x05dd 758 | #x0cee #x05de 759 | #x0cef #x05df 760 | #x0cf0 #x05e0 761 | #x0cf1 #x05e1 762 | #x0cf2 #x05e2 763 | #x0cf3 #x05e3 764 | #x0cf4 #x05e4 765 | #x0cf5 #x05e5 766 | #x0cf6 #x05e6 767 | #x0cf7 #x05e7 768 | #x0cf8 #x05e8 769 | #x0cf9 #x05e9 770 | #x0cfa #x05ea 771 | #x0da1 #x0e01 772 | #x0da2 #x0e02 773 | #x0da3 #x0e03 774 | #x0da4 #x0e04 775 | #x0da5 #x0e05 776 | #x0da6 #x0e06 777 | #x0da7 #x0e07 778 | #x0da8 #x0e08 779 | #x0da9 #x0e09 780 | #x0daa #x0e0a 781 | #x0dab #x0e0b 782 | #x0dac #x0e0c 783 | #x0dad #x0e0d 784 | #x0dae #x0e0e 785 | #x0daf #x0e0f 786 | #x0db0 #x0e10 787 | #x0db1 #x0e11 788 | #x0db2 #x0e12 789 | #x0db3 #x0e13 790 | #x0db4 #x0e14 791 | #x0db5 #x0e15 792 | #x0db6 #x0e16 793 | #x0db7 #x0e17 794 | #x0db8 #x0e18 795 | #x0db9 #x0e19 796 | #x0dba #x0e1a 797 | #x0dbb #x0e1b 798 | #x0dbc #x0e1c 799 | #x0dbd #x0e1d 800 | #x0dbe #x0e1e 801 | #x0dbf #x0e1f 802 | #x0dc0 #x0e20 803 | #x0dc1 #x0e21 804 | #x0dc2 #x0e22 805 | #x0dc3 #x0e23 806 | #x0dc4 #x0e24 807 | #x0dc5 #x0e25 808 | #x0dc6 #x0e26 809 | #x0dc7 #x0e27 810 | #x0dc8 #x0e28 811 | #x0dc9 #x0e29 812 | #x0dca #x0e2a 813 | #x0dcb #x0e2b 814 | #x0dcc #x0e2c 815 | #x0dcd #x0e2d 816 | #x0dce #x0e2e 817 | #x0dcf #x0e2f 818 | #x0dd0 #x0e30 819 | #x0dd1 #x0e31 820 | #x0dd2 #x0e32 821 | #x0dd3 #x0e33 822 | #x0dd4 #x0e34 823 | #x0dd5 #x0e35 824 | #x0dd6 #x0e36 825 | #x0dd7 #x0e37 826 | #x0dd8 #x0e38 827 | #x0dd9 #x0e39 828 | #x0dda #x0e3a 829 | #x0ddf #x0e3f 830 | #x0de0 #x0e40 831 | #x0de1 #x0e41 832 | #x0de2 #x0e42 833 | #x0de3 #x0e43 834 | #x0de4 #x0e44 835 | #x0de5 #x0e45 836 | #x0de6 #x0e46 837 | #x0de7 #x0e47 838 | #x0de8 #x0e48 839 | #x0de9 #x0e49 840 | #x0dea #x0e4a 841 | #x0deb #x0e4b 842 | #x0dec #x0e4c 843 | #x0ded #x0e4d 844 | #x0df0 #x0e50 845 | #x0df1 #x0e51 846 | #x0df2 #x0e52 847 | #x0df3 #x0e53 848 | #x0df4 #x0e54 849 | #x0df5 #x0e55 850 | #x0df6 #x0e56 851 | #x0df7 #x0e57 852 | #x0df8 #x0e58 853 | #x0df9 #x0e59 854 | #x0ea1 #x3131 855 | #x0ea2 #x3132 856 | #x0ea3 #x3133 857 | #x0ea4 #x3134 858 | #x0ea5 #x3135 859 | #x0ea6 #x3136 860 | #x0ea7 #x3137 861 | #x0ea8 #x3138 862 | #x0ea9 #x3139 863 | #x0eaa #x313a 864 | #x0eab #x313b 865 | #x0eac #x313c 866 | #x0ead #x313d 867 | #x0eae #x313e 868 | #x0eaf #x313f 869 | #x0eb0 #x3140 870 | #x0eb1 #x3141 871 | #x0eb2 #x3142 872 | #x0eb3 #x3143 873 | #x0eb4 #x3144 874 | #x0eb5 #x3145 875 | #x0eb6 #x3146 876 | #x0eb7 #x3147 877 | #x0eb8 #x3148 878 | #x0eb9 #x3149 879 | #x0eba #x314a 880 | #x0ebb #x314b 881 | #x0ebc #x314c 882 | #x0ebd #x314d 883 | #x0ebe #x314e 884 | #x0ebf #x314f 885 | #x0ec0 #x3150 886 | #x0ec1 #x3151 887 | #x0ec2 #x3152 888 | #x0ec3 #x3153 889 | #x0ec4 #x3154 890 | #x0ec5 #x3155 891 | #x0ec6 #x3156 892 | #x0ec7 #x3157 893 | #x0ec8 #x3158 894 | #x0ec9 #x3159 895 | #x0eca #x315a 896 | #x0ecb #x315b 897 | #x0ecc #x315c 898 | #x0ecd #x315d 899 | #x0ece #x315e 900 | #x0ecf #x315f 901 | #x0ed0 #x3160 902 | #x0ed1 #x3161 903 | #x0ed2 #x3162 904 | #x0ed3 #x3163 905 | #x0ed4 #x11a8 906 | #x0ed5 #x11a9 907 | #x0ed6 #x11aa 908 | #x0ed7 #x11ab 909 | #x0ed8 #x11ac 910 | #x0ed9 #x11ad 911 | #x0eda #x11ae 912 | #x0edb #x11af 913 | #x0edc #x11b0 914 | #x0edd #x11b1 915 | #x0ede #x11b2 916 | #x0edf #x11b3 917 | #x0ee0 #x11b4 918 | #x0ee1 #x11b5 919 | #x0ee2 #x11b6 920 | #x0ee3 #x11b7 921 | #x0ee4 #x11b8 922 | #x0ee5 #x11b9 923 | #x0ee6 #x11ba 924 | #x0ee7 #x11bb 925 | #x0ee8 #x11bc 926 | #x0ee9 #x11bd 927 | #x0eea #x11be 928 | #x0eeb #x11bf 929 | #x0eec #x11c0 930 | #x0eed #x11c1 931 | #x0eee #x11c2 932 | #x0eef #x316d 933 | #x0ef0 #x3171 934 | #x0ef1 #x3178 935 | #x0ef2 #x317f 936 | #x0ef3 #x3181 937 | #x0ef4 #x3184 938 | #x0ef5 #x3186 939 | #x0ef6 #x318d 940 | #x0ef7 #x318e 941 | #x0ef8 #x11eb 942 | #x0ef9 #x11f0 943 | #x0efa #x11f9 944 | #x0eff #x20a9 945 | #x13a4 #x20ac 946 | #x13bc #x0152 947 | #x13bd #x0153 948 | #x13be #x0178 949 | #x20ac #x20ac 950 | #xfe51 #x00b4 951 | #xfe54 #x00af 952 | #xfe55 #x02d8 953 | #xfe56 #x02d9 954 | #xfe57 #x00a8 955 | #xfe58 #x02da 956 | #xfe59 #x02dd 957 | #xfe5a #x02c7 958 | #xfe5b #x00b8 959 | #xfe5c #x02db 960 | #xfe5d #x037a 961 | #xfe5e #x309b 962 | #xfe5f #x309c 963 | #xfe64 #x02bc 964 | #xfe65 #x02bd 965 | #xfe66 #x02f5 966 | #xfe67 #x02f3 967 | #xfe68 #x02cd 968 | #xfe69 #xa788 969 | #xfe6a #x02f7 970 | #xfe6e #x0000 971 | #xfe6f #x00a4 972 | #XFE80 #x0061 973 | #XFE81 #x0041 974 | #XFE82 #x0065 975 | #XFE83 #x0045 976 | #XFE84 #x0069 977 | #XFE85 #x0049 978 | #XFE86 #x006F 979 | #XFE87 #x004F 980 | #XFE88 #x0075 981 | #XFE89 #x0055 982 | #XFFAF #x002F 983 | #xfe8a #x0259 984 | #xfe8b #x018f 985 | #xfe8c #x00b5 986 | #xfe91 #x02c8 987 | #xfe92 #x02cc 988 | #XFE50 #x0060 989 | #XFE52 #x005E 990 | #XFE53 #x007E 991 | #XFE63 #x002F 992 | #XFE90 #x005F 993 | #XFF80 #x0020 994 | #XFFAF #x002F 995 | #xff95 #x0037 996 | #xff96 #x0034 997 | #xff97 #x0038 998 | #xff98 #x0036 999 | #xff99 #x0032 1000 | #xff9a #x0039 1001 | #xff9b #x0033 1002 | #xff9c #x0031 1003 | #xff9d #x0035 1004 | #xff9e #x0030 1005 | #XFFAA #x002A 1006 | #XFFAB #x002B 1007 | #XFFAC #x0000 1008 | #XFFAD #x002D 1009 | #XFFAE #x002E 1010 | #XFFAF #x002F 1011 | #xffb0 #x0030 1012 | #xffb1 #x0031 1013 | #xffb2 #x0032 1014 | #xffb3 #x0033 1015 | #xffb4 #x0034 1016 | #xffb5 #x0035 1017 | #xffb6 #x0036 1018 | #xffb7 #x0037 1019 | #xffb8 #x0038 1020 | #xffb9 #x0039 1021 | #xffbd #x003D 1022 | -------------------------------------------------------------------------------- /xlib/bindings.lisp: -------------------------------------------------------------------------------- 1 | (in-package #:org.shirakumo.framebuffers.xlib.cffi) 2 | 3 | (cffi:define-foreign-library x11 4 | (:linux (:or (:default "libX11") "libX11.so.6")) 5 | (T (:or (:default "libX11") (:default "X11")))) 6 | 7 | (cffi:define-foreign-library xext 8 | (:linux (:or (:default "libXext") "libXext.so.6")) 9 | (T (:or (:default "libXext") (:default "Xext")))) 10 | 11 | (cffi:define-foreign-library xrandr 12 | (:linux (:or (:default "libXrandr") "libXrandr.so.2")) 13 | (T (:or (:default "libXrandr") (:default "Xrandr")))) 14 | 15 | (cffi:define-foreign-library xinerama 16 | (:linux (:or (:default "libXinerama") "libXinerama.so.1")) 17 | (T (:or (:default "libXinerama") (:default "Xinerama")))) 18 | 19 | (cffi:define-foreign-library xcursor 20 | (:linux (:or (:default "libXcursor") "libXcursor.so.1")) 21 | (T (:or (:default "libXcursor") (:default "Xcursor")))) 22 | 23 | (cffi:define-foreign-library xi 24 | (:linux (:or (:default "libXi") "libXi.so.6")) 25 | (T (:or (:default "libXi") (:default "Xi")))) 26 | 27 | (set 'cl-user::*foreign-system-libraries* 28 | (union (when (boundp 'cl-user::*foreign-system-libraries*) 29 | (symbol-value 'cl-user::*foreign-system-libraries*)) 30 | '(x11 xext xrandr xinerama xcursor xi))) 31 | 32 | (cffi:defctype xid :ulong) 33 | (cffi:defctype atom :ulong) 34 | 35 | (cffi:defcenum (event-type :uint :allow-other-keys T) 36 | (:key-press 2) 37 | (:key-release 3) 38 | (:button-press 4) 39 | (:button-release 5) 40 | (:motion-notify 6) 41 | (:enter-notify 7) 42 | (:leave-notify 8) 43 | (:focus-in 9) 44 | (:focus-out 10) 45 | (:keymap-notify 11) 46 | (:expose 12) 47 | (:graphics-expose 13) 48 | (:no-expose 14) 49 | (:visibility-notify 15) 50 | (:create-notify 16) 51 | (:destroy-notify 17) 52 | (:unmap-notify 18) 53 | (:map-notify 19) 54 | (:map-request 20) 55 | (:reparent-notify 21) 56 | (:configure-notify 22) 57 | (:configure-request 23) 58 | (:gravity-notify 24) 59 | (:resize-request 25) 60 | (:circulate-notify 26) 61 | (:circulate-request 27) 62 | (:property-notify 28) 63 | (:selection-clear 29) 64 | (:selection-request 30) 65 | (:selection-notify 31) 66 | (:colormap-notify 32) 67 | (:client-message 33) 68 | (:mapping-notify 34) 69 | (:generic-event 35)) 70 | 71 | (cffi:defcstruct (xrm-value :conc-name xrm-value-) 72 | (size :uint) 73 | (addr :pointer)) 74 | 75 | (cffi:defcstruct (error-event :conc-name error-event-) 76 | (type :int) 77 | (display :pointer) 78 | (resource-id xid) 79 | (serial :ulong) 80 | (error-code :uchar) 81 | (request-code :uchar) 82 | (minor-code :uchar)) 83 | 84 | (cffi:defcstruct (image :conc-name image-) 85 | (width :int) 86 | (height :int) 87 | (xoffset :int) 88 | (format :int) 89 | (data :pointer) 90 | (byte-order :int) 91 | (bitmap-unit :int) 92 | (bitmap-bit-order :int) 93 | (bitmap-pad :int) 94 | (depth :int) 95 | (bytes-per-line :int) 96 | (bits-per-pixel :int) 97 | (red-mask :ulong) 98 | (green-mask :ulong) 99 | (blue-mask :ulong) 100 | (obdata :pointer) 101 | (create-image :pointer) 102 | (destroy-image :pointer) 103 | (get-pixel :pointer) 104 | (put-pixel :pointer) 105 | (sub-image :pointer) 106 | (add-pixel :pointer)) 107 | 108 | (cffi:defcstruct (set-window-attributes :conc-name set-window-attributes-) 109 | (background-pixmap xid) 110 | (background-pixel :ulong) 111 | (border-pixmap xid) 112 | (border-pixel :ulong) 113 | (bit-gravity :int) 114 | (win-gravity :int) 115 | (backing-store :int) 116 | (backing-planes :ulong) 117 | (backing-pixel :ulong) 118 | (save-under :bool) 119 | (event-mask :long) 120 | (do-not-propagate-mask :long) 121 | (override-redirect :bool) 122 | (colormap xid) 123 | (cursor xid)) 124 | 125 | (cffi:defcstruct (pixmap-format :conc-name pixmap-format-) 126 | (depth :int) 127 | (bits-per-pixel :int) 128 | (scanline-pad :int)) 129 | 130 | (cffi:defbitfield size-hint-flags 131 | (:position 4) 132 | :size 133 | :min-size 134 | :max-size 135 | :resize-inc 136 | :aspect 137 | :base-size 138 | :win-gravity) 139 | 140 | (cffi:defcstruct (size-hint :conc-name size-hint-) 141 | (flags size-hint-flags) 142 | (x :int) 143 | (y :int) 144 | (width :int) 145 | (height :int) 146 | (min-width :int) 147 | (min-height :int) 148 | (max-width :int) 149 | (max-height :int) 150 | (width-inc :int) 151 | (height-inc :int) 152 | (min-aspect-x :int) 153 | (min-aspect-y :int) 154 | (max-aspect-x :int) 155 | (max-aspect-y :int) 156 | (base-width :int) 157 | (base-height :int) 158 | (win-gravity :int)) 159 | 160 | (cffi:defcstruct event 161 | (_ :char :count 192)) 162 | 163 | (cffi:defcstruct (base-event :conc-name base-event-) 164 | (type event-type) 165 | (serial :ulong) 166 | (send-event :bool) 167 | (display :pointer) 168 | (window xid)) 169 | 170 | (cffi:defcstruct (positioned-event :conc-name positioned-event-) 171 | (_ (:struct base-event)) 172 | (root xid) 173 | (subwindow xid) 174 | (time :ulong) 175 | (x :int) 176 | (y :int) 177 | (x-root :int) 178 | (y-root :int)) 179 | 180 | (cffi:defbitfield modifiers 181 | (:shift 1) 182 | (:caps-lock 2) 183 | (:control 4) 184 | (:alt 8) ; MOD1 185 | (:num-lock 16) ; MOD2 186 | (:scroll-lock 32) ; MOD3 187 | (:super 64) ; MOD4 188 | (:hyper 128)) ; MOD5 189 | 190 | (cffi:defcstruct (key-event :conc-name key-event-) 191 | (_ (:struct positioned-event)) 192 | (state modifiers) 193 | (keycode :uint) 194 | (same-screen :bool)) 195 | 196 | (cffi:defcstruct (button-event :conc-name button-event-) 197 | (_ (:struct positioned-event)) 198 | (state modifiers) 199 | (button :uint) 200 | (same-screen :bool)) 201 | 202 | (cffi:defcstruct (motion-event :conc-name motion-event-) 203 | (_ (:struct positioned-event)) 204 | (state :uint) 205 | (is-hint :char) 206 | (same-screen :bool)) 207 | 208 | (cffi:defcstruct (focus-change-event :conc-name focus-change-event-) 209 | (_ (:struct base-event)) 210 | (mode :int) 211 | (detail :int)) 212 | 213 | (cffi:defcstruct (configure-event :conc-name configure-event-) 214 | (_ (:struct base-event)) 215 | (window xid) 216 | (x :int) 217 | (y :int) 218 | (width :int) 219 | (height :int) 220 | (border-width :int) 221 | (above xid) 222 | (override-redirect :bool)) 223 | 224 | (cffi:defcstruct (property-event :conc-name property-event-) 225 | (_ (:struct base-event)) 226 | (atom atom) 227 | (time :ulong) 228 | (state :int)) 229 | 230 | (cffi:defcstruct (destroy-window-event :conc-name destroy-window-event-) 231 | (_ (:struct base-event))) 232 | 233 | (cffi:defcstruct (client-message-event :conc-name client-message-event-) 234 | (_ (:struct base-event)) 235 | (message-type atom) 236 | (format :int) 237 | (data :char :count 20)) 238 | 239 | (cffi:defcstruct (net-message-event :conc-name net-message-event-) 240 | (_ (:struct base-event)) 241 | (message-type atom) 242 | (format :int) 243 | (protocol atom)) 244 | 245 | (cffi:defcfun (black-pixel "XBlackPixel") :ulong 246 | (display :pointer) 247 | (screen :int)) 248 | 249 | (cffi:defcfun (default-depth "XDefaultDepth") :int 250 | (display :pointer) 251 | (screen :int)) 252 | 253 | (cffi:defcfun (default-gc "XDefaultGC") :pointer 254 | (display :pointer) 255 | (screen :int)) 256 | 257 | (cffi:defcfun (default-root-window "XDefaultRootWindow") xid 258 | (display :pointer)) 259 | 260 | (cffi:defcfun (default-visual "XDefaultVisual") :pointer 261 | (display :pointer) 262 | (screen :int)) 263 | 264 | (cffi:defcfun (default-screen "XDefaultScreen") :int 265 | (display :pointer)) 266 | 267 | (cffi:defcfun (display-height "XDisplayHeight") :int 268 | (display :pointer) 269 | (screen :int)) 270 | 271 | (cffi:defcfun (display-width "XDisplayWidth") :int 272 | (display :pointer) 273 | (screen :int)) 274 | 275 | (cffi:defcfun (init-threads "XInitThreads") :int) 276 | 277 | (cffi:defcfun (free-threads "XFreeThreads") :int) 278 | 279 | (cffi:defcfun (change-property "XChangeProperty") :int 280 | (display :pointer) 281 | (window xid) 282 | (property atom) 283 | (type atom) 284 | (format :int) 285 | (code :int) 286 | (data :pointer) 287 | (elements :int)) 288 | 289 | (cffi:defcfun (delete-property "XDeleteProperty") :int 290 | (display :pointer) 291 | (window xid) 292 | (property atom)) 293 | 294 | (cffi:defcfun (get-window-property "XGetWindowProperty") :int 295 | (display :pointer) 296 | (window xid) 297 | (property atom) 298 | (offset :long) 299 | (length :long) 300 | (delete :bool) 301 | (request-type atom) 302 | (actual-type :pointer) 303 | (actual-format :pointer) 304 | (item-count :pointer) 305 | (bytes-after-return :pointer) 306 | (return :pointer)) 307 | 308 | (cffi:defcfun (clear-window "XClearWindow") :int 309 | (display :pointer) 310 | (window xid)) 311 | 312 | (cffi:defcfun (clear-area "XClearArea") :int 313 | (display :pointer) 314 | (window xid) 315 | (x :int) 316 | (y :int) 317 | (width :uint) 318 | (height :uint) 319 | (exposures :bool)) 320 | 321 | (cffi:defcfun (close-display "XCloseDisplay") :int 322 | (display :pointer)) 323 | 324 | (cffi:defcfun (create-image "XCreateImage") :pointer 325 | (display :pointer) 326 | (visual :pointer) 327 | (depth :uint) 328 | (format :int) 329 | (offset :int) 330 | (data :pointer) 331 | (width :uint) 332 | (height :uint) 333 | (bitmap-pad :int) 334 | (bytes-per-line :int)) 335 | 336 | (cffi:defbitfield window-value-mask 337 | (:back-pixmap 1) 338 | :back-pixel 339 | :border-pixmap 340 | :border-pixel 341 | :bit-gravity 342 | :win-gravity 343 | :backing-store 344 | :backing-planes 345 | :backing-pixel 346 | :override-redirect 347 | :save-under 348 | :event-mask 349 | :dont-propagate 350 | :colormap 351 | :cursor) 352 | 353 | (cffi:defcfun (create-window "XCreateWindow") xid 354 | (display :pointer) 355 | (window xid) 356 | (x :int) 357 | (y :int) 358 | (width :uint) 359 | (height :uint) 360 | (border-width :uint) 361 | (depth :int) 362 | (class :uint) 363 | (visual :pointer) 364 | (value-mask window-value-mask) 365 | (attributes :pointer)) 366 | 367 | (cffi:defcfun (destroy-image "XDestroyImage") :int 368 | (image :pointer)) 369 | 370 | (cffi:defcfun (destroy-window "XDestroyWindow") :int 371 | (display :pointer) 372 | (window xid)) 373 | 374 | (cffi:defcfun (events-queued "XEventsQueued") :int 375 | (display :pointer) 376 | (mode :int)) 377 | 378 | (cffi:defcfun (flush "XFlush") :int 379 | (display :pointer)) 380 | 381 | (cffi:defcfun (sync "XSync") :int 382 | (display :pointer)) 383 | 384 | (cffi:defcfun (free "XFree") :int 385 | (data :pointer)) 386 | 387 | (cffi:defcfun (intern-atom "XInternAtom") atom 388 | (display :pointer) 389 | (name :string) 390 | (if-exists :bool)) 391 | 392 | (cffi:defcfun (list-pixmap-formats "XListPixmapFormats") :pointer 393 | (display :pointer) 394 | (count :pointer)) 395 | 396 | (cffi:defcfun (map-raised "XMapRaised") :int 397 | (display :pointer) 398 | (window xid)) 399 | 400 | (cffi:defcfun (unmap-window "XUnmapWindow") :int 401 | (display :pointer) 402 | (window xid)) 403 | 404 | (cffi:defcfun (next-event "XNextEvent") :int 405 | (display :pointer) 406 | (event :pointer)) 407 | 408 | (cffi:defcfun (open-display "XOpenDisplay") :pointer 409 | (name :string)) 410 | 411 | (cffi:defcfun (peek-event "XPeekEvent") :int 412 | (display :pointer) 413 | (event :pointer)) 414 | 415 | (cffi:defcfun (pending "XPending") :int 416 | (display :pointer)) 417 | 418 | (cffi:defcfun (put-image "XPutImage") :int 419 | (display :pointer) 420 | (drawable xid) 421 | (gc :pointer) 422 | (image :pointer) 423 | (x :int) 424 | (y :int) 425 | (dst-x :int) 426 | (dst-y :int) 427 | (width :uint) 428 | (height :uint)) 429 | 430 | (cffi:defbitfield (event-mask :long) 431 | (:key-press 1) 432 | :key-release 433 | :button-press 434 | :button-release 435 | :enter-window 436 | :leave-window 437 | :pointer-motion 438 | :pointer-motion-hint 439 | :button1-motion 440 | :button2-motion 441 | :button3-motion 442 | :button4-motion 443 | :button5-motion 444 | :button-motion 445 | :keymap-state 446 | :exposure 447 | :visibility-change 448 | :structure-notify 449 | :resize-redirect 450 | :substructure-notify 451 | :substructure-redirect 452 | :focus-change 453 | :property-change 454 | :colormap-change 455 | :owner-grab-button) 456 | 457 | (cffi:defcfun (select-input "XSelectInput") :int 458 | (display :pointer) 459 | (window xid) 460 | (event-mask event-mask)) 461 | 462 | (cffi:defcfun (set-wm-normal-hints "XSetWMNormalHints") :void 463 | (display :pointer) 464 | (window xid) 465 | (hints :pointer)) 466 | 467 | (cffi:defcfun (set-wm-protocols "XSetWMProtocols") :int 468 | (display :pointer) 469 | (window xid) 470 | (protocols :pointer) 471 | (count :int)) 472 | 473 | (cffi:defcfun (store-name "XStoreName") :int 474 | (display :pointer) 475 | (window xid) 476 | (name :string)) 477 | 478 | (cffi:defcfun (move-window "XMoveWindow") :int 479 | (display :pointer) 480 | (window xid) 481 | (x :int) 482 | (y :int)) 483 | 484 | (cffi:defcfun (resize-window "XResizeWindow") :int 485 | (display :pointer) 486 | (window xid) 487 | (width :uint) 488 | (height :uint)) 489 | 490 | (cffi:defcfun (send-event "XSendEvent") :int 491 | (display :pointer) 492 | (window xid) 493 | (propagate :bool) 494 | (event-mask :long) 495 | (event :pointer)) 496 | 497 | (cffi:defcfun (iconify-window "XIconifyWindow") :int 498 | (display :pointer) 499 | (window xid) 500 | (screen :int)) 501 | 502 | (cffi:defcfun (set-error-handler "XSetErrorHandler") :pointer 503 | (handler :pointer)) 504 | 505 | (cffi:defcfun (set-io-error-handler "XSetIOErrorHandler") :pointer 506 | (handler :pointer)) 507 | 508 | (cffi:defcfun (set-io-error-exit-handler "XSetIOErrorExitHandler") :void 509 | (display :pointer) 510 | (handler :pointer) 511 | (user-data :pointer)) 512 | 513 | (cffi:defcfun (get-error-text "XGetErrorText") :int 514 | (display :pointer) 515 | (code :int) 516 | (buffer :pointer) 517 | (length :int)) 518 | 519 | (cffi:defcfun (display-keycodes "XDisplayKeycodes") :int 520 | (display :pointer) 521 | (min :pointer) 522 | (max :pointer)) 523 | 524 | (cffi:defcfun (connection-number "XConnectionNumber") :int 525 | (display :pointer)) 526 | 527 | (cffi:defcfun (get-keyboard-mapping "XGetKeyboardMapping") :pointer 528 | (display :pointer) 529 | (first :uchar) 530 | (count :int) 531 | (width :pointer)) 532 | 533 | (cffi:defcfun (resource-manager-string "XResourceManagerString") :pointer 534 | (display :pointer)) 535 | 536 | (cffi:defcfun (xrm-get-string-database "XrmGetStringDatabase") :pointer 537 | (string :pointer)) 538 | 539 | (cffi:defcfun (xrm-get-resource "XrmGetResource") :bool 540 | (database :pointer) 541 | (name :string) 542 | (class :string) 543 | (str-return :pointer) 544 | (value :pointer)) 545 | 546 | (cffi:defcfun (xrm-destroy-database "XrmDestroyDatabase") :void 547 | (database :pointer)) 548 | 549 | (cffi:defcfun (utf8-lookup-string "Xutf8LookupString") :int 550 | (ic :pointer) 551 | (event :pointer) 552 | (buffer :pointer) 553 | (bytes :int) 554 | (keysym :pointer) 555 | (status :pointer)) 556 | 557 | (cffi:defcfun (lookup-string "XLookupString") :int 558 | (event :pointer) 559 | (buffer :pointer) 560 | (bytes :int) 561 | (keysym :pointer) 562 | (status :pointer)) 563 | 564 | ;; XKB 565 | (cffi:defcstruct (xkb-desc :conc-name xkb-desc-) 566 | (display :pointer) 567 | (flags :ushort) 568 | (device-spec :ushort) 569 | (min-key-code :uchar) 570 | (max-key-code :uchar) 571 | (controls :pointer) 572 | (server-map :pointer) 573 | (client-map :pointer) 574 | (indicator :pointer) 575 | (names :pointer) 576 | (compat-map :pointer) 577 | (geometry :pointer)) 578 | 579 | (cffi:defcstruct (xkb-key :conc-name xkb-key-) 580 | (name :char :count 4)) 581 | 582 | (cffi:defcstruct (xkb-alias :conc-name xkb-alias-) 583 | (real :char :count 4) 584 | (alias :char :count 4)) 585 | 586 | (cffi:defcstruct (xkb-names :conc-name xkb-names-) 587 | (keycodes atom) 588 | (geometry atom) 589 | (symbols atom) 590 | (types atom) 591 | (compat atom) 592 | (vmods atom :count 16) 593 | (indicators atom :count 32) 594 | (groups atom :count 4) 595 | (keys :pointer) 596 | (key-aliases :pointer) 597 | (radio-groups :pointer) 598 | (phys-symbols atom) 599 | (num-keys :uchar) 600 | (num-key-aliases :uchar) 601 | (num-rg :ushort)) 602 | 603 | (cffi:defcfun (xkb-query-extension "XkbQueryExtension") :bool 604 | (display :pointer) 605 | (opcode :pointer) 606 | (event-base :pointer) 607 | (error-base :pointer) 608 | (major :pointer) 609 | (minor :pointer)) 610 | 611 | (cffi:defcfun (xkb-keycode-to-keysym "XkbKeycodeToKeysym") xid 612 | (display :pointer) 613 | (code :uchar) 614 | (group :int) 615 | (level :int)) 616 | 617 | (cffi:defcfun (xkb-get-map "XkbGetMap") :pointer 618 | (display :pointer) 619 | (which :uint) 620 | (device-spec :uint)) 621 | 622 | (cffi:defcfun (xkb-get-names "XkbGetNames") :int 623 | (display :pointer) 624 | (which :uint) 625 | (desc :pointer)) 626 | 627 | (cffi:defcfun (xkb-free-names "XkbFreeNames") :void 628 | (desc :pointer) 629 | (which :uint) 630 | (free :bool)) 631 | 632 | (cffi:defcfun (xkb-free-keyboard "XkbFreeKeyboard") :void 633 | (desc :pointer) 634 | (which :uint) 635 | (free :bool)) 636 | 637 | ;; XSHM 638 | (cffi:defcstruct (shm-segment-info :conc-name shm-segment-info-) 639 | (message :ulong) 640 | (id :int) 641 | (address :pointer) 642 | (read-only :bool)) 643 | 644 | (cffi:defcfun (xshm-query-extension "XShmQueryExtension") :bool 645 | (display :pointer)) 646 | 647 | (cffi:defcfun (xshm-pixmap-format "XShmPixmapFormat") :int 648 | (display :pointer)) 649 | 650 | (cffi:defcfun (xshm-put-image "XShmPutImage") :bool 651 | (display :pointer) 652 | (drawable xid) 653 | (gc :pointer) 654 | (image :pointer) 655 | (x :int) 656 | (y :int) 657 | (dst-x :int) 658 | (dst-y :int) 659 | (width :uint) 660 | (height :uint) 661 | (send-event :bool)) 662 | 663 | (cffi:defcfun (xshm-create-image "XShmCreateImage") :pointer 664 | (display :pointer) 665 | (visual :pointer) 666 | (depth :uint) 667 | (format :int) 668 | (data :pointer) 669 | (shm-info :pointer) 670 | (width :uint) 671 | (height :uint)) 672 | 673 | (cffi:defcfun (xshm-attach "XShmAttach") :bool 674 | (display :pointer) 675 | (shm :pointer)) 676 | 677 | (cffi:defcfun (xshm-detach "XShmDetach") :bool 678 | (display :pointer) 679 | (shm :pointer)) 680 | 681 | ;; Xrandr Xinerama 682 | (cffi:defbitfield (mode-flags :ulong) 683 | (:H-Sync-Positive #x00000001) 684 | (:H-Sync-Negative #x00000002) 685 | (:V-Sync-Positive #x00000004) 686 | (:V-Sync-Negative #x00000008) 687 | (:Interlace #x00000010) 688 | (:Double-Scan #x00000020) 689 | (:C-Sync #x00000040) 690 | (:C-Sync-Positive #x00000080) 691 | (:C-Sync-Negative #x00000100) 692 | (:H-Skew-Present #x00000200) 693 | (:BCast #x00000400) 694 | (:Pixel-Multiplex #x00000800) 695 | (:Double-Clock #x00001000) 696 | (:Clock-Divide-By-2 #x00002000)) 697 | 698 | (cffi:defbitfield (rotation :ushort) 699 | (:0 1) 700 | (:90 2) 701 | (:180 4) 702 | (:270 8) 703 | (:reflect-x 16) 704 | (:reflect-y 32)) 705 | 706 | (cffi:defcenum (connection :ushort) 707 | (:connected 0) 708 | (:disconnected 1) 709 | (:unknown 2)) 710 | 711 | (cffi:defcstruct (output-info :conc-name output-info-) 712 | (timestamp :ulong) 713 | (crtc xid) 714 | (name :string) 715 | (name-length :int) 716 | (mm-width :ulong) 717 | (mm-height :ulong) 718 | (connection connection) 719 | (subpixel-order :ushort) 720 | (crtc-count :int) 721 | (crtcs :pointer) 722 | (clone-count :int) 723 | (clones :pointer) 724 | (mode-count :int) 725 | (preferred :int) 726 | (modes :pointer)) 727 | 728 | (cffi:defcstruct (screen-resources :conc-name screen-resources-) 729 | (timestamp :ulong) 730 | (config-timestamp :ulong) 731 | (crtc-count :int) 732 | (crtcs :pointer) 733 | (output-count :int) 734 | (outputs :pointer) 735 | (mode-count :int) 736 | (modes :pointer)) 737 | 738 | (cffi:defcstruct (mode-info :conc-name mode-info-) 739 | (id xid) 740 | (width :uint) 741 | (height :uint) 742 | (dot-clock :ulong) 743 | (hsync-start :uint) 744 | (hsync-end :uint) 745 | (htotal :uint) 746 | (hskew :uint) 747 | (vsync-start :uint) 748 | (vsync-end :uint) 749 | (vtotal :uint) 750 | (name :string) 751 | (name-length :uint) 752 | (flags mode-flags)) 753 | 754 | (cffi:defcstruct (crtc-info :conc-name crtc-info-) 755 | (timestamp :ulong) 756 | (x :int) 757 | (y :int) 758 | (width :uint) 759 | (height :uint) 760 | (mode xid) 761 | (rotation rotation) 762 | (output-count :int) 763 | (outputs :pointer) 764 | (rotations rotation) 765 | (possible-count :int) 766 | (possibles :pointer)) 767 | 768 | (cffi:defcstruct (screen :conc-name screen-) 769 | (number :int) 770 | (x :short) 771 | (y :short) 772 | (width :short) 773 | (height :short)) 774 | 775 | (cffi:defcfun (xrr-query-extension "XRRQueryExtension") :bool 776 | (display :pointer) 777 | (event-base :pointer) 778 | (error-base :pointer)) 779 | 780 | (cffi:defcfun (xrr-get-screen-resources-current "XRRGetScreenResourcesCurrent") :pointer 781 | (display :pointer) 782 | (root xid)) 783 | 784 | (cffi:defcfun (xrr-get-output-primary "XRRGetOutputPrimary") xid 785 | (display :pointer) 786 | (root xid)) 787 | 788 | (cffi:defcfun (xrr-get-output-info "XRRGetOutputInfo") :pointer 789 | (display :pointer) 790 | (screen-resources :pointer) 791 | (output xid)) 792 | 793 | (cffi:defcfun (xrr-get-crtc-info "XRRGetCrtcInfo") :pointer 794 | (display :pointer) 795 | (screen-resources :pointer) 796 | (crtc xid)) 797 | 798 | (cffi:defcfun (xrr-free-crtc-info "XRRFreeCrtcInfo") :void 799 | (info :pointer)) 800 | 801 | (cffi:defcfun (xrr-free-output-info "XRRFreeOutputInfo") :void 802 | (info :pointer)) 803 | 804 | (cffi:defcfun (xrr-free-screen-resources "XRRFreeScreenResources") :void 805 | (info :pointer)) 806 | 807 | (cffi:defcfun (xrr-set-crtc-config "XRRSetCrtcConfig") :int 808 | (display :Pointer) 809 | (screen-resources :pointer) 810 | (crtc xid) 811 | (timestamp :ulong) 812 | (x :int) 813 | (y :int) 814 | (mode xid) 815 | (rotation rotation) 816 | (outputs :pointer) 817 | (output-count :int)) 818 | 819 | (cffi:defcfun (xrr-update-configuration "XRRUpdateConfiguration") :int 820 | (event :pointer)) 821 | 822 | (cffi:defcfun (xinerama-query-extension "XineramaQueryExtension") :bool 823 | (display :pointer) 824 | (event-base :pointer) 825 | (error-base :pointer)) 826 | 827 | (cffi:defcfun (xinerama-query-screens "XineramaQueryScreens") :pointer 828 | (display :pointer) 829 | (count :pointer)) 830 | 831 | -------------------------------------------------------------------------------- /internal.lisp: -------------------------------------------------------------------------------- 1 | (in-package #:org.shirakumo.framebuffers.int) 2 | 3 | (defun dbg (fmt &rest args) 4 | (format *standard-output* "~&> ~?~%" fmt args) 5 | (finish-output *standard-output*)) 6 | 7 | (defvar *here* #.(make-pathname :name NIL :type NIL :defaults (or *compile-file-pathname* *load-pathname* (error "Need compile-file or load.")))) 8 | (defvar *windows-table* (make-hash-table :test 'eql)) 9 | (defvar *available-backends* ()) 10 | (defvar *backend* NIL) 11 | 12 | (defgeneric init-backend (backend)) 13 | (defgeneric shutdown-backend (backend)) 14 | (defgeneric open-backend (backend &key)) 15 | (defgeneric list-displays-backend (backend)) 16 | (defgeneric wait-for-events (backend windows &key timeout)) 17 | 18 | (defun static-file (path) 19 | (merge-pathnames path *here*)) 20 | 21 | (defun default-title () 22 | (format NIL "Framebuffer (~a ~a)" (lisp-implementation-type) (lisp-implementation-version))) 23 | 24 | (declaim (inline ptr-int)) 25 | (defun ptr-int (ptr) 26 | (etypecase ptr 27 | #+cffi 28 | (cffi:foreign-pointer (cffi:pointer-address ptr)) 29 | ((integer 1) ptr))) 30 | 31 | (declaim (inline ptr-window)) 32 | (defun ptr-window (ptr) 33 | (gethash (ptr-int ptr) *windows-table*)) 34 | 35 | (defun (setf ptr-window) (window ptr) 36 | (if window 37 | (setf (gethash (ptr-int ptr) *windows-table*) window) 38 | (remhash (ptr-int ptr) *windows-table*)) 39 | window) 40 | 41 | (defun list-windows () 42 | (loop for window being the hash-values of *windows-table* 43 | collect window)) 44 | 45 | (defun init (&optional backend) 46 | (cond (backend 47 | (init-backend backend) 48 | backend) 49 | (T 50 | (dolist (backend *available-backends*) 51 | (handler-case 52 | (progn (init-backend backend) 53 | (setf *backend* backend) 54 | (return-from init backend)) 55 | (error ()))) 56 | (if *available-backends* 57 | (error "Tried to configure ~{~a~^, ~a~}, but none would start properly." *available-backends*) 58 | (error "There are no available backends for your system."))))) 59 | 60 | (defun shutdown () 61 | (when *backend* 62 | (dolist (window (list-windows)) 63 | (ignore-errors (close window))) 64 | (shutdown-backend (shiftf *backend* NIL)) 65 | (clrhash *windows-table*))) 66 | 67 | (defun list-displays () 68 | (list-displays-backend (or *backend* (init)))) 69 | 70 | (defun open (&rest args &key size location title visible-p maximum-size minimum-size maximized-p iconified-p borderless-p always-on-top-p floating-p resizable-p &allow-other-keys) 71 | (declare (ignore size location title visible-p)) 72 | (let ((window (apply #'open-backend (or *backend* (init)) 73 | ;; We filter this way to allow backend-specific extension args 74 | (loop for (k v) on args by #'cddr 75 | for culled-prop-p = (find k '(:maximum-size :minimum-size :maximized-p :iconified-p :borderless-p :always-on-top-p :floating-p :resizable-p)) 76 | unless culled-prop-p collect k 77 | unless culled-prop-p collect v)))) 78 | (when maximum-size (setf (fb:maximum-size window) maximum-size)) 79 | (when minimum-size (setf (fb:minimum-size window) minimum-size)) 80 | (when maximized-p (setf (fb:maximized-p window) maximized-p)) 81 | (when iconified-p (setf (fb:iconified-p window) iconified-p)) 82 | (when borderless-p (setf (fb:borderless-p window) borderless-p)) 83 | (when always-on-top-p (setf (fb:always-on-top-p window) always-on-top-p)) 84 | (when floating-p (setf (fb:floating-p window) floating-p)) 85 | (when resizable-p (setf (fb:resizable-p window) resizable-p)) 86 | window)) 87 | 88 | (defmethod print-object ((icon fb:icon) stream) 89 | (print-unreadable-object (icon stream :type T :identity T) 90 | (format stream "~a x ~a" (width icon) (height icon)))) 91 | 92 | (defmethod width ((icon fb:icon)) 93 | (icon-width icon)) 94 | 95 | (defmethod (setf width) (value (icon fb:icon)) 96 | (setf (icon-width icon) value)) 97 | 98 | (defmethod height ((icon fb:icon)) 99 | (icon-height icon)) 100 | 101 | (defmethod (setf height) (value (icon fb:icon)) 102 | (setf (icon-height icon) value)) 103 | 104 | (defmethod buffer ((icon fb:icon)) 105 | (icon-buffer icon)) 106 | 107 | (defmethod (setf buffer) (value (icon fb:icon)) 108 | (setf (icon-buffer icon) value)) 109 | 110 | (defmethod print-object ((touchpoint touchpoint) stream) 111 | (print-unreadable-object (touchpoint stream :type T :identity T) 112 | (format stream "~a" (location touchpoint)))) 113 | 114 | (defmethod fb:location ((touchpoint touchpoint)) 115 | (touchpoint-location touchpoint)) 116 | 117 | (defmethod location ((touchpoint touchpoint)) 118 | (touchpoint-location touchpoint)) 119 | 120 | (defmethod (setf location) (location (touchpoint touchpoint)) 121 | (setf (touchpoint-location touchpoint) location)) 122 | 123 | (defmethod fb:radius ((touchpoint touchpoint)) 124 | (touchpoint-radius touchpoint)) 125 | 126 | (defmethod radius ((touchpoint touchpoint)) 127 | (touchpoint-radius touchpoint)) 128 | 129 | (defmethod (setf radius) (radius (touchpoint touchpoint)) 130 | (setf (touchpoint-radius touchpoint) radius)) 131 | 132 | (defmethod fb:angle ((touchpoint touchpoint)) 133 | (touchpoint-angle touchpoint)) 134 | 135 | (defmethod angle ((touchpoint touchpoint)) 136 | (touchpoint-angle touchpoint)) 137 | 138 | (defmethod (setf angle) (angle (touchpoint touchpoint)) 139 | (setf (touchpoint-angle touchpoint) angle)) 140 | 141 | (defmethod fb:pressure ((touchpoint touchpoint)) 142 | (touchpoint-pressure touchpoint)) 143 | 144 | (defmethod pressure ((touchpoint touchpoint)) 145 | (touchpoint-pressure touchpoint)) 146 | 147 | (defmethod (setf pressure) (pressure (touchpoint touchpoint)) 148 | (setf (touchpoint-pressure touchpoint) pressure)) 149 | 150 | (defmethod print-object ((video-mode fb:video-mode) stream) 151 | (print-unreadable-object (video-mode stream :type T) 152 | (format stream "~a" (fb:title video-mode)))) 153 | 154 | (defmethod fb:display ((video-mode fb:video-mode)) 155 | (video-mode-display video-mode)) 156 | 157 | (defmethod display ((video-mode fb:video-mode)) 158 | (video-mode-display video-mode)) 159 | 160 | (defmethod (setf display) (display (video-mode fb:video-mode)) 161 | (setf (video-mode-display video-mode) display)) 162 | 163 | (defmethod width ((video-mode fb:video-mode)) 164 | (video-mode-width video-mode)) 165 | 166 | (defmethod height ((video-mode fb:video-mode)) 167 | (video-mode-height video-mode)) 168 | 169 | (defmethod refresh-rate ((video-mode fb:video-mode)) 170 | (video-mode-refresh-rate video-mode)) 171 | 172 | (defmethod fb:id ((video-mode fb:video-mode)) 173 | (format NIL "~dx~d@~d~@[-~a~]" 174 | (width video-mode) (height video-mode) 175 | (refresh-rate video-mode) (when (display video-mode) 176 | (id (display video-mode))))) 177 | 178 | (defmethod fb:title ((video-mode fb:video-mode)) 179 | (format NIL "~dx~d @ ~dHz~@[ ~a~]" 180 | (width video-mode) (height video-mode) 181 | (refresh-rate video-mode) (when (display video-mode) 182 | (or (title (display video-mode)) (id (display video-mode)))))) 183 | 184 | (defmethod fb:size ((video-mode fb:video-mode)) 185 | (cons (video-mode-width video-mode) 186 | (video-mode-height video-mode))) 187 | 188 | (defclass display () 189 | ((id :initarg :id :reader fb:id :accessor id) 190 | (title :initarg :title :initform NIL :reader fb:title :accessor title) 191 | (size :initform (cons 0 0) :initarg :size :reader fb:size :accessor size) 192 | (location :initform (cons 0 0) :initarg :location :reader fb:location :accessor location) 193 | (primary-p :initform NIL :initarg :primary-p :reader fb:primary-p :accessor primary-p) 194 | (video-mode :initform NIL :initarg :video-mode :reader fb:video-mode :accessor video-mode) 195 | (video-modes :initform () :initarg :video-modes :reader fb:video-modes :accessor video-modes))) 196 | 197 | (defmethod shared-initialize :after ((display display) slots &key) 198 | (dolist (mode (video-modes display)) 199 | (setf (video-mode-display mode) display)) 200 | (when (fb:video-mode display) 201 | (setf (car (fb:size display)) (fb:width (fb:video-mode display))) 202 | (setf (cdr (fb:size display)) (fb:height (fb:video-mode display))))) 203 | 204 | (defmethod print-object ((display display) stream) 205 | (print-unreadable-object (display stream :type T) 206 | (format stream "~a~@[ PRIMARY~]" (or (title display) (id display)) (primary-p display)))) 207 | 208 | (defmethod width ((display display)) 209 | (car (size display))) 210 | 211 | (defmethod height ((display display)) 212 | (cdr (size display))) 213 | 214 | (defmethod (setf video-mode) :after ((video-mode fb:video-mode) (display display)) 215 | (setf (car (size display)) (fb:width video-mode)) 216 | (setf (cdr (size display)) (fb:height video-mode))) 217 | 218 | (defclass window () 219 | ((event-handler :initform (make-instance 'event-handler) :accessor event-handler) 220 | (mouse-location :initform (cons 0 0) :accessor mouse-location) 221 | (key-states :initform (make-array 356 :element-type 'bit) :accessor key-states) 222 | (mouse-states :initform (make-array 10 :element-type 'bit) :accessor mouse-states) 223 | (close-requested-p :initform NIL :initarg :close-requested-p :accessor fb:close-requested-p :accessor close-requested-p) 224 | (maximum-size :initform (cons NIL NIL) :initarg :maximum-size :reader fb:maximum-size :accessor maximum-size) 225 | (minimum-size :initform (cons 1 1) :initarg :minimum-size :reader fb:minimum-size :accessor minimum-size) 226 | (size :initform (cons 0 0) :initarg :size :reader fb:size :accessor size) 227 | (location :initform (cons 0 0) :initarg :location :reader fb:location :accessor location) 228 | (title :initform "" :initarg :title :reader fb:title :accessor title) 229 | (visible-p :initform NIL :initarg :visible-p :reader fb:visible-p :accessor visible-p) 230 | (maximized-p :initform NIL :initarg :maximized-p :reader fb:maximized-p :accessor maximized-p) 231 | (iconified-p :initform NIL :initarg :iconified-p :reader fb:iconified-p :accessor iconified-p) 232 | (focused-p :initform NIL :initarg :focused-p :reader fb:focused-p :accessor focused-p) 233 | (borderless-p :initform NIL :initarg :borderless-p :reader fb:borderless-p :accessor borderless-p) 234 | (always-on-top-p :initform NIL :initarg :always-on-top-p :reader fb:always-on-top-p :accessor always-on-top-p) 235 | (resizable-p :initform NIL :initarg :resizable-p :reader fb:resizable-p :accessor resizable-p) 236 | (floating-p :initform NIL :initarg :floating-p :reader fb:floating-p :accessor floating-p) 237 | (mouse-entered-p :initform NIL :initarg :mouse-entered-p :reader fb:mouse-entered-p :accessor mouse-entered-p) 238 | (fullscren-p :initform NIL :initarg :fullscreen-p :reader fb:fullscreen-p :accessor fullscreen-p) 239 | (content-scale :initform (cons 1 1) :initarg :content-scale :reader fb:content-scale :accessor content-scale) 240 | (icon :initform NIL :initarg :icon :reader fb:icon :accessor icon) 241 | (cursor-icon :initform :arrow :initarg :cursor-icon :reader fb:cursor-icon :accessor cursor-icon) 242 | (cursor-state :initform :normal :initarg :cursor-state :reader fb:cursor-state :accessor cursor-state))) 243 | 244 | (defmethod print-object ((window window) stream) 245 | (print-unreadable-object (window stream :type T :identity T) 246 | (if (valid-p window) 247 | (format stream "~dx~d" (width window) (height window)) 248 | (format stream "CLOSED")))) 249 | 250 | (defmethod initialize-instance :after ((window window) &key event-handler) 251 | (setf (event-handler window) event-handler)) 252 | 253 | (defmethod (setf event-handler) :before ((handler event-handler) (window window)) 254 | (setf (window handler) window)) 255 | 256 | (defmethod mouse-button-pressed-p (button (window window)) 257 | (< 0 (sbit (mouse-states window) (case button 258 | (:left 0) 259 | (:right 1) 260 | (:middle 2) 261 | (T (+ 3 button)))))) 262 | 263 | (defmethod key-pressed-p ((scancode integer) (window window)) 264 | (when (<= 0 scancode 355) 265 | (< 0 (sbit (key-states window) scancode)))) 266 | 267 | (defmethod key-pressed-p ((key symbol) (window window)) 268 | (let ((scancode (key-scan-code key window))) 269 | (when (<= 0 scancode 355) 270 | (< 0 (sbit (key-states window) scancode))))) 271 | 272 | (defmethod local-key-string ((key symbol) (window window)) 273 | (let ((code (key-scan-code key window))) 274 | (when code (local-key-string code window)))) 275 | 276 | (defmethod width ((window window)) 277 | (car (size window))) 278 | 279 | (defmethod height ((window window)) 280 | (cdr (size window))) 281 | 282 | (defmethod fb:close :before ((window window)) 283 | (setf (close-requested-p window) T)) 284 | 285 | (defun find-mode-by-id (id) 286 | (loop for display in (list-displays) 287 | do (when (string= id (fb:id display)) 288 | (return-from find-mode-by-id display)) 289 | (loop for mode in (video-modes display) 290 | do (when (string= id (fb:id mode)) 291 | (return-from find-mode-by-id mode))))) 292 | 293 | (defmethod (setf fb:fullscreen-p) ((string string) (window window)) 294 | (setf (fb:fullscreen-p window) (or (find-mode-by-id string) T))) 295 | 296 | (defmethod (setf fb:fullscreen-p) ((default (eql T)) (window window)) 297 | (setf (fb:fullscreen-p window) (or (fb:display window) 298 | (find-if #'fb:primary-p (list-displays)) 299 | (first (list-displays))))) 300 | 301 | (defmethod (setf fb:fullscreen-p) ((display display) (window window)) 302 | (setf (fb:fullscreen-p window) (video-mode display))) 303 | 304 | (defmethod fb:display ((window window)) 305 | ;; Estimate display by window and display placement 306 | (let* ((displays (fb:list-displays)) 307 | (best (first displays))) 308 | (destructuring-bind (ww . wh) (size window) 309 | (destructuring-bind (wx . wy) (location window) 310 | (flet ((sigdist (display) 311 | (destructuring-bind (mw . mh) (size display) 312 | (destructuring-bind (mx . my) (location display) 313 | (let* ((x- (max wx mx)) 314 | (y- (max wy my)) 315 | (x+ (min (+ wx ww) (+ mx mw))) 316 | (y+ (min (+ wy wh) (+ my mh)))) 317 | (* (- x+ x-) (- y+ y-))))))) 318 | (dolist (display (rest displays) best) 319 | (when (< (sigdist best) (sigdist display)) 320 | (setf best display)))))))) 321 | 322 | (defmethod (setf fb:cursor-icon) ((value null) (window window)) 323 | (setf (fb:cursor-icon window) :arrow)) 324 | 325 | (defmacro define-event-callback (name args) 326 | `(progn 327 | (defmethod ,name ((window window) ,@args) 328 | (,name (event-handler window) ,@args)) 329 | 330 | (defmethod ,name ((handler event-handler) ,@args)) 331 | 332 | (defmethod ,name ((handler dynamic-event-handler) ,@args) 333 | (funcall (handler handler) ',name (window handler) ,@args)))) 334 | 335 | (defclass dynamic-event-handler (event-handler) 336 | ((handler :initarg :handler :accessor handler))) 337 | 338 | (define-event-callback window-moved (xpos ypos)) 339 | (define-event-callback window-resized (width height)) 340 | (define-event-callback window-refreshed ()) 341 | (define-event-callback window-focused (focused-p)) 342 | (define-event-callback window-iconified (iconified-p)) 343 | (define-event-callback window-maximized (maximized-p)) 344 | (define-event-callback window-closed ()) 345 | (define-event-callback mouse-button-changed (button action modifiers)) 346 | (define-event-callback mouse-moved (xpos ypos)) 347 | (define-event-callback mouse-entered (entered-p)) 348 | (define-event-callback mouse-scrolled (xoffset yoffset)) 349 | (define-event-callback key-changed (key scan-code action modifiers)) 350 | (define-event-callback string-entered (string)) 351 | (define-event-callback file-dropped (paths)) 352 | (define-event-callback content-scale-changed (xscale yscale)) 353 | (define-event-callback touch-started (points)) 354 | (define-event-callback touch-moved (points)) 355 | (define-event-callback touch-ended (points)) 356 | (define-event-callback touch-cancelled (points)) 357 | (define-event-callback pen-moved (xpos ypos mode pressure xtilt ytilt)) 358 | (define-event-callback timer-triggered (timer)) 359 | 360 | (defmethod window-moved :before ((window window) x y) 361 | (setf (car (location window)) x) 362 | (setf (cdr (location window)) y)) 363 | 364 | (defmethod window-resized :before ((window window) width height) 365 | (setf (car (size window)) width) 366 | (setf (cdr (size window)) height)) 367 | 368 | (defmethod window-focused :before ((window window) focused-p) 369 | (unless focused-p 370 | (fill (mouse-states window) 0) 371 | (fill (key-states window) 0)) 372 | (setf (focused-p window) focused-p)) 373 | 374 | (defmethod window-iconified :before ((window window) iconified-p) 375 | (when iconified-p 376 | (fill (mouse-states window) 0) 377 | (fill (key-states window) 0)) 378 | (setf (iconified-p window) iconified-p)) 379 | 380 | (defmethod window-maximized :before ((window window) maximized-p) 381 | (setf (maximized-p window) maximized-p)) 382 | 383 | (defmethod window-closed :before ((window window)) 384 | (setf (close-requested-p window) T)) 385 | 386 | (defmethod mouse-button-changed :before ((window window) button action modifiers) 387 | (let ((scan-code (case button 388 | (:left 0) 389 | (:right 1) 390 | (:middle 2) 391 | (T (+ 3 button))))) 392 | (case action 393 | (:press (setf (sbit (mouse-states window) scan-code) 1)) 394 | (:release (setf (sbit (mouse-states window) scan-code) 0))))) 395 | 396 | (defmethod mouse-moved :before ((window window) xpos ypos) 397 | (setf (car (mouse-location window)) xpos) 398 | (setf (car (mouse-location window)) ypos)) 399 | 400 | (defmethod mouse-entered :before ((window window) entered-p) 401 | (setf (mouse-entered-p window) entered-p)) 402 | 403 | (defmethod key-changed :before ((window window) key scan-code action modifiers) 404 | (when (<= 0 scan-code 355) 405 | (case action 406 | (:press (setf (sbit (key-states window) scan-code) 1)) 407 | (:release (setf (sbit (key-states window) scan-code) 0))))) 408 | 409 | (defmethod content-scale-changed :before ((window window) xscale yscale) 410 | (setf (car (content-scale window)) xscale) 411 | (setf (car (content-scale window)) yscale)) 412 | 413 | (defun resize-buffer (w h &optional old-buffer ow oh) 414 | (let ((buffer #+static-vectors (static-vectors:make-static-vector (* 4 w h) :initial-element 0 #+static-vectors-aligned :alignment #+static-vectors-aligned 4096) 415 | #-static-vectors (make-array (* 4 w h) :element-type '(unsigned-byte 8) :initial-element 0))) 416 | (when old-buffer 417 | ;; Copy sub-region back. 418 | (dotimes (y (min h oh)) 419 | (dotimes (x (min w ow)) 420 | (setf (nibbles:ub32ref/le buffer (* 4 (+ x (* w y)))) 421 | (nibbles:ub32ref/le old-buffer (* 4 (+ x (* ow y))))))) 422 | #+static-vectors (static-vectors:free-static-vector old-buffer)) 423 | buffer)) 424 | 425 | (defmacro with-cleanup (cleanup &body body) 426 | (let ((ok (gensym "OK"))) 427 | `(let ((,ok NIL)) 428 | (unwind-protect 429 | (multiple-value-prog1 (progn ,@body) 430 | (setf ,ok T)) 431 | (unless ,ok 432 | ,cleanup))))) 433 | 434 | (defmacro clean (window accessor free) 435 | `(let ((,accessor (,accessor ,window))) 436 | (when ,accessor 437 | (,free ,accessor) 438 | (setf (,accessor ,window) NIL)))) 439 | 440 | (defmacro with-window ((window &rest initargs) &body handlers) 441 | (let ((handle (gensym "HANDLE")) 442 | (event-type (gensym "EVENT-TYPE")) 443 | (args (gensym "ARGS"))) 444 | `(flet ((,handle (,event-type ,window &rest ,args) 445 | (case ,event-type 446 | ,@(loop for (type lambda-list . body) in handlers 447 | collect (if (eql T type) 448 | `(,type (destructuring-bind ,lambda-list (list* ,event-type ,args) 449 | ,@body)) 450 | `(,type (destructuring-bind ,lambda-list ,args 451 | ,@body))))))) 452 | (let ((,window (open :event-handler (make-instance 'dynamic-event-handler :handler #',handle) ,@initargs))) 453 | (unwind-protect 454 | (loop initially (,handle 'init ,window) 455 | finally (,handle 'shutdown ,window) 456 | until (close-requested-p ,window) 457 | do (process-events ,window :timeout T)) 458 | (close ,window)))))) 459 | 460 | (defmethod process-events ((windows list) &key timeout) 461 | (dolist (window (wait-for-events *backend* windows :timeout timeout)) 462 | (process-events window :timeout NIL))) 463 | 464 | #-mezzano 465 | (trivial-indent:define-indentation with-window 466 | (4 &rest (&whole 2 6 &body))) 467 | 468 | (defmacro do-pixels ((buf i x y) window &body body) 469 | (let ((wg (gensym "WIDTH")) 470 | (hg (gensym "HEIGHT")) 471 | (win (gensym "WINDOW"))) 472 | `(let* ((,i 0) 473 | (,win ,window) 474 | (,buf (buffer ,win))) 475 | (destructuring-bind (,wg . ,hg) (size ,win) 476 | (declare (type (simple-array (unsigned-byte 8) (*)) ,buf)) 477 | (declare (type (unsigned-byte 32) ,i ,wg ,hg)) 478 | (dotimes (,y ,hg ,buf) 479 | (dotimes (,x ,wg) 480 | (progn ,@body) 481 | (incf ,i 4))))))) 482 | 483 | (defun clear (buffer &optional (color :black)) 484 | (let ((color (ecase color 485 | (:black 0) 486 | (:white 255)))) 487 | #+cffi 488 | (cffi:with-pointer-to-vector-data (ptr buffer) 489 | (cffi:foreign-funcall "memset" :pointer ptr :int color :size (length buffer))) 490 | #-cffi 491 | (fill buffer color) 492 | buffer)) 493 | 494 | #+cffi 495 | (progn 496 | (declaim (inline memset)) 497 | (defun memset (ptr type) 498 | (cffi:foreign-funcall "memset" :pointer ptr :int 0 :size 499 | (etypecase type 500 | (integer type) 501 | ((or cons symbol) (cffi:foreign-type-size type)))))) 502 | 503 | #+cffi 504 | (progn 505 | (declaim (inline memcpy)) 506 | (defun memcpy (dst src type) 507 | (cffi:foreign-funcall "memcpy" :pointer dst :pointer src :size 508 | (etypecase type 509 | (integer type) 510 | ((or cons symbol) (cffi:foreign-type-size type)))))) 511 | -------------------------------------------------------------------------------- /documentation.lisp: -------------------------------------------------------------------------------- 1 | (in-package #:org.shirakumo.framebuffers) 2 | 3 | (docs:define-docs 4 | (type framebuffer-error 5 | "Error signalled when a backend fails to perform an operation. 6 | 7 | See WINDOW") 8 | 9 | (function window 10 | "Accesses the window associated with the object. 11 | 12 | See WINDOW (type) 13 | See FRAMEBUFFER-ERROR (type) 14 | See EVENT-HANDLER (type)") 15 | 16 | (type icon 17 | "Representation of the pixel data of some icon. 18 | 19 | See MAKE-ICON 20 | See WIDTH 21 | See HEIGHT 22 | See BUFFER 23 | See ICON 24 | See CURSOR-ICON") 25 | 26 | (function make-icon 27 | "Constructs an icon from the raw image data. 28 | 29 | WIDTH and HEIGHT should be the dimensions of the image data in 30 | pixels. BUFFER should be a (SIMPLE-ARRAY (UNSIGNED-BYTE 8) (*)) that 31 | represents the image data in BGRA order. 32 | 33 | See BUFFER 34 | See ICON (type)") 35 | 36 | (type touchpoint 37 | "Representation of a point that is being touched on the screen. 38 | 39 | See LOCATION 40 | See RADIUS 41 | See ANGLE 42 | See PRESSURE") 43 | 44 | (function radius 45 | "Returns the radius of the touch ellipsis as a (X . Y) cons in pixels. 46 | 47 | See TOUCHPOINT (type)") 48 | 49 | (function angle 50 | "Returns the angle of the touch ellipsis in a normalized [0 . PI] range. 51 | 52 | See TOUCHPOINT (type)") 53 | 54 | (function pressure 55 | "Returns the pressure of the touchpoint in a normalized [0 . 1] range. 56 | 57 | See TOUCHPOINT (type)") 58 | 59 | (type display 60 | "Representation of an output display or monitor attached to the system. 61 | 62 | See WINDOW (type) 63 | See LIST-DISPLAYS 64 | See ID 65 | See TITLE 66 | See VIDEO-MODES 67 | See VIDEO-MODE 68 | See PRIMARY-P 69 | See SIZE 70 | See LOCATION 71 | See WIDTH 72 | See HEIGHT") 73 | 74 | (function id 75 | "Returns the unique ID of the display or video-mode. 76 | 77 | Represents the display or video-mode uniquely as a string. This ID 78 | will remain the same across restarts of the application. 79 | 80 | See DISPLAY (type) 81 | See VIDEO-MODE (type)") 82 | 83 | (function title 84 | "Returns a human-readable title for the display or video-mode. 85 | 86 | This is not necessarily globally unique or the same across restarts of 87 | the application, but it should be identifiable enough for humans. 88 | 89 | See DISPLAY (type) 90 | See VIDEO-MODE (type)") 91 | 92 | (function video-modes 93 | "Lists all valid video modes for the given display. 94 | 95 | See VIDEO-MODE (type) 96 | See DISPLAY (type)") 97 | 98 | (function video-mode 99 | "Returns the current video mode of the given display. 100 | 101 | See VIDEO-MODE (type) 102 | See DISPLAY (type)") 103 | 104 | (function primary-p 105 | "Returns whether the display is configured as the primary display. 106 | 107 | See DISPLAY (type)") 108 | 109 | (type video-mode 110 | "Representation of a particular mode the display can take on. 111 | 112 | See DISPLAY (type) 113 | See LIST-VIDEO-MODES 114 | See ID 115 | See TITLE 116 | See DISPLAY 117 | See WIDTH 118 | See HEIGHT 119 | See REFRESH-RATE") 120 | 121 | (function display 122 | "Returns the display of the object. 123 | 124 | For a VIDEO-MODE that is the display for which it was listed. For a 125 | WINDOW, it is the display the window is currently located on, if any, 126 | regardless of whether the window is fullscreened or not. 127 | 128 | See DISPLAY (type) 129 | See WINDOW (type) 130 | See VIDEO-MODE (type)") 131 | 132 | (function refresh-rate 133 | "Returns the refresh-rate of the video mode in hertz. 134 | 135 | See VIDEO-MODE") 136 | 137 | (function init 138 | "Initialises the backend. 139 | 140 | If no backend is passed, this will try all available backends until 141 | one is found that works. If a working one is found, its name is 142 | returned. If none is found, an error is signalled. 143 | 144 | If you pass a backend name explicitly (as a keyword), it will only try 145 | that specific backend and will error if it fails to initialise for 146 | whatever reason. 147 | 148 | See SHUTDOWN") 149 | 150 | (function shutdown 151 | "Shuts the backend down (if any). 152 | 153 | This will also close all windows that are still open. 154 | 155 | See INIT") 156 | 157 | (type window 158 | "Representation of a framebuffer. 159 | 160 | See WITH-WINDOW 161 | See EVENT-HANDLER 162 | See OPEN 163 | See VALID-P 164 | See CLOSE-REQUESTED-P 165 | See CLOSE 166 | See WIDTH 167 | See HEIGHT 168 | See SIZE 169 | See MINIMUM-SIZE 170 | See MAXIMUM-SIZE 171 | See LOCATION 172 | See TITLE 173 | See VISIBLE-P 174 | See MAXIMIZED-P 175 | See ICONIFIED-P 176 | See FOCUSED-P 177 | See BORDERLESS-P 178 | See ALWAYS-ON-TOP-P 179 | See RESIZABLE-P 180 | See FLOATING-P 181 | See MOUSE-ENTERED-P 182 | See FULLSCREEN-P 183 | See CLIPBOARD 184 | See CONTENT-SCALE 185 | See BUFFER 186 | See SWAP-BUFFERS 187 | See PROCESS-EVENTS 188 | See REQUEST-ATTENTION 189 | See MOUSE-LOCATION 190 | See MOUSE-BUTTON-PRESSED-P 191 | See KEY-PRESSED-P 192 | See ICON 193 | See CURSOR-ICON 194 | See CURSOR-STATE 195 | See DISPLAY 196 | See SET-TIMER 197 | See CANCEL-TIMER") 198 | 199 | (type event-handler 200 | "Accesses the event handler of the window. 201 | 202 | Event callbacks to the window will be delegated to this handler. 203 | You can change the event handler at any time. 204 | 205 | See EVENT-HANDLER 206 | See WINDOW (type) 207 | See WINDOW-MOVED 208 | See WINDOW-RESIZED 209 | See WINDOW-REFRESHED 210 | See WINDOW-FOCUSED 211 | See WINDOW-ICONIFIED 212 | See WINDOW-MAXIMIZED 213 | See WINDOW-CLOSED 214 | See MOUSE-BUTTON-CHANGED 215 | See MOUSE-MOVED 216 | See MOUSE-ENTERED 217 | See MOUSE-SCROLLED 218 | See KEY-CHANGED 219 | See STRING-ENTERED 220 | See FILE-DROPPED 221 | See CONTENT-SCALE-CHANGED 222 | See TOUCH-STARTED 223 | See TOUCH-MOVED 224 | See TOUCH-ENDED 225 | See TOUCH-CANCELLED 226 | See PEN-MOVED 227 | See TIMER-TRIGGERED") 228 | 229 | (function event-handler 230 | "Accesses the event handler for the window. 231 | 232 | See WINDOW (type) 233 | See EVENT-HANDLER (type)") 234 | 235 | (function open 236 | "Creates a new framebuffer window. 237 | 238 | This implicitly calls INIT if it hasn't been called yet. 239 | If successful returns a new WINDOW instance suitable for the selected 240 | backend. 241 | 242 | The window will have the following default properties unless 243 | customised: 244 | 245 | EVENT-HANDLER --- EVENT-HANDLER 246 | SIZE --- (NIL . NIL) Fills the screen 247 | LOCATION --- (NIL . NIL) Centers on screen 248 | TITLE --- \"Framebuffer\" 249 | VISIBLE-P --- T 250 | MAXIMIZED-P --- NIL 251 | ICONIFIED-P --- NIL 252 | MINIMUM-SIZE --- (1 . 1) 253 | MAXIMUM-SIZE --- (NIL . NIL) 254 | FOCUSED-P --- T 255 | BORDERLESS-P --- NIL 256 | ALWAYS-ON-TOP-P --- NIL 257 | FULLSCREEN-P --- NIL 258 | RESIZABLE-P --- T 259 | FLOATING-P --- NIL 260 | ICON --- NIL 261 | CURSOR-STATE --- :NORMAL 262 | CURSOR-ICON --- :ARROW 263 | 264 | See INIT 265 | See WINDOW (type) 266 | See WITH-WINDOW") 267 | 268 | (function with-window 269 | "Convenience function to establish a window and event loop. 270 | 271 | WINDOW is bound to the window instance. 272 | INITARGS are argument spassed to OPEN. 273 | HANDLERS should be event handler bodies: 274 | 275 | HANDLER ::= (event-type (arg...) . body) 276 | | (T (event-name arg...) . body) 277 | EVENT-TYPE --- The name of an event-handler function 278 | EVENT-NMAE --- Variable bound to the name of the event type called. 279 | ARG --- Varibale bound to the respective event type argument. 280 | BODY --- Body forms to execute when the event is handled. 281 | 282 | The special event types INIT and SHUTDOWN can also be handled (with no 283 | arguments, both) to handle setup and teardown forms when the window is 284 | created or closed. 285 | 286 | See WINDOW (type) 287 | See EVENT-HANDLER (type)") 288 | 289 | (function do-pixels 290 | "Iterate over the pixels in the buffer. 291 | 292 | BUF is bound to the (USIGNED-BYTE 8) array 293 | I is bound to the pixel starting index 294 | X is bound to the pixel's X coordinate 295 | Y is bound to the pixel's Y coordinate 296 | 297 | WINDOW should be the framebuffer window to iterate over. 298 | 299 | BODY are forms to be executed for each pixel. 300 | 301 | Each pixel is stored as a quadruplet of (UNSIGNED-BYTE 8) values, in 302 | the order of Blue Green Red Alpha, with the first pixel being in the 303 | top left corner of the framebuffer, growing in X then Y. 304 | 305 | See WINDOW (type)") 306 | 307 | (function clear 308 | "Clears the pixel buffer to :white or :black. 309 | 310 | This is equivalent to (fill buffer 0) for black or (fill buffer 255) 311 | for white, but may be more efficient. 312 | 313 | See BUFFER") 314 | 315 | (function valid-p 316 | "Returns whether the window is usable or not. 317 | 318 | See CLOSE 319 | See WINDOW (type)") 320 | 321 | (function close-requested-p 322 | "Accesses whether the user has requested a close of the window. 323 | 324 | You should set this to NIL again to avoid an automatic closure of the 325 | window. 326 | 327 | See WINDOW (type)") 328 | 329 | (function close 330 | "Closes and deallocates the window permanently. 331 | 332 | After this the window will no longer be valid and cannot be used 333 | further. The CLOSE-REQUESTED-P will also be forced to T. 334 | 335 | See VALID-P 336 | See CLOSE-REQUESTED-P 337 | See WINDOW (type)") 338 | 339 | (function width 340 | "Returns the width of the object in pixels. 341 | 342 | See WINDOW (type) 343 | See ICON (type) 344 | See DISPLAY (type)") 345 | 346 | (function height 347 | "Returns the height of the object in pixels. 348 | 349 | See WINDOW (type) 350 | See ICON (type) 351 | See DISPLAY (type)") 352 | 353 | (function size 354 | "Accesses the size of the object as a (W . H) cons in pixels. 355 | 356 | See WINDOW (type) 357 | See DISPLAY (type)") 358 | 359 | (function minimum-size 360 | "Accesses the minimum size of the window as a (W . H) cons in pixels. 361 | 362 | W and H must be integers above 0. 363 | 364 | See WINDOW (type)") 365 | 366 | (function maximum-size 367 | "Accesses the maximum size of the window as a (W . H) cons in pixels. 368 | 369 | W and H must be integers above 0 or NIL to denote no limit. 370 | 371 | See WINDOW (type)") 372 | 373 | (function location 374 | "Accesses the location of the object as a (X . Y) cons in pixels. 375 | 376 | [Wayland] The window location cannot be accessed and will simply 377 | return (0 . 0) always. 378 | 379 | See WINDOW (type) 380 | See TOCHPOINT (type) 381 | See DISPLAY (type)") 382 | 383 | (function title 384 | "Accesses the title of the window. 385 | 386 | See WINDOW (type)") 387 | 388 | (function visible-p 389 | "Accesses whether the window is visible at all. 390 | 391 | See WINDOW (type)") 392 | 393 | (function maximized-p 394 | "Accesses whether the window should be maximized or not. 395 | 396 | See WINDOW (type)") 397 | 398 | (function iconified-p 399 | "Accesses whether the window should be iconified/minimized or not. 400 | 401 | [Wayland] The window cannot be un-minimized programmatically. Trying 402 | to do so will simply be a no-op. 403 | 404 | See WINDOW (type)") 405 | 406 | (function focused-p 407 | "Accesses whether the window has focus or not. 408 | 409 | When setting this property, it can usually only forcibly be set to true. 410 | 411 | See WINDOW (type)") 412 | 413 | (function borderless-p 414 | "Accesses whether the window should have a border or decorations, or not. 415 | 416 | See WINDOW (type)") 417 | 418 | (function always-on-top-p 419 | "Accesses whether the window should always stick on top or not. 420 | 421 | See WINDOW (type)") 422 | 423 | (function resizable-p 424 | "Accesses whether the window is meant to be resizable or not. 425 | 426 | Note that even when set not to be, your window may be forced to a 427 | particular size by the windowing system. 428 | 429 | See WINDOW (type)") 430 | 431 | (function floating-p 432 | "Accesses whether the window is set to be floating or not. 433 | 434 | See WINDOW (type)") 435 | 436 | (function mouse-entered-p 437 | "Returns whether the mouse is currently in the window or not. 438 | 439 | See WINDOW (type)") 440 | 441 | (function fullscreen-p 442 | "Returns whether the window is currently in fullscreen mode or not. 443 | 444 | When setting this place, you may pass one of the following: 445 | 446 | NIL --- Returns the window to its original state prior to 447 | fullscreening. 448 | T --- Fullscreens on the current DISPLAY without changing 449 | its current VIDEO-MODE. If the window has no current 450 | display, the display that is PRIMARY-P is used. 451 | DISPLAY --- Fullscreens on the given DISPLAY without changing 452 | its current VIDEO-MODE. 453 | VIDEO-MODE --- Fullscreens on the display of the VIDEO-MODE and if 454 | necessary switches it to that mode. 455 | STRING --- Fullscreens on the VIDEO-MODE or DISPLAY that has an 456 | ID that's STRING= to the passed string. If none is 457 | found, this is the same as T. 458 | 459 | See DISPLAY (type) 460 | See VIDEO-MODE (type) 461 | See WINDOW (type)") 462 | 463 | (function clipboard 464 | "Accesses the clipboard contents. 465 | 466 | Which types of clipboard contents are supported varies by 467 | backend. Ideally it should support getting and setting the following 468 | value types: 469 | 470 | STRING --- Basic text 471 | PATHNAME --- A file 472 | (LIST PATHNAME) --- A list of files 473 | ICON --- An image 474 | NULL --- Empty clipboard 475 | 476 | See WINDOW (type)") 477 | 478 | (function content-scale 479 | "Returns the content scaling factor the OS reports for the window as a (XSCALE . YSCALE) cons. 480 | 481 | Ideally you should scale your window contents by these factors for 482 | optimal DPI-aware display. 483 | 484 | See WINDOW (type)") 485 | 486 | (function buffer 487 | "Returns the framebuffer or icon contents as a (SIMPLE-ARRAY (UNSIGNED-BYTE 8) (*)) 488 | 489 | The framebuffer is guaranteed to have a length of (* 4 WIDTH HEIGHT), 490 | with the pixels stored in row(width)-major order and the first pixel 491 | being in the top-left corner. 492 | 493 | Each pixel is stored as a quadruplet of (UNSIGNED-BYTE 8) values, in 494 | the order of Blue Green Red Alpha. 495 | 496 | See SIZE 497 | See WINDOW (type) 498 | See ICON (type)") 499 | 500 | (function swap-buffers 501 | "Swaps the framebuffer to display its contents to the user. 502 | 503 | X, Y, W, H may be used to designate a sub-region of the framebuffer to 504 | swap for more efficient updates. 505 | If SYNC is T, the function will block until the swap has flushed 506 | through. Otherwise it may return immediately before the contents are 507 | visible. 508 | 509 | See WINDOW (type)") 510 | 511 | (function process-events 512 | "Processes pending events for the window. 513 | 514 | This will cause the event handler functions to be invoked for any 515 | pending events that may be queued for the window. 516 | 517 | TIMEOUT may be one of the following: 518 | NIL --- Process only immediately pending events. 519 | T --- Process events in a loop until the window is closed or 520 | CLOSE-REQUESTED-P is true. 521 | REAL --- A real number representing the maximum number of seconds to 522 | wait for events to arrive. If there are pending events 523 | already this option is equivalent to NIL. 524 | 525 | See WINDOW (type)") 526 | 527 | (function request-attention 528 | "Request the user to pay attention to the window. 529 | 530 | This usually makes the window or its icon representation flash in some 531 | way. 532 | 533 | See WINDOW (type)") 534 | 535 | (function mouse-location 536 | "Returns the last known mouse location inside the window as a (X . Y) cons in pixels. 537 | 538 | See WINDOW (type)") 539 | 540 | (function mouse-button-pressed-p 541 | "Returns the last known mouse button state. 542 | 543 | See WINDOW (type) 544 | See MOUSE-BUTTON-CHANGED") 545 | 546 | (function key-pressed-p 547 | "Returns the last known key state. 548 | 549 | See WINDOW (type) 550 | See KEY-CHANGED") 551 | 552 | (function key-scan-code 553 | "Returns the scan code for a particular key symbol. 554 | 555 | If no translation is known for the given key, NIL is returned. 556 | 557 | See WINDOW (type) 558 | See KEY-CHANGED") 559 | 560 | (function local-key-string 561 | "Returns a string representing the icon on the physical key represented by the particular key symbol. 562 | 563 | This will perform an inverse translation based on the user's keyboard 564 | layout and try to present a matching human-readable representation of 565 | that key's label. 566 | 567 | For instance, on a DVORAK layout, passing in :I will return \"C\" 568 | while on a standard US QWERTY layout it will return \"I\". 569 | 570 | If no translation is known for the given key, NIL is returned. 571 | 572 | See WINDOW (type) 573 | See KEY-CHANGED") 574 | 575 | (function icon 576 | "Accesses the icon of the window. 577 | 578 | Returns NIL if no icon was set previously. 579 | The call may fail if the ICON instance has unsuitable dimensions for 580 | the backend. 581 | 582 | See ICON (type) 583 | See WINDOW (type)") 584 | 585 | (function cursor-icon 586 | "Accesess the icon of the cursor in the window. 587 | 588 | May return an ICON instance if one was set explicitly by the user, or 589 | one of the following keywords defining default cursor types: 590 | 591 | NIL 592 | :ARROW --- The default pointer/arrow cursor shape 593 | :IBEAM --- A crossbeam usually for text input 594 | :CROSSHAIR --- A crosshair usually for precise selection 595 | :POINTING-HAND --- A pointing hand to designate interactivity or 596 | dragging 597 | :RESIZE-EW --- Shapes to indicate the directions in which 598 | :RESIZE-NS something may be resized 599 | :RESIZE-NWSE 600 | :RESIZE-NESW 601 | :RESIZE-ALL 602 | :NOT-ALLOWED --- To indicate a deactivated or forbidden 603 | interaction 604 | 605 | You may also set the cursor-icon in the same way. A backend may also 606 | support additional icon types, though only the above are required. 607 | 608 | The call may fail if the ICON intsance has unsuitable dimensions for 609 | the backend. 610 | 611 | See ICON (type) 612 | See WINDOW (type)") 613 | 614 | (function cursor-state 615 | "Accesses the state of the cursor behaviour. 616 | 617 | The state may be one of the following: 618 | 619 | :NORMAL --- The cursor behaves as normal 620 | :HIDDEN --- The cursor is not displayed over the window 621 | :CAPTURED --- The cursor cannot leave the window 622 | 623 | See WINDOW (type)") 624 | 625 | (function set-timer 626 | "Creates a new timer object and returns it. 627 | 628 | DELAY is the number of seconds after which TIMER-TRIGGERED is 629 | invoked for the returned timer object. If REPEAT is true, then the 630 | callback is repeatedly invoked in every DELAY interval until 631 | CANCEL-TIMER is called for the timer, or the WINDOW is closed. 632 | 633 | Note that how accurate the callback is is dependent on how often 634 | PROCESS-EVENTS is called. 635 | 636 | See WINDOW (type) 637 | See CANCEL-TIMER 638 | See TIMER-TRIGGERED 639 | See PROCESS-EVENTS") 640 | 641 | (function cancel-timer 642 | "Cancels the timer object. 643 | 644 | After this call, no further TIMER-TRIGGERED callbacks will be invoked 645 | for the given timer object. 646 | 647 | See WINDOW (type) 648 | See SET-TIMER 649 | See TIMER-TRIGGERED") 650 | 651 | (function window-moved 652 | "Callback for when the window has moved on screen. 653 | 654 | See LOCATION 655 | See EVENT-HANDLER (type) 656 | See WINDOW (type)") 657 | 658 | (function window-resized 659 | "Callback for when the window and framebuffer have been resized. 660 | 661 | The contents of the BUFFER will have been modified to fit the new 662 | size. The resizing logic keeps old data attached to the top-left 663 | corner, cutting it off as necessary and extending it with zeros as 664 | necessary. 665 | 666 | See SIZE 667 | See EVENT-HANDLER (type) 668 | See WINDOW (type)") 669 | 670 | (function window-refreshed 671 | "Callback for when the window has been damaged in some way and should have its contents redrawn. 672 | 673 | You should probably invoke SWAP-BUFFERS from this. 674 | 675 | See SWAP-BUFFERS 676 | See EVENT-HANDLER (type) 677 | See WINDOW (type)") 678 | 679 | (function window-focused 680 | "Callback for when the window's focus state has changed. 681 | 682 | See EVENT-HANDLER (type) 683 | See WINDOW (type)") 684 | 685 | (function window-iconified 686 | "Callback for when the window's iconified/minimized status has changed. 687 | 688 | See ICONIFIED-P 689 | See EVENT-HANDLER (type) 690 | See WINDOW (type)") 691 | 692 | (function window-maximized 693 | "Callback for when the window's maximized status has changed. 694 | 695 | See MAXIMIZED-P 696 | See EVENT-HANDLER (type) 697 | See WINDOW (type)") 698 | 699 | (function window-closed 700 | "Callback for when the window is requested to be closed by the user. 701 | 702 | On call CLOSE-REQUESTED-P will be set to T. You should set it back to 703 | NIL if you would like to reject the window close request. 704 | 705 | See CLOSE-REQUESTED-P 706 | See EVENT-HANDLER (type) 707 | See WINDOW (type)") 708 | 709 | (function mouse-button-changed 710 | "Callback for when a mouse button has changed. 711 | 712 | BUTTON may be one of: 713 | :LEFT --- The left mouse button 714 | :RIGHT --- The right mouse button 715 | :MIDDLE --- The middle/scroll wheel mouse button 716 | integer --- An extra button identified by its number 717 | 718 | ACTION may be one of: 719 | :PRESS --- The button is now held down 720 | :RELEASE --- The button is no longer held down 721 | :DOUBLE-CLICK --- The button has been clicked twice in succession 722 | 723 | MODIFIERS is a set of the following modifiers that wer active at the 724 | time: 725 | :CONTROL 726 | :ALT 727 | :SHIFT 728 | :SUPER 729 | :HYPER 730 | :CAPS-LOCK 731 | :NUM-LOCK 732 | :SCROLL-LOCK 733 | 734 | See EVENT-HANDLER (type) 735 | See WINDOW (type)") 736 | 737 | (function mouse-moved 738 | "Callback for when the mouse cursor has moved over the window. 739 | 740 | See EVENT-HANDLER (type) 741 | See WINDOW (type)") 742 | 743 | (function mouse-entered 744 | "Callback for when the mouse cursor has entered or left the window. 745 | 746 | See EVENT-HANDLER (type) 747 | See WINDOW (type)") 748 | 749 | (function mouse-scrolled 750 | "Callback for when the mouse scroll wheel has moved. 751 | 752 | See EVENT-HANDLER (type) 753 | See WINDOW (type)") 754 | 755 | (function key-changed 756 | "Callback for when a key's state has changed. 757 | 758 | KEY is a keyword description of the ANSI-US label of the key that was 759 | pressed, or NIL if no description is known. In addition to the basic 760 | alphanumerics, this library also defines the following key names: 761 | 762 | :F1 763 | :F2 764 | :F3 765 | :F4 766 | :F5 767 | :F6 768 | :F7 769 | :F8 770 | :F9 771 | :F10 772 | :F11 773 | :F12 774 | :F13 775 | :F14 776 | :F15 777 | :F16 778 | :F17 779 | :F18 780 | :F19 781 | :F20 782 | :F21 783 | :F22 784 | :F23 785 | :F24 786 | :KP-7 787 | :KP-8 788 | :KP-9 789 | :KP-4 790 | :KP-5 791 | :KP-6 792 | :KP-1 793 | :KP-2 794 | :KP-3 795 | :KP-0 796 | :KP-SUBTRACT 797 | :KP-ADD 798 | :KP-DECIMAL 799 | :KP-EQUAL 800 | :KP-ENTER 801 | :KP-DIVIDE 802 | :KP-MULTIPLY 803 | :LEFT-ALT 804 | :LEFT-BRACKET 805 | :LEFT-CONTROL 806 | :LEFT-SHIFT 807 | :LEFT-SUPER 808 | :RIGHT-ALT 809 | :RIGHT-BRACKET 810 | :RIGHT-CONTROL 811 | :RIGHT-SHIFT 812 | :RIGHT-SUPER 813 | :APOSTROPHE 814 | :BACKSLASH 815 | :BACKSPACE 816 | :CAPS-LOCK 817 | :COMMA 818 | :DELETE 819 | :DOWN 820 | :END 821 | :ENTER 822 | :EQUAL 823 | :ESCAPE 824 | :GRAVE-ACCENT 825 | :HOME 826 | :INSERT 827 | :LEFT 828 | :MENU 829 | :MINUS 830 | :NUM-LOCK 831 | :PAGE-DOWN 832 | :PAGE-UP 833 | :PAUSE 834 | :PERIOD 835 | :PRINT-SCREEN 836 | :RIGHT 837 | :SCROLL-LOCK 838 | :SEMICOLON 839 | :SLASH 840 | :SPACE 841 | :TAB 842 | :UP 843 | :WORLD-2 844 | 845 | SCAN-CODE is the internal integer code of the key that was pressed. 846 | 847 | ACTION may be one of: 848 | :PRESS --- The key is now held down 849 | :RELEASE --- The key is no longer held down 850 | :REPEAT --- The key is still left down and is being repeated by the 851 | system 852 | 853 | MODIFIERS is a set of the following modifiers that wer active at the 854 | time: 855 | :CONTROL 856 | :ALT 857 | :SHIFT 858 | :SUPER 859 | :HYPER 860 | :CAPS-LOCK 861 | :NUM-LOCK 862 | :SCROLL-LOCK 863 | 864 | Note that you should not use this function to process textual input, 865 | as it is not aware of keyboard layout translation mechanisms. Use 866 | STRING-ENTERED instead for such purposes. 867 | 868 | See STRING-ENTERED 869 | See EVENT-HANDLER (type) 870 | See WINDOW (type)") 871 | 872 | (function string-entered 873 | "Callback for when some text has been entered into the window. 874 | 875 | This text has been properly processed by whatever keyboard layout 876 | translation mechanisms or input method translations may be 877 | applicable. 878 | 879 | See EVENT-HANDLER (type) 880 | See WINDOW (type)") 881 | 882 | (function file-dropped 883 | "Callback for when one or more files have been dragged and dropped onto the window. 884 | 885 | See EVENT-HANDLER (type) 886 | See WINDOW (type)") 887 | 888 | (function content-scale-changed 889 | "Callback for when the desired content-scale of the window has changed. 890 | 891 | This can occur due to a monitor reconfiguration or the window being 892 | moved to another monitor with different requirements. 893 | 894 | See CONTENT-SCALE 895 | See EVENT-HANDLER (type) 896 | See WINDOW (type)") 897 | 898 | (function touch-started 899 | "Callback for when a touch event has started. 900 | 901 | The POINTS is a list of TOUCHPOINT instances describing the contact 902 | points and their shape on the screen. 903 | 904 | See EVENT-HANDLER (type) 905 | See WINDOW (type) 906 | See TOUCH-POINT (type)") 907 | 908 | (function touch-moved 909 | "Callback for when a touch event has changed. 910 | 911 | The POINTS is a list of TOUCHPOINT instances describing the contact 912 | points and their shape on the screen. The points in the set will be EQ 913 | to the ones from the previous TOUCH-MOVED or TOUCH-STARTED if they are 914 | tracked to be the same points. The set may change as touchpoints are 915 | removed or added druing the same motion. 916 | 917 | See EVENT-HANDLER (type) 918 | See WINDOW (type) 919 | See TOUCH-POINT (type)") 920 | 921 | (function touch-ended 922 | "Callback for when a touch event has successfully completed. 923 | 924 | This is called when all touchpoints have left the screen. The set of 925 | POINTS is the last before this happened. 926 | 927 | See EVENT-HANDLER (type) 928 | See WINDOW (type) 929 | See TOUCH-POINT (type)") 930 | 931 | (function touch-cancelled 932 | "Callback fro when a touch event has bene interrupted by some other system action. 933 | 934 | This should be used to cancel an operation that was started by the 935 | touch event.The set of POINTS is the last before this happened. 936 | 937 | See EVENT-HANDLER (type) 938 | See WINDOW (type) 939 | See TOUCH-POINT (type)") 940 | 941 | (function pen-moved 942 | "Callback for when a stylus or pen has been moved across the screen. 943 | 944 | This is in addition to a mouse event, and carries the following extra 945 | information: 946 | 947 | MODE --- Either :NORMAL or :ERASER 948 | PRESSURE --- A normalised pressure value in the range [0 . 1] 949 | XTILT --- The tilt of the pen in X direction along the screen as 950 | an angle in the range [0 . PI] 951 | YTILT --- The tilt of the pen in Y direction along the screen as 952 | an angle in the range [0 . PI] 953 | 954 | See EVENT-HANDLER (type) 955 | See WINDOW (type)") 956 | 957 | (function timer-triggered 958 | "Callback for when a timer has reached its timeout. 959 | 960 | This will be called repeatedly for the same timer if the timer is set 961 | to repeat. For non-repeating timers it is only called once. 962 | 963 | Note that how accurate the callback is to the timer's timeout is 964 | dependent on how often PROCESS-EVENTS is called. 965 | 966 | See EVENT-HANDLER (type) 967 | See SET-TIMER 968 | See CANCEL-TIMER 969 | See PROCESS-EVENTS") 970 | 971 | (function display-connected 972 | "Callback for when a display connection state has changed. 973 | 974 | Note that this is only called for the first window to process events 975 | after the display change has occurred. It is up to you to make sure 976 | all relevant windows have processed the change. 977 | 978 | See DISPLAY (type) 979 | See EVENT-HANDLER (type) 980 | See LIST-DISPLAYS")) 981 | --------------------------------------------------------------------------------