diff options
author | 2014-10-25 00:30:36 -0400 | |
---|---|---|
committer | 2014-10-25 00:30:36 -0400 | |
commit | 83c20c89439386f31050718c94551d863298cdb9 (patch) | |
tree | 536dd52392df00ded7bbc5f650ea0eb0d397d52d /src | |
parent | 1de8c1bb596a7dbff39ab55685ead31a5d0c9373 (diff) | |
download | textadept-83c20c89439386f31050718c94551d863298cdb9.tar.gz textadept-83c20c89439386f31050718c94551d863298cdb9.zip |
Improvements to terminal mouse handling.
Emit events for unhandled mouse events and connect to such events in order to
focus and resize views.
Patch libtermkey with new Win32 PDCurses driver for unified key/mouse input.
Update CDK patch to always use libtermkey and to ignore mouse events.
Requires Scinterm r97 (changeset 8d1a625c9b4d).
Thanks to Chris Emerson for proof of concept code that handles mouse events and
for the code that focuses and resizes views.
Diffstat (limited to 'src')
-rw-r--r-- | src/Makefile | 27 | ||||
-rw-r--r-- | src/cdk.patch | 17 | ||||
-rw-r--r-- | src/termkey.patch | 339 | ||||
-rw-r--r-- | src/textadept.c | 99 |
4 files changed, 392 insertions, 90 deletions
diff --git a/src/Makefile b/src/Makefile index 8a17c517..9e7cf185 100644 --- a/src/Makefile +++ b/src/Makefile @@ -137,7 +137,9 @@ luajit_lib_objs = lpcapjit.o lpcodejit.o lpprintjit.o lptreejit.o lpvmjit.o \ lfsjit.o lua_spawn_objs = lspawn.o lspawnjit.o lspawn-curses.o lspawnjit-curses.o gtdialog_objs = gtdialog.o gtdialog-curses.o -termkey_objs = termkey.o driver-ti.o driver-csi.o +termkey_unix_objs = driver-ti.o driver-csi.o +termkey_win32_objs = driver-win32-pdcurses.o +termkey_objs = termkey.o $(termkey_unix_objs) $(termkey_win32_objs) windowman_objs = windowman.o cdk_objs = binding.o buttonbox.o button.o cdk.o cdk_display.o cdk_objs.o \ cdk_params.o cdkscreen.o debug.o draw.o entry.o fselect.o \ @@ -188,7 +190,8 @@ $(windowman_objs): %.o: windowman/%.c $(cdk_objs): %.o: cdk/%.c $(CROSS)$(CC) -c $(CFLAGS) -D_GNU_SOURCE -Itermkey -Icdk $(CURSES_CFLAGS) $< \ -o $@ -$(termkey_objs): %.o: termkey/%.c ; $(CROSS)$(CC) -c $(CFLAGS) -std=c99 $< -o $@ +$(termkey_objs): %.o: termkey/%.c + $(CROSS)$(CC) -c $(CFLAGS) -std=c99 $(termkey_flags) $< -o $@ textadept_rc.o: textadept.rc ; $(CROSS)$(WINDRES) $< $@ # Target-specific variables. @@ -209,6 +212,7 @@ lspawn.o lspawnjit.o: spawn_flags = -DGTK $(GLIB_CFLAGS) $(gtdialog_objs): gtdialog_flags = $(plat_flag) -DNOHELP -DLIBRARY gtdialog.o: gtdialog_flags += $(GTK_CFLAGS) gtdialog-curses.o: gtdialog_flags += -Icdk $(CURSES_CFLAGS) +$(termkey_win32_objs): termkey_flags += $(CURSES_CFLAGS) # Executables. @@ -221,14 +225,14 @@ textadeptjit: $(sci_objs) $(sci_lex_objs) $(sci_gtk_objs) scintilla-marshal.o \ $(CROSS)$(CXX) $(CXXFLAGS) -o ../$@ $^ $(GTK_LIBS) $(LDFLAGS) textadept-curses: $(sci_objs) $(sci_lex_objs) ScintillaTerm.o LexLPeg-curses.o \ textadept-curses.o $(lua_objs) $(lua_lib_objs) \ - lspawn-curses.o gtdialog-curses.o $(termkey_objs) \ - $(windowman_objs) $(cdk_objs) + lspawn-curses.o gtdialog-curses.o termkey.o \ + $(termkey_unix_objs) $(windowman_objs) $(cdk_objs) $(CROSS)$(CXX) $(CXXFLAGS) -o ../$@ $^ $(CURSES_LIBS) $(LDFLAGS) textadeptjit-curses: $(sci_objs) $(sci_lex_objs) ScintillaTerm.o \ LexLPegjit-curses.o textadeptjit-curses.o \ $(luajit_lib_objs) $(libluajit) lspawnjit-curses.o \ - gtdialog-curses.o $(termkey_objs) $(windowman_objs) \ - $(cdk_objs) + gtdialog-curses.o termkey.o $(termkey_unix_objs) \ + $(windowman_objs) $(cdk_objs) $(CROSS)$(CXX) $(CXXFLAGS) -o ../$@ $^ $(CURSES_LIBS) $(LDFLAGS) textadept.exe: $(sci_objs) $(sci_lex_objs) $(sci_gtk_objs) scintilla-marshal.o \ LexLPeg.o textadept.o textadept_rc.o $(lua_objs) \ @@ -242,13 +246,14 @@ textadeptjit.exe: $(sci_objs) $(sci_lex_objs) $(sci_gtk_objs) \ textadept-curses.exe: $(sci_objs) $(sci_lex_objs) ScintillaTerm.o \ LexLPeg-curses.o textadept-curses.o textadept_rc.o \ $(lua_objs) $(lua_lib_objs) lspawn-curses.o \ - gtdialog-curses.o $(windowman_objs) $(cdk_objs) + gtdialog-curses.o termkey.o $(termkey_win32_objs) \ + $(windowman_objs) $(cdk_objs) $(CROSS)$(CXX) $(CXXFLAGS) -o ../$@ $^ $(CURSES_LIBS) $(LDFLAGS) textadeptjit-curses.exe: $(sci_objs) $(sci_lex_objs) ScintillaTerm.o \ LexLPegjit-curses.o textadeptjit-curses.o \ textadept_rc.o $(luajit_lib_objs) $(libluajit) \ - lspawnjit-curses.o gtdialog-curses.o \ - $(windowman_objs) $(cdk_objs) + lspawnjit-curses.o gtdialog-curses.o termkey.o \ + $(termkey_win32_objs) $(windowman_objs) $(cdk_objs) $(CROSS)$(CXX) $(CXXFLAGS) -o ../$@ $^ $(CURSES_LIBS) $(LDFLAGS) # Install/uninstall. @@ -443,7 +448,9 @@ cdk: cdk.patch | $(cdk_tgz) mv $@/include/*.h $@ patch -d $@ -N -p1 < $< $(termkey_tgz): ; wget http://www.leonerd.org.uk/code/libtermkey/$@ -termkey: | $(termkey_tgz) ; mkdir $@ && tar xzf $| -C $@ && mv $@/*/* $@ +termkey: termkey.patch | $(termkey_tgz) + mkdir $@ && tar xzf $| -C $@ && mv $@/*/* $@ + patch -d $@ -N -p1 < $< $(win32gtk_zip): wget http://ftp.gnome.org/pub/gnome/binaries/win32/gtk+/2.24/$@ $(win32iconv_bin_zip): ; wget http://gnuwin32.sourceforge.net/downlinks/$@ diff --git a/src/cdk.patch b/src/cdk.patch index b9fc42b9..20ab9227 100644 --- a/src/cdk.patch +++ b/src/cdk.patch @@ -1,24 +1,24 @@ diff -r 9d0780ddcbab binding.c --- a/binding.c 2011-05-16 18:36:08.000000000 -0400 +++ b/binding.c 2013-12-18 11:51:43.781198100 -0500 -@@ -1,4 +1,8 @@ +@@ -1,4 +1,6 @@ #include <cdk_int.h> -+#if !_WIN32 +#include "termkey.h" +extern TermKey *ta_tk; -+#endif /* * $Author: tom $ -@@ -167,7 +171,47 @@ +@@ -167,7 +169,47 @@ { EObjectType cdktype = ObjTypeOf (obj); CDKOBJS *test = bindableObject (&cdktype, obj); -+#if !_WIN32 +- int result = wgetch (InputWindowOf (obj)); + int result = ERR; + TermKeyKey key; + int keysyms[] = {0,KEY_BACKSPACE,KEY_TAB,KEY_ENTER,KEY_ESC,0,0,KEY_UP,KEY_DOWN,KEY_LEFT,KEY_RIGHT,0,0,KEY_IC,KEY_DC,0,KEY_PPAGE,KEY_NPAGE,KEY_HOME,KEY_END}; -+ TermKeyResult res = termkey_waitkey(ta_tk, &key); ++ TermKeyResult res; ++retry: ++ res = termkey_waitkey(ta_tk, &key); + switch (res) + { + case TERMKEY_RES_KEY: @@ -39,6 +39,8 @@ diff -r 9d0780ddcbab binding.c + case TERMKEY_TYPE_KEYSYM: + result = keysyms[key.code.sym]; + break; ++ case TERMKEY_TYPE_MOUSE: ++ goto retry; + default: + result = ERR; + } @@ -52,9 +54,6 @@ diff -r 9d0780ddcbab binding.c + result = 0; + break; + } -+#else - int result = wgetch (InputWindowOf (obj)); -+#endif if (result >= 0 && test != 0 diff --git a/src/termkey.patch b/src/termkey.patch new file mode 100644 index 00000000..f649cbaf --- /dev/null +++ b/src/termkey.patch @@ -0,0 +1,339 @@ +diff -r a94d84bdd4a6 driver-win32-pdcurses.c +--- /dev/null Thu Jan 01 00:00:00 1970 +0000 ++++ b/driver-win32-pdcurses.c Fri Oct 24 21:59:44 2014 -0400 +@@ -0,0 +1,106 @@ ++// Copyright 2014 Mitchell mitchell.att.foicica.com. See LICENSE. ++ ++#include "termkey.h" ++#include "termkey-internal.h" ++ ++#include <ctype.h> ++#include <curses.h> ++ ++static void *new_driver(TermKey *tk, const char *term) { return tk; } ++static void free_driver(void *info) {} ++ ++static int initialized; ++ ++// Lookup tables for keysyms and characters. ++static int keysyms[] = {0,TERMKEY_SYM_DOWN,TERMKEY_SYM_UP,TERMKEY_SYM_LEFT,TERMKEY_SYM_RIGHT,TERMKEY_SYM_HOME,TERMKEY_SYM_BACKSPACE,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,TERMKEY_SYM_DELETE,TERMKEY_SYM_INSERT,0,0,0,0,0,0,TERMKEY_SYM_PAGEDOWN,TERMKEY_SYM_PAGEUP,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,TERMKEY_SYM_END}; ++static int shift_keysyms[] = {TERMKEY_SYM_TAB,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,TERMKEY_SYM_DELETE,0,0,TERMKEY_SYM_END,0,0,0,TERMKEY_SYM_HOME,TERMKEY_SYM_INSERT,0,TERMKEY_SYM_LEFT,0,0,0,0,0,0,0,0,TERMKEY_SYM_RIGHT,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,TERMKEY_SYM_UP,TERMKEY_SYM_DOWN}; ++static int ctrl_keysyms[] = {TERMKEY_SYM_LEFT,TERMKEY_SYM_RIGHT,TERMKEY_SYM_PAGEUP,TERMKEY_SYM_PAGEDOWN,TERMKEY_SYM_HOME,TERMKEY_SYM_END,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,TERMKEY_SYM_INSERT,0,0,TERMKEY_SYM_UP,TERMKEY_SYM_DOWN,TERMKEY_SYM_TAB,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,TERMKEY_SYM_BACKSPACE,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,TERMKEY_SYM_DELETE,0,TERMKEY_SYM_ENTER}; ++static int alt_keysyms[] = {TERMKEY_SYM_DELETE,TERMKEY_SYM_INSERT,0,0,0,TERMKEY_SYM_TAB,0,0,TERMKEY_SYM_HOME,TERMKEY_SYM_PAGEUP,TERMKEY_SYM_PAGEDOWN,TERMKEY_SYM_END,TERMKEY_SYM_UP,TERMKEY_SYM_DOWN,TERMKEY_SYM_RIGHT,TERMKEY_SYM_LEFT,TERMKEY_SYM_ENTER,TERMKEY_SYM_ESCAPE,0,0,0,0,0,0,0,0,TERMKEY_SYM_BACKSPACE}; // TERMKEY_SYM_RETURN does not work for me ++static int alt_keychars[] = {'-','=',0,0,0,0,0,0,0,0,0,0,'`','[',']',';','\'',',','.','/',0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'\\'}; // -=`;,./ do not work for me ++static int mousesyms[] = {TERMKEY_MOUSE_RELEASE,TERMKEY_MOUSE_PRESS,0,TERMKEY_MOUSE_PRESS,0,TERMKEY_MOUSE_DRAG,0}; ++ ++static TermKeyResult peekkey(TermKey *tk, void *info, TermKeyKey *key, int force, size_t *nbytep) { ++ if (!initialized) { ++ raw(), noecho(); ++ PDC_save_key_modifiers(TRUE), mouse_set(ALL_MOUSE_EVENTS), mouseinterval(0); ++ initialized = TRUE; ++ } ++ ++ int c = wgetch((WINDOW *)tk->fd), shift = 0, ctrl = 0, alt = 0; ++ if (c == ERR) return TERMKEY_RES_EOF; ++ int codepoint = c, number = 0, button = 0; ++ TermKeyType type = TERMKEY_TYPE_UNICODE; ++ TermKeySym sym = TERMKEY_SYM_UNKNOWN; ++ TermKeyMouseEvent event = TERMKEY_MOUSE_UNKNOWN; ++ if (c != KEY_MOUSE) { ++ if (c < 0x20 && c != 8 && c != 9 && c != 13 && c != 27) ++ type = TERMKEY_TYPE_UNICODE, codepoint = tolower(c ^ 0x40); ++ else if (c == 27) ++ type = TERMKEY_TYPE_KEYSYM, sym = TERMKEY_SYM_ESCAPE; ++ else if (c >= KEY_MIN && c <= KEY_END && keysyms[c - KEY_MIN]) ++ type = TERMKEY_TYPE_KEYSYM, sym = keysyms[c - KEY_MIN]; ++ else if (c >= KEY_F(1) && c <= KEY_F(48)) ++ type = TERMKEY_TYPE_FUNCTION, number = (c - KEY_F(1)) % 12 + 1; ++ else if (c >= KEY_BTAB && c <= KEY_SDOWN && shift_keysyms[c - KEY_BTAB]) ++ type = TERMKEY_TYPE_KEYSYM, sym = shift_keysyms[c - KEY_BTAB]; ++ else if (c >= CTL_LEFT && c <= CTL_ENTER && ctrl_keysyms[c - CTL_LEFT]) ++ type = TERMKEY_TYPE_KEYSYM, sym = ctrl_keysyms[c - CTL_LEFT]; ++ else if (c >= ALT_DEL && c <= ALT_BKSP && alt_keysyms[c - ALT_DEL]) ++ type = TERMKEY_TYPE_KEYSYM, sym = alt_keysyms[c - ALT_DEL]; ++ else if (c >= ALT_MINUS && c <= ALT_BSLASH && alt_keychars[c - ALT_MINUS]) ++ type = TERMKEY_TYPE_UNICODE, codepoint = alt_keychars[c - ALT_MINUS]; ++ shift = PDC_get_key_modifiers() & PDC_KEY_MODIFIER_SHIFT; ++ ctrl = PDC_get_key_modifiers() & PDC_KEY_MODIFIER_CONTROL; ++ alt = PDC_get_key_modifiers() & PDC_KEY_MODIFIER_ALT; ++ // Do not shift printable keys. ++ if (shift && codepoint >= 32 && codepoint <= 127) shift = 0; ++ key->type = type; ++ if (type == TERMKEY_TYPE_UNICODE) { ++ key->code.codepoint = codepoint; ++ key->utf8[0] = key->code.codepoint, key->utf8[1] = '\0'; ++ } else if (type == TERMKEY_TYPE_FUNCTION) ++ key->code.number = number; ++ else if (type == TERMKEY_TYPE_KEYSYM) ++ key->code.sym = sym; ++ } else { ++ request_mouse_pos(); ++ if (A_BUTTON_CHANGED) { ++ for (int i = 1; i <= 3; i++) ++ if (BUTTON_CHANGED(i)) { ++ event = mousesyms[BUTTON_STATUS(i) & BUTTON_ACTION_MASK], button = i; ++ shift = BUTTON_STATUS(i) & PDC_BUTTON_SHIFT; ++ ctrl = BUTTON_STATUS(i) & PDC_BUTTON_CONTROL; ++ alt = BUTTON_STATUS(i) & PDC_BUTTON_ALT; ++ break; ++ } ++ } else if (MOUSE_WHEEL_UP || MOUSE_WHEEL_DOWN) ++ event = TERMKEY_MOUSE_PRESS, button = MOUSE_WHEEL_UP ? 4 : 5; ++ key->type = TERMKEY_TYPE_MOUSE; ++ key->code.mouse[0] = button | (event << 4); ++ termkey_key_set_linecol(key, MOUSE_X_POS + 1, MOUSE_Y_POS + 1); ++ } ++ key->modifiers = (shift ? TERMKEY_KEYMOD_SHIFT : 0) | ++ (ctrl ? TERMKEY_KEYMOD_CTRL : 0) | ++ (alt ? TERMKEY_KEYMOD_ALT : 0); ++ return TERMKEY_RES_KEY; ++} ++ ++TermKeyResult termkey_interpret_mouse(TermKey *tk, const TermKeyKey *key, TermKeyMouseEvent *event, int *button, int *line, int *col) { ++ if (key->type != TERMKEY_TYPE_MOUSE) return TERMKEY_RES_NONE; ++ if (event) *event = (key->code.mouse[0] & 0xF0) >> 4; ++ if (button) *button = key->code.mouse[0] & 0xF; ++ termkey_key_get_linecol(key, line, col); ++ return TERMKEY_RES_KEY; ++} ++ ++// Unimplemented. ++TermKeyResult termkey_interpret_modereport(TermKey *tk, const TermKeyKey *key, int *initial, int *mode, int *value) { return TERMKEY_RES_ERROR; } ++TermKeyResult termkey_interpret_position(TermKey *tk, const TermKeyKey *key, int *line, int *col) { return TERMKEY_RES_ERROR; } ++TermKeyResult termkey_interpret_csi(TermKey *tk, const TermKeyKey *key, long args[], size_t *nargs, unsigned long *cmd) { return TERMKEY_RES_ERROR; } ++ ++struct TermKeyDriver termkey_driver_win32_pdcurses = { ++ .name = "win32-pdcurses", ++ .new_driver = new_driver, ++ .free_driver = free_driver, ++ .peekkey = peekkey, ++}; +diff -r a94d84bdd4a6 termkey-internal.h +--- a/termkey-internal.h Fri Oct 24 21:58:29 2014 -0400 ++++ b/termkey-internal.h Fri Oct 24 21:59:44 2014 -0400 +@@ -4,7 +4,9 @@ + #include "termkey.h" + + #include <stdint.h> ++#if !_WIN32 + #include <termios.h> ++#endif + + struct TermKeyDriver + { +@@ -31,7 +33,7 @@ + }; + + struct TermKey { +- int fd; ++ termkey_fd_t fd; + int flags; + int canonflags; + unsigned char *buffer; +@@ -41,7 +43,9 @@ + size_t hightide; /* Position beyond buffstart at which peekkey() should next start + * normally 0, but see also termkey_interpret_csi */ + ++#if !_WIN32 + struct termios restore_termios; ++#endif + char restore_termios_valid; + + int waittime; // msec +@@ -88,7 +92,11 @@ + key->code.mouse[3] = (line & 0xf00) >> 8 | (col & 0x300) >> 4; + } + ++#if !_WIN32 + extern struct TermKeyDriver termkey_driver_csi; + extern struct TermKeyDriver termkey_driver_ti; ++#else ++extern struct TermKeyDriver termkey_driver_win32_pdcurses; ++#endif + + #endif +diff -r a94d84bdd4a6 termkey.c +--- a/termkey.c Fri Oct 24 21:58:29 2014 -0400 ++++ b/termkey.c Fri Oct 24 21:59:44 2014 -0400 +@@ -3,8 +3,12 @@ + + #include <ctype.h> + #include <errno.h> ++#if !_WIN32 + #include <poll.h> + #include <unistd.h> ++#else ++#define ssize_t int ++#endif + #include <string.h> + + #include <stdio.h> +@@ -27,8 +31,12 @@ + } + + static struct TermKeyDriver *drivers[] = { ++#if !_WIN32 + &termkey_driver_ti, + &termkey_driver_csi, ++#else ++ &termkey_driver_win32_pdcurses, ++#endif + NULL, + }; + +@@ -263,7 +271,7 @@ + + /* Default all the object fields but don't allocate anything */ + +- tk->fd = -1; ++ tk->fd = FD_NONE; + tk->flags = 0; + tk->canonflags = 0; + +@@ -373,7 +381,7 @@ + return 0; + } + +-TermKey *termkey_new(int fd, int flags) ++TermKey *termkey_new(termkey_fd_t fd, int flags) + { + TermKey *tk = termkey_alloc(); + if(!tk) +@@ -414,7 +422,7 @@ + if(!tk) + return NULL; + +- tk->fd = -1; ++ tk->fd = FD_NONE; + + termkey_set_flags(tk, flags); + +@@ -457,6 +465,7 @@ + if(tk->is_started) + return 1; + ++#if !_WIN32 + if(tk->fd != -1 && !(tk->flags & TERMKEY_FLAG_NOTERMIOS)) { + struct termios termios; + if(tcgetattr(tk->fd, &termios) == 0) { +@@ -487,6 +496,7 @@ + tcsetattr(tk->fd, TCSANOW, &termios); + } + } ++#endif + + struct TermKeyDriverNode *p; + for(p = tk->drivers; p; p = p->next) +@@ -512,8 +522,10 @@ + if(p->driver->stop_driver) + (*p->driver->stop_driver)(tk, p->info); + ++#if !_WIN32 + if(tk->restore_termios_valid) + tcsetattr(tk->fd, TCSANOW, &tk->restore_termios); ++#endif + + tk->is_started = 0; + +@@ -525,11 +537,18 @@ + return tk->is_started; + } + +-int termkey_get_fd(TermKey *tk) ++termkey_fd_t termkey_get_fd(TermKey *tk) + { + return tk->fd; + } + ++#if _WIN32 ++void termkey_set_fd(TermKey *tk, termkey_fd_t fd) ++{ ++ tk->fd = fd; ++} ++#endif ++ + int termkey_get_flags(TermKey *tk) + { + return tk->flags; +@@ -1012,7 +1031,7 @@ + + TermKeyResult termkey_waitkey(TermKey *tk, TermKeyKey *key) + { +- if(tk->fd == -1) { ++ if(tk->fd == FD_NONE) { + errno = EBADF; + return TERMKEY_RES_ERROR; + } +@@ -1026,6 +1045,7 @@ + case TERMKEY_RES_ERROR: + return ret; + ++#if !_WIN32 + case TERMKEY_RES_NONE: + ret = termkey_advisereadable(tk); + if(ret == TERMKEY_RES_ERROR) +@@ -1064,6 +1084,7 @@ + return termkey_getkey_force(tk, key); + } + break; ++#endif + } + } + +@@ -1072,6 +1093,7 @@ + + TermKeyResult termkey_advisereadable(TermKey *tk) + { ++#if !_WIN32 + ssize_t len; + + if(tk->fd == -1) { +@@ -1109,6 +1131,9 @@ + tk->buffcount += len; + return TERMKEY_RES_AGAIN; + } ++#else ++ return TERMKEY_RES_NONE; ++#endif + } + + size_t termkey_push_bytes(TermKey *tk, const char *bytes, size_t len) +diff -r a94d84bdd4a6 termkey.h +--- a/termkey.h Fri Oct 24 21:58:29 2014 -0400 ++++ b/termkey.h Fri Oct 24 21:59:44 2014 -0400 +@@ -14,6 +14,14 @@ + #define TERMKEY_CHECK_VERSION \ + termkey_check_version(TERMKEY_VERSION_MAJOR, TERMKEY_VERSION_MINOR) + ++#if !_WIN32 ++#define termkey_fd_t int ++#define FD_NONE -1 ++#else ++#define termkey_fd_t void* ++#define FD_NONE NULL ++#endif ++ + typedef enum { + TERMKEY_SYM_UNKNOWN = -1, + TERMKEY_SYM_NONE = 0, +@@ -161,7 +169,7 @@ + + void termkey_check_version(int major, int minor); + +-TermKey *termkey_new(int fd, int flags); ++TermKey *termkey_new(termkey_fd_t fd, int flags); + TermKey *termkey_new_abstract(const char *term, int flags); + void termkey_free(TermKey *tk); + void termkey_destroy(TermKey *tk); +@@ -170,7 +178,10 @@ + int termkey_stop(TermKey *tk); + int termkey_is_started(TermKey *tk); + +-int termkey_get_fd(TermKey *tk); ++termkey_fd_t termkey_get_fd(TermKey *tk); ++#if _WIN32 ++void termkey_set_fd(TermKey *tk, termkey_fd_t fd); ++#endif + + int termkey_get_flags(TermKey *tk); + void termkey_set_flags(TermKey *tk, int newflags); diff --git a/src/textadept.c b/src/textadept.c index b5fe7b55..fb47bf3c 100644 --- a/src/textadept.c +++ b/src/textadept.c @@ -51,10 +51,8 @@ #include "ScintillaTerm.h" #include "windowman.h" #include "cdk_int.h" -#if !_WIN32 #include "termkey.h" #endif -#endif // GTK definitions and macros. #if GTK @@ -148,9 +146,7 @@ static ListStore *find_store, *repl_store; // curses window. static struct WindowManager *wm; static int command_entry_focused; -#if !_WIN32 TermKey *ta_tk; // global for CDK use -#endif #define SS(view, msg, w, l) scintilla_send_message(view, msg, w, l) #define focus_view(view) \ (focused_view ? SS(focused_view, SCI_SETFOCUS, 0, 0) : 0, \ @@ -192,6 +188,10 @@ static ListStore find_store[10], repl_store[10]; fcopy(&option_labels[i], lua_tostring(L, -1)); \ if (!*option) option_labels[i] += 4; \ } +#if _WIN32 +#define textadept_waitkey(tk, key) \ + (termkey_set_fd(tk, scintilla_get_window(view)), termkey_getkey(tk, key)) +#endif #endif #define set_clipboard(s) SS(focused_view, SCI_COPYTEXT, strlen(s), (sptr_t)s) @@ -2275,16 +2275,10 @@ int main(int argc, char **argv) { #if GTK gtk_init(&argc, &argv); #elif CURSES -#if !_WIN32 ta_tk = termkey_new(0, 0); - printf("\033[?1003h"); // enable mouse mode -#endif setlocale(LC_CTYPE, ""); // for displaying UTF-8 characters properly initscr(); // raw()/cbreak() and noecho() are taken care of in libtermkey curs_set(0); // disable cursor when Scintilla has focus -#if _WIN32 - raw(), noecho(); -#endif #if NCURSES_REENTRANT ESCDELAY = getenv("ESCDELAY") ? atoi(getenv("ESCDELAY")) : 100; #endif @@ -2369,66 +2363,22 @@ int main(int argc, char **argv) { act.sa_handler = resize, sigaction(SIGWINCH, &act, NULL); #else freopen("NUL", "w", stderr); // redirect stderr - PDC_save_key_modifiers(TRUE), mouse_set(ALL_MOUSE_EVENTS), mouseinterval(0); #endif Scintilla *view = focused_view; - int c = 0, shift = 0, ctrl = 0, alt = 0; // key info - int event = 0, button = 0, y = 0, x = 0, millis = 0; // mouse info -#if _WIN32 - int keysyms[] = {0,SCK_DOWN,SCK_UP,SCK_LEFT,SCK_RIGHT,SCK_HOME,SCK_BACK,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,SCK_DELETE,SCK_INSERT,0,0,0,0,0,0,SCK_NEXT,SCK_PRIOR,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,SCK_END}; - int shift_keysyms[] = {SCK_TAB,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,SCK_DELETE,0,0,SCK_END,0,0,0,SCK_HOME,SCK_INSERT,0,SCK_LEFT,0,0,0,0,0,0,0,0,SCK_RIGHT,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,SCK_UP,SCK_DOWN}; - int ctrl_keysyms[] = {SCK_LEFT,SCK_RIGHT,SCK_PRIOR,SCK_NEXT,SCK_HOME,SCK_END,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,SCK_INSERT,0,0,SCK_UP,SCK_DOWN,SCK_TAB,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,SCK_BACK,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,SCK_DELETE,0,SCK_RETURN}; - int alt_keysyms[] = {SCK_DELETE,SCK_INSERT,0,0,0,SCK_TAB,'-','=',SCK_HOME,SCK_PRIOR,SCK_NEXT,SCK_END,SCK_UP,SCK_DOWN,SCK_RIGHT,SCK_LEFT,SCK_RETURN,SCK_ESCAPE,'`','[',']',';','\'',',','.','/',SCK_BACK,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,'\\'}; // SCK_RETURN, '\\' do not work for me - int mousesyms[] = {SCM_RELEASE,SCM_PRESS,0,SCM_PRESS,0,SCM_DRAG,0}; - while ((c = wgetch(scintilla_get_window(view))) != ERR) { - if (c != KEY_MOUSE) { - if (c < 0x20 && c != 8 && c != 9 && c != 13 && c != 27) - c = tolower(c ^ 0x40); - else if (c == 27) - c = SCK_ESCAPE; - else if (c >= KEY_MIN && c <= KEY_END && keysyms[c - KEY_MIN]) - c = keysyms[c - KEY_MIN]; - else if (c >= KEY_F(1) && c <= KEY_F(48)) - c = 0xFFBE + (c - KEY_F(1)) % 12; // use GDK keysym values for now - else if (c >= KEY_BTAB && c <= KEY_SDOWN && shift_keysyms[c - KEY_BTAB]) - c = shift_keysyms[c - KEY_BTAB]; - else if (c >= CTL_LEFT && c <= CTL_ENTER && ctrl_keysyms[c - CTL_LEFT]) - c = ctrl_keysyms[c - CTL_LEFT]; - else if (c >= ALT_DEL && c <= ALT_BSLASH && alt_keysyms[c - ALT_DEL]) - c = alt_keysyms[c - ALT_DEL]; - shift = PDC_get_key_modifiers() & PDC_KEY_MODIFIER_SHIFT; - ctrl = PDC_get_key_modifiers() & PDC_KEY_MODIFIER_CONTROL; - alt = PDC_get_key_modifiers() & PDC_KEY_MODIFIER_ALT; - if (c >= 32 && c <= 127) shift = 0; // do not shift printable keys - } else { - request_mouse_pos(), button = 0, y = MOUSE_Y_POS, x = MOUSE_X_POS; - if (BUTTON_CHANGED(1)) { - event = mousesyms[BUTTON_STATUS(1) & BUTTON_ACTION_MASK], button = 1; - shift = BUTTON_STATUS(1) & PDC_BUTTON_SHIFT; - ctrl = BUTTON_STATUS(1) & PDC_BUTTON_CONTROL; - alt = BUTTON_STATUS(1) & PDC_BUTTON_ALT; - } else if (MOUSE_WHEEL_UP || MOUSE_WHEEL_DOWN) - event = SCM_PRESS, button = MOUSE_WHEEL_UP ? 4 : 5; - FILETIME time; - GetSystemTimeAsFileTime(&time); - ULARGE_INTEGER ticks; - ticks.LowPart = time.dwLowDateTime, ticks.HighPart = time.dwHighDateTime; - millis = ticks.QuadPart / 10000; // each tick is a 100-nanosecond interval - } -#else + int ch = 0, event = 0, button = 0, y = 0, x = 0, millis = 0; TermKeyResult res; TermKeyKey key; int keysyms[] = {0,SCK_BACK,SCK_TAB,SCK_RETURN,SCK_ESCAPE,0,SCK_BACK,SCK_UP,SCK_DOWN,SCK_LEFT,SCK_RIGHT,0,0,SCK_INSERT,SCK_DELETE,0,SCK_PRIOR,SCK_NEXT,SCK_HOME,SCK_END}; - while ((c = 0, res = textadept_waitkey(ta_tk, &key)) != TERMKEY_RES_EOF) { + while ((ch = 0, res = textadept_waitkey(ta_tk, &key)) != TERMKEY_RES_EOF) { if (res == TERMKEY_RES_ERROR) continue; if (key.type == TERMKEY_TYPE_UNICODE) - c = key.code.codepoint; + ch = key.code.codepoint; else if (key.type == TERMKEY_TYPE_FUNCTION) - c = 0xFFBD + key.code.number; // use GDK keysym values for now + ch = 0xFFBD + key.code.number; // use GDK keysym values for now else if (key.type == TERMKEY_TYPE_KEYSYM && key.code.sym >= 0 && key.code.sym <= TERMKEY_SYM_END) - c = keysyms[key.code.sym]; + ch = keysyms[key.code.sym]; else if (key.type == TERMKEY_TYPE_UNKNOWN_CSI) { long args[16]; size_t nargs = 16; @@ -2442,19 +2392,29 @@ int main(int argc, char **argv) { } else if (key.type == TERMKEY_TYPE_MOUSE) { termkey_interpret_mouse(ta_tk, &key, (TermKeyMouseEvent*)&event, &button, &y, &x), y--, x--; +#if !_WIN32 struct timeval time = {0, 0}; gettimeofday(&time, NULL); millis = time.tv_sec * 1000 + time.tv_usec / 1000; +#else + FILETIME time; + GetSystemTimeAsFileTime(&time); + ULARGE_INTEGER ticks; + ticks.LowPart = time.dwLowDateTime, ticks.HighPart = time.dwHighDateTime; + millis = ticks.QuadPart / 10000; // each tick is a 100-nanosecond interval +#endif } else continue; // skip unknown types - shift = key.modifiers & TERMKEY_KEYMOD_SHIFT; - ctrl = key.modifiers & TERMKEY_KEYMOD_CTRL; - alt = key.modifiers & TERMKEY_KEYMOD_ALT; -#endif - if (!c || c == KEY_MOUSE) - scintilla_send_mouse(view, event, millis, button, y, x, shift, ctrl, alt); - else if (!lL_event(lua, "keypress", LUA_TNUMBER, c, LUA_TBOOLEAN, shift, - LUA_TBOOLEAN, ctrl, LUA_TBOOLEAN, alt, -1)) - scintilla_send_key(view, c, shift, ctrl, alt); + int shift = key.modifiers & TERMKEY_KEYMOD_SHIFT; + int ctrl = key.modifiers & TERMKEY_KEYMOD_CTRL; + int alt = key.modifiers & TERMKEY_KEYMOD_ALT; + if (ch && !lL_event(lua, "keypress", LUA_TNUMBER, ch, LUA_TBOOLEAN, shift, + LUA_TBOOLEAN, ctrl, LUA_TBOOLEAN, alt, -1)) + scintilla_send_key(view, ch, shift, ctrl, alt); + else if (!ch && !scintilla_send_mouse(view, event, millis, button, y, x, + shift, ctrl, alt)) + lL_event(lua, "mouse", LUA_TNUMBER, event, LUA_TNUMBER, button, + LUA_TNUMBER, y, LUA_TNUMBER, x, LUA_TBOOLEAN, shift, + LUA_TBOOLEAN, ctrl, LUA_TBOOLEAN, alt, -1); if (quit && lL_event(lua, "quit", -1)) { l_close(lua); // Free some memory. @@ -2474,11 +2434,8 @@ int main(int argc, char **argv) { view = !command_entry_focused ? focused_view : command_entry; } endwin(); -#if !_WIN32 - printf("\033[?1003l"); // disable mouse mode termkey_destroy(ta_tk); #endif -#endif free(textadept_home); } |