Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with
or
.
Download ZIP
Browse files

better and improved key bindings mechanism

  • Loading branch information...
commit 612aef4d15c2d23d543acff9803f3710cd044635 1 parent c26286f
@rsms authored
View
16 kod.xcodeproj/project.pbxproj
@@ -136,6 +136,8 @@
3AB97DA612B2A00F00F4ADB2 /* BWCustomView.m in Sources */ = {isa = PBXBuildFile; fileRef = 3AB97DA512B2A00F00F4ADB2 /* BWCustomView.m */; };
3AB97DAC12B2A02300F4ADB2 /* NSApplication+BWAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 3AB97DA812B2A02300F4ADB2 /* NSApplication+BWAdditions.m */; };
3AB97DAD12B2A02300F4ADB2 /* NSWindow+BWAdditions.m in Sources */ = {isa = PBXBuildFile; fileRef = 3AB97DAB12B2A02300F4ADB2 /* NSWindow+BWAdditions.m */; };
+ 3ABAEFB012F5C781001E4A36 /* dec2bin.c in Sources */ = {isa = PBXBuildFile; fileRef = 3ABAEFAF12F5C781001E4A36 /* dec2bin.c */; };
+ 3ABAF0A112F5DFA1001E4A36 /* NSEvent-kod.m in Sources */ = {isa = PBXBuildFile; fileRef = 3ABAF0A012F5DFA1001E4A36 /* NSEvent-kod.m */; };
3ABF49C012A450660020233C /* NSView-kod.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3ABF49BF12A450660020233C /* NSView-kod.mm */; };
3ABF4C6D12A48E7D0020233C /* NSData-kod.mm in Sources */ = {isa = PBXBuildFile; fileRef = 3ABF4C6C12A48E7D0020233C /* NSData-kod.mm */; };
3ABF4F3E12A55AFC0020233C /* NSString-editdistance.m in Sources */ = {isa = PBXBuildFile; fileRef = 3ABF4F3D12A55AFC0020233C /* NSString-editdistance.m */; };
@@ -480,6 +482,10 @@
3AB97DA912B2A02300F4ADB2 /* NSCustomView.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NSCustomView.h; path = deps/bwtoolkit/NSCustomView.h; sourceTree = SOURCE_ROOT; };
3AB97DAA12B2A02300F4ADB2 /* NSWindow+BWAdditions.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = "NSWindow+BWAdditions.h"; path = "deps/bwtoolkit/NSWindow+BWAdditions.h"; sourceTree = SOURCE_ROOT; };
3AB97DAB12B2A02300F4ADB2 /* NSWindow+BWAdditions.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; name = "NSWindow+BWAdditions.m"; path = "deps/bwtoolkit/NSWindow+BWAdditions.m"; sourceTree = SOURCE_ROOT; };
+ 3ABAEFAE12F5C781001E4A36 /* dec2bin.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = dec2bin.h; sourceTree = "<group>"; };
+ 3ABAEFAF12F5C781001E4A36 /* dec2bin.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = dec2bin.c; sourceTree = "<group>"; };
+ 3ABAF09F12F5DFA1001E4A36 /* NSEvent-kod.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSEvent-kod.h"; sourceTree = "<group>"; };
+ 3ABAF0A012F5DFA1001E4A36 /* NSEvent-kod.m */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.objc; path = "NSEvent-kod.m"; sourceTree = "<group>"; };
3ABF483812A406AF0020233C /* hdispatch.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = hdispatch.h; sourceTree = "<group>"; };
3ABF49BE12A450660020233C /* NSView-kod.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = "NSView-kod.h"; sourceTree = "<group>"; };
3ABF49BF12A450660020233C /* NSView-kod.mm */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.objcpp; path = "NSView-kod.mm"; sourceTree = "<group>"; };
@@ -611,6 +617,8 @@
3A510C4A12C2ADCB00AAC1D5 /* kfs.m */,
3AF3A0A312BF7F6400FC534A /* KAnimation.h */,
3AF3A0A412BF7F6400FC534A /* KAnimation.m */,
+ 3ABAEFAE12F5C781001E4A36 /* dec2bin.h */,
+ 3ABAEFAF12F5C781001E4A36 /* dec2bin.c */,
);
name = Helpers;
sourceTree = "<group>";
@@ -778,6 +786,8 @@
3A92911A1229B96A00DA7E43 /* KDocument.mm */,
3AC2D4A51298D8050066B586 /* KTextStorage.h */,
3AC2D4A61298D8050066B586 /* KTextStorage.mm */,
+ 3A7D86AC12F45EF6005740FF /* KInputBindings.h */,
+ 3A7D86AD12F45EF6005740FF /* KInputBindings.mm */,
3AA8133812C36B390085F086 /* URL handlers */,
3AA819AF12C549490085F086 /* Crash reporting */,
3A5107C812C1231700AAC1D5 /* kod helper */,
@@ -933,8 +943,6 @@
3ABF539712A5D5360020233C /* Main views */ = {
isa = PBXGroup;
children = (
- 3A7D86AC12F45EF6005740FF /* KInputBindings.h */,
- 3A7D86AD12F45EF6005740FF /* KInputBindings.mm */,
3A7D866712F43392005740FF /* KWindow.h */,
3A7D866812F43392005740FF /* KWindow.mm */,
3ABF539412A5D52F0020233C /* KSplitView.h */,
@@ -1025,6 +1033,8 @@
3AA81B2312C62D270085F086 /* CIImage-kod.m */,
3AA81B2512C62D6A0085F086 /* NSImage-kod.h */,
3AA81B2612C62D6A0085F086 /* NSImage-kod.m */,
+ 3ABAF09F12F5DFA1001E4A36 /* NSEvent-kod.h */,
+ 3ABAF0A012F5DFA1001E4A36 /* NSEvent-kod.m */,
);
name = "NS categories";
sourceTree = "<group>";
@@ -1373,6 +1383,8 @@
3A1A4A8712E0A6EF00887625 /* KWindowBackgroundCoverView.m in Sources */,
3A7D866912F43392005740FF /* KWindow.mm in Sources */,
3A7D86AE12F45EF6005740FF /* KInputBindings.mm in Sources */,
+ 3ABAEFB012F5C781001E4A36 /* dec2bin.c in Sources */,
+ 3ABAF0A112F5DFA1001E4A36 /* NSEvent-kod.m in Sources */,
);
runOnlyForDeploymentPostprocessing = 0;
};
View
29 src/HUnorderedMap.h
@@ -49,10 +49,13 @@ class HUnorderedMap {
virtual ~HUnorderedMap() { }
+ // reference to the underlying tr1 unordered_map
inline map_type &map() { return map_; }
+ // adding entries
inline void insert(K key, T value) { map_.insert(entry_type(key, value)); }
+ // locating entries
inline iterator find(K key) { return map_.find(key); }
inline const_iterator find(K key) const { return map_.find(key); }
inline iterator findSync(K key) {
@@ -60,17 +63,37 @@ class HUnorderedMap {
return map_.find(key);
}
+ // removing specific entries
+ inline iterator erase(iterator where) { return map_.erase(where); }
+ inline iterator erase(iterator first, iterator last) {
+ return map_.erase(first, last);
+ }
+ inline size_t erase(const K& key) { return map_.erase(key); }
+ iterator eraseSync(iterator where) {
+ _HSLScope(spinlock_);
+ return erase(where);
+ }
+ iterator eraseSync(iterator first, iterator last) {
+ _HSLScope(spinlock_);
+ return erase(first, last);
+ }
+ size_t eraseSync(const K& key) { _HSLScope(spinlock_); return erase(key); }
+
+ // removing all entries
+ void clear() { map_.clear(); }
+ void clearSync() { _HSLScope(spinlock_); clear(); }
+
+ // swapping this map with another map
inline void swap(map_type& other) { map_.swap(other.map_); }
inline void swapSync(map_type& other) { _HSLScope(spinlock_); swap(other); }
+ // counting entries
inline size_t size() const { return map_.size(); }
inline size_t sizeSync() const { _HSLScope(spinlock_); return size(); }
+ // testing for empty-ness
bool empty() const { return size() == 0; }
bool emptySync() const { return sizeSync() == 0; }
-
- void clear() { map_.clear(); }
- void clearSync() { _HSLScope(spinlock_); clear(); }
};
View
61 src/KInputBindings.h
@@ -1,16 +1,17 @@
-#include <map>
-#include <string>
#include <tr1/memory>
+#include <assert.h>
#include "HUnorderedMap.h"
+#import "NSEvent-kod.h"
-class KInputAction;
-typedef std::tr1::shared_ptr<KInputAction> KInputActionPtr;
-
+// an action which is associated with an input sequence in KInputBindings
class KInputAction {
public:
virtual BOOL perform(id sender) = 0;
};
+typedef std::tr1::shared_ptr<KInputAction> KInputActionPtr;
+
+// an action which invokes a Objective-C selector on its target or sender
class KSelectorInputAction : public KInputAction {
public:
KSelectorInputAction(SEL selector, id target=nil) {
@@ -35,21 +36,55 @@ class KSelectorInputAction : public KInputAction {
id target_;
};
+// holds input bindings
class KInputBindings {
public:
- static void set(std::string seq, KInputAction *action) {
- bindings_.putSync(seq, action);
+ // map type
+ typedef HUnorderedMapSharedPtr<uint64_t, KInputAction> Map;
+
+ // level of the application where an event is bound and active
+ enum Level {
+ AppLevel = 0, // events captured when entering the app ("top level")
+ TextEditorLevel, // events captured in the text editor
+ MaxLevel // (Never use this)
+ };
+
+ static void set(Level level, uint64_t key, KInputAction *action) {
+ assert(level < MaxLevel);
+ bindings_[level].putSync(key, action);
}
- static void set(NSString *seq, KInputAction *action) {
- set(std::string([seq UTF8String]), action);
+ // bind |action| to a sequence (e.g. "M-S-r")
+ static BOOL set(Level level, NSString *seq, KInputAction *action);
+
+ // find an action for an event. returns null if not found.
+ static KInputAction *get(Level level, uint64_t key) {
+ assert(level < MaxLevel);
+ return bindings_[level].getSync(key);
+ }
+ static KInputAction *get(Level level, NSEvent *event) {
+ return get(level, [event kodHash]);
}
+ static KInputAction *get(Level level, NSString *seq);
+
+ // retrieve mappings for |level|. |level| must be within [0-MaxLevel)
+ static Map& get(Level level) { return bindings_[level]; }
- static KInputAction *get(std::string seq) {
- return bindings_.getSync(seq);
+ // remove any binding for |key|. returns true if found and removed.
+ static BOOL remove(Level level, uint64_t key) {
+ assert(level < MaxLevel);
+ return bindings_[level].eraseSync(key) != 0;
}
- static KInputAction *get(NSEvent *event);
+ // removes |key| from all levels and returns the number of bindings removed
+ static size_t remove(uint64_t key);
+
+ // removes all bindings (from all levels if level is MaxLevel)
+ static void clear(Level level=MaxLevel);
+
+ // parse a single sequence (e.g. "M-S-r") into it's canonical key
+ // returns 0 (zero) to indicate a bad/illegal sequence.
+ static uint64_t parseSequence(NSString *seq);
protected:
- static HUnorderedMapSharedPtr<std::string, KInputAction> bindings_;
+ static Map bindings_[MaxLevel];
};
View
286 src/KInputBindings.mm
@@ -1,124 +1,192 @@
#import "KInputBindings.h"
#import "common.h"
+#include "dec2bin.h"
-HUnorderedMapSharedPtr<std::string, KInputAction> KInputBindings::bindings_;
+#define K_UC_ISFNKEY(c) ((c) >= 0xF700 && (c) <= 0xF8FF)
+KInputBindings::Map KInputBindings::bindings_[KInputBindings::MaxLevel];
-KInputAction *KInputBindings::get(NSEvent *event) {
- // we only handle key events (for now)
- NSEventType t = event.type;
- if (t != NSKeyDown && t != NSKeyUp) return NULL;
+static NSDictionary *gFuncKeyNamesToUnicodePoints = nil;
+
+static void __attribute__((constructor)) __init() {
+ NSAutoreleasePool *pool = [NSAutoreleasePool new];
+ gFuncKeyNamesToUnicodePoints = [[NSDictionary alloc] initWithObjectsAndKeys:
+ [NSNumber numberWithShort:NSUpArrowFunctionKey], @"up",
+ [NSNumber numberWithShort:NSDownArrowFunctionKey], @"down",
+ [NSNumber numberWithShort:NSLeftArrowFunctionKey], @"left",
+ [NSNumber numberWithShort:NSRightArrowFunctionKey], @"right",
+ [NSNumber numberWithShort:NSF1FunctionKey], @"f1",
+ [NSNumber numberWithShort:NSF2FunctionKey], @"f2",
+ [NSNumber numberWithShort:NSF3FunctionKey], @"f3",
+ [NSNumber numberWithShort:NSF4FunctionKey], @"f4",
+ [NSNumber numberWithShort:NSF5FunctionKey], @"f5",
+ [NSNumber numberWithShort:NSF6FunctionKey], @"f6",
+ [NSNumber numberWithShort:NSF7FunctionKey], @"f7",
+ [NSNumber numberWithShort:NSF8FunctionKey], @"f8",
+ [NSNumber numberWithShort:NSF9FunctionKey], @"f9",
+ [NSNumber numberWithShort:NSF10FunctionKey], @"f10",
+ [NSNumber numberWithShort:NSF11FunctionKey], @"f11",
+ [NSNumber numberWithShort:NSF12FunctionKey], @"f12",
+ [NSNumber numberWithShort:NSF13FunctionKey], @"f13",
+ [NSNumber numberWithShort:NSF14FunctionKey], @"f14",
+ [NSNumber numberWithShort:NSF15FunctionKey], @"f15",
+ [NSNumber numberWithShort:NSF16FunctionKey], @"f16",
+ [NSNumber numberWithShort:NSF17FunctionKey], @"f17",
+ [NSNumber numberWithShort:NSF18FunctionKey], @"f18",
+ [NSNumber numberWithShort:NSF19FunctionKey], @"f19",
+ [NSNumber numberWithShort:NSF20FunctionKey], @"f20",
+ [NSNumber numberWithShort:NSF21FunctionKey], @"f21",
+ [NSNumber numberWithShort:NSF22FunctionKey], @"f22",
+ [NSNumber numberWithShort:NSF23FunctionKey], @"f23",
+ [NSNumber numberWithShort:NSF24FunctionKey], @"f24",
+ [NSNumber numberWithShort:NSF25FunctionKey], @"f25",
+ [NSNumber numberWithShort:NSF26FunctionKey], @"f26",
+ [NSNumber numberWithShort:NSF27FunctionKey], @"f27",
+ [NSNumber numberWithShort:NSF28FunctionKey], @"f28",
+ [NSNumber numberWithShort:NSF29FunctionKey], @"f29",
+ [NSNumber numberWithShort:NSF30FunctionKey], @"f30",
+ [NSNumber numberWithShort:NSF31FunctionKey], @"f31",
+ [NSNumber numberWithShort:NSF32FunctionKey], @"f32",
+ [NSNumber numberWithShort:NSF33FunctionKey], @"f33",
+ [NSNumber numberWithShort:NSF34FunctionKey], @"f34",
+ [NSNumber numberWithShort:NSF35FunctionKey], @"f35",
+ [NSNumber numberWithShort:NSInsertFunctionKey], @"insert",
+ [NSNumber numberWithShort:NSDeleteFunctionKey], @"del",
+ [NSNumber numberWithShort:NSHomeFunctionKey], @"home",
+ [NSNumber numberWithShort:NSBeginFunctionKey], @"begin",
+ [NSNumber numberWithShort:NSEndFunctionKey], @"end",
+ [NSNumber numberWithShort:NSPageUpFunctionKey], @"pageup",
+ [NSNumber numberWithShort:NSPageDownFunctionKey], @"pagedown",
+ [NSNumber numberWithShort:NSPrintScreenFunctionKey], @"printscreen",
+ [NSNumber numberWithShort:NSScrollLockFunctionKey], @"scrollock",
+ [NSNumber numberWithShort:NSPauseFunctionKey], @"pause",
+ [NSNumber numberWithShort:NSSysReqFunctionKey], @"sysreq",
+ [NSNumber numberWithShort:NSBreakFunctionKey], @"break",
+ [NSNumber numberWithShort:NSResetFunctionKey], @"reset",
+ [NSNumber numberWithShort:NSStopFunctionKey], @"stop",
+ [NSNumber numberWithShort:NSMenuFunctionKey], @"menu",
+ [NSNumber numberWithShort:NSUserFunctionKey], @"user",
+ [NSNumber numberWithShort:NSSystemFunctionKey], @"system",
+ [NSNumber numberWithShort:NSPrintFunctionKey], @"print",
+ [NSNumber numberWithShort:NSClearLineFunctionKey], @"clearline",
+ [NSNumber numberWithShort:NSClearDisplayFunctionKey], @"cleardisplay",
+ [NSNumber numberWithShort:NSInsertLineFunctionKey], @"insertline",
+ [NSNumber numberWithShort:NSDeleteLineFunctionKey], @"deleteline",
+ [NSNumber numberWithShort:NSInsertCharFunctionKey], @"insertchar",
+ [NSNumber numberWithShort:NSDeleteCharFunctionKey], @"deletechar",
+ [NSNumber numberWithShort:NSPrevFunctionKey], @"prev",
+ [NSNumber numberWithShort:NSNextFunctionKey], @"next",
+ [NSNumber numberWithShort:NSSelectFunctionKey], @"select",
+ [NSNumber numberWithShort:NSExecuteFunctionKey], @"execute",
+ [NSNumber numberWithShort:NSUndoFunctionKey], @"undo",
+ [NSNumber numberWithShort:NSRedoFunctionKey], @"redo",
+ [NSNumber numberWithShort:NSFindFunctionKey], @"find",
+ [NSNumber numberWithShort:NSHelpFunctionKey], @"help",
+ [NSNumber numberWithShort:NSModeSwitchFunctionKey], @"modeswitch",
+ nil];
+ [pool drain];
+}
- std::string seq;
- NSUInteger modifiers = [event modifierFlags];
- NSString *chars = [event charactersIgnoringModifiers];
- NSString *charsLower = nil;
- unichar functionKeyChar = 0;
- // TODO: support more than one key
- if (chars.length != 0) {
- unichar ch = [chars characterAtIndex:0];
- if (ch >= 0xF700 && ch <= 0xF8FF) {
- functionKeyChar = ch;
- modifiers &= ~NSFunctionKeyMask;
- } else {
- chars = [chars substringToIndex:1];
- charsLower = [chars lowercaseString];
- if (![chars isEqualToString:charsLower])
- modifiers |= NSShiftKeyMask;
+uint64_t KInputBindings::parseSequence(NSString *seq) {
+ uint64_t key = 0;
+ static const int ucbufSize = 512;
+ unichar ucbuf[ucbufSize];
+ int charoffs = 16;
+ NSRange r = NSMakeRange(0, MIN([seq length], ucbufSize));
+ [seq getCharacters:ucbuf range:r];
+ for (NSUInteger i=0; i<r.length; ++i) {
+ unichar c = ucbuf[i];
+ if (isupper(c)) {
+ switch (c) {
+ case 'A': key |= (NSAlternateKeyMask >> 16); break;
+ case 'C': key |= (NSControlKeyMask >> 16); break;
+ case 'F': key |= (NSFunctionKeyMask >> 16); break;
+ case 'H': key |= (NSHelpKeyMask >> 16); break;
+ case 'L': key |= (NSAlphaShiftKeyMask >> 16); break;
+ case 'M': key |= (NSCommandKeyMask >> 16); break;
+ case 'N': key |= (NSNumericPadKeyMask >> 16); break;
+ case 'S': key |= (NSShiftKeyMask >> 16); break;
+ default: break;
+ }
+ //DLOG("key ->\n%s", dec2bin(key, 64));
+ } else if (c != '-') {
+ if (c == '<') {
+ // read named function key
+ NSUInteger x = i;
+ c = 0;
+ for (x; x<r.length; ++x) {
+ if (ucbuf[x] == '>') {
+ NSString *funcname =
+ [seq substringWithRange:NSMakeRange(i+1, x-(i+1))];
+ //DLOG("funcname -> '%@'", funcname);
+ NSNumber *n = [gFuncKeyNamesToUnicodePoints objectForKey:funcname];
+ if (n) {
+ c = [n shortValue];
+ //if (c == NSRightArrowFunctionKey)
+ // DLOG("c = NSRightArrowFunctionKey");
+ }
+ break;
+ }
+ }
+ if (c == 0)
+ return 0; // malformed input
+ i = x;
+ }
+ if (charoffs <= 48) {
+ /*DLOG("c << charoffs (%u << %d)", c, charoffs);
+ if (K_UC_ISFNKEY(c)) {
+ DLOG("c is a function key char");
+ }*/
+ key |= ((uint64_t)c) << charoffs;
+ charoffs += 16;
+ //DLOG("key ->\n%s", dec2bin(key, 64));
+ } // else there are too many chars which we just skip
}
}
+ //DLOG("return key ->\n%s", dec2bin(key, 64));
+ return key;
+}
- if (modifiers & NSAlternateKeyMask) seq += "A-";
- if (modifiers & NSControlKeyMask) seq += "C-";
- if (modifiers & NSFunctionKeyMask) seq += "F-";
- if (modifiers & NSHelpKeyMask) seq += "H-";
- if (modifiers & NSAlphaShiftKeyMask) seq += "L-";
- if (modifiers & NSCommandKeyMask) seq += "M-";
- if (modifiers & NSNumericPadKeyMask) seq += "N-";
- if (modifiers & NSShiftKeyMask) seq += "S-";
- if (charsLower) {
- seq += [charsLower UTF8String];
- } else if (functionKeyChar) {
- switch (functionKeyChar) {
- case NSUpArrowFunctionKey: seq += "<up>"; break;
- case NSDownArrowFunctionKey: seq += "<down>"; break;
- case NSLeftArrowFunctionKey: seq += "<left>"; break;
- case NSRightArrowFunctionKey: seq += "<right>"; break;
- case NSF1FunctionKey: seq += "<f1>"; break;
- case NSF2FunctionKey: seq += "<f2>"; break;
- case NSF3FunctionKey: seq += "<f3>"; break;
- case NSF4FunctionKey: seq += "<f4>"; break;
- case NSF5FunctionKey: seq += "<f5>"; break;
- case NSF6FunctionKey: seq += "<f6>"; break;
- case NSF7FunctionKey: seq += "<f7>"; break;
- case NSF8FunctionKey: seq += "<f8>"; break;
- case NSF9FunctionKey: seq += "<f9>"; break;
- case NSF10FunctionKey: seq += "<f10>"; break;
- case NSF11FunctionKey: seq += "<f11>"; break;
- case NSF12FunctionKey: seq += "<f12>"; break;
- case NSF13FunctionKey: seq += "<f13>"; break;
- case NSF14FunctionKey: seq += "<f14>"; break;
- case NSF15FunctionKey: seq += "<f15>"; break;
- case NSF16FunctionKey: seq += "<f16>"; break;
- case NSF17FunctionKey: seq += "<f17>"; break;
- case NSF18FunctionKey: seq += "<f18>"; break;
- case NSF19FunctionKey: seq += "<f19>"; break;
- case NSF20FunctionKey: seq += "<f20>"; break;
- case NSF21FunctionKey: seq += "<f21>"; break;
- case NSF22FunctionKey: seq += "<f22>"; break;
- case NSF23FunctionKey: seq += "<f23>"; break;
- case NSF24FunctionKey: seq += "<f24>"; break;
- case NSF25FunctionKey: seq += "<f25>"; break;
- case NSF26FunctionKey: seq += "<f26>"; break;
- case NSF27FunctionKey: seq += "<f27>"; break;
- case NSF28FunctionKey: seq += "<f28>"; break;
- case NSF29FunctionKey: seq += "<f29>"; break;
- case NSF30FunctionKey: seq += "<f30>"; break;
- case NSF31FunctionKey: seq += "<f31>"; break;
- case NSF32FunctionKey: seq += "<f32>"; break;
- case NSF33FunctionKey: seq += "<f33>"; break;
- case NSF34FunctionKey: seq += "<f34>"; break;
- case NSF35FunctionKey: seq += "<f35>"; break;
- case NSInsertFunctionKey: seq += "<insert>"; break;
- case NSDeleteFunctionKey: seq += "<del>"; break;
- case NSHomeFunctionKey: seq += "<home>"; break;
- case NSBeginFunctionKey: seq += "<begin>"; break;
- case NSEndFunctionKey: seq += "<end>"; break;
- case NSPageUpFunctionKey: seq += "<pageup>"; break;
- case NSPageDownFunctionKey: seq += "<pagedown>"; break;
- case NSPrintScreenFunctionKey: seq += "<printscreen>"; break;
- case NSScrollLockFunctionKey: seq += "<scrollock>"; break;
- case NSPauseFunctionKey: seq += "<pause>"; break;
- case NSSysReqFunctionKey: seq += "<sysreq>"; break;
- case NSBreakFunctionKey: seq += "<break>"; break;
- case NSResetFunctionKey: seq += "<reset>"; break;
- case NSStopFunctionKey: seq += "<stop>"; break;
- case NSMenuFunctionKey: seq += "<menu>"; break;
- case NSUserFunctionKey: seq += "<user>"; break;
- case NSSystemFunctionKey: seq += "<system>"; break;
- case NSPrintFunctionKey: seq += "<print>"; break;
- case NSClearLineFunctionKey: seq += "<clearline>"; break;
- case NSClearDisplayFunctionKey: seq += "<cleardisplay>"; break;
- case NSInsertLineFunctionKey: seq += "<insertline>"; break;
- case NSDeleteLineFunctionKey: seq += "<deleteline>"; break;
- case NSInsertCharFunctionKey: seq += "<insertchar>"; break;
- case NSDeleteCharFunctionKey: seq += "<deletechar>"; break;
- case NSPrevFunctionKey: seq += "<prev>"; break;
- case NSNextFunctionKey: seq += "<next>"; break;
- case NSSelectFunctionKey: seq += "<select>"; break;
- case NSExecuteFunctionKey: seq += "<execute>"; break;
- case NSUndoFunctionKey: seq += "<undo>"; break;
- case NSRedoFunctionKey: seq += "<redo>"; break;
- case NSFindFunctionKey: seq += "<find>"; break;
- case NSHelpFunctionKey: seq += "<help>"; break;
- case NSModeSwitchFunctionKey: seq += "<modeswitch>"; break;
- default: break;
- }
+BOOL KInputBindings::set(Level level, NSString *seqs, KInputAction *action) {
+ for (NSString *seq in [seqs componentsSeparatedByString:@" "]) {
+ uint64_t key = parseSequence(seq);
+ // TODO: support more than one sequence
+ if (key) {
+ set(level, key, action);
+ return YES;
+ } else break;
}
+ return NO;
+}
- DLOG("seq: '%s'", seq.c_str());
- return get(seq);
+KInputAction *KInputBindings::get(Level level, NSString *seqs) {
+ for (NSString *seq in [seqs componentsSeparatedByString:@" "]) {
+ uint64_t key = parseSequence(seq);
+ // TODO: support more than one sequence
+ if (key) {
+ return get(level, key);
+ } else break;
+ }
+ return nil;
+}
+
+
+size_t KInputBindings::remove(uint64_t key) {
+ size_t count = 0;
+ for (int level=MaxLevel; --level >= 0; )
+ count += bindings_[level].eraseSync(key);
+ return count;
+}
+
+
+void KInputBindings::clear(Level level) {
+ if (level < MaxLevel) {
+ bindings_[level].clearSync();
+ } else {
+ for (int level=MaxLevel; --level >= 0; )
+ bindings_[level].clearSync();
+ }
}
View
12 src/KTextView.mm
@@ -365,15 +365,15 @@ - (void)mouseMoved:(NSEvent*)event {
// return nil for "I handled this"
- (NSEvent*)filterInputEvent:(NSEvent*)event {
- DLOG("input event: %@", event);
- static BOOL debugDidSet = NO;
- if (!debugDidSet) {
- debugDidSet = YES;
- KInputBindings::set("A-r",
+ // XXX bind alt+rightwardsarrow to "indent"
+ static BOOL debugDidSet = NO; if (!debugDidSet) { debugDidSet = YES;
+ KInputBindings::set(KInputBindings::TextEditorLevel, @"A-<right>",
new KSelectorInputAction(@selector(increaseIndentation)));
}
- KInputAction *action = KInputBindings::get(event);
+ KInputAction *action =
+ KInputBindings::get(KInputBindings::TextEditorLevel, event);
+ DLOG("input event: %@ -- %@", [event kodInputBindingDescription], event);
DLOG("input action -> %p", action);
if (action && action->perform(self))
return nil;
View
13 src/NSEvent-kod.h
@@ -0,0 +1,13 @@
+// Copyright (c) 2010-2011, Rasmus Andersson. All rights reserved.
+// Use of this source code is governed by a MIT-style license that can be
+// found in the LICENSE file.
+
+@interface NSEvent (kod)
+// returns a 64-bit integer which uniquely represents this event in a
+// device-independent fashion
+- (uint64_t)kodHash;
+
+// returns a string representation of the equivalent kod input binding sequence
+// e.g. an event triggered by Cmd+R would return "M-S-r" (meta-shift-r)
+- (NSString*)kodInputBindingDescription;
+@end
View
170 src/NSEvent-kod.m
@@ -0,0 +1,170 @@
+// Copyright (c) 2010-2011, Rasmus Andersson. All rights reserved.
+// Use of this source code is governed by a MIT-style license that can be
+// found in the LICENSE file.
+
+#import "NSEvent-kod.h"
+
+#define K_UC_ISFNKEY(c) ((c) >= 0xF700 && (c) <= 0xF8FF)
+
+@implementation NSEvent (kod)
+
+- (uint64_t)kodHash {
+ // first 16 bits are the device-independent modifier flags (ctrl, alt, etc)
+ uint64_t key = [self modifierFlags] & NSDeviceIndependentModifierFlagsMask;
+ // we don't care about the NSFunctionKeyMask as it's implied by function chars
+ key &= ~NSFunctionKeyMask;
+ //DLOG("key0 %llx\n%s", key, dec2bin(key, 64));
+
+ // the following 16-48 bits constitute the char code (1-3 unichars)
+ NSString *chars = [self charactersIgnoringModifiers];
+ NSUInteger L = chars.length;
+ if (L > 0) {
+ unichar c = [chars characterAtIndex:0];
+ // special case for function chars to turn
+ // "ALT + rightwards arrow" == "A-N-<right>"
+ // into
+ // "ALT + rightwards arrow" == "A-<right>"
+ // as "A-<right>" sans N is "A-<end>"
+ if (c >= NSUpArrowFunctionKey && c <= NSRightArrowFunctionKey) {
+ key &= ~NSNumericPadKeyMask;
+ }
+ key = key >> 16;
+ key |= ((uint64_t)c) << 16;
+ //DLOG("key1 %llx\n%s", key, dec2bin(key, 64));
+ if (L > 1) {
+ key |= ((uint64_t)[chars characterAtIndex:1]) << 24;
+ //DLOG("key2 %llx\n%s", key, dec2bin(key, 64));
+ if (L > 2) {
+ key |= ((uint64_t)[chars characterAtIndex:2]) << 48;
+ //DLOG("key3 %llx\n%s", key, dec2bin(key, 64));
+ }
+ }
+ } else {
+ key = key >> 16;
+ }
+ //DLOG("return key:\n%s", dec2bin(key, 64));
+ return key;
+}
+
+
+- (NSString*)kodInputBindingDescription {
+ // we only handle key events (for now)
+ NSEventType t = [self type];
+ if (t != NSKeyDown && t != NSKeyUp) return nil;
+
+ NSMutableString *seq = [NSMutableString stringWithCapacity:4];
+ NSUInteger modifiers = [self modifierFlags];
+ NSString *chars = [self charactersIgnoringModifiers];
+ NSString *charsLower = nil;
+ unichar functionKeyChar = 0;
+ // TODO: support more than one key
+
+ if (chars.length != 0) {
+ unichar c = [chars characterAtIndex:0];
+ if (K_UC_ISFNKEY(c)) {
+ functionKeyChar = c;
+ modifiers &= ~NSFunctionKeyMask;
+ if (c >= NSUpArrowFunctionKey && c <= NSRightArrowFunctionKey)
+ modifiers &= ~NSNumericPadKeyMask;
+ } else {
+ chars = [chars substringToIndex:1];
+ charsLower = [chars lowercaseString];
+ if (![chars isEqualToString:charsLower])
+ modifiers |= NSShiftKeyMask;
+ }
+ }
+
+ if (modifiers & NSAlternateKeyMask) [seq appendString:@"A-"];
+ if (modifiers & NSControlKeyMask) [seq appendString:@"C-"];
+ if (modifiers & NSFunctionKeyMask) [seq appendString:@"F-"];
+ if (modifiers & NSHelpKeyMask) [seq appendString:@"H-"];
+ if (modifiers & NSAlphaShiftKeyMask) [seq appendString:@"L-"];
+ if (modifiers & NSCommandKeyMask) [seq appendString:@"M-"];
+ if (modifiers & NSNumericPadKeyMask) [seq appendString:@"N-"];
+ if (modifiers & NSShiftKeyMask) [seq appendString:@"S-"];
+
+ if (charsLower) {
+ [seq appendString:charsLower];
+ } else if (functionKeyChar) {
+ switch (functionKeyChar) {
+ case NSUpArrowFunctionKey: [seq appendString:@"<up>"]; break;
+ case NSDownArrowFunctionKey: [seq appendString:@"<down>"]; break;
+ case NSLeftArrowFunctionKey: [seq appendString:@"<left>"]; break;
+ case NSRightArrowFunctionKey: [seq appendString:@"<right>"]; break;
+ case NSF1FunctionKey: [seq appendString:@"<f1>"]; break;
+ case NSF2FunctionKey: [seq appendString:@"<f2>"]; break;
+ case NSF3FunctionKey: [seq appendString:@"<f3>"]; break;
+ case NSF4FunctionKey: [seq appendString:@"<f4>"]; break;
+ case NSF5FunctionKey: [seq appendString:@"<f5>"]; break;
+ case NSF6FunctionKey: [seq appendString:@"<f6>"]; break;
+ case NSF7FunctionKey: [seq appendString:@"<f7>"]; break;
+ case NSF8FunctionKey: [seq appendString:@"<f8>"]; break;
+ case NSF9FunctionKey: [seq appendString:@"<f9>"]; break;
+ case NSF10FunctionKey: [seq appendString:@"<f10>"]; break;
+ case NSF11FunctionKey: [seq appendString:@"<f11>"]; break;
+ case NSF12FunctionKey: [seq appendString:@"<f12>"]; break;
+ case NSF13FunctionKey: [seq appendString:@"<f13>"]; break;
+ case NSF14FunctionKey: [seq appendString:@"<f14>"]; break;
+ case NSF15FunctionKey: [seq appendString:@"<f15>"]; break;
+ case NSF16FunctionKey: [seq appendString:@"<f16>"]; break;
+ case NSF17FunctionKey: [seq appendString:@"<f17>"]; break;
+ case NSF18FunctionKey: [seq appendString:@"<f18>"]; break;
+ case NSF19FunctionKey: [seq appendString:@"<f19>"]; break;
+ case NSF20FunctionKey: [seq appendString:@"<f20>"]; break;
+ case NSF21FunctionKey: [seq appendString:@"<f21>"]; break;
+ case NSF22FunctionKey: [seq appendString:@"<f22>"]; break;
+ case NSF23FunctionKey: [seq appendString:@"<f23>"]; break;
+ case NSF24FunctionKey: [seq appendString:@"<f24>"]; break;
+ case NSF25FunctionKey: [seq appendString:@"<f25>"]; break;
+ case NSF26FunctionKey: [seq appendString:@"<f26>"]; break;
+ case NSF27FunctionKey: [seq appendString:@"<f27>"]; break;
+ case NSF28FunctionKey: [seq appendString:@"<f28>"]; break;
+ case NSF29FunctionKey: [seq appendString:@"<f29>"]; break;
+ case NSF30FunctionKey: [seq appendString:@"<f30>"]; break;
+ case NSF31FunctionKey: [seq appendString:@"<f31>"]; break;
+ case NSF32FunctionKey: [seq appendString:@"<f32>"]; break;
+ case NSF33FunctionKey: [seq appendString:@"<f33>"]; break;
+ case NSF34FunctionKey: [seq appendString:@"<f34>"]; break;
+ case NSF35FunctionKey: [seq appendString:@"<f35>"]; break;
+ case NSInsertFunctionKey: [seq appendString:@"<insert>"]; break;
+ case NSDeleteFunctionKey: [seq appendString:@"<del>"]; break;
+ case NSHomeFunctionKey: [seq appendString:@"<home>"]; break;
+ case NSBeginFunctionKey: [seq appendString:@"<begin>"]; break;
+ case NSEndFunctionKey: [seq appendString:@"<end>"]; break;
+ case NSPageUpFunctionKey: [seq appendString:@"<pageup>"]; break;
+ case NSPageDownFunctionKey: [seq appendString:@"<pagedown>"]; break;
+ case NSPrintScreenFunctionKey: [seq appendString:@"<printscreen>"]; break;
+ case NSScrollLockFunctionKey: [seq appendString:@"<scrollock>"]; break;
+ case NSPauseFunctionKey: [seq appendString:@"<pause>"]; break;
+ case NSSysReqFunctionKey: [seq appendString:@"<sysreq>"]; break;
+ case NSBreakFunctionKey: [seq appendString:@"<break>"]; break;
+ case NSResetFunctionKey: [seq appendString:@"<reset>"]; break;
+ case NSStopFunctionKey: [seq appendString:@"<stop>"]; break;
+ case NSMenuFunctionKey: [seq appendString:@"<menu>"]; break;
+ case NSUserFunctionKey: [seq appendString:@"<user>"]; break;
+ case NSSystemFunctionKey: [seq appendString:@"<system>"]; break;
+ case NSPrintFunctionKey: [seq appendString:@"<print>"]; break;
+ case NSClearLineFunctionKey: [seq appendString:@"<clearline>"]; break;
+ case NSClearDisplayFunctionKey: [seq appendString:@"<cleardisplay>"]; break;
+ case NSInsertLineFunctionKey: [seq appendString:@"<insertline>"]; break;
+ case NSDeleteLineFunctionKey: [seq appendString:@"<deleteline>"]; break;
+ case NSInsertCharFunctionKey: [seq appendString:@"<insertchar>"]; break;
+ case NSDeleteCharFunctionKey: [seq appendString:@"<deletechar>"]; break;
+ case NSPrevFunctionKey: [seq appendString:@"<prev>"]; break;
+ case NSNextFunctionKey: [seq appendString:@"<next>"]; break;
+ case NSSelectFunctionKey: [seq appendString:@"<select>"]; break;
+ case NSExecuteFunctionKey: [seq appendString:@"<execute>"]; break;
+ case NSUndoFunctionKey: [seq appendString:@"<undo>"]; break;
+ case NSRedoFunctionKey: [seq appendString:@"<redo>"]; break;
+ case NSFindFunctionKey: [seq appendString:@"<find>"]; break;
+ case NSHelpFunctionKey: [seq appendString:@"<help>"]; break;
+ case NSModeSwitchFunctionKey: [seq appendString:@"<modeswitch>"]; break;
+ default: break;
+ }
+ }
+
+ return seq;
+}
+
+
+@end
View
14 src/common.h
@@ -163,20 +163,6 @@ static inline void *k_swapptr(void * volatile *dst, void *src) {
return old;
}
-// format a string showing which bits are set
-#if NDEBUG
-#define debug_bits32(a) NULL
-#else
-static inline const char *debug_bits32(int32_t a) {
- int i;
- static char buf[33] = {0};
- for (i = 31 ; i >= 0 ; --i) {
- buf[31-i] = ((a & (1 << i)) == 0) ? '.' : '1';
- }
- return buf;
-}
-#endif
-
#import "hatomic_flags.h"
#import "hdispatch.h"
#import "hcommon.h"
View
33 src/dec2bin.c
@@ -0,0 +1,33 @@
+// Copyright (c) 2010-2011, Rasmus Andersson. All rights reserved.
+// Use of this source code is governed by a MIT-style license that can be
+// found in the LICENSE file.
+
+#include "dec2bin.h"
+
+const char *dec2bin(long decimal, int nbits) {
+ int k = 0, n = 0;
+ int neg_flag = 0;
+ int remain;
+ char temp[80];
+ static char binary[80] = {0};
+
+ if (decimal < 0) {
+ decimal = -decimal;
+ neg_flag = 1;
+ }
+
+ do {
+ remain = decimal % 2;
+ decimal = decimal / 2;
+ temp[k++] = remain ? '1' : '.';
+ } while (decimal > 0);
+
+ binary[n++] = neg_flag ? '-' : ' ';
+ while (n <= nbits-k)
+ binary[n++] = '.';
+ while (k >= 0)
+ binary[n++] = temp[--k];
+ binary[n-1] = 0;
+
+ return binary;
+}
View
16 src/dec2bin.h
@@ -0,0 +1,16 @@
+// Copyright (c) 2010-2011, Rasmus Andersson. All rights reserved.
+// Use of this source code is governed by a MIT-style license that can be
+// found in the LICENSE file.
+
+#ifndef KOD_DEC2BIN_H_
+#define KOD_DEC2BIN_H_
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+const char *dec2bin(long decimal, int nbits);
+
+#ifdef __cplusplus
+} // extern "C"
+#endif
+#endif // KOD_DEC2BIN_H_
Please sign in to comment.
Something went wrong with that request. Please try again.