aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--core/.buffer.luadoc6
-rw-r--r--core/events.lua18
-rw-r--r--core/iface.lua2
-rw-r--r--core/ui.lua49
-rw-r--r--properties.lua8
-rwxr-xr-xscripts/gen_iface.lua5
-rw-r--r--src/Makefile27
-rw-r--r--src/cdk.patch17
-rw-r--r--src/termkey.patch339
-rw-r--r--src/textadept.c99
10 files changed, 473 insertions, 97 deletions
diff --git a/core/.buffer.luadoc b/core/.buffer.luadoc
index c5e5e2fd..f9b92834 100644
--- a/core/.buffer.luadoc
+++ b/core/.buffer.luadoc
@@ -1002,6 +1002,12 @@
--
-- @field MOD_SUPER (number, Read-only)
--
+-- @field MOUSE_DRAG (number, Read-only)
+--
+-- @field MOUSE_PRESS (number, Read-only)
+--
+-- @field MOUSE_RELEASE (number, Read-only)
+--
-- @field VS_NONE (number, Read-only)
--
-- @field VS_RECTANGULARSELECTION (number, Read-only)
diff --git a/core/events.lua b/core/events.lua
index 56331196..c63e98a8 100644
--- a/core/events.lua
+++ b/core/events.lua
@@ -192,6 +192,18 @@ local M = {}
-- Arguments:
--
-- * _`menu_id`_: The numeric ID of the menu item set in [`ui.menu()`]().
+-- @field MOUSE (string)
+-- Emitted by the terminal version for an unhandled mouse event.
+-- Arguments:
+--
+-- * _`event`_: The mouse event: `buffer.MOUSE_PRESS`, `buffer.MOUSE_DRAG`, or
+-- `buffer.MOUSE_RELEASE`.
+-- * _`button`_: The mouse button number.
+-- * _`y`_: The y-coordinate of the mouse event, starting from 1.
+-- * _`x`_: The x-coordinate of the mouse event, starting from 1.
+-- * _`shift`_: The "Shift" modifier key is held down.
+-- * _`ctrl`_: The "Control" modifier key is held down.
+-- * _`alt`_: The "Alt"/"Option" modifier key is held down.
-- @field QUIT (string)
-- Emitted when quitting Textadept.
-- When connecting to this event, connect with an index of 1 or the handler
@@ -366,9 +378,9 @@ for _, n in pairs(scnotifications) do M[n[1]:upper()] = n[1] end
local ta_events = {
'appleevent_odoc', 'buffer_after_switch', 'buffer_before_switch',
'buffer_deleted', 'buffer_new', 'csi', 'error', 'find', 'focus',
- 'initialized', 'keypress', 'menu_clicked', 'quit', 'replace', 'replace_all',
- 'reset_after', 'reset_before', 'view_after_switch', 'view_before_switch',
- 'view_new'
+ 'initialized', 'keypress', 'menu_clicked', 'mouse', 'quit', 'replace',
+ 'replace_all', 'reset_after', 'reset_before', 'view_after_switch',
+ 'view_before_switch', 'view_new'
}
for _, e in pairs(ta_events) do M[e:upper()] = e end
diff --git a/core/iface.lua b/core/iface.lua
index c56ccca3..1fbc89e5 100644
--- a/core/iface.lua
+++ b/core/iface.lua
@@ -14,7 +14,7 @@ module('_SCINTILLA')]]
-- @class table
-- @name constants
-- @see _G.buffer
-M.constants = {ALPHA_NOALPHA=256,ALPHA_OPAQUE=255,ALPHA_TRANSPARENT=0,ANNOTATION_BOXED=2,ANNOTATION_HIDDEN=0,ANNOTATION_STANDARD=1,AUTOMATICFOLD_CHANGE=0x0004,AUTOMATICFOLD_CLICK=0x0002,AUTOMATICFOLD_SHOW=0x0001,CARETSTICKY_OFF=0,CARETSTICKY_ON=1,CARETSTICKY_WHITESPACE=2,CARETSTYLE_BLOCK=2,CARETSTYLE_INVISIBLE=0,CARETSTYLE_LINE=1,CARET_EVEN=0x08,CARET_JUMPS=0x10,CARET_SLOP=0x01,CARET_STRICT=0x04,CASEINSENSITIVEBEHAVIOUR_IGNORECASE=1,CASEINSENSITIVEBEHAVIOUR_RESPECTCASE=0,CASE_LOWER=2,CASE_MIXED=0,CASE_UPPER=1,CP_UTF8=65001,CURSORARROW=2,CURSORNORMAL=-1,CURSORREVERSEARROW=7,CURSORWAIT=4,EDGE_BACKGROUND=2,EDGE_LINE=1,EDGE_NONE=0,EOL_CR=1,EOL_CRLF=0,EOL_LF=2,FIND_MATCHCASE=0x4,FIND_REGEXP=6291456,FIND_WHOLEWORD=0x2,FIND_WORDSTART=0x00100000,FOLDACTION_CONTRACT=0,FOLDACTION_EXPAND=1,FOLDACTION_TOGGLE=2,FOLDFLAG_LEVELNUMBERS=0x0040,FOLDFLAG_LINEAFTER_CONTRACTED=0x0010,FOLDFLAG_LINEAFTER_EXPANDED=0x0008,FOLDFLAG_LINEBEFORE_CONTRACTED=0x0004,FOLDFLAG_LINEBEFORE_EXPANDED=0x0002,FOLDFLAG_LINESTATE=0x0080,FOLDLEVELBASE=0x400,FOLDLEVELHEADERFLAG=0x2000,FOLDLEVELNUMBERMASK=0x0FFF,FOLDLEVELWHITEFLAG=0x1000,IME_INLINE=1,IME_WINDOWED=0,INDIC_BOX=6,INDIC_COMPOSITIONTHICK=14,INDIC_CONTAINER=8,INDIC_DASH=9,INDIC_DIAGONAL=3,INDIC_DOTBOX=12,INDIC_DOTS=10,INDIC_HIDDEN=5,INDIC_MAX=31,INDIC_PLAIN=0,INDIC_ROUNDBOX=7,INDIC_SQUIGGLE=1,INDIC_SQUIGGLELOW=11,INDIC_SQUIGGLEPIXMAP=13,INDIC_STRAIGHTBOX=8,INDIC_STRIKE=4,INDIC_TT=2,IV_LOOKBOTH=3,IV_LOOKFORWARD=2,IV_NONE=0,IV_REAL=1,LASTSTEPINUNDOREDO=0x100,MARGINOPTION_NONE=0,MARGINOPTION_SUBLINESELECT=1,MARGIN_BACK=2,MARGIN_FORE=3,MARGIN_NUMBER=1,MARGIN_RTEXT=5,MARGIN_SYMBOL=0,MARGIN_TEXT=4,MARKER_MAX=31,MARKNUM_FOLDER=30,MARKNUM_FOLDEREND=25,MARKNUM_FOLDERMIDTAIL=27,MARKNUM_FOLDEROPEN=31,MARKNUM_FOLDEROPENMID=26,MARKNUM_FOLDERSUB=29,MARKNUM_FOLDERTAIL=28,MARK_ARROW=2,MARK_ARROWDOWN=6,MARK_ARROWS=24,MARK_AVAILABLE=28,MARK_BACKGROUND=22,MARK_BOOKMARK=31,MARK_BOXMINUS=14,MARK_BOXMINUSCONNECTED=15,MARK_BOXPLUS=12,MARK_BOXPLUSCONNECTED=13,MARK_CHARACTER=10000,MARK_CIRCLE=0,MARK_CIRCLEMINUS=20,MARK_CIRCLEMINUSCONNECTED=21,MARK_CIRCLEPLUS=18,MARK_CIRCLEPLUSCONNECTED=19,MARK_DOTDOTDOT=23,MARK_EMPTY=5,MARK_FULLRECT=26,MARK_LCORNER=10,MARK_LCORNERCURVE=16,MARK_LEFTRECT=27,MARK_MINUS=7,MARK_PIXMAP=25,MARK_PLUS=8,MARK_RGBAIMAGE=30,MARK_ROUNDRECT=1,MARK_SHORTARROW=4,MARK_SMALLRECT=3,MARK_TCORNER=11,MARK_TCORNERCURVE=17,MARK_UNDERLINE=29,MARK_VLINE=9,MASK_FOLDERS=-33554432,MAX_MARGIN=4,MODEVENTMASKALL=0x3FFFFF,MOD_ALT=4,MOD_BEFOREDELETE=0x800,MOD_BEFOREINSERT=0x400,MOD_CHANGEANNOTATION=0x20000,MOD_CHANGEFOLD=0x8,MOD_CHANGEINDICATOR=0x4000,MOD_CHANGELINESTATE=0x8000,MOD_CHANGEMARGIN=0x10000,MOD_CHANGEMARKER=0x200,MOD_CHANGESTYLE=0x4,MOD_CHANGETABSTOPS=0x200000,MOD_CONTAINER=0x40000,MOD_CTRL=2,MOD_DELETETEXT=0x2,MOD_INSERTCHECK=0x100000,MOD_INSERTTEXT=0x1,MOD_LEXERSTATE=0x80000,MOD_META=16,MOD_NORM=0,MOD_SHIFT=1,MOD_SUPER=8,MULTIAUTOC_EACH=1,MULTIAUTOC_ONCE=0,MULTILINEUNDOREDO=0x1000,MULTIPASTE_EACH=1,MULTIPASTE_ONCE=0,MULTISTEPUNDOREDO=0x80,ORDER_CUSTOM=2,ORDER_PERFORMSORT=1,ORDER_PRESORTED=0,PERFORMED_REDO=0x40,PERFORMED_UNDO=0x20,PERFORMED_USER=0x10,PHASES_MULTIPLE=2,PHASES_ONE=0,PHASES_TWO=1,SCN_AUTOCCANCELLED=2025,SCN_AUTOCCHARDELETED=2026,SCN_AUTOCSELECTION=2022,SCN_CALLTIPCLICK=2021,SCN_CHARADDED=2001,SCN_DOUBLECLICK=2006,SCN_DWELLEND=2017,SCN_DWELLSTART=2016,SCN_FOCUSIN=2028,SCN_FOCUSOUT=2029,SCN_HOTSPOTCLICK=2019,SCN_HOTSPOTDOUBLECLICK=2020,SCN_HOTSPOTRELEASECLICK=2027,SCN_INDICATORCLICK=2023,SCN_INDICATORRELEASE=2024,SCN_KEY=2005,SCN_MACRORECORD=2009,SCN_MARGINCLICK=2010,SCN_MODIFIED=2008,SCN_MODIFYATTEMPTRO=2004,SCN_NEEDSHOWN=2011,SCN_PAINTED=2013,SCN_SAVEPOINTLEFT=2003,SCN_SAVEPOINTREACHED=2002,SCN_STYLENEEDED=2000,SCN_UPDATEUI=2007,SCN_URIDROPPED=2015,SCN_USERLISTSELECTION=2014,SCN_ZOOM=2018,SEL_LINES=2,SEL_RECTANGLE=1,SEL_STREAM=0,SEL_THIN=3,STARTACTION=0x2000,STYLE_BRACEBAD=35,STYLE_BRACELIGHT=34,STYLE_CALLTIP=38,STYLE_CONTROLCHAR=36,STYLE_DEFAULT=32,STYLE_INDENTGUIDE=37,STYLE_LASTPREDEFINED=39,STYLE_LINENUMBER=33,STYLE_MAX=255,TIME_FOREVER=10000000,UPDATE_CONTENT=0x1,UPDATE_H_SCROLL=0x8,UPDATE_SELECTION=0x2,UPDATE_V_SCROLL=0x4,VISIBLE_SLOP=0x01,VISIBLE_STRICT=0x04,VS_NONE=0,VS_RECTANGULARSELECTION=1,VS_USERACCESSIBLE=2,WRAPINDENT_FIXED=0,WRAPINDENT_INDENT=2,WRAPINDENT_SAME=1,WRAPVISUALFLAGLOC_DEFAULT=0x0000,WRAPVISUALFLAGLOC_END_BY_TEXT=0x0001,WRAPVISUALFLAGLOC_START_BY_TEXT=0x0002,WRAPVISUALFLAG_END=0x0001,WRAPVISUALFLAG_MARGIN=0x0004,WRAPVISUALFLAG_NONE=0x0000,WRAPVISUALFLAG_START=0x0002,WRAP_CHAR=2,WRAP_NONE=0,WRAP_WHITESPACE=3,WRAP_WORD=1,WS_INVISIBLE=0,WS_VISIBLEAFTERINDENT=2,WS_VISIBLEALWAYS=1}
+M.constants = {ALPHA_NOALPHA=256,ALPHA_OPAQUE=255,ALPHA_TRANSPARENT=0,ANNOTATION_BOXED=2,ANNOTATION_HIDDEN=0,ANNOTATION_STANDARD=1,AUTOMATICFOLD_CHANGE=0x0004,AUTOMATICFOLD_CLICK=0x0002,AUTOMATICFOLD_SHOW=0x0001,CARETSTICKY_OFF=0,CARETSTICKY_ON=1,CARETSTICKY_WHITESPACE=2,CARETSTYLE_BLOCK=2,CARETSTYLE_INVISIBLE=0,CARETSTYLE_LINE=1,CARET_EVEN=0x08,CARET_JUMPS=0x10,CARET_SLOP=0x01,CARET_STRICT=0x04,CASEINSENSITIVEBEHAVIOUR_IGNORECASE=1,CASEINSENSITIVEBEHAVIOUR_RESPECTCASE=0,CASE_LOWER=2,CASE_MIXED=0,CASE_UPPER=1,CP_UTF8=65001,CURSORARROW=2,CURSORNORMAL=-1,CURSORREVERSEARROW=7,CURSORWAIT=4,EDGE_BACKGROUND=2,EDGE_LINE=1,EDGE_NONE=0,EOL_CR=1,EOL_CRLF=0,EOL_LF=2,FIND_MATCHCASE=0x4,FIND_REGEXP=6291456,FIND_WHOLEWORD=0x2,FIND_WORDSTART=0x00100000,FOLDACTION_CONTRACT=0,FOLDACTION_EXPAND=1,FOLDACTION_TOGGLE=2,FOLDFLAG_LEVELNUMBERS=0x0040,FOLDFLAG_LINEAFTER_CONTRACTED=0x0010,FOLDFLAG_LINEAFTER_EXPANDED=0x0008,FOLDFLAG_LINEBEFORE_CONTRACTED=0x0004,FOLDFLAG_LINEBEFORE_EXPANDED=0x0002,FOLDFLAG_LINESTATE=0x0080,FOLDLEVELBASE=0x400,FOLDLEVELHEADERFLAG=0x2000,FOLDLEVELNUMBERMASK=0x0FFF,FOLDLEVELWHITEFLAG=0x1000,IME_INLINE=1,IME_WINDOWED=0,INDIC_BOX=6,INDIC_COMPOSITIONTHICK=14,INDIC_CONTAINER=8,INDIC_DASH=9,INDIC_DIAGONAL=3,INDIC_DOTBOX=12,INDIC_DOTS=10,INDIC_HIDDEN=5,INDIC_MAX=31,INDIC_PLAIN=0,INDIC_ROUNDBOX=7,INDIC_SQUIGGLE=1,INDIC_SQUIGGLELOW=11,INDIC_SQUIGGLEPIXMAP=13,INDIC_STRAIGHTBOX=8,INDIC_STRIKE=4,INDIC_TT=2,IV_LOOKBOTH=3,IV_LOOKFORWARD=2,IV_NONE=0,IV_REAL=1,LASTSTEPINUNDOREDO=0x100,MARGINOPTION_NONE=0,MARGINOPTION_SUBLINESELECT=1,MARGIN_BACK=2,MARGIN_FORE=3,MARGIN_NUMBER=1,MARGIN_RTEXT=5,MARGIN_SYMBOL=0,MARGIN_TEXT=4,MARKER_MAX=31,MARKNUM_FOLDER=30,MARKNUM_FOLDEREND=25,MARKNUM_FOLDERMIDTAIL=27,MARKNUM_FOLDEROPEN=31,MARKNUM_FOLDEROPENMID=26,MARKNUM_FOLDERSUB=29,MARKNUM_FOLDERTAIL=28,MARK_ARROW=2,MARK_ARROWDOWN=6,MARK_ARROWS=24,MARK_AVAILABLE=28,MARK_BACKGROUND=22,MARK_BOOKMARK=31,MARK_BOXMINUS=14,MARK_BOXMINUSCONNECTED=15,MARK_BOXPLUS=12,MARK_BOXPLUSCONNECTED=13,MARK_CHARACTER=10000,MARK_CIRCLE=0,MARK_CIRCLEMINUS=20,MARK_CIRCLEMINUSCONNECTED=21,MARK_CIRCLEPLUS=18,MARK_CIRCLEPLUSCONNECTED=19,MARK_DOTDOTDOT=23,MARK_EMPTY=5,MARK_FULLRECT=26,MARK_LCORNER=10,MARK_LCORNERCURVE=16,MARK_LEFTRECT=27,MARK_MINUS=7,MARK_PIXMAP=25,MARK_PLUS=8,MARK_RGBAIMAGE=30,MARK_ROUNDRECT=1,MARK_SHORTARROW=4,MARK_SMALLRECT=3,MARK_TCORNER=11,MARK_TCORNERCURVE=17,MARK_UNDERLINE=29,MARK_VLINE=9,MASK_FOLDERS=-33554432,MAX_MARGIN=4,MODEVENTMASKALL=0x3FFFFF,MOD_ALT=4,MOD_BEFOREDELETE=0x800,MOD_BEFOREINSERT=0x400,MOD_CHANGEANNOTATION=0x20000,MOD_CHANGEFOLD=0x8,MOD_CHANGEINDICATOR=0x4000,MOD_CHANGELINESTATE=0x8000,MOD_CHANGEMARGIN=0x10000,MOD_CHANGEMARKER=0x200,MOD_CHANGESTYLE=0x4,MOD_CHANGETABSTOPS=0x200000,MOD_CONTAINER=0x40000,MOD_CTRL=2,MOD_DELETETEXT=0x2,MOD_INSERTCHECK=0x100000,MOD_INSERTTEXT=0x1,MOD_LEXERSTATE=0x80000,MOD_META=16,MOD_NORM=0,MOD_SHIFT=1,MOD_SUPER=8,MOUSE_DRAG=2,MOUSE_PRESS=1,MOUSE_RELEASE=3,MULTIAUTOC_EACH=1,MULTIAUTOC_ONCE=0,MULTILINEUNDOREDO=0x1000,MULTIPASTE_EACH=1,MULTIPASTE_ONCE=0,MULTISTEPUNDOREDO=0x80,ORDER_CUSTOM=2,ORDER_PERFORMSORT=1,ORDER_PRESORTED=0,PERFORMED_REDO=0x40,PERFORMED_UNDO=0x20,PERFORMED_USER=0x10,PHASES_MULTIPLE=2,PHASES_ONE=0,PHASES_TWO=1,SCN_AUTOCCANCELLED=2025,SCN_AUTOCCHARDELETED=2026,SCN_AUTOCSELECTION=2022,SCN_CALLTIPCLICK=2021,SCN_CHARADDED=2001,SCN_DOUBLECLICK=2006,SCN_DWELLEND=2017,SCN_DWELLSTART=2016,SCN_FOCUSIN=2028,SCN_FOCUSOUT=2029,SCN_HOTSPOTCLICK=2019,SCN_HOTSPOTDOUBLECLICK=2020,SCN_HOTSPOTRELEASECLICK=2027,SCN_INDICATORCLICK=2023,SCN_INDICATORRELEASE=2024,SCN_KEY=2005,SCN_MACRORECORD=2009,SCN_MARGINCLICK=2010,SCN_MODIFIED=2008,SCN_MODIFYATTEMPTRO=2004,SCN_NEEDSHOWN=2011,SCN_PAINTED=2013,SCN_SAVEPOINTLEFT=2003,SCN_SAVEPOINTREACHED=2002,SCN_STYLENEEDED=2000,SCN_UPDATEUI=2007,SCN_URIDROPPED=2015,SCN_USERLISTSELECTION=2014,SCN_ZOOM=2018,SEL_LINES=2,SEL_RECTANGLE=1,SEL_STREAM=0,SEL_THIN=3,STARTACTION=0x2000,STYLE_BRACEBAD=35,STYLE_BRACELIGHT=34,STYLE_CALLTIP=38,STYLE_CONTROLCHAR=36,STYLE_DEFAULT=32,STYLE_INDENTGUIDE=37,STYLE_LASTPREDEFINED=39,STYLE_LINENUMBER=33,STYLE_MAX=255,TIME_FOREVER=10000000,UPDATE_CONTENT=0x1,UPDATE_H_SCROLL=0x8,UPDATE_SELECTION=0x2,UPDATE_V_SCROLL=0x4,VISIBLE_SLOP=0x01,VISIBLE_STRICT=0x04,VS_NONE=0,VS_RECTANGULARSELECTION=1,VS_USERACCESSIBLE=2,WRAPINDENT_FIXED=0,WRAPINDENT_INDENT=2,WRAPINDENT_SAME=1,WRAPVISUALFLAGLOC_DEFAULT=0x0000,WRAPVISUALFLAGLOC_END_BY_TEXT=0x0001,WRAPVISUALFLAGLOC_START_BY_TEXT=0x0002,WRAPVISUALFLAG_END=0x0001,WRAPVISUALFLAG_MARGIN=0x0004,WRAPVISUALFLAG_NONE=0x0000,WRAPVISUALFLAG_START=0x0002,WRAP_CHAR=2,WRAP_NONE=0,WRAP_WHITESPACE=3,WRAP_WORD=1,WS_INVISIBLE=0,WS_VISIBLEAFTERINDENT=2,WS_VISIBLEALWAYS=1}
---
-- Map of Scintilla function names to tables containing their IDs, return types,
diff --git a/core/ui.lua b/core/ui.lua
index 9d7788be..24a5cbaf 100644
--- a/core/ui.lua
+++ b/core/ui.lua
@@ -401,6 +401,55 @@ events_connect(events.BUFFER_DELETED, function()
if i and _BUFFERS[buffer] ~= i then view:goto_buffer(i) end
end)
+-- Enables and disables mouse mode in curses and focuses and resizes views based
+-- on mouse events.
+if CURSES then
+ if not WIN32 then
+ io.stdout:write("\x1b[?1002h") -- enable mouse mode
+ io.stdout:flush()
+ events.connect(events.QUIT, function()
+ io.stdout:write("\x1b[?1002l") -- disable mouse mode
+ io.stdout:flush()
+ end, 1)
+ end
+
+ -- Retrieves the view or split at the given terminal coordinates.
+ -- @param view View or split to test for coordinates within.
+ -- @param y The y terminal coordinate.
+ -- @param x The x terminal coordinate.
+ local function get_view(view, y, x)
+ if not view[1] and not view[2] then return view end
+ local vertical, size = view.vertical, view.size
+ if vertical and x < size or not vertical and y < size then
+ return get_view(view[1], y, x)
+ elseif vertical and x > size or not vertical and y > size then
+ -- Zero y or x relative to the other view based on split orientation.
+ return get_view(view[2], vertical and y or y - size - 1,
+ vertical and x - size - 1 or x)
+ else
+ return view -- in-between views; return the split itself
+ end
+ end
+
+ local resize
+ events.connect(events.MOUSE, function(event, button, y, x)
+ if event == buffer.MOUSE_RELEASE or button ~= 1 then return end
+ if event == buffer.MOUSE_PRESS then
+ local view = get_view(ui.get_split_table(), y - 1, x) -- title is at y=1
+ if not view[1] and not view[2] then
+ ui.goto_view(_VIEWS[view])
+ resize = nil
+ else
+ resize = function(y2, x2)
+ view[1].size = view.size + (view.vertical and x2 - x or y2 - y)
+ end
+ end
+ elseif resize then
+ resize(y, x)
+ end
+ end)
+end
+
events_connect(events.ERROR, ui.print)
--[[ The tables below were defined in C.
diff --git a/properties.lua b/properties.lua
index 43bc5d30..55ad116d 100644
--- a/properties.lua
+++ b/properties.lua
@@ -8,9 +8,11 @@ buffer.additional_selection_typing = true
--buffer.multi_paste = buffer.MULTIPASTE_EACH
--buffer.virtual_space_options = buffer.VS_RECTANGULARSELECTION +
-- buffer.VS_USERACCESSIBLE
-buffer.rectangular_selection_modifier = (WIN32 or OSX) and buffer.MOD_ALT or
- buffer.MOD_SUPER
--- Note: rectangular selection modifier for CURSES is always ctrl + alt.
+if not CURSES then
+ -- Note: Always Ctrl+Alt on non-Win32 curses and always Alt on Win32 curses.
+ buffer.rectangular_selection_modifier = (WIN32 or OSX) and buffer.MOD_ALT or
+ buffer.MOD_SUPER
+end
--buffer.additional_carets_blink = false
--buffer.additional_carets_visible = false
diff --git a/scripts/gen_iface.lua b/scripts/gen_iface.lua
index cf06ff75..49fd747e 100755
--- a/scripts/gen_iface.lua
+++ b/scripts/gen_iface.lua
@@ -77,6 +77,11 @@ for line in io.lines('../src/scintilla/include/Scintilla.iface') do
::continue::
end
+-- Add mouse events from Scinterm manually.
+constants[#constants + 1] = 'MOUSE_PRESS=1'
+constants[#constants + 1] = 'MOUSE_DRAG=2'
+constants[#constants + 1] = 'MOUSE_RELEASE=3'
+
table.sort(constants)
table.sort(functions)
table.sort(properties)
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);
}