1 /* vi:set ts=8 sts=4 sw=4 noet:
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 /*
11  * ui.c: functions that handle the user interface.
12  * 1. Keyboard input stuff, and a bit of windowing stuff.  These are called
13  *    before the machine specific stuff (mch_*) so that we can call the GUI
14  *    stuff instead if the GUI is running.
15  * 2. Input buffer stuff.
16  */
17 
18 #include "vim.h"
19 
20     void
ui_write(char_u * s,int len,int console UNUSED)21 ui_write(char_u *s, int len, int console UNUSED)
22 {
23 #ifdef FEAT_GUI
24     if (gui.in_use && !gui.dying && !gui.starting
25 # ifndef NO_CONSOLE
26 	    && !console
27 # endif
28 	    )
29     {
30 	gui_write(s, len);
31 	if (p_wd)
32 	    gui_wait_for_chars(p_wd, typebuf.tb_change_cnt);
33 	return;
34     }
35 #endif
36 #ifndef NO_CONSOLE
37     // Don't output anything in silent mode ("ex -s") unless 'verbose' set
38     if (!(silent_mode && p_verbose == 0))
39     {
40 # if !defined(MSWIN)
41 	char_u	*tofree = NULL;
42 
43 	if (output_conv.vc_type != CONV_NONE)
44 	{
45 	    // Convert characters from 'encoding' to 'termencoding'.
46 	    tofree = string_convert(&output_conv, s, &len);
47 	    if (tofree != NULL)
48 		s = tofree;
49 	}
50 # endif
51 
52 	mch_write(s, len);
53 # if defined(HAVE_FSYNC)
54 	if (console && s[len - 1] == '\n')
55 	    vim_fsync(1);
56 # endif
57 
58 # if !defined(MSWIN)
59 	if (output_conv.vc_type != CONV_NONE)
60 	    vim_free(tofree);
61 # endif
62     }
63 #endif
64 }
65 
66 #if defined(UNIX) || defined(VMS) || defined(PROTO) || defined(MSWIN)
67 /*
68  * When executing an external program, there may be some typed characters that
69  * are not consumed by it.  Give them back to ui_inchar() and they are stored
70  * here for the next call.
71  */
72 static char_u *ta_str = NULL;
73 static int ta_off;	// offset for next char to use when ta_str != NULL
74 static int ta_len;	// length of ta_str when it's not NULL
75 
76     void
ui_inchar_undo(char_u * s,int len)77 ui_inchar_undo(char_u *s, int len)
78 {
79     char_u  *new;
80     int	    newlen;
81 
82     newlen = len;
83     if (ta_str != NULL)
84 	newlen += ta_len - ta_off;
85     new = alloc(newlen);
86     if (new != NULL)
87     {
88 	if (ta_str != NULL)
89 	{
90 	    mch_memmove(new, ta_str + ta_off, (size_t)(ta_len - ta_off));
91 	    mch_memmove(new + ta_len - ta_off, s, (size_t)len);
92 	    vim_free(ta_str);
93 	}
94 	else
95 	    mch_memmove(new, s, (size_t)len);
96 	ta_str = new;
97 	ta_len = newlen;
98 	ta_off = 0;
99     }
100 }
101 #endif
102 
103 /*
104  * ui_inchar(): low level input function.
105  * Get characters from the keyboard.
106  * Return the number of characters that are available.
107  * If "wtime" == 0 do not wait for characters.
108  * If "wtime" == -1 wait forever for characters.
109  * If "wtime" > 0 wait "wtime" milliseconds for a character.
110  *
111  * "tb_change_cnt" is the value of typebuf.tb_change_cnt if "buf" points into
112  * it.  When typebuf.tb_change_cnt changes (e.g., when a message is received
113  * from a remote client) "buf" can no longer be used.  "tb_change_cnt" is NULL
114  * otherwise.
115  */
116     int
ui_inchar(char_u * buf,int maxlen,long wtime,int tb_change_cnt)117 ui_inchar(
118     char_u	*buf,
119     int		maxlen,
120     long	wtime,	    // don't use "time", MIPS cannot handle it
121     int		tb_change_cnt)
122 {
123     int		retval = 0;
124 
125 #if defined(FEAT_GUI) && (defined(UNIX) || defined(VMS))
126     /*
127      * Use the typeahead if there is any.
128      */
129     if (ta_str != NULL)
130     {
131 	if (maxlen >= ta_len - ta_off)
132 	{
133 	    mch_memmove(buf, ta_str + ta_off, (size_t)ta_len);
134 	    VIM_CLEAR(ta_str);
135 	    return ta_len;
136 	}
137 	mch_memmove(buf, ta_str + ta_off, (size_t)maxlen);
138 	ta_off += maxlen;
139 	return maxlen;
140     }
141 #endif
142 
143 #ifdef FEAT_PROFILE
144     if (do_profiling == PROF_YES && wtime != 0)
145 	prof_inchar_enter();
146 #endif
147 
148 #ifdef NO_CONSOLE_INPUT
149     // Don't wait for character input when the window hasn't been opened yet.
150     // Do try reading, this works when redirecting stdin from a file.
151     // Must return something, otherwise we'll loop forever.  If we run into
152     // this very often we probably got stuck, exit Vim.
153     if (no_console_input())
154     {
155 	static int count = 0;
156 
157 # ifndef NO_CONSOLE
158 	retval = mch_inchar(buf, maxlen, wtime, tb_change_cnt);
159 	if (retval > 0 || typebuf_changed(tb_change_cnt) || wtime >= 0)
160 	    goto theend;
161 # endif
162 	if (wtime == -1 && ++count == 1000)
163 	    read_error_exit();
164 	buf[0] = CAR;
165 	retval = 1;
166 	goto theend;
167     }
168 #endif
169 
170     // If we are going to wait for some time or block...
171     if (wtime == -1 || wtime > 100L)
172     {
173 	// ... allow signals to kill us.
174 	(void)vim_handle_signal(SIGNAL_UNBLOCK);
175 
176 	// ... there is no need for CTRL-C to interrupt something, don't let
177 	// it set got_int when it was mapped.
178 	if ((mapped_ctrl_c | curbuf->b_mapped_ctrl_c) & get_real_state())
179 	    ctrl_c_interrupts = FALSE;
180     }
181 
182     /*
183      * Here we call gui_inchar() or mch_inchar(), the GUI or machine-dependent
184      * input function.  The functionality they implement is like this:
185      *
186      * while (not timed out)
187      * {
188      *    handle-resize;
189      *    parse-queued-messages;
190      *    if (waited for 'updatetime')
191      *       trigger-cursorhold;
192      *    ui_wait_for_chars_or_timer()
193      *    if (character available)
194      *      break;
195      * }
196      *
197      * ui_wait_for_chars_or_timer() does:
198      *
199      * while (not timed out)
200      * {
201      *     if (any-timer-triggered)
202      *        invoke-timer-callback;
203      *     wait-for-character();
204      *     if (character available)
205      *        break;
206      * }
207      *
208      * wait-for-character() does:
209      * while (not timed out)
210      * {
211      *     Wait for event;
212      *     if (something on channel)
213      *        read/write channel;
214      *     else if (resized)
215      *        handle_resize();
216      *     else if (system event)
217      *        deal-with-system-event;
218      *     else if (character available)
219      *        break;
220      * }
221      *
222      */
223 
224 #ifdef FEAT_GUI
225     if (gui.in_use)
226 	retval = gui_inchar(buf, maxlen, wtime, tb_change_cnt);
227 #endif
228 #ifndef NO_CONSOLE
229 # ifdef FEAT_GUI
230     else
231 # endif
232 	retval = mch_inchar(buf, maxlen, wtime, tb_change_cnt);
233 #endif
234 
235     if (wtime == -1 || wtime > 100L)
236 	// block SIGHUP et al.
237 	(void)vim_handle_signal(SIGNAL_BLOCK);
238 
239     ctrl_c_interrupts = TRUE;
240 
241 #ifdef NO_CONSOLE_INPUT
242 theend:
243 #endif
244 #ifdef FEAT_PROFILE
245     if (do_profiling == PROF_YES && wtime != 0)
246 	prof_inchar_exit();
247 #endif
248     return retval;
249 }
250 
251 #if defined(UNIX) || defined(VMS) || defined(FEAT_GUI) || defined(PROTO)
252 /*
253  * Common code for mch_inchar() and gui_inchar(): Wait for a while or
254  * indefinitely until characters are available, dealing with timers and
255  * messages on channels.
256  *
257  * "buf" may be NULL if the available characters are not to be returned, only
258  * check if they are available.
259  *
260  * Return the number of characters that are available.
261  * If "wtime" == 0 do not wait for characters.
262  * If "wtime" == n wait a short time for characters.
263  * If "wtime" == -1 wait forever for characters.
264  */
265     int
inchar_loop(char_u * buf,int maxlen,long wtime,int tb_change_cnt,int (* wait_func)(long wtime,int * interrupted,int ignore_input),int (* resize_func)(int check_only))266 inchar_loop(
267     char_u	*buf,
268     int		maxlen,
269     long	wtime,	    // don't use "time", MIPS cannot handle it
270     int		tb_change_cnt,
271     int		(*wait_func)(long wtime, int *interrupted, int ignore_input),
272     int		(*resize_func)(int check_only))
273 {
274     int		len;
275     int		interrupted = FALSE;
276     int		did_call_wait_func = FALSE;
277     int		did_start_blocking = FALSE;
278     long	wait_time;
279     long	elapsed_time = 0;
280 #ifdef ELAPSED_FUNC
281     elapsed_T	start_tv;
282 
283     ELAPSED_INIT(start_tv);
284 #endif
285 
286     // repeat until we got a character or waited long enough
287     for (;;)
288     {
289 	// Check if window changed size while we were busy, perhaps the ":set
290 	// columns=99" command was used.
291 	if (resize_func != NULL)
292 	    resize_func(FALSE);
293 
294 #ifdef MESSAGE_QUEUE
295 	// Only process messages when waiting.
296 	if (wtime != 0)
297 	{
298 	    parse_queued_messages();
299 	    // If input was put directly in typeahead buffer bail out here.
300 	    if (typebuf_changed(tb_change_cnt))
301 		return 0;
302 	}
303 #endif
304 	if (wtime < 0 && did_start_blocking)
305 	    // blocking and already waited for p_ut
306 	    wait_time = -1;
307 	else
308 	{
309 	    if (wtime >= 0)
310 		wait_time = wtime;
311 	    else
312 		// going to block after p_ut
313 		wait_time = p_ut;
314 #ifdef ELAPSED_FUNC
315 	    elapsed_time = ELAPSED_FUNC(start_tv);
316 #endif
317 	    wait_time -= elapsed_time;
318 
319 	    // If the waiting time is now zero or less, we timed out.  However,
320 	    // loop at least once to check for characters and events.  Matters
321 	    // when "wtime" is zero.
322 	    if (wait_time <= 0 && did_call_wait_func)
323 	    {
324 		if (wtime >= 0)
325 		    // no character available within "wtime"
326 		    return 0;
327 
328 		// No character available within 'updatetime'.
329 		did_start_blocking = TRUE;
330 		if (trigger_cursorhold() && maxlen >= 3
331 					    && !typebuf_changed(tb_change_cnt))
332 		{
333 		    // Put K_CURSORHOLD in the input buffer or return it.
334 		    if (buf == NULL)
335 		    {
336 			char_u	ibuf[3];
337 
338 			ibuf[0] = CSI;
339 			ibuf[1] = KS_EXTRA;
340 			ibuf[2] = (int)KE_CURSORHOLD;
341 			add_to_input_buf(ibuf, 3);
342 		    }
343 		    else
344 		    {
345 			buf[0] = K_SPECIAL;
346 			buf[1] = KS_EXTRA;
347 			buf[2] = (int)KE_CURSORHOLD;
348 		    }
349 		    return 3;
350 		}
351 
352 		// There is no character available within 'updatetime' seconds:
353 		// flush all the swap files to disk.  Also done when
354 		// interrupted by SIGWINCH.
355 		before_blocking();
356 		continue;
357 	    }
358 	}
359 
360 #ifdef FEAT_JOB_CHANNEL
361 	if (wait_time < 0 || wait_time > 100L)
362 	{
363 	    // Checking if a job ended requires polling.  Do this at least
364 	    // every 100 msec.
365 	    if (has_pending_job())
366 		wait_time = 100L;
367 
368 	    // If there is readahead then parse_queued_messages() timed out and
369 	    // we should call it again soon.
370 	    if (channel_any_readahead())
371 		wait_time = 10L;
372 	}
373 #endif
374 #ifdef FEAT_BEVAL_GUI
375 	if (p_beval && wait_time > 100L)
376 	    // The 'balloonexpr' may indirectly invoke a callback while waiting
377 	    // for a character, need to check often.
378 	    wait_time = 100L;
379 #endif
380 
381 	// Wait for a character to be typed or another event, such as the winch
382 	// signal or an event on the monitored file descriptors.
383 	did_call_wait_func = TRUE;
384 	if (wait_func(wait_time, &interrupted, FALSE))
385 	{
386 	    // If input was put directly in typeahead buffer bail out here.
387 	    if (typebuf_changed(tb_change_cnt))
388 		return 0;
389 
390 	    // We might have something to return now.
391 	    if (buf == NULL)
392 		// "buf" is NULL, we were just waiting, not actually getting
393 		// input.
394 		return input_available();
395 
396 	    len = read_from_input_buf(buf, (long)maxlen);
397 	    if (len > 0)
398 		return len;
399 	    continue;
400 	}
401 	// Timed out or interrupted with no character available.
402 
403 #ifndef ELAPSED_FUNC
404 	// estimate the elapsed time
405 	elapsed_time += wait_time;
406 #endif
407 
408 	if ((resize_func != NULL && resize_func(TRUE))
409 #if defined(FEAT_CLIENTSERVER) && defined(UNIX)
410 		|| server_waiting()
411 #endif
412 #ifdef MESSAGE_QUEUE
413 		|| interrupted
414 #endif
415 		|| wait_time > 0
416 		|| (wtime < 0 && !did_start_blocking))
417 	    // no character available, but something to be done, keep going
418 	    continue;
419 
420 	// no character available or interrupted, return zero
421 	break;
422     }
423     return 0;
424 }
425 #endif
426 
427 #if defined(FEAT_TIMERS) || defined(PROTO)
428 /*
429  * Wait for a timer to fire or "wait_func" to return non-zero.
430  * Returns OK when something was read.
431  * Returns FAIL when it timed out or was interrupted.
432  */
433     int
ui_wait_for_chars_or_timer(long wtime,int (* wait_func)(long wtime,int * interrupted,int ignore_input),int * interrupted,int ignore_input)434 ui_wait_for_chars_or_timer(
435     long    wtime,
436     int	    (*wait_func)(long wtime, int *interrupted, int ignore_input),
437     int	    *interrupted,
438     int	    ignore_input)
439 {
440     int	    due_time;
441     long    remaining = wtime;
442     int	    tb_change_cnt = typebuf.tb_change_cnt;
443 # ifdef FEAT_JOB_CHANNEL
444     int	    brief_wait = FALSE;
445 # endif
446 
447     // When waiting very briefly don't trigger timers.
448     if (wtime >= 0 && wtime < 10L)
449 	return wait_func(wtime, NULL, ignore_input);
450 
451     while (wtime < 0 || remaining > 0)
452     {
453 	// Trigger timers and then get the time in wtime until the next one is
454 	// due.  Wait up to that time.
455 	due_time = check_due_timer();
456 	if (typebuf.tb_change_cnt != tb_change_cnt)
457 	{
458 	    // timer may have used feedkeys()
459 	    return FAIL;
460 	}
461 	if (due_time <= 0 || (wtime > 0 && due_time > remaining))
462 	    due_time = remaining;
463 # if defined(FEAT_JOB_CHANNEL) || defined(FEAT_SOUND_CANBERRA)
464 	if ((due_time < 0 || due_time > 10L) && (
465 #  if defined(FEAT_JOB_CHANNEL)
466 		(
467 #   if defined(FEAT_GUI)
468 		!gui.in_use &&
469 #   endif
470 		(has_pending_job() || channel_any_readahead()))
471 #   ifdef FEAT_SOUND_CANBERRA
472 		||
473 #   endif
474 #  endif
475 #  ifdef FEAT_SOUND_CANBERRA
476 		    has_any_sound_callback()
477 #  endif
478 		    ))
479 	{
480 	    // There is a pending job or channel, should return soon in order
481 	    // to handle them ASAP.  Do check for input briefly.
482 	    due_time = 10L;
483 #  ifdef FEAT_JOB_CHANNEL
484 	    brief_wait = TRUE;
485 #  endif
486 	}
487 # endif
488 	if (wait_func(due_time, interrupted, ignore_input))
489 	    return OK;
490 	if ((interrupted != NULL && *interrupted)
491 # ifdef FEAT_JOB_CHANNEL
492 		|| brief_wait
493 # endif
494 		)
495 	    // Nothing available, but need to return so that side effects get
496 	    // handled, such as handling a message on a channel.
497 	    return FAIL;
498 	if (wtime > 0)
499 	    remaining -= due_time;
500     }
501     return FAIL;
502 }
503 #endif
504 
505 /*
506  * Return non-zero if a character is available.
507  */
508     int
ui_char_avail(void)509 ui_char_avail(void)
510 {
511 #ifdef FEAT_GUI
512     if (gui.in_use)
513     {
514 	gui_mch_update();
515 	return input_available();
516     }
517 #endif
518 #ifndef NO_CONSOLE
519 # ifdef NO_CONSOLE_INPUT
520     if (no_console_input())
521 	return 0;
522 # endif
523     return mch_char_avail();
524 #else
525     return 0;
526 #endif
527 }
528 
529 /*
530  * Delay for the given number of milliseconds.	If ignoreinput is FALSE then we
531  * cancel the delay if a key is hit.
532  */
533     void
ui_delay(long msec_arg,int ignoreinput)534 ui_delay(long msec_arg, int ignoreinput)
535 {
536     long msec = msec_arg;
537 
538 #ifdef FEAT_EVAL
539     if (ui_delay_for_testing > 0)
540 	msec = ui_delay_for_testing;
541 #endif
542 #ifdef FEAT_JOB_CHANNEL
543     ch_log(NULL, "ui_delay(%ld)", msec);
544 #endif
545 #ifdef FEAT_GUI
546     if (gui.in_use && !ignoreinput)
547 	gui_wait_for_chars(msec, typebuf.tb_change_cnt);
548     else
549 #endif
550 	mch_delay(msec, ignoreinput ? MCH_DELAY_IGNOREINPUT : 0);
551 }
552 
553 /*
554  * If the machine has job control, use it to suspend the program,
555  * otherwise fake it by starting a new shell.
556  * When running the GUI iconify the window.
557  */
558     void
ui_suspend(void)559 ui_suspend(void)
560 {
561 #ifdef FEAT_GUI
562     if (gui.in_use)
563     {
564 	gui_mch_iconify();
565 	return;
566     }
567 #endif
568     mch_suspend();
569 }
570 
571 #if !defined(UNIX) || !defined(SIGTSTP) || defined(PROTO)
572 /*
573  * When the OS can't really suspend, call this function to start a shell.
574  * This is never called in the GUI.
575  */
576     void
suspend_shell(void)577 suspend_shell(void)
578 {
579     if (*p_sh == NUL)
580 	emsg(_(e_shellempty));
581     else
582     {
583 	msg_puts(_("new shell started\n"));
584 	do_shell(NULL, 0);
585     }
586 }
587 #endif
588 
589 /*
590  * Try to get the current Vim shell size.  Put the result in Rows and Columns.
591  * Use the new sizes as defaults for 'columns' and 'lines'.
592  * Return OK when size could be determined, FAIL otherwise.
593  */
594     int
ui_get_shellsize(void)595 ui_get_shellsize(void)
596 {
597     int	    retval;
598 
599 #ifdef FEAT_GUI
600     if (gui.in_use)
601 	retval = gui_get_shellsize();
602     else
603 #endif
604 	retval = mch_get_shellsize();
605 
606     check_shellsize();
607 
608     // adjust the default for 'lines' and 'columns'
609     if (retval == OK)
610     {
611 	set_number_default("lines", Rows);
612 	set_number_default("columns", Columns);
613     }
614     return retval;
615 }
616 
617 /*
618  * Set the size of the Vim shell according to Rows and Columns, if possible.
619  * The gui_set_shellsize() or mch_set_shellsize() function will try to set the
620  * new size.  If this is not possible, it will adjust Rows and Columns.
621  */
622     void
ui_set_shellsize(int mustset UNUSED)623 ui_set_shellsize(
624     int		mustset UNUSED)	// set by the user
625 {
626 #ifdef FEAT_GUI
627     if (gui.in_use)
628 	gui_set_shellsize(mustset, TRUE, RESIZE_BOTH);
629     else
630 #endif
631 	mch_set_shellsize();
632 }
633 
634 /*
635  * Called when Rows and/or Columns changed.  Adjust scroll region and mouse
636  * region.
637  */
638     void
ui_new_shellsize(void)639 ui_new_shellsize(void)
640 {
641     if (full_screen && !exiting)
642     {
643 #ifdef FEAT_GUI
644 	if (gui.in_use)
645 	    gui_new_shellsize();
646 	else
647 #endif
648 	    mch_new_shellsize();
649     }
650 }
651 
652 #if ((defined(FEAT_EVAL) || defined(FEAT_TERMINAL)) \
653 	    && (defined(FEAT_GUI) \
654 		|| defined(MSWIN) \
655 		|| (defined(HAVE_TGETENT) && defined(FEAT_TERMRESPONSE)))) \
656 	|| defined(PROTO)
657 /*
658  * Get the window position in pixels, if possible.
659  * Return FAIL when not possible.
660  */
661     int
ui_get_winpos(int * x,int * y,varnumber_T timeout UNUSED)662 ui_get_winpos(int *x, int *y, varnumber_T timeout UNUSED)
663 {
664 # ifdef FEAT_GUI
665     if (gui.in_use)
666 	return gui_mch_get_winpos(x, y);
667 # endif
668 # if defined(MSWIN) && (!defined(FEAT_GUI) || defined(VIMDLL))
669     return mch_get_winpos(x, y);
670 # else
671 #  if defined(HAVE_TGETENT) && defined(FEAT_TERMRESPONSE)
672     return term_get_winpos(x, y, timeout);
673 #  else
674     return FAIL;
675 #  endif
676 # endif
677 }
678 #endif
679 
680     void
ui_breakcheck(void)681 ui_breakcheck(void)
682 {
683     ui_breakcheck_force(FALSE);
684 }
685 
686 /*
687  * When "force" is true also check when the terminal is not in raw mode.
688  * This is useful to read input on channels.
689  */
690     void
ui_breakcheck_force(int force)691 ui_breakcheck_force(int force)
692 {
693     static int	recursive = FALSE;
694     int		save_updating_screen = updating_screen;
695 
696     // We could be called recursively if stderr is redirected, calling
697     // fill_input_buf() calls settmode() when stdin isn't a tty.  settmode()
698     // calls vgetorpeek() which calls ui_breakcheck() again.
699     if (recursive)
700 	return;
701     recursive = TRUE;
702 
703     // We do not want gui_resize_shell() to redraw the screen here.
704     ++updating_screen;
705 
706 #ifdef FEAT_GUI
707     if (gui.in_use)
708 	gui_mch_update();
709     else
710 #endif
711 	mch_breakcheck(force);
712 
713     if (save_updating_screen)
714 	updating_screen = TRUE;
715     else
716 	after_updating_screen(FALSE);
717 
718     recursive = FALSE;
719 }
720 
721 //////////////////////////////////////////////////////////////////////////////
722 // Functions that handle the input buffer.
723 // This is used for any GUI version, and the unix terminal version.
724 //
725 // For Unix, the input characters are buffered to be able to check for a
726 // CTRL-C.  This should be done with signals, but I don't know how to do that
727 // in a portable way for a tty in RAW mode.
728 //
729 // For the client-server code in the console the received keys are put in the
730 // input buffer.
731 
732 #if defined(USE_INPUT_BUF) || defined(PROTO)
733 
734 /*
735  * Internal typeahead buffer.  Includes extra space for long key code
736  * descriptions which would otherwise overflow.  The buffer is considered full
737  * when only this extra space (or part of it) remains.
738  */
739 #if defined(FEAT_JOB_CHANNEL) || defined(FEAT_CLIENTSERVER)
740    /*
741     * NetBeans stuffs debugger commands into the input buffer.
742     * This requires a larger buffer...
743     * (Madsen) Go with this for remote input as well ...
744     */
745 # define INBUFLEN 4096
746 #else
747 # define INBUFLEN 250
748 #endif
749 
750 static char_u	inbuf[INBUFLEN + MAX_KEY_CODE_LEN];
751 static int	inbufcount = 0;	    // number of chars in inbuf[]
752 
753 /*
754  * vim_is_input_buf_full(), vim_is_input_buf_empty(), add_to_input_buf(), and
755  * trash_input_buf() are functions for manipulating the input buffer.  These
756  * are used by the gui_* calls when a GUI is used to handle keyboard input.
757  */
758 
759     int
vim_is_input_buf_full(void)760 vim_is_input_buf_full(void)
761 {
762     return (inbufcount >= INBUFLEN);
763 }
764 
765     int
vim_is_input_buf_empty(void)766 vim_is_input_buf_empty(void)
767 {
768     return (inbufcount == 0);
769 }
770 
771 #if defined(FEAT_OLE) || defined(PROTO)
772     int
vim_free_in_input_buf(void)773 vim_free_in_input_buf(void)
774 {
775     return (INBUFLEN - inbufcount);
776 }
777 #endif
778 
779 #if defined(FEAT_GUI_GTK) || defined(PROTO)
780     int
vim_used_in_input_buf(void)781 vim_used_in_input_buf(void)
782 {
783     return inbufcount;
784 }
785 #endif
786 
787 /*
788  * Return the current contents of the input buffer and make it empty.
789  * The returned pointer must be passed to set_input_buf() later.
790  */
791     char_u *
get_input_buf(void)792 get_input_buf(void)
793 {
794     garray_T	*gap;
795 
796     // We use a growarray to store the data pointer and the length.
797     gap = ALLOC_ONE(garray_T);
798     if (gap != NULL)
799     {
800 	// Add one to avoid a zero size.
801 	gap->ga_data = alloc(inbufcount + 1);
802 	if (gap->ga_data != NULL)
803 	    mch_memmove(gap->ga_data, inbuf, (size_t)inbufcount);
804 	gap->ga_len = inbufcount;
805     }
806     trash_input_buf();
807     return (char_u *)gap;
808 }
809 
810 /*
811  * Restore the input buffer with a pointer returned from get_input_buf().
812  * The allocated memory is freed, this only works once!
813  * When "overwrite" is FALSE input typed later is kept.
814  */
815     void
set_input_buf(char_u * p,int overwrite)816 set_input_buf(char_u *p, int overwrite)
817 {
818     garray_T	*gap = (garray_T *)p;
819 
820     if (gap != NULL)
821     {
822 	if (gap->ga_data != NULL)
823 	{
824 	    if (overwrite || inbufcount + gap->ga_len >= INBUFLEN)
825 	    {
826 		mch_memmove(inbuf, gap->ga_data, gap->ga_len);
827 		inbufcount = gap->ga_len;
828 	    }
829 	    else
830 	    {
831 		mch_memmove(inbuf + gap->ga_len, inbuf, inbufcount);
832 		mch_memmove(inbuf, gap->ga_data, gap->ga_len);
833 		inbufcount += gap->ga_len;
834 	    }
835 	    vim_free(gap->ga_data);
836 	}
837 	vim_free(gap);
838     }
839 }
840 
841 /*
842  * Add the given bytes to the input buffer
843  * Special keys start with CSI.  A real CSI must have been translated to
844  * CSI KS_EXTRA KE_CSI.  K_SPECIAL doesn't require translation.
845  */
846     void
add_to_input_buf(char_u * s,int len)847 add_to_input_buf(char_u *s, int len)
848 {
849     if (inbufcount + len > INBUFLEN + MAX_KEY_CODE_LEN)
850 	return;	    // Shouldn't ever happen!
851 
852     while (len--)
853 	inbuf[inbufcount++] = *s++;
854 }
855 
856 /*
857  * Add "str[len]" to the input buffer while escaping CSI bytes.
858  */
859     void
add_to_input_buf_csi(char_u * str,int len)860 add_to_input_buf_csi(char_u *str, int len)
861 {
862     int		i;
863     char_u	buf[2];
864 
865     for (i = 0; i < len; ++i)
866     {
867 	add_to_input_buf(str + i, 1);
868 	if (str[i] == CSI)
869 	{
870 	    // Turn CSI into K_CSI.
871 	    buf[0] = KS_EXTRA;
872 	    buf[1] = (int)KE_CSI;
873 	    add_to_input_buf(buf, 2);
874 	}
875     }
876 }
877 
878 /*
879  * Remove everything from the input buffer.  Called when ^C is found.
880  */
881     void
trash_input_buf(void)882 trash_input_buf(void)
883 {
884     inbufcount = 0;
885 }
886 
887 /*
888  * Read as much data from the input buffer as possible up to maxlen, and store
889  * it in buf.
890  */
891     int
read_from_input_buf(char_u * buf,long maxlen)892 read_from_input_buf(char_u *buf, long maxlen)
893 {
894     if (inbufcount == 0)	// if the buffer is empty, fill it
895 	fill_input_buf(TRUE);
896     if (maxlen > inbufcount)
897 	maxlen = inbufcount;
898     mch_memmove(buf, inbuf, (size_t)maxlen);
899     inbufcount -= maxlen;
900     if (inbufcount)
901 	mch_memmove(inbuf, inbuf + maxlen, (size_t)inbufcount);
902     return (int)maxlen;
903 }
904 
905     void
fill_input_buf(int exit_on_error UNUSED)906 fill_input_buf(int exit_on_error UNUSED)
907 {
908 #if defined(UNIX) || defined(VMS) || defined(MACOS_X)
909     int		len;
910     int		try;
911     static int	did_read_something = FALSE;
912     static char_u *rest = NULL;	    // unconverted rest of previous read
913     static int	restlen = 0;
914     int		unconverted;
915 #endif
916 
917 #ifdef FEAT_GUI
918     if (gui.in_use
919 # ifdef NO_CONSOLE_INPUT
920     // Don't use the GUI input when the window hasn't been opened yet.
921     // We get here from ui_inchar() when we should try reading from stdin.
922 	    && !no_console_input()
923 # endif
924        )
925     {
926 	gui_mch_update();
927 	return;
928     }
929 #endif
930 #if defined(UNIX) || defined(VMS) || defined(MACOS_X)
931     if (vim_is_input_buf_full())
932 	return;
933     /*
934      * Fill_input_buf() is only called when we really need a character.
935      * If we can't get any, but there is some in the buffer, just return.
936      * If we can't get any, and there isn't any in the buffer, we give up and
937      * exit Vim.
938      */
939     if (rest != NULL)
940     {
941 	// Use remainder of previous call, starts with an invalid character
942 	// that may become valid when reading more.
943 	if (restlen > INBUFLEN - inbufcount)
944 	    unconverted = INBUFLEN - inbufcount;
945 	else
946 	    unconverted = restlen;
947 	mch_memmove(inbuf + inbufcount, rest, unconverted);
948 	if (unconverted == restlen)
949 	    VIM_CLEAR(rest);
950 	else
951 	{
952 	    restlen -= unconverted;
953 	    mch_memmove(rest, rest + unconverted, restlen);
954 	}
955 	inbufcount += unconverted;
956     }
957     else
958 	unconverted = 0;
959 
960     len = 0;	// to avoid gcc warning
961     for (try = 0; try < 100; ++try)
962     {
963 	size_t readlen = (size_t)((INBUFLEN - inbufcount)
964 						       / input_conv.vc_factor);
965 #  ifdef VMS
966 	len = vms_read((char *)inbuf + inbufcount, readlen);
967 #  else
968 	len = read(read_cmd_fd, (char *)inbuf + inbufcount, readlen);
969 #  endif
970 #  ifdef FEAT_JOB_CHANNEL
971 	if (len > 0)
972 	{
973 	    inbuf[inbufcount + len] = NUL;
974 	    ch_log(NULL, "raw key input: \"%s\"", inbuf + inbufcount);
975 	}
976 #  endif
977 
978 	if (len > 0 || got_int)
979 	    break;
980 	/*
981 	 * If reading stdin results in an error, continue reading stderr.
982 	 * This helps when using "foo | xargs vim".
983 	 */
984 	if (!did_read_something && !isatty(read_cmd_fd) && read_cmd_fd == 0)
985 	{
986 	    int m = cur_tmode;
987 
988 	    // We probably set the wrong file descriptor to raw mode.  Switch
989 	    // back to cooked mode, use another descriptor and set the mode to
990 	    // what it was.
991 	    settmode(TMODE_COOK);
992 #ifdef HAVE_DUP
993 	    // Use stderr for stdin, also works for shell commands.
994 	    close(0);
995 	    vim_ignored = dup(2);
996 #else
997 	    read_cmd_fd = 2;	// read from stderr instead of stdin
998 #endif
999 	    settmode(m);
1000 	}
1001 	if (!exit_on_error)
1002 	    return;
1003     }
1004     if (len <= 0 && !got_int)
1005 	read_error_exit();
1006     if (len > 0)
1007 	did_read_something = TRUE;
1008     if (got_int)
1009     {
1010 	// Interrupted, pretend a CTRL-C was typed.
1011 	inbuf[0] = 3;
1012 	inbufcount = 1;
1013     }
1014     else
1015     {
1016 	/*
1017 	 * May perform conversion on the input characters.
1018 	 * Include the unconverted rest of the previous call.
1019 	 * If there is an incomplete char at the end it is kept for the next
1020 	 * time, reading more bytes should make conversion possible.
1021 	 * Don't do this in the unlikely event that the input buffer is too
1022 	 * small ("rest" still contains more bytes).
1023 	 */
1024 	if (input_conv.vc_type != CONV_NONE)
1025 	{
1026 	    inbufcount -= unconverted;
1027 	    len = convert_input_safe(inbuf + inbufcount,
1028 				     len + unconverted, INBUFLEN - inbufcount,
1029 				       rest == NULL ? &rest : NULL, &restlen);
1030 	}
1031 	while (len-- > 0)
1032 	{
1033 	    // If a CTRL-C was typed, remove it from the buffer and set
1034 	    // got_int.  Also recognize CTRL-C with modifyOtherKeys set, in two
1035 	    // forms.
1036 	    if (ctrl_c_interrupts && (inbuf[inbufcount] == 3
1037 			|| (len >= 10 && STRNCMP(inbuf + inbufcount,
1038 						   "\033[27;5;99~", 10) == 0)
1039 			|| (len >= 7 && STRNCMP(inbuf + inbufcount,
1040 						       "\033[99;5u", 7) == 0)))
1041 	    {
1042 		// remove everything typed before the CTRL-C
1043 		mch_memmove(inbuf, inbuf + inbufcount, (size_t)(len + 1));
1044 		inbufcount = 0;
1045 		got_int = TRUE;
1046 	    }
1047 	    ++inbufcount;
1048 	}
1049     }
1050 #endif // UNIX || VMS || MACOS_X
1051 }
1052 #endif // USE_INPUT_BUF
1053 
1054 /*
1055  * Exit because of an input read error.
1056  */
1057     void
read_error_exit(void)1058 read_error_exit(void)
1059 {
1060     if (silent_mode)	// Normal way to exit for "ex -s"
1061 	getout(0);
1062     STRCPY(IObuff, _("Vim: Error reading input, exiting...\n"));
1063     preserve_exit();
1064 }
1065 
1066 #if defined(CURSOR_SHAPE) || defined(PROTO)
1067 /*
1068  * May update the shape of the cursor.
1069  */
1070     void
ui_cursor_shape_forced(int forced)1071 ui_cursor_shape_forced(int forced)
1072 {
1073 # ifdef FEAT_GUI
1074     if (gui.in_use)
1075 	gui_update_cursor_later();
1076     else
1077 # endif
1078 	term_cursor_mode(forced);
1079 
1080 # ifdef MCH_CURSOR_SHAPE
1081     mch_update_cursor();
1082 # endif
1083 
1084 # ifdef FEAT_CONCEAL
1085     conceal_check_cursor_line(FALSE);
1086 # endif
1087 }
1088 
1089     void
ui_cursor_shape(void)1090 ui_cursor_shape(void)
1091 {
1092     ui_cursor_shape_forced(FALSE);
1093 }
1094 #endif
1095 
1096 /*
1097  * Check bounds for column number
1098  */
1099     int
check_col(int col)1100 check_col(int col)
1101 {
1102     if (col < 0)
1103 	return 0;
1104     if (col >= (int)screen_Columns)
1105 	return (int)screen_Columns - 1;
1106     return col;
1107 }
1108 
1109 /*
1110  * Check bounds for row number
1111  */
1112     int
check_row(int row)1113 check_row(int row)
1114 {
1115     if (row < 0)
1116 	return 0;
1117     if (row >= (int)screen_Rows)
1118 	return (int)screen_Rows - 1;
1119     return row;
1120 }
1121 
1122 /*
1123  * Called when focus changed.  Used for the GUI or for systems where this can
1124  * be done in the console (Win32).
1125  */
1126     void
ui_focus_change(int in_focus)1127 ui_focus_change(
1128     int		in_focus)	// TRUE if focus gained.
1129 {
1130     static time_t	last_time = (time_t)0;
1131     int			need_redraw = FALSE;
1132 
1133     // When activated: Check if any file was modified outside of Vim.
1134     // Only do this when not done within the last two seconds (could get
1135     // several events in a row).
1136     if (in_focus && last_time + 2 < time(NULL))
1137     {
1138 	need_redraw = check_timestamps(
1139 # ifdef FEAT_GUI
1140 		gui.in_use
1141 # else
1142 		FALSE
1143 # endif
1144 		);
1145 	last_time = time(NULL);
1146     }
1147 
1148     /*
1149      * Fire the focus gained/lost autocommand.
1150      */
1151     need_redraw |= apply_autocmds(in_focus ? EVENT_FOCUSGAINED
1152 				: EVENT_FOCUSLOST, NULL, NULL, FALSE, curbuf);
1153 
1154     if (need_redraw)
1155     {
1156 	// Something was executed, make sure the cursor is put back where it
1157 	// belongs.
1158 	need_wait_return = FALSE;
1159 
1160 	if (State & CMDLINE)
1161 	    redrawcmdline();
1162 	else if (State == HITRETURN || State == SETWSIZE || State == ASKMORE
1163 		|| State == EXTERNCMD || State == CONFIRM || exmode_active)
1164 	    repeat_message();
1165 	else if ((State & NORMAL) || (State & INSERT))
1166 	{
1167 	    if (must_redraw != 0)
1168 		update_screen(0);
1169 	    setcursor();
1170 	}
1171 	cursor_on();	    // redrawing may have switched it off
1172 	out_flush_cursor(FALSE, TRUE);
1173 # ifdef FEAT_GUI
1174 	if (gui.in_use)
1175 	    gui_update_scrollbars(FALSE);
1176 # endif
1177     }
1178 
1179     // File may have been changed from 'readonly' to 'noreadonly'
1180     if (need_maketitle)
1181 	maketitle();
1182 }
1183 
1184 #if defined(HAVE_INPUT_METHOD) || defined(PROTO)
1185 /*
1186  * Save current Input Method status to specified place.
1187  */
1188     void
im_save_status(long * psave)1189 im_save_status(long *psave)
1190 {
1191     // Don't save when 'imdisable' is set or "xic" is NULL, IM is always
1192     // disabled then (but might start later).
1193     // Also don't save when inside a mapping, vgetc_im_active has not been set
1194     // then.
1195     // And don't save when the keys were stuffed (e.g., for a "." command).
1196     // And don't save when the GUI is running but our window doesn't have
1197     // input focus (e.g., when a find dialog is open).
1198     if (!p_imdisable && KeyTyped && !KeyStuffed
1199 # ifdef FEAT_XIM
1200 	    && xic != NULL
1201 # endif
1202 # ifdef FEAT_GUI
1203 	    && (!gui.in_use || gui.in_focus)
1204 # endif
1205 	)
1206     {
1207 	// Do save when IM is on, or IM is off and saved status is on.
1208 	if (vgetc_im_active)
1209 	    *psave = B_IMODE_IM;
1210 	else if (*psave == B_IMODE_IM)
1211 	    *psave = B_IMODE_NONE;
1212     }
1213 }
1214 #endif
1215