# HG changeset patch # User Bram Moolenaar # Date 1556474410 -7200 # Node ID 7ae2396cef622b53dc0c53fef9494d12ae6e51f1 # Parent bf74bce807e8f45da50093791117848dbc3a3cc8 patch 8.1.1230: a lot of code is shared between vim.exe and gvim.exe commit https://github.com/vim/vim/commit/afde13b62b8fa25dac4635d5caee8d088b937ee0 Author: Bram Moolenaar Date: Sun Apr 28 19:46:49 2019 +0200 patch 8.1.1230: a lot of code is shared between vim.exe and gvim.exe Problem: A lot of code is shared between vim.exe and gvim.exe. Solution: Optionally put the shared code in vim.dll. (Ken Takata, closes #4287) diff --git a/.gitignore b/.gitignore --- a/.gitignore +++ b/.gitignore @@ -33,6 +33,8 @@ src/auto/pathdef.c *.suo *.res *.RES +vim*.dll +vim*.lib src/if_perl.c src/pathdef.c src/Obj*/pathdef.c diff --git a/Filelist b/Filelist --- a/Filelist +++ b/Filelist @@ -454,6 +454,7 @@ SRC_DOS = \ src/iscygpty.h \ src/iid_ole.c \ src/os_dos.h \ + src/os_w32dll.c \ src/os_w32exe.c \ src/os_win32.c \ src/os_mswin.c \ diff --git a/nsis/gvim.nsi b/nsis/gvim.nsi --- a/nsis/gvim.nsi +++ b/nsis/gvim.nsi @@ -322,6 +322,9 @@ Section "$(str_section_exe)" id_section_ SetOutPath $0 File /oname=gvim.exe ${VIMSRC}\gvim_ole.exe +!if /FileExists "${VIMSRC}\vim${BIT}.dll" + File ${VIMSRC}\vim${BIT}.dll +!endif File /oname=install.exe ${VIMSRC}\installw32.exe File /oname=uninstal.exe ${VIMSRC}\uninstalw32.exe File ${VIMSRC}\vimrun.exe diff --git a/runtime/doc/gui_w32.txt b/runtime/doc/gui_w32.txt --- a/runtime/doc/gui_w32.txt +++ b/runtime/doc/gui_w32.txt @@ -1,4 +1,4 @@ -*gui_w32.txt* For Vim version 8.1. Last change: 2017 Oct 27 +*gui_w32.txt* For Vim version 8.1. Last change: 2019 Apr 28 VIM REFERENCE MANUAL by Bram Moolenaar @@ -31,6 +31,17 @@ The GUI will always run in the Windows s return with a command prompt after starting gvim. If not, you should use the "start" command: > start gvim [options] file .. +< *E988* +The console version with the |-g| option may also start the GUI by executing +gvim.exe: > + vim -g [options] file .. +To make this work, gvim.exe must exist in the same directory as the vim.exe, +and this feature must be enabled at compile time. + +One may also use `:gui` from the console version. However, this is an +experimental feature and this feature must be enabled at compile time. +It uses a session file to recreate the current state of the console Vim in the +GUI Vim. Note: All fonts (bold, italic) must be of the same size!!! If you don't do this, text will disappear or mess up the display. Vim does not check the font diff --git a/src/Make_cyg_ming.mak b/src/Make_cyg_ming.mak --- a/src/Make_cyg_ming.mak +++ b/src/Make_cyg_ming.mak @@ -36,7 +36,7 @@ FEATURES=HUGE DEBUG=no # set to yes to create a mapfile -# MAP=yes +#MAP=yes # set to SIZE for size, SPEED for speed, MAXSPEED for maximum optimization OPTIMIZE=MAXSPEED @@ -44,6 +44,11 @@ OPTIMIZE=MAXSPEED # set to yes to make gvim, no for vim GUI=yes +# set to yes to enable the DLL support (EXPERIMENTAL). +# Creates vim{32,64}.dll, and stub gvim.exe and vim.exe. +# "GUI" should be also set to "yes". +#VIMDLL=yes + # set to no if you do not want to use DirectWrite (DirectX) # MinGW-w64 is needed, and ARCH should be set to i686 or x86-64. DIRECTX=yes @@ -687,7 +692,7 @@ else # SPEED CFLAGS += -O2 endif endif -CFLAGS += -s +LFLAGS += -s endif LIB = -lkernel32 -luser32 -lgdi32 -ladvapi32 -lcomdlg32 -lcomctl32 -lnetapi32 -lversion @@ -739,7 +744,6 @@ OBJ = \ $(OUTDIR)/ops.o \ $(OUTDIR)/option.o \ $(OUTDIR)/os_mswin.o \ - $(OUTDIR)/os_w32exe.o \ $(OUTDIR)/os_win32.o \ $(OUTDIR)/pathdef.o \ $(OUTDIR)/popupmnu.o \ @@ -760,10 +764,17 @@ OBJ = \ $(OUTDIR)/usercmd.o \ $(OUTDIR)/userfunc.o \ $(OUTDIR)/version.o \ - $(OUTDIR)/vimrc.o \ $(OUTDIR)/winclip.o \ $(OUTDIR)/window.o +ifeq ($(VIMDLL),yes) +OBJ += $(OUTDIR)/os_w32dll.o $(OUTDIR)/vimrcd.o +EXEOBJC = $(OUTDIR)/os_w32exec.o $(OUTDIR)/vimrcc.o +EXEOBJG = $(OUTDIR)/os_w32exeg.o $(OUTDIR)/vimrcg.o +else +OBJ += $(OUTDIR)/os_w32exe.o $(OUTDIR)/vimrc.o +endif + ifdef PERL OBJ += $(OUTDIR)/if_perl.o endif @@ -870,16 +881,36 @@ endif LFLAGS += -municode -ifeq ($(GUI),yes) +ifeq ($(VIMDLL),yes) +VIMEXE := vim$(DEBUG_SUFFIX).exe +GVIMEXE := gvim$(DEBUG_SUFFIX).exe + ifeq ($(ARCH),x86-64) +VIMDLLBASE := vim64$(DEBUG_SUFFIX) + else +VIMDLLBASE := vim32$(DEBUG_SUFFIX) + endif +TARGET = $(VIMDLLBASE).dll +LFLAGS += -shared +EXELFLAGS += -municode + ifneq ($(DEBUG),yes) +EXELFLAGS += -s + endif +DEFINES += $(DEF_GUI) -DVIMDLL +OBJ += $(GUIOBJ) $(CUIOBJ) +OUTDIR = dobj$(DEBUG_SUFFIX)$(MZSCHEME_SUFFIX)$(ARCH) +MAIN_TARGET = $(GVIMEXE) $(VIMEXE) $(VIMDLLBASE).dll +else ifeq ($(GUI),yes) TARGET := gvim$(DEBUG_SUFFIX).exe DEFINES += $(DEF_GUI) OBJ += $(GUIOBJ) LFLAGS += -mwindows OUTDIR = gobj$(DEBUG_SUFFIX)$(MZSCHEME_SUFFIX)$(ARCH) +MAIN_TARGET = $(TARGET) else OBJ += $(CUIOBJ) TARGET := vim$(DEBUG_SUFFIX).exe OUTDIR = obj$(DEBUG_SUFFIX)$(MZSCHEME_SUFFIX)$(ARCH) +MAIN_TARGET = $(TARGET) endif ifdef GETTEXT @@ -955,7 +986,7 @@ ifeq (yes, $(MAP)) LFLAGS += -Wl,-Map=$(TARGET).map endif -all: $(TARGET) vimrun.exe xxd/xxd.exe tee/tee.exe install.exe uninstal.exe GvimExt/gvimext.dll +all: $(MAIN_TARGET) vimrun.exe xxd/xxd.exe tee/tee.exe install.exe uninstal.exe GvimExt/gvimext.dll vimrun.exe: vimrun.c $(CC) $(CFLAGS) -o vimrun.exe vimrun.c $(LIB) @@ -966,8 +997,19 @@ install.exe: dosinst.c uninstal.exe: uninstal.c $(CC) $(CFLAGS) -o uninstal.exe uninstal.c $(LIB) +ifeq ($(VIMDLL),yes) +$(TARGET): $(OUTDIR) $(OBJ) + $(LINK) $(CFLAGS) $(LFLAGS) -o $@ $(OBJ) $(LIB) -lole32 -luuid -lgdi32 $(LUA_LIB) $(MZSCHEME_LIBDIR) $(MZSCHEME_LIB) $(PYTHONLIB) $(PYTHON3LIB) $(RUBYLIB) + +$(GVIMEXE): $(OUTDIR) $(EXEOBJG) $(VIMDLLBASE).dll + $(CC) -L. $(EXELFLAGS) -mwindows -o $@ $(EXEOBJG) -l$(VIMDLLBASE) + +$(VIMEXE): $(OUTDIR) $(EXEOBJC) $(VIMDLLBASE).dll + $(CC) -L. $(EXELFLAGS) -o $@ $(EXEOBJC) -l$(VIMDLLBASE) +else $(TARGET): $(OUTDIR) $(OBJ) $(LINK) $(CFLAGS) $(LFLAGS) -o $@ $(OBJ) $(LIB) -lole32 -luuid $(LUA_LIB) $(MZSCHEME_LIBDIR) $(MZSCHEME_LIB) $(PYTHONLIB) $(PYTHON3LIB) $(RUBYLIB) +endif upx: exes upx gvim.exe @@ -996,7 +1038,7 @@ clean: -$(DEL) $(OUTDIR)$(DIRSLASH)*.o -$(DEL) $(OUTDIR)$(DIRSLASH)*.res -rmdir $(OUTDIR) - -$(DEL) $(TARGET) vimrun.exe install.exe uninstal.exe + -$(DEL) $(MAIN_TARGET) vimrun.exe install.exe uninstal.exe -$(DEL) pathdef.c ifdef PERL -$(DEL) if_perl.c @@ -1025,74 +1067,95 @@ CUI_INCL = iscygpty.h $(OUTDIR)/%.o : %.c $(INCL) $(CC) -c $(CFLAGS) $< -o $@ -$(OUTDIR)/vimrc.o: vim.rc version.h gui_w32_rc.h +ifeq ($(VIMDLL),yes) +$(OUTDIR)/vimrcc.o: vim.rc gvim.exe.mnf version.h gui_w32_rc.h vim.ico + $(WINDRES) $(WINDRES_FLAGS) $(DEFINES) -UFEAT_GUI_MSWIN \ + --input-format=rc --output-format=coff -i vim.rc -o $@ + +$(OUTDIR)/vimrcg.o: vim.rc gvim.exe.mnf version.h gui_w32_rc.h vim.ico $(WINDRES) $(WINDRES_FLAGS) $(DEFINES) \ --input-format=rc --output-format=coff -i vim.rc -o $@ +$(OUTDIR)/vimrcd.o: vim.rc version.h gui_w32_rc.h \ + tools.bmp tearoff.bmp vim.ico vim_error.ico \ + vim_alert.ico vim_info.ico vim_quest.ico + $(WINDRES) $(WINDRES_FLAGS) $(DEFINES) -DRCDLL -DVIMDLLBASE=\\\"$(VIMDLLBASE)\\\" \ + --input-format=rc --output-format=coff -i vim.rc -o $@ +else +$(OUTDIR)/vimrc.o: vim.rc gvim.exe.mnf version.h gui_w32_rc.h \ + tools.bmp tearoff.bmp vim.ico vim_error.ico \ + vim_alert.ico vim_info.ico vim_quest.ico + $(WINDRES) $(WINDRES_FLAGS) $(DEFINES) \ + --input-format=rc --output-format=coff -i vim.rc -o $@ +endif + $(OUTDIR): $(MKDIR) $(OUTDIR) $(OUTDIR)/gui_dwrite.o: gui_dwrite.cpp $(INCL) gui_dwrite.h - $(CC) -c $(CFLAGS) $(CXXFLAGS) gui_dwrite.cpp -o $(OUTDIR)/gui_dwrite.o + $(CC) -c $(CFLAGS) $(CXXFLAGS) gui_dwrite.cpp -o $@ $(OUTDIR)/gui.o: gui.c $(INCL) $(GUI_INCL) - $(CC) -c $(CFLAGS) gui.c -o $(OUTDIR)/gui.o + $(CC) -c $(CFLAGS) gui.c -o $@ $(OUTDIR)/beval.o: beval.c $(INCL) $(GUI_INCL) - $(CC) -c $(CFLAGS) beval.c -o $(OUTDIR)/beval.o + $(CC) -c $(CFLAGS) beval.c -o $@ $(OUTDIR)/gui_beval.o: gui_beval.c $(INCL) $(GUI_INCL) - $(CC) -c $(CFLAGS) gui_beval.c -o $(OUTDIR)/gui_beval.o + $(CC) -c $(CFLAGS) gui_beval.c -o $@ $(OUTDIR)/gui_w32.o: gui_w32.c $(INCL) $(GUI_INCL) - $(CC) -c $(CFLAGS) gui_w32.c -o $(OUTDIR)/gui_w32.o + $(CC) -c $(CFLAGS) gui_w32.c -o $@ $(OUTDIR)/if_cscope.o: if_cscope.c $(INCL) if_cscope.h - $(CC) -c $(CFLAGS) if_cscope.c -o $(OUTDIR)/if_cscope.o + $(CC) -c $(CFLAGS) if_cscope.c -o $@ $(OUTDIR)/if_mzsch.o: if_mzsch.c $(INCL) $(MZSCHEME_INCL) $(MZ_EXTRA_DEP) - $(CC) -c $(CFLAGS) if_mzsch.c -o $(OUTDIR)/if_mzsch.o + $(CC) -c $(CFLAGS) if_mzsch.c -o $@ mzscheme_base.c: $(MZSCHEME)/mzc --c-mods mzscheme_base.c ++lib scheme/base # Remove -D__IID_DEFINED__ for newer versions of the w32api $(OUTDIR)/if_ole.o: if_ole.cpp $(INCL) if_ole.h - $(CC) $(CFLAGS) $(CXXFLAGS) -c -o $(OUTDIR)/if_ole.o if_ole.cpp + $(CC) -c $(CFLAGS) $(CXXFLAGS) if_ole.cpp -o $@ auto/if_perl.c: if_perl.xs typemap $(XSUBPP) -prototypes -typemap \ $(PERLTYPEMAP) if_perl.xs -output $@ $(OUTDIR)/if_perl.o: auto/if_perl.c $(INCL) - $(CC) -c $(CFLAGS) auto/if_perl.c -o $(OUTDIR)/if_perl.o + $(CC) -c $(CFLAGS) auto/if_perl.c -o $@ $(OUTDIR)/if_ruby.o: if_ruby.c $(INCL) ifeq (16, $(RUBY)) - $(CC) $(CFLAGS) -U_WIN32 -c -o $(OUTDIR)/if_ruby.o if_ruby.c + $(CC) $(CFLAGS) -U_WIN32 -c -o $@ if_ruby.c endif $(OUTDIR)/iscygpty.o: iscygpty.c $(CUI_INCL) $(CC) -c $(CFLAGS) iscygpty.c -o $(OUTDIR)/iscygpty.o -U_WIN32_WINNT -D_WIN32_WINNT=0x0600 -DUSE_DYNFILEID -DENABLE_STUB_IMPL $(OUTDIR)/main.o: main.c $(INCL) $(CUI_INCL) - $(CC) -c $(CFLAGS) main.c -o $(OUTDIR)/main.o + $(CC) -c $(CFLAGS) main.c -o $@ $(OUTDIR)/netbeans.o: netbeans.c $(INCL) $(NBDEBUG_INCL) $(NBDEBUG_SRC) - $(CC) -c $(CFLAGS) netbeans.c -o $(OUTDIR)/netbeans.o + $(CC) -c $(CFLAGS) netbeans.c -o $@ + +$(OUTDIR)/os_w32exec.o: os_w32exe.c $(INCL) + $(CC) -c $(CFLAGS) -UFEAT_GUI_MSWIN os_w32exe.c -o $@ + +$(OUTDIR)/os_w32exeg.o: os_w32exe.c $(INCL) + $(CC) -c $(CFLAGS) os_w32exe.c -o $@ $(OUTDIR)/os_win32.o: os_win32.c $(INCL) $(MZSCHEME_INCL) - $(CC) -c $(CFLAGS) os_win32.c -o $(OUTDIR)/os_win32.o + $(CC) -c $(CFLAGS) os_win32.c -o $@ $(OUTDIR)/regexp.o: regexp.c regexp_nfa.c $(INCL) - $(CC) -c $(CFLAGS) regexp.c -o $(OUTDIR)/regexp.o + $(CC) -c $(CFLAGS) regexp.c -o $@ $(OUTDIR)/terminal.o: terminal.c $(INCL) $(TERM_DEPS) - $(CC) -c $(CFLAGS) terminal.c -o $(OUTDIR)/terminal.o - -$(OUTDIR)/textprop.o: textprop.c $(INCL) - $(CC) -c $(CFLAGS) textprop.c -o $(OUTDIR)/textprop.o + $(CC) -c $(CFLAGS) terminal.c -o $@ CCCTERM = $(CC) -c $(CFLAGS) -Ilibvterm/include -DINLINE="" \ @@ -1100,50 +1163,13 @@ CCCTERM = $(CC) -c $(CFLAGS) -Ilibvterm/ -DIS_COMBINING_FUNCTION=utf_iscomposing_uint \ -DWCWIDTH_FUNCTION=utf_uint2cells -$(OUTDIR)/encoding.o: libvterm/src/encoding.c $(TERM_DEPS) - $(CCCTERM) libvterm/src/encoding.c -o $@ - -$(OUTDIR)/keyboard.o: libvterm/src/keyboard.c $(TERM_DEPS) - $(CCCTERM) libvterm/src/keyboard.c -o $@ - -$(OUTDIR)/mouse.o: libvterm/src/mouse.c $(TERM_DEPS) - $(CCCTERM) libvterm/src/mouse.c -o $@ +$(OUTDIR)/%.o : libvterm/src/%.c $(TERM_DEPS) + $(CCCTERM) $< -o $@ -$(OUTDIR)/parser.o: libvterm/src/parser.c $(TERM_DEPS) - $(CCCTERM) libvterm/src/parser.c -o $@ - -$(OUTDIR)/pen.o: libvterm/src/pen.c $(TERM_DEPS) - $(CCCTERM) libvterm/src/pen.c -o $@ - -$(OUTDIR)/termscreen.o: libvterm/src/termscreen.c $(TERM_DEPS) - $(CCCTERM) libvterm/src/termscreen.c -o $@ - -$(OUTDIR)/state.o: libvterm/src/state.c $(TERM_DEPS) - $(CCCTERM) libvterm/src/state.c -o $@ -$(OUTDIR)/unicode.o: libvterm/src/unicode.c $(TERM_DEPS) - $(CCCTERM) libvterm/src/unicode.c -o $@ - -$(OUTDIR)/vterm.o: libvterm/src/vterm.c $(TERM_DEPS) - $(CCCTERM) libvterm/src/vterm.c -o $@ - -$(OUTDIR)/xdiffi.o: xdiff/xdiffi.c $(XDIFF_DEPS) - $(CC) -c $(CFLAGS) xdiff/xdiffi.c -o $(OUTDIR)/xdiffi.o - -$(OUTDIR)/xemit.o: xdiff/xemit.c $(XDIFF_DEPS) - $(CC) -c $(CFLAGS) xdiff/xemit.c -o $(OUTDIR)/xemit.o +$(OUTDIR)/%.o : xdiff/%.c $(XDIFF_DEPS) + $(CC) -c $(CFLAGS) $< -o $@ -$(OUTDIR)/xprepare.o: xdiff/xprepare.c $(XDIFF_DEPS) - $(CC) -c $(CFLAGS) xdiff/xprepare.c -o $(OUTDIR)/xprepare.o - -$(OUTDIR)/xutils.o: xdiff/xutils.c $(XDIFF_DEPS) - $(CC) -c $(CFLAGS) xdiff/xutils.c -o $(OUTDIR)/xutils.o - -$(OUTDIR)/xhistogram.o: xdiff/xhistogram.c $(XDIFF_DEPS) - $(CC) -c $(CFLAGS) xdiff/xhistogram.c -o $(OUTDIR)/xhistogram.o - -$(OUTDIR)/xpatience.o: xdiff/xpatience.c $(XDIFF_DEPS) - $(CC) -c $(CFLAGS) xdiff/xpatience.c -o $(OUTDIR)/xpatience.o pathdef.c: $(INCL) ifneq (sh.exe, $(SHELL)) diff --git a/src/Make_mvc.mak b/src/Make_mvc.mak --- a/src/Make_mvc.mak +++ b/src/Make_mvc.mak @@ -40,6 +40,12 @@ # # Terminal support: TERMINAL=yes (default is yes) # +# DLL support (EXPERIMENTAL): VIMDLL=yes (default is no) +# Creates vim{32,64}.dll, and stub gvim.exe and vim.exe. +# The shared codes between the GUI and the console are built into +# the DLL. This reduces the total file size and memory usage. +# Also supports `vim -g` and the `:gui` command. +# # Lua interface: # LUA=[Path to Lua directory] # DYNAMIC_LUA=yes (to load the Lua DLL dynamically) @@ -178,6 +184,10 @@ TARGETOS = WINNT +!if "$(VIMDLL)" == "yes" +GUI = yes +!endif + !ifndef DIRECTX DIRECTX = $(GUI) !endif @@ -185,7 +195,9 @@ DIRECTX = $(GUI) # Select one of eight object code directories, depends on GUI, OLE, DEBUG and # interfaces. # If you change something else, do "make clean" first! -!if "$(GUI)" == "yes" +!if "$(VIMDLL)" == "yes" +OBJDIR = .\ObjD +!elseif "$(GUI)" == "yes" OBJDIR = .\ObjG !else OBJDIR = .\ObjC @@ -410,7 +422,7 @@ CHANNEL = $(GUI) !endif !endif -# GUI sepcific features. +# GUI specific features. !if "$(GUI)" == "yes" # Only allow NETBEANS for a GUI build and CHANNEL. !if "$(NETBEANS)" == "yes" && "$(CHANNEL)" == "yes" @@ -461,7 +473,7 @@ XPM = no XPM_OBJ = $(OBJDIR)/xpm_w32.obj XPM_DEFS = -DFEAT_XPM_W32 !if $(MSVC_MAJOR) >= 14 -# VC14 cannot use a library built by VC12 or eariler, because VC14 uses +# VC14 cannot use a library built by VC12 or earlier, because VC14 uses # Universal CRT. XPM_LIB = $(XPM)\lib-vc14\libXpm.lib !else @@ -566,7 +578,7 @@ CPUARG = # VC<11 generates fp87 code by default ! if $(MSVC_MAJOR) < 11 CPUARG = -# VC>=11 needs explicit insturctions to generate fp87 code +# VC>=11 needs explicit instructions to generate fp87 code ! else CPUARG = /arch:IA32 ! endif @@ -612,6 +624,17 @@ CPUARG = /arch:AVX2 # Pass CPUARG to GvimExt, to avoid using version-dependent defaults MAKEFLAGS_GVIMEXT = $(MAKEFLAGS_GVIMEXT) CPUARG="$(CPUARG)" +!if "$(VIMDLL)" == "yes" +VIMDLLBASE = vim +! if "$(ASSEMBLY_ARCHITECTURE)" == "i386" +VIMDLLBASE = $(VIMDLLBASE)32 +! else +VIMDLLBASE = $(VIMDLLBASE)64 +! endif +! if "$(DEBUG)" == "yes" +VIMDLLBASE = $(VIMDLLBASE)d +! endif +!endif LIBC = DEBUGINFO = /Zi @@ -747,7 +770,6 @@ OBJ = \ $(OUTDIR)\ops.obj \ $(OUTDIR)\option.obj \ $(OUTDIR)\os_mswin.obj \ - $(OUTDIR)\os_w32exe.obj \ $(OUTDIR)\os_win32.obj \ $(OUTDIR)\pathdef.obj \ $(OUTDIR)\popupmnu.obj \ @@ -769,7 +791,15 @@ OBJ = \ $(OUTDIR)\userfunc.obj \ $(OUTDIR)\winclip.obj \ $(OUTDIR)\window.obj \ - $(OUTDIR)\vim.res + +!if "$(VIMDLL)" == "yes" +OBJ = $(OBJ) $(OUTDIR)\os_w32dll.obj $(OUTDIR)\vimd.res +EXEOBJC = $(OUTDIR)\os_w32exec.obj $(OUTDIR)\vimc.res +EXEOBJG = $(OUTDIR)\os_w32exeg.obj $(OUTDIR)\vimg.res +CFLAGS = $(CFLAGS) -DVIMDLL +!else +OBJ = $(OBJ) $(OUTDIR)\os_w32exe.obj $(OUTDIR)\vim.res +!endif !if "$(OLE)" == "yes" CFLAGS = $(CFLAGS) -DFEAT_OLE @@ -800,7 +830,15 @@ OBJ = $(OBJ) $(OUTDIR)\dimm_i.obj $(OUTD SUBSYSTEM = windows CFLAGS = $(CFLAGS) -DFEAT_GUI_MSWIN RCFLAGS = $(RCFLAGS) -DFEAT_GUI_MSWIN +! if "$(VIMDLL)" == "yes" +SUBSYSTEM_CON = console +GVIM = g$(VIM) +CUI_INCL = iscygpty.h +CUI_OBJ = $(OUTDIR)\iscygpty.obj +RCFLAGS = $(RCFLAGS) -DVIMDLL +! else VIM = g$(VIM) +! endif GUI_INCL = \ gui.h GUI_OBJ = \ @@ -839,6 +877,9 @@ XDIFF_DEPS = \ !if "$(SUBSYSTEM_VER)" != "" SUBSYSTEM = $(SUBSYSTEM),$(SUBSYSTEM_VER) SUBSYSTEM_TOOLS = $(SUBSYSTEM_TOOLS),$(SUBSYSTEM_VER) +! if "$(VIMDLL)" != "yes" +SUBSYSTEM_CON = $(SUBSYSTEM_CON),$(SUBSYSTEM_VER) +! endif # Pass SUBSYSTEM_VER to GvimExt and other tools MAKEFLAGS_GVIMEXT = $(MAKEFLAGS_GVIMEXT) SUBSYSTEM_VER=$(SUBSYSTEM_VER) MAKEFLAGS_TOOLS = $(MAKEFLAGS_TOOLS) SUBSYSTEM_VER=$(SUBSYSTEM_VER) @@ -1174,7 +1215,11 @@ CFLAGS = $(CFLAGS) -DFEAT_$(FEATURES) # debug more conveniently (able to look at variables which are in registers) # CFLAGS = $(CFLAGS) /Fd$(OUTDIR)/ $(DEBUGINFO) +!if "$(VIMDLL)" == "yes" +LINK_PDB = /PDB:$(VIMDLLBASE).pdb -debug +!else LINK_PDB = /PDB:$(VIM).pdb -debug +!endif # # End extra feature include @@ -1186,7 +1231,7 @@ CFLAGS_OUTDIR=$(CFLAGS) /Fo$(OUTDIR)/ # Add /opt:ref to remove unreferenced functions and data even when /DEBUG is # added. -conflags = /nologo /subsystem:$(SUBSYSTEM) /opt:ref +conflags = /nologo /opt:ref PATHDEF_SRC = $(OUTDIR)\pathdef.c @@ -1219,7 +1264,13 @@ LINKARGS1 = $(LINKARGS1) /LTCG:STATUS LINKARGS1 = $(LINKARGS1) /HIGHENTROPYVA:NO !endif -all: $(VIM).exe \ +!if "$(VIMDLL)" == "yes" +MAIN_TARGET = $(GVIM).exe $(VIM).exe $(VIMDLLBASE).dll +!else +MAIN_TARGET = $(VIM).exe +!endif + +all: $(MAIN_TARGET) \ vimrun.exe \ install.exe \ uninstal.exe \ @@ -1227,17 +1278,41 @@ all: $(VIM).exe \ tee/tee.exe \ GvimExt/gvimext.dll +!if "$(VIMDLL)" == "yes" + +$(VIMDLLBASE).dll: $(OUTDIR) $(OBJ) $(XDIFF_OBJ) $(GUI_OBJ) $(CUI_OBJ) $(OLE_OBJ) $(OLE_IDL) $(MZSCHEME_OBJ) \ + $(LUA_OBJ) $(PERL_OBJ) $(PYTHON_OBJ) $(PYTHON3_OBJ) $(RUBY_OBJ) $(TCL_OBJ) \ + $(CSCOPE_OBJ) $(TERM_OBJ) $(NETBEANS_OBJ) $(CHANNEL_OBJ) $(XPM_OBJ) \ + version.c version.h + $(CC) $(CFLAGS_OUTDIR) version.c + $(link) $(LINKARGS1) /dll -out:$(VIMDLLBASE).dll $(OBJ) $(XDIFF_OBJ) $(GUI_OBJ) $(CUI_OBJ) $(OLE_OBJ) \ + $(LUA_OBJ) $(MZSCHEME_OBJ) $(PERL_OBJ) $(PYTHON_OBJ) $(PYTHON3_OBJ) $(RUBY_OBJ) \ + $(TCL_OBJ) $(CSCOPE_OBJ) $(TERM_OBJ) $(NETBEANS_OBJ) $(CHANNEL_OBJ) \ + $(XPM_OBJ) $(OUTDIR)\version.obj $(LINKARGS2) + +$(GVIM).exe: $(OUTDIR) $(EXEOBJG) $(VIMDLLBASE).dll + $(link) $(LINKARGS1) /subsystem:$(SUBSYSTEM) -out:$(GVIM).exe $(EXEOBJG) $(VIMDLLBASE).lib $(LIBC) + if exist $(GVIM).exe.manifest mt.exe -nologo -manifest $(GVIM).exe.manifest -updateresource:$(GVIM).exe;1 + +$(VIM).exe: $(OUTDIR) $(EXEOBJC) $(VIMDLLBASE).dll + $(link) $(LINKARGS1) /subsystem:$(SUBSYSTEM_CON) -out:$(VIM).exe $(EXEOBJC) $(VIMDLLBASE).lib $(LIBC) + if exist $(VIM).exe.manifest mt.exe -nologo -manifest $(VIM).exe.manifest -updateresource:$(VIM).exe;1 + +!else + $(VIM).exe: $(OUTDIR) $(OBJ) $(XDIFF_OBJ) $(GUI_OBJ) $(CUI_OBJ) $(OLE_OBJ) $(OLE_IDL) $(MZSCHEME_OBJ) \ $(LUA_OBJ) $(PERL_OBJ) $(PYTHON_OBJ) $(PYTHON3_OBJ) $(RUBY_OBJ) $(TCL_OBJ) \ $(CSCOPE_OBJ) $(TERM_OBJ) $(NETBEANS_OBJ) $(CHANNEL_OBJ) $(XPM_OBJ) \ version.c version.h $(CC) $(CFLAGS_OUTDIR) version.c - $(link) $(LINKARGS1) -out:$(VIM).exe $(OBJ) $(XDIFF_OBJ) $(GUI_OBJ) $(CUI_OBJ) $(OLE_OBJ) \ + $(link) $(LINKARGS1) /subsystem:$(SUBSYSTEM) -out:$(VIM).exe $(OBJ) $(XDIFF_OBJ) $(GUI_OBJ) $(CUI_OBJ) $(OLE_OBJ) \ $(LUA_OBJ) $(MZSCHEME_OBJ) $(PERL_OBJ) $(PYTHON_OBJ) $(PYTHON3_OBJ) $(RUBY_OBJ) \ $(TCL_OBJ) $(CSCOPE_OBJ) $(TERM_OBJ) $(NETBEANS_OBJ) $(CHANNEL_OBJ) \ $(XPM_OBJ) $(OUTDIR)\version.obj $(LINKARGS2) if exist $(VIM).exe.manifest mt.exe -nologo -manifest $(VIM).exe.manifest -updateresource:$(VIM).exe;1 +!endif + $(VIM): $(VIM).exe $(OUTDIR): @@ -1287,6 +1362,15 @@ clean: - if exist $(VIM).pdb del $(VIM).pdb - if exist $(VIM).map del $(VIM).map - if exist $(VIM).ncb del $(VIM).ncb +!if "$(VIMDLL)" == "yes" + - if exist $(GVIM).exe del $(GVIM).exe + - if exist $(GVIM).map del $(GVIM).map + - if exist $(VIMDLLBASE).dll del $(VIMDLLBASE).dll + - if exist $(VIMDLLBASE).lib del $(VIMDLLBASE).lib + - if exist $(VIMDLLBASE).exp del $(VIMDLLBASE).exp + - if exist $(VIMDLLBASE).pdb del $(VIMDLLBASE).pdb + - if exist $(VIMDLLBASE).map del $(VIMDLLBASE).map +!endif - if exist vimrun.exe del vimrun.exe - if exist install.exe del install.exe - if exist uninstal.exe del uninstal.exe @@ -1334,21 +1418,15 @@ testclean: ########################################################################### # Create a default rule for transforming .c files to .obj files in $(OUTDIR) -# Batch compilation is supported by nmake 1.62 (part of VS 5.0) and later) -!IF "$(_NMAKE_VER)" == "" -.c{$(OUTDIR)/}.obj: -!ELSE .c{$(OUTDIR)/}.obj:: -!ENDIF + $(CC) $(CFLAGS_OUTDIR) $< + +# Create a default rule for xdiff. +{xdiff/}.c{$(OUTDIR)/}.obj:: $(CC) $(CFLAGS_OUTDIR) $< # Create a default rule for transforming .cpp files to .obj files in $(OUTDIR) -# Batch compilation is supported by nmake 1.62 (part of VS 5.0) and later) -!IF "$(_NMAKE_VER)" == "" -.cpp{$(OUTDIR)/}.obj: -!ELSE .cpp{$(OUTDIR)/}.obj:: -!ENDIF $(CC) $(CFLAGS_OUTDIR) $< $(OUTDIR)/arabic.obj: $(OUTDIR) arabic.c $(INCL) @@ -1376,22 +1454,16 @@ testclean: $(OUTDIR)/diff.obj: $(OUTDIR) diff.c $(INCL) $(OUTDIR)/xdiffi.obj: $(OUTDIR) xdiff/xdiffi.c $(XDIFF_DEPS) - $(CC) $(CFLAGS_OUTDIR) xdiff/xdiffi.c $(OUTDIR)/xemit.obj: $(OUTDIR) xdiff/xemit.c $(XDIFF_DEPS) - $(CC) $(CFLAGS_OUTDIR) xdiff/xemit.c $(OUTDIR)/xprepare.obj: $(OUTDIR) xdiff/xprepare.c $(XDIFF_DEPS) - $(CC) $(CFLAGS_OUTDIR) xdiff/xprepare.c $(OUTDIR)/xutils.obj: $(OUTDIR) xdiff/xutils.c $(XDIFF_DEPS) - $(CC) $(CFLAGS_OUTDIR) xdiff/xutils.c $(OUTDIR)/xhistogram.obj: $(OUTDIR) xdiff/xhistogram.c $(XDIFF_DEPS) - $(CC) $(CFLAGS_OUTDIR) xdiff/xhistogram.c $(OUTDIR)/xpatience.obj: $(OUTDIR) xdiff/xpatience.c $(XDIFF_DEPS) - $(CC) $(CFLAGS_OUTDIR) xdiff/xpatience.c $(OUTDIR)/digraph.obj: $(OUTDIR) digraph.c $(INCL) @@ -1516,8 +1588,16 @@ lib$(MZSCHEME_MAIN_LIB)$(MZSCHEME_VER).l $(OUTDIR)/os_win32.obj: $(OUTDIR) os_win32.c $(INCL) $(MZSCHEME_INCL) +$(OUTDIR)/os_w32dll.obj: $(OUTDIR) os_w32dll.c + $(OUTDIR)/os_w32exe.obj: $(OUTDIR) os_w32exe.c $(INCL) +$(OUTDIR)/os_w32exec.obj: $(OUTDIR) os_w32exe.c $(INCL) + $(CC) $(CFLAGS:-DFEAT_GUI_MSWIN=) /Fo$@ os_w32exe.c + +$(OUTDIR)/os_w32exeg.obj: $(OUTDIR) os_w32exe.c $(INCL) + $(CC) $(CFLAGS) /Fo$@ os_w32exe.c + $(OUTDIR)/pathdef.obj: $(OUTDIR) $(PATHDEF_SRC) $(INCL) $(CC) $(CFLAGS_OUTDIR) $(PATHDEF_SRC) @@ -1560,10 +1640,25 @@ lib$(MZSCHEME_MAIN_LIB)$(MZSCHEME_VER).l $(OUTDIR)/xpm_w32.obj: $(OUTDIR) xpm_w32.c $(CC) $(CFLAGS_OUTDIR) $(XPM_INC) xpm_w32.c -$(OUTDIR)/vim.res: $(OUTDIR) vim.rc gvim.exe.mnf version.h tools.bmp \ - tearoff.bmp vim.ico vim_error.ico \ +!if "$(VIMDLL)" == "yes" +$(OUTDIR)/vimc.res: $(OUTDIR) vim.rc gvim.exe.mnf version.h gui_w32_rc.h \ + vim.ico + $(RC) /nologo /l 0x409 /Fo$@ $(RCFLAGS:-DFEAT_GUI_MSWIN=) vim.rc + +$(OUTDIR)/vimg.res: $(OUTDIR) vim.rc gvim.exe.mnf version.h gui_w32_rc.h \ + vim.ico + $(RC) /nologo /l 0x409 /Fo$@ $(RCFLAGS) vim.rc + +$(OUTDIR)/vimd.res: $(OUTDIR) vim.rc version.h gui_w32_rc.h \ + tools.bmp tearoff.bmp vim.ico vim_error.ico \ vim_alert.ico vim_info.ico vim_quest.ico - $(RC) /nologo /l 0x409 /Fo$(OUTDIR)/vim.res $(RCFLAGS) vim.rc + $(RC) /nologo /l 0x409 /Fo$@ $(RCFLAGS) -DRCDLL -DVIMDLLBASE=\"$(VIMDLLBASE)\" vim.rc +!else +$(OUTDIR)/vim.res: $(OUTDIR) vim.rc gvim.exe.mnf version.h gui_w32_rc.h \ + tools.bmp tearoff.bmp vim.ico vim_error.ico \ + vim_alert.ico vim_info.ico vim_quest.ico + $(RC) /nologo /l 0x409 /Fo$@ $(RCFLAGS) vim.rc +!endif iid_ole.c if_ole.h vim.tlb: if_ole.idl midl /nologo /error none /proxy nul /iid iid_ole.c /tlb vim.tlb \ @@ -1583,32 +1678,27 @@ CCCTERM = $(CC) $(CFLAGS) -Ilibvterm/inc -DWCWIDTH_FUNCTION=utf_uint2cells \ -D_CRT_SECURE_NO_WARNINGS +# Create a default rule for libvterm. +{libvterm/src/}.c{$(OUTDIR)/}.obj:: + $(CCCTERM) -Fo$(OUTDIR)/ $< + $(OUTDIR)/encoding.obj: $(OUTDIR) libvterm/src/encoding.c $(TERM_DEPS) - $(CCCTERM) -Fo$@ libvterm/src/encoding.c $(OUTDIR)/keyboard.obj: $(OUTDIR) libvterm/src/keyboard.c $(TERM_DEPS) - $(CCCTERM) -Fo$@ libvterm/src/keyboard.c $(OUTDIR)/mouse.obj: $(OUTDIR) libvterm/src/mouse.c $(TERM_DEPS) - $(CCCTERM) -Fo$@ libvterm/src/mouse.c $(OUTDIR)/parser.obj: $(OUTDIR) libvterm/src/parser.c $(TERM_DEPS) - $(CCCTERM) -Fo$@ libvterm/src/parser.c $(OUTDIR)/pen.obj: $(OUTDIR) libvterm/src/pen.c $(TERM_DEPS) - $(CCCTERM) -Fo$@ libvterm/src/pen.c $(OUTDIR)/termscreen.obj: $(OUTDIR) libvterm/src/termscreen.c $(TERM_DEPS) - $(CCCTERM) -Fo$@ libvterm/src/termscreen.c $(OUTDIR)/state.obj: $(OUTDIR) libvterm/src/state.c $(TERM_DEPS) - $(CCCTERM) -Fo$@ libvterm/src/state.c $(OUTDIR)/unicode.obj: $(OUTDIR) libvterm/src/unicode.c $(TERM_DEPS) - $(CCCTERM) -Fo$@ libvterm/src/unicode.c $(OUTDIR)/vterm.obj: $(OUTDIR) libvterm/src/vterm.c $(TERM_DEPS) - $(CCCTERM) -Fo$@ libvterm/src/vterm.c # $CFLAGS may contain backslashes and double quotes, escape them both. diff --git a/src/channel.c b/src/channel.c --- a/src/channel.c +++ b/src/channel.c @@ -5319,7 +5319,7 @@ job_still_useful(job_T *job) return job_need_end_check(job) || job_channel_still_useful(job); } -#if defined(GUI_MAY_FORK) || defined(PROTO) +#if defined(GUI_MAY_FORK) || defined(GUI_MAY_SPAWN) || defined(PROTO) /* * Return TRUE when there is any running job that we care about. */ diff --git a/src/evalfunc.c b/src/evalfunc.c --- a/src/evalfunc.c +++ b/src/evalfunc.c @@ -4201,11 +4201,13 @@ f_foreground(typval_T *argvars UNUSED, t { #ifdef FEAT_GUI if (gui.in_use) + { gui_mch_set_foreground(); -#else -# ifdef MSWIN + return; + } +#endif +#if defined(MSWIN) && (!defined(FEAT_GUI) || defined(VIMDLL)) win32_set_foreground(); -# endif #endif } diff --git a/src/ex_cmds.c b/src/ex_cmds.c --- a/src/ex_cmds.c +++ b/src/ex_cmds.c @@ -1537,7 +1537,7 @@ do_shell( int flags) /* may be SHELL_DOOUT when output is redirected */ { buf_T *buf; -#ifndef FEAT_GUI_MSWIN +#if !defined(FEAT_GUI_MSWIN) || defined(VIMDLL) int save_nwr; #endif #ifdef MSWIN @@ -1636,32 +1636,37 @@ do_shell( * Otherwise there is probably text on the screen that the user wants * to read before redrawing, so call wait_return(). */ -#ifndef FEAT_GUI_MSWIN - if (cmd == NULL +#if !defined(FEAT_GUI_MSWIN) || defined(VIMDLL) +# ifdef VIMDLL + if (!gui.in_use) +# endif + { + if (cmd == NULL # ifdef MSWIN - || (keep_termcap && !need_wait_return) + || (keep_termcap && !need_wait_return) # endif - ) - { - if (msg_silent == 0) - redraw_later_clear(); - need_wait_return = FALSE; - } - else - { - /* - * If we switch screens when starttermcap() is called, we really - * want to wait for "hit return to continue". - */ - save_nwr = no_wait_return; - if (swapping_screen()) - no_wait_return = FALSE; + ) + { + if (msg_silent == 0) + redraw_later_clear(); + need_wait_return = FALSE; + } + else + { + /* + * If we switch screens when starttermcap() is called, we + * really want to wait for "hit return to continue". + */ + save_nwr = no_wait_return; + if (swapping_screen()) + no_wait_return = FALSE; # ifdef AMIGA - wait_return(term_console ? -1 : msg_silent == 0); /* see below */ + wait_return(term_console ? -1 : msg_silent == 0); // see below # else - wait_return(msg_silent == 0); + wait_return(msg_silent == 0); # endif - no_wait_return = save_nwr; + no_wait_return = save_nwr; + } } #endif /* FEAT_GUI_MSWIN */ diff --git a/src/ex_docmd.c b/src/ex_docmd.c --- a/src/ex_docmd.c +++ b/src/ex_docmd.c @@ -7756,7 +7756,10 @@ ex_winpos(exarg_T *eap) if (*arg == NUL) { # if defined(FEAT_GUI) || defined(MSWIN) -# ifdef FEAT_GUI +# ifdef VIMDLL + if (gui.in_use ? gui_mch_get_winpos(&x, &y) != FAIL : + mch_get_winpos(&x, &y) != FAIL) +# elif defined(FEAT_GUI) if (gui.in_use && gui_mch_get_winpos(&x, &y) != FAIL) # else if (mch_get_winpos(&x, &y) != FAIL) @@ -7789,13 +7792,12 @@ ex_winpos(exarg_T *eap) gui_win_x = x; gui_win_y = y; } -# ifdef HAVE_TGETENT +# if defined(HAVE_TGETENT) || defined(VIMDLL) else # endif -# else -# ifdef MSWIN +# endif +# if defined(MSWIN) && (!defined(FEAT_GUI) || defined(VIMDLL)) mch_set_winpos(x, y); -# endif # endif # ifdef HAVE_TGETENT if (*T_CWP) @@ -8239,8 +8241,11 @@ ex_redraw(exarg_T *eap) if (need_maketitle) maketitle(); #endif -#if defined(MSWIN) && !defined(FEAT_GUI_MSWIN) - resize_console_buf(); +#if defined(MSWIN) && (!defined(FEAT_GUI_MSWIN) || defined(VIMDLL)) +# ifdef VIMDLL + if (!gui.in_use) +# endif + resize_console_buf(); #endif RedrawingDisabled = r; p_lz = p; diff --git a/src/feature.h b/src/feature.h --- a/src/feature.h +++ b/src/feature.h @@ -712,7 +712,8 @@ * there is no terminal version, and on Windows we can't figure out how to * fork one off with :gui. */ -#if defined(FEAT_GUI_MSWIN) || (defined(FEAT_GUI_MAC) && !defined(MACOS_X_DARWIN)) +#if (defined(FEAT_GUI_MSWIN) && !defined(VIMDLL)) \ + || (defined(FEAT_GUI_MAC) && !defined(MACOS_X_DARWIN)) # define ALWAYS_USE_GUI #endif @@ -1138,8 +1139,8 @@ * mouse shape Adjust the shape of the mouse pointer to the mode. */ #ifdef FEAT_NORMAL -/* MS-DOS console and Win32 console can change cursor shape */ -# if defined(MSWIN) && !defined(FEAT_GUI_MSWIN) +// Win32 console can change cursor shape +# if defined(MSWIN) && (!defined(FEAT_GUI_MSWIN) || defined(VIMDLL)) # define MCH_CURSOR_SHAPE # endif # if defined(FEAT_GUI_MSWIN) || defined(FEAT_GUI_MOTIF) \ @@ -1263,7 +1264,8 @@ * +balloon_eval_term Allow balloon expression evaluation in the terminal. */ #if defined(FEAT_HUGE) && defined(FEAT_TIMERS) && \ - (defined(UNIX) || defined(VMS) || (defined(MSWIN) && !defined(FEAT_GUI_MSWIN))) + (defined(UNIX) || defined(VMS) || \ + (defined(MSWIN) && (!defined(FEAT_GUI_MSWIN) || defined(VIMDLL)))) # define FEAT_BEVAL_TERM #endif @@ -1317,6 +1319,6 @@ /* * +vtp: Win32 virtual console. */ -#if !defined(FEAT_GUI) && defined(MSWIN) +#if (!defined(FEAT_GUI) || defined(VIMDLL)) && defined(MSWIN) # define FEAT_VTP #endif diff --git a/src/fileio.c b/src/fileio.c --- a/src/fileio.c +++ b/src/fileio.c @@ -792,7 +792,10 @@ readfile( if (!is_not_a_term()) { #ifndef ALWAYS_USE_GUI - mch_msg(_("Vim: Reading from stdin...\n")); +# ifdef VIMDLL + if (!gui.in_use) +# endif + mch_msg(_("Vim: Reading from stdin...\n")); #endif #ifdef FEAT_GUI /* Also write a message in the GUI window, if there is one. */ diff --git a/src/getchar.c b/src/getchar.c --- a/src/getchar.c +++ b/src/getchar.c @@ -1626,7 +1626,11 @@ vgetc(void) #if defined(FEAT_GUI_MSWIN) && defined(FEAT_MENU) && defined(FEAT_TEAROFF) // Handle K_TEAROFF here, the caller of vgetc() doesn't need to // know that a menu was torn off - if (c == K_TEAROFF) + if ( +# ifdef VIMDLL + gui.in_use && +# endif + c == K_TEAROFF) { char_u name[200]; int i; @@ -3113,6 +3117,7 @@ fix_input_buffer(char_u *buf, int len) p += 2; i -= 2; } +# ifndef MSWIN /* When the GUI is not used CSI needs to be escaped. */ else if (!gui.in_use && p[0] == CSI) { @@ -3122,12 +3127,16 @@ fix_input_buffer(char_u *buf, int len) *p = (int)KE_CSI; len += 2; } +# endif else #endif if (p[0] == NUL || (p[0] == K_SPECIAL /* timeout may generate K_CURSORHOLD */ && (i < 2 || p[1] != KS_EXTRA || p[2] != (int)KE_CURSORHOLD) -#if defined(MSWIN) && !defined(FEAT_GUI) +#if defined(MSWIN) && (!defined(FEAT_GUI) || defined(VIMDLL)) +# ifdef VIMDLL + && !gui.in_use +# endif /* Win32 console passes modifiers */ && (i < 2 || p[1] != KS_MODIFIER) #endif @@ -5232,20 +5241,21 @@ check_map( #if defined(MSWIN) || defined(MACOS_X) -#define VIS_SEL (VISUAL+SELECTMODE) /* abbreviation */ +# define VIS_SEL (VISUAL+SELECTMODE) /* abbreviation */ /* * Default mappings for some often used keys. */ -static struct initmap +struct initmap { char_u *arg; int mode; -} initmappings[] = +}; + +# ifdef FEAT_GUI_MSWIN +/* Use the Windows (CUA) keybindings. (GUI) */ +static struct initmap initmappings[] = { -#if defined(MSWIN) - /* Use the Windows (CUA) keybindings. */ -# ifdef FEAT_GUI /* paste, copy and cut */ {(char_u *)" \"*P", NORMAL}, {(char_u *)" \"-d\"*P", VIS_SEL}, @@ -5255,7 +5265,13 @@ static struct initmap {(char_u *)" \"*d", VIS_SEL}, {(char_u *)" \"*d", VIS_SEL}, /* Missing: CTRL-C (cancel) and CTRL-V (block selection) */ -# else +}; +# endif + +# if defined(MSWIN) && (!defined(FEAT_GUI) || defined(VIMDLL)) +/* Use the Windows (CUA) keybindings. (Console) */ +static struct initmap cinitmappings[] = +{ {(char_u *)"\316w ", NORMAL+VIS_SEL}, {(char_u *)"\316w ", INSERT+CMDLINE}, {(char_u *)"\316u ", NORMAL+VIS_SEL}, @@ -5278,10 +5294,12 @@ static struct initmap {(char_u *)"\316\327 d", VIS_SEL}, /* SHIFT-Del is d */ {(char_u *)"\316\330 d", VIS_SEL}, /* CTRL-Del is d */ # endif +}; # endif -#endif - -#if defined(MACOS_X) + +# if defined(MACOS_X) +static struct initmap initmappings[] = +{ /* Use the Standard MacOS binding. */ /* paste, copy and cut */ {(char_u *)" \"*P", NORMAL}, @@ -5290,8 +5308,8 @@ static struct initmap {(char_u *)" \"*y", VIS_SEL}, {(char_u *)" \"*d", VIS_SEL}, {(char_u *)" \"-d", VIS_SEL}, -#endif }; +# endif # undef VIS_SEL #endif @@ -5305,8 +5323,20 @@ init_mappings(void) #if defined(MSWIN) || defined(MACOS_X) int i; +# if defined(MSWIN) && (!defined(FEAT_GUI_MSWIN) || defined(VIMDLL)) +# ifdef VIMDLL + if (!gui.starting) +# endif + { + for (i = 0; + i < (int)(sizeof(cinitmappings) / sizeof(struct initmap)); ++i) + add_map(cinitmappings[i].arg, cinitmappings[i].mode); + } +# endif +# if defined(FEAT_GUI_MSWIN) || defined(MACOS_X) for (i = 0; i < (int)(sizeof(initmappings) / sizeof(struct initmap)); ++i) add_map(initmappings[i].arg, initmappings[i].mode); +# endif #endif } diff --git a/src/globals.h b/src/globals.h --- a/src/globals.h +++ b/src/globals.h @@ -1442,7 +1442,7 @@ EXTERN char e_nesting[] INIT(= N_("E22: EXTERN char e_noalt[] INIT(= N_("E23: No alternate file")); EXTERN char e_noabbr[] INIT(= N_("E24: No such abbreviation")); EXTERN char e_nobang[] INIT(= N_("E477: No ! allowed")); -#ifndef FEAT_GUI +#if !defined(FEAT_GUI) || defined(VIMDLL) EXTERN char e_nogvim[] INIT(= N_("E25: GUI cannot be used: Not enabled at compile time")); #endif #ifndef FEAT_RIGHTLEFT @@ -1645,6 +1645,7 @@ EXTERN int *eval_lavars_used INIT(= NULL #ifdef MSWIN EXTERN int ctrl_break_was_pressed INIT(= FALSE); +EXTERN HINSTANCE g_hinst INIT(= NULL); #endif #ifdef FEAT_TEXT_PROP diff --git a/src/gui.c b/src/gui.c --- a/src/gui.c +++ b/src/gui.c @@ -65,10 +65,13 @@ static int disable_flush = 0; /* If > 0, * recursive call. */ void -gui_start(void) +gui_start(char_u *arg UNUSED) { char_u *old_term; static int recursive = 0; +#ifdef GUI_MAY_SPAWN + char *msg = NULL; +#endif old_term = vim_strsave(T_NAME); @@ -98,6 +101,22 @@ gui_start(void) } else #endif +#ifdef GUI_MAY_SPAWN + if (gui.dospawn +# ifdef EXPERIMENTAL_GUI_CMD + && gui.dofork +# endif + && !vim_strchr(p_go, GO_FORG) + && !anyBufIsChanged() +# ifdef FEAT_JOB_CHANNEL + && !job_any_running() +# endif + ) + { + msg = gui_mch_do_spawn(arg); + } + else +#endif { #ifdef FEAT_GUI_GTK /* If there is 'f' in 'guioptions' and specify -g argument, @@ -125,6 +144,10 @@ gui_start(void) #ifdef FEAT_TITLE set_title_defaults(); /* set 'title' and 'icon' again */ #endif +#if defined(GUI_MAY_SPAWN) && defined(EXPERIMENTAL_GUI_CMD) + if (msg) + emsg(msg); +#endif } vim_free(old_term); @@ -431,7 +454,7 @@ gui_init_check(void) gui.scrollbar_width = gui.scrollbar_height = SB_DEFAULT_WIDTH; gui.prev_wrap = -1; -#ifdef ALWAYS_USE_GUI +#if defined(ALWAYS_USE_GUI) || defined(VIMDLL) result = OK; #else # ifdef FEAT_GUI_GTK @@ -4948,12 +4971,22 @@ ex_gui(exarg_T *eap) } if (!gui.in_use) { +#if defined(VIMDLL) && !defined(EXPERIMENTAL_GUI_CMD) + emsg(_(e_nogvim)); + return; +#else /* Clear the command. Needed for when forking+exiting, to avoid part * of the argument ending up after the shell prompt. */ msg_clr_eos_force(); - gui_start(); -#ifdef FEAT_JOB_CHANNEL +# ifdef GUI_MAY_SPAWN + if (!ends_excmd(*eap->arg)) + gui_start(eap->arg); + else +# endif + gui_start(NULL); +# ifdef FEAT_JOB_CHANNEL channel_gui_register_all(); +# endif #endif } if (!ends_excmd(*eap->arg)) diff --git a/src/gui.h b/src/gui.h --- a/src/gui.h +++ b/src/gui.h @@ -237,6 +237,16 @@ typedef long guicolor_T; /* handle f # endif #endif +#ifdef VIMDLL +// Use spawn when GUI is starting. +# define GUI_MAY_SPAWN + +// Uncomment the next definition if you want to use the `:gui` command on +// Windows. It uses `:mksession` to inherit the session from vim.exe to +// gvim.exe. So, it doesn't work perfectly. (EXPERIMENTAL) +//# define EXPERIMENTAL_GUI_CMD +#endif + typedef struct Gui { int in_focus; /* Vim has input focus */ @@ -245,6 +255,9 @@ typedef struct Gui int shell_created; /* Has the shell been created yet? */ int dying; /* Is vim dying? Then output to terminal */ int dofork; /* Use fork() when GUI is starting */ +#ifdef GUI_MAY_SPAWN + int dospawn; /* Use spawn() when GUI is starting */ +#endif int dragged_sb; /* Which scrollbar being dragged, if any? */ win_T *dragged_wp; /* Which WIN's sb being dragged, if any? */ int pointer_hidden; /* Is the mouse pointer hidden? */ diff --git a/src/gui_gtk_x11.c b/src/gui_gtk_x11.c --- a/src/gui_gtk_x11.c +++ b/src/gui_gtk_x11.c @@ -2315,75 +2315,6 @@ sm_client_check_changed_any(GnomeClient } /* - * Generate a script that can be used to restore the current editing session. - * Save the value of v:this_session before running :mksession in order to make - * automagic session save fully transparent. Return TRUE on success. - */ - static int -write_session_file(char_u *filename) -{ - char_u *escaped_filename; - char *mksession_cmdline; - unsigned int save_ssop_flags; - int failed; - - /* - * Build an ex command line to create a script that restores the current - * session if executed. Escape the filename to avoid nasty surprises. - */ - escaped_filename = vim_strsave_escaped(filename, escape_chars); - if (escaped_filename == NULL) - return FALSE; - mksession_cmdline = g_strconcat("mksession ", (char *)escaped_filename, - NULL); - vim_free(escaped_filename); - - /* - * Use a reasonable hardcoded set of 'sessionoptions' flags to avoid - * unpredictable effects when the session is saved automatically. Also, - * we definitely need SSOP_GLOBALS to be able to restore v:this_session. - * Don't use SSOP_BUFFERS to prevent the buffer list from becoming - * enormously large if the GNOME session feature is used regularly. - */ - save_ssop_flags = ssop_flags; - ssop_flags = (SSOP_BLANK|SSOP_CURDIR|SSOP_FOLDS|SSOP_GLOBALS - |SSOP_HELP|SSOP_OPTIONS|SSOP_WINSIZE|SSOP_TABPAGES); - - do_cmdline_cmd((char_u *)"let Save_VV_this_session = v:this_session"); - failed = (do_cmdline_cmd((char_u *)mksession_cmdline) == FAIL); - do_cmdline_cmd((char_u *)"let v:this_session = Save_VV_this_session"); - do_unlet((char_u *)"Save_VV_this_session", TRUE); - - ssop_flags = save_ssop_flags; - g_free(mksession_cmdline); - - /* - * Reopen the file and append a command to restore v:this_session, - * as if this save never happened. This is to avoid conflicts with - * the user's own sessions. FIXME: It's probably less hackish to add - * a "stealth" flag to 'sessionoptions' -- gotta ask Bram. - */ - if (!failed) - { - FILE *fd; - - fd = open_exfile(filename, TRUE, APPENDBIN); - - failed = (fd == NULL - || put_line(fd, "let v:this_session = Save_VV_this_session") == FAIL - || put_line(fd, "unlet Save_VV_this_session") == FAIL); - - if (fd != NULL && fclose(fd) != 0) - failed = TRUE; - - if (failed) - mch_remove(filename); - } - - return !failed; -} - -/* * "save_yourself" signal handler. Initiate an interaction to ask the user * for confirmation if necessary. Save the current editing session and tell * the session manager how to restart Vim. diff --git a/src/gui_w32.c b/src/gui_w32.c --- a/src/gui_w32.c +++ b/src/gui_w32.c @@ -320,7 +320,6 @@ static int s_findrep_is_find; // TRUE f // for find/replace dialog #endif -static HINSTANCE s_hinst = NULL; #if !defined(FEAT_GUI) static #endif @@ -1424,7 +1423,7 @@ gui_mch_create_scrollbar( 10, /* Any value will do for now */ 10, /* Any value will do for now */ s_hwnd, NULL, - s_hinst, NULL); + g_hinst, NULL); } /* @@ -2237,15 +2236,6 @@ gui_mch_draw_menubar(void) } #endif /*FEAT_MENU*/ -#ifndef PROTO -void -_cdecl -SaveInst(HINSTANCE hInst) -{ - s_hinst = hInst; -} -#endif - /* * Return the RGB value of a pixel as a long. */ @@ -4839,6 +4829,141 @@ ole_error(char *arg) } #endif +#if defined(GUI_MAY_SPAWN) || defined(PROTO) + static char * +gvim_error(void) +{ + char *msg = _("E988: GUI cannot be used. Cannot execute gvim.exe."); + + if (starting) + { + mch_errmsg(msg); + mch_errmsg("\n"); + mch_exit(2); + } + return msg; +} + + char * +gui_mch_do_spawn(char_u *arg) +{ + int len; +# if defined(FEAT_SESSION) && defined(EXPERIMENTAL_GUI_CMD) + char_u *session = NULL; + LPWSTR tofree1 = NULL; +# endif + WCHAR name[MAX_PATH]; + LPWSTR cmd, newcmd = NULL, p, warg, tofree2 = NULL; + STARTUPINFOW si = {sizeof(si)}; + PROCESS_INFORMATION pi; + + if (!GetModuleFileNameW(g_hinst, name, MAX_PATH)) + goto error; + p = wcsrchr(name, L'\\'); + if (p == NULL) + goto error; + // Replace the executable name from vim(d).exe to gvim(d).exe. +# ifdef DEBUG + wcscpy(p + 1, L"gvimd.exe"); +# else + wcscpy(p + 1, L"gvim.exe"); +# endif + +# if defined(FEAT_SESSION) && defined(EXPERIMENTAL_GUI_CMD) + if (starting) +# endif + { + // Pass the command line to the new process. + p = GetCommandLineW(); + // Skip 1st argument. + while (*p && *p != L' ' && *p != L'\t') + { + if (*p == L'"') + { + while (*p && *p != L'"') + ++p; + if (*p) + ++p; + } + else + ++p; + } + cmd = p; + } +# if defined(FEAT_SESSION) && defined(EXPERIMENTAL_GUI_CMD) + else + { + // Create a session file and pass it to the new process. + LPWSTR wsession; + char_u *savebg; + int ret; + + session = vim_tempname('s', FALSE); + if (session == NULL) + goto error; + savebg = p_bg; + p_bg = vim_strsave((char_u *)"light"); // Set 'bg' to "light". + ret = write_session_file(session); + vim_free(p_bg); + p_bg = savebg; + if (!ret) + goto error; + wsession = enc_to_utf16(session, NULL); + if (wsession == NULL) + goto error; + len = (int)wcslen(wsession) * 2 + 27 + 1; + cmd = (LPWSTR)alloc(len * (int)sizeof(WCHAR)); + if (cmd == NULL) + { + vim_free(wsession); + goto error; + } + tofree1 = cmd; + _snwprintf(cmd, len, L" -S \"%s\" -c \"call delete('%s')\"", + wsession, wsession); + vim_free(wsession); + } +# endif + + // Check additional arguments to the `:gui` command. + if (arg != NULL) + { + warg = enc_to_utf16(arg, NULL); + if (warg == NULL) + goto error; + tofree2 = warg; + } + else + warg = L""; + + // Set up the new command line. + len = (int)wcslen(name) + (int)wcslen(cmd) + (int)wcslen(warg) + 4; + newcmd = (LPWSTR)alloc(len * (int)sizeof(WCHAR)); + if (newcmd == NULL) + goto error; + _snwprintf(newcmd, len, L"\"%s\"%s %s", name, cmd, warg); + + // Spawn a new GUI process. + if (!CreateProcessW(NULL, newcmd, NULL, NULL, TRUE, 0, + NULL, NULL, &si, &pi)) + goto error; + CloseHandle(pi.hProcess); + CloseHandle(pi.hThread); + mch_exit(0); + +error: +# if defined(FEAT_SESSION) && defined(EXPERIMENTAL_GUI_CMD) + if (session) + mch_remove(session); + vim_free(session); + vim_free(tofree1); +# endif + vim_free(newcmd); + vim_free(tofree2); + return gvim_error(); +} +#endif + /* * Parse the GUI related command-line arguments. Any arguments used are * deleted from argv, and *argc is decremented accordingly. This is called @@ -4957,7 +5082,7 @@ gui_mch_init(void) * Load the tearoff bitmap */ #ifdef FEAT_TEAROFF - s_htearbitmap = LoadBitmap(s_hinst, "IDB_TEAROFF"); + s_htearbitmap = LoadBitmap(g_hinst, "IDB_TEAROFF"); #endif gui.scrollbar_width = GetSystemMetrics(SM_CXVSCROLL); @@ -4971,13 +5096,13 @@ gui_mch_init(void) /* First try using the wide version, so that we can use any title. * Otherwise only characters in the active codepage will work. */ - if (GetClassInfoW(s_hinst, szVimWndClassW, &wndclassw) == 0) + if (GetClassInfoW(g_hinst, szVimWndClassW, &wndclassw) == 0) { wndclassw.style = CS_DBLCLKS; wndclassw.lpfnWndProc = _WndProc; wndclassw.cbClsExtra = 0; wndclassw.cbWndExtra = 0; - wndclassw.hInstance = s_hinst; + wndclassw.hInstance = g_hinst; wndclassw.hIcon = LoadIcon(wndclassw.hInstance, "IDR_VIM"); wndclassw.hCursor = LoadCursor(NULL, IDC_ARROW); wndclassw.hbrBackground = s_brush; @@ -5011,7 +5136,7 @@ gui_mch_init(void) 100, // Any value will do 100, // Any value will do vim_parent_hwnd, NULL, - s_hinst, NULL); + g_hinst, NULL); #ifdef HAVE_TRY_EXCEPT } __except(EXCEPTION_EXECUTE_HANDLER) @@ -5043,7 +5168,7 @@ gui_mch_init(void) 100, /* Any value will do */ 100, /* Any value will do */ NULL, NULL, - s_hinst, NULL); + g_hinst, NULL); if (s_hwnd != NULL && win_socket_id != 0) { SetParent(s_hwnd, (HWND)win_socket_id); @@ -5062,13 +5187,13 @@ gui_mch_init(void) #endif /* Create the text area window */ - if (GetClassInfoW(s_hinst, szTextAreaClassW, &wndclassw) == 0) + if (GetClassInfoW(g_hinst, szTextAreaClassW, &wndclassw) == 0) { wndclassw.style = CS_OWNDC; wndclassw.lpfnWndProc = _TextAreaWndProc; wndclassw.cbClsExtra = 0; wndclassw.cbWndExtra = 0; - wndclassw.hInstance = s_hinst; + wndclassw.hInstance = g_hinst; wndclassw.hIcon = NULL; wndclassw.hCursor = LoadCursor(NULL, IDC_ARROW); wndclassw.hbrBackground = NULL; @@ -5086,7 +5211,7 @@ gui_mch_init(void) 100, // Any value will do for now 100, // Any value will do for now s_hwnd, NULL, - s_hinst, NULL); + g_hinst, NULL); if (s_textArea == NULL) return FAIL; @@ -6640,8 +6765,11 @@ gui_mch_dialog( #ifndef NO_CONSOLE /* Don't output anything in silent mode ("ex -s") */ - if (silent_mode) - return dfltbutton; /* return default option */ +# ifdef VIMDLL + if (!(gui.in_use || gui.starting)) +# endif + if (silent_mode) + return dfltbutton; /* return default option */ #endif if (s_hwnd == NULL) @@ -7050,7 +7178,7 @@ gui_mch_dialog( /* show the dialog box modally and get a return value */ nchar = (int)DialogBoxIndirect( - s_hinst, + g_hinst, (LPDLGTEMPLATE)pdlgtemplate, s_hwnd, (DLGPROC)dialog_callback); @@ -7644,7 +7772,7 @@ gui_mch_tearoff( /* show modelessly */ the_menu->tearoff_handle = CreateDialogIndirectParam( - s_hinst, + g_hinst, (LPDLGTEMPLATE)pdlgtemplate, s_hwnd, (DLGPROC)tearoff_callback, @@ -7689,7 +7817,7 @@ initialise_toolbar(void) WS_CHILD | TBSTYLE_TOOLTIPS | TBSTYLE_FLAT, 4000, //any old big number 31, //number of images in initial bitmap - s_hinst, + g_hinst, IDR_TOOLBAR1, // id of initial bitmap NULL, 0, // initial number of buttons @@ -7790,7 +7918,7 @@ initialise_tabline(void) s_tabhwnd = CreateWindow(WC_TABCONTROL, "Vim tabline", WS_CHILD|TCS_FOCUSNEVER|TCS_TOOLTIPS, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, - CW_USEDEFAULT, s_hwnd, NULL, s_hinst, NULL); + CW_USEDEFAULT, s_hwnd, NULL, g_hinst, NULL); s_tabline_wndproc = SubclassWindow(s_tabhwnd, tabline_wndproc); gui.tabline_height = TABLINE_HEIGHT; @@ -8245,7 +8373,7 @@ make_tooltip(BalloonEval *beval, char *t beval->balloon = CreateWindowExW(WS_EX_TOPMOST, TOOLTIPS_CLASSW, NULL, WS_POPUP | TTS_NOPREFIX | TTS_ALWAYSTIP, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, CW_USEDEFAULT, - beval->target, NULL, s_hinst, NULL); + beval->target, NULL, g_hinst, NULL); SetWindowPos(beval->balloon, HWND_TOPMOST, 0, 0, 0, 0, SWP_NOMOVE | SWP_NOSIZE | SWP_NOACTIVATE); diff --git a/src/if_mzsch.c b/src/if_mzsch.c --- a/src/if_mzsch.c +++ b/src/if_mzsch.c @@ -822,7 +822,7 @@ static EventLoopTimerRef timer_id = NULL static EventLoopTimerUPP timerUPP; #endif -#ifndef FEAT_GUI_MSWIN /* Win32 console and Unix */ +#if !defined(FEAT_GUI_MSWIN) || defined(VIMDLL) /* Win32 console and Unix */ void mzvim_check_threads(void) { @@ -1775,9 +1775,11 @@ get_option(void *data, int argc, Scheme_ case -2: MZ_GC_UNREG(); raise_vim_exn(_("hidden option")); + /*NOTREACHED*/ case -3: MZ_GC_UNREG(); raise_vim_exn(_("unknown option")); + /*NOTREACHED*/ } /* unreachable */ return scheme_void; diff --git a/src/main.c b/src/main.c --- a/src/main.c +++ b/src/main.c @@ -19,7 +19,7 @@ # include #endif -#if defined(MSWIN) && !defined(FEAT_GUI_MSWIN) +#if defined(MSWIN) && (!defined(FEAT_GUI_MSWIN) || defined(VIMDLL)) # include "iscygpty.h" #endif @@ -95,6 +95,9 @@ static char_u *start_dir = NULL; /* curr static int has_dash_c_arg = FALSE; +# ifdef VIMDLL +__declspec(dllexport) +# endif int # ifdef MSWIN # ifdef __BORLANDC__ @@ -174,6 +177,11 @@ main #endif common_init(¶ms); +#ifdef VIMDLL + // Check if the current executable file is for the GUI subsystem. + gui.starting = mch_is_gui_executable(); +#endif + #ifdef FEAT_CLIENTSERVER /* * Do the client-server stuff, unless "--servername ''" was used. @@ -292,7 +300,8 @@ main * For GTK we can't be sure, but when started from the desktop it doesn't * make sense to try using a terminal. */ -#if defined(ALWAYS_USE_GUI) || defined(FEAT_GUI_X11) || defined(FEAT_GUI_GTK) +#if defined(ALWAYS_USE_GUI) || defined(FEAT_GUI_X11) || defined(FEAT_GUI_GTK) \ + || defined(VIMDLL) if (gui.starting # ifdef FEAT_GUI_GTK && !isatty(2) @@ -542,7 +551,7 @@ vim_main2(void) putchar('\n'); #endif - gui_start(); /* will set full_screen to TRUE */ + gui_start(NULL); /* will set full_screen to TRUE */ TIME_MSG("starting GUI"); /* When running "evim" or "gvim -y" we need the menus, exit if we @@ -851,8 +860,11 @@ vim_main2(void) } #endif -#if defined(MSWIN) && !defined(FEAT_GUI_MSWIN) - mch_set_winsize_now(); /* Allow winsize changes from now on */ +#if defined(MSWIN) && (!defined(FEAT_GUI_MSWIN) || defined(VIMDLL)) +# ifdef VIMDLL + if (!gui.in_use) +# endif + mch_set_winsize_now(); /* Allow winsize changes from now on */ #endif #if defined(FEAT_GUI) @@ -1761,7 +1773,15 @@ parse_command_name(mparm_T *parmp) #ifdef FEAT_GUI ++initstr; #endif +#ifdef GUI_MAY_SPAWN + gui.dospawn = FALSE; // No need to spawn a new process. +#endif } +#ifdef GUI_MAY_SPAWN + else + gui.dospawn = TRUE; // Not "gvim". Need to spawn gvim.exe. +#endif + if (STRNICMP(initstr, "view", 4) == 0) { @@ -2181,7 +2201,7 @@ command_line_scan(mparm_T *parmp) case 'v': /* "-v" Vi-mode (as if called "vi") */ exmode_active = 0; -#ifdef FEAT_GUI +#if defined(FEAT_GUI) && !defined(VIMDLL) gui.starting = FALSE; /* don't start GUI */ #endif break; @@ -2558,8 +2578,12 @@ check_tty(mparm_T *parmp) exit(1); } #endif -#if defined(MSWIN) && !defined(FEAT_GUI_MSWIN) - if (is_cygpty_used()) +#if defined(MSWIN) && (!defined(FEAT_GUI_MSWIN) || defined(VIMDLL)) + if ( +# ifdef VIMDLL + !gui.starting && +# endif + is_cygpty_used()) { # if defined(HAVE_BIND_TEXTDOMAIN_CODESET) \ && defined(FEAT_GETTEXT) @@ -3440,8 +3464,13 @@ usage(void) main_msg(_("--echo-wid\t\tMake gvim echo the Window ID on stdout")); #endif #ifdef FEAT_GUI_MSWIN - main_msg(_("-P \tOpen Vim inside parent application")); - main_msg(_("--windowid \tOpen Vim inside another win32 widget")); +# ifdef VIMDLL + if (gui.starting) +# endif + { + main_msg(_("-P \tOpen Vim inside parent application")); + main_msg(_("--windowid \tOpen Vim inside another win32 widget")); + } #endif #ifdef FEAT_GUI_GNOME diff --git a/src/mbyte.c b/src/mbyte.c --- a/src/mbyte.c +++ b/src/mbyte.c @@ -4392,7 +4392,7 @@ enc_alias_search(char_u *name) # include #endif -#ifndef FEAT_GUI_MSWIN +#if !defined(FEAT_GUI_MSWIN) || defined(VIMDLL) /* * Get the canonicalized encoding from the specified locale string "locale" * or from the environment variables LC_ALL, LC_CTYPE and LANG. diff --git a/src/memline.c b/src/memline.c --- a/src/memline.c +++ b/src/memline.c @@ -4798,7 +4798,7 @@ findswapname( // the messages displayed in the Vim window when // loading a session from the .gvimrc file. if (gui.starting && !gui.in_use) - gui_start(); + gui_start(NULL); #endif // Show info about the existing swap file. attention_message(buf, fname); diff --git a/src/message.c b/src/message.c --- a/src/message.c +++ b/src/message.c @@ -2563,8 +2563,12 @@ t_puts( msg_use_printf(void) { return (!msg_check_screen() -#if defined(MSWIN) && !defined(FEAT_GUI_MSWIN) +#if defined(MSWIN) && (!defined(FEAT_GUI_MSWIN) || defined(VIMDLL)) +# ifdef VIMDLL + || (!gui.in_use && !termcap_active) +# else || !termcap_active +# endif #endif || (swapping_screen() && !termcap_active) ); @@ -2940,15 +2944,10 @@ do_more_prompt(int typed_char) # undef mch_msg #endif -/* - * Give an error message. To be used when the screen hasn't been initialized - * yet. When stderr can't be used, collect error messages until the GUI has - * started and they can be displayed in a message box. - */ - void -mch_errmsg(char *str) +#if defined(MSWIN) && (!defined(FEAT_GUI_MSWIN) || defined(VIMDLL)) + static void +mch_errmsg_c(char *str) { -#if defined(MSWIN) && !defined(FEAT_GUI_MSWIN) int len = (int)STRLEN(str); DWORD nwrite = 0; DWORD mode = 0; @@ -2966,34 +2965,57 @@ mch_errmsg(char *str) { fprintf(stderr, "%s", str); } -#else +} +#endif + +/* + * Give an error message. To be used when the screen hasn't been initialized + * yet. When stderr can't be used, collect error messages until the GUI has + * started and they can be displayed in a message box. + */ + void +mch_errmsg(char *str) +{ +#if !defined(MSWIN) || defined(FEAT_GUI_MSWIN) int len; - -# if (defined(UNIX) || defined(FEAT_GUI)) && !defined(ALWAYS_USE_GUI) +#endif + +#if (defined(UNIX) || defined(FEAT_GUI)) && (!defined(ALWAYS_USE_GUI) || !defined(VIMDLL)) /* On Unix use stderr if it's a tty. * When not going to start the GUI also use stderr. * On Mac, when started from Finder, stderr is the console. */ if ( -# ifdef UNIX -# ifdef MACOS_X +# ifdef UNIX +# ifdef MACOS_X (isatty(2) && strcmp("/dev/console", ttyname(2)) != 0) -# else +# else isatty(2) -# endif -# ifdef FEAT_GUI - || -# endif # endif # ifdef FEAT_GUI + || +# endif +# endif +# ifdef FEAT_GUI !(gui.in_use || gui.starting) -# endif +# endif ) { fprintf(stderr, "%s", str); return; } +#endif + +#if defined(MSWIN) && (!defined(FEAT_GUI_MSWIN) || defined(VIMDLL)) +# ifdef VIMDLL + if (!(gui.in_use || gui.starting)) # endif - + { + mch_errmsg_c(str); + return; + } +#endif + +#if !defined(MSWIN) || defined(FEAT_GUI_MSWIN) /* avoid a delay for a message that isn't there */ emsg_on_display = FALSE; @@ -3028,15 +3050,10 @@ mch_errmsg(char *str) #endif } -/* - * Give a message. To be used when the screen hasn't been initialized yet. - * When there is no tty, collect messages until the GUI has started and they - * can be displayed in a message box. - */ - void -mch_msg(char *str) +#if defined(MSWIN) && (!defined(FEAT_GUI_MSWIN) || defined(VIMDLL)) + static void +mch_msg_c(char *str) { -#if defined(MSWIN) && !defined(FEAT_GUI_MSWIN) int len = (int)STRLEN(str); DWORD nwrite = 0; DWORD mode; @@ -3055,32 +3072,53 @@ mch_msg(char *str) { printf("%s", str); } -#else -# if (defined(UNIX) || defined(FEAT_GUI)) && !defined(ALWAYS_USE_GUI) +} +#endif + +/* + * Give a message. To be used when the screen hasn't been initialized yet. + * When there is no tty, collect messages until the GUI has started and they + * can be displayed in a message box. + */ + void +mch_msg(char *str) +{ +#if (defined(UNIX) || defined(FEAT_GUI)) && (!defined(ALWAYS_USE_GUI) || !defined(VIMDLL)) /* On Unix use stdout if we have a tty. This allows "vim -h | more" and * uses mch_errmsg() when started from the desktop. * When not going to start the GUI also use stdout. * On Mac, when started from Finder, stderr is the console. */ if ( -# ifdef UNIX -# ifdef MACOS_X +# ifdef UNIX +# ifdef MACOS_X (isatty(2) && strcmp("/dev/console", ttyname(2)) != 0) -# else +# else isatty(2) -# endif -# ifdef FEAT_GUI +# endif +# ifdef FEAT_GUI || -# endif # endif -# ifdef FEAT_GUI +# endif +# ifdef FEAT_GUI !(gui.in_use || gui.starting) -# endif +# endif ) { printf("%s", str); return; } +#endif + +#if defined(MSWIN) && (!defined(FEAT_GUI_MSWIN) || defined(VIMDLL)) +# ifdef VIMDLL + if (!(gui.in_use || gui.starting)) # endif + { + mch_msg_c(str); + return; + } +#endif +#if !defined(MSWIN) || defined(FEAT_GUI_MSWIN) mch_errmsg(str); #endif } diff --git a/src/misc2.c b/src/misc2.c --- a/src/misc2.c +++ b/src/misc2.c @@ -4650,3 +4650,80 @@ build_argv_from_list(list_T *l, char *** } # endif #endif + +#if defined(FEAT_SESSION) || defined(PROTO) +/* + * Generate a script that can be used to restore the current editing session. + * Save the value of v:this_session before running :mksession in order to make + * automagic session save fully transparent. Return TRUE on success. + */ + int +write_session_file(char_u *filename) +{ + char_u *escaped_filename; + char *mksession_cmdline; + unsigned int save_ssop_flags; + int failed; + + /* + * Build an ex command line to create a script that restores the current + * session if executed. Escape the filename to avoid nasty surprises. + */ + escaped_filename = vim_strsave_escaped(filename, escape_chars); + if (escaped_filename == NULL) + return FALSE; + mksession_cmdline = (char *)alloc(10 + (int)STRLEN(escaped_filename) + 1); + if (mksession_cmdline == NULL) + { + vim_free(escaped_filename); + return FALSE; + } + strcpy(mksession_cmdline, "mksession "); + STRCAT(mksession_cmdline, escaped_filename); + vim_free(escaped_filename); + + /* + * Use a reasonable hardcoded set of 'sessionoptions' flags to avoid + * unpredictable effects when the session is saved automatically. Also, + * we definitely need SSOP_GLOBALS to be able to restore v:this_session. + * Don't use SSOP_BUFFERS to prevent the buffer list from becoming + * enormously large if the GNOME session feature is used regularly. + */ + save_ssop_flags = ssop_flags; + ssop_flags = (SSOP_BLANK|SSOP_CURDIR|SSOP_FOLDS|SSOP_GLOBALS + |SSOP_HELP|SSOP_OPTIONS|SSOP_WINSIZE|SSOP_TABPAGES); + + do_cmdline_cmd((char_u *)"let Save_VV_this_session = v:this_session"); + failed = (do_cmdline_cmd((char_u *)mksession_cmdline) == FAIL); + do_cmdline_cmd((char_u *)"let v:this_session = Save_VV_this_session"); + do_unlet((char_u *)"Save_VV_this_session", TRUE); + + ssop_flags = save_ssop_flags; + vim_free(mksession_cmdline); + + /* + * Reopen the file and append a command to restore v:this_session, + * as if this save never happened. This is to avoid conflicts with + * the user's own sessions. FIXME: It's probably less hackish to add + * a "stealth" flag to 'sessionoptions' -- gotta ask Bram. + */ + if (!failed) + { + FILE *fd; + + fd = open_exfile(filename, TRUE, APPENDBIN); + + failed = (fd == NULL + || put_line(fd, "let v:this_session = Save_VV_this_session") == FAIL + || put_line(fd, "unlet Save_VV_this_session") == FAIL); + + if (fd != NULL && fclose(fd) != 0) + failed = TRUE; + + if (failed) + mch_remove(filename); + } + + return !failed; +} +#endif diff --git a/src/normal.c b/src/normal.c --- a/src/normal.c +++ b/src/normal.c @@ -5394,8 +5394,11 @@ nv_clear(cmdarg_T *cap) # endif #endif redraw_later(CLEAR); -#if defined(MSWIN) && !defined(FEAT_GUI_MSWIN) - resize_console_buf(); +#if defined(MSWIN) && (!defined(FEAT_GUI_MSWIN) || defined(VIMDLL)) +# ifdef VIMDLL + if (!gui.in_use) +# endif + resize_console_buf(); #endif } } diff --git a/src/option.c b/src/option.c --- a/src/option.c +++ b/src/option.c @@ -3321,9 +3321,7 @@ set_init_1(int clean_arg) if (((p = mch_getenv((char_u *)"SHELL")) != NULL && *p != NUL) #if defined(MSWIN) || ((p = mch_getenv((char_u *)"COMSPEC")) != NULL && *p != NUL) -# ifdef MSWIN || ((p = (char_u *)default_shell()) != NULL && *p != NUL) -# endif #endif ) set_string_default_esc("sh", p, TRUE); @@ -3673,10 +3671,14 @@ set_init_1(int clean_arg) } #endif -#if defined(MSWIN) && !defined(FEAT_GUI) +#if defined(MSWIN) && (!defined(FEAT_GUI) || defined(VIMDLL)) /* Win32 console: When GetACP() returns a different value from * GetConsoleCP() set 'termencoding'. */ - if (GetACP() != GetConsoleCP()) + if ( +# ifdef VIMDLL + (!gui.in_use && !gui.starting) && +# endif + GetACP() != GetConsoleCP()) { char buf[50]; @@ -6856,11 +6858,14 @@ did_set_string_option( { out_str(T_ME); redraw_later(CLEAR); -#if defined(MSWIN) && !defined(FEAT_GUI_MSWIN) +#if defined(MSWIN) && (!defined(FEAT_GUI_MSWIN) || defined(VIMDLL)) /* Since t_me has been set, this probably means that the user * wants to use this as default colors. Need to reset default * background/foreground colors. */ - mch_set_normal_colors(); +# ifdef VIMDLL + if (!gui.in_use && !gui.starting) +# endif + mch_set_normal_colors(); #endif } if (varp == &T_BE && termcap_active) @@ -8838,7 +8843,11 @@ set_bool_option( { # ifdef FEAT_VTP /* Do not turn on 'tgc' when 24-bit colors are not supported. */ - if (!has_vtp_working()) + if ( +# ifdef VIMDLL + !gui.in_use && !gui.starting && +# endif + !has_vtp_working()) { p_tgc = 0; return N_("E954: 24-bit colors are not supported on this environment"); diff --git a/src/os_mswin.c b/src/os_mswin.c --- a/src/os_mswin.c +++ b/src/os_mswin.c @@ -129,7 +129,7 @@ typedef void VOID; FILE* fdDump = NULL; #endif -#ifndef FEAT_GUI_MSWIN +#if !defined(FEAT_GUI_MSWIN) || defined(VIMDLL) extern char g_szOrigTitle[]; #endif @@ -195,6 +195,17 @@ int _stricoll(char *a, char *b) #endif +#ifndef PROTO +/* + * Save the instance handle of the exe/dll. + */ + void +SaveInst(HINSTANCE hInst) +{ + g_hinst = hInst; +} +#endif + #if defined(FEAT_GUI_MSWIN) || defined(PROTO) /* * GUI version of mch_exit(). @@ -202,7 +213,7 @@ int _stricoll(char *a, char *b) * Careful: mch_exit() may be called before mch_init()! */ void -mch_exit(int r) +mch_exit_g(int r) { exiting = TRUE; @@ -262,8 +273,12 @@ mch_early_init(void) mch_input_isatty(void) { #ifdef FEAT_GUI_MSWIN - return OK; /* GUI always has a tty */ -#else +# ifdef VIMDLL + if (gui.in_use) +# endif + return TRUE; /* GUI always has a tty */ +#endif +#if !defined(FEAT_GUI_MSWIN) || defined(VIMDLL) if (isatty(read_cmd_fd)) return TRUE; return FALSE; @@ -280,8 +295,15 @@ mch_settitle( char_u *icon) { # ifdef FEAT_GUI_MSWIN - gui_mch_settitle(title, icon); -# else +# ifdef VIMDLL + if (gui.in_use) +# endif + { + gui_mch_settitle(title, icon); + return; + } +# endif +# if !defined(FEAT_GUI_MSWIN) || defined(VIMDLL) if (title != NULL) { WCHAR *wp = enc_to_utf16(title, NULL); @@ -307,8 +329,11 @@ mch_settitle( void mch_restore_title(int which UNUSED) { -#ifndef FEAT_GUI_MSWIN - SetConsoleTitle(g_szOrigTitle); +#if !defined(FEAT_GUI_MSWIN) || defined(VIMDLL) +# ifdef VIMDLL + if (!gui.in_use) +# endif + SetConsoleTitle(g_szOrigTitle); #endif } @@ -554,7 +579,7 @@ vim_stat(const char *name, stat_T *stp) return n; } -#if defined(FEAT_GUI_MSWIN) || defined(PROTO) +#if (defined(FEAT_GUI_MSWIN) && !defined(VIMDLL)) || defined(PROTO) void mch_settmode(int tmode UNUSED) { @@ -596,44 +621,47 @@ mch_suspend(void) #if defined(USE_MCH_ERRMSG) || defined(PROTO) -#ifdef display_errors -# undef display_errors -#endif - -#ifdef FEAT_GUI +# ifdef display_errors +# undef display_errors +# endif + /* * Display the saved error message(s). */ void display_errors(void) { +# ifdef FEAT_GUI char *p; - if (error_ga.ga_data != NULL) +# ifdef VIMDLL + if (gui.in_use || gui.starting) +# endif { - /* avoid putting up a message box with blanks only */ - for (p = (char *)error_ga.ga_data; *p; ++p) - if (!isspace(*p)) - { - (void)gui_mch_dialog( + if (error_ga.ga_data != NULL) + { + /* avoid putting up a message box with blanks only */ + for (p = (char *)error_ga.ga_data; *p; ++p) + if (!isspace(*p)) + { + (void)gui_mch_dialog( gui.starting ? VIM_INFO : VIM_ERROR, gui.starting ? (char_u *)_("Message") : (char_u *)_("Error"), (char_u *)p, (char_u *)_("&Ok"), 1, NULL, FALSE); - break; - } - ga_clear(&error_ga); + break; + } + ga_clear(&error_ga); + } + return; } +# endif +# if !defined(FEAT_GUI) || defined(VIMDLL) + FlushFileBuffers(GetStdHandle(STD_ERROR_HANDLE)); +# endif } -#else - void -display_errors(void) -{ - FlushFileBuffers(GetStdHandle(STD_ERROR_HANDLE)); -} -#endif #endif @@ -717,7 +745,7 @@ mch_chdir(char *path) } -#ifdef FEAT_GUI_MSWIN +#if defined(FEAT_GUI_MSWIN) && !defined(VIMDLL) /* * return non-zero if a character is available */ @@ -955,7 +983,7 @@ Trace( #endif //_DEBUG -#if !defined(FEAT_GUI) || defined(PROTO) +#if !defined(FEAT_GUI) || defined(VIMDLL) || defined(PROTO) # ifdef FEAT_TITLE extern HWND g_hWnd; /* This is in os_win32.c. */ # endif @@ -1121,8 +1149,11 @@ PrintDlgProc( VIM_CLEAR(prt_name); } EnableMenuItem(GetSystemMenu(hDlg, FALSE), SC_CLOSE, MF_GRAYED); -#ifndef FEAT_GUI - BringWindowToTop(s_hwnd); +#if !defined(FEAT_GUI) || defined(VIMDLL) +# ifdef VIMDLL + if (!gui.in_use) +# endif + BringWindowToTop(s_hwnd); #endif return TRUE; @@ -1155,7 +1186,7 @@ AbortProc(HDC hdcPrn UNUSED, int iCode U return !*bUserAbort; } -#ifndef FEAT_GUI +#if !defined(FEAT_GUI) || defined(VIMDLL) static UINT_PTR CALLBACK PrintHookProc( @@ -1349,8 +1380,11 @@ mch_print_init(prt_settings_T *psettings bUserAbort = &(psettings->user_abort); vim_memset(&prt_dlg, 0, sizeof(PRINTDLGW)); prt_dlg.lStructSize = sizeof(PRINTDLGW); -#ifndef FEAT_GUI - GetConsoleHwnd(); /* get value of s_hwnd */ +#if !defined(FEAT_GUI) || defined(VIMDLL) +# ifdef VIMDLL + if (!gui.in_use) +# endif + GetConsoleHwnd(); /* get value of s_hwnd */ #endif prt_dlg.hwndOwner = s_hwnd; prt_dlg.Flags = PD_NOPAGENUMS | PD_NOSELECTION | PD_RETURNDC; @@ -1359,12 +1393,17 @@ mch_print_init(prt_settings_T *psettings prt_dlg.hDevMode = stored_dm; prt_dlg.hDevNames = stored_devn; prt_dlg.lCustData = stored_nCopies; // work around bug in print dialog -#ifndef FEAT_GUI - /* - * Use hook to prevent console window being sent to back - */ - prt_dlg.lpfnPrintHook = PrintHookProc; - prt_dlg.Flags |= PD_ENABLEPRINTHOOK; +#if !defined(FEAT_GUI) || defined(VIMDLL) +# ifdef VIMDLL + if (!gui.in_use) +# endif + { + /* + * Use hook to prevent console window being sent to back + */ + prt_dlg.lpfnPrintHook = PrintHookProc; + prt_dlg.Flags |= PD_ENABLEPRINTHOOK; + } #endif prt_dlg.Flags |= stored_nFlags; } @@ -1374,8 +1413,12 @@ mch_print_init(prt_settings_T *psettings * never show dialog if we are running over telnet */ if (forceit -#ifndef FEAT_GUI +#if !defined(FEAT_GUI) || defined(VIMDLL) +# ifdef VIMDLL + || (!gui.in_use && !term_console) +# else || !term_console +# endif #endif ) { @@ -1548,7 +1591,7 @@ mch_print_begin(prt_settings_T *psetting char szBuffer[300]; WCHAR *wp; - hDlgPrint = CreateDialog(GetModuleHandle(NULL), TEXT("PrintDlgBox"), + hDlgPrint = CreateDialog(g_hinst, TEXT("PrintDlgBox"), prt_dlg.hwndOwner, PrintDlgProc); SetAbortProc(prt_dlg.hDC, AbortProc); wsprintf(szBuffer, _("Printing '%s'"), gettail(psettings->jobname)); @@ -1568,7 +1611,10 @@ mch_print_begin(prt_settings_T *psetting #ifdef FEAT_GUI /* Give focus back to main window (when using MDI). */ - SetFocus(s_hwnd); +# ifdef VIMDLL + if (gui.in_use) +# endif + SetFocus(s_hwnd); #endif return (ret > 0); @@ -1927,16 +1973,14 @@ mch_resolve_path(char_u *fname, int repa } #endif -#if (defined(FEAT_EVAL) && !defined(FEAT_GUI)) || defined(PROTO) +#if (defined(FEAT_EVAL) && (!defined(FEAT_GUI) || defined(VIMDLL))) || defined(PROTO) /* * Bring ourselves to the foreground. Does work if the OS doesn't allow it. */ void win32_set_foreground(void) { -# ifndef FEAT_GUI GetConsoleHwnd(); /* get value of s_hwnd */ -# endif if (s_hwnd != 0) SetForegroundWindow(s_hwnd); } @@ -2078,8 +2122,11 @@ Messaging_WndProc(HWND hwnd, UINT msg, W # ifdef FEAT_GUI /* Wake up the main GUI loop. */ - if (s_hwnd != 0) - PostMessage(s_hwnd, WM_NULL, 0, 0); +# ifdef VIMDLL + if (gui.in_use) +# endif + if (s_hwnd != 0) + PostMessage(s_hwnd, WM_NULL, 0, 0); # endif return 1; @@ -2145,8 +2192,11 @@ Messaging_WndProc(HWND hwnd, UINT msg, W { /* When the message window is activated (brought to the foreground), * this actually applies to the text window. */ -#ifndef FEAT_GUI - GetConsoleHwnd(); /* get value of s_hwnd */ +#if !defined(FEAT_GUI) || defined(VIMDLL) +# ifdef VIMDLL + if (!gui.in_use) +# endif + GetConsoleHwnd(); /* get value of s_hwnd */ #endif if (s_hwnd != 0) { @@ -2166,7 +2216,6 @@ Messaging_WndProc(HWND hwnd, UINT msg, W serverInitMessaging(void) { WNDCLASS wndclass; - HINSTANCE s_hinst; /* Clean up on exit */ atexit(CleanUpMessaging); @@ -2174,12 +2223,11 @@ serverInitMessaging(void) /* Register a window class - we only really care * about the window procedure */ - s_hinst = (HINSTANCE)GetModuleHandle(0); wndclass.style = 0; wndclass.lpfnWndProc = Messaging_WndProc; wndclass.cbClsExtra = 0; wndclass.cbWndExtra = 0; - wndclass.hInstance = s_hinst; + wndclass.hInstance = g_hinst; wndclass.hIcon = NULL; wndclass.hCursor = NULL; wndclass.hbrBackground = NULL; @@ -2194,7 +2242,7 @@ serverInitMessaging(void) WS_POPUPWINDOW | WS_CAPTION, CW_USEDEFAULT, CW_USEDEFAULT, 100, 100, NULL, NULL, - s_hinst, NULL); + g_hinst, NULL); } /* Used by serverSendToVim() to find an alternate server name. */ @@ -2744,12 +2792,11 @@ static const LOGFONTW s_lfDefault = L"Fixedsys" /* see _ReadVimIni */ }; -/* Initialise the "current height" to -12 (same as s_lfDefault) just - * in case the user specifies a font in "guifont" with no size before a font - * with an explicit size has been set. This defaults the size to this value - * (-12 equates to roughly 9pt). - */ -int current_font_height = -12; /* also used in gui_w48.c */ +// Initialise the "current height" to -12 (same as s_lfDefault) just +// in case the user specifies a font in "guifont" with no size before a font +// with an explicit size has been set. This defaults the size to this value +// (-12 equates to roughly 9pt). +int current_font_height = -12; // also used in gui_w32.c /* Convert a string representing a point size into pixels. The string should * be a positive decimal number, with an optional decimal point (eg, "12", or diff --git a/src/os_w32dll.c b/src/os_w32dll.c new file mode 100644 --- /dev/null +++ b/src/os_w32dll.c @@ -0,0 +1,27 @@ +/* vi:set ts=8 sts=4 sw=4 noet: + * + * VIM - Vi IMproved by Bram Moolenaar + * + * Do ":help uganda" in Vim to read copying and usage conditions. + * Do ":help credits" in Vim to see a list of people who contributed. + * See README.txt for an overview of the Vim source code. + */ +/* + * Windows GUI: main program (DLL) entry point: + * + * Ron Aaron wrote this and the DLL support code. + * Adapted by Ken Takata. + */ +#ifndef WIN32_LEAN_AND_MEAN +# define WIN32_LEAN_AND_MEAN +#endif +#include + +void SaveInst(HINSTANCE hInst); + +BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) +{ + if (fdwReason == DLL_PROCESS_ATTACH) + SaveInst(hinstDLL); + return TRUE; +} diff --git a/src/os_w32exe.c b/src/os_w32exe.c --- a/src/os_w32exe.c +++ b/src/os_w32exe.c @@ -22,8 +22,11 @@ #endif // cproto doesn't create a prototype for VimMain() +#ifdef VIMDLL +__declspec(dllimport) +#endif int _cdecl VimMain(int argc, char **argv); -#ifdef FEAT_GUI +#ifndef VIMDLL void _cdecl SaveInst(HINSTANCE hInst); #endif @@ -40,8 +43,12 @@ wWinMain( wmain(int argc UNUSED, wchar_t **argv UNUSED) # endif { -# ifdef FEAT_GUI +# ifndef VIMDLL +# ifdef FEAT_GUI SaveInst(hInstance); +# else + SaveInst(GetModuleHandleW(NULL)); +# endif # endif VimMain(0, NULL); diff --git a/src/os_win32.c b/src/os_win32.c --- a/src/os_win32.c +++ b/src/os_win32.c @@ -151,7 +151,7 @@ typedef int LPSECURITY_ATTRIBUTES; # define wcsicmp(a, b) wcscmpi((a), (b)) #endif -#ifndef FEAT_GUI_MSWIN +#if !defined(FEAT_GUI_MSWIN) || defined(VIMDLL) /* Win32 Console handles for input and output */ static HANDLE g_hConIn = INVALID_HANDLE_VALUE; static HANDLE g_hConOut = INVALID_HANDLE_VALUE; @@ -179,7 +179,8 @@ static void gotoxy(unsigned x, unsigned static void standout(void); static int s_cursor_visible = TRUE; static int did_create_conin = FALSE; -#else +#endif +#ifdef FEAT_GUI_MSWIN static int s_dont_use_vimrun = TRUE; static int need_vimrun_warning = FALSE; static char *vimrun_path = "vimrun "; @@ -193,7 +194,7 @@ static int conpty_working = 0; static int conpty_stable = 0; static void vtp_flag_init(); -#ifndef FEAT_GUI_MSWIN +#if !defined(FEAT_GUI_MSWIN) || defined(VIMDLL) static int vtp_working = 0; static void vtp_init(); static void vtp_exit(); @@ -227,7 +228,7 @@ static void reset_console_color_rgb(void # define ENABLE_VIRTUAL_TERMINAL_PROCESSING 0x0004 #endif -#ifndef FEAT_GUI_MSWIN +#if !defined(FEAT_GUI_MSWIN) || defined(VIMDLL) static int suppress_winsize = 1; /* don't fiddle with console */ #endif @@ -235,7 +236,7 @@ static char_u *exe_path = NULL; static BOOL win8_or_later = FALSE; -#ifndef FEAT_GUI_MSWIN +#if !defined(FEAT_GUI_MSWIN) || defined(VIMDLL) /* Dynamic loading for portability */ typedef struct _DYN_CONSOLE_SCREEN_BUFFER_INFOEX { @@ -284,7 +285,7 @@ get_build_number(void) return ver; } -#ifndef FEAT_GUI_MSWIN +#if !defined(FEAT_GUI_MSWIN) || defined(VIMDLL) /* * Version of ReadConsoleInput() that works with IME. * Works around problems on Windows 8. @@ -496,6 +497,28 @@ vimLoadLib(char *name) return dll; } +#if defined(VIMDLL) || defined(PROTO) +/* + * Check if the current executable file is for the GUI subsystem. + */ + int +mch_is_gui_executable(void) +{ + PBYTE pImage = (PBYTE)GetModuleHandle(NULL); + PIMAGE_DOS_HEADER pDOS = (PIMAGE_DOS_HEADER)pImage; + PIMAGE_NT_HEADERS pPE; + + if (pDOS->e_magic != IMAGE_DOS_SIGNATURE) + return FALSE; + pPE = (PIMAGE_NT_HEADERS)(pImage + pDOS->e_lfanew); + if (pPE->Signature != IMAGE_NT_SIGNATURE) + return FALSE; + if (pPE->OptionalHeader.Subsystem == IMAGE_SUBSYSTEM_WINDOWS_GUI) + return TRUE; + return FALSE; +} +#endif + #if defined(DYNAMIC_ICONV) || defined(DYNAMIC_GETTEXT) || defined(PROTO) /* * Get related information about 'funcname' which is imported by 'hInst'. @@ -816,7 +839,7 @@ PlatformId(void) } } -#ifndef FEAT_GUI_MSWIN +#if !defined(FEAT_GUI_MSWIN) || defined(VIMDLL) #define SHIFT (SHIFT_PRESSED) #define CTRL (RIGHT_CTRL_PRESSED | LEFT_CTRL_PRESSED) @@ -1116,7 +1139,7 @@ decode_key_event( /* * For the GUI the mouse handling is in gui_w32.c. */ -# ifdef FEAT_GUI_MSWIN +# if defined(FEAT_GUI_MSWIN) && !defined(VIMDLL) void mch_setmouse(int on UNUSED) { @@ -1136,6 +1159,10 @@ mch_setmouse(int on) { DWORD cmodein; +# ifdef VIMDLL + if (gui.in_use) + return; +# endif if (!g_fMouseAvail) return; @@ -1454,6 +1481,11 @@ mch_update_cursor(void) int idx; int thickness; +# ifdef VIMDLL + if (gui.in_use) + return; +# endif + /* * How the cursor is drawn depends on the current mode. */ @@ -1467,7 +1499,7 @@ mch_update_cursor(void) } #endif -#ifndef FEAT_GUI_MSWIN /* this isn't used for the GUI */ +#if !defined(FEAT_GUI_MSWIN) || defined(VIMDLL) /* * Handle FOCUS_EVENT. */ @@ -1677,13 +1709,16 @@ WaitForChar(long msec, int ignore_input) return FALSE; } -#ifndef FEAT_GUI_MSWIN /* * return non-zero if a character is available */ int mch_char_avail(void) { +# ifdef VIMDLL + if (gui.in_use) + return TRUE; +# endif return WaitForChar(0L, FALSE); } @@ -1694,10 +1729,13 @@ mch_char_avail(void) int mch_check_messages(void) { +# ifdef VIMDLL + if (gui.in_use) + return TRUE; +# endif return WaitForChar(0L, TRUE); } # endif -#endif /* * Create the console input. Used when reading stdin doesn't work. @@ -1779,7 +1817,7 @@ mch_inchar( long time UNUSED, int tb_change_cnt UNUSED) { -#ifndef FEAT_GUI_MSWIN /* this isn't used for the GUI */ +#if !defined(FEAT_GUI_MSWIN) || defined(VIMDLL) int len; int c; @@ -1787,6 +1825,11 @@ mch_inchar( static char_u typeahead[TYPEAHEADLEN]; /* previously typed bytes. */ static int typeaheadlen = 0; +# ifdef VIMDLL + if (gui.in_use) + return 0; +# endif + /* First use any typeahead that was kept because "buf" was too small. */ if (typeaheadlen > 0) goto theend; @@ -2092,8 +2135,8 @@ bad_param_handler(const wchar_t *express /* * GUI version of mch_init(). */ - void -mch_init(void) + static void +mch_init_g(void) { #ifndef __MINGW32__ extern int _fmode; @@ -2160,7 +2203,9 @@ mch_init(void) } -#else /* FEAT_GUI_MSWIN */ +#endif /* FEAT_GUI_MSWIN */ + +#if !defined(FEAT_GUI_MSWIN) || defined(VIMDLL) #define SRWIDTH(sr) ((sr).Right - (sr).Left + 1) #define SRHEIGHT(sr) ((sr).Bottom - (sr).Top + 1) @@ -2442,11 +2487,6 @@ static ConsoleBuffer g_cbNonTermcap = { static ConsoleBuffer g_cbTermcap = { 0 }; #ifdef FEAT_TITLE -#ifdef __BORLANDC__ -typedef HWND (__stdcall *GETCONSOLEWINDOWPROC)(VOID); -#else -typedef HWND (WINAPI *GETCONSOLEWINDOWPROC)(VOID); -#endif char g_szOrigTitle[256] = { 0 }; HWND g_hWnd = NULL; /* also used in os_mswin.c */ static HICON g_hOrigIconSmall = NULL; @@ -2563,8 +2603,8 @@ static DWORD g_cmodeout = 0; /* * non-GUI version of mch_init(). */ - void -mch_init(void) + static void +mch_init_c(void) { #ifndef FEAT_RESTORE_ORIG_SCREEN CONSOLE_SCREEN_BUFFER_INFO csbi; @@ -2660,8 +2700,8 @@ mch_init(void) * Shut down and exit with status `r' * Careful: mch_exit() may be called before mch_init()! */ - void -mch_exit(int r) + static void +mch_exit_c(int r) { exiting = TRUE; @@ -2711,6 +2751,36 @@ mch_exit(int r) } #endif /* !FEAT_GUI_MSWIN */ + void +mch_init(void) +{ +#ifdef VIMDLL + if (gui.starting) + mch_init_g(); + else + mch_init_c(); +#elif defined(FEAT_GUI_MSWIN) + mch_init_g(); +#else + mch_init_c(); +#endif +} + + void +mch_exit(int r) +{ +#ifdef VIMDLL + if (gui.starting || gui.in_use) + mch_exit_g(r); + else + mch_exit_c(r); +#elif defined(FEAT_GUI_MSWIN) + mch_exit_g(r); +#else + mch_exit_c(r); +#endif +} + /* * Do we have an interactive window? */ @@ -2721,9 +2791,13 @@ mch_check_win( { get_exe_name(); -#ifdef FEAT_GUI_MSWIN +#if defined(FEAT_GUI_MSWIN) && !defined(VIMDLL) return OK; /* GUI always has a tty */ #else +# ifdef VIMDLL + if (gui.in_use) + return OK; +# endif if (isatty(1)) return OK; return FAIL; @@ -3446,7 +3520,7 @@ mch_free_acl(vim_acl_T acl) #endif } -#ifndef FEAT_GUI_MSWIN +#if !defined(FEAT_GUI_MSWIN) || defined(VIMDLL) /* * handler for ctrl-break, ctrl-c interrupts, and fatal events. @@ -3516,6 +3590,10 @@ mch_settmode(int tmode) DWORD cmodeout; BOOL bEnableHandler; +# ifdef VIMDLL + if (gui.in_use) + return; +# endif GetConsoleMode(g_hConIn, &cmodein); GetConsoleMode(g_hConOut, &cmodeout); if (tmode == TMODE_RAW) @@ -3528,7 +3606,7 @@ mch_settmode(int tmode) #endif cmodeout &= ~( #ifdef FEAT_TERMGUICOLORS - /* Do not turn off the ENABLE_PROCESSRD_OUTPUT flag when using + /* Do not turn off the ENABLE_PROCESSED_OUTPUT flag when using * VTP. */ ((vtp_working) ? 0 : ENABLE_PROCESSED_OUTPUT) | #else @@ -3570,6 +3648,10 @@ mch_get_shellsize(void) { CONSOLE_SCREEN_BUFFER_INFO csbi; +# ifdef VIMDLL + if (gui.in_use) + return OK; +# endif if (!g_fTermcapMode && g_cbTermcap.IsValid) { /* @@ -3717,6 +3799,10 @@ mch_set_shellsize(void) { COORD coordScreen; +# ifdef VIMDLL + if (gui.in_use) + return; +# endif /* Don't change window size while still starting up */ if (suppress_winsize != 0) { @@ -3744,6 +3830,10 @@ mch_set_shellsize(void) void mch_new_shellsize(void) { +# ifdef VIMDLL + if (gui.in_use) + return; +# endif set_scroll_region(0, 0, Columns - 1, Rows - 1); } @@ -4369,7 +4459,7 @@ mch_system_piped(char *cmd, int options) } static int -mch_system(char *cmd, int options) +mch_system_g(char *cmd, int options) { /* if we can pipe and the shelltemp option is off */ if (!p_stmp) @@ -4377,10 +4467,11 @@ mch_system(char *cmd, int options) else return mch_system_classic(cmd, options); } -#else - +#endif + +#if !defined(FEAT_GUI_MSWIN) || defined(VIMDLL) static int -mch_system(char *cmd, int options) +mch_system_c(char *cmd, int options) { int ret; WCHAR *wcmd; @@ -4396,6 +4487,21 @@ mch_system(char *cmd, int options) #endif + static int +mch_system(char *cmd, int options) +{ +#ifdef VIMDLL + if (gui.in_use) + return mch_system_g(cmd, options); + else + return mch_system_c(cmd, options); +#elif defined(FEAT_GUI_MSWIN) + return mch_system_g(cmd, options); +#else + return mch_system_c(cmd, options); +#endif +} + #if defined(FEAT_GUI) && defined(FEAT_TERMINAL) /* * Use a terminal window to run a shell command in. @@ -4527,7 +4633,11 @@ mch_call_shell( #endif #if defined(FEAT_GUI) && defined(FEAT_TERMINAL) /* TODO: make the terminal window work with input or output redirected. */ - if (vim_strchr(p_go, GO_TERMINAL) != NULL + if ( +# ifdef VIMDLL + gui.in_use && +# endif + vim_strchr(p_go, GO_TERMINAL) != NULL && (options & (SHELL_FILTER|SHELL_DOOUT|SHELL_WRITE|SHELL_READ)) == 0) { /* Use a terminal window to run the command in. */ @@ -4679,7 +4789,10 @@ mch_call_shell( { x = -1; #ifdef FEAT_GUI_MSWIN - emsg(_("E371: Command not found")); +# ifdef VIMDLL + if (gui.in_use) +# endif + emsg(_("E371: Command not found")); #endif } @@ -4699,7 +4812,7 @@ mch_call_shell( { cmdlen = ( #ifdef FEAT_GUI_MSWIN - (!p_stmp ? 0 : STRLEN(vimrun_path)) + + (gui.in_use ? (!p_stmp ? 0 : STRLEN(vimrun_path)) : 0) + #endif STRLEN(p_sh) + STRLEN(p_shcf) + STRLEN(cmd) + 10); @@ -4707,7 +4820,11 @@ mch_call_shell( if (newcmd != NULL) { #if defined(FEAT_GUI_MSWIN) - if (need_vimrun_warning) + if ( +# ifdef VIMDLL + gui.in_use && +# endif + need_vimrun_warning) { char *msg = _("VIMRUN.EXE not found in your $PATH.\n" "External commands will not pause after completion.\n" @@ -4722,7 +4839,11 @@ mch_call_shell( vim_free(wtitle); need_vimrun_warning = FALSE; } - if (!s_dont_use_vimrun && p_stmp) + if ( +# ifdef VIMDLL + gui.in_use && +# endif + !s_dont_use_vimrun && p_stmp) /* Use vimrun to execute the command. It opens a console * window, which can be closed without killing Vim. */ vim_snprintf((char *)newcmd, cmdlen, "%s%s%s %s %s", @@ -4746,7 +4867,8 @@ mch_call_shell( /* Print the return value, unless "vimrun" was used. */ if (x != 0 && !(options & SHELL_SILENT) && !emsg_silent #if defined(FEAT_GUI_MSWIN) - && ((options & SHELL_DOOUT) || s_dont_use_vimrun || !p_stmp) + && (gui.in_use ? + ((options & SHELL_DOOUT) || s_dont_use_vimrun || !p_stmp) : 1) #endif ) { @@ -5278,7 +5400,7 @@ mch_clear_job(job_T *job) #endif -#ifndef FEAT_GUI_MSWIN +#if !defined(FEAT_GUI_MSWIN) || defined(VIMDLL) /* * Start termcap mode @@ -5397,7 +5519,7 @@ termcap_mode_end(void) #endif /* FEAT_GUI_MSWIN */ -#ifdef FEAT_GUI_MSWIN +#if defined(FEAT_GUI_MSWIN) && !defined(VIMDLL) void mch_write( char_u *s UNUSED, @@ -5694,7 +5816,7 @@ gotoxy( /* * Set the current text attribute = (foreground | background) - * See ../doc/os_win32.txt for the numbers. + * See ../runtime/doc/os_win32.txt for the numbers. */ static void textattr(WORD wAttr) @@ -5924,6 +6046,11 @@ mch_write( char_u *s, int len) { +# ifdef VIMDLL + if (gui.in_use) + return; +# endif + s[len] = NUL; if (!term_console) @@ -6222,9 +6349,16 @@ mch_delay( long msec, int ignoreinput UNUSED) { -#ifdef FEAT_GUI_MSWIN +#if defined(FEAT_GUI_MSWIN) && !defined(VIMDLL) Sleep((int)msec); /* never wait for input */ #else /* Console */ +# ifdef VIMDLL + if (gui.in_use) + { + Sleep((int)msec); /* never wait for input */ + return; + } +# endif if (ignoreinput) # ifdef FEAT_MZSCHEME if (mzthreads_allowed() && p_mzq > 0 && msec > p_mzq) @@ -6286,13 +6420,16 @@ mch_remove(char_u *name) void mch_breakcheck(int force) { -#ifndef FEAT_GUI_MSWIN /* never used */ - if (g_fCtrlCPressed || g_fCBrkPressed) - { - ctrl_break_was_pressed = g_fCBrkPressed; - g_fCtrlCPressed = g_fCBrkPressed = FALSE; - got_int = TRUE; - } +#if !defined(FEAT_GUI_MSWIN) || defined(VIMDLL) +# ifdef VIMDLL + if (!gui.in_use) +# endif + if (g_fCtrlCPressed || g_fCBrkPressed) + { + ctrl_break_was_pressed = g_fCBrkPressed; + g_fCtrlCPressed = g_fCBrkPressed = FALSE; + got_int = TRUE; + } #endif } @@ -6308,7 +6445,7 @@ mch_total_mem(int special UNUSED) MEMORYSTATUSEX ms; /* Need to use GlobalMemoryStatusEx() when there is more memory than - * what fits in 32 bits. But it's not always available. */ + * what fits in 32 bits. */ ms.dwLength = sizeof(MEMORYSTATUSEX); GlobalMemoryStatusEx(&ms); if (ms.ullAvailVirtual < ms.ullTotalPhys) @@ -7098,17 +7235,22 @@ mch_setenv(char *var, char *value, int x vtp_flag_init(void) { DWORD ver = get_build_number(); -#ifndef FEAT_GUI_MSWIN +#if !defined(FEAT_GUI_MSWIN) || defined(VIMDLL) DWORD mode; HANDLE out; - out = GetStdHandle(STD_OUTPUT_HANDLE); - - vtp_working = (ver >= VTP_FIRST_SUPPORT_BUILD) ? 1 : 0; - GetConsoleMode(out, &mode); - mode |= (ENABLE_PROCESSED_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING); - if (SetConsoleMode(out, mode) == 0) - vtp_working = 0; +# ifdef VIMDLL + if (!gui.in_use) +# endif + { + out = GetStdHandle(STD_OUTPUT_HANDLE); + + vtp_working = (ver >= VTP_FIRST_SUPPORT_BUILD) ? 1 : 0; + GetConsoleMode(out, &mode); + mode |= (ENABLE_PROCESSED_OUTPUT | ENABLE_VIRTUAL_TERMINAL_PROCESSING); + if (SetConsoleMode(out, mode) == 0) + vtp_working = 0; + } #endif if (ver >= CONPTY_FIRST_SUPPORT_BUILD) @@ -7118,7 +7260,7 @@ vtp_flag_init(void) } -#if !defined(FEAT_GUI_MSWIN) || defined(PROTO) +#if !defined(FEAT_GUI_MSWIN) || defined(VIMDLL) || defined(PROTO) static void vtp_init(void) @@ -7343,7 +7485,7 @@ is_conpty_stable(void) return conpty_stable; } -#if !defined(FEAT_GUI_MSWIN) || defined(PROTO) +#if !defined(FEAT_GUI_MSWIN) || defined(VIMDLL) || defined(PROTO) void resize_console_buf(void) { diff --git a/src/os_win32.h b/src/os_win32.h --- a/src/os_win32.h +++ b/src/os_win32.h @@ -78,7 +78,7 @@ #define HAVE_PUTENV /* at least Bcc 5.2 and MSC have it */ -#ifdef FEAT_GUI_MSWIN +#if defined(FEAT_GUI_MSWIN) && !defined(VIMDLL) # define NO_CONSOLE /* don't included console-only code */ #endif diff --git a/src/proto/gui.pro b/src/proto/gui.pro --- a/src/proto/gui.pro +++ b/src/proto/gui.pro @@ -1,5 +1,5 @@ /* gui.c */ -void gui_start(void); +void gui_start(char_u *arg); void gui_prepare(int *argc, char **argv); int gui_init_check(void); void gui_init(void); diff --git a/src/proto/gui_w32.pro b/src/proto/gui_w32.pro --- a/src/proto/gui_w32.pro +++ b/src/proto/gui_w32.pro @@ -61,6 +61,7 @@ void mch_set_mouse_shape(int shape); char_u *gui_mch_browse(int saving, char_u *title, char_u *dflt, char_u *ext, char_u *initdir, char_u *filter); char_u *gui_mch_browsedir(char_u *title, char_u *initdir); void gui_mch_set_parent(char *title); +char *gui_mch_do_spawn(char_u *arg); void gui_mch_prepare(int *argc, char **argv); int gui_mch_init(void); void gui_mch_set_shellsize(int width, int height, int min_width, int min_height, int base_width, int base_height, int direction); diff --git a/src/proto/misc2.pro b/src/proto/misc2.pro --- a/src/proto/misc2.pro +++ b/src/proto/misc2.pro @@ -108,4 +108,5 @@ void parse_queued_messages(void); int mch_parse_cmd(char_u *cmd, int use_shcf, char ***argv, int *argc); int build_argv_from_string(char_u *cmd, char ***argv, int *argc); int build_argv_from_list(list_T *l, char ***argv, int *argc); +int write_session_file(char_u *filename); /* vim: set ft=c : */ diff --git a/src/proto/os_mswin.pro b/src/proto/os_mswin.pro --- a/src/proto/os_mswin.pro +++ b/src/proto/os_mswin.pro @@ -1,5 +1,5 @@ /* os_mswin.c */ -void mch_exit(int r); +void mch_exit_g(int r); void mch_early_init(void); int mch_input_isatty(void); void mch_settitle(char_u *title, char_u *icon); diff --git a/src/proto/os_win32.pro b/src/proto/os_win32.pro --- a/src/proto/os_win32.pro +++ b/src/proto/os_win32.pro @@ -1,5 +1,6 @@ /* os_win32.c */ HINSTANCE vimLoadLib(char *name); +int mch_is_gui_executable(void); HINSTANCE find_imported_module_by_funcname(HINSTANCE hInst, const char *funcname); void *get_dll_import_func(HINSTANCE hInst, const char *funcname); int dyn_libintl_init(void); diff --git a/src/syntax.c b/src/syntax.c --- a/src/syntax.c +++ b/src/syntax.c @@ -8280,6 +8280,13 @@ restore_cterm_colors(void) * background/foreground colors. */ mch_set_normal_colors(); #else +# ifdef VIMDLL + if (!gui.in_use) + { + mch_set_normal_colors(); + return; + } +# endif cterm_normal_fg_color = 0; cterm_normal_fg_bold = 0; cterm_normal_bg_color = 0; @@ -9823,7 +9830,7 @@ syn_id2colors(int hl_id, guicolor_T *fgp #endif #if (defined(MSWIN) \ - && !defined(FEAT_GUI_MSWIN) \ + && (!defined(FEAT_GUI_MSWIN) || defined(VIMDLL)) \ && defined(FEAT_TERMGUICOLORS)) || defined(PROTO) void syn_id2cterm_bg(int hl_id, int *fgp, int *bgp) diff --git a/src/term.c b/src/term.c --- a/src/term.c +++ b/src/term.c @@ -4094,7 +4094,12 @@ add_termcode(char_u *name, char_u *strin #if defined(MSWIN) && !defined(FEAT_GUI) s = vim_strnsave(string, (int)STRLEN(string) + 1); #else - s = vim_strsave(string); +# ifdef VIMDLL + if (!gui.in_use) + s = vim_strnsave(string, (int)STRLEN(string) + 1); + else +# endif + s = vim_strsave(string); #endif if (s == NULL) return; @@ -4106,11 +4111,16 @@ add_termcode(char_u *name, char_u *strin s[0] = term_7to8bit(string); } -#if defined(MSWIN) && !defined(FEAT_GUI) - if (s[0] == K_NUL) +#if defined(MSWIN) && (!defined(FEAT_GUI) || defined(VIMDLL)) +# ifdef VIMDLL + if (!gui.in_use) +# endif { - STRMOVE(s + 1, s); - s[1] = 3; + if (s[0] == K_NUL) + { + STRMOVE(s + 1, s); + s[1] = 3; + } } #endif @@ -6712,7 +6722,7 @@ translate_mapping( } #endif -#if (defined(MSWIN) && !defined(FEAT_GUI)) || defined(PROTO) +#if (defined(MSWIN) && (!defined(FEAT_GUI) || defined(VIMDLL))) || defined(PROTO) static char ksme_str[20]; static char ksmr_str[20]; static char ksmd_str[20]; @@ -6902,6 +6912,19 @@ hex_digit(int c) return 0x1ffffff; } +# ifdef VIMDLL + static guicolor_T +gui_adjust_rgb(guicolor_T c) +{ + if (gui.in_use) + return c; + else + return ((c & 0xff) << 16) | (c & 0x00ff00) | ((c >> 16) & 0xff); +} +# else +# define gui_adjust_rgb(c) (c) +# endif + guicolor_T gui_get_color_cmn(char_u *name) { @@ -6973,13 +6996,13 @@ gui_get_color_cmn(char_u *name) ((hex_digit(name[5]) << 4) + hex_digit(name[6]))); if (color > 0xffffff) return INVALCOLOR; - return color; + return gui_adjust_rgb(color); } /* Check if the name is one of the colors we know */ for (i = 0; i < (int)(sizeof(rgb_table) / sizeof(rgb_table[0])); i++) if (STRICMP(name, rgb_table[i].color_name) == 0) - return rgb_table[i].color; + return gui_adjust_rgb(rgb_table[i].color); /* * Last attempt. Look in the file "$VIMRUNTIME/rgb.txt". @@ -7060,7 +7083,7 @@ gui_get_color_cmn(char_u *name) for (i = 0; i < size; i++) if (STRICMP(name, colornames_table[i].color_name) == 0) - return colornames_table[i].color; + return gui_adjust_rgb(colornames_table[i].color); return INVALCOLOR; } @@ -7072,11 +7095,11 @@ gui_get_rgb_color_cmn(int r, int g, int if (color > 0xffffff) return INVALCOLOR; - return color; + return gui_adjust_rgb(color); } #endif -#if (defined(MSWIN) && !defined(FEAT_GUI_MSWIN)) || defined(FEAT_TERMINAL) \ +#if (defined(MSWIN) && (!defined(FEAT_GUI_MSWIN) || defined(VIMDLL))) || defined(FEAT_TERMINAL) \ || defined(PROTO) static int cube_value[] = { 0x00, 0x5F, 0x87, 0xAF, 0xD7, 0xFF diff --git a/src/terminal.c b/src/terminal.c --- a/src/terminal.c +++ b/src/terminal.c @@ -3553,7 +3553,7 @@ init_default_colors(term_T *term) } else { -#if defined(MSWIN) && !defined(FEAT_GUI_MSWIN) +#if defined(MSWIN) && (!defined(FEAT_GUI_MSWIN) || defined(VIMDLL)) int tmp; #endif @@ -3561,10 +3561,15 @@ init_default_colors(term_T *term) if (cterm_normal_fg_color > 0) { cterm_color2vterm(cterm_normal_fg_color - 1, fg); -# if defined(MSWIN) && !defined(FEAT_GUI_MSWIN) - tmp = fg->red; - fg->red = fg->blue; - fg->blue = tmp; +# if defined(MSWIN) && (!defined(FEAT_GUI_MSWIN) || defined(VIMDLL)) +# ifdef VIMDLL + if (!gui.in_use) +# endif + { + tmp = fg->red; + fg->red = fg->blue; + fg->blue = tmp; + } # endif } # ifdef FEAT_TERMRESPONSE @@ -3575,10 +3580,15 @@ init_default_colors(term_T *term) if (cterm_normal_bg_color > 0) { cterm_color2vterm(cterm_normal_bg_color - 1, bg); -# if defined(MSWIN) && !defined(FEAT_GUI_MSWIN) - tmp = bg->red; - bg->red = bg->blue; - bg->blue = tmp; +# if defined(MSWIN) && (!defined(FEAT_GUI_MSWIN) || defined(VIMDLL)) +# ifdef VIMDLL + if (!gui.in_use) +# endif + { + tmp = fg->red; + fg->red = fg->blue; + fg->blue = tmp; + } # endif } # ifdef FEAT_TERMRESPONSE @@ -3887,7 +3897,7 @@ parse_csi( #endif { // We roughly estimate the position of the terminal window inside - // the Vim window by assuing a 10 x 7 character cell. + // the Vim window by assuming a 10 x 7 character cell. x += wp->w_wincol * 7; y += W_WINROW(wp) * 10; } diff --git a/src/ui.c b/src/ui.c --- a/src/ui.c +++ b/src/ui.c @@ -643,7 +643,7 @@ ui_get_winpos(int *x, int *y, varnumber_ if (gui.in_use) return gui_mch_get_winpos(x, y); # endif -# if defined(MSWIN) && !defined(FEAT_GUI) +# if defined(MSWIN) && (!defined(FEAT_GUI) || defined(VIMDLL)) return mch_get_winpos(x, y); # else # if defined(HAVE_TGETENT) && defined(FEAT_TERMRESPONSE) diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -768,6 +768,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 1230, +/**/ 1229, /**/ 1228, @@ -3420,10 +3422,18 @@ list_version(void) msg(longVersion); #ifdef MSWIN # ifdef FEAT_GUI_MSWIN -# ifdef _WIN64 +# ifdef VIMDLL +# ifdef _WIN64 + msg_puts(_("\nMS-Windows 64-bit GUI/console version")); +# else + msg_puts(_("\nMS-Windows 32-bit GUI/console version")); +# endif +# else +# ifdef _WIN64 msg_puts(_("\nMS-Windows 64-bit GUI version")); -# else +# else msg_puts(_("\nMS-Windows 32-bit GUI version")); +# endif # endif # ifdef FEAT_OLE msg_puts(_(" with OLE support")); diff --git a/src/vim.rc b/src/vim.rc --- a/src/vim.rc +++ b/src/vim.rc @@ -23,7 +23,7 @@ // IDR_VIM ICON "vim.ico" -#ifdef FEAT_GUI_MSWIN +#if (defined(FEAT_GUI_MSWIN) && !defined(VIMDLL)) || defined(RCDLL) IDR_VIM_ERROR ICON "vim_error.ico" IDR_VIM_ALERT ICON "vim_alert.ico" IDR_VIM_INFO ICON "vim_info.ico" @@ -34,7 +34,9 @@ IDR_VIM_QUESTION ICON "vim_quest.ico" // IDB_TEAROFF BITMAP DISCARDABLE "tearoff.bmp" IDR_TOOLBAR1 BITMAP DISCARDABLE "tools.bmp" +#endif // FEAT_GUI_MSWIN +#ifndef RCDLL // // WinXP theme support // @@ -46,7 +48,7 @@ IDR_TOOLBAR1 BITMAP DISCARDABLE "tools #endif CREATEPROCESS_MANIFEST_RESOURCE_ID RT_MANIFEST "gvim.exe.mnf" -#endif // FEAT_GUI_MSWIN +#endif // RCDLL // // Type Library @@ -79,7 +81,11 @@ VS_VERSION_INFO VERSIONINFO #endif FILEOS VOS__WINDOWS32 +#ifdef RCDLL + FILETYPE VFT_DLL +#else FILETYPE VFT_APP +#endif FILESUBTYPE 0x0L BEGIN BLOCK "StringFileInfo" @@ -93,7 +99,13 @@ BEGIN VALUE "InternalName", "VIM\0" VALUE "LegalCopyright", "Copyright \251 1996\0" VALUE "LegalTrademarks", "Vim\0" - VALUE "OriginalFilename", "VIM.EXE\0" +#ifdef VIMDLLBASE + VALUE "OriginalFilename", VIMDLLBASE ".dll\0" +#elif defined(FEAT_GUI_MSWIN) + VALUE "OriginalFilename", "gvim.exe\0" +#else + VALUE "OriginalFilename", "vim.exe\0" +#endif VALUE "ProductName", "Vim\0" VALUE "ProductVersion", VIM_VERSION_MAJOR_STR ", " VIM_VERSION_MINOR_STR ", " VIM_VERSION_BUILD_STR ", " VIM_VERSION_PATCHLEVEL_STR "\0" END @@ -104,6 +116,7 @@ BEGIN END END +#if !defined(VIMDLL) || defined(RCDLL) /* * Printing Status Dialog (should only be used when FEAT_PRINTER is defined) */ @@ -121,3 +134,4 @@ BEGIN CTEXT "Initializing...",IDC_PROGRESS,24,38,157,9 GROUPBOX "",IDC_BOX1,19,9,170,47 END +#endif