xref: /vim-8.2.3635/src/ui.c (revision bc93cebb)
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. Clipboard stuff.
16  * 3. Input buffer stuff.
17  */
18 
19 #include "vim.h"
20 
21 #ifdef FEAT_CYGWIN_WIN32_CLIPBOARD
22 # define WIN32_LEAN_AND_MEAN
23 # include <windows.h>
24 # include "winclip.pro"
25 #endif
26 
27     void
28 ui_write(char_u *s, int len)
29 {
30 #ifdef FEAT_GUI
31     if (gui.in_use && !gui.dying && !gui.starting)
32     {
33 	gui_write(s, len);
34 	if (p_wd)
35 	    gui_wait_for_chars(p_wd, typebuf.tb_change_cnt);
36 	return;
37     }
38 #endif
39 #ifndef NO_CONSOLE
40     // Don't output anything in silent mode ("ex -s") unless 'verbose' set
41     if (!(silent_mode && p_verbose == 0))
42     {
43 #if !defined(MSWIN)
44 	char_u	*tofree = NULL;
45 
46 	if (output_conv.vc_type != CONV_NONE)
47 	{
48 	    // Convert characters from 'encoding' to 'termencoding'.
49 	    tofree = string_convert(&output_conv, s, &len);
50 	    if (tofree != NULL)
51 		s = tofree;
52 	}
53 #endif
54 
55 	mch_write(s, len);
56 
57 # if !defined(MSWIN)
58 	if (output_conv.vc_type != CONV_NONE)
59 	    vim_free(tofree);
60 # endif
61     }
62 #endif
63 }
64 
65 #if defined(UNIX) || defined(VMS) || defined(PROTO) || defined(MSWIN)
66 /*
67  * When executing an external program, there may be some typed characters that
68  * are not consumed by it.  Give them back to ui_inchar() and they are stored
69  * here for the next call.
70  */
71 static char_u *ta_str = NULL;
72 static int ta_off;	// offset for next char to use when ta_str != NULL
73 static int ta_len;	// length of ta_str when it's not NULL
74 
75     void
76 ui_inchar_undo(char_u *s, int len)
77 {
78     char_u  *new;
79     int	    newlen;
80 
81     newlen = len;
82     if (ta_str != NULL)
83 	newlen += ta_len - ta_off;
84     new = alloc(newlen);
85     if (new != NULL)
86     {
87 	if (ta_str != NULL)
88 	{
89 	    mch_memmove(new, ta_str + ta_off, (size_t)(ta_len - ta_off));
90 	    mch_memmove(new + ta_len - ta_off, s, (size_t)len);
91 	    vim_free(ta_str);
92 	}
93 	else
94 	    mch_memmove(new, s, (size_t)len);
95 	ta_str = new;
96 	ta_len = newlen;
97 	ta_off = 0;
98     }
99 }
100 #endif
101 
102 /*
103  * ui_inchar(): low level input function.
104  * Get characters from the keyboard.
105  * Return the number of characters that are available.
106  * If "wtime" == 0 do not wait for characters.
107  * If "wtime" == -1 wait forever for characters.
108  * If "wtime" > 0 wait "wtime" milliseconds for a character.
109  *
110  * "tb_change_cnt" is the value of typebuf.tb_change_cnt if "buf" points into
111  * it.  When typebuf.tb_change_cnt changes (e.g., when a message is received
112  * from a remote client) "buf" can no longer be used.  "tb_change_cnt" is NULL
113  * otherwise.
114  */
115     int
116 ui_inchar(
117     char_u	*buf,
118     int		maxlen,
119     long	wtime,	    // don't use "time", MIPS cannot handle it
120     int		tb_change_cnt)
121 {
122     int		retval = 0;
123 
124 #if defined(FEAT_GUI) && (defined(UNIX) || defined(VMS))
125     /*
126      * Use the typeahead if there is any.
127      */
128     if (ta_str != NULL)
129     {
130 	if (maxlen >= ta_len - ta_off)
131 	{
132 	    mch_memmove(buf, ta_str + ta_off, (size_t)ta_len);
133 	    VIM_CLEAR(ta_str);
134 	    return ta_len;
135 	}
136 	mch_memmove(buf, ta_str + ta_off, (size_t)maxlen);
137 	ta_off += maxlen;
138 	return maxlen;
139     }
140 #endif
141 
142 #ifdef FEAT_PROFILE
143     if (do_profiling == PROF_YES && wtime != 0)
144 	prof_inchar_enter();
145 #endif
146 
147 #ifdef NO_CONSOLE_INPUT
148     // Don't wait for character input when the window hasn't been opened yet.
149     // Do try reading, this works when redirecting stdin from a file.
150     // Must return something, otherwise we'll loop forever.  If we run into
151     // this very often we probably got stuck, exit Vim.
152     if (no_console_input())
153     {
154 	static int count = 0;
155 
156 # ifndef NO_CONSOLE
157 	retval = mch_inchar(buf, maxlen, wtime, tb_change_cnt);
158 	if (retval > 0 || typebuf_changed(tb_change_cnt) || wtime >= 0)
159 	    goto theend;
160 # endif
161 	if (wtime == -1 && ++count == 1000)
162 	    read_error_exit();
163 	buf[0] = CAR;
164 	retval = 1;
165 	goto theend;
166     }
167 #endif
168 
169     // If we are going to wait for some time or block...
170     if (wtime == -1 || wtime > 100L)
171     {
172 	// ... allow signals to kill us.
173 	(void)vim_handle_signal(SIGNAL_UNBLOCK);
174 
175 	// ... there is no need for CTRL-C to interrupt something, don't let
176 	// it set got_int when it was mapped.
177 	if ((mapped_ctrl_c | curbuf->b_mapped_ctrl_c) & get_real_state())
178 	    ctrl_c_interrupts = FALSE;
179     }
180 
181     /*
182      * Here we call gui_inchar() or mch_inchar(), the GUI or machine-dependent
183      * input function.  The functionality they implement is like this:
184      *
185      * while (not timed out)
186      * {
187      *    handle-resize;
188      *    parse-queued-messages;
189      *    if (waited for 'updatetime')
190      *       trigger-cursorhold;
191      *    ui_wait_for_chars_or_timer()
192      *    if (character available)
193      *      break;
194      * }
195      *
196      * ui_wait_for_chars_or_timer() does:
197      *
198      * while (not timed out)
199      * {
200      *     if (any-timer-triggered)
201      *        invoke-timer-callback;
202      *     wait-for-character();
203      *     if (character available)
204      *        break;
205      * }
206      *
207      * wait-for-character() does:
208      * while (not timed out)
209      * {
210      *     Wait for event;
211      *     if (something on channel)
212      *        read/write channel;
213      *     else if (resized)
214      *        handle_resize();
215      *     else if (system event)
216      *        deal-with-system-event;
217      *     else if (character available)
218      *        break;
219      * }
220      *
221      */
222 
223 #ifdef FEAT_GUI
224     if (gui.in_use)
225 	retval = gui_inchar(buf, maxlen, wtime, tb_change_cnt);
226 #endif
227 #ifndef NO_CONSOLE
228 # ifdef FEAT_GUI
229     else
230 # endif
231 	retval = mch_inchar(buf, maxlen, wtime, tb_change_cnt);
232 #endif
233 
234     if (wtime == -1 || wtime > 100L)
235 	// block SIGHUP et al.
236 	(void)vim_handle_signal(SIGNAL_BLOCK);
237 
238     ctrl_c_interrupts = TRUE;
239 
240 #ifdef NO_CONSOLE_INPUT
241 theend:
242 #endif
243 #ifdef FEAT_PROFILE
244     if (do_profiling == PROF_YES && wtime != 0)
245 	prof_inchar_exit();
246 #endif
247     return retval;
248 }
249 
250 #if defined(UNIX) || defined(VMS) || defined(FEAT_GUI) || defined(PROTO)
251 /*
252  * Common code for mch_inchar() and gui_inchar(): Wait for a while or
253  * indefinitely until characters are available, dealing with timers and
254  * messages on channels.
255  *
256  * "buf" may be NULL if the available characters are not to be returned, only
257  * check if they are available.
258  *
259  * Return the number of characters that are available.
260  * If "wtime" == 0 do not wait for characters.
261  * If "wtime" == n wait a short time for characters.
262  * If "wtime" == -1 wait forever for characters.
263  */
264     int
265 inchar_loop(
266     char_u	*buf,
267     int		maxlen,
268     long	wtime,	    // don't use "time", MIPS cannot handle it
269     int		tb_change_cnt,
270     int		(*wait_func)(long wtime, int *interrupted, int ignore_input),
271     int		(*resize_func)(int check_only))
272 {
273     int		len;
274     int		interrupted = FALSE;
275     int		did_call_wait_func = FALSE;
276     int		did_start_blocking = FALSE;
277     long	wait_time;
278     long	elapsed_time = 0;
279 #ifdef ELAPSED_FUNC
280     elapsed_T	start_tv;
281 
282     ELAPSED_INIT(start_tv);
283 #endif
284 
285     // repeat until we got a character or waited long enough
286     for (;;)
287     {
288 	// Check if window changed size while we were busy, perhaps the ":set
289 	// columns=99" command was used.
290 	if (resize_func != NULL)
291 	    resize_func(FALSE);
292 
293 #ifdef MESSAGE_QUEUE
294 	// Only process messages when waiting.
295 	if (wtime != 0)
296 	{
297 	    parse_queued_messages();
298 	    // If input was put directly in typeahead buffer bail out here.
299 	    if (typebuf_changed(tb_change_cnt))
300 		return 0;
301 	}
302 #endif
303 	if (wtime < 0 && did_start_blocking)
304 	    // blocking and already waited for p_ut
305 	    wait_time = -1;
306 	else
307 	{
308 	    if (wtime >= 0)
309 		wait_time = wtime;
310 	    else
311 		// going to block after p_ut
312 		wait_time = p_ut;
313 #ifdef ELAPSED_FUNC
314 	    elapsed_time = ELAPSED_FUNC(start_tv);
315 #endif
316 	    wait_time -= elapsed_time;
317 
318 	    // If the waiting time is now zero or less, we timed out.  However,
319 	    // loop at least once to check for characters and events.  Matters
320 	    // when "wtime" is zero.
321 	    if (wait_time <= 0 && did_call_wait_func)
322 	    {
323 		if (wtime >= 0)
324 		    // no character available within "wtime"
325 		    return 0;
326 
327 		// No character available within 'updatetime'.
328 		did_start_blocking = TRUE;
329 		if (trigger_cursorhold() && maxlen >= 3
330 					    && !typebuf_changed(tb_change_cnt))
331 		{
332 		    // Put K_CURSORHOLD in the input buffer or return it.
333 		    if (buf == NULL)
334 		    {
335 			char_u	ibuf[3];
336 
337 			ibuf[0] = CSI;
338 			ibuf[1] = KS_EXTRA;
339 			ibuf[2] = (int)KE_CURSORHOLD;
340 			add_to_input_buf(ibuf, 3);
341 		    }
342 		    else
343 		    {
344 			buf[0] = K_SPECIAL;
345 			buf[1] = KS_EXTRA;
346 			buf[2] = (int)KE_CURSORHOLD;
347 		    }
348 		    return 3;
349 		}
350 
351 		// There is no character available within 'updatetime' seconds:
352 		// flush all the swap files to disk.  Also done when
353 		// interrupted by SIGWINCH.
354 		before_blocking();
355 		continue;
356 	    }
357 	}
358 
359 #ifdef FEAT_JOB_CHANNEL
360 	if (wait_time < 0 || wait_time > 100L)
361 	{
362 	    // Checking if a job ended requires polling.  Do this at least
363 	    // every 100 msec.
364 	    if (has_pending_job())
365 		wait_time = 100L;
366 
367 	    // If there is readahead then parse_queued_messages() timed out and
368 	    // we should call it again soon.
369 	    if (channel_any_readahead())
370 		wait_time = 10L;
371 	}
372 #endif
373 #ifdef FEAT_BEVAL_GUI
374 	if (p_beval && wait_time > 100L)
375 	    // The 'balloonexpr' may indirectly invoke a callback while waiting
376 	    // for a character, need to check often.
377 	    wait_time = 100L;
378 #endif
379 
380 	// Wait for a character to be typed or another event, such as the winch
381 	// signal or an event on the monitored file descriptors.
382 	did_call_wait_func = TRUE;
383 	if (wait_func(wait_time, &interrupted, FALSE))
384 	{
385 	    // If input was put directly in typeahead buffer bail out here.
386 	    if (typebuf_changed(tb_change_cnt))
387 		return 0;
388 
389 	    // We might have something to return now.
390 	    if (buf == NULL)
391 		// "buf" is NULL, we were just waiting, not actually getting
392 		// input.
393 		return input_available();
394 
395 	    len = read_from_input_buf(buf, (long)maxlen);
396 	    if (len > 0)
397 		return len;
398 	    continue;
399 	}
400 	// Timed out or interrupted with no character available.
401 
402 #ifndef ELAPSED_FUNC
403 	// estimate the elapsed time
404 	elapsed_time += wait_time;
405 #endif
406 
407 	if ((resize_func != NULL && resize_func(TRUE))
408 #if defined(FEAT_CLIENTSERVER) && defined(UNIX)
409 		|| server_waiting()
410 #endif
411 #ifdef MESSAGE_QUEUE
412 		|| interrupted
413 #endif
414 		|| wait_time > 0
415 		|| (wtime < 0 && !did_start_blocking))
416 	    // no character available, but something to be done, keep going
417 	    continue;
418 
419 	// no character available or interrupted, return zero
420 	break;
421     }
422     return 0;
423 }
424 #endif
425 
426 #if defined(FEAT_TIMERS) || defined(PROTO)
427 /*
428  * Wait for a timer to fire or "wait_func" to return non-zero.
429  * Returns OK when something was read.
430  * Returns FAIL when it timed out or was interrupted.
431  */
432     int
433 ui_wait_for_chars_or_timer(
434     long    wtime,
435     int	    (*wait_func)(long wtime, int *interrupted, int ignore_input),
436     int	    *interrupted,
437     int	    ignore_input)
438 {
439     int	    due_time;
440     long    remaining = wtime;
441     int	    tb_change_cnt = typebuf.tb_change_cnt;
442 # ifdef FEAT_JOB_CHANNEL
443     int	    brief_wait = FALSE;
444 # endif
445 
446     // When waiting very briefly don't trigger timers.
447     if (wtime >= 0 && wtime < 10L)
448 	return wait_func(wtime, NULL, ignore_input);
449 
450     while (wtime < 0 || remaining > 0)
451     {
452 	// Trigger timers and then get the time in wtime until the next one is
453 	// due.  Wait up to that time.
454 	due_time = check_due_timer();
455 	if (typebuf.tb_change_cnt != tb_change_cnt)
456 	{
457 	    // timer may have used feedkeys()
458 	    return FAIL;
459 	}
460 	if (due_time <= 0 || (wtime > 0 && due_time > remaining))
461 	    due_time = remaining;
462 # if defined(FEAT_JOB_CHANNEL) || defined(FEAT_SOUND_CANBERRA)
463 	if ((due_time < 0 || due_time > 10L) && (
464 #  if defined(FEAT_JOB_CHANNEL)
465 		(
466 #   if defined(FEAT_GUI)
467 		!gui.in_use &&
468 #   endif
469 		(has_pending_job() || channel_any_readahead()))
470 #   ifdef FEAT_SOUND_CANBERRA
471 		||
472 #   endif
473 #  endif
474 #  ifdef FEAT_SOUND_CANBERRA
475 		    has_any_sound_callback()
476 #  endif
477 		    ))
478 	{
479 	    // There is a pending job or channel, should return soon in order
480 	    // to handle them ASAP.  Do check for input briefly.
481 	    due_time = 10L;
482 #  ifdef FEAT_JOB_CHANNEL
483 	    brief_wait = TRUE;
484 #  endif
485 	}
486 # endif
487 	if (wait_func(due_time, interrupted, ignore_input))
488 	    return OK;
489 	if ((interrupted != NULL && *interrupted)
490 # ifdef FEAT_JOB_CHANNEL
491 		|| brief_wait
492 # endif
493 		)
494 	    // Nothing available, but need to return so that side effects get
495 	    // handled, such as handling a message on a channel.
496 	    return FAIL;
497 	if (wtime > 0)
498 	    remaining -= due_time;
499     }
500     return FAIL;
501 }
502 #endif
503 
504 /*
505  * Return non-zero if a character is available.
506  */
507     int
508 ui_char_avail(void)
509 {
510 #ifdef FEAT_GUI
511     if (gui.in_use)
512     {
513 	gui_mch_update();
514 	return input_available();
515     }
516 #endif
517 #ifndef NO_CONSOLE
518 # ifdef NO_CONSOLE_INPUT
519     if (no_console_input())
520 	return 0;
521 # endif
522     return mch_char_avail();
523 #else
524     return 0;
525 #endif
526 }
527 
528 /*
529  * Delay for the given number of milliseconds.	If ignoreinput is FALSE then we
530  * cancel the delay if a key is hit.
531  */
532     void
533 ui_delay(long msec, int ignoreinput)
534 {
535 #ifdef FEAT_JOB_CHANNEL
536     ch_log(NULL, "ui_delay(%ld)", msec);
537 #endif
538 #ifdef FEAT_GUI
539     if (gui.in_use && !ignoreinput)
540 	gui_wait_for_chars(msec, typebuf.tb_change_cnt);
541     else
542 #endif
543 	mch_delay(msec, ignoreinput);
544 }
545 
546 /*
547  * If the machine has job control, use it to suspend the program,
548  * otherwise fake it by starting a new shell.
549  * When running the GUI iconify the window.
550  */
551     void
552 ui_suspend(void)
553 {
554 #ifdef FEAT_GUI
555     if (gui.in_use)
556     {
557 	gui_mch_iconify();
558 	return;
559     }
560 #endif
561     mch_suspend();
562 }
563 
564 #if !defined(UNIX) || !defined(SIGTSTP) || defined(PROTO) || defined(__BEOS__)
565 /*
566  * When the OS can't really suspend, call this function to start a shell.
567  * This is never called in the GUI.
568  */
569     void
570 suspend_shell(void)
571 {
572     if (*p_sh == NUL)
573 	emsg(_(e_shellempty));
574     else
575     {
576 	msg_puts(_("new shell started\n"));
577 	do_shell(NULL, 0);
578     }
579 }
580 #endif
581 
582 /*
583  * Try to get the current Vim shell size.  Put the result in Rows and Columns.
584  * Use the new sizes as defaults for 'columns' and 'lines'.
585  * Return OK when size could be determined, FAIL otherwise.
586  */
587     int
588 ui_get_shellsize(void)
589 {
590     int	    retval;
591 
592 #ifdef FEAT_GUI
593     if (gui.in_use)
594 	retval = gui_get_shellsize();
595     else
596 #endif
597 	retval = mch_get_shellsize();
598 
599     check_shellsize();
600 
601     // adjust the default for 'lines' and 'columns'
602     if (retval == OK)
603     {
604 	set_number_default("lines", Rows);
605 	set_number_default("columns", Columns);
606     }
607     return retval;
608 }
609 
610 /*
611  * Set the size of the Vim shell according to Rows and Columns, if possible.
612  * The gui_set_shellsize() or mch_set_shellsize() function will try to set the
613  * new size.  If this is not possible, it will adjust Rows and Columns.
614  */
615     void
616 ui_set_shellsize(
617     int		mustset UNUSED)	// set by the user
618 {
619 #ifdef FEAT_GUI
620     if (gui.in_use)
621 	gui_set_shellsize(mustset, TRUE, RESIZE_BOTH);
622     else
623 #endif
624 	mch_set_shellsize();
625 }
626 
627 /*
628  * Called when Rows and/or Columns changed.  Adjust scroll region and mouse
629  * region.
630  */
631     void
632 ui_new_shellsize(void)
633 {
634     if (full_screen && !exiting)
635     {
636 #ifdef FEAT_GUI
637 	if (gui.in_use)
638 	    gui_new_shellsize();
639 	else
640 #endif
641 	    mch_new_shellsize();
642     }
643 }
644 
645 #if ((defined(FEAT_EVAL) || defined(FEAT_TERMINAL)) \
646 	    && (defined(FEAT_GUI) \
647 		|| defined(MSWIN) \
648 		|| (defined(HAVE_TGETENT) && defined(FEAT_TERMRESPONSE)))) \
649 	|| defined(PROTO)
650 /*
651  * Get the window position in pixels, if possible.
652  * Return FAIL when not possible.
653  */
654     int
655 ui_get_winpos(int *x, int *y, varnumber_T timeout UNUSED)
656 {
657 # ifdef FEAT_GUI
658     if (gui.in_use)
659 	return gui_mch_get_winpos(x, y);
660 # endif
661 # if defined(MSWIN) && (!defined(FEAT_GUI) || defined(VIMDLL))
662     return mch_get_winpos(x, y);
663 # else
664 #  if defined(HAVE_TGETENT) && defined(FEAT_TERMRESPONSE)
665     return term_get_winpos(x, y, timeout);
666 #  else
667     return FAIL;
668 #  endif
669 # endif
670 }
671 #endif
672 
673     void
674 ui_breakcheck(void)
675 {
676     ui_breakcheck_force(FALSE);
677 }
678 
679 /*
680  * When "force" is true also check when the terminal is not in raw mode.
681  * This is useful to read input on channels.
682  */
683     void
684 ui_breakcheck_force(int force)
685 {
686     static int	recursive = FALSE;
687     int		save_updating_screen = updating_screen;
688 
689     // We could be called recursively if stderr is redirected, calling
690     // fill_input_buf() calls settmode() when stdin isn't a tty.  settmode()
691     // calls vgetorpeek() which calls ui_breakcheck() again.
692     if (recursive)
693 	return;
694     recursive = TRUE;
695 
696     // We do not want gui_resize_shell() to redraw the screen here.
697     ++updating_screen;
698 
699 #ifdef FEAT_GUI
700     if (gui.in_use)
701 	gui_mch_update();
702     else
703 #endif
704 	mch_breakcheck(force);
705 
706     if (save_updating_screen)
707 	updating_screen = TRUE;
708     else
709 	after_updating_screen(FALSE);
710 
711     recursive = FALSE;
712 }
713 
714 //////////////////////////////////////////////////////////////////////////////
715 // Functions for copying and pasting text between applications.
716 // This is always included in a GUI version, but may also be included when the
717 // clipboard and mouse is available to a terminal version such as xterm.
718 // Note: there are some more functions in ops.c that handle selection stuff.
719 //
720 // Also note that the majority of functions here deal with the X 'primary'
721 // (visible - for Visual mode use) selection, and only that. There are no
722 // versions of these for the 'clipboard' selection, as Visual mode has no use
723 // for them.
724 
725 #if defined(FEAT_CLIPBOARD) || defined(PROTO)
726 
727 static void clip_gen_lose_selection(Clipboard_T *cbd);
728 static int clip_gen_own_selection(Clipboard_T *cbd);
729 #if defined(FEAT_X11) && defined(FEAT_XCLIPBOARD) && defined(USE_SYSTEM)
730 static int clip_x11_owner_exists(Clipboard_T *cbd);
731 #endif
732 
733 /*
734  * Selection stuff using Visual mode, for cutting and pasting text to other
735  * windows.
736  */
737 
738 /*
739  * Call this to initialise the clipboard.  Pass it FALSE if the clipboard code
740  * is included, but the clipboard can not be used, or TRUE if the clipboard can
741  * be used.  Eg unix may call this with FALSE, then call it again with TRUE if
742  * the GUI starts.
743  */
744     void
745 clip_init(int can_use)
746 {
747     Clipboard_T *cb;
748 
749     cb = &clip_star;
750     for (;;)
751     {
752 	cb->available  = can_use;
753 	cb->owned      = FALSE;
754 	cb->start.lnum = 0;
755 	cb->start.col  = 0;
756 	cb->end.lnum   = 0;
757 	cb->end.col    = 0;
758 	cb->state      = SELECT_CLEARED;
759 
760 	if (cb == &clip_plus)
761 	    break;
762 	cb = &clip_plus;
763     }
764 }
765 
766 /*
767  * Check whether the VIsual area has changed, and if so try to become the owner
768  * of the selection, and free any old converted selection we may still have
769  * lying around.  If the VIsual mode has ended, make a copy of what was
770  * selected so we can still give it to others.	Will probably have to make sure
771  * this is called whenever VIsual mode is ended.
772  */
773     void
774 clip_update_selection(Clipboard_T *clip)
775 {
776     pos_T	    start, end;
777 
778     // If visual mode is only due to a redo command ("."), then ignore it
779     if (!redo_VIsual_busy && VIsual_active && (State & NORMAL))
780     {
781 	if (LT_POS(VIsual, curwin->w_cursor))
782 	{
783 	    start = VIsual;
784 	    end = curwin->w_cursor;
785 	    if (has_mbyte)
786 		end.col += (*mb_ptr2len)(ml_get_cursor()) - 1;
787 	}
788 	else
789 	{
790 	    start = curwin->w_cursor;
791 	    end = VIsual;
792 	}
793 	if (!EQUAL_POS(clip->start, start)
794 		|| !EQUAL_POS(clip->end, end)
795 		|| clip->vmode != VIsual_mode)
796 	{
797 	    clip_clear_selection(clip);
798 	    clip->start = start;
799 	    clip->end = end;
800 	    clip->vmode = VIsual_mode;
801 	    clip_free_selection(clip);
802 	    clip_own_selection(clip);
803 	    clip_gen_set_selection(clip);
804 	}
805     }
806 }
807 
808     void
809 clip_own_selection(Clipboard_T *cbd)
810 {
811     /*
812      * Also want to check somehow that we are reading from the keyboard rather
813      * than a mapping etc.
814      */
815 #ifdef FEAT_X11
816     // Always own the selection, we might have lost it without being
817     // notified, e.g. during a ":sh" command.
818     if (cbd->available)
819     {
820 	int was_owned = cbd->owned;
821 
822 	cbd->owned = (clip_gen_own_selection(cbd) == OK);
823 	if (!was_owned && (cbd == &clip_star || cbd == &clip_plus))
824 	{
825 	    // May have to show a different kind of highlighting for the
826 	    // selected area.  There is no specific redraw command for this,
827 	    // just redraw all windows on the current buffer.
828 	    if (cbd->owned
829 		    && (get_real_state() == VISUAL
830 					    || get_real_state() == SELECTMODE)
831 		    && (cbd == &clip_star ? clip_isautosel_star()
832 						      : clip_isautosel_plus())
833 		    && HL_ATTR(HLF_V) != HL_ATTR(HLF_VNC))
834 		redraw_curbuf_later(INVERTED_ALL);
835 	}
836     }
837 #else
838     // Only own the clipboard when we didn't own it yet.
839     if (!cbd->owned && cbd->available)
840 	cbd->owned = (clip_gen_own_selection(cbd) == OK);
841 #endif
842 }
843 
844     void
845 clip_lose_selection(Clipboard_T *cbd)
846 {
847 #ifdef FEAT_X11
848     int	    was_owned = cbd->owned;
849 #endif
850     int     visual_selection = FALSE;
851 
852     if (cbd == &clip_star || cbd == &clip_plus)
853 	visual_selection = TRUE;
854 
855     clip_free_selection(cbd);
856     cbd->owned = FALSE;
857     if (visual_selection)
858 	clip_clear_selection(cbd);
859     clip_gen_lose_selection(cbd);
860 #ifdef FEAT_X11
861     if (visual_selection)
862     {
863 	// May have to show a different kind of highlighting for the selected
864 	// area.  There is no specific redraw command for this, just redraw all
865 	// windows on the current buffer.
866 	if (was_owned
867 		&& (get_real_state() == VISUAL
868 					    || get_real_state() == SELECTMODE)
869 		&& (cbd == &clip_star ?
870 				clip_isautosel_star() : clip_isautosel_plus())
871 		&& HL_ATTR(HLF_V) != HL_ATTR(HLF_VNC))
872 	{
873 	    update_curbuf(INVERTED_ALL);
874 	    setcursor();
875 	    cursor_on();
876 	    out_flush_cursor(TRUE, FALSE);
877 	}
878     }
879 #endif
880 }
881 
882     static void
883 clip_copy_selection(Clipboard_T *clip)
884 {
885     if (VIsual_active && (State & NORMAL) && clip->available)
886     {
887 	clip_update_selection(clip);
888 	clip_free_selection(clip);
889 	clip_own_selection(clip);
890 	if (clip->owned)
891 	    clip_get_selection(clip);
892 	clip_gen_set_selection(clip);
893     }
894 }
895 
896 /*
897  * Save and restore clip_unnamed before doing possibly many changes. This
898  * prevents accessing the clipboard very often which might slow down Vim
899  * considerably.
900  */
901 static int global_change_count = 0; // if set, inside a start_global_changes
902 static int clipboard_needs_update = FALSE; // clipboard needs to be updated
903 static int clip_did_set_selection = TRUE;
904 
905 /*
906  * Save clip_unnamed and reset it.
907  */
908     void
909 start_global_changes(void)
910 {
911     if (++global_change_count > 1)
912 	return;
913     clip_unnamed_saved = clip_unnamed;
914     clipboard_needs_update = FALSE;
915 
916     if (clip_did_set_selection)
917     {
918 	clip_unnamed = 0;
919 	clip_did_set_selection = FALSE;
920     }
921 }
922 
923 /*
924  * Return TRUE if setting the clipboard was postponed, it already contains the
925  * right text.
926  */
927     int
928 is_clipboard_needs_update()
929 {
930     return clipboard_needs_update;
931 }
932 
933 /*
934  * Restore clip_unnamed and set the selection when needed.
935  */
936     void
937 end_global_changes(void)
938 {
939     if (--global_change_count > 0)
940 	// recursive
941 	return;
942     if (!clip_did_set_selection)
943     {
944 	clip_did_set_selection = TRUE;
945 	clip_unnamed = clip_unnamed_saved;
946 	clip_unnamed_saved = 0;
947 	if (clipboard_needs_update)
948 	{
949 	    // only store something in the clipboard,
950 	    // if we have yanked anything to it
951 	    if (clip_unnamed & CLIP_UNNAMED)
952 	    {
953 		clip_own_selection(&clip_star);
954 		clip_gen_set_selection(&clip_star);
955 	    }
956 	    if (clip_unnamed & CLIP_UNNAMED_PLUS)
957 	    {
958 		clip_own_selection(&clip_plus);
959 		clip_gen_set_selection(&clip_plus);
960 	    }
961 	}
962     }
963     clipboard_needs_update = FALSE;
964 }
965 
966 /*
967  * Called when Visual mode is ended: update the selection.
968  */
969     void
970 clip_auto_select(void)
971 {
972     if (clip_isautosel_star())
973 	clip_copy_selection(&clip_star);
974     if (clip_isautosel_plus())
975 	clip_copy_selection(&clip_plus);
976 }
977 
978 /*
979  * Return TRUE if automatic selection of Visual area is desired for the *
980  * register.
981  */
982     int
983 clip_isautosel_star(void)
984 {
985     return (
986 #ifdef FEAT_GUI
987 	    gui.in_use ? (vim_strchr(p_go, GO_ASEL) != NULL) :
988 #endif
989 	    clip_autoselect_star);
990 }
991 
992 /*
993  * Return TRUE if automatic selection of Visual area is desired for the +
994  * register.
995  */
996     int
997 clip_isautosel_plus(void)
998 {
999     return (
1000 #ifdef FEAT_GUI
1001 	    gui.in_use ? (vim_strchr(p_go, GO_ASELPLUS) != NULL) :
1002 #endif
1003 	    clip_autoselect_plus);
1004 }
1005 
1006 
1007 /*
1008  * Stuff for general mouse selection, without using Visual mode.
1009  */
1010 
1011 static void clip_invert_area(Clipboard_T *, int, int, int, int, int how);
1012 static void clip_invert_rectangle(Clipboard_T *, int row, int col, int height, int width, int invert);
1013 static void clip_get_word_boundaries(Clipboard_T *, int, int);
1014 static int  clip_get_line_end(Clipboard_T *, int);
1015 static void clip_update_modeless_selection(Clipboard_T *, int, int, int, int);
1016 
1017 // "how" flags for clip_invert_area()
1018 #define CLIP_CLEAR	1
1019 #define CLIP_SET	2
1020 #define CLIP_TOGGLE	3
1021 
1022 /*
1023  * Start, continue or end a modeless selection.  Used when editing the
1024  * command-line, in the cmdline window and when the mouse is in a popup window.
1025  */
1026     void
1027 clip_modeless(int button, int is_click, int is_drag)
1028 {
1029     int		repeat;
1030 
1031     repeat = ((clip_star.mode == SELECT_MODE_CHAR
1032 		|| clip_star.mode == SELECT_MODE_LINE)
1033 					      && (mod_mask & MOD_MASK_2CLICK))
1034 	    || (clip_star.mode == SELECT_MODE_WORD
1035 					     && (mod_mask & MOD_MASK_3CLICK));
1036     if (is_click && button == MOUSE_RIGHT)
1037     {
1038 	// Right mouse button: If there was no selection, start one.
1039 	// Otherwise extend the existing selection.
1040 	if (clip_star.state == SELECT_CLEARED)
1041 	    clip_start_selection(mouse_col, mouse_row, FALSE);
1042 	clip_process_selection(button, mouse_col, mouse_row, repeat);
1043     }
1044     else if (is_click)
1045 	clip_start_selection(mouse_col, mouse_row, repeat);
1046     else if (is_drag)
1047     {
1048 	// Don't try extending a selection if there isn't one.  Happens when
1049 	// button-down is in the cmdline and them moving mouse upwards.
1050 	if (clip_star.state != SELECT_CLEARED)
1051 	    clip_process_selection(button, mouse_col, mouse_row, repeat);
1052     }
1053     else // release
1054 	clip_process_selection(MOUSE_RELEASE, mouse_col, mouse_row, FALSE);
1055 }
1056 
1057 /*
1058  * Compare two screen positions ala strcmp()
1059  */
1060     static int
1061 clip_compare_pos(
1062     int		row1,
1063     int		col1,
1064     int		row2,
1065     int		col2)
1066 {
1067     if (row1 > row2) return(1);
1068     if (row1 < row2) return(-1);
1069     if (col1 > col2) return(1);
1070     if (col1 < col2) return(-1);
1071     return(0);
1072 }
1073 
1074 /*
1075  * Start the selection
1076  */
1077     void
1078 clip_start_selection(int col, int row, int repeated_click)
1079 {
1080     Clipboard_T	*cb = &clip_star;
1081 #ifdef FEAT_PROP_POPUP
1082     win_T	*wp;
1083     int		row_cp = row;
1084     int		col_cp = col;
1085 
1086     wp = mouse_find_win(&row_cp, &col_cp, FIND_POPUP);
1087     if (wp != NULL && WIN_IS_POPUP(wp)
1088 				  && popup_is_in_scrollbar(wp, row_cp, col_cp))
1089 	// click or double click in scrollbar does not start a selection
1090 	return;
1091 #endif
1092 
1093     if (cb->state == SELECT_DONE)
1094 	clip_clear_selection(cb);
1095 
1096     row = check_row(row);
1097     col = check_col(col);
1098     col = mb_fix_col(col, row);
1099 
1100     cb->start.lnum  = row;
1101     cb->start.col   = col;
1102     cb->end	    = cb->start;
1103     cb->origin_row  = (short_u)cb->start.lnum;
1104     cb->state	    = SELECT_IN_PROGRESS;
1105 #ifdef FEAT_PROP_POPUP
1106     if (wp != NULL && WIN_IS_POPUP(wp))
1107     {
1108 	// Click in a popup window restricts selection to that window,
1109 	// excluding the border.
1110 	cb->min_col = wp->w_wincol + wp->w_popup_border[3];
1111 	cb->max_col = wp->w_wincol + popup_width(wp)
1112 				 - wp->w_popup_border[1] - wp->w_has_scrollbar;
1113 	if (cb->max_col > screen_Columns)
1114 	    cb->max_col = screen_Columns;
1115 	cb->min_row = wp->w_winrow + wp->w_popup_border[0];
1116 	cb->max_row = wp->w_winrow + popup_height(wp) - 1
1117 						   - wp->w_popup_border[2];
1118     }
1119     else
1120     {
1121 	cb->min_col = 0;
1122 	cb->max_col = screen_Columns;
1123 	cb->min_row = 0;
1124 	cb->max_row = screen_Rows;
1125     }
1126 #endif
1127 
1128     if (repeated_click)
1129     {
1130 	if (++cb->mode > SELECT_MODE_LINE)
1131 	    cb->mode = SELECT_MODE_CHAR;
1132     }
1133     else
1134 	cb->mode = SELECT_MODE_CHAR;
1135 
1136 #ifdef FEAT_GUI
1137     // clear the cursor until the selection is made
1138     if (gui.in_use)
1139 	gui_undraw_cursor();
1140 #endif
1141 
1142     switch (cb->mode)
1143     {
1144 	case SELECT_MODE_CHAR:
1145 	    cb->origin_start_col = cb->start.col;
1146 	    cb->word_end_col = clip_get_line_end(cb, (int)cb->start.lnum);
1147 	    break;
1148 
1149 	case SELECT_MODE_WORD:
1150 	    clip_get_word_boundaries(cb, (int)cb->start.lnum, cb->start.col);
1151 	    cb->origin_start_col = cb->word_start_col;
1152 	    cb->origin_end_col	 = cb->word_end_col;
1153 
1154 	    clip_invert_area(cb, (int)cb->start.lnum, cb->word_start_col,
1155 			    (int)cb->end.lnum, cb->word_end_col, CLIP_SET);
1156 	    cb->start.col = cb->word_start_col;
1157 	    cb->end.col   = cb->word_end_col;
1158 	    break;
1159 
1160 	case SELECT_MODE_LINE:
1161 	    clip_invert_area(cb, (int)cb->start.lnum, 0, (int)cb->start.lnum,
1162 			    (int)Columns, CLIP_SET);
1163 	    cb->start.col = 0;
1164 	    cb->end.col   = Columns;
1165 	    break;
1166     }
1167 
1168     cb->prev = cb->start;
1169 
1170 #ifdef DEBUG_SELECTION
1171     printf("Selection started at (%ld,%d)\n", cb->start.lnum, cb->start.col);
1172 #endif
1173 }
1174 
1175 /*
1176  * Continue processing the selection
1177  */
1178     void
1179 clip_process_selection(
1180     int		button,
1181     int		col,
1182     int		row,
1183     int_u	repeated_click)
1184 {
1185     Clipboard_T	*cb = &clip_star;
1186     int		diff;
1187     int		slen = 1;	// cursor shape width
1188 
1189     if (button == MOUSE_RELEASE)
1190     {
1191 	if (cb->state != SELECT_IN_PROGRESS)
1192 	    return;
1193 
1194 	// Check to make sure we have something selected
1195 	if (cb->start.lnum == cb->end.lnum && cb->start.col == cb->end.col)
1196 	{
1197 #ifdef FEAT_GUI
1198 	    if (gui.in_use)
1199 		gui_update_cursor(FALSE, FALSE);
1200 #endif
1201 	    cb->state = SELECT_CLEARED;
1202 	    return;
1203 	}
1204 
1205 #ifdef DEBUG_SELECTION
1206 	printf("Selection ended: (%ld,%d) to (%ld,%d)\n", cb->start.lnum,
1207 		cb->start.col, cb->end.lnum, cb->end.col);
1208 #endif
1209 	if (clip_isautosel_star()
1210 		|| (
1211 #ifdef FEAT_GUI
1212 		    gui.in_use ? (vim_strchr(p_go, GO_ASELML) != NULL) :
1213 #endif
1214 		    clip_autoselectml))
1215 	    clip_copy_modeless_selection(FALSE);
1216 #ifdef FEAT_GUI
1217 	if (gui.in_use)
1218 	    gui_update_cursor(FALSE, FALSE);
1219 #endif
1220 
1221 	cb->state = SELECT_DONE;
1222 	return;
1223     }
1224 
1225     row = check_row(row);
1226     col = check_col(col);
1227     col = mb_fix_col(col, row);
1228 
1229     if (col == (int)cb->prev.col && row == cb->prev.lnum && !repeated_click)
1230 	return;
1231 
1232     /*
1233      * When extending the selection with the right mouse button, swap the
1234      * start and end if the position is before half the selection
1235      */
1236     if (cb->state == SELECT_DONE && button == MOUSE_RIGHT)
1237     {
1238 	/*
1239 	 * If the click is before the start, or the click is inside the
1240 	 * selection and the start is the closest side, set the origin to the
1241 	 * end of the selection.
1242 	 */
1243 	if (clip_compare_pos(row, col, (int)cb->start.lnum, cb->start.col) < 0
1244 		|| (clip_compare_pos(row, col,
1245 					   (int)cb->end.lnum, cb->end.col) < 0
1246 		    && (((cb->start.lnum == cb->end.lnum
1247 			    && cb->end.col - col > col - cb->start.col))
1248 			|| ((diff = (cb->end.lnum - row) -
1249 						   (row - cb->start.lnum)) > 0
1250 			    || (diff == 0 && col < (int)(cb->start.col +
1251 							 cb->end.col) / 2)))))
1252 	{
1253 	    cb->origin_row = (short_u)cb->end.lnum;
1254 	    cb->origin_start_col = cb->end.col - 1;
1255 	    cb->origin_end_col = cb->end.col;
1256 	}
1257 	else
1258 	{
1259 	    cb->origin_row = (short_u)cb->start.lnum;
1260 	    cb->origin_start_col = cb->start.col;
1261 	    cb->origin_end_col = cb->start.col;
1262 	}
1263 	if (cb->mode == SELECT_MODE_WORD && !repeated_click)
1264 	    cb->mode = SELECT_MODE_CHAR;
1265     }
1266 
1267     // set state, for when using the right mouse button
1268     cb->state = SELECT_IN_PROGRESS;
1269 
1270 #ifdef DEBUG_SELECTION
1271     printf("Selection extending to (%d,%d)\n", row, col);
1272 #endif
1273 
1274     if (repeated_click && ++cb->mode > SELECT_MODE_LINE)
1275 	cb->mode = SELECT_MODE_CHAR;
1276 
1277     switch (cb->mode)
1278     {
1279 	case SELECT_MODE_CHAR:
1280 	    // If we're on a different line, find where the line ends
1281 	    if (row != cb->prev.lnum)
1282 		cb->word_end_col = clip_get_line_end(cb, row);
1283 
1284 	    // See if we are before or after the origin of the selection
1285 	    if (clip_compare_pos(row, col, cb->origin_row,
1286 						   cb->origin_start_col) >= 0)
1287 	    {
1288 		if (col >= (int)cb->word_end_col)
1289 		    clip_update_modeless_selection(cb, cb->origin_row,
1290 			    cb->origin_start_col, row, (int)Columns);
1291 		else
1292 		{
1293 		    if (has_mbyte && mb_lefthalve(row, col))
1294 			slen = 2;
1295 		    clip_update_modeless_selection(cb, cb->origin_row,
1296 			    cb->origin_start_col, row, col + slen);
1297 		}
1298 	    }
1299 	    else
1300 	    {
1301 		if (has_mbyte
1302 			&& mb_lefthalve(cb->origin_row, cb->origin_start_col))
1303 		    slen = 2;
1304 		if (col >= (int)cb->word_end_col)
1305 		    clip_update_modeless_selection(cb, row, cb->word_end_col,
1306 			    cb->origin_row, cb->origin_start_col + slen);
1307 		else
1308 		    clip_update_modeless_selection(cb, row, col,
1309 			    cb->origin_row, cb->origin_start_col + slen);
1310 	    }
1311 	    break;
1312 
1313 	case SELECT_MODE_WORD:
1314 	    // If we are still within the same word, do nothing
1315 	    if (row == cb->prev.lnum && col >= (int)cb->word_start_col
1316 		    && col < (int)cb->word_end_col && !repeated_click)
1317 		return;
1318 
1319 	    // Get new word boundaries
1320 	    clip_get_word_boundaries(cb, row, col);
1321 
1322 	    // Handle being after the origin point of selection
1323 	    if (clip_compare_pos(row, col, cb->origin_row,
1324 		    cb->origin_start_col) >= 0)
1325 		clip_update_modeless_selection(cb, cb->origin_row,
1326 			cb->origin_start_col, row, cb->word_end_col);
1327 	    else
1328 		clip_update_modeless_selection(cb, row, cb->word_start_col,
1329 			cb->origin_row, cb->origin_end_col);
1330 	    break;
1331 
1332 	case SELECT_MODE_LINE:
1333 	    if (row == cb->prev.lnum && !repeated_click)
1334 		return;
1335 
1336 	    if (clip_compare_pos(row, col, cb->origin_row,
1337 		    cb->origin_start_col) >= 0)
1338 		clip_update_modeless_selection(cb, cb->origin_row, 0, row,
1339 			(int)Columns);
1340 	    else
1341 		clip_update_modeless_selection(cb, row, 0, cb->origin_row,
1342 			(int)Columns);
1343 	    break;
1344     }
1345 
1346     cb->prev.lnum = row;
1347     cb->prev.col  = col;
1348 
1349 #ifdef DEBUG_SELECTION
1350 	printf("Selection is: (%ld,%d) to (%ld,%d)\n", cb->start.lnum,
1351 		cb->start.col, cb->end.lnum, cb->end.col);
1352 #endif
1353 }
1354 
1355 # if defined(FEAT_GUI) || defined(PROTO)
1356 /*
1357  * Redraw part of the selection if character at "row,col" is inside of it.
1358  * Only used for the GUI.
1359  */
1360     void
1361 clip_may_redraw_selection(int row, int col, int len)
1362 {
1363     int		start = col;
1364     int		end = col + len;
1365 
1366     if (clip_star.state != SELECT_CLEARED
1367 	    && row >= clip_star.start.lnum
1368 	    && row <= clip_star.end.lnum)
1369     {
1370 	if (row == clip_star.start.lnum && start < (int)clip_star.start.col)
1371 	    start = clip_star.start.col;
1372 	if (row == clip_star.end.lnum && end > (int)clip_star.end.col)
1373 	    end = clip_star.end.col;
1374 	if (end > start)
1375 	    clip_invert_area(&clip_star, row, start, row, end, 0);
1376     }
1377 }
1378 # endif
1379 
1380 /*
1381  * Called from outside to clear selected region from the display
1382  */
1383     void
1384 clip_clear_selection(Clipboard_T *cbd)
1385 {
1386 
1387     if (cbd->state == SELECT_CLEARED)
1388 	return;
1389 
1390     clip_invert_area(cbd, (int)cbd->start.lnum, cbd->start.col,
1391 				 (int)cbd->end.lnum, cbd->end.col, CLIP_CLEAR);
1392     cbd->state = SELECT_CLEARED;
1393 }
1394 
1395 /*
1396  * Clear the selection if any lines from "row1" to "row2" are inside of it.
1397  */
1398     void
1399 clip_may_clear_selection(int row1, int row2)
1400 {
1401     if (clip_star.state == SELECT_DONE
1402 	    && row2 >= clip_star.start.lnum
1403 	    && row1 <= clip_star.end.lnum)
1404 	clip_clear_selection(&clip_star);
1405 }
1406 
1407 /*
1408  * Called before the screen is scrolled up or down.  Adjusts the line numbers
1409  * of the selection.  Call with big number when clearing the screen.
1410  */
1411     void
1412 clip_scroll_selection(
1413     int	    rows)		// negative for scroll down
1414 {
1415     int	    lnum;
1416 
1417     if (clip_star.state == SELECT_CLEARED)
1418 	return;
1419 
1420     lnum = clip_star.start.lnum - rows;
1421     if (lnum <= 0)
1422 	clip_star.start.lnum = 0;
1423     else if (lnum >= screen_Rows)	// scrolled off of the screen
1424 	clip_star.state = SELECT_CLEARED;
1425     else
1426 	clip_star.start.lnum = lnum;
1427 
1428     lnum = clip_star.end.lnum - rows;
1429     if (lnum < 0)			// scrolled off of the screen
1430 	clip_star.state = SELECT_CLEARED;
1431     else if (lnum >= screen_Rows)
1432 	clip_star.end.lnum = screen_Rows - 1;
1433     else
1434 	clip_star.end.lnum = lnum;
1435 }
1436 
1437 /*
1438  * Invert a region of the display between a starting and ending row and column
1439  * Values for "how":
1440  * CLIP_CLEAR:  undo inversion
1441  * CLIP_SET:    set inversion
1442  * CLIP_TOGGLE: set inversion if pos1 < pos2, undo inversion otherwise.
1443  * 0: invert (GUI only).
1444  */
1445     static void
1446 clip_invert_area(
1447 	Clipboard_T	*cbd,
1448 	int		row1,
1449 	int		col1,
1450 	int		row2,
1451 	int		col2,
1452 	int		how)
1453 {
1454     int		invert = FALSE;
1455     int		max_col;
1456 
1457 #ifdef FEAT_PROP_POPUP
1458     max_col = cbd->max_col - 1;
1459 #else
1460     max_col = Columns - 1;
1461 #endif
1462 
1463     if (how == CLIP_SET)
1464 	invert = TRUE;
1465 
1466     // Swap the from and to positions so the from is always before
1467     if (clip_compare_pos(row1, col1, row2, col2) > 0)
1468     {
1469 	int tmp_row, tmp_col;
1470 
1471 	tmp_row = row1;
1472 	tmp_col = col1;
1473 	row1	= row2;
1474 	col1	= col2;
1475 	row2	= tmp_row;
1476 	col2	= tmp_col;
1477     }
1478     else if (how == CLIP_TOGGLE)
1479 	invert = TRUE;
1480 
1481     // If all on the same line, do it the easy way
1482     if (row1 == row2)
1483     {
1484 	clip_invert_rectangle(cbd, row1, col1, 1, col2 - col1, invert);
1485     }
1486     else
1487     {
1488 	// Handle a piece of the first line
1489 	if (col1 > 0)
1490 	{
1491 	    clip_invert_rectangle(cbd, row1, col1, 1,
1492 						  (int)Columns - col1, invert);
1493 	    row1++;
1494 	}
1495 
1496 	// Handle a piece of the last line
1497 	if (col2 < max_col)
1498 	{
1499 	    clip_invert_rectangle(cbd, row2, 0, 1, col2, invert);
1500 	    row2--;
1501 	}
1502 
1503 	// Handle the rectangle that's left
1504 	if (row2 >= row1)
1505 	    clip_invert_rectangle(cbd, row1, 0, row2 - row1 + 1,
1506 							 (int)Columns, invert);
1507     }
1508 }
1509 
1510 /*
1511  * Invert or un-invert a rectangle of the screen.
1512  * "invert" is true if the result is inverted.
1513  */
1514     static void
1515 clip_invert_rectangle(
1516 	Clipboard_T	*cbd UNUSED,
1517 	int		row_arg,
1518 	int		col_arg,
1519 	int		height_arg,
1520 	int		width_arg,
1521 	int		invert)
1522 {
1523     int		row = row_arg;
1524     int		col = col_arg;
1525     int		height = height_arg;
1526     int		width = width_arg;
1527 
1528 #ifdef FEAT_PROP_POPUP
1529     // this goes on top of all popup windows
1530     screen_zindex = CLIP_ZINDEX;
1531 
1532     if (col < cbd->min_col)
1533     {
1534 	width -= cbd->min_col - col;
1535 	col = cbd->min_col;
1536     }
1537     if (width > cbd->max_col - col)
1538 	width = cbd->max_col - col;
1539     if (row < cbd->min_row)
1540     {
1541 	height -= cbd->min_row - row;
1542 	row = cbd->min_row;
1543     }
1544     if (height > cbd->max_row - row + 1)
1545 	height = cbd->max_row - row + 1;
1546 #endif
1547 #ifdef FEAT_GUI
1548     if (gui.in_use)
1549 	gui_mch_invert_rectangle(row, col, height, width);
1550     else
1551 #endif
1552 	screen_draw_rectangle(row, col, height, width, invert);
1553 #ifdef FEAT_PROP_POPUP
1554     screen_zindex = 0;
1555 #endif
1556 }
1557 
1558 /*
1559  * Copy the currently selected area into the '*' register so it will be
1560  * available for pasting.
1561  * When "both" is TRUE also copy to the '+' register.
1562  */
1563     void
1564 clip_copy_modeless_selection(int both UNUSED)
1565 {
1566     char_u	*buffer;
1567     char_u	*bufp;
1568     int		row;
1569     int		start_col;
1570     int		end_col;
1571     int		line_end_col;
1572     int		add_newline_flag = FALSE;
1573     int		len;
1574     char_u	*p;
1575     int		row1 = clip_star.start.lnum;
1576     int		col1 = clip_star.start.col;
1577     int		row2 = clip_star.end.lnum;
1578     int		col2 = clip_star.end.col;
1579 
1580     // Can't use ScreenLines unless initialized
1581     if (ScreenLines == NULL)
1582 	return;
1583 
1584     /*
1585      * Make sure row1 <= row2, and if row1 == row2 that col1 <= col2.
1586      */
1587     if (row1 > row2)
1588     {
1589 	row = row1; row1 = row2; row2 = row;
1590 	row = col1; col1 = col2; col2 = row;
1591     }
1592     else if (row1 == row2 && col1 > col2)
1593     {
1594 	row = col1; col1 = col2; col2 = row;
1595     }
1596 #ifdef FEAT_PROP_POPUP
1597     if (col1 < clip_star.min_col)
1598 	col1 = clip_star.min_col;
1599     if (col2 > clip_star.max_col)
1600 	col2 = clip_star.max_col;
1601     if (row1 > clip_star.max_row || row2 < clip_star.min_row)
1602 	return;
1603     if (row1 < clip_star.min_row)
1604 	row1 = clip_star.min_row;
1605     if (row2 > clip_star.max_row)
1606 	row2 = clip_star.max_row;
1607 #endif
1608     // correct starting point for being on right halve of double-wide char
1609     p = ScreenLines + LineOffset[row1];
1610     if (enc_dbcs != 0)
1611 	col1 -= (*mb_head_off)(p, p + col1);
1612     else if (enc_utf8 && p[col1] == 0)
1613 	--col1;
1614 
1615     // Create a temporary buffer for storing the text
1616     len = (row2 - row1 + 1) * Columns + 1;
1617     if (enc_dbcs != 0)
1618 	len *= 2;	// max. 2 bytes per display cell
1619     else if (enc_utf8)
1620 	len *= MB_MAXBYTES;
1621     buffer = alloc(len);
1622     if (buffer == NULL)	    // out of memory
1623 	return;
1624 
1625     // Process each row in the selection
1626     for (bufp = buffer, row = row1; row <= row2; row++)
1627     {
1628 	if (row == row1)
1629 	    start_col = col1;
1630 	else
1631 #ifdef FEAT_PROP_POPUP
1632 	    start_col = clip_star.min_col;
1633 #else
1634 	    start_col = 0;
1635 #endif
1636 
1637 	if (row == row2)
1638 	    end_col = col2;
1639 	else
1640 #ifdef FEAT_PROP_POPUP
1641 	    end_col = clip_star.max_col;
1642 #else
1643 	    end_col = Columns;
1644 #endif
1645 
1646 	line_end_col = clip_get_line_end(&clip_star, row);
1647 
1648 	// See if we need to nuke some trailing whitespace
1649 	if (end_col >=
1650 #ifdef FEAT_PROP_POPUP
1651 		clip_star.max_col
1652 #else
1653 		Columns
1654 #endif
1655 		    && (row < row2 || end_col > line_end_col))
1656 	{
1657 	    // Get rid of trailing whitespace
1658 	    end_col = line_end_col;
1659 	    if (end_col < start_col)
1660 		end_col = start_col;
1661 
1662 	    // If the last line extended to the end, add an extra newline
1663 	    if (row == row2)
1664 		add_newline_flag = TRUE;
1665 	}
1666 
1667 	// If after the first row, we need to always add a newline
1668 	if (row > row1 && !LineWraps[row - 1])
1669 	    *bufp++ = NL;
1670 
1671 	// Safetey check for in case resizing went wrong
1672 	if (row < screen_Rows && end_col <= screen_Columns)
1673 	{
1674 	    if (enc_dbcs != 0)
1675 	    {
1676 		int	i;
1677 
1678 		p = ScreenLines + LineOffset[row];
1679 		for (i = start_col; i < end_col; ++i)
1680 		    if (enc_dbcs == DBCS_JPNU && p[i] == 0x8e)
1681 		    {
1682 			// single-width double-byte char
1683 			*bufp++ = 0x8e;
1684 			*bufp++ = ScreenLines2[LineOffset[row] + i];
1685 		    }
1686 		    else
1687 		    {
1688 			*bufp++ = p[i];
1689 			if (MB_BYTE2LEN(p[i]) == 2)
1690 			    *bufp++ = p[++i];
1691 		    }
1692 	    }
1693 	    else if (enc_utf8)
1694 	    {
1695 		int	off;
1696 		int	i;
1697 		int	ci;
1698 
1699 		off = LineOffset[row];
1700 		for (i = start_col; i < end_col; ++i)
1701 		{
1702 		    // The base character is either in ScreenLinesUC[] or
1703 		    // ScreenLines[].
1704 		    if (ScreenLinesUC[off + i] == 0)
1705 			*bufp++ = ScreenLines[off + i];
1706 		    else
1707 		    {
1708 			bufp += utf_char2bytes(ScreenLinesUC[off + i], bufp);
1709 			for (ci = 0; ci < Screen_mco; ++ci)
1710 			{
1711 			    // Add a composing character.
1712 			    if (ScreenLinesC[ci][off + i] == 0)
1713 				break;
1714 			    bufp += utf_char2bytes(ScreenLinesC[ci][off + i],
1715 									bufp);
1716 			}
1717 		    }
1718 		    // Skip right halve of double-wide character.
1719 		    if (ScreenLines[off + i + 1] == 0)
1720 			++i;
1721 		}
1722 	    }
1723 	    else
1724 	    {
1725 		STRNCPY(bufp, ScreenLines + LineOffset[row] + start_col,
1726 							 end_col - start_col);
1727 		bufp += end_col - start_col;
1728 	    }
1729 	}
1730     }
1731 
1732     // Add a newline at the end if the selection ended there
1733     if (add_newline_flag)
1734 	*bufp++ = NL;
1735 
1736     // First cleanup any old selection and become the owner.
1737     clip_free_selection(&clip_star);
1738     clip_own_selection(&clip_star);
1739 
1740     // Yank the text into the '*' register.
1741     clip_yank_selection(MCHAR, buffer, (long)(bufp - buffer), &clip_star);
1742 
1743     // Make the register contents available to the outside world.
1744     clip_gen_set_selection(&clip_star);
1745 
1746 #ifdef FEAT_X11
1747     if (both)
1748     {
1749 	// Do the same for the '+' register.
1750 	clip_free_selection(&clip_plus);
1751 	clip_own_selection(&clip_plus);
1752 	clip_yank_selection(MCHAR, buffer, (long)(bufp - buffer), &clip_plus);
1753 	clip_gen_set_selection(&clip_plus);
1754     }
1755 #endif
1756     vim_free(buffer);
1757 }
1758 
1759 /*
1760  * Find the starting and ending positions of the word at the given row and
1761  * column.  Only white-separated words are recognized here.
1762  */
1763 #define CHAR_CLASS(c)	(c <= ' ' ? ' ' : vim_iswordc(c))
1764 
1765     static void
1766 clip_get_word_boundaries(Clipboard_T *cb, int row, int col)
1767 {
1768     int		start_class;
1769     int		temp_col;
1770     char_u	*p;
1771     int		mboff;
1772 
1773     if (row >= screen_Rows || col >= screen_Columns || ScreenLines == NULL)
1774 	return;
1775 
1776     p = ScreenLines + LineOffset[row];
1777     // Correct for starting in the right halve of a double-wide char
1778     if (enc_dbcs != 0)
1779 	col -= dbcs_screen_head_off(p, p + col);
1780     else if (enc_utf8 && p[col] == 0)
1781 	--col;
1782     start_class = CHAR_CLASS(p[col]);
1783 
1784     temp_col = col;
1785     for ( ; temp_col > 0; temp_col--)
1786 	if (enc_dbcs != 0
1787 		   && (mboff = dbcs_screen_head_off(p, p + temp_col - 1)) > 0)
1788 	    temp_col -= mboff;
1789 	else if (CHAR_CLASS(p[temp_col - 1]) != start_class
1790 		&& !(enc_utf8 && p[temp_col - 1] == 0))
1791 	    break;
1792     cb->word_start_col = temp_col;
1793 
1794     temp_col = col;
1795     for ( ; temp_col < screen_Columns; temp_col++)
1796 	if (enc_dbcs != 0 && dbcs_ptr2cells(p + temp_col) == 2)
1797 	    ++temp_col;
1798 	else if (CHAR_CLASS(p[temp_col]) != start_class
1799 		&& !(enc_utf8 && p[temp_col] == 0))
1800 	    break;
1801     cb->word_end_col = temp_col;
1802 }
1803 
1804 /*
1805  * Find the column position for the last non-whitespace character on the given
1806  * line at or before start_col.
1807  */
1808     static int
1809 clip_get_line_end(Clipboard_T *cbd UNUSED, int row)
1810 {
1811     int	    i;
1812 
1813     if (row >= screen_Rows || ScreenLines == NULL)
1814 	return 0;
1815     for (i =
1816 #ifdef FEAT_PROP_POPUP
1817 	    cbd->max_col;
1818 #else
1819 	    screen_Columns;
1820 #endif
1821 			    i > 0; i--)
1822 	if (ScreenLines[LineOffset[row] + i - 1] != ' ')
1823 	    break;
1824     return i;
1825 }
1826 
1827 /*
1828  * Update the currently selected region by adding and/or subtracting from the
1829  * beginning or end and inverting the changed area(s).
1830  */
1831     static void
1832 clip_update_modeless_selection(
1833     Clipboard_T    *cb,
1834     int		    row1,
1835     int		    col1,
1836     int		    row2,
1837     int		    col2)
1838 {
1839     // See if we changed at the beginning of the selection
1840     if (row1 != cb->start.lnum || col1 != (int)cb->start.col)
1841     {
1842 	clip_invert_area(cb, row1, col1, (int)cb->start.lnum, cb->start.col,
1843 								 CLIP_TOGGLE);
1844 	cb->start.lnum = row1;
1845 	cb->start.col  = col1;
1846     }
1847 
1848     // See if we changed at the end of the selection
1849     if (row2 != cb->end.lnum || col2 != (int)cb->end.col)
1850     {
1851 	clip_invert_area(cb, (int)cb->end.lnum, cb->end.col, row2, col2,
1852 								 CLIP_TOGGLE);
1853 	cb->end.lnum = row2;
1854 	cb->end.col  = col2;
1855     }
1856 }
1857 
1858     static int
1859 clip_gen_own_selection(Clipboard_T *cbd)
1860 {
1861 #ifdef FEAT_XCLIPBOARD
1862 # ifdef FEAT_GUI
1863     if (gui.in_use)
1864 	return clip_mch_own_selection(cbd);
1865     else
1866 # endif
1867 	return clip_xterm_own_selection(cbd);
1868 #else
1869     return clip_mch_own_selection(cbd);
1870 #endif
1871 }
1872 
1873     static void
1874 clip_gen_lose_selection(Clipboard_T *cbd)
1875 {
1876 #ifdef FEAT_XCLIPBOARD
1877 # ifdef FEAT_GUI
1878     if (gui.in_use)
1879 	clip_mch_lose_selection(cbd);
1880     else
1881 # endif
1882 	clip_xterm_lose_selection(cbd);
1883 #else
1884     clip_mch_lose_selection(cbd);
1885 #endif
1886 }
1887 
1888     void
1889 clip_gen_set_selection(Clipboard_T *cbd)
1890 {
1891     if (!clip_did_set_selection)
1892     {
1893 	// Updating postponed, so that accessing the system clipboard won't
1894 	// hang Vim when accessing it many times (e.g. on a :g command).
1895 	if ((cbd == &clip_plus && (clip_unnamed_saved & CLIP_UNNAMED_PLUS))
1896 		|| (cbd == &clip_star && (clip_unnamed_saved & CLIP_UNNAMED)))
1897 	{
1898 	    clipboard_needs_update = TRUE;
1899 	    return;
1900 	}
1901     }
1902 #ifdef FEAT_XCLIPBOARD
1903 # ifdef FEAT_GUI
1904     if (gui.in_use)
1905 	clip_mch_set_selection(cbd);
1906     else
1907 # endif
1908 	clip_xterm_set_selection(cbd);
1909 #else
1910     clip_mch_set_selection(cbd);
1911 #endif
1912 }
1913 
1914     void
1915 clip_gen_request_selection(Clipboard_T *cbd)
1916 {
1917 #ifdef FEAT_XCLIPBOARD
1918 # ifdef FEAT_GUI
1919     if (gui.in_use)
1920 	clip_mch_request_selection(cbd);
1921     else
1922 # endif
1923 	clip_xterm_request_selection(cbd);
1924 #else
1925     clip_mch_request_selection(cbd);
1926 #endif
1927 }
1928 
1929 #if (defined(FEAT_X11) && defined(USE_SYSTEM)) || defined(PROTO)
1930     int
1931 clip_gen_owner_exists(Clipboard_T *cbd UNUSED)
1932 {
1933 #ifdef FEAT_XCLIPBOARD
1934 # ifdef FEAT_GUI_GTK
1935     if (gui.in_use)
1936 	return clip_gtk_owner_exists(cbd);
1937     else
1938 # endif
1939 	return clip_x11_owner_exists(cbd);
1940 #else
1941     return TRUE;
1942 #endif
1943 }
1944 #endif
1945 
1946 /*
1947  * Extract the items in the 'clipboard' option and set global values.
1948  * Return an error message or NULL for success.
1949  */
1950     char *
1951 check_clipboard_option(void)
1952 {
1953     int		new_unnamed = 0;
1954     int		new_autoselect_star = FALSE;
1955     int		new_autoselect_plus = FALSE;
1956     int		new_autoselectml = FALSE;
1957     int		new_html = FALSE;
1958     regprog_T	*new_exclude_prog = NULL;
1959     char	*errmsg = NULL;
1960     char_u	*p;
1961 
1962     for (p = p_cb; *p != NUL; )
1963     {
1964 	if (STRNCMP(p, "unnamed", 7) == 0 && (p[7] == ',' || p[7] == NUL))
1965 	{
1966 	    new_unnamed |= CLIP_UNNAMED;
1967 	    p += 7;
1968 	}
1969 	else if (STRNCMP(p, "unnamedplus", 11) == 0
1970 					    && (p[11] == ',' || p[11] == NUL))
1971 	{
1972 	    new_unnamed |= CLIP_UNNAMED_PLUS;
1973 	    p += 11;
1974 	}
1975 	else if (STRNCMP(p, "autoselect", 10) == 0
1976 					    && (p[10] == ',' || p[10] == NUL))
1977 	{
1978 	    new_autoselect_star = TRUE;
1979 	    p += 10;
1980 	}
1981 	else if (STRNCMP(p, "autoselectplus", 14) == 0
1982 					    && (p[14] == ',' || p[14] == NUL))
1983 	{
1984 	    new_autoselect_plus = TRUE;
1985 	    p += 14;
1986 	}
1987 	else if (STRNCMP(p, "autoselectml", 12) == 0
1988 					    && (p[12] == ',' || p[12] == NUL))
1989 	{
1990 	    new_autoselectml = TRUE;
1991 	    p += 12;
1992 	}
1993 	else if (STRNCMP(p, "html", 4) == 0 && (p[4] == ',' || p[4] == NUL))
1994 	{
1995 	    new_html = TRUE;
1996 	    p += 4;
1997 	}
1998 	else if (STRNCMP(p, "exclude:", 8) == 0 && new_exclude_prog == NULL)
1999 	{
2000 	    p += 8;
2001 	    new_exclude_prog = vim_regcomp(p, RE_MAGIC);
2002 	    if (new_exclude_prog == NULL)
2003 		errmsg = e_invarg;
2004 	    break;
2005 	}
2006 	else
2007 	{
2008 	    errmsg = e_invarg;
2009 	    break;
2010 	}
2011 	if (*p == ',')
2012 	    ++p;
2013     }
2014     if (errmsg == NULL)
2015     {
2016 	clip_unnamed = new_unnamed;
2017 	clip_autoselect_star = new_autoselect_star;
2018 	clip_autoselect_plus = new_autoselect_plus;
2019 	clip_autoselectml = new_autoselectml;
2020 	clip_html = new_html;
2021 	vim_regfree(clip_exclude_prog);
2022 	clip_exclude_prog = new_exclude_prog;
2023 #ifdef FEAT_GUI_GTK
2024 	if (gui.in_use)
2025 	{
2026 	    gui_gtk_set_selection_targets();
2027 	    gui_gtk_set_dnd_targets();
2028 	}
2029 #endif
2030     }
2031     else
2032 	vim_regfree(new_exclude_prog);
2033 
2034     return errmsg;
2035 }
2036 
2037 #endif // FEAT_CLIPBOARD
2038 
2039 //////////////////////////////////////////////////////////////////////////////
2040 // Functions that handle the input buffer.
2041 // This is used for any GUI version, and the unix terminal version.
2042 //
2043 // For Unix, the input characters are buffered to be able to check for a
2044 // CTRL-C.  This should be done with signals, but I don't know how to do that
2045 // in a portable way for a tty in RAW mode.
2046 //
2047 // For the client-server code in the console the received keys are put in the
2048 // input buffer.
2049 
2050 #if defined(USE_INPUT_BUF) || defined(PROTO)
2051 
2052 /*
2053  * Internal typeahead buffer.  Includes extra space for long key code
2054  * descriptions which would otherwise overflow.  The buffer is considered full
2055  * when only this extra space (or part of it) remains.
2056  */
2057 #if defined(FEAT_JOB_CHANNEL) || defined(FEAT_CLIENTSERVER)
2058    /*
2059     * NetBeans stuffs debugger commands into the input buffer.
2060     * This requires a larger buffer...
2061     * (Madsen) Go with this for remote input as well ...
2062     */
2063 # define INBUFLEN 4096
2064 #else
2065 # define INBUFLEN 250
2066 #endif
2067 
2068 static char_u	inbuf[INBUFLEN + MAX_KEY_CODE_LEN];
2069 static int	inbufcount = 0;	    // number of chars in inbuf[]
2070 
2071 /*
2072  * vim_is_input_buf_full(), vim_is_input_buf_empty(), add_to_input_buf(), and
2073  * trash_input_buf() are functions for manipulating the input buffer.  These
2074  * are used by the gui_* calls when a GUI is used to handle keyboard input.
2075  */
2076 
2077     int
2078 vim_is_input_buf_full(void)
2079 {
2080     return (inbufcount >= INBUFLEN);
2081 }
2082 
2083     int
2084 vim_is_input_buf_empty(void)
2085 {
2086     return (inbufcount == 0);
2087 }
2088 
2089 #if defined(FEAT_OLE) || defined(PROTO)
2090     int
2091 vim_free_in_input_buf(void)
2092 {
2093     return (INBUFLEN - inbufcount);
2094 }
2095 #endif
2096 
2097 #if defined(FEAT_GUI_GTK) || defined(PROTO)
2098     int
2099 vim_used_in_input_buf(void)
2100 {
2101     return inbufcount;
2102 }
2103 #endif
2104 
2105 /*
2106  * Return the current contents of the input buffer and make it empty.
2107  * The returned pointer must be passed to set_input_buf() later.
2108  */
2109     char_u *
2110 get_input_buf(void)
2111 {
2112     garray_T	*gap;
2113 
2114     // We use a growarray to store the data pointer and the length.
2115     gap = ALLOC_ONE(garray_T);
2116     if (gap != NULL)
2117     {
2118 	// Add one to avoid a zero size.
2119 	gap->ga_data = alloc(inbufcount + 1);
2120 	if (gap->ga_data != NULL)
2121 	    mch_memmove(gap->ga_data, inbuf, (size_t)inbufcount);
2122 	gap->ga_len = inbufcount;
2123     }
2124     trash_input_buf();
2125     return (char_u *)gap;
2126 }
2127 
2128 /*
2129  * Restore the input buffer with a pointer returned from get_input_buf().
2130  * The allocated memory is freed, this only works once!
2131  */
2132     void
2133 set_input_buf(char_u *p)
2134 {
2135     garray_T	*gap = (garray_T *)p;
2136 
2137     if (gap != NULL)
2138     {
2139 	if (gap->ga_data != NULL)
2140 	{
2141 	    mch_memmove(inbuf, gap->ga_data, gap->ga_len);
2142 	    inbufcount = gap->ga_len;
2143 	    vim_free(gap->ga_data);
2144 	}
2145 	vim_free(gap);
2146     }
2147 }
2148 
2149 /*
2150  * Add the given bytes to the input buffer
2151  * Special keys start with CSI.  A real CSI must have been translated to
2152  * CSI KS_EXTRA KE_CSI.  K_SPECIAL doesn't require translation.
2153  */
2154     void
2155 add_to_input_buf(char_u *s, int len)
2156 {
2157     if (inbufcount + len > INBUFLEN + MAX_KEY_CODE_LEN)
2158 	return;	    // Shouldn't ever happen!
2159 
2160     while (len--)
2161 	inbuf[inbufcount++] = *s++;
2162 }
2163 
2164 /*
2165  * Add "str[len]" to the input buffer while escaping CSI bytes.
2166  */
2167     void
2168 add_to_input_buf_csi(char_u *str, int len)
2169 {
2170     int		i;
2171     char_u	buf[2];
2172 
2173     for (i = 0; i < len; ++i)
2174     {
2175 	add_to_input_buf(str + i, 1);
2176 	if (str[i] == CSI)
2177 	{
2178 	    // Turn CSI into K_CSI.
2179 	    buf[0] = KS_EXTRA;
2180 	    buf[1] = (int)KE_CSI;
2181 	    add_to_input_buf(buf, 2);
2182 	}
2183     }
2184 }
2185 
2186 /*
2187  * Remove everything from the input buffer.  Called when ^C is found.
2188  */
2189     void
2190 trash_input_buf(void)
2191 {
2192     inbufcount = 0;
2193 }
2194 
2195 /*
2196  * Read as much data from the input buffer as possible up to maxlen, and store
2197  * it in buf.
2198  */
2199     int
2200 read_from_input_buf(char_u *buf, long maxlen)
2201 {
2202     if (inbufcount == 0)	// if the buffer is empty, fill it
2203 	fill_input_buf(TRUE);
2204     if (maxlen > inbufcount)
2205 	maxlen = inbufcount;
2206     mch_memmove(buf, inbuf, (size_t)maxlen);
2207     inbufcount -= maxlen;
2208     if (inbufcount)
2209 	mch_memmove(inbuf, inbuf + maxlen, (size_t)inbufcount);
2210     return (int)maxlen;
2211 }
2212 
2213     void
2214 fill_input_buf(int exit_on_error UNUSED)
2215 {
2216 #if defined(UNIX) || defined(VMS) || defined(MACOS_X)
2217     int		len;
2218     int		try;
2219     static int	did_read_something = FALSE;
2220     static char_u *rest = NULL;	    // unconverted rest of previous read
2221     static int	restlen = 0;
2222     int		unconverted;
2223 #endif
2224 
2225 #ifdef FEAT_GUI
2226     if (gui.in_use
2227 # ifdef NO_CONSOLE_INPUT
2228     // Don't use the GUI input when the window hasn't been opened yet.
2229     // We get here from ui_inchar() when we should try reading from stdin.
2230 	    && !no_console_input()
2231 # endif
2232        )
2233     {
2234 	gui_mch_update();
2235 	return;
2236     }
2237 #endif
2238 #if defined(UNIX) || defined(VMS) || defined(MACOS_X)
2239     if (vim_is_input_buf_full())
2240 	return;
2241     /*
2242      * Fill_input_buf() is only called when we really need a character.
2243      * If we can't get any, but there is some in the buffer, just return.
2244      * If we can't get any, and there isn't any in the buffer, we give up and
2245      * exit Vim.
2246      */
2247 # ifdef __BEOS__
2248     /*
2249      * On the BeBox version (for now), all input is secretly performed within
2250      * beos_select() which is called from RealWaitForChar().
2251      */
2252     while (!vim_is_input_buf_full() && RealWaitForChar(read_cmd_fd, 0, NULL))
2253 	    ;
2254     len = inbufcount;
2255     inbufcount = 0;
2256 # else
2257 
2258     if (rest != NULL)
2259     {
2260 	// Use remainder of previous call, starts with an invalid character
2261 	// that may become valid when reading more.
2262 	if (restlen > INBUFLEN - inbufcount)
2263 	    unconverted = INBUFLEN - inbufcount;
2264 	else
2265 	    unconverted = restlen;
2266 	mch_memmove(inbuf + inbufcount, rest, unconverted);
2267 	if (unconverted == restlen)
2268 	    VIM_CLEAR(rest);
2269 	else
2270 	{
2271 	    restlen -= unconverted;
2272 	    mch_memmove(rest, rest + unconverted, restlen);
2273 	}
2274 	inbufcount += unconverted;
2275     }
2276     else
2277 	unconverted = 0;
2278 
2279     len = 0;	// to avoid gcc warning
2280     for (try = 0; try < 100; ++try)
2281     {
2282 	size_t readlen = (size_t)((INBUFLEN - inbufcount)
2283 			    / input_conv.vc_factor);
2284 #  ifdef VMS
2285 	len = vms_read((char *)inbuf + inbufcount, readlen);
2286 #  else
2287 	len = read(read_cmd_fd, (char *)inbuf + inbufcount, readlen);
2288 #  endif
2289 
2290 	if (len > 0 || got_int)
2291 	    break;
2292 	/*
2293 	 * If reading stdin results in an error, continue reading stderr.
2294 	 * This helps when using "foo | xargs vim".
2295 	 */
2296 	if (!did_read_something && !isatty(read_cmd_fd) && read_cmd_fd == 0)
2297 	{
2298 	    int m = cur_tmode;
2299 
2300 	    // We probably set the wrong file descriptor to raw mode.  Switch
2301 	    // back to cooked mode, use another descriptor and set the mode to
2302 	    // what it was.
2303 	    settmode(TMODE_COOK);
2304 #ifdef HAVE_DUP
2305 	    // Use stderr for stdin, also works for shell commands.
2306 	    close(0);
2307 	    vim_ignored = dup(2);
2308 #else
2309 	    read_cmd_fd = 2;	// read from stderr instead of stdin
2310 #endif
2311 	    settmode(m);
2312 	}
2313 	if (!exit_on_error)
2314 	    return;
2315     }
2316 # endif
2317     if (len <= 0 && !got_int)
2318 	read_error_exit();
2319     if (len > 0)
2320 	did_read_something = TRUE;
2321     if (got_int)
2322     {
2323 	// Interrupted, pretend a CTRL-C was typed.
2324 	inbuf[0] = 3;
2325 	inbufcount = 1;
2326     }
2327     else
2328     {
2329 	/*
2330 	 * May perform conversion on the input characters.
2331 	 * Include the unconverted rest of the previous call.
2332 	 * If there is an incomplete char at the end it is kept for the next
2333 	 * time, reading more bytes should make conversion possible.
2334 	 * Don't do this in the unlikely event that the input buffer is too
2335 	 * small ("rest" still contains more bytes).
2336 	 */
2337 	if (input_conv.vc_type != CONV_NONE)
2338 	{
2339 	    inbufcount -= unconverted;
2340 	    len = convert_input_safe(inbuf + inbufcount,
2341 				     len + unconverted, INBUFLEN - inbufcount,
2342 				       rest == NULL ? &rest : NULL, &restlen);
2343 	}
2344 	while (len-- > 0)
2345 	{
2346 	    /*
2347 	     * if a CTRL-C was typed, remove it from the buffer and set got_int
2348 	     */
2349 	    if (inbuf[inbufcount] == 3 && ctrl_c_interrupts)
2350 	    {
2351 		// remove everything typed before the CTRL-C
2352 		mch_memmove(inbuf, inbuf + inbufcount, (size_t)(len + 1));
2353 		inbufcount = 0;
2354 		got_int = TRUE;
2355 	    }
2356 	    ++inbufcount;
2357 	}
2358     }
2359 #endif // UNIX || VMS || MACOS_X
2360 }
2361 #endif // USE_INPUT_BUF
2362 
2363 /*
2364  * Exit because of an input read error.
2365  */
2366     void
2367 read_error_exit(void)
2368 {
2369     if (silent_mode)	// Normal way to exit for "ex -s"
2370 	getout(0);
2371     STRCPY(IObuff, _("Vim: Error reading input, exiting...\n"));
2372     preserve_exit();
2373 }
2374 
2375 #if defined(CURSOR_SHAPE) || defined(PROTO)
2376 /*
2377  * May update the shape of the cursor.
2378  */
2379     void
2380 ui_cursor_shape_forced(int forced)
2381 {
2382 # ifdef FEAT_GUI
2383     if (gui.in_use)
2384 	gui_update_cursor_later();
2385     else
2386 # endif
2387 	term_cursor_mode(forced);
2388 
2389 # ifdef MCH_CURSOR_SHAPE
2390     mch_update_cursor();
2391 # endif
2392 
2393 # ifdef FEAT_CONCEAL
2394     conceal_check_cursor_line();
2395 # endif
2396 }
2397 
2398     void
2399 ui_cursor_shape(void)
2400 {
2401     ui_cursor_shape_forced(FALSE);
2402 }
2403 #endif
2404 
2405 /*
2406  * Check bounds for column number
2407  */
2408     int
2409 check_col(int col)
2410 {
2411     if (col < 0)
2412 	return 0;
2413     if (col >= (int)screen_Columns)
2414 	return (int)screen_Columns - 1;
2415     return col;
2416 }
2417 
2418 /*
2419  * Check bounds for row number
2420  */
2421     int
2422 check_row(int row)
2423 {
2424     if (row < 0)
2425 	return 0;
2426     if (row >= (int)screen_Rows)
2427 	return (int)screen_Rows - 1;
2428     return row;
2429 }
2430 
2431 /*
2432  * Stuff for the X clipboard.  Shared between VMS and Unix.
2433  */
2434 
2435 #if defined(FEAT_XCLIPBOARD) || defined(FEAT_GUI_X11) || defined(PROTO)
2436 # include <X11/Xatom.h>
2437 # include <X11/Intrinsic.h>
2438 
2439 /*
2440  * Open the application context (if it hasn't been opened yet).
2441  * Used for Motif and Athena GUI and the xterm clipboard.
2442  */
2443     void
2444 open_app_context(void)
2445 {
2446     if (app_context == NULL)
2447     {
2448 	XtToolkitInitialize();
2449 	app_context = XtCreateApplicationContext();
2450     }
2451 }
2452 
2453 static Atom	vim_atom;	// Vim's own special selection format
2454 static Atom	vimenc_atom;	// Vim's extended selection format
2455 static Atom	utf8_atom;
2456 static Atom	compound_text_atom;
2457 static Atom	text_atom;
2458 static Atom	targets_atom;
2459 static Atom	timestamp_atom;	// Used to get a timestamp
2460 
2461     void
2462 x11_setup_atoms(Display *dpy)
2463 {
2464     vim_atom	       = XInternAtom(dpy, VIM_ATOM_NAME,   False);
2465     vimenc_atom	       = XInternAtom(dpy, VIMENC_ATOM_NAME,False);
2466     utf8_atom	       = XInternAtom(dpy, "UTF8_STRING",   False);
2467     compound_text_atom = XInternAtom(dpy, "COMPOUND_TEXT", False);
2468     text_atom	       = XInternAtom(dpy, "TEXT",	   False);
2469     targets_atom       = XInternAtom(dpy, "TARGETS",	   False);
2470     clip_star.sel_atom = XA_PRIMARY;
2471     clip_plus.sel_atom = XInternAtom(dpy, "CLIPBOARD",	   False);
2472     timestamp_atom     = XInternAtom(dpy, "TIMESTAMP",	   False);
2473 }
2474 
2475 /*
2476  * X Selection stuff, for cutting and pasting text to other windows.
2477  */
2478 
2479 static Boolean	clip_x11_convert_selection_cb(Widget w, Atom *sel_atom, Atom *target, Atom *type, XtPointer *value, long_u *length, int *format);
2480 static void clip_x11_lose_ownership_cb(Widget w, Atom *sel_atom);
2481 static void clip_x11_notify_cb(Widget w, Atom *sel_atom, Atom *target);
2482 
2483 /*
2484  * Property callback to get a timestamp for XtOwnSelection.
2485  */
2486     static void
2487 clip_x11_timestamp_cb(
2488     Widget	w,
2489     XtPointer	n UNUSED,
2490     XEvent	*event,
2491     Boolean	*cont UNUSED)
2492 {
2493     Atom	    actual_type;
2494     int		    format;
2495     unsigned  long  nitems, bytes_after;
2496     unsigned char   *prop=NULL;
2497     XPropertyEvent  *xproperty=&event->xproperty;
2498 
2499     // Must be a property notify, state can't be Delete (True), has to be
2500     // one of the supported selection types.
2501     if (event->type != PropertyNotify || xproperty->state
2502 	    || (xproperty->atom != clip_star.sel_atom
2503 				    && xproperty->atom != clip_plus.sel_atom))
2504 	return;
2505 
2506     if (XGetWindowProperty(xproperty->display, xproperty->window,
2507 	  xproperty->atom, 0, 0, False, timestamp_atom, &actual_type, &format,
2508 						&nitems, &bytes_after, &prop))
2509 	return;
2510 
2511     if (prop)
2512 	XFree(prop);
2513 
2514     // Make sure the property type is "TIMESTAMP" and it's 32 bits.
2515     if (actual_type != timestamp_atom || format != 32)
2516 	return;
2517 
2518     // Get the selection, using the event timestamp.
2519     if (XtOwnSelection(w, xproperty->atom, xproperty->time,
2520 	    clip_x11_convert_selection_cb, clip_x11_lose_ownership_cb,
2521 	    clip_x11_notify_cb) == OK)
2522     {
2523 	// Set the "owned" flag now, there may have been a call to
2524 	// lose_ownership_cb in between.
2525 	if (xproperty->atom == clip_plus.sel_atom)
2526 	    clip_plus.owned = TRUE;
2527 	else
2528 	    clip_star.owned = TRUE;
2529     }
2530 }
2531 
2532     void
2533 x11_setup_selection(Widget w)
2534 {
2535     XtAddEventHandler(w, PropertyChangeMask, False,
2536 	    /*(XtEventHandler)*/clip_x11_timestamp_cb, (XtPointer)NULL);
2537 }
2538 
2539     static void
2540 clip_x11_request_selection_cb(
2541     Widget	w UNUSED,
2542     XtPointer	success,
2543     Atom	*sel_atom,
2544     Atom	*type,
2545     XtPointer	value,
2546     long_u	*length,
2547     int		*format)
2548 {
2549     int		motion_type = MAUTO;
2550     long_u	len;
2551     char_u	*p;
2552     char	**text_list = NULL;
2553     Clipboard_T	*cbd;
2554     char_u	*tmpbuf = NULL;
2555 
2556     if (*sel_atom == clip_plus.sel_atom)
2557 	cbd = &clip_plus;
2558     else
2559 	cbd = &clip_star;
2560 
2561     if (value == NULL || *length == 0)
2562     {
2563 	clip_free_selection(cbd);	// nothing received, clear register
2564 	*(int *)success = FALSE;
2565 	return;
2566     }
2567     p = (char_u *)value;
2568     len = *length;
2569     if (*type == vim_atom)
2570     {
2571 	motion_type = *p++;
2572 	len--;
2573     }
2574 
2575     else if (*type == vimenc_atom)
2576     {
2577 	char_u		*enc;
2578 	vimconv_T	conv;
2579 	int		convlen;
2580 
2581 	motion_type = *p++;
2582 	--len;
2583 
2584 	enc = p;
2585 	p += STRLEN(p) + 1;
2586 	len -= p - enc;
2587 
2588 	// If the encoding of the text is different from 'encoding', attempt
2589 	// converting it.
2590 	conv.vc_type = CONV_NONE;
2591 	convert_setup(&conv, enc, p_enc);
2592 	if (conv.vc_type != CONV_NONE)
2593 	{
2594 	    convlen = len;	// Need to use an int here.
2595 	    tmpbuf = string_convert(&conv, p, &convlen);
2596 	    len = convlen;
2597 	    if (tmpbuf != NULL)
2598 		p = tmpbuf;
2599 	    convert_setup(&conv, NULL, NULL);
2600 	}
2601     }
2602 
2603     else if (*type == compound_text_atom
2604 	    || *type == utf8_atom
2605 	    || (enc_dbcs != 0 && *type == text_atom))
2606     {
2607 	XTextProperty	text_prop;
2608 	int		n_text = 0;
2609 	int		status;
2610 
2611 	text_prop.value = (unsigned char *)value;
2612 	text_prop.encoding = *type;
2613 	text_prop.format = *format;
2614 	text_prop.nitems = len;
2615 #if defined(X_HAVE_UTF8_STRING)
2616 	if (*type == utf8_atom)
2617 	    status = Xutf8TextPropertyToTextList(X_DISPLAY, &text_prop,
2618 							 &text_list, &n_text);
2619 	else
2620 #endif
2621 	    status = XmbTextPropertyToTextList(X_DISPLAY, &text_prop,
2622 							 &text_list, &n_text);
2623 	if (status != Success || n_text < 1)
2624 	{
2625 	    *(int *)success = FALSE;
2626 	    return;
2627 	}
2628 	p = (char_u *)text_list[0];
2629 	len = STRLEN(p);
2630     }
2631     clip_yank_selection(motion_type, p, (long)len, cbd);
2632 
2633     if (text_list != NULL)
2634 	XFreeStringList(text_list);
2635     vim_free(tmpbuf);
2636     XtFree((char *)value);
2637     *(int *)success = TRUE;
2638 }
2639 
2640     void
2641 clip_x11_request_selection(
2642     Widget	myShell,
2643     Display	*dpy,
2644     Clipboard_T	*cbd)
2645 {
2646     XEvent	event;
2647     Atom	type;
2648     static int	success;
2649     int		i;
2650     time_t	start_time;
2651     int		timed_out = FALSE;
2652 
2653     for (i = 0; i < 6; i++)
2654     {
2655 	switch (i)
2656 	{
2657 	    case 0:  type = vimenc_atom;	break;
2658 	    case 1:  type = vim_atom;		break;
2659 	    case 2:  type = utf8_atom;		break;
2660 	    case 3:  type = compound_text_atom; break;
2661 	    case 4:  type = text_atom;		break;
2662 	    default: type = XA_STRING;
2663 	}
2664 	if (type == utf8_atom
2665 # if defined(X_HAVE_UTF8_STRING)
2666 		&& !enc_utf8
2667 # endif
2668 		)
2669 	    // Only request utf-8 when 'encoding' is utf8 and
2670 	    // Xutf8TextPropertyToTextList is available.
2671 	    continue;
2672 	success = MAYBE;
2673 	XtGetSelectionValue(myShell, cbd->sel_atom, type,
2674 	    clip_x11_request_selection_cb, (XtPointer)&success, CurrentTime);
2675 
2676 	// Make sure the request for the selection goes out before waiting for
2677 	// a response.
2678 	XFlush(dpy);
2679 
2680 	/*
2681 	 * Wait for result of selection request, otherwise if we type more
2682 	 * characters, then they will appear before the one that requested the
2683 	 * paste!  Don't worry, we will catch up with any other events later.
2684 	 */
2685 	start_time = time(NULL);
2686 	while (success == MAYBE)
2687 	{
2688 	    if (XCheckTypedEvent(dpy, PropertyNotify, &event)
2689 		    || XCheckTypedEvent(dpy, SelectionNotify, &event)
2690 		    || XCheckTypedEvent(dpy, SelectionRequest, &event))
2691 	    {
2692 		// This is where clip_x11_request_selection_cb() should be
2693 		// called.  It may actually happen a bit later, so we loop
2694 		// until "success" changes.
2695 		// We may get a SelectionRequest here and if we don't handle
2696 		// it we hang.  KDE klipper does this, for example.
2697 		// We need to handle a PropertyNotify for large selections.
2698 		XtDispatchEvent(&event);
2699 		continue;
2700 	    }
2701 
2702 	    // Time out after 2 to 3 seconds to avoid that we hang when the
2703 	    // other process doesn't respond.  Note that the SelectionNotify
2704 	    // event may still come later when the selection owner comes back
2705 	    // to life and the text gets inserted unexpectedly.  Don't know
2706 	    // why that happens or how to avoid that :-(.
2707 	    if (time(NULL) > start_time + 2)
2708 	    {
2709 		timed_out = TRUE;
2710 		break;
2711 	    }
2712 
2713 	    // Do we need this?  Probably not.
2714 	    XSync(dpy, False);
2715 
2716 	    // Wait for 1 msec to avoid that we eat up all CPU time.
2717 	    ui_delay(1L, TRUE);
2718 	}
2719 
2720 	if (success == TRUE)
2721 	    return;
2722 
2723 	// don't do a retry with another type after timing out, otherwise we
2724 	// hang for 15 seconds.
2725 	if (timed_out)
2726 	    break;
2727     }
2728 
2729     // Final fallback position - use the X CUT_BUFFER0 store
2730     yank_cut_buffer0(dpy, cbd);
2731 }
2732 
2733     static Boolean
2734 clip_x11_convert_selection_cb(
2735     Widget	w UNUSED,
2736     Atom	*sel_atom,
2737     Atom	*target,
2738     Atom	*type,
2739     XtPointer	*value,
2740     long_u	*length,
2741     int		*format)
2742 {
2743     static char_u   *save_result = NULL;
2744     static long_u   save_length = 0;
2745     char_u	    *string;
2746     int		    motion_type;
2747     Clipboard_T    *cbd;
2748     int		    i;
2749 
2750     if (*sel_atom == clip_plus.sel_atom)
2751 	cbd = &clip_plus;
2752     else
2753 	cbd = &clip_star;
2754 
2755     if (!cbd->owned)
2756 	return False;	    // Shouldn't ever happen
2757 
2758     // requestor wants to know what target types we support
2759     if (*target == targets_atom)
2760     {
2761 	static Atom array[7];
2762 
2763 	*value = (XtPointer)array;
2764 	i = 0;
2765 	array[i++] = targets_atom;
2766 	array[i++] = vimenc_atom;
2767 	array[i++] = vim_atom;
2768 	if (enc_utf8)
2769 	    array[i++] = utf8_atom;
2770 	array[i++] = XA_STRING;
2771 	array[i++] = text_atom;
2772 	array[i++] = compound_text_atom;
2773 
2774 	*type = XA_ATOM;
2775 	// This used to be: *format = sizeof(Atom) * 8; but that caused
2776 	// crashes on 64 bit machines. (Peter Derr)
2777 	*format = 32;
2778 	*length = i;
2779 	return True;
2780     }
2781 
2782     if (       *target != XA_STRING
2783 	    && *target != vimenc_atom
2784 	    && (*target != utf8_atom || !enc_utf8)
2785 	    && *target != vim_atom
2786 	    && *target != text_atom
2787 	    && *target != compound_text_atom)
2788 	return False;
2789 
2790     clip_get_selection(cbd);
2791     motion_type = clip_convert_selection(&string, length, cbd);
2792     if (motion_type < 0)
2793 	return False;
2794 
2795     // For our own format, the first byte contains the motion type
2796     if (*target == vim_atom)
2797 	(*length)++;
2798 
2799     // Our own format with encoding: motion 'encoding' NUL text
2800     if (*target == vimenc_atom)
2801 	*length += STRLEN(p_enc) + 2;
2802 
2803     if (save_length < *length || save_length / 2 >= *length)
2804 	*value = XtRealloc((char *)save_result, (Cardinal)*length + 1);
2805     else
2806 	*value = save_result;
2807     if (*value == NULL)
2808     {
2809 	vim_free(string);
2810 	return False;
2811     }
2812     save_result = (char_u *)*value;
2813     save_length = *length;
2814 
2815     if (*target == XA_STRING || (*target == utf8_atom && enc_utf8))
2816     {
2817 	mch_memmove(save_result, string, (size_t)(*length));
2818 	*type = *target;
2819     }
2820     else if (*target == compound_text_atom || *target == text_atom)
2821     {
2822 	XTextProperty	text_prop;
2823 	char		*string_nt = (char *)save_result;
2824 	int		conv_result;
2825 
2826 	// create NUL terminated string which XmbTextListToTextProperty wants
2827 	mch_memmove(string_nt, string, (size_t)*length);
2828 	string_nt[*length] = NUL;
2829 	conv_result = XmbTextListToTextProperty(X_DISPLAY, (char **)&string_nt,
2830 					   1, XCompoundTextStyle, &text_prop);
2831 	if (conv_result != Success)
2832 	{
2833 	    vim_free(string);
2834 	    return False;
2835 	}
2836 	*value = (XtPointer)(text_prop.value);	//    from plain text
2837 	*length = text_prop.nitems;
2838 	*type = compound_text_atom;
2839 	XtFree((char *)save_result);
2840 	save_result = (char_u *)*value;
2841 	save_length = *length;
2842     }
2843     else if (*target == vimenc_atom)
2844     {
2845 	int l = STRLEN(p_enc);
2846 
2847 	save_result[0] = motion_type;
2848 	STRCPY(save_result + 1, p_enc);
2849 	mch_memmove(save_result + l + 2, string, (size_t)(*length - l - 2));
2850 	*type = vimenc_atom;
2851     }
2852     else
2853     {
2854 	save_result[0] = motion_type;
2855 	mch_memmove(save_result + 1, string, (size_t)(*length - 1));
2856 	*type = vim_atom;
2857     }
2858     *format = 8;	    // 8 bits per char
2859     vim_free(string);
2860     return True;
2861 }
2862 
2863     static void
2864 clip_x11_lose_ownership_cb(Widget w UNUSED, Atom *sel_atom)
2865 {
2866     if (*sel_atom == clip_plus.sel_atom)
2867 	clip_lose_selection(&clip_plus);
2868     else
2869 	clip_lose_selection(&clip_star);
2870 }
2871 
2872     void
2873 clip_x11_lose_selection(Widget myShell, Clipboard_T *cbd)
2874 {
2875     XtDisownSelection(myShell, cbd->sel_atom,
2876 				XtLastTimestampProcessed(XtDisplay(myShell)));
2877 }
2878 
2879     static void
2880 clip_x11_notify_cb(Widget w UNUSED, Atom *sel_atom UNUSED, Atom *target UNUSED)
2881 {
2882     // To prevent automatically freeing the selection value.
2883 }
2884 
2885     int
2886 clip_x11_own_selection(Widget myShell, Clipboard_T *cbd)
2887 {
2888     // When using the GUI we have proper timestamps, use the one of the last
2889     // event.  When in the console we don't get events (the terminal gets
2890     // them), Get the time by a zero-length append, clip_x11_timestamp_cb will
2891     // be called with the current timestamp.
2892 #ifdef FEAT_GUI
2893     if (gui.in_use)
2894     {
2895 	if (XtOwnSelection(myShell, cbd->sel_atom,
2896 	       XtLastTimestampProcessed(XtDisplay(myShell)),
2897 	       clip_x11_convert_selection_cb, clip_x11_lose_ownership_cb,
2898 	       clip_x11_notify_cb) == False)
2899 	    return FAIL;
2900     }
2901     else
2902 #endif
2903     {
2904 	if (!XChangeProperty(XtDisplay(myShell), XtWindow(myShell),
2905 		  cbd->sel_atom, timestamp_atom, 32, PropModeAppend, NULL, 0))
2906 	    return FAIL;
2907     }
2908     // Flush is required in a terminal as nothing else is doing it.
2909     XFlush(XtDisplay(myShell));
2910     return OK;
2911 }
2912 
2913 /*
2914  * Send the current selection to the clipboard.  Do nothing for X because we
2915  * will fill in the selection only when requested by another app.
2916  */
2917     void
2918 clip_x11_set_selection(Clipboard_T *cbd UNUSED)
2919 {
2920 }
2921 
2922 #if (defined(FEAT_X11) && defined(FEAT_XCLIPBOARD) && defined(USE_SYSTEM)) \
2923 	|| defined(PROTO)
2924     static int
2925 clip_x11_owner_exists(Clipboard_T *cbd)
2926 {
2927     return XGetSelectionOwner(X_DISPLAY, cbd->sel_atom) != None;
2928 }
2929 #endif
2930 #endif
2931 
2932 #if defined(FEAT_XCLIPBOARD) || defined(FEAT_GUI_X11) \
2933     || defined(FEAT_GUI_GTK) || defined(PROTO)
2934 /*
2935  * Get the contents of the X CUT_BUFFER0 and put it in "cbd".
2936  */
2937     void
2938 yank_cut_buffer0(Display *dpy, Clipboard_T *cbd)
2939 {
2940     int		nbytes = 0;
2941     char_u	*buffer = (char_u *)XFetchBuffer(dpy, &nbytes, 0);
2942 
2943     if (nbytes > 0)
2944     {
2945 	int  done = FALSE;
2946 
2947 	// CUT_BUFFER0 is supposed to be always latin1.  Convert to 'enc' when
2948 	// using a multi-byte encoding.  Conversion between two 8-bit
2949 	// character sets usually fails and the text might actually be in
2950 	// 'enc' anyway.
2951 	if (has_mbyte)
2952 	{
2953 	    char_u	*conv_buf;
2954 	    vimconv_T	vc;
2955 
2956 	    vc.vc_type = CONV_NONE;
2957 	    if (convert_setup(&vc, (char_u *)"latin1", p_enc) == OK)
2958 	    {
2959 		conv_buf = string_convert(&vc, buffer, &nbytes);
2960 		if (conv_buf != NULL)
2961 		{
2962 		    clip_yank_selection(MCHAR, conv_buf, (long)nbytes, cbd);
2963 		    vim_free(conv_buf);
2964 		    done = TRUE;
2965 		}
2966 		convert_setup(&vc, NULL, NULL);
2967 	    }
2968 	}
2969 	if (!done)  // use the text without conversion
2970 	    clip_yank_selection(MCHAR, buffer, (long)nbytes, cbd);
2971 	XFree((void *)buffer);
2972 	if (p_verbose > 0)
2973 	{
2974 	    verbose_enter();
2975 	    verb_msg(_("Used CUT_BUFFER0 instead of empty selection"));
2976 	    verbose_leave();
2977 	}
2978     }
2979 }
2980 #endif
2981 
2982 #if defined(FEAT_GUI) || defined(MSWIN) || defined(PROTO)
2983 /*
2984  * Called when focus changed.  Used for the GUI or for systems where this can
2985  * be done in the console (Win32).
2986  */
2987     void
2988 ui_focus_change(
2989     int		in_focus)	// TRUE if focus gained.
2990 {
2991     static time_t	last_time = (time_t)0;
2992     int			need_redraw = FALSE;
2993 
2994     // When activated: Check if any file was modified outside of Vim.
2995     // Only do this when not done within the last two seconds (could get
2996     // several events in a row).
2997     if (in_focus && last_time + 2 < time(NULL))
2998     {
2999 	need_redraw = check_timestamps(
3000 # ifdef FEAT_GUI
3001 		gui.in_use
3002 # else
3003 		FALSE
3004 # endif
3005 		);
3006 	last_time = time(NULL);
3007     }
3008 
3009     /*
3010      * Fire the focus gained/lost autocommand.
3011      */
3012     need_redraw |= apply_autocmds(in_focus ? EVENT_FOCUSGAINED
3013 				: EVENT_FOCUSLOST, NULL, NULL, FALSE, curbuf);
3014 
3015     if (need_redraw)
3016     {
3017 	// Something was executed, make sure the cursor is put back where it
3018 	// belongs.
3019 	need_wait_return = FALSE;
3020 
3021 	if (State & CMDLINE)
3022 	    redrawcmdline();
3023 	else if (State == HITRETURN || State == SETWSIZE || State == ASKMORE
3024 		|| State == EXTERNCMD || State == CONFIRM || exmode_active)
3025 	    repeat_message();
3026 	else if ((State & NORMAL) || (State & INSERT))
3027 	{
3028 	    if (must_redraw != 0)
3029 		update_screen(0);
3030 	    setcursor();
3031 	}
3032 	cursor_on();	    // redrawing may have switched it off
3033 	out_flush_cursor(FALSE, TRUE);
3034 # ifdef FEAT_GUI
3035 	if (gui.in_use)
3036 	    gui_update_scrollbars(FALSE);
3037 # endif
3038     }
3039 #ifdef FEAT_TITLE
3040     // File may have been changed from 'readonly' to 'noreadonly'
3041     if (need_maketitle)
3042 	maketitle();
3043 #endif
3044 }
3045 #endif
3046 
3047 #if defined(HAVE_INPUT_METHOD) || defined(PROTO)
3048 /*
3049  * Save current Input Method status to specified place.
3050  */
3051     void
3052 im_save_status(long *psave)
3053 {
3054     // Don't save when 'imdisable' is set or "xic" is NULL, IM is always
3055     // disabled then (but might start later).
3056     // Also don't save when inside a mapping, vgetc_im_active has not been set
3057     // then.
3058     // And don't save when the keys were stuffed (e.g., for a "." command).
3059     // And don't save when the GUI is running but our window doesn't have
3060     // input focus (e.g., when a find dialog is open).
3061     if (!p_imdisable && KeyTyped && !KeyStuffed
3062 # ifdef FEAT_XIM
3063 	    && xic != NULL
3064 # endif
3065 # ifdef FEAT_GUI
3066 	    && (!gui.in_use || gui.in_focus)
3067 # endif
3068 	)
3069     {
3070 	// Do save when IM is on, or IM is off and saved status is on.
3071 	if (vgetc_im_active)
3072 	    *psave = B_IMODE_IM;
3073 	else if (*psave == B_IMODE_IM)
3074 	    *psave = B_IMODE_NONE;
3075     }
3076 }
3077 #endif
3078