Created
June 2, 2012 13:22
-
-
Save saitoha/2858391 to your computer and use it in GitHub Desktop.
SGR-styled mouse reporting. (for MouseTerm, https://bitheap.org/mouseterm/).
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
diff --git a/Japanese.lproj/Localizable.strings b/Japanese.lproj/Localizable.strings | |
new file mode 100644 | |
index 0000000..02a8de8 | |
--- /dev/null | |
+++ b/Japanese.lproj/Localizable.strings | |
@@ -0,0 +1,2 @@ | |
+/* Send Mouse Events menu item */ | |
+"Send Mouse Events" = "マウスイベントを送る"; | |
diff --git a/MTParser.rl b/MTParser.rl | |
index e554262..7c80c85 100644 | |
--- a/MTParser.rl | |
+++ b/MTParser.rl | |
@@ -32,7 +32,7 @@ | |
state.handleSda = YES; | |
} | |
- action handle_mouse | |
+ action handle_mouse_mode | |
{ | |
int mouseMode = state.pendingMouseMode; | |
MouseMode newMouseMode = NO_MODE; | |
@@ -59,6 +59,22 @@ | |
[mobj MouseTerm_setMouseMode: NO_MODE]; | |
} | |
+ action handle_urxvt_protocol | |
+ { | |
+ if (state.toggleState) | |
+ [mobj MouseTerm_setMouseProtocol: URXVT_PROTOCOL]; | |
+ else | |
+ [mobj MouseTerm_setMouseProtocol: NORMAL_PROTOCOL]; | |
+ } | |
+ | |
+ action handle_sgr_protocol | |
+ { | |
+ if (state.toggleState) | |
+ [mobj MouseTerm_setMouseProtocol: SGR_PROTOCOL]; | |
+ else | |
+ [mobj MouseTerm_setMouseProtocol: NORMAL_PROTOCOL]; | |
+ } | |
+ | |
esc = 0x1b; | |
csi = esc . "["; | |
flag = ("h" | "l") @handle_flag; | |
@@ -68,7 +84,9 @@ | |
debug = (csi . "li"); | |
cs_sda = csi . ">" . [01]? . "c"; | |
mode_toggle = csi . "?" . (appkeys . flag @handle_flag @handle_appkeys | |
- | mouse . flag @handle_flag @handle_mouse); | |
+ | mouse . flag @handle_flag @handle_mouse_mode | |
+ | "1015" . flag @handle_flag @handle_urxvt_protocol | |
+ | "1006" . flag @handle_flag @handle_sgr_protocol); | |
bel = 0x07; | |
st = 0x9c; | |
diff --git a/MTShell.h b/MTShell.h | |
index eea06f6..22ce5c8 100644 | |
--- a/MTShell.h | |
+++ b/MTShell.h | |
@@ -10,6 +10,9 @@ | |
- (void) MouseTerm_setMouseMode: (int) mouseMode; | |
- (int) MouseTerm_getMouseMode; | |
+- (void) MouseTerm_setMouseProtocol: (int) mouseProtocol; | |
+- (int) MouseTerm_getMouseProtocol; | |
+ | |
- (void) MouseTerm_setAppCursorMode: (BOOL) appCursorMode; | |
- (BOOL) MouseTerm_getAppCursorMode; | |
diff --git a/MTShell.m b/MTShell.m | |
index a191a90..411c3d6 100644 | |
--- a/MTShell.m | |
+++ b/MTShell.m | |
@@ -15,6 +15,8 @@ | |
[MouseTerm_ivars setObject: dict forKey: ptr]; | |
[dict setObject: [NSNumber numberWithInt: NO_MODE] | |
forKey: @"mouseMode"]; | |
+ [dict setObject: [NSNumber numberWithInt: NORMAL_PROTOCOL] | |
+ forKey: @"mouseProtocol"]; | |
[dict setObject: [NSNumber numberWithBool: NO] | |
forKey: @"appCursorMode"]; | |
[dict setObject: [NSNumber numberWithBool: NO] | |
@@ -39,6 +41,21 @@ | |
objectForKey: @"mouseMode"] intValue]; | |
} | |
+- (void) MouseTerm_setMouseProtocol: (int) mouseProtocol | |
+{ | |
+ NSValue *ptr = [self MouseTerm_initVars]; | |
+ [[MouseTerm_ivars objectForKey: ptr] | |
+ setObject: [NSNumber numberWithInt:mouseProtocol] | |
+ forKey: @"mouseProtocol"]; | |
+} | |
+ | |
+- (int) MouseTerm_getMouseProtocol | |
+{ | |
+ NSValue *ptr = [self MouseTerm_initVars]; | |
+ return [(NSNumber*) [[MouseTerm_ivars objectForKey: ptr] | |
+ objectForKey: @"mouseProtocol"] intValue]; | |
+} | |
+ | |
- (void) MouseTerm_setAppCursorMode: (BOOL) appCursorMode | |
{ | |
NSValue *ptr = [self MouseTerm_initVars]; | |
diff --git a/MTView.h b/MTView.h | |
index 757e260..490a8d6 100644 | |
--- a/MTView.h | |
+++ b/MTView.h | |
@@ -5,7 +5,8 @@ | |
@interface NSView (MTView) | |
- (NSData*) MouseTerm_codeForEvent: (NSEvent*) event | |
button: (MouseButton) button | |
- motion: (BOOL) motion; | |
+ motion: (BOOL) motion | |
+ release: (BOOL) release; | |
+ (void) MouseTerm_setEnabled: (BOOL) value; | |
+ (BOOL) MouseTerm_getEnabled; | |
- (NSScroller*) MouseTerm_scroller; | |
diff --git a/MTView.m b/MTView.m | |
index 211a46f..d7ebfc2 100644 | |
--- a/MTView.m | |
+++ b/MTView.m | |
@@ -13,11 +13,12 @@ static BOOL enabled = YES; | |
- (NSData*) MouseTerm_codeForEvent: (NSEvent*) event | |
button: (MouseButton) button | |
motion: (BOOL) motion | |
+ release: (BOOL) release | |
{ | |
Position pos = [self MouseTerm_currentPosition: event]; | |
unsigned int x = pos.x; | |
unsigned int y = pos.y; | |
- char cb = button + 32; | |
+ char cb = button; | |
char modflag = [event modifierFlags]; | |
if (modflag & NSShiftKeyMask) cb |= 4; | |
@@ -25,12 +26,41 @@ static BOOL enabled = YES; | |
if (modflag & NSControlKeyMask) cb |= 16; | |
if (motion) cb += 32; | |
- x = MIN(x + 33, 255); | |
- y = MIN(y + 33, 255); | |
- | |
- char buf[MOUSE_RESPONSE_LEN + 1]; | |
- snprintf(buf, sizeof(buf), MOUSE_RESPONSE, cb, x, y); | |
- return [NSData dataWithBytes: buf length: MOUSE_RESPONSE_LEN]; | |
+ MTShell* shell = [[(TTView*) self controller] shell]; | |
+ MouseProtocol mouseProtocol = [shell MouseTerm_getMouseProtocol]; | |
+ unsigned int len; | |
+ const size_t BUFFER_LENGTH = 256; | |
+ char buf[BUFFER_LENGTH]; | |
+ | |
+ switch (mouseProtocol) { | |
+ | |
+ case URXVT_PROTOCOL: | |
+ if (release) | |
+ cb |= MOUSE_RELEASE; | |
+ snprintf(buf, BUFFER_LENGTH, "\e[%d;%d;%dM", cb + 32, x, y); | |
+ len = strlen(buf); | |
+ break; | |
+ | |
+ case SGR_PROTOCOL: | |
+ if (release) // release | |
+ snprintf(buf, BUFFER_LENGTH, "\e[<%d;%d;%dm", cb, x, y); | |
+ else | |
+ snprintf(buf, BUFFER_LENGTH, "\e[<%d;%d;%dM", cb, x, y); | |
+ len = strlen(buf); | |
+ break; | |
+ | |
+ case NORMAL_PROTOCOL: | |
+ default: | |
+ if (release) | |
+ cb |= MOUSE_RELEASE; | |
+ x = MIN(x + 33, 255); | |
+ y = MIN(y + 33, 255); | |
+ len = MOUSE_RESPONSE_LEN; | |
+ | |
+ snprintf(buf, len + 1, MOUSE_RESPONSE, cb + 32, x, y); | |
+ break; | |
+ } | |
+ return [NSData dataWithBytes: buf length: len]; | |
} | |
+ (void) MouseTerm_setEnabled: (BOOL) value | |
@@ -101,6 +131,10 @@ static BOOL enabled = YES; | |
// The above method returns the position *including* scrollback, | |
// so we have to compensate for that. | |
pos.y -= scrollback; | |
+ // pos.x may not indicate correct coordinate value if the tail | |
+ // cells of line buffer are empty, so we calculate it from the cell size. | |
+ CGSize size = [(TTView*) self cellSize]; | |
+ pos.x = floor(viewloc.x / size.width); | |
return pos; | |
} | |
@@ -122,7 +156,8 @@ static BOOL enabled = YES; | |
[shell MouseTerm_setIsMouseDown: YES]; | |
NSData* data = [self MouseTerm_codeForEvent: event | |
button: button | |
- motion: NO]; | |
+ motion: NO | |
+ release: NO]; | |
[(TTShell*) shell writeData: data]; | |
goto handled; | |
@@ -153,8 +188,9 @@ ignored: | |
case ALL_MODE: | |
{ | |
NSData* data = [self MouseTerm_codeForEvent: event | |
- button: MOUSE_RELEASE | |
- motion: YES]; | |
+ button: button | |
+ motion: YES | |
+ release: NO]; | |
[(TTShell*) shell writeData: data]; | |
goto handled; | |
} | |
@@ -183,8 +219,9 @@ ignored: | |
{ | |
[shell MouseTerm_setIsMouseDown: NO]; | |
NSData* data = [self MouseTerm_codeForEvent: event | |
- button: MOUSE_RELEASE | |
- motion: NO]; | |
+ button: button | |
+ motion: NO | |
+ release: YES]; | |
[(TTShell*) shell writeData: data]; | |
goto handled; | |
@@ -345,7 +382,8 @@ ignored: | |
NSData* data = [self MouseTerm_codeForEvent: event | |
button: button | |
- motion: NO]; | |
+ motion: NO | |
+ release: NO]; | |
long i; | |
long lines = lround(delta) + 1; | |
diff --git a/Makefile b/Makefile | |
index 0cf09f5..ab7945b 100644 | |
--- a/Makefile | |
+++ b/Makefile | |
@@ -40,6 +40,16 @@ $(TARGET): $(OBJS) | |
--output-format human-readable-text --compile \ | |
$(BUNDLE)/Contents/Resources/English.lproj/Configuration.nib \ | |
English.lproj/Configuration.xib | |
+ rm -f $(BUNDLE)/Contents/Resources/Japanese.lproj/*.xib | |
+ ibtool --errors --warnings --notices \ | |
+ --output-format human-readable-text --compile \ | |
+ $(BUNDLE)/Contents/Resources/Japanese.lproj/Configuration.nib \ | |
+ English.lproj/Configuration.xib | |
+ rm -f $(BUNDLE)/Contents/Resources/French.lproj/*.xib | |
+ ibtool --errors --warnings --notices \ | |
+ --output-format human-readable-text --compile \ | |
+ $(BUNDLE)/Contents/Resources/French.lproj/Configuration.nib \ | |
+ English.lproj/Configuration.xib | |
all: $(TARGET) | |
dist: $(TARGET) | |
diff --git a/Mouse.h b/Mouse.h | |
index 81f1978..2d6ff11 100644 | |
--- a/Mouse.h | |
+++ b/Mouse.h | |
@@ -8,6 +8,13 @@ typedef enum | |
ALL_MODE | |
} MouseMode; | |
+typedef enum | |
+{ | |
+ NORMAL_PROTOCOL = 0, | |
+ URXVT_PROTOCOL, | |
+ SGR_PROTOCOL | |
+} MouseProtocol; | |
+ | |
// Control codes | |
#define PDA_RESPONSE "\033[?1;2c" | |
diff --git a/Terminal.h b/Terminal.h | |
index c967c0b..d509e53 100644 | |
--- a/Terminal.h | |
+++ b/Terminal.h | |
@@ -45,6 +45,7 @@ typedef struct | |
- (MTTabController*) controller; | |
- (Position) displayPositionForPoint: (NSPoint) point; | |
- (void) clearTextSelection; | |
+- (struct CGSize)cellSize; | |
@end | |
@interface TTProfileArrayController: |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment