diff options
-rw-r--r-- | core/.buffer.luadoc | 6 | ||||
-rw-r--r-- | core/events.lua | 18 | ||||
-rw-r--r-- | core/iface.lua | 2 | ||||
-rw-r--r-- | core/ui.lua | 49 | ||||
-rw-r--r-- | properties.lua | 8 | ||||
-rwxr-xr-x | scripts/gen_iface.lua | 5 | ||||
-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 |
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); } |