blob: 92367eedfc4b2f89f9bb0c5413efde606874b4a2 [file] [log] [blame]
Bram Moolenaar071d4272004-06-13 20:20:40 +00001/* vi:set ts=8 sts=4 sw=4:
2 *
3 * VIM - Vi IMproved by Bram Moolenaar
4 *
5 * Do ":help uganda" in Vim to read copying and usage conditions.
6 * Do ":help credits" in Vim to see a list of people who contributed.
7 * See README.txt for an overview of the Vim source code.
8 */
9/*
10 * os_win16.c
11 *
12 * Win16 (Windows 3.1x) system-dependent routines.
13 * Carved brutally from os_win32.c by Vince Negri <vn@aslnet.co.uk>
14 */
15#ifdef __BORLANDC__
16# pragma warn -par
17# pragma warn -ucp
18# pragma warn -use
19# pragma warn -aus
20# pragma warn -obs
21#endif
22
Bram Moolenaar071d4272004-06-13 20:20:40 +000023#include "vim.h"
24
Bram Moolenaar82881492012-11-20 16:53:39 +010025/* cproto fails on missing include files */
26#ifndef PROTO
27# include <dos.h>
28#endif
29
Bram Moolenaar071d4272004-06-13 20:20:40 +000030#include <string.h>
31#include <sys/types.h>
Bram Moolenaar071d4272004-06-13 20:20:40 +000032#include <signal.h>
33#include <limits.h>
Bram Moolenaar071d4272004-06-13 20:20:40 +000034
Bram Moolenaar82881492012-11-20 16:53:39 +010035#ifndef PROTO
36# include <process.h>
37
38# undef chdir
39# include <direct.h>
40# include <shellapi.h> /* required for FindExecutable() */
41#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +000042
43
44/* Record all output and all keyboard & mouse input */
45/* #define MCH_WRITE_DUMP */
46
47#ifdef MCH_WRITE_DUMP
48FILE* fdDump = NULL;
49#endif
50
51
52/*
53 * When generating prototypes for Win32 on Unix, these lines make the syntax
54 * errors disappear. They do not need to be correct.
55 */
56#ifdef PROTO
57typedef int HANDLE;
58typedef int SMALL_RECT;
59typedef int COORD;
60typedef int SHORT;
61typedef int WORD;
62typedef int DWORD;
63typedef int BOOL;
64typedef int LPSTR;
65typedef int LPTSTR;
66typedef int KEY_EVENT_RECORD;
67typedef int MOUSE_EVENT_RECORD;
68# define WINAPI
69typedef int CONSOLE_CURSOR_INFO;
70typedef char * LPCSTR;
71# define WINBASEAPI
72typedef int INPUT_RECORD;
73# define _cdecl
74#endif
75
76#ifdef __BORLANDC__
77/* being a more ANSI compliant compiler, BorlandC doesn't define _stricoll:
78 * but it does in BC 5.02! */
79# if __BORLANDC__ < 0x502
80int _stricoll(char *a, char *b);
81# endif
82#endif
83
84/* cproto doesn't create a prototype for main() */
85int _cdecl
86VimMain
Bram Moolenaard99df422016-01-29 23:20:40 +010087 (int argc, char **argv);
Bram Moolenaar7fae6362005-06-30 22:06:41 +000088static int (_cdecl *pmain)(int, char **);
Bram Moolenaar071d4272004-06-13 20:20:40 +000089
90#ifndef PROTO
91void _cdecl SaveInst(HINSTANCE hInst);
Bram Moolenaar7fae6362005-06-30 22:06:41 +000092static void (_cdecl *pSaveInst)(HINSTANCE);
Bram Moolenaar071d4272004-06-13 20:20:40 +000093
94int WINAPI
95WinMain(
96 HINSTANCE hInstance,
97 HINSTANCE hPrevInst,
98 LPSTR lpszCmdLine,
99 int nCmdShow)
100{
101 int argc;
102 char **argv;
103 char *tofree;
104 char prog[256];
105
106 /*
107 * Ron: added full path name so that the $VIM variable will get set to our
108 * startup path (so the .vimrc file can be found w/o a VIM env. var.)
109 * Remove the ".exe" extension, and find the 1st non-space.
110 */
111 GetModuleFileName(hInstance, prog, 255);
112 if (*prog != NUL)
113 exe_name = FullName_save((char_u *)prog, FALSE);
114
115 /* Separate the command line into arguments. */
116 argc = get_cmd_args(prog, (char *)lpszCmdLine, &argv, &tofree);
117 if (argc == 0)
118 {
119 /* Error message? */
120 return 0;
121 }
122
123 pSaveInst = SaveInst;
124 pmain = VimMain;
125 pSaveInst(hInstance);
126 pmain(argc, argv);
127
128 free(argv);
Bram Moolenaar12806c82008-11-12 12:36:30 +0000129 if (tofree != NULL)
130 free(tofree);
Bram Moolenaar071d4272004-06-13 20:20:40 +0000131
132 return 0;
133}
134#endif
135
136
137
138
139
140
141#ifdef FEAT_MOUSE
142
143/*
144 * For the GUI the mouse handling is in gui_w32.c.
145 */
146 void
147mch_setmouse(
148 int on)
149{
150}
151#endif /* FEAT_MOUSE */
152
153
154
155/*
156 * GUI version of mch_init().
157 */
158 void
Bram Moolenaar05540972016-01-30 20:31:25 +0100159mch_init(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000160{
161 extern int _fmode;
162
163
164 /* Let critical errors result in a failure, not in a dialog box. Required
165 * for the timestamp test to work on removed floppies. */
166 SetErrorMode(SEM_FAILCRITICALERRORS);
167
168 _fmode = O_BINARY; /* we do our own CR-LF translation */
169
170 /* Specify window size. Is there a place to get the default from? */
171 Rows = 25;
172 Columns = 80;
173
174
175 set_option_value((char_u *)"grepprg", 0, (char_u *)"grep -n", 0);
176
177#ifdef FEAT_CLIPBOARD
178 clip_init(TRUE);
179
180 /*
181 * Vim's own clipboard format recognises whether the text is char, line,
182 * or rectangular block. Only useful for copying between two Vims.
183 * "VimClipboard" was used for previous versions, using the first
184 * character to specify MCHAR, MLINE or MBLOCK.
185 */
186 clip_star.format = RegisterClipboardFormat("VimClipboard2");
187 clip_star.format_raw = RegisterClipboardFormat("VimRawBytes");
188#endif
189}
190
191
192
193/*
194 * Do we have an interactive window?
195 */
196 int
197mch_check_win(
198 int argc,
199 char **argv)
200{
Bram Moolenaar071d4272004-06-13 20:20:40 +0000201 return OK; /* GUI always has a tty */
202}
203
204
205/*
206 * return process ID
207 */
208 long
Bram Moolenaar05540972016-01-30 20:31:25 +0100209mch_get_pid(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000210{
211 return (long)GetCurrentTask();
212}
213
214
215/*
216 * Specialised version of system().
217 * This version proceeds as follows:
218 * 1. Start the program with WinExec
219 * 2. Wait for the module use count of the program to go to 0
220 * (This is the best way of detecting the program has finished)
221 */
222
223 static int
224mch_system(char *cmd, int options)
225{
226 DWORD ret = 0;
227 UINT wShowWindow;
228 UINT h_module;
229 MSG msg;
230 BOOL again = TRUE;
231
232 /*
233 * It's nicer to run a filter command in a minimized window, but in
234 */
235 if (options & SHELL_DOOUT)
236 wShowWindow = SW_SHOWMINIMIZED;
237 else
238 wShowWindow = SW_SHOWNORMAL;
239
240 /* Now, run the command */
241 h_module = WinExec((LPCSTR)cmd, wShowWindow);
242
243 if (h_module < 32)
244 {
245 /*error*/
246 ret = -h_module;
247 }
248 else
249 {
250 /* Wait for the command to terminate before continuing */
251 while (GetModuleUsage((HINSTANCE)h_module) > 0 && again )
252 {
Bram Moolenaar62dbdc42011-10-20 18:24:22 +0200253 while (PeekMessage(&msg, NULL, 0, 0, PM_REMOVE) && again)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000254 {
Bram Moolenaar62dbdc42011-10-20 18:24:22 +0200255 if (msg.message == WM_QUIT)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000256
257 {
258 PostQuitMessage(msg.wParam);
259 again = FALSE;
260 }
261 TranslateMessage(&msg);
262 DispatchMessage(&msg);
263 }
264 }
265 }
266
267 return ret;
268}
269
270/*
271 * Either execute a command by calling the shell or start a new shell
272 */
273 int
274mch_call_shell(
275 char_u *cmd,
276 int options) /* SHELL_, see vim.h */
277{
278 int x;
279 int tmode = cur_tmode;
280
281 out_flush();
282
283
284#ifdef MCH_WRITE_DUMP
285 if (fdDump)
286 {
287 fprintf(fdDump, "mch_call_shell(\"%s\", %d)\n", cmd, options);
288 fflush(fdDump);
289 }
290#endif
291
292 /*
293 * Catch all deadly signals while running the external command, because a
294 * CTRL-C, Ctrl-Break or illegal instruction might otherwise kill us.
295 */
296 signal(SIGINT, SIG_IGN);
297 signal(SIGILL, SIG_IGN);
298 signal(SIGFPE, SIG_IGN);
299 signal(SIGSEGV, SIG_IGN);
300 signal(SIGTERM, SIG_IGN);
301 signal(SIGABRT, SIG_IGN);
302
303 if (options & SHELL_COOKED)
304 settmode(TMODE_COOK); /* set to normal mode */
305
306 if (cmd == NULL)
307 {
308 x = mch_system(p_sh, options);
309 }
310 else
311 {
312 /* we use "command" or "cmd" to start the shell; slow but easy */
313 char_u *newcmd;
314
315 newcmd = lalloc(
316 STRLEN(p_sh) + STRLEN(p_shcf) + STRLEN(cmd) + 10, TRUE);
317 if (newcmd != NULL)
318 {
319 if (STRNICMP(cmd, "start ", 6) == 0)
320 {
321 sprintf((char *)newcmd, "%s\0", cmd+6);
322 if (WinExec((LPCSTR)newcmd, SW_SHOWNORMAL) > 31)
323 x = 0;
324 else
325 x = -1;
326 }
327 else
328 {
329 sprintf((char *)newcmd, "%s%s %s %s",
330 "",
331 p_sh,
332 p_shcf,
333 cmd);
334 x = mch_system((char *)newcmd, options);
335 }
336 vim_free(newcmd);
337 }
338 }
339
340 if (tmode == TMODE_RAW)
341 settmode(TMODE_RAW); /* set to raw mode */
342
343 if (x && !(options & SHELL_SILENT) && !emsg_silent)
344 {
345 smsg(_("shell returned %d"), x);
346 msg_putchar('\n');
347 }
348#ifdef FEAT_TITLE
349 resettitle();
350#endif
351
352 signal(SIGINT, SIG_DFL);
353 signal(SIGILL, SIG_DFL);
354 signal(SIGFPE, SIG_DFL);
355 signal(SIGSEGV, SIG_DFL);
356 signal(SIGTERM, SIG_DFL);
357 signal(SIGABRT, SIG_DFL);
358
359
360 return x;
361}
362
363
364/*
365 * Delay for half a second.
366 */
367 void
368mch_delay(
369 long msec,
370 int ignoreinput)
371{
372#ifdef MUST_FIX
373 Sleep((int)msec); /* never wait for input */
374#endif
375}
376
377
378/*
379 * check for an "interrupt signal": CTRL-break or CTRL-C
380 */
381 void
Bram Moolenaar05540972016-01-30 20:31:25 +0100382mch_breakcheck(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000383{
384 /* never used */
385}
386
387
388/*
Bram Moolenaar11b73d62012-06-29 15:51:30 +0200389 * How much memory is available in Kbyte?
Bram Moolenaar071d4272004-06-13 20:20:40 +0000390 */
391 long_u
392mch_avail_mem(
393 int special)
394{
Bram Moolenaar11b73d62012-06-29 15:51:30 +0200395 return GetFreeSpace(0) >> 10;
Bram Moolenaar071d4272004-06-13 20:20:40 +0000396}
397
398
399/*
400 * Like rename(), returns 0 upon success, non-zero upon failure.
401 * Should probably set errno appropriately when errors occur.
402 */
403 int
404mch_rename(
405 const char *pszOldFile,
406 const char *pszNewFile)
407{
408
409 /*
410 * No need to play tricks, this isn't rubbish like Windows 95 <g>
411 */
412 return rename(pszOldFile, pszNewFile);
413
414}
415
416/*
417 * Get the default shell for the current hardware platform
418 */
419 char*
Bram Moolenaar05540972016-01-30 20:31:25 +0100420default_shell(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +0000421{
422 char* psz = NULL;
423
424 psz = "command.com";
425
426 return psz;
427}