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