/* vi:set ts=8 sts=4 sw=4:
*
* VIM - Vi IMproved gvimext by Tianmiao Hu
*
* Do ":help uganda" in Vim to read copying and usage conditions.
* Do ":help credits" in Vim to see a list of people who contributed.
*/
/*
* gvimext is a DLL which is used for the "Edit with Vim" context menu
* extension. It implements a MS defined interface with the Shell.
*
* If you have any questions or any suggestions concerning gvimext, please
* contact Tianmiao Hu: tianmiao@acm.org.
*/
#include "gvimext.h"
#ifdef __BORLANDC__
# include <dir.h>
# ifndef _strnicmp
# define _strnicmp(a, b, c) strnicmp((a), (b), (c))
# endif
#else
static char *searchpath(char *name);
#endif
// Always get an error while putting the following stuff to the
// gvimext.h file as class protected variables, give up and
// declare them as global stuff
FORMATETC fmte = {CF_HDROP,
(DVTARGETDEVICE FAR *)NULL,
DVASPECT_CONTENT,
-1,
TYMED_HGLOBAL
};
STGMEDIUM medium;
HRESULT hres = 0;
UINT cbFiles = 0;
/* The buffers size used to be MAX_PATH (256 bytes), but that's not always
* enough */
#define BUFSIZE 1100
//
// Get the name of the Gvim executable to use, with the path.
// When "runtime" is non-zero, we were called to find the runtime directory.
// Returns the path in name[BUFSIZE]. It's empty when it fails.
//
static void
getGvimName(char *name, int runtime)
{
HKEY keyhandle;
DWORD hlen;
// Get the location of gvim from the registry.
name[0] = 0;
if (RegOpenKeyEx(HKEY_LOCAL_MACHINE, "Software\\Vim\\Gvim", 0,
KEY_READ, &keyhandle) == ERROR_SUCCESS)
{
hlen = BUFSIZE;
if (RegQueryValueEx(keyhandle, "path", 0, NULL, (BYTE *)name, &hlen)
!= ERROR_SUCCESS)
name[0] = 0;
else
name[hlen] = 0;
RegCloseKey(keyhandle);
}
// Registry didn't work, use the search path.
if (name[0] == 0)
strcpy(name, searchpath((char *)"gvim.exe"));
if (!runtime)
{
// Only when looking for the executable, not the runtime dir, we can
// search for the batch file or a name without a path.
if (name[0] == 0)
strcpy(name, searchpath((char *)"gvim.bat"));
if (name[0] == 0)
strcpy(name, "gvim"); // finds gvim.bat or gvim.exe
// avoid that Vim tries to expand wildcards in the file names
strcat(name, " --literal");
}
}
static void
getGvimNameW(wchar_t *nameW)
{
char *name;
name = (char *)malloc(BUFSIZE);
getGvimName(name, 0);
mbstowcs(nameW, name, BUFSIZE);
free(name);
}
//
// Get the Vim runtime directory into buf[BUFSIZE].
// The result is empty when it failed.
// When it works, the path ends in a slash or backslash.
//
static void
getRuntimeDir(char *buf)
{
int idx;
getGvimName(buf, 1);
if (buf[0] != 0)
{
// When no path found, use the search path to expand it.
if (strchr(buf, '/') == NULL && strchr(buf, '\\') == NULL)
strcpy(buf, searchpath(buf));
// remove "gvim.exe" from the end
for (idx = (int)strlen(buf) - 1; idx >= 0; idx--)
if (buf[idx] == '\\' || buf[idx] == '/')
{
buf[idx + 1] = 0;
break;
}
}
}
//
// GETTEXT: translated messages and menu entries
//
#ifndef FEAT_GETTEXT
# define _(x) x
#else
# define _(x) (*dyn_libintl_gettext)(x)
# define VIMPACKAGE "vim"
# ifndef GETTEXT_DLL
# define GETTEXT_DLL "libintl.dll"
# endif
// Dummy functions
static char *null_libintl_gettext(const char *);
static char *null_libintl_textdomain(const char *);
static char *null_libintl_bindtextdomain(const char *, const char *);
static int dyn_libintl_init(char *dir);
static void dyn_libintl_end(void);
static wchar_t *oldenv = NULL;
static HINSTANCE hLibintlDLL = 0;
static char *(*dyn_libintl_gettext)(const char *) = null_libintl_gettext;
static char *(*dyn_libintl_textdomain)(const char *) = null_libintl_textdomain;
static char *(*dyn_libintl_bindtextdomain)(const char *, const char *)
= null_libintl_bindtextdomain;
//
// Attempt to load libintl.dll. If it doesn't work, use dummy functions.
// "dir" is the directory where the libintl.dll might be.
// Return 1 for success, 0 for failure.
//
static int
dyn_libintl_init(char *dir)
{
int i;
static struct
{
char *name;
FARPROC *ptr