Skip to content

Instantly share code, notes, and snippets.

@saitoha
Created June 2, 2012 13:22
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save saitoha/2858391 to your computer and use it in GitHub Desktop.
Save saitoha/2858391 to your computer and use it in GitHub Desktop.
SGR-styled mouse reporting. (for MouseTerm, https://bitheap.org/mouseterm/).
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