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