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