Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

Delete content and redirec to new home.

  • Loading branch information...
commit d60b4d789c6205c3a3235732cf0ea983a0bbbe80 1 parent f5f85ec
@candera authored
View
10 .gitignore
@@ -1,10 +0,0 @@
-*.suo
-*~
-/obj
-/bin
-*.user
-/.lein-deps-sum
-/.lein-failures
-/lib
-/classes
-/target
View
3  README.md
@@ -0,0 +1,3 @@
+# This project has moved
+
+New home: https://github.com/candera/khordr
View
BIN  ext/interception-dummy.dll
Binary file not shown
View
BIN  ext/interception-dummy.pdb
Binary file not shown
View
BIN  ext/interception-original.dll
Binary file not shown
View
BIN  ext/interception-original.pdb
Binary file not shown
View
BIN  ext/interception.dll
Binary file not shown
View
BIN  ext/interception.pdb
Binary file not shown
View
BIN  ext/test.dylib
Binary file not shown
View
123 notes.org
@@ -1,123 +0,0 @@
-* Notes
-** What I should work on next
-- Make the existing tests pass
-** What I should work on after that
-- Make sure we're handling the case of two equivalent modifier aliases
- being pressed at the same time
-- Get the main loop of the app working
-** Thoughts on how to implement
-Right now, the app is written to have a giant switch statement, in the
-form of a core.match expression. But I think I might be able to clean
-it up a lot. The key observation is that for modifier aliases, you
-don't actually have to wait until all of the modifiers have been
-pressed. When a modifier alias goes down, it is undecided, but it can
-be decided as a modifier at the very next key press, even if the next
-press is a different modifier alias. And you can even send the aliased
-modifier down event right away.
-
-So instead of the current behavior, which is this:
-
-[:j :dn] => []
-[:j :dn :k :dn] => []
-[:j :dn :k :dn :x :dn] => [:rshift :dn :rcontrol :dn :x :dn]
-
-You'd get this:
-
-[:j :dn] => []
-[:j :dn :k :dn] => [:rshift :dn]
-[:j :dn :k :dn :x :dn] => [:rshift :dn :rcontrol :dn :x :dn]
-
-Further, I think you might be able to structure the code much better.
-I think you could define an IKeyHandler protocol that consists of
-self-down, self-up, other-down, and other-up functions. An instance of
-a record would be kept in an ordered list for every key that was down,
-in the order they were pressed. Every key pressed would be passed to
-all the handlers, in order, either to the self methods (if the handler
-was associated with the key that was pressed) or to the other methods
-(if not).
-
-So initially we'd have two implementations of the protocol:
-RegularKeyHandler and ModifierAliasKeyHandler. RegularKeyHandler would
-have a pretty simple implementation, as it would simply pass through
-self events, and do nothing at all with other events.
-ModifierAliasKeyHandler would, at self-down, go into an undecided
-state. If an other-down happened before a self-up, then it could
-transition to a decided state, and send its aliased down event.
-
-And after further thought, I wonder whether there might not be a
-better way. The responsibilities would be split between the app and
-key handlers. The app would be responsible for knowing which keys are
-down and which are up. These would be maintained in an ordered list,
-with the keys that went down first being first. Each key would have an
-associated handler (perhaps an implementation of the IKeyHandler
-protocol), a new instance of which would be created for each key that
-goes down. IKeyHandler/process would be called for each key press,
-including the one that corresponds to the creation of the handler. The
-method would accept the key event and would return a map. The map
-would have the following keys:
-
-| :handler | a new handler object to represent the updated state of this handler. Returning nil would remove the handler from the handler list. |
-| :continue | false if no further handlers should be called; true to continue processing. |
-| :events | a vector of key events to generate. Events from all handlers will be concatenated. |
-
-So the application's job would be to watch for key events. When a key
-goes from up to down, a new handler would be instantiated and added to
-the handler list. For all key events, process would be called and the
-result examined. The handler would be updated based on the value
-of :handler, events from :events would be accumulated, and processing
-would continue or not based on the value of :continue.
-
-There are at least three implementations of IKeyHandler: one for
-regular keys, one for modifiers alias, and one for special action
-keys.
-
-The regular key handler would be very simple. It would return a map
-whose :handler was itself unless the key was going up, in which
-case :handler would be nil. :continue would always be true. :events
-would simply be whatever event was being handled if it was for the
-self key, and nil otherwise.
-
-The modifier alias handler would initially send no keys and continue
-processing. On the next non-self key down event it saw, it would send
-the modifier and enter a decided state, unless the next event was self
-up, in which case it would send self down, self up and remove itself
-from the handler list. Once decided, it would always send the modifier
-for self down events and remove itself on self up.
-
-The special action handler would be for things like quitting the
-application or suspending key processing. For this we'd probably need
-to modify :events to be something more like :commands. Then it could
-be a sequence of tuples like [:keys [:a :dn :a :up] :suspend
-true :mouse [:left 200]].
-
-How do we leverage multimethods or protocols to make all this work? It
-seems like we ought to be able to dispatch off of the key to look up
-the key handler, although perhaps all we need there is a record class,
-so we can call new on it, passing the key as an argument.
-
-Maybe what we have is a map, like this:
-
-#+begin_src clojure
- {:j [->ModifierAliasHandler :rshift]
- :q [->SpecialActionHandler]}
-#+end_src
-
-That is, a map that associates keys with a tuple whose first element
-is a function that returns an implementation of IKeyHandler given a
-key and any other elements of the tuple. Failing an entry, an instance
-of DefaultHandler is used.
-
-*** Questions
-**** How to send events?
-Maybe we'd pass a function to self/other-up/down that could be called
-to transmit events.
-**** Do we need the ability to suppress further processing?
-For example, if I add macros, I might need a way to prevent
-[:q :dn :z :dn] from having the :z event transmit anything. Or maybe
-this implies that the handler associated with a key can be changed as
-a result of some other key going down, so that holding down :q results
-in no other key transmitting itself.
-**** Do we really need to have the self/other and up/down split?
-Would it make more sense to just have one method on the protocol that
-handles everything? Or would we wind up doing having a bunch of
-conditional processing in every implementation?
View
17 project.clj
@@ -1,17 +0,0 @@
-(defproject kchordr "1.0.0-SNAPSHOT"
- :description "FIXME: write description"
- :dependencies [[org.clojure/clojure "1.4.0"]
- [org.clojure/core.match "0.2.0-alpha9"]
- [net.java.dev.jna/jna "3.4.0"]
- [com.nativelibs4java/jnaerator-runtime "0.9.10-SNAPSHOT"]
- ;;[kchordr/interception "1.0.0"]
- ]
- :plugins [[lein-swank "1.4.4"]]
- :source-paths ["src/clj"]
- ;; Use one of the two following, depending on whether you want
- ;; source or jar dependency
- :java-source-paths ["src/java"]
- :repositories {"local" "file:repo"
- "sonatype" "http://oss.sonatype.org/content/repositories/releases"
- "nativelibs4java-repo" "http://nativelibs4java.sourceforge.net/maven"}
- :jvm-opts ["-Djna.library.path=ext"])
View
BIN  repo/kchordr/interception/1.0.0/interception-1.0.0.jar
Binary file not shown
View
1  repo/kchordr/interception/1.0.0/interception-1.0.0.jar.sha
@@ -1 +0,0 @@
-9721d5ceefde06076a74cd563eac06b6f0bfdf02 *interception-1.0.0.jar
View
199 scratch.clj
@@ -1,199 +0,0 @@
-;; IntPtr context;
-
-;; int device;
-;; Interception.Stroke stroke = new Interception.Stroke();
-
-;; context = Interception.CreateContext();
-(System/setProperty "jna.library.path" "ext")
-(import 'interception.InterceptionLibrary)
-(let [ctx (.interception_create_context InterceptionLibrary/INSTANCE)]
- (try
- (.interception_set_filter
- InterceptionLibrary/INSTANCE
- ctx
- (reify interception.InterceptionLibrary$InterceptionPredicate
- (apply [_ device]
- (.interception_is_keyboard InterceptionLibrary/INSTANCE device)))
- (short -1))
-
- (dotimes [n 50]
- (let [device (.interception_wait InterceptionLibrary/INSTANCE ctx)
- stroke (interception.InterceptionKeyStroke$ByReference.)
- received (.interception_receive
- InterceptionLibrary/INSTANCE
- ctx
- device
- stroke
- 1)]
-
- (when (< 0 received)
- (println "received:" received (.code stroke) (.state stroke))
- ;; (when (= 0x15 (.code stroke))
- ;; (set! (.code stroke) 0x2d))
- (.interception_send InterceptionLibrary/INSTANCE ctx device stroke 1)
- ;; If it's a y, send an additional x
- (when (= 0x15 (.code stroke))
- (set! (.code stroke) 0x2d)
- (.interception_send InterceptionLibrary/INSTANCE ctx device stroke 1))
- ;; // Hitting escape terminates the program
- ;; if (stroke.key.code == ScanCode.Escape)
- (if (= 0x01 (.code stroke))
- (println "quitting")
- ;(recur)
- ))))
- (finally
- (.interception_destroy_context InterceptionLibrary/INSTANCE ctx))))
-
-
-;; {
-;; break;
-;; }
-;; }
-
-;; Interception.DestroyContext(context);
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(System/setProperty "jna.library.path" "ext")
-
-(interception.TestLibrary/INSTANCE)
-(import interception.TestLibrary)
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(require :reload 'kchordr.core)
-(in-ns 'kchordr.core)
-
-(process (state default-key-behaviors) (->event :q :dn))
-
-(def jdn (process (state default-key-behaviors) (->event :j :dn)))
-
-(handle-deciding-regular-press jdn :q)
-
-(process jdn (->event :j :up))
-(process jdn (->event :q :dn))
-jdn
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(map #(apply ->event %) [[:b :dn] [:b :up]])
-
-(->event :b :dn)
-
-(update-in {:to-send []} [:to-send] append (->event :x :up))
-
-(append [(->event :x :up)] (->event :x :dn))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-evt: {:key :j :direction :dn}
-
-state:
-{:to-send [evt evt evt]
- :keystate {:j :undecided, :k :right-control}}
-
-process: state, evt -> state
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(undecided-modifier-downs jdn)
-
-(get-in jdn [:behaviors :q])
-(modifier-alias? nil)
-
-(undecided-modifier? (:keystate jdn))
-
-(regular-key? jdn :j)
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-(require :reload 'kchordr.core)
-(decide-modifiers jdn)
-(clojure.repl/doc decide-modifier)
-
-(decide-modifier jdn [:j :undecided])
-
-(reduce println jdn (:keystate state))
-
-(concat (:to-send jdn) (undecided-modifier-downs jdn) [(->event :q :dn)])
-
-(clojure.pprint/pprint (process jdn (->event :q :dn)))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-;; Working! The only weirdness is around printscreen and pause, which
-;; both generate multiple keypresses. Since I don't care about those
-;; at the moment, I'm not going to bother with them.
-(defn handle-event [event]
- (let [{:keys [key direction]} event]
- (println "received" key direction)
- (not (or (= key 1) (= key :esc)))))
-
-(System/setProperty "jna.library.path" "ext")
-(require :reload-all 'kchordr.core)
-(kchordr.core/intercept #'handle-event)
-
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(handle-keys (base-state {}) {:key :a :direction :dn})
-
-(def state (base-state {}))
-(def state (update-key-positions state :a :dn))
-(def state (maybe-add-handler (base-state {}) :a :dn))
-(process (first (:handlers state)) :a :dn)
-(def results (map #(process % :a :dn) (:handlers state)))
-(def results (take-while :continue results))
-(filter identity (map :handler results))
-(mapcat :effects results)
-state
-
-handle-keys
-
-(let [_ (println "--------------------")
- state (base-state {})
- event {:key :a :direction :dn}
- {:keys [key direction]} event
- _ (println "With update-key-positions: " state)
- state (maybe-add-handler state key direction)
- _ (println "Key direction: " key direction)
- state (update-key-positions state key direction)
- _ (println "With maybe-add-handler state:" state)
- ;; Walk the handler chain, dealing with the results at each step
- results (map #(process % key direction) (:handlers state))
- results (take-while :continue results)]
- (assoc state
- :handlers (filter identity (map :handler results))
- :effects (mapcat :effects results)))
-
-(maybe-add-handler {:handlers [] :positions {:a :dn}} :a :dn)
-
-(is-down? (base-state {}) :a)
-
-(update-in {:handlers [] :positions {:a :dn}} [:handlers] concat [:foo])
-
-(class (update-key-positions (base-state {}) :a :dn))
-(class (base-state {}))
-
-default-key-behaviors
-
-(base-state default-key-behaviors)
-
-(map (juxt :key :direction)) (:effects (handle-keys (base-state default-key-behaviors) {:key :b :direction :dn}))
-
-;; [[:j :dn] [:x :dn] [:x :up] [:j :up]]
-
-(-> (base-state default-key-behaviors)
- (handle-keys (->event :j :dn))
- (handle-keys (->event :x :dn))
- (handle-keys (->event :x :up))
- #_(handle-keys (->event :j :up)))
-
-(def state (-> (base-state default-key-behaviors)
- (handle-keys (->event :j :dn))))
-
-state
-(def h (first (:handlers state)))
-h
-(def results (map #(process % :j :up) [h]))
-results
-(satisfies? IKeyHandler h)
View
230 src/clj/kchordr.clj
@@ -1,230 +0,0 @@
-(ns kchordr
- (:refer-clojure :exclude [key send])
- (:use [clojure.core.match :only (match)]
- kchordr.keycodes)
- ;; (:import interception.InterceptionLibrary)
- )
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(defn no-op [& args])
-(def log no-op)
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;
-;; IKeyHandler and implementations
-;;
-
-(defprotocol IKeyHandler
- (process [this key direction]
- "Process a key event, returning a map. The map should contain the
- following keys: :handler - either an implementation of
- IKeyHandler representing the updated state of this handler or
- nil, indicating that the handler should be removed from the
- handler list; :effects - a seq of commands legal for consumption
- by `engine`; :continue - true if the event should be passed to
- later handlers in the chain."))
-
-(defrecord DefaultKeyHandler [self-key]
- IKeyHandler
- (process [this key direction]
- (if (= key (:self-key this))
- {:handler (when (= direction :dn) this)
- :continue true
- :effects [:key [key direction]]}
- {:handler this
- :effects []
- :continue true})))
-
-
-(defrecord ModifierAliasKeyHandler [self-key alias state]
- IKeyHandler
- (process [this key direction]
- (match [state (if (= key self-key) :self :other) direction]
-
- ;; If we're undecided and we see another self-down,
- ;; continue waiting.
- [:undecided :self :dn]
- {:handler this
- :continue true}
-
- ;; If we're undecided and we see an other-down, then we
- ;; know that we're going to be aliasing, so we change state
- ;; and send the alias down.
- [:undecided :other :dn]
- {:handler (ModifierAliasKeyHandler. self-key alias :aliasing)
- :effects [:key [alias :dn]]
- :continue true}
-
- ;; If we're undecided and we see a self-up, then we're not
- ;; aliasing, so we can just send self-down and self-up.
- [:undecided :self :up]
- {:handler nil
- :effects [:key [self-key :dn] :key [self-key :up]]
- :continue true}
-
- ;; If we're aliasing and we see a self-down or a self-up,
- ;; then we can just send the alias, removing ourselves from
- ;; the chain if it's an up
- [:aliasing :self _]
- {:handler (when (= direction :dn) this)
- :effects [:key [alias direction]]
- :continue true}
-
- ;; Otherwise, we don't change anything
- [_ _ _]
- {:handler this
- :effects []
- :continue true}
- )))
-
-(defn make-modifier-alias
- "Helper function to create a ModifierAliasKeyHandler in its initial
- state."
- [key alias]
- (->ModifierAliasKeyHandler key alias :undecided))
-
-(defrecord SpecialActionKeyHandler [self-key]
- ;; TODO: Implement IKeyHandler
- )
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-
-(def ^{:doc "Map of keys to behaviors. Absence from this list means it's a regular key."}
- default-key-behaviors
- {:j [make-modifier-alias :rshift]
- :k [make-modifier-alias :rcontrol]})
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;; Key events
-
-(defn ->event
- "Given a key name and a direction, either as individual arguments or
- as a two-element sequence, return a new key event."
- ([[key direction]] (->event key direction))
- ([key direction] {:key key :direction direction}))
-
-(defn append
- "Append bs to a, where bs and a are (potentially empty) sequences of
- events."
- [a & bs]
- (concat a bs))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;
-;; Application engine
-
-(defn base-state
- "An empty key-state value. Used for initializing the application
- engine."
- [behaviors]
- {:behaviors behaviors
- :handlers []
- :positions {}})
-
-(defn is-down?
- "Return true if the specified key is in the down position."
- [state key]
- (= :dn (get-in state [:positions key])))
-
-(defn handler
- "Return a new handler for the specified key."
- [state key]
- (let [[make-handler & params]
- (get (:behaviors state) key [->DefaultKeyHandler])]
- (apply make-handler key params)))
-
-(defn maybe-add-handler
- "Return a state value that has been updated to include any necessary
- new key handlers."
- [state key direction]
- ;; Is this a key down event? If not, return the state unchanged. If
- ;; so, is the key already down? If not, create a handler and add it
- ;; to the end of the chain. If so, return the state unchanged.
- (if (and (= direction :dn)
- (not (is-down? state key)))
- (update-in state [:handlers] concat [(handler state key)])
- state))
-
-(defn update-key-positions
- "Return a state that has been updated to reflect which keys are up
- and which are down."
- [state key direction]
- (assoc-in state [:positions key] direction))
-
-(defn handle-keys
- "Given the current state and a key event, return an updated state."
- [state event]
- (let [{:keys [key direction]} event
- ;; Important! Don't update the positions until after we add
- ;; the new handler, since whether or not we add one depends on
- ;; whether a key is already down.
- state (maybe-add-handler state key direction)
- state (update-key-positions state key direction)
- ;; Walk the handler chain, dealing with the results at each step
- handlers (:handlers state)
- results (map #(process % key direction) handlers)
- ;; If one of the handlers prevents processing from continuing,
- ;; we don't take any subsequent effects into consideration,
- ;; but we do let the handlers update themselves based on the
- ;; key event. We may need to revisit this in the future for
- ;; more complex scenarios, perhaps by making :continue provide
- ;; an enumerated value, rather than just a boolean.
- continue-count (count (take-while :continue results))
- effects (mapcat :effects (take (inc continue-count) results))]
- (-> state
- (assoc-in [:handlers] (filter identity (map :handler results)))
- (update-in [:effects] concat effects))))
-
-;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
-;;
-;; Main loop - commented out FTM
-
-(comment
- (defn intercept
- "Start intercepting keys, calling the function (or var) with the
- received key event f until it returns false."
- [f]
- ;; TODO: This next statement needs to happen before this library loads
- ;; (System/setProperty "jna.library.path" "ext")
-
- ;; And this one should live somewhere else entirely
- ;;(import 'interception.InterceptionLibrary)
-
- (let [ctx (.interception_create_context InterceptionLibrary/INSTANCE)]
- (try
- (.interception_set_filter
- InterceptionLibrary/INSTANCE
- ctx
- (reify interception.InterceptionLibrary$InterceptionPredicate
- (apply [_ device]
- (.interception_is_keyboard InterceptionLibrary/INSTANCE device)))
- (short -1))
- (loop []
- (let [device (.interception_wait InterceptionLibrary/INSTANCE ctx)
- stroke (interception.InterceptionKeyStroke$ByReference.)
- received (.interception_receive
- InterceptionLibrary/INSTANCE
- ctx
- device
- stroke
- 1)]
-
- (when (< 0 received)
- ;; TODO: figure out how this should work - what function
- ;; should call what other function? Should there be a
- ;; trampoline involved?
- ;; (println "raw code:" (.code stroke) "raw state:" (.state stroke))
- (let [state (.state stroke)
- direction (if (bit-test state 0) :up :dn)
- e0 (when (bit-test state 1) :e0)
- e1 (when (bit-test state 2) :e1)
- key-index (filter identity [(.code stroke) e0 e1])
- key (get kchordr.keycodes/keycodes key-index (.code stroke))
- result (.invoke f (->event key direction))]
- ;; For now, just always send on the keystrokes
- (.interception_send InterceptionLibrary/INSTANCE ctx device stroke 1)
- (when result
- (recur))))))
- (finally
- (.interception_destroy_context InterceptionLibrary/INSTANCE ctx))))))
View
108 src/clj/kchordr/keycodes.clj
@@ -1,108 +0,0 @@
-(ns kchordr.keycodes)
-
-(def keycodes
- {[1] :esc
- [59] :f1
- [60] :f2
- [61] :f3
- [62] :f4
- [63] :f5
- [64] :f6
- [65] :f7
- [66] :f8
- [67] :f9
- [68] :f10
- [87] :f11
- [88] :f12
- [42 :e0] :prtscn
- [70] :scrlk
- [29 :e1] :pause ; Something is weird. A press gives both 29 (extended) and 69 (not extended)
- [41] :backtick
- [2] :1
- [3] :2
- [4] :3
- [5] :4
- [6] :5
- [7] :6
- [8] :7
- [9] :8
- [10] :9
- [11] :0
- [12] :dash
- [13] :equal
- [14] :backspace
- [82 :e0] :insert
- [71 :e0] :home
- [73 :e0] :page-up
- [81 :e0] :page-down
- [83 :e0] :delete
- [79 :e0] :end
- [15] :tab
- [16] :q
- [17] :w
- [18] :e
- [19] :r
- [20] :t
- [21] :y
- [22] :u
- [23] :i
- [24] :o
- [25] :p
- [26] :lbracket
- [27] :rbracket
- [43] :backslash
- [58] :capslock
- [30] :a
- [31] :s
- [32] :d
- [33] :f
- [34] :g
- [35] :h
- [36] :j
- [37] :k
- [38] :l
- [39] :semicolon
- [40] :quote
- [28] :enter
- [42] :lshift
- [44] :z
- [45] :x
- [46] :c
- [47] :v
- [48] :b
- [49] :n
- [50] :m
- [51] :comma
- [52] :period
- [53] :slash
- [54] :rshift
- [29] :lcontrol
- [91 :e0] :lwindows
- [56] :lalt
- [57] :space
- [56 :e0] :ralt
- [92 :e0] :rwindows
- [93 :e0] :menu
- [29 :e0] :rcontrol
- [72 :e0] :up
- [80 :e0]:down
- [75 :e0] :left
- [77 :e0] :right
- [69] :numlock
- [53 :e0] :kpslash
- [55] :kpstar
- [74] :kpdash
- [82] :kp0
- [79] :kp1
- [80] :kp2
- [81] :kp3
- [75] :kp4
- [76] :kp5
- [77] :kp6
- [71] :kp7
- [72] :kp8
- [73] :kp9
- [83] :kpperiod
- [78] :kpplus
- [28 :e0] :kpenter})
-
View
4 src/clj/kchordr/main.clj
@@ -1,4 +0,0 @@
-(ns kchordr.main
- (:use kchordr))
-
-
View
38 src/java/interception/InterceptionKeyStroke.java
@@ -1,38 +0,0 @@
-package interception;
-import com.ochafik.lang.jnaerator.runtime.Structure;
-/**
- * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
- * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
- * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
- */
-public class InterceptionKeyStroke extends Structure<InterceptionKeyStroke, InterceptionKeyStroke.ByValue, InterceptionKeyStroke.ByReference > {
- public short code;
- public short state;
- public int information;
- public InterceptionKeyStroke() {
- super();
- initFieldOrder();
- }
- protected void initFieldOrder() {
- setFieldOrder(new String[]{"code", "state", "information"});
- }
- public InterceptionKeyStroke(short code, short state, int information) {
- super();
- this.code = code;
- this.state = state;
- this.information = information;
- initFieldOrder();
- }
- protected ByReference newByReference() { return new ByReference(); }
- protected ByValue newByValue() { return new ByValue(); }
- protected InterceptionKeyStroke newInstance() { return new InterceptionKeyStroke(); }
- public static InterceptionKeyStroke[] newArray(int arrayLength) {
- return Structure.newArray(InterceptionKeyStroke.class, arrayLength);
- }
- public static class ByReference extends InterceptionKeyStroke implements Structure.ByReference {
-
- };
- public static class ByValue extends InterceptionKeyStroke implements Structure.ByValue {
-
- };
-}
View
336 src/java/interception/InterceptionLibrary.java
@@ -1,336 +0,0 @@
-package interception;
-import com.ochafik.lang.jnaerator.runtime.LibraryExtractor;
-import com.ochafik.lang.jnaerator.runtime.MangledFunctionMapper;
-import com.sun.jna.Callback;
-import com.sun.jna.Library;
-import com.sun.jna.Native;
-import com.sun.jna.NativeLibrary;
-import com.sun.jna.NativeLong;
-import com.sun.jna.Pointer;
-/**
- * JNA Wrapper for library <b>interception</b><br>
- * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
- * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
- * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
- */
-public interface InterceptionLibrary extends Library {
- public static final String JNA_LIBRARY_NAME = LibraryExtractor.getLibraryPath("interception", true, InterceptionLibrary.class);
- public static final NativeLibrary JNA_NATIVE_LIB = NativeLibrary.getInstance(InterceptionLibrary.JNA_LIBRARY_NAME, MangledFunctionMapper.DEFAULT_OPTIONS);
- public static final InterceptionLibrary INSTANCE = (InterceptionLibrary)Native.loadLibrary(InterceptionLibrary.JNA_LIBRARY_NAME, InterceptionLibrary.class, MangledFunctionMapper.DEFAULT_OPTIONS);
- /**
- * <i>native declaration : line 55</i><br>
- * enum values
- */
- public static interface InterceptionKeyState {
- /// <i>native declaration : line 57</i>
- public static final int INTERCEPTION_KEY_DOWN = (int)0x00;
- /// <i>native declaration : line 58</i>
- public static final int INTERCEPTION_KEY_UP = (int)0x01;
- /// <i>native declaration : line 59</i>
- public static final int INTERCEPTION_KEY_E0 = (int)0x02;
- /// <i>native declaration : line 60</i>
- public static final int INTERCEPTION_KEY_E1 = (int)0x04;
- /// <i>native declaration : line 61</i>
- public static final int INTERCEPTION_KEY_TERMSRV_SET_LED = (int)0x08;
- /// <i>native declaration : line 62</i>
- public static final int INTERCEPTION_KEY_TERMSRV_SHADOW = (int)0x10;
- /// <i>native declaration : line 63</i>
- public static final int INTERCEPTION_KEY_TERMSRV_VKPACKET = (int)0x20;
- };
- /**
- * <i>native declaration : line 66</i><br>
- * enum values
- */
- public static interface InterceptionFilterKeyState {
- /// <i>native declaration : line 68</i>
- public static final int INTERCEPTION_FILTER_KEY_NONE = (int)0x0000;
- /// <i>native declaration : line 69</i>
- public static final int INTERCEPTION_FILTER_KEY_ALL = (int)0xFFFF;
- /**
- * SKIPPED:<br>
- * <i>native declaration : line 70</i><br>
- * INTERCEPTION_FILTER_KEY_DOWN = INTERCEPTION_KEY_UP
- */
- /**
- * SKIPPED:<br>
- * <i>native declaration : line 71</i><br>
- * INTERCEPTION_FILTER_KEY_UP = INTERCEPTION_KEY_UP << 1
- */
- /**
- * SKIPPED:<br>
- * <i>native declaration : line 72</i><br>
- * INTERCEPTION_FILTER_KEY_E0 = INTERCEPTION_KEY_E0 << 1
- */
- /**
- * SKIPPED:<br>
- * <i>native declaration : line 73</i><br>
- * INTERCEPTION_FILTER_KEY_E1 = INTERCEPTION_KEY_E1 << 1
- */
- /**
- * SKIPPED:<br>
- * <i>native declaration : line 74</i><br>
- * INTERCEPTION_FILTER_KEY_TERMSRV_SET_LED = INTERCEPTION_KEY_TERMSRV_SET_LED << 1
- */
- /**
- * SKIPPED:<br>
- * <i>native declaration : line 75</i><br>
- * INTERCEPTION_FILTER_KEY_TERMSRV_SHADOW = INTERCEPTION_KEY_TERMSRV_SHADOW << 1
- */
- /**
- * SKIPPED:<br>
- * <i>native declaration : line 76</i><br>
- * INTERCEPTION_FILTER_KEY_TERMSRV_VKPACKET = INTERCEPTION_KEY_TERMSRV_VKPACKET << 1
- */
- };
- /**
- * <i>native declaration : line 79</i><br>
- * enum values
- */
- public static interface InterceptionMouseState {
- /// <i>native declaration : line 81</i>
- public static final int INTERCEPTION_MOUSE_LEFT_BUTTON_DOWN = (int)0x001;
- /// <i>native declaration : line 82</i>
- public static final int INTERCEPTION_MOUSE_LEFT_BUTTON_UP = (int)0x002;
- /// <i>native declaration : line 83</i>
- public static final int INTERCEPTION_MOUSE_RIGHT_BUTTON_DOWN = (int)0x004;
- /// <i>native declaration : line 84</i>
- public static final int INTERCEPTION_MOUSE_RIGHT_BUTTON_UP = (int)0x008;
- /// <i>native declaration : line 85</i>
- public static final int INTERCEPTION_MOUSE_MIDDLE_BUTTON_DOWN = (int)0x010;
- /// <i>native declaration : line 86</i>
- public static final int INTERCEPTION_MOUSE_MIDDLE_BUTTON_UP = (int)0x020;
- /**
- * SKIPPED:<br>
- * <i>native declaration : line 88</i><br>
- * INTERCEPTION_MOUSE_BUTTON_1_DOWN = INTERCEPTION_MOUSE_LEFT_BUTTON_DOWN
- */
- /**
- * SKIPPED:<br>
- * <i>native declaration : line 89</i><br>
- * INTERCEPTION_MOUSE_BUTTON_1_UP = INTERCEPTION_MOUSE_LEFT_BUTTON_UP
- */
- /**
- * SKIPPED:<br>
- * <i>native declaration : line 90</i><br>
- * INTERCEPTION_MOUSE_BUTTON_2_DOWN = INTERCEPTION_MOUSE_RIGHT_BUTTON_DOWN
- */
- /**
- * SKIPPED:<br>
- * <i>native declaration : line 91</i><br>
- * INTERCEPTION_MOUSE_BUTTON_2_UP = INTERCEPTION_MOUSE_RIGHT_BUTTON_UP
- */
- /**
- * SKIPPED:<br>
- * <i>native declaration : line 92</i><br>
- * INTERCEPTION_MOUSE_BUTTON_3_DOWN = INTERCEPTION_MOUSE_MIDDLE_BUTTON_DOWN
- */
- /**
- * SKIPPED:<br>
- * <i>native declaration : line 93</i><br>
- * INTERCEPTION_MOUSE_BUTTON_3_UP = INTERCEPTION_MOUSE_MIDDLE_BUTTON_UP
- */
- /// <i>native declaration : line 95</i>
- public static final int INTERCEPTION_MOUSE_BUTTON_4_DOWN = (int)0x040;
- /// <i>native declaration : line 96</i>
- public static final int INTERCEPTION_MOUSE_BUTTON_4_UP = (int)0x080;
- /// <i>native declaration : line 97</i>
- public static final int INTERCEPTION_MOUSE_BUTTON_5_DOWN = (int)0x100;
- /// <i>native declaration : line 98</i>
- public static final int INTERCEPTION_MOUSE_BUTTON_5_UP = (int)0x200;
- /// <i>native declaration : line 100</i>
- public static final int INTERCEPTION_MOUSE_WHEEL = (int)0x400;
- /// <i>native declaration : line 101</i>
- public static final int INTERCEPTION_MOUSE_HWHEEL = (int)0x800;
- };
- /**
- * <i>native declaration : line 104</i><br>
- * enum values
- */
- public static interface InterceptionFilterMouseState {
- /// <i>native declaration : line 106</i>
- public static final int INTERCEPTION_FILTER_MOUSE_NONE = (int)0x0000;
- /// <i>native declaration : line 107</i>
- public static final int INTERCEPTION_FILTER_MOUSE_ALL = (int)0xFFFF;
- /**
- * SKIPPED:<br>
- * <i>native declaration : line 109</i><br>
- * INTERCEPTION_FILTER_MOUSE_LEFT_BUTTON_DOWN = INTERCEPTION_MOUSE_LEFT_BUTTON_DOWN
- */
- /**
- * SKIPPED:<br>
- * <i>native declaration : line 110</i><br>
- * INTERCEPTION_FILTER_MOUSE_LEFT_BUTTON_UP = INTERCEPTION_MOUSE_LEFT_BUTTON_UP
- */
- /**
- * SKIPPED:<br>
- * <i>native declaration : line 111</i><br>
- * INTERCEPTION_FILTER_MOUSE_RIGHT_BUTTON_DOWN = INTERCEPTION_MOUSE_RIGHT_BUTTON_DOWN
- */
- /**
- * SKIPPED:<br>
- * <i>native declaration : line 112</i><br>
- * INTERCEPTION_FILTER_MOUSE_RIGHT_BUTTON_UP = INTERCEPTION_MOUSE_RIGHT_BUTTON_UP
- */
- /**
- * SKIPPED:<br>
- * <i>native declaration : line 113</i><br>
- * INTERCEPTION_FILTER_MOUSE_MIDDLE_BUTTON_DOWN = INTERCEPTION_MOUSE_MIDDLE_BUTTON_DOWN
- */
- /**
- * SKIPPED:<br>
- * <i>native declaration : line 114</i><br>
- * INTERCEPTION_FILTER_MOUSE_MIDDLE_BUTTON_UP = INTERCEPTION_MOUSE_MIDDLE_BUTTON_UP
- */
- /**
- * SKIPPED:<br>
- * <i>native declaration : line 116</i><br>
- * INTERCEPTION_FILTER_MOUSE_BUTTON_1_DOWN = INTERCEPTION_MOUSE_BUTTON_1_DOWN
- */
- /**
- * SKIPPED:<br>
- * <i>native declaration : line 117</i><br>
- * INTERCEPTION_FILTER_MOUSE_BUTTON_1_UP = INTERCEPTION_MOUSE_BUTTON_1_UP
- */
- /**
- * SKIPPED:<br>
- * <i>native declaration : line 118</i><br>
- * INTERCEPTION_FILTER_MOUSE_BUTTON_2_DOWN = INTERCEPTION_MOUSE_BUTTON_2_DOWN
- */
- /**
- * SKIPPED:<br>
- * <i>native declaration : line 119</i><br>
- * INTERCEPTION_FILTER_MOUSE_BUTTON_2_UP = INTERCEPTION_MOUSE_BUTTON_2_UP
- */
- /**
- * SKIPPED:<br>
- * <i>native declaration : line 120</i><br>
- * INTERCEPTION_FILTER_MOUSE_BUTTON_3_DOWN = INTERCEPTION_MOUSE_BUTTON_3_DOWN
- */
- /**
- * SKIPPED:<br>
- * <i>native declaration : line 121</i><br>
- * INTERCEPTION_FILTER_MOUSE_BUTTON_3_UP = INTERCEPTION_MOUSE_BUTTON_3_UP
- */
- /**
- * SKIPPED:<br>
- * <i>native declaration : line 123</i><br>
- * INTERCEPTION_FILTER_MOUSE_BUTTON_4_DOWN = INTERCEPTION_MOUSE_BUTTON_4_DOWN
- */
- /**
- * SKIPPED:<br>
- * <i>native declaration : line 124</i><br>
- * INTERCEPTION_FILTER_MOUSE_BUTTON_4_UP = INTERCEPTION_MOUSE_BUTTON_4_UP
- */
- /**
- * SKIPPED:<br>
- * <i>native declaration : line 125</i><br>
- * INTERCEPTION_FILTER_MOUSE_BUTTON_5_DOWN = INTERCEPTION_MOUSE_BUTTON_5_DOWN
- */
- /**
- * SKIPPED:<br>
- * <i>native declaration : line 126</i><br>
- * INTERCEPTION_FILTER_MOUSE_BUTTON_5_UP = INTERCEPTION_MOUSE_BUTTON_5_UP
- */
- /**
- * SKIPPED:<br>
- * <i>native declaration : line 128</i><br>
- * INTERCEPTION_FILTER_MOUSE_WHEEL = INTERCEPTION_MOUSE_WHEEL
- */
- /**
- * SKIPPED:<br>
- * <i>native declaration : line 129</i><br>
- * INTERCEPTION_FILTER_MOUSE_HWHEEL = INTERCEPTION_MOUSE_HWHEEL
- */
- /// <i>native declaration : line 131</i>
- public static final int INTERCEPTION_FILTER_MOUSE_MOVE = (int)0x1000;
- };
- /**
- * <i>native declaration : line 134</i><br>
- * enum values
- */
- public static interface InterceptionMouseFlag {
- /// <i>native declaration : line 136</i>
- public static final int INTERCEPTION_MOUSE_MOVE_RELATIVE = (int)0x000;
- /// <i>native declaration : line 137</i>
- public static final int INTERCEPTION_MOUSE_MOVE_ABSOLUTE = (int)0x001;
- /// <i>native declaration : line 138</i>
- public static final int INTERCEPTION_MOUSE_VIRTUAL_DESKTOP = (int)0x002;
- /// <i>native declaration : line 139</i>
- public static final int INTERCEPTION_MOUSE_ATTRIBUTES_CHANGED = (int)0x004;
- /// <i>native declaration : line 140</i>
- public static final int INTERCEPTION_MOUSE_MOVE_NOCOALESCE = (int)0x008;
- /// <i>native declaration : line 141</i>
- public static final int INTERCEPTION_MOUSE_TERMSRV_SRC_SHADOW = (int)0x100;
- };
- public static final int INTERCEPTION_MAX_DEVICE = (int)((10) + (10));
- public static final int INTERCEPTION_MAX_MOUSE = (int)10;
- public static final int INTERCEPTION_MAX_KEYBOARD = (int)10;
- public interface InterceptionPredicate extends Callback {
- int apply(int device);
- };
- /**
- * Original signature : <code>__attribute__((dllimport)) InterceptionContext interception_create_context()</code><br>
- * <i>native declaration : line 163</i>
- */
- Pointer interception_create_context();
- /**
- * Original signature : <code>__attribute__((dllimport)) void interception_destroy_context(InterceptionContext)</code><br>
- * <i>native declaration : line 165</i>
- */
- void interception_destroy_context(Pointer context);
- /**
- * Original signature : <code>__attribute__((dllimport)) InterceptionPrecedence interception_get_precedence(InterceptionContext, InterceptionDevice)</code><br>
- * <i>native declaration : line 167</i>
- */
- int interception_get_precedence(Pointer context, int device);
- /**
- * Original signature : <code>__attribute__((dllimport)) void interception_set_precedence(InterceptionContext, InterceptionDevice, InterceptionPrecedence)</code><br>
- * <i>native declaration : line 169</i>
- */
- void interception_set_precedence(Pointer context, int device, int precedence);
- /**
- * Original signature : <code>__attribute__((dllimport)) InterceptionFilter interception_get_filter(InterceptionContext, InterceptionDevice)</code><br>
- * <i>native declaration : line 171</i>
- */
- short interception_get_filter(Pointer context, int device);
- /**
- * Original signature : <code>__attribute__((dllimport)) void interception_set_filter(InterceptionContext, InterceptionPredicate, InterceptionFilter)</code><br>
- * <i>native declaration : line 173</i>
- */
- void interception_set_filter(Pointer context, InterceptionLibrary.InterceptionPredicate predicate, short filter);
- /**
- * Original signature : <code>__attribute__((dllimport)) InterceptionDevice interception_wait(InterceptionContext)</code><br>
- * <i>native declaration : line 175</i>
- */
- int interception_wait(Pointer context);
- /**
- * Original signature : <code>__attribute__((dllimport)) InterceptionDevice interception_wait_with_timeout(InterceptionContext, unsigned long)</code><br>
- * <i>native declaration : line 177</i>
- */
- int interception_wait_with_timeout(Pointer context, NativeLong milliseconds);
- /**
- * Original signature : <code>__attribute__((dllimport)) int interception_send(InterceptionContext, InterceptionDevice, const InterceptionStroke*, unsigned int)</code><br>
- * <i>native declaration : line 179</i>
- */
- int interception_send(Pointer context, int device, InterceptionKeyStroke.ByReference stroke, int nstroke);
- /**
- * Original signature : <code>__attribute__((dllimport)) int interception_receive(InterceptionContext, InterceptionDevice, InterceptionStroke*, unsigned int)</code><br>
- * <i>native declaration : line 181</i>
- */
- int interception_receive(Pointer context, int device, InterceptionKeyStroke.ByReference stroke, int nstroke);
- /**
- * Original signature : <code>__attribute__((dllimport)) int interception_is_invalid(InterceptionDevice)</code><br>
- * <i>native declaration : line 183</i>
- */
- int interception_is_invalid(int device);
- /**
- * Original signature : <code>__attribute__((dllimport)) int interception_is_keyboard(InterceptionDevice)</code><br>
- * <i>native declaration : line 185</i>
- */
- int interception_is_keyboard(int device);
- /**
- * Original signature : <code>__attribute__((dllimport)) int interception_is_mouse(InterceptionDevice)</code><br>
- * <i>native declaration : line 187</i>
- */
- int interception_is_mouse(int device);
-}
View
44 src/java/interception/InterceptionMouseStroke.java
@@ -1,44 +0,0 @@
-package interception;
-import com.ochafik.lang.jnaerator.runtime.Structure;
-/**
- * This file was autogenerated by <a href="http://jnaerator.googlecode.com/">JNAerator</a>,<br>
- * a tool written by <a href="http://ochafik.com/">Olivier Chafik</a> that <a href="http://code.google.com/p/jnaerator/wiki/CreditsAndLicense">uses a few opensource projects.</a>.<br>
- * For help, please visit <a href="http://nativelibs4java.googlecode.com/">NativeLibs4Java</a> , <a href="http://rococoa.dev.java.net/">Rococoa</a>, or <a href="http://jna.dev.java.net/">JNA</a>.
- */
-public class InterceptionMouseStroke extends Structure<InterceptionMouseStroke, InterceptionMouseStroke.ByValue, InterceptionMouseStroke.ByReference > {
- public short state;
- public short flags;
- public short rolling;
- public int x;
- public int y;
- public int information;
- public InterceptionMouseStroke() {
- super();
- initFieldOrder();
- }
- protected void initFieldOrder() {
- setFieldOrder(new String[]{"state", "flags", "rolling", "x", "y", "information"});
- }
- public InterceptionMouseStroke(short state, short flags, short rolling, int x, int y, int information) {
- super();
- this.state = state;
- this.flags = flags;
- this.rolling = rolling;
- this.x = x;
- this.y = y;
- this.information = information;
- initFieldOrder();
- }
- protected ByReference newByReference() { return new ByReference(); }
- protected ByValue newByValue() { return new ByValue(); }
- protected InterceptionMouseStroke newInstance() { return new InterceptionMouseStroke(); }
- public static InterceptionMouseStroke[] newArray(int arrayLength) {
- return Structure.newArray(InterceptionMouseStroke.class, arrayLength);
- }
- public static class ByReference extends InterceptionMouseStroke implements Structure.ByReference {
-
- };
- public static class ByValue extends InterceptionMouseStroke implements Structure.ByValue {
-
- };
-}
View
17 src/java/interception/TestLibrary.java
@@ -1,17 +0,0 @@
-package interception;
-import com.ochafik.lang.jnaerator.runtime.LibraryExtractor;
-import com.ochafik.lang.jnaerator.runtime.MangledFunctionMapper;
-import com.sun.jna.Callback;
-import com.sun.jna.Library;
-import com.sun.jna.Native;
-import com.sun.jna.NativeLibrary;
-import com.sun.jna.NativeLong;
-import com.sun.jna.Pointer;
-
-public interface TestLibrary extends Library {
- public static final String JNA_LIBRARY_NAME = LibraryExtractor.getLibraryPath("test", true, TestLibrary.class);
- public static final NativeLibrary JNA_NATIVE_LIB = NativeLibrary.getInstance(TestLibrary.JNA_LIBRARY_NAME, MangledFunctionMapper.DEFAULT_OPTIONS);
- public static final TestLibrary INSTANCE = (TestLibrary)Native.loadLibrary(TestLibrary.JNA_LIBRARY_NAME, TestLibrary.class, MangledFunctionMapper.DEFAULT_OPTIONS);
-
- int DoSomething(int x);
-}
View
104 test/kchordr/test/kchordr.clj
@@ -1,104 +0,0 @@
-(ns kchordr.test.kchordr
- (:refer-clojure :exclude (send))
- (:require [kchordr :refer (handle-keys make-modifier-alias base-state)])
- (:use [clojure.test]))
-
-(def test-key-behaviors
- {:j [make-modifier-alias :rshift]
- :k [make-modifier-alias :rcontrol]})
-
-(defn- sent
- "Given a sequence of key events, return the sequence of keys that
- will actually be sent."
- [events]
- (:effects (reduce #(handle-keys %1 %2)
- (base-state test-key-behaviors)
- events)))
-
-(defn- ->event
- [[key direction]]
- {:key key :direction direction})
-
-(defn- press
- "Given a seq of pairs of [key direction], return the sent keys as a
- similar seq."
- [pressed]
- (sent (map ->event pressed)))
-
-(deftest key-tests
- (are [pressed anticipated]
- ;; We use vectors as the test format because they're easier to
- ;; read, but we still want to use maps as the underlying
- ;; construct for their flexibility. Yay juxt!
- (= anticipated (press pressed))
- ;; Single regular key press
- [[:b :dn]]
- [:key [:b :dn]]
-
- ;; Single regular key press and release
- [[:b :dn] [:b :up]]
- [:key [:b :dn] :key [:b :up]]
-
- ;; Modifier alias press only
- [[:j :dn]]
- []
-
- ;; Modifier alias press and release
- [[:j :dn] [:j :up]]
- [:key [:j :dn] :key [:j :up]]
-
- ;; Modifier alias repeat and release
- [[:j :dn] [:j :dn] [:j :dn] [:j :dn] [:j :up]]
- [:key [:j :dn] :key [:j :up]]
-
- ;; Modifier alias with regular key press
- [[:j :dn] [:x :dn]]
- [:key [:rshift :dn] :key [:x :dn]]
-
- ;; Modifier alias with regular key press and release
- [[:j :dn] [:x :dn] [:x :up] [:j :up]]
- [:key [:rshift :dn] :key [:x :dn] :key [:x :up] :key [:rshift :up]]
-
- ;; Modifier alias with regular key press and release followed
- ;; by modifier alias press and release
- [[:j :dn] [:x :dn] [:x :up] [:j :up] [:j :dn] [:j :up]]
- [:key [:rshift :dn]
- :key [:x :dn]
- :key [:x :up]
- :key [:rshift :up]
- :key [:j :dn]
- :key [:j :up]]
-
- ;; Multiple modifier aliases down sends the first modifier
- [[:j :dn] [:k :dn]]
- [:key [:rshift :dn]]
-
- ;; Multiple modifier aliases down followed by regular key down
- ;; adds both modifiers to regular key
- [[:j :dn] [:k :dn] [:x :dn]]
- [:key [:rshift :dn] :key [:rcontrol :dn] :key [:x :dn]]
-
- ;; Order of modifier aliases down is preserved? (TODO: Is this
- ;; what we want?)
- [[:k :dn] [:j :dn] [:x :dn]]
- [:key [:rcontrol :dn] :key [:rshift :dn] :key [:x :dn]]
-
- ;; A modifier alias going up when another modifier is undecided
- ;; means the second modifier was a regular keypress.
- [[:j :dn] [:k :dn] [:k :up]]
- [:key [:rshift :dn] :key [:k :dn] :key [:k :up]]
-
- ;; We have the ability to quit the application
- [[:backtick :dn] [:q :dn]]
- [:quit nil]
-
- ;; But other nearby key sequences don't quit
- [[:backtick :dn] [:backtick :up] [:q :dn] [:backtick :dn]]
- [:key [:backtick :dn]
- :key [:backtick :up]
- :key [:q :dn]
- :key [:backtick :dn]]
-
- ;; TODO: Also move towards using key maps to describe keys even on output
- ))
-
View
9 test/kchordr/test/keycodes.clj
@@ -1,9 +0,0 @@
-(ns kchordr.test.keycodes
- (:use kchordr.keycodes
- clojure.test))
-
-;; (deftest keycode-tests
-;; (are [original expected-translation]
-;; (= expected-translation (translate original))
-
-;; 30 :a))
Please sign in to comment.
Something went wrong with that request. Please try again.