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