* clear out some warnings by gcc 9.3.1.
[alpine.git] / pico / basic.c
blob65ba6cc960f3e0df7082f197360f12bbb2dd1029
1 #if !defined(lint) && !defined(DOS)
2 static char rcsid[] = "$Id: basic.c 831 2007-11-27 01:04:19Z hubert@u.washington.edu $";
3 #endif
5 /*
6 * ========================================================================
7 * Copyright 2006-2007 University of Washington
8 * Copyright 2013-2020 Eduardo Chappa
10 * Licensed under the Apache License, Version 2.0 (the "License");
11 * you may not use this file except in compliance with the License.
12 * You may obtain a copy of the License at
14 * http://www.apache.org/licenses/LICENSE-2.0
16 * ========================================================================
18 * Program: Cursor manipulation functions
22 * The routines in this file move the cursor around on the screen. They
23 * compute a new value for the cursor, then adjust ".". The display code
24 * always updates the cursor location, so only moves between lines, or
25 * functions that adjust the top line in the window and invalidate the
26 * framing, are hard.
28 #include "headers.h"
30 #include "osdep/terminal.h"
34 * Move the cursor to the
35 * beginning of the current line.
36 * Trivial.
38 int
39 gotobol(int f, int n)
41 curwp->w_doto = 0;
42 return (TRUE);
46 * Move the cursor backwards by "n" characters. If "n" is less than zero call
47 * "forwchar" to actually do the move. Otherwise compute the new cursor
48 * location. Error if you try and move out of the buffer. Set the flag if the
49 * line pointer for dot changes.
51 int
52 backchar(int f, int n)
54 register LINE *lp;
56 if (n < 0)
57 return (forwchar(f, -n));
59 while (n--) {
60 if (curwp->w_doto == 0) {
61 if ((lp=lback(curwp->w_dotp)) == curbp->b_linep){
62 if(Pmaster && Pmaster->headents)
64 * go up into editing the mail header if on
65 * the top line and the user hits the left arrow!!!
67 * if the editor returns anything except -1, the
68 * user requested something special, so let
69 * pico know...
71 return(HeaderEditor(2, 1));
72 else
73 return (FALSE);
76 curwp->w_dotp = lp;
77 curwp->w_doto = llength(lp);
78 curwp->w_flag |= WFMOVE;
79 } else
80 curwp->w_doto--;
83 return (TRUE);
87 * Move the cursor backwards by "n" characters. If "n" is less than zero call
88 * "forwchar" to actually do the move. Otherwise compute the new cursor
89 * location. Error if you try and move out of the buffer. Set the flag if the
90 * line pointer for dot changes.
92 * This routine does _not_ do the header editor checks. It is used by
93 * backword() in pico\word.c which gets stuck in a loop trying to go
94 * back if you've jumped into a header.
96 int
97 backchar_no_header_editor(int f, int n)
99 register LINE *lp;
101 if (n < 0)
102 return (forwchar(f, -n));
104 while (n--) {
105 if (curwp->w_doto == 0) {
106 if ((lp=lback(curwp->w_dotp)) == curbp->b_linep){
107 return (FALSE);
110 curwp->w_dotp = lp;
111 curwp->w_doto = llength(lp);
112 curwp->w_flag |= WFMOVE;
113 } else
114 curwp->w_doto--;
117 return (TRUE);
121 * Move the cursor to the end of the current line. Trivial. No errors.
124 gotoeol(int f, int n)
126 curwp->w_doto = llength(curwp->w_dotp);
127 return (TRUE);
132 * Move the cursor forwwards by "n" characters. If "n" is less than zero call
133 * "backchar" to actually do the move. Otherwise compute the new cursor
134 * location, and move ".". Error if you try and move off the end of the
135 * buffer. Set the flag if the line pointer for dot changes.
138 forwchar(int f, int n)
140 if (n < 0)
141 return (backchar(f, -n));
143 while (n--) {
144 if (curwp->w_doto == llength(curwp->w_dotp)) {
145 if (curwp->w_dotp == curbp->b_linep)
146 return (FALSE);
148 curwp->w_dotp = lforw(curwp->w_dotp);
149 curwp->w_doto = 0;
150 curwp->w_flag |= WFMOVE;
152 else
153 curwp->w_doto++;
156 return (TRUE);
161 * move to a particular line.
162 * argument (n) must be a positive integer for
163 * this to actually do anything
166 gotoline(int f, int n)
168 if (n < 1) /* if a bogus argument...then leave */
169 return(FALSE);
171 /* first, we go to the start of the buffer */
172 curwp->w_dotp = lforw(curbp->b_linep);
173 curwp->w_doto = 0;
174 return(forwline(f, n-1));
179 * Goto the beginning of the buffer. Massive adjustment of dot. This is
180 * considered to be hard motion; it really isn't if the original value of dot
181 * is the same as the new value of dot. Normally bound to "M-<".
184 gotobob(int f, int n)
186 curwp->w_dotp = lforw(curbp->b_linep);
187 curwp->w_doto = 0;
188 curwp->w_flag |= WFHARD;
189 return (TRUE);
194 * Move to the end of the buffer. Dot is always put at the end of the file
195 * (ZJ). The standard screen code does most of the hard parts of update.
196 * Bound to "M->".
199 gotoeob(int f, int n)
201 curwp->w_dotp = curbp->b_linep;
202 curwp->w_doto = 0;
203 curwp->w_flag |= WFHARD;
204 return (TRUE);
209 * Move forward by full lines. If the number of lines to move is less than
210 * zero, call the backward line function to actually do it. The last command
211 * controls how the goal column is set. Bound to "C-N". No errors are
212 * possible.
215 forwline(int f, int n)
217 register LINE *dlp;
219 if (n < 0)
220 return (backline(f, -n));
222 if ((lastflag&CFCPCN) == 0) /* Reset goal if last */
223 curgoal = getccol(FALSE); /* not C-P or C-N */
225 thisflag |= CFCPCN;
226 dlp = curwp->w_dotp;
227 while (n-- && dlp!=curbp->b_linep)
228 dlp = lforw(dlp);
230 curwp->w_dotp = dlp;
231 curwp->w_doto = getgoal(dlp);
232 curwp->w_flag |= WFMOVE;
233 return (TRUE);
238 * This function is like "forwline", but goes backwards. The scheme is exactly
239 * the same. Check for arguments that are less than zero and call your
240 * alternate. Figure out the new line and call "movedot" to perform the
241 * motion. No errors are possible. Bound to "C-P".
244 backline(int f, int n)
246 register LINE *dlp;
248 if (n < 0)
249 return (forwline(f, -n));
251 if(Pmaster && Pmaster->headents){
253 * go up into editing the mail header if on the top line
254 * and the user hits the up arrow!!!
256 if (lback(curwp->w_dotp) == curbp->b_linep)
258 * if the editor returns anything except -1 then the user
259 * has requested something special, so let pico know...
261 return(HeaderEditor(1, 1));
264 if ((lastflag&CFCPCN) == 0) /* Reset goal if the */
265 curgoal = getccol(FALSE); /* last isn't C-P, C-N */
267 thisflag |= CFCPCN;
268 dlp = curwp->w_dotp;
269 while (n-- && lback(dlp)!=curbp->b_linep)
270 dlp = lback(dlp);
272 curwp->w_dotp = dlp;
273 curwp->w_doto = getgoal(dlp);
274 curwp->w_flag |= WFMOVE;
275 return (TRUE);
280 * go back to the beginning of the current paragraph
281 * here we look for a <NL><NL> or <NL><TAB> or <NL><SPACE>
282 * combination to delimit the beginning of a paragraph
285 gotobop(int f, int n)
287 int quoted, qlen;
288 UCS qstr[NLINE], qstr2[NLINE];
290 if (n < 0) /* the other way...*/
291 return(gotoeop(f, -n));
293 while (n-- > 0) { /* for each one asked for */
295 while(lisblank(curwp->w_dotp)
296 && lback(curwp->w_dotp) != curbp->b_linep){
297 curwp->w_dotp = lback(curwp->w_dotp);
298 curwp->w_doto = 0;
301 /* scan line by line until we come to a line ending with
302 * a <NL><NL> or <NL><TAB> or <NL><SPACE>
304 * PLUS: if there's a quote string, a quoted-to-non-quoted
305 * line transition.
307 quoted = quote_match(glo_quote_str, curwp->w_dotp, qstr, NLINE);
308 qlen = quoted ? ucs4_strlen(qstr) : 0;
309 while(lback(curwp->w_dotp) != curbp->b_linep
310 && llength(lback(curwp->w_dotp)) > qlen
311 && quoted == quote_match(glo_quote_str,
312 lback(curwp->w_dotp),
313 qstr2, NLINE)
314 && !ucs4_strcmp(qstr, qstr2)
315 && lgetc(curwp->w_dotp, qlen).c != TAB
316 && lgetc(curwp->w_dotp, qlen).c != ' ')
317 curwp->w_dotp = lback(curwp->w_dotp);
319 if(n){
320 /* keep looking */
321 if(lback(curwp->w_dotp) == curbp->b_linep)
322 break;
323 else
324 curwp->w_dotp = lback(curwp->w_dotp);
326 curwp->w_doto = 0;
328 else{
329 /* leave cursor on first word in para */
330 curwp->w_doto = 0;
331 while(ucs4_isspace(lgetc(curwp->w_dotp, curwp->w_doto).c))
332 if(++curwp->w_doto >= llength(curwp->w_dotp)){
333 curwp->w_doto = 0;
334 curwp->w_dotp = lforw(curwp->w_dotp);
335 if(curwp->w_dotp == curbp->b_linep)
336 break;
341 curwp->w_flag |= WFMOVE; /* force screen update */
342 return(TRUE);
347 * go forword to the end of the current paragraph
348 * here we look for a <NL><NL> or <NL><TAB> or <NL><SPACE>
349 * combination to delimit the beginning of a paragraph
352 gotoeop(int f, int n)
354 int quoted, qlen;
355 UCS qstr[NLINE], qstr2[NLINE];
357 if (n < 0) /* the other way...*/
358 return(gotobop(f, -n));
360 while (n-- > 0) { /* for each one asked for */
362 while(lisblank(curwp->w_dotp)){
363 curwp->w_doto = 0;
364 if((curwp->w_dotp = lforw(curwp->w_dotp)) == curbp->b_linep)
365 break;
368 /* scan line by line until we come to a line ending with
369 * a <NL><NL> or <NL><TAB> or <NL><SPACE>
371 * PLUS: if there's a quote string, a quoted-to-non-quoted
372 * line transition.
374 quoted = quote_match(glo_quote_str,
375 curwp->w_dotp, qstr, NLINE);
376 qlen = quoted ? ucs4_strlen(qstr) : 0;
378 while(curwp->w_dotp != curbp->b_linep
379 && llength(lforw(curwp->w_dotp)) > qlen
380 && (quoted == quote_match(glo_quote_str,
381 lforw(curwp->w_dotp),
382 qstr2, NLINE)
383 && !ucs4_strcmp(qstr, qstr2))
384 && lgetc(lforw(curwp->w_dotp), qlen).c != TAB
385 && lgetc(lforw(curwp->w_dotp), qlen).c != ' ')
386 curwp->w_dotp = lforw(curwp->w_dotp);
388 curwp->w_doto = llength(curwp->w_dotp);
390 /* still looking? */
391 if(n){
392 if(curwp->w_dotp == curbp->b_linep)
393 break;
394 else
395 curwp->w_dotp = lforw(curwp->w_dotp);
397 curwp->w_doto = 0;
401 curwp->w_flag |= WFMOVE; /* force screen update */
402 return(curwp->w_dotp != curbp->b_linep);
406 * This routine, given a pointer to a LINE, and the current cursor goal
407 * column, return the best choice for the offset. The offset is returned.
408 * Used by "C-N" and "C-P".
411 getgoal(LINE *dlp)
413 UCS c;
414 register int col;
415 register int newcol;
416 register int dbo;
418 col = 0;
419 dbo = 0;
420 while (dbo != llength(dlp)) {
421 c = lgetc(dlp, dbo).c;
422 newcol = col;
424 if (c == '\t'){
425 newcol |= 0x07;
426 ++newcol;
428 else if (ISCONTROL(c)){
429 newcol += 2;
431 else{
432 int w;
434 w = wcellwidth(c);
435 newcol += (w >= 0 ? w : 1);
438 if (newcol > curgoal)
439 break;
441 col = newcol;
442 ++dbo;
445 return (dbo);
450 * Scroll the display forward (up) n lines.
453 scrollforw(int n, int movedot)
455 register LINE *lp;
456 LINE *lp2;
457 register int nl;
458 int i;
460 nl = n;
461 lp = curwp->w_linep;
462 while (n-- && lp!=curbp->b_linep)
463 lp = lforw(lp);
465 if (movedot) { /* Move dot to top of page. */
466 curwp->w_dotp = lp;
467 curwp->w_doto = 0;
470 curwp->w_flag |= WFHARD;
471 if(lp == curbp->b_linep)
472 return(TRUE);
473 else
474 curwp->w_linep = lp;
477 * if the header is open, close it ...
479 if(Pmaster && Pmaster->headents && ComposerTopLine != COMPOSER_TOP_LINE){
480 n -= ComposerTopLine - COMPOSER_TOP_LINE;
481 ToggleHeader(0);
485 * scroll down from the top the same number of lines we've moved
486 * forward
488 if(TERM_OPTIMIZE)
489 scrollup(curwp, -1, nl-n-1);
491 if(!movedot){
492 /* Requested to not move the dot. Look for the dot in the current
493 * window. loop through all lines, stop when at end of window
494 * or endof buffer. If the dot is found, it can stay where it
495 * is, otherwise we do need to move it.
497 movedot = TRUE;
498 for ( lp2 = lp, i = 0;
499 lp2 != curbp->b_linep && i < curwp->w_ntrows;
500 lp2 = lforw(lp2), ++i) {
501 if (curwp->w_dotp == lp2) {
502 movedot = FALSE;
503 break;
506 if (movedot) {
507 /* Dot not found in window. Move to first line of window. */
508 curwp->w_dotp = lp;
509 curwp->w_doto = 0;
513 return (TRUE);
518 * Scroll forward by a specified number of lines, or by a full page if no
519 * argument. Bound to "C-V". The "2" in the arithmetic on the window size is
520 * the overlap; this value is the default overlap value in ITS EMACS. Because
521 * this zaps the top line in the display window, we have to do a hard update.
524 forwpage(int f, int n)
527 if (f == FALSE) {
528 n = curwp->w_ntrows - 2; /* Default scroll. */
529 if (n <= 0) /* Forget the overlap */
530 n = 1; /* if tiny window. */
531 } else if (n < 0)
532 return (backpage(f, -n));
533 #if CVMVAS
534 else /* Convert from pages */
535 n *= curwp->w_ntrows; /* to lines. */
536 #endif
537 return (scrollforw (n, TRUE));
542 * Scroll back (down) number of lines.
545 scrollback(int n, int movedot)
547 register LINE *lp, *tp;
548 register int nl;
549 int i;
551 if(Pmaster && Pmaster->headents){
553 * go up into editing the mail header if on the top line
554 * and the user hits the up arrow!!!
556 if (lback(curwp->w_dotp) == curbp->b_linep){
558 * if the editor returns anything except -1 then the user
559 * has requested something special, so let pico know...
561 return(HeaderEditor(1, 1));
566 * Count back the number of lines requested.
568 nl = n;
569 lp = curwp->w_linep;
570 while (n-- && lback(lp)!=curbp->b_linep)
571 lp = lback(lp);
573 curwp->w_linep = lp;
574 curwp->w_flag |= WFHARD;
577 * scroll down from the top the same number of lines we've moved
578 * forward
580 * This isn't too cool, but it has to be this way so we can
581 * gracefully scroll in the message header
583 if(Pmaster && Pmaster->headents){
584 if((lback(lp)==curbp->b_linep) && (ComposerTopLine==COMPOSER_TOP_LINE))
585 n -= entry_line(1000, TRUE); /* never more than 1000 headers */
586 if(nl-n-1 < curwp->w_ntrows)
587 if(TERM_OPTIMIZE)
588 scrolldown(curwp, -1, nl-n-1);
590 else
591 if(TERM_OPTIMIZE)
592 scrolldown(curwp, -1, nl-n-1);
594 if(Pmaster && Pmaster->headents){
596 * if we're at the top of the page, and the header is closed,
597 * open it ...
599 if((lback(lp) == curbp->b_linep)
600 && (ComposerTopLine == COMPOSER_TOP_LINE)){
601 ToggleHeader(1);
602 movecursor(ComposerTopLine, 0);
607 * Decide if we move the dot or not. Calculation done AFTER deciding
608 * if we display the header because that will change the number of
609 * lines on the screen.
611 if (movedot) {
612 /* Dot gets put at top of window. */
613 curwp->w_dotp = curwp->w_linep;
614 curwp->w_doto = 0;
616 else {
617 /* Requested not to move dot, but we do need to keep in on
618 * the screen. Verify that it is still in the range of lines
619 * visible in the window. Loop from the first line to the
620 * last line, until we reach the end of the buffer or the end
621 * of the window. If we find the dot, then we don't need
622 * to move it. */
623 movedot = TRUE;
624 for ( tp = curwp->w_linep, i = 0;
625 tp != curbp->b_linep && i < curwp->w_ntrows;
626 tp = lforw(tp), ++i) {
627 if (curwp->w_dotp == tp) {
628 movedot = FALSE;
629 break;
632 if (movedot) {
633 /* Dot not found in window. Move to last line of window. */
634 curwp->w_dotp = lback (tp);
635 curwp->w_doto = 0;
639 return (TRUE);
646 * This command is like "forwpage", but it goes backwards. The "2", like
647 * above, is the overlap between the two windows. The value is from the ITS
648 * EMACS manual. Bound to "M-V". We do a hard update for exactly the same
649 * reason.
652 backpage(int f, int n)
655 if (f == FALSE) {
656 n = curwp->w_ntrows - 2; /* Default scroll. */
657 if (n <= 0) /* Don't blow up if the */
658 n = 1; /* window is tiny. */
659 } else if (n < 0)
660 return (forwpage(f, -n));
661 #if CVMVAS
662 else /* Convert from pages */
663 n *= curwp->w_ntrows; /* to lines. */
664 #endif
665 return (scrollback (n, TRUE));
670 scrollupline(int f, int n)
672 return (scrollback (1, FALSE));
677 scrolldownline(int f, int n)
679 return (scrollforw (1, FALSE));
685 * Scroll to a position.
688 scrollto(int f, int n)
690 #ifdef _WINDOWS
691 long scrollLine;
692 LINE *lp;
693 int i;
695 scrollLine = mswin_getscrollto ();
698 * Starting at the first data line in the buffer, step forward
699 * 'scrollLine' lines to find the new top line. It is a circular
700 * list of buffers, so watch for the first line to reappear. if
701 * it does, we have some sort of internal error, abort scroll
702 * operation. Also watch for NULL, just in case.
704 lp = lforw (curbp->b_linep);
705 for (i = 0; i < scrollLine && lp != curbp->b_linep && lp != NULL; ++i)
706 lp = lforw(lp);
708 if (lp == curbp->b_linep || lp == NULL)
709 return (FALSE); /* Whoops! */
712 /* Set the new top line for the window and flag a redraw. */
713 curwp->w_linep = lp;
714 curwp->w_dotp = lp;
715 curwp->w_doto = 0;
716 curwp->w_flag |= WFHARD;
718 if(Pmaster && Pmaster->headents){
720 * If we are at the top of the page and header not open, open it.
721 * If we are not at the top of the page and the header is open,
722 * close it.
724 if((lback(lp) == curbp->b_linep)
725 && (ComposerTopLine == COMPOSER_TOP_LINE)){
726 ToggleHeader(1);
727 movecursor(ComposerTopLine, 0);
729 else if((lback(lp) != curbp->b_linep)
730 && (ComposerTopLine != COMPOSER_TOP_LINE)){
731 ToggleHeader (0);
734 #endif
736 return (TRUE);
742 * Set the mark in the current window to the value of "." in the window. No
743 * errors are possible. Bound to "M-.". If told to set an already set mark
744 * unset it.
747 setmark(int f, int n)
749 if(!curwp->w_markp){
750 curwp->w_markp = curwp->w_dotp;
751 curwp->w_marko = curwp->w_doto;
752 if(n)
753 emlwrite("Mark Set", NULL);
755 else{
756 /* clear inverse chars between here and dot */
757 markregion(0);
758 curwp->w_markp = NULL;
759 if(n)
760 emlwrite("Mark UNset", NULL);
763 #ifdef _WINDOWS
764 mswin_allowcopycut(curwp->w_markp ? kremove : NULL);
765 #endif
766 return (TRUE);
771 * Swap the values of "." and "mark" in the current window. This is pretty
772 * easy, because all of the hard work gets done by the standard routine
773 * that moves the mark about. The only possible error is "no mark". Bound to
774 * "C-X C-X".
777 swapmark(int f, int n)
779 register LINE *odotp;
780 register int odoto;
782 if (curwp->w_markp == NULL) {
783 if(Pmaster == NULL)
784 emlwrite("No mark in this window", NULL);
785 return (FALSE);
788 odotp = curwp->w_dotp;
789 odoto = curwp->w_doto;
790 curwp->w_dotp = curwp->w_markp;
791 curwp->w_doto = curwp->w_marko;
792 curwp->w_markp = odotp;
793 curwp->w_marko = odoto;
794 curwp->w_flag |= WFMOVE;
795 return (TRUE);
800 * Set the mark in the current window to the value of "." in the window. No
801 * errors are possible. Bound to "M-.". If told to set an already set mark
802 * unset it.
805 setimark(int f, int n)
807 curwp->w_imarkp = curwp->w_dotp;
808 curwp->w_imarko = curwp->w_doto;
809 return(TRUE);
814 * Swap the values of "." and "mark" in the current window. This is pretty
815 * easy, because all of the hard work gets done by the standard routine
816 * that moves the mark about. The only possible error is "no mark". Bound to
817 * "C-X C-X".
820 swapimark(int f, int n)
822 register LINE *odotp;
823 register int odoto;
825 if (curwp->w_imarkp == NULL) {
826 if(Pmaster == NULL)
827 emlwrite("Programmer botch! No mark in this window", NULL);
828 return (FALSE);
831 odotp = curwp->w_dotp;
832 odoto = curwp->w_doto;
833 curwp->w_dotp = curwp->w_imarkp;
834 curwp->w_doto = curwp->w_imarko;
835 curwp->w_imarkp = odotp;
836 curwp->w_imarko = odoto;
837 curwp->w_flag |= WFMOVE;
838 return (TRUE);
843 * If dot comes before mark, do nothing.
844 * If mark comes before dot, swap them.
846 void
847 swap_mark_and_dot_if_mark_comes_first(void)
849 LINE *blp, *flp;
851 if(!(curwp && curwp->w_dotp && curwp->w_markp))
852 return;
854 if(curwp->w_dotp == curwp->w_markp){ /* they are in the same line */
855 if(curwp->w_doto > curwp->w_marko)
856 swapmark(0,1);
858 return;
862 * Search forward and backward from dot to see if mark
863 * is less than or greater than dot.
865 flp = blp = curwp->w_dotp;
866 while(flp != curbp->b_linep || lback(blp) != curbp->b_linep){
867 if(flp != curbp->b_linep){
868 flp = lforw(flp);
869 if(flp == curwp->w_markp) /* dot already less than mark */
870 return;
873 if(lback(blp) != curbp->b_linep){
874 blp = lback(blp);
875 if(blp == curwp->w_markp){
876 swapmark(0, 1);
877 return;
884 #ifdef MOUSE
887 * Handle a mouse down.
890 mousepress(int f, int n)
892 MOUSEPRESS mp;
893 LINE *lp;
894 int i;
897 mouse_get_last (NULL, &mp);
900 lp = curwp->w_linep;
901 i = mp.row - ((Pmaster && Pmaster->headents) ? ComposerTopLine : 2);
902 if (i < 0) {
903 if (Pmaster) {
904 /* Clear existing region. */
905 if (curwp->w_markp)
906 setmark(0,1);
908 /* Move to top of document before editing header. */
909 curwp->w_dotp = curwp->w_linep;
910 curwp->w_doto = 0;
911 curwp->w_flag |= WFMOVE;
912 update (); /* And update. */
914 return (HeaderEditor (1, 1));
917 else {
918 while(i-- && lp != curbp->b_linep)
919 lp = lforw(lp);
921 curgoal = mp.col;
922 curwp->w_dotp = lp;
923 curwp->w_doto = getgoal(lp);
924 curwp->w_flag |= WFMOVE;
926 if(mp.doubleclick)
927 setmark(0, 1);
930 return(FALSE);
935 toggle_xterm_mouse(int f, int n)
937 #ifndef _WINDOWS
938 int e;
940 (e=mouseexist()) ? end_mouse() : (void) init_mouse();
941 if(e != mouseexist()){
942 mouseexist() ? emlwrite(_("Xterm mouse tracking on!"), NULL)
943 : emlwrite(_("Xterm mouse tracking off!"), NULL);
945 else if(!e)
946 emlwrite(_("Xterm mouse tracking still off ($DISPLAY variable set?)"), NULL);
947 #endif
948 return(TRUE);
950 #endif