1 /***********************************************************************/
2 /* CURSOR.C - CURSOR commands                                          */
3 /* This file contains all commands that can be assigned to function    */
4 /* keys or typed on the command line.                                  */
5 /***********************************************************************/
6 /*
7  * THE - The Hessling Editor. A text editor similar to VM/CMS xedit.
8  * Copyright (C) 1991-2013 Mark Hessling
9  *
10  * This program is free software; you can redistribute it and/or
11  * modify it under the terms of the GNU General Public License as
12  * published by the Free Software Foundation; either version 2 of
13  * the License, or any later version.
14  *
15  * This program is distributed in the hope that it will be useful,
16  * but WITHOUT ANY WARRANTY; without even the implied warranty of
17  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18  * General Public License for more details.
19  *
20  * You should have received a copy of the GNU General Public License
21  * along with this program; if not, write to:
22  *
23  *    The Free Software Foundation, Inc.
24  *    675 Mass Ave,
25  *    Cambridge, MA 02139 USA.
26  *
27  *
28  * If you make modifications to this software that you feel increases
29  * it usefulness for the rest of the community, please email the
30  * changes, enhancements, bug fixes as well as any and all ideas to me.
31  * This software is going to be maintained and enhanced as deemed
32  * necessary by the community.
33  *
34  * Mark Hessling, mark@rexx.org  http://www.rexx.org/
35  */
36 
37 
38 #include <the.h>
39 #include <proto.h>
40 
41 /***********************************************************************/
42 #ifdef HAVE_PROTO
THEcursor_cmdline(CHARTYPE curr_screen,VIEW_DETAILS * curr_view,short col)43 short THEcursor_cmdline( CHARTYPE curr_screen, VIEW_DETAILS *curr_view, short col)
44 #else
45 short THEcursor_cmdline( curr_screen, curr_view, col )
46 CHARTYPE curr_screen;
47 VIEW_DETAILS *curr_view;
48 short col;
49 #endif
50 /***********************************************************************/
51 {
52    short rc=RC_OK;
53 
54    TRACE_FUNCTION("cursor.c:  THEcursor_cmdline");
55    /*
56     * If in READV CMDLINE, return without doing anything
57     */
58    if ( in_readv )
59    {
60       TRACE_RETURN();
61       return(RC_OK);
62    }
63    /*
64     * If CMDLINE is OFF return without doing anything.
65     */
66    if (SCREEN_WINDOW_COMMAND(curr_screen) == (WINDOW *)NULL)
67    {
68       TRACE_RETURN();
69       return(rc);
70    }
71    if ( curr_view->current_window != WINDOW_COMMAND )
72    {
73       curr_view->previous_window = curr_view->current_window;
74       post_process_line( curr_view, curr_view->focus_line, (LINE *)NULL, TRUE );
75       curr_view->current_window = WINDOW_COMMAND;
76    }
77    wmove( SCREEN_WINDOW(curr_screen), 0, col-1 );
78    curr_view->cmdline_col = col-1;
79    cmd_verify_col = 1;
80    TRACE_RETURN();
81    return(rc);
82 }
83 /***********************************************************************/
84 #ifdef HAVE_PROTO
THEcursor_column(void)85 short THEcursor_column(void)
86 #else
87 short THEcursor_column()
88 #endif
89 /***********************************************************************/
90 {
91    short rc=RC_OK;
92    unsigned short x=0,y=0;
93 
94    TRACE_FUNCTION("cursor.c:  THEcursor_column");
95    /*
96     * If in READV CMDLINE, return without doing anything
97     */
98    if (in_readv)
99    {
100       TRACE_RETURN();
101       return(RC_OK);
102    }
103    switch(CURRENT_VIEW->current_window)
104    {
105       case WINDOW_COMMAND:
106          rc = THEcursor_home( current_screen, CURRENT_VIEW, FALSE );
107          break;
108       case WINDOW_PREFIX:
109          getyx(CURRENT_WINDOW,y,x);
110          CURRENT_VIEW->current_window = WINDOW_FILEAREA;
111          wmove(CURRENT_WINDOW,y,0);
112          break;
113    }
114    rc = execute_move_cursor( current_screen, CURRENT_VIEW, CURRENT_VIEW->current_column-1 );
115    TRACE_RETURN();
116    return(rc);
117 }
118 /***********************************************************************/
119 #ifdef HAVE_PROTO
THEcursor_down(CHARTYPE curr_screen,VIEW_DETAILS * curr_view,short escreen)120 short THEcursor_down( CHARTYPE curr_screen, VIEW_DETAILS *curr_view, short escreen)
121 #else
122 short THEcursor_down( curr_screen, curr_view, escreen )
123 CHARTYPE curr_screen;
124 VIEW_DETAILS *curr_view;
125 short escreen;
126 #endif
127 /***********************************************************************/
128 {
129    short rc=RC_OK;
130    short x,y;
131 
132    TRACE_FUNCTION("cursor.c:  THEcursor_down");
133    /*
134     * If in READV CMDLINE, return without doing anything
135     */
136    if ( in_readv )
137    {
138       TRACE_RETURN();
139       return(RC_OK);
140    }
141    switch( curr_view->current_window )
142    {
143       case WINDOW_PREFIX:
144       case WINDOW_FILEAREA:
145          rc = scroll_line( curr_screen, curr_view, DIRECTION_FORWARD, 1L, FALSE, escreen );
146          if ( rc == RC_OK
147          &&   escreen == CURSOR_CUA )
148          {
149             getyx( SCREEN_WINDOW_FILEAREA(curr_screen), y, x );
150             if ( x + curr_view->verify_col > min(rec_len,curr_view->verify_end) )
151                rc = execute_move_cursor( curr_screen, curr_view, rec_len );
152          }
153          break;
154       case WINDOW_COMMAND:
155          /*
156           * Cycle forward  through the command list or tab to first line.
157           */
158          if ( CMDARROWSTABCMDx )
159             rc = Sos_topedge( (CHARTYPE *)"" );
160          else
161             rc = Retrieve( (CHARTYPE *)"+" );
162          break;
163       default:
164          display_error( 2, (CHARTYPE *)"", FALSE );
165          break;
166    }
167    TRACE_RETURN();
168    return(rc);
169 }
170 /***********************************************************************/
171 #ifdef HAVE_PROTO
THEcursor_file(bool show_errors,LINETYPE line,LENGTHTYPE col)172 short THEcursor_file(bool show_errors,LINETYPE line,LENGTHTYPE col)
173 #else
174 short THEcursor_file(show_errors,line,col)
175 bool show_errors;
176 LINETYPE line;
177 LENGTHTYPE col;
178 #endif
179 /***********************************************************************/
180 {
181    short rc=RC_OK;
182    short y=0,x=0;
183 
184    TRACE_FUNCTION("cursor.c:  THEcursor_file");
185    /*
186     * If in READV CMDLINE, return without doing anything.
187     */
188    if (in_readv)
189    {
190       TRACE_RETURN();
191       return(RC_OK);
192    }
193    /*
194     * If line is not in display, error.
195     */
196    if (!line_in_view(current_screen,line))
197    {
198       if ( show_errors )
199          display_error(63,(CHARTYPE *)"",FALSE);
200       TRACE_RETURN();
201       return(RC_INVALID_OPERAND);
202    }
203    /*
204     * If column is not 0 and not in display, error.
205     */
206    if (col == 0)
207       x = 1;
208    else
209    {
210       if (!column_in_view(current_screen,col-1))
211       {
212          if ( show_errors )
213             display_error(63,(CHARTYPE *)"",FALSE);
214          TRACE_RETURN();
215          return(RC_INVALID_OPERAND);
216       }
217       x = (LENGTHTYPE)((LINETYPE)col - (LINETYPE)CURRENT_VIEW->verify_col + 1);
218    }
219    y = get_row_for_focus_line(current_screen,line,CURRENT_VIEW->current_row);
220    rc = THEcursor_move( current_screen, CURRENT_VIEW, show_errors, TRUE, (short)(y+1), x );
221    TRACE_RETURN();
222    return(rc);
223 }
224 /***********************************************************************/
225 #ifdef HAVE_PROTO
THEcursor_home(CHARTYPE curr_screen,VIEW_DETAILS * curr_view,bool save)226 short THEcursor_home( CHARTYPE curr_screen, VIEW_DETAILS *curr_view, bool save )
227 #else
228 short THEcursor_home( curr_screen, curr_view, save )
229 CHARTYPE curr_screen;
230 VIEW_DETAILS *curr_view;
231 bool save;
232 #endif
233 /***********************************************************************/
234 {
235    CHARTYPE last_win=0;
236    unsigned short x=0,y=0;
237    short rc=RC_OK;
238 
239    TRACE_FUNCTION("cursor.c:  THEcursor_home");
240    /*
241     * If CMDLINE is OFF or in READV CMDLINE, return without doing anything
242     */
243    if ( SCREEN_WINDOW_COMMAND(curr_screen) == (WINDOW *)NULL
244    ||   in_readv)
245    {
246       TRACE_RETURN();
247       return(rc);
248    }
249    last_win = curr_view->previous_window;
250    curr_view->previous_window = curr_view->current_window;
251    if (curr_view->current_window == WINDOW_COMMAND)
252    {
253       if ( !line_in_view( curr_screen, curr_view->focus_line ) )
254          curr_view->focus_line = curr_view->current_line;
255       pre_process_line( curr_view, curr_view->focus_line, (LINE *)NULL );
256       if ( save )
257          curr_view->current_window = last_win;
258       else
259          curr_view->current_window = WINDOW_FILEAREA;
260       getyx( SCREEN_WINDOW(curr_screen), y, x );
261       y = get_row_for_focus_line( curr_screen, curr_view->focus_line, curr_view->current_row );
262       wmove( SCREEN_WINDOW(curr_screen), y, x );
263    }
264    else
265    {
266       post_process_line( curr_view, curr_view->focus_line, (LINE *)NULL, TRUE );
267       curr_view->current_window = WINDOW_COMMAND;
268       wmove( SCREEN_WINDOW(curr_screen), 0, 0 );
269    }
270    build_screen( curr_screen );
271    TRACE_RETURN();
272    return(rc);
273 }
274 /***********************************************************************/
275 #ifdef HAVE_PROTO
THEcursor_left(short escreen,bool kedit_defaults)276 short THEcursor_left(short escreen,bool kedit_defaults)
277 #else
278 short THEcursor_left(escreen,kedit_defaults)
279 short escreen;
280 bool kedit_defaults;
281 #endif
282 /***********************************************************************/
283 {
284    unsigned short x=0,y=0;
285    short rc=RC_OK;
286 
287    /*
288     * If escreen is CURSOR_ESCREEN or CURSOR_CUA, then scrolling of the
289     * window will be done if possible.
290     */
291    TRACE_FUNCTION("cursor.c:  THEcursor_left");
292    /*
293     * The following should be a temporary fix for KEDIT compatibility...
294     */
295    if (CURRENT_VIEW->prefix
296    &&  kedit_defaults)
297       escreen = CURSOR_SCREEN;
298 
299    getyx(CURRENT_WINDOW,y,x);
300    /*
301     * For all windows, if we are not at left column, move 1 pos to left.
302     */
303    if ( x > 0 )
304    {
305       wmove( CURRENT_WINDOW, y, x - 1 );
306       TRACE_RETURN();
307       return(RC_OK);
308    }
309    /*
310     * We are at the left edge of the window
311     * For all windows, determine if CMDARROWSTABLRx is set for tabbing or
312     * scrolling and act accordingly.
313     */
314    switch( CURRENT_VIEW->current_window )
315    {
316       case WINDOW_FILEAREA:
317          /*
318           * For CUA interface, at the left column of the file, move the cursor
319           * to the last character of the previous line; that line
320           * which is in scope
321           */
322          if ( escreen == CURSOR_CUA
323          &&   CURRENT_VIEW->verify_col == 1 )
324          {
325             rc = scroll_line( current_screen, CURRENT_VIEW, DIRECTION_BACKWARD, 1L, FALSE, escreen );
326             rc = Sos_endchar( (CHARTYPE *)"" );
327             break;
328          }
329          if ( escreen == CURSOR_SCREEN )
330          {
331             /*
332              * Move the cursor into the prefix area, to the right-most
333              * column, then move the cursor to the last column of the
334              * window, either PREFIX (if ON) or FILEAREA
335              */
336             if ( CURRENT_VIEW->prefix )
337                rc = Sos_prefix( (CHARTYPE *)"" );
338             rc = Sos_lastcol( (CHARTYPE *)"" );
339          }
340          else
341          {
342             if ( CURRENT_VIEW->verify_col != 1
343             &&   CURRENT_VIEW->autoscroll != 0 )
344             {
345                LENGTHTYPE curr_col = x + CURRENT_VIEW->verify_col - 1;
346                LENGTHTYPE num_cols = (CURRENT_VIEW->autoscroll == (-1)) ? CURRENT_SCREEN.cols[WINDOW_FILEAREA]/2 : CURRENT_VIEW->autoscroll;
347 
348                num_cols = min( num_cols, CURRENT_SCREEN.cols[WINDOW_FILEAREA] );
349                if ( num_cols >= CURRENT_VIEW->verify_col )
350                   CURRENT_VIEW->verify_col = 1;
351                else
352                   CURRENT_VIEW->verify_col = CURRENT_VIEW->verify_col-num_cols;
353                build_screen( current_screen );
354                display_screen( current_screen );
355                wmove( CURRENT_WINDOW, y, curr_col - CURRENT_VIEW->verify_col );
356             }
357             else
358             {
359                if ( compatible_feel == COMPAT_KEDIT
360                ||   compatible_feel == COMPAT_KEDITW )
361                {
362                   if ( ( CURRENT_VIEW->prefix & PREFIX_LOCATION_MASK ) == PREFIX_LEFT )
363                      rc = Sos_prefix( (CHARTYPE *)"" );
364                   rc = Sos_lastcol((CHARTYPE *)"");
365                }
366             }
367          }
368          break;
369       case WINDOW_COMMAND:
370          if ( cmd_verify_col != 1
371          &&   CURRENT_VIEW->autoscroll != 0 )
372          {
373             LENGTHTYPE curr_col = x + cmd_verify_col - 1;
374             LENGTHTYPE num_cols = (CURRENT_VIEW->autoscroll == (-1)) ? CURRENT_SCREEN.cols[WINDOW_COMMAND]/2 : CURRENT_VIEW->autoscroll;
375 
376             num_cols = min( num_cols, CURRENT_SCREEN.cols[WINDOW_COMMAND] );
377             if ( num_cols >= cmd_verify_col )
378                cmd_verify_col = 1;
379             else
380                cmd_verify_col = cmd_verify_col - num_cols;
381             display_cmdline( current_screen, CURRENT_VIEW );
382             wmove( CURRENT_WINDOW, y, curr_col - cmd_verify_col );
383          }
384          else
385          {
386             if ( escreen == CURSOR_SCREEN )
387                rc = Sos_rightedge( (CHARTYPE *)"" );
388          }
389          break;
390       case WINDOW_PREFIX:
391          if ( (escreen == CURSOR_ESCREEN
392            && (CURRENT_VIEW->prefix&PREFIX_LOCATION_MASK) == PREFIX_RIGHT)
393          ||  escreen == CURSOR_SCREEN )
394              rc = Sos_rightedge((CHARTYPE *)"");
395          break;
396       default:
397          break;
398    }
399    TRACE_RETURN();
400    return(rc);
401 }
402 /***********************************************************************/
403 #ifdef HAVE_PROTO
THEcursor_right(short escreen,bool kedit_defaults)404 short THEcursor_right(short escreen,bool kedit_defaults)
405 #else
406 short THEcursor_right(escreen,kedit_defaults)
407 short escreen;
408 bool kedit_defaults;
409 #endif
410 /***********************************************************************/
411 {
412    unsigned short x=0,y=0,tempx=0;
413    COLTYPE right_column=0;
414    short rc=RC_OK;
415 
416    TRACE_FUNCTION("cursor.c:  THEcursor_right");
417    /*
418     * The following should be a temporary fix for KEDIT compatibility...
419     */
420    if (CURRENT_VIEW->prefix
421    &&  kedit_defaults)
422       escreen = CURSOR_SCREEN;
423    getyx(CURRENT_WINDOW,y,x);
424    right_column = getmaxx( CURRENT_WINDOW ) - 1;
425    if ( CURRENT_VIEW->current_window == WINDOW_FILEAREA )
426    {
427       /*
428        * Check for going past end of line - max_line_length
429        */
430       if ( CURRENT_VIEW->verify_col+x+1 > max_line_length )
431       {
432          TRACE_RETURN();
433          return(RC_OK);
434       }
435       /*
436        * For CUA interface, if after the right-most character of the line,
437        * move the cursor to the first column of the next line; that line
438        * which is in scope
439        */
440       if ( escreen == CURSOR_CUA
441       &&   x + CURRENT_VIEW->verify_col > min(rec_len,CURRENT_VIEW->verify_end) )
442       {
443          rc = scroll_line( current_screen, CURRENT_VIEW, DIRECTION_FORWARD, 1L, FALSE, escreen );
444          rc = Sos_firstcol( (CHARTYPE *)"" );
445          TRACE_RETURN();
446          return(rc);
447       }
448    }
449    /*
450     * For all windows, if we are not at right column, move 1 pos to right.
451     */
452    if ( x < right_column )
453    {
454       wmove( CURRENT_WINDOW, y, x+1 );
455       TRACE_RETURN();
456       return(RC_OK);
457    }
458    /*
459     * For all windows, determine if CMDARROWSTABLRx is set for tabbing or
460     * scrolling and act accordingly.
461     */
462    switch( CURRENT_VIEW->current_window )
463    {
464       case WINDOW_FILEAREA:
465          if (escreen == CURSOR_SCREEN)
466          {
467             if (CURRENT_VIEW->prefix)
468                rc = Sos_prefix((CHARTYPE *)"");
469             else
470                wmove(CURRENT_WINDOW,y,0); /* this should move down a line too */
471          }
472          else
473          {
474             tempx = getmaxx(CURRENT_WINDOW);
475             if (x == tempx-1
476             &&  CURRENT_VIEW->autoscroll != 0)
477             {
478                LENGTHTYPE curr_col=x+CURRENT_VIEW->verify_col-1;
479                LENGTHTYPE num_cols = (CURRENT_VIEW->autoscroll == (-1)) ? CURRENT_SCREEN.cols[WINDOW_FILEAREA]/2 : CURRENT_VIEW->autoscroll;
480 
481                num_cols = min(num_cols,CURRENT_SCREEN.cols[WINDOW_FILEAREA]);
482                CURRENT_VIEW->verify_col += num_cols;
483                build_screen(current_screen);
484                display_screen(current_screen);
485                wmove(CURRENT_WINDOW,y,curr_col-CURRENT_VIEW->verify_col+2);
486             }
487          }
488          break;
489       case WINDOW_PREFIX:
490          rc = Sos_leftedge( (CHARTYPE *)"" );
491          break;
492       case WINDOW_COMMAND:
493          tempx = getmaxx( CURRENT_WINDOW );
494          if ( x == tempx - 1
495          &&  CURRENT_VIEW->autoscroll != 0 )
496          {
497             LENGTHTYPE curr_col = x + cmd_verify_col - 1;
498             LENGTHTYPE num_cols = (CURRENT_VIEW->autoscroll == (-1)) ? CURRENT_SCREEN.cols[WINDOW_COMMAND]/2 : CURRENT_VIEW->autoscroll;
499 
500             num_cols = min( num_cols, CURRENT_SCREEN.cols[WINDOW_COMMAND] );
501             cmd_verify_col += num_cols;
502             display_cmdline( current_screen, CURRENT_VIEW );
503             wmove( CURRENT_WINDOW, y, curr_col - cmd_verify_col + 2 );
504          }
505          break;
506       default:
507          break;
508    }
509    TRACE_RETURN();
510    return(rc);
511 }
512 /***********************************************************************/
513 #ifdef HAVE_PROTO
THEcursor_up(short escreen)514 short THEcursor_up(short escreen)
515 #else
516 short THEcursor_up(escreen)
517 short escreen;
518 #endif
519 /***********************************************************************/
520 {
521    short rc=RC_OK;
522    short x,y;
523    CHARTYPE *current_command=NULL;
524 
525    TRACE_FUNCTION("cursor.c:  THEcursor_up");
526    /*
527     * If in READV CMDLINE, return without doing anything
528     */
529    if (in_readv)
530    {
531       TRACE_RETURN();
532       return(RC_OK);
533    }
534    switch( CURRENT_VIEW->current_window )
535    {
536       case WINDOW_FILEAREA:
537       case WINDOW_PREFIX:
538          rc = scroll_line( current_screen, CURRENT_VIEW, DIRECTION_BACKWARD, 1L, FALSE, escreen );
539          if ( rc == RC_OK
540          &&   escreen == CURSOR_CUA )
541          {
542             getyx( CURRENT_WINDOW_FILEAREA, y, x );
543             if ( x + CURRENT_VIEW->verify_col > min( rec_len, CURRENT_VIEW->verify_end) )
544                rc = execute_move_cursor( current_screen, CURRENT_VIEW, rec_len );
545          }
546          break;
547       case WINDOW_COMMAND:
548          /*
549           * Cycle backward through the command list or tab to last line.
550           */
551          if ( CMDARROWSTABCMDx )
552             rc = Sos_bottomedge( (CHARTYPE *)"" );
553          else
554          {
555             current_command = get_next_command( DIRECTION_FORWARD, 1 );
556             wmove( CURRENT_WINDOW_COMMAND, 0, 0 );
557             my_wclrtoeol( CURRENT_WINDOW_COMMAND );
558             if ( current_command != (CHARTYPE *)NULL )
559             {
560                Cmsg( current_command );
561             }
562          }
563          break;
564       default:
565          display_error(2, (CHARTYPE *)"", FALSE );
566          rc = RC_INVALID_OPERAND;
567          break;
568    }
569    TRACE_RETURN();
570    return(rc);
571 }
572 /***********************************************************************/
573 #ifdef HAVE_PROTO
THEcursor_move(CHARTYPE curr_screen,VIEW_DETAILS * curr_view,bool show_errors,bool escreen,short row,short col)574 short THEcursor_move( CHARTYPE curr_screen, VIEW_DETAILS *curr_view, bool show_errors, bool escreen, short row, short col)
575 #else
576 short THEcursor_move( curr_screen, curr_view, show_errors, escreen, row, col )
577 CHARTYPE curr_screen;
578 VIEW_DETAILS *curr_view;
579 bool show_errors,escreen;
580 short row,col;
581 #endif
582 /***********************************************************************/
583 {
584    register int i=0;
585    short rc=RC_OK;
586    unsigned short x=0,y=0;
587    unsigned short max_row=0,min_row=0,max_col=0;
588    short idx=(-1);
589 
590    TRACE_FUNCTION("cursor.c:  THEcursor_move");
591 
592    getyx( SCREEN_WINDOW_FILEAREA(curr_screen), y, x );
593    /*
594     * Always post_process_line() for CURRENT_VIEW
595     */
596    post_process_line( CURRENT_VIEW, CURRENT_VIEW->focus_line, (LINE *)NULL, TRUE );
597    if ( escreen )
598    {
599       /*
600        * For CURSOR ESCREEN...
601        */
602       if ( find_last_focus_line( curr_screen, &max_row ) != RC_OK )
603       {
604          TRACE_RETURN();
605          return(rc);
606       }
607       if ( find_first_focus_line( curr_screen, &min_row ) != RC_OK )
608       {
609          TRACE_RETURN();
610          return(rc);
611       }
612       if ( row == 0 )
613          row = y;
614       else
615       {
616          if ( row > max_row )
617             row = max_row;
618          else
619          {
620             if ( row < min_row )
621                row = min_row;
622             else
623             {
624                if ( screen[curr_screen].sl[row-1].main_enterable )
625                   row--;
626                else
627                {
628                   if ( show_errors )
629                      display_error( 63, (CHARTYPE *)"", FALSE );
630                   TRACE_RETURN();
631                   return(RC_TOF_EOF_REACHED);/* this is a strange RC :-( */
632                }
633             }
634          }
635       }
636       max_col = screen[curr_screen].cols[WINDOW_FILEAREA];
637       if ( col == 0 )
638        col = x;
639       else
640       {
641          if ( col > max_col )
642             col = max_col - 1;
643          else
644             col--;
645       }
646       switch( curr_view->current_window )
647       {
648          case WINDOW_COMMAND:
649             rc = THEcursor_home( curr_screen, curr_view, FALSE );
650             break;
651          case WINDOW_PREFIX:
652             curr_view->current_window = WINDOW_FILEAREA;
653             break;
654       }
655       wmove( SCREEN_WINDOW_FILEAREA(curr_screen), row, col );
656       curr_view->focus_line = screen[curr_screen].sl[row].line_number;
657       pre_process_line( curr_view, curr_view->focus_line, (LINE *)NULL );
658    }
659    else
660    {
661       /*
662        * Convert supplied row/col to 0 based offset...
663        */
664       if ( row == 0 )
665          row = screen[curr_screen].start_row[curr_view->current_window] + y;
666       else
667          row--;
668       if ( col == 0 )
669          col = screen[curr_screen].start_col[curr_view->current_window] + x;
670       else
671          col--;
672       max_row = screen[curr_screen].screen_rows - 1;
673       max_col = screen[curr_screen].screen_cols - 1;
674       /*
675        * If row/col outside maximum screen size, exit...
676        */
677       if ( row > max_row
678       ||   col > max_col )
679       {
680          if ( show_errors )
681             display_error( 63, (CHARTYPE *)"", FALSE );
682          TRACE_RETURN();
683          return(RC_TOF_EOF_REACHED);/* this is a strange RC :-( */
684       }
685       /*
686        * Determine which window the cursor will end up in...
687        */
688       for ( i = 0; i < VIEW_WINDOWS; i++ )
689       {
690          int top_int_row = screen[curr_screen].start_row[i] - screen[curr_screen].screen_start_row;
691          int bot_int_row = screen[curr_screen].start_row[i] - screen[curr_screen].screen_start_row + screen[curr_screen].rows[i] - 1;
692          if ( row >= top_int_row
693          &&   row <= bot_int_row
694          &&   col >= (screen[curr_screen].start_col[i]  - screen[curr_screen].screen_start_col)
695          &&   col <= (screen[curr_screen].start_col[i] + screen[curr_screen].cols[i] - 1 - screen[curr_screen].screen_start_col) )
696          {
697             idx = i;
698             break;
699          }
700       }
701       row = row - (screen[curr_screen].start_row[idx] - screen[curr_screen].screen_start_row);
702       col = col - (screen[curr_screen].start_col[idx] - screen[curr_screen].screen_start_col);
703       switch( idx )
704       {
705          case WINDOW_FILEAREA:
706             row = get_row_for_tof_eof( row, curr_screen );
707             if ( !screen[curr_screen].sl[row].main_enterable )
708             {
709                if ( show_errors )
710                   display_error( 63, (CHARTYPE *)"", FALSE );
711                TRACE_RETURN();
712                return(RC_TOF_EOF_REACHED);/* this is a strange RC :-( */
713             }
714             rc = do_Sos_current( (CHARTYPE *)"", curr_screen, curr_view );
715             wmove( SCREEN_WINDOW_FILEAREA(curr_screen), row, col );
716             curr_view->focus_line = screen[curr_screen].sl[row].line_number;
717             pre_process_line( curr_view, curr_view->focus_line, (LINE *)NULL );
718             /*
719              * If the colours of FILEAREA and CURSORLINE are different, we need
720              * to display the screen.
721              */
722             if ( set_colour( curr_view->file_for_view->attr+ATTR_FILEAREA ) != set_colour( curr_view->file_for_view->attr+ATTR_CURSORLINE ) )
723             {
724                build_screen( curr_screen );
725                display_screen( curr_screen );
726             }
727             break;
728          case WINDOW_PREFIX:
729             row = get_row_for_tof_eof( row, curr_screen );
730             if ( !screen[curr_screen].sl[row].prefix_enterable )
731             {
732                if ( show_errors )
733                   display_error( 63, (CHARTYPE *)"", FALSE );
734                TRACE_RETURN();
735                return(RC_TOF_EOF_REACHED);/* this is a strange RC :-( */
736             }
737             rc = do_Sos_current( (CHARTYPE *)"", curr_screen, curr_view );
738             rc = do_Sos_prefix( (CHARTYPE *)"", curr_screen, curr_view );
739             wmove( SCREEN_WINDOW_PREFIX(curr_screen), row, col );
740             curr_view->focus_line = screen[curr_screen].sl[row].line_number;
741             pre_process_line( curr_view, curr_view->focus_line, (LINE *)NULL );
742             break;
743          case WINDOW_COMMAND:
744             rc = THEcursor_cmdline( curr_screen, curr_view, (short)(col + 1) );
745             break;
746          default:
747             if ( show_errors )
748                display_error( 63, (CHARTYPE *)"", FALSE );
749             TRACE_RETURN();
750             return(RC_TOF_EOF_REACHED);/* this is a strange RC :-( */
751             break;
752       }
753    }
754    TRACE_RETURN();
755    return(rc);
756 }
757 /***********************************************************************/
758 #ifdef HAVE_PROTO
THEcursor_goto(LINETYPE row,LENGTHTYPE col)759 short THEcursor_goto(LINETYPE row, LENGTHTYPE col)
760 #else
761 short THEcursor_goto(row,col)
762 LINETYPE row;
763 LENGTHTYPE col;
764 #endif
765 /***********************************************************************/
766 {
767    short rc=RC_OK;
768 
769    TRACE_FUNCTION("cursor.c:  THEcursor_goto");
770    if ( row > CURRENT_FILE->number_lines
771    ||   row < 0
772    ||  col > max_line_length )
773    {
774       display_error(63,(CHARTYPE *)"",FALSE);
775       TRACE_RETURN();
776       return(RC_TOF_EOF_REACHED);/* this is a strange RC :-( */
777    }
778    if ( col == 0 )
779    {
780       col = CURRENT_VIEW->verify_col;
781    }
782    if ( THEcursor_file( FALSE, row, col ) != RC_OK )
783    {
784       pre_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,(LINE *)NULL);
785       /*
786        * Make specified line current and display specified column in the
787        * middle of the screen if not already displayed.
788        */
789       CURRENT_VIEW->current_line = CURRENT_VIEW->focus_line = row;
790       pre_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,(LINE *)NULL);
791       if (!column_in_view(current_screen,col-1))
792       {
793          if ( col < CURRENT_SCREEN.cols[WINDOW_FILEAREA]/2 )
794             CURRENT_VIEW->verify_col = 1;
795          else
796             CURRENT_VIEW->verify_col = col - (CURRENT_SCREEN.cols[WINDOW_FILEAREA]/2);
797       }
798       build_screen(current_screen);
799       display_screen(current_screen);
800       THEcursor_file( FALSE, row, col );
801    }
802    TRACE_RETURN();
803    return(rc);
804 }
805 /***********************************************************************/
806 #ifdef HAVE_PROTO
THEcursor_mouse(void)807 short THEcursor_mouse(void)
808 #else
809 short THEcursor_mouse()
810 #endif
811 /***********************************************************************/
812 {
813 #if defined(PDCURSES_MOUSE_ENABLED)
814 #define MOUSE_Y (MOUSE_Y_POS+1-screen[scrn].screen_start_row)
815 #define MOUSE_X (MOUSE_X_POS+1-screen[scrn].screen_start_col)
816 #endif
817 #if defined(NCURSES_MOUSE_VERSION)
818 #define MOUSE_Y (ncurses_mouse_event.y+1-screen[scrn].screen_start_row)
819 #define MOUSE_X (ncurses_mouse_event.x+1-screen[scrn].screen_start_col)
820 #endif
821 #if defined(PDCURSES_MOUSE_ENABLED) || defined(NCURSES_MOUSE_VERSION)
822    int w=0;
823    CHARTYPE scrn=0;
824 #endif
825    short rc=RC_OK;
826 
827    TRACE_FUNCTION("cursor.c:  THEcursor_mouse");
828 
829 #if defined(PDCURSES_MOUSE_ENABLED) || defined(NCURSES_MOUSE_VERSION)
830    /*
831     * If in READV CMDLINE, return without doing anything
832     */
833    if (in_readv)
834    {
835       TRACE_RETURN();
836       return(RC_OK);
837    }
838    /*
839     * First determine in which window the mouse is...
840     */
841    which_window_is_mouse_in(&scrn,&w);
842    if (w == (-1)) /* shouldn't happen! */
843    {
844       TRACE_RETURN();
845       return(RC_INVALID_ENVIRON);
846    }
847    /*
848     * If the mouse is in a different screen to the current one, move there
849     */
850    if (current_screen != scrn)
851    {
852       (void)Nextwindow((CHARTYPE *)"");
853    }
854    /*
855     * Move the cursor to the correct screen coordinates...
856     */
857    rc = THEcursor_move( current_screen, CURRENT_VIEW, TRUE, FALSE, (short)MOUSE_Y, (short)MOUSE_X );
858 #endif
859 
860    TRACE_RETURN();
861    return(rc);
862 }
863 /***********************************************************************/
864 #ifdef HAVE_PROTO
where_now(void)865 long where_now(void)
866 #else
867 long where_now()
868 #endif
869 /***********************************************************************/
870 {
871    long rc=0L;
872    unsigned short x=0,y=0;
873 
874    TRACE_FUNCTION("cursor.c:  where_now");
875    getyx(CURRENT_WINDOW,y,x);
876    switch(CURRENT_VIEW->current_window)
877    {
878       case WINDOW_FILEAREA:
879          rc |= WHERE_WINDOW_FILEAREA;
880          break;
881       case WINDOW_PREFIX:
882          if ((CURRENT_VIEW->prefix & PREFIX_LOCATION_MASK) == PREFIX_LEFT)
883             rc |= WHERE_WINDOW_PREFIX_LEFT;
884          else
885             rc |= WHERE_WINDOW_PREFIX_RIGHT;
886          break;
887       case WINDOW_COMMAND:
888          if (CURRENT_VIEW->cmd_line == 'B')
889             rc |= WHERE_WINDOW_CMDLINE_BOTTOM;
890          else
891             rc |= WHERE_WINDOW_CMDLINE_TOP;
892          break;
893    }
894    if (display_screens == 1)
895       rc |= WHERE_SCREEN_ONLY;
896    else
897    {
898       if (current_screen == 0)
899          rc |= WHERE_SCREEN_FIRST;
900       else
901          rc |= WHERE_SCREEN_LAST;
902    }
903    rc |= (long)y;
904    TRACE_RETURN();
905    return(rc);
906 }
907 /***********************************************************************/
908 #ifdef HAVE_PROTO
what_current_now(void)909 long what_current_now(void)
910 #else
911 long what_current_now()
912 #endif
913 /***********************************************************************/
914 {
915    long rc=0;
916 
917    TRACE_FUNCTION("cursor.c:  what_current_now");
918    if (CURRENT_WINDOW_PREFIX != NULL)
919    {
920       if ((CURRENT_VIEW->prefix & PREFIX_LOCATION_MASK) == PREFIX_LEFT)
921          rc |= WHERE_WINDOW_PREFIX_LEFT;
922       else
923          rc |= WHERE_WINDOW_PREFIX_RIGHT;
924    }
925    if (CURRENT_VIEW->cmd_line == 'B')
926       rc |= WHERE_WINDOW_CMDLINE_BOTTOM;
927    else
928    {
929       if (CURRENT_VIEW->cmd_line == 'T')
930          rc |= WHERE_WINDOW_CMDLINE_TOP;
931    }
932    TRACE_RETURN();
933    return(rc);
934 }
935 /***********************************************************************/
936 #ifdef HAVE_PROTO
what_other_now(void)937 long what_other_now(void)
938 #else
939 long what_other_now()
940 #endif
941 /***********************************************************************/
942 {
943    long rc=0L;
944 
945    TRACE_FUNCTION("cursor.c:  what_other_now");
946    if (display_screens == 1)
947    {
948       TRACE_RETURN();
949       return(rc);
950    }
951    if (OTHER_SCREEN.win[WINDOW_PREFIX] != NULL)
952    {
953       if ((OTHER_SCREEN.screen_view->prefix & PREFIX_LOCATION_MASK) == PREFIX_LEFT)
954          rc |= WHERE_WINDOW_PREFIX_LEFT;
955       else
956          rc |= WHERE_WINDOW_PREFIX_RIGHT;
957    }
958    if (OTHER_SCREEN.screen_view->cmd_line == 'B')
959       rc |= WHERE_WINDOW_CMDLINE_BOTTOM;
960    else
961    {
962       if (OTHER_SCREEN.screen_view->cmd_line == 'T')
963          rc |= WHERE_WINDOW_CMDLINE_TOP;
964    }
965    TRACE_RETURN();
966    return(rc);
967 }
968 /***********************************************************************/
969 #ifdef HAVE_PROTO
where_next(long where,long what_current,long what_other)970 long where_next(long where,long what_current,long what_other)
971 #else
972 long where_next(where,what_current,what_other)
973 long where,what_current,what_other;
974 #endif
975 /***********************************************************************/
976 {
977    long where_row=0L,where_window=0L,where_screen=0L;
978    long what_current_window=0L;
979    long what_other_window=0L;
980    long rc=0L;
981    unsigned short current_top_row=0,current_bottom_row=0;
982 
983    where_row = where & WHERE_ROW_MASK;
984    where_window = where & WHERE_WINDOW_MASK;
985    where_screen = where & WHERE_SCREEN_MASK;
986    what_current_window = what_current & WHERE_WINDOW_MASK;
987    what_other_window = what_other & WHERE_WINDOW_MASK;
988    find_first_focus_line( current_screen, &current_top_row );
989    find_last_focus_line( current_screen, &current_bottom_row );
990 
991    switch(where_window)
992    {
993       case WHERE_WINDOW_FILEAREA:
994          /*
995           * In filearea.
996           */
997          if (what_current_window & WHERE_WINDOW_PREFIX_RIGHT)
998          {
999             /*
1000              * In filearea and there is prefix on right.
1001              * Result: same row,same screen,go to prefix.
1002              */
1003             return(where_row | where_screen | WHERE_WINDOW_PREFIX_RIGHT);
1004          }
1005          switch(where_screen)
1006          {
1007             case WHERE_SCREEN_FIRST:
1008             case WHERE_SCREEN_LAST:
1009                /* the two cases above will be separate in future */
1010             case WHERE_SCREEN_ONLY:
1011                /*
1012                 * In filearea and only screen.
1013                 */
1014                if (where_row == (long)current_bottom_row)
1015                {
1016                   /*
1017                    * In filearea, prefix on left or off, on bottom line.
1018                    */
1019                   if (what_current_window & WHERE_WINDOW_CMDLINE_TOP)
1020                   {
1021                      /*
1022                       * In filearea,prefix on left or off, on bottom line.
1023                       * Result: row irrelevant,same screen,go to cmdline.
1024                       */
1025                      return(where_row | where_screen | WHERE_WINDOW_CMDLINE_TOP);
1026                   }
1027                   if (what_current_window & WHERE_WINDOW_CMDLINE_BOTTOM)
1028                   {
1029                      /*
1030                       * In filearea,prefix on left or off, on bottom line.
1031                       * Result: row irrelevant,same screen,go to cmdline.
1032                       */
1033                      return(where_row | where_screen | WHERE_WINDOW_CMDLINE_BOTTOM);
1034                   }
1035                   /*
1036                    * ****************** To get here, there is no cmdline. ****************
1037                    */
1038                   if (what_current_window & WHERE_WINDOW_PREFIX_LEFT)
1039                   {
1040                      /*
1041                       * In filearea,prefix on left or off, on bottom line.
1042                       * Result: first row,same screen,go to prefix.
1043                       */
1044                      return((long)current_top_row | where_screen | WHERE_WINDOW_PREFIX_LEFT);
1045                   }
1046                }
1047                /*
1048                 * ****************** To get here, we are not on last row. *************
1049                 */
1050                if (what_current_window & WHERE_WINDOW_PREFIX_LEFT)
1051                {
1052                   /*
1053                    * In filearea, prefix on left, not on bottom line.
1054                    * Result: next row,same screen,go to prefix.
1055                    */
1056                   return((where_row+1L) | where_screen | WHERE_WINDOW_PREFIX_LEFT);
1057                }
1058                /*
1059                 * In filearea, no prefix, not on bottom line.
1060                 * Result: next row,same screen,same window.
1061                 */
1062                return((where_row+1L) | where_screen | WHERE_WINDOW_FILEAREA);
1063                break;
1064          }
1065          break;
1066       case WHERE_WINDOW_PREFIX_LEFT:
1067          rc = where_row | where_screen | WHERE_WINDOW_FILEAREA;
1068          break;
1069       case WHERE_WINDOW_PREFIX_RIGHT:
1070          switch(where_screen)
1071          {
1072             case WHERE_SCREEN_FIRST:
1073             case WHERE_SCREEN_LAST:
1074                /* the two cases above will be separate in future */
1075             case WHERE_SCREEN_ONLY:
1076                /*
1077                 * In right prefix and only screen.
1078                 */
1079                if (where_row != (long)current_bottom_row)
1080                {
1081                   /*
1082                    * In right prefix and not on bottom line.
1083                    * Result: next row,same screen,go to filearea.
1084                    */
1085                   return((where_row+1L) | where_screen | WHERE_WINDOW_FILEAREA);
1086                }
1087                if (what_current_window & WHERE_WINDOW_CMDLINE_BOTTOM)
1088                {
1089                   /*
1090                    * In right prefix, cmdline on bottom, on bottom line.
1091                    * Result: row irrelevant,same screen,go to cmdline.
1092                    */
1093                   return(where_row | where_screen | WHERE_WINDOW_CMDLINE_BOTTOM);
1094                }
1095                if (what_current_window & WHERE_WINDOW_CMDLINE_TOP)
1096                {
1097                   /*
1098                    * In right prefix, cmdline on top, on bottom line.
1099                    * Result: row irrelevant,same screen,go to cmdline.
1100                    */
1101                   return(where_row | where_screen | WHERE_WINDOW_CMDLINE_TOP);
1102                }
1103                /*
1104                 * In right prefix, no cmdline, on bottom line.
1105                 * Result: first row,same screen,go to filearea.
1106                 */
1107                return((long)current_top_row | where_screen | WHERE_WINDOW_FILEAREA);
1108                break;
1109          }
1110          break;
1111       case WHERE_WINDOW_CMDLINE_TOP:
1112          switch(where_screen)
1113          {
1114             case WHERE_SCREEN_FIRST:
1115             case WHERE_SCREEN_LAST:
1116                /* the two cases above will be separate in future */
1117             case WHERE_SCREEN_ONLY:
1118                /*
1119                 * In cmdline, and only screen.
1120                 */
1121                if (what_current_window & WHERE_WINDOW_PREFIX_LEFT)
1122                {
1123                   /*
1124                    * In cmdline, and only screen and prefix on left.
1125                    * Result: first row, same screen, go to prefix.
1126                    */
1127                   return((long)current_top_row | where_screen | WHERE_WINDOW_PREFIX_LEFT);
1128                }
1129                /*
1130                 * In cmdline, and prefix on right or none.
1131                 * Result: first row, same screen, go to filearea.
1132                 */
1133                return((long)current_top_row | where_screen | WHERE_WINDOW_FILEAREA);
1134                break;
1135          }
1136          break;
1137       case WHERE_WINDOW_CMDLINE_BOTTOM:
1138          switch(where_screen)
1139          {
1140             case WHERE_SCREEN_FIRST:
1141             case WHERE_SCREEN_LAST:
1142                /* the two cases above will be separate in future */
1143             case WHERE_SCREEN_ONLY:
1144                /*
1145                 * In cmdline, and only screen.
1146                 */
1147                if (what_current_window & WHERE_WINDOW_PREFIX_LEFT)
1148                {
1149                   /*
1150                    * In cmdline, and only screen and prefix on left.
1151                    * Result: first row, same screen, go to prefix.
1152                    */
1153                   return((long)current_top_row | where_screen | WHERE_WINDOW_PREFIX_LEFT);
1154                }
1155                /*
1156                 * In cmdline, and prefix on right or none.
1157                 * Result: first row, same screen, go to filearea.
1158                 */
1159                return((long)current_top_row | where_screen | WHERE_WINDOW_FILEAREA);
1160                break;
1161          }
1162          break;
1163    }
1164    return(rc);
1165 }
1166 /***********************************************************************/
1167 #ifdef HAVE_PROTO
where_before(long where,long what_current,long what_other)1168 long where_before(long where,long what_current,long what_other)
1169 #else
1170 long where_before(where,what_current,what_other)
1171 long where,what_current,what_other;
1172 #endif
1173 /***********************************************************************/
1174 {
1175    long where_row=0L,where_window=0L,where_screen=0L;
1176    long what_current_window=0L;
1177    long what_other_window=0L;
1178    long rc=0L;
1179    unsigned short current_top_row=0,current_bottom_row=0;
1180 
1181    where_row = where & WHERE_ROW_MASK;
1182    where_window = where & WHERE_WINDOW_MASK;
1183    where_screen = where & WHERE_SCREEN_MASK;
1184    what_current_window = what_current & WHERE_WINDOW_MASK;
1185    what_other_window = what_other & WHERE_WINDOW_MASK;
1186    find_first_focus_line( current_screen, &current_top_row );
1187    find_last_focus_line( current_screen, &current_bottom_row );
1188 
1189    switch(where_window)
1190    {
1191       case WHERE_WINDOW_FILEAREA:
1192          /*
1193           * In filearea.
1194           */
1195          if (what_current_window & WHERE_WINDOW_PREFIX_LEFT)
1196          {
1197             /*
1198              * In filearea and there is prefix on left.
1199              * Result: same row,same screen,go to prefix.
1200              */
1201             return(where_row | where_screen | WHERE_WINDOW_PREFIX_LEFT);
1202          }
1203          switch(where_screen)
1204          {
1205             case WHERE_SCREEN_FIRST:
1206             case WHERE_SCREEN_LAST:
1207                /* the two cases above will be separate in future */
1208             case WHERE_SCREEN_ONLY:
1209                /*
1210                 * In filearea and only screen.
1211                 */
1212                if (where_row == (long)current_top_row)
1213                {
1214                   /*
1215                    * In filearea, prefix on right or off, on top    line.
1216                    */
1217                   if (what_current_window & WHERE_WINDOW_CMDLINE_BOTTOM)
1218                   {
1219                      /*
1220                       * In filearea,prefix on right or off, on top    line.
1221                       * Result: row irrelevant,same screen,go to cmdline.
1222                       */
1223                      return(where_row | where_screen | WHERE_WINDOW_CMDLINE_BOTTOM);
1224                   }
1225                   if (what_current_window & WHERE_WINDOW_CMDLINE_TOP)
1226                   {
1227                      /*
1228                       * In filearea,prefix on right or off, on top    line.
1229                       * Result: row irrelevant,same screen,go to cmdline.
1230                       */
1231                      return(where_row | where_screen | WHERE_WINDOW_CMDLINE_TOP);
1232                   }
1233                   /*
1234                    * ****************** To get here, there is no cmdline. ****************
1235                    */
1236                   if (what_current_window & WHERE_WINDOW_PREFIX_RIGHT)
1237                   {
1238                      /*
1239                       * In filearea,prefix on right or off, on top    line.
1240                       * Result: last  row,same screen,go to prefix.
1241                       */
1242                      return((long)current_bottom_row | where_screen | WHERE_WINDOW_PREFIX_RIGHT);
1243                   }
1244                }
1245                /*
1246                 * ****************** To get here, we are not on top  row. *************
1247                 */
1248                if (what_current_window & WHERE_WINDOW_PREFIX_RIGHT)
1249                {
1250                   /*
1251                    * In filearea, prefix on right, not on top    line.
1252                    * Result: prior row,same screen,go to prefix.
1253                    */
1254                   return((where_row-1L) | where_screen | WHERE_WINDOW_PREFIX_RIGHT);
1255                }
1256                /*
1257                 * In filearea, no prefix, not on top    line.
1258                 * Result: prior row,same screen,same window.
1259                 */
1260                return((where_row-1L) | where_screen | WHERE_WINDOW_FILEAREA);
1261                break;
1262          }
1263          break;
1264       case WHERE_WINDOW_PREFIX_RIGHT:
1265          rc = where_row | where_screen | WHERE_WINDOW_FILEAREA;
1266          break;
1267       case WHERE_WINDOW_PREFIX_LEFT:
1268          switch(where_screen)
1269          {
1270             case WHERE_SCREEN_FIRST:
1271             case WHERE_SCREEN_LAST:
1272                /* the two cases above will be separate in future */
1273             case WHERE_SCREEN_ONLY:
1274                /*
1275                 * In left  prefix and only screen.
1276                 */
1277                if (where_row != (long)current_top_row)
1278                {
1279                   /*
1280                    * In left  prefix and not on top    line.
1281                    * Result: prior row,same screen,go to filearea.
1282                    */
1283                   return((where_row-1L) | where_screen | WHERE_WINDOW_FILEAREA);
1284                }
1285                if (what_current_window & WHERE_WINDOW_CMDLINE_BOTTOM)
1286                {
1287                   /*
1288                    * In left  prefix, cmdline on bottom, on top    line.
1289                    * Result: row irrelevant,same screen,go to cmdline.
1290                    */
1291                   return(where_row | where_screen | WHERE_WINDOW_CMDLINE_BOTTOM);
1292                }
1293                if (what_current_window & WHERE_WINDOW_CMDLINE_TOP)
1294                {
1295                   /*
1296                    * In left  prefix, cmdline on top, on top    line.
1297                    * Result: row irrelevant,same screen,go to cmdline.
1298                    */
1299                   return(where_row | where_screen | WHERE_WINDOW_CMDLINE_TOP);
1300                }
1301                /*
1302                 * In left  prefix, no cmdline, on top    line.
1303                 * Result: last  row,same screen,go to filearea.
1304                 */
1305                return((long)current_bottom_row | where_screen | WHERE_WINDOW_FILEAREA);
1306                break;
1307          }
1308          break;
1309       case WHERE_WINDOW_CMDLINE_TOP:
1310          switch(where_screen)
1311          {
1312             case WHERE_SCREEN_FIRST:
1313             case WHERE_SCREEN_LAST:
1314                /* the two cases above will be separate in future */
1315             case WHERE_SCREEN_ONLY:
1316                /*
1317                 * In cmdline, and only screen.
1318                 */
1319                if (what_current_window & WHERE_WINDOW_PREFIX_RIGHT)
1320                {
1321                   /*
1322                    * In cmdline, and only screen and prefix on right.
1323                    * Result: last  row, same screen, go to prefix.
1324                    */
1325                   return((long)current_bottom_row | where_screen | WHERE_WINDOW_PREFIX_RIGHT);
1326                }
1327                /*
1328                 * In cmdline, and prefix on left  or none.
1329                 * Result: last  row, same screen, go to filearea.
1330                 */
1331                return((long)current_bottom_row | where_screen | WHERE_WINDOW_FILEAREA);
1332                break;
1333          }
1334          break;
1335       case WHERE_WINDOW_CMDLINE_BOTTOM:
1336          switch(where_screen)
1337          {
1338             case WHERE_SCREEN_FIRST:
1339             case WHERE_SCREEN_LAST:
1340                /* the two cases above will be separate in future */
1341             case WHERE_SCREEN_ONLY:
1342                /*
1343                 * In cmdline, and only screen.
1344                 */
1345                if (what_current_window & WHERE_WINDOW_PREFIX_RIGHT)
1346                {
1347                   /*
1348                    * In cmdline, and only screen and prefix on right.
1349                    * Result: last  row, same screen, go to prefix.
1350                    */
1351                   return((long)current_bottom_row | where_screen | WHERE_WINDOW_PREFIX_RIGHT);
1352                }
1353                /*
1354                 * In cmdline, and prefix on left  or none.
1355                 * Result: last  row, same screen, go to filearea.
1356                 */
1357                return((long)current_bottom_row | where_screen | WHERE_WINDOW_FILEAREA);
1358                break;
1359          }
1360          break;
1361    }
1362    return(rc);
1363 }
1364 /***********************************************************************/
1365 #ifdef HAVE_PROTO
enterable_field(long where)1366 bool enterable_field(long where)
1367 #else
1368 bool enterable_field(where)
1369 long where;
1370 #endif
1371 /***********************************************************************/
1372 {
1373    bool rc=TRUE;
1374    ROWTYPE row=0;
1375    long where_screen=0L;
1376    CHARTYPE scrn=0;
1377 
1378    TRACE_FUNCTION("cursor.c:  enterable_field");
1379    where_screen = where & WHERE_SCREEN_MASK;
1380    row = (ROWTYPE)(where & WHERE_ROW_MASK);
1381    scrn = (where_screen == WHERE_SCREEN_LAST) ? 1 : 0;
1382    switch(where & WHERE_WINDOW_MASK)
1383    {
1384       case WHERE_WINDOW_FILEAREA:
1385          if (!screen[scrn].sl[row].main_enterable)
1386             rc = FALSE;
1387          break;
1388       case WHERE_WINDOW_PREFIX_LEFT:
1389       case WHERE_WINDOW_PREFIX_RIGHT:
1390          if (!screen[scrn].sl[row].prefix_enterable)
1391             rc = FALSE;
1392          break;
1393       case WHERE_WINDOW_CMDLINE_TOP:
1394       case WHERE_WINDOW_CMDLINE_BOTTOM:
1395          break;
1396    }
1397    TRACE_RETURN();
1398    return(rc);
1399 }
1400 /***********************************************************************/
1401 #ifdef HAVE_PROTO
go_to_new_field(long save_where,long where)1402 short go_to_new_field(long save_where,long where)
1403 #else
1404 short go_to_new_field(save_where,where)
1405 long save_where,where;
1406 #endif
1407 /***********************************************************************/
1408 {
1409    short rc=RC_OK;
1410    long save_where_screen=0L,where_screen=0L;
1411    long save_where_window=0L,where_window=0L;
1412    ROWTYPE where_row=0;
1413 
1414    TRACE_FUNCTION("cursor.c:  go_to_new_field");
1415    save_where_screen = save_where & WHERE_SCREEN_MASK;
1416    where_screen = where & WHERE_SCREEN_MASK;
1417    save_where_window = save_where & WHERE_WINDOW_MASK;
1418    where_window = where & WHERE_WINDOW_MASK;
1419    where_row = (ROWTYPE)(where & WHERE_ROW_MASK);
1420 #if 0
1421    if (save_where_screen != where_screen)
1422    {
1423    }
1424 #endif
1425    if (save_where_window == where_window)
1426    {
1427       /*
1428        * No change to screen or window...
1429        */
1430       CURRENT_VIEW->focus_line = CURRENT_SCREEN.sl[where_row].line_number;
1431    }
1432    else
1433    {
1434       switch(save_where_window)
1435       {
1436          case WHERE_WINDOW_FILEAREA:
1437             switch(where_window)
1438             {
1439                case WHERE_WINDOW_PREFIX_LEFT:
1440                case WHERE_WINDOW_PREFIX_RIGHT:
1441                   CURRENT_VIEW->current_window = WINDOW_PREFIX;
1442                   CURRENT_VIEW->focus_line = CURRENT_SCREEN.sl[where_row].line_number;
1443                   break;
1444                case WHERE_WINDOW_CMDLINE_TOP:
1445                case WHERE_WINDOW_CMDLINE_BOTTOM:
1446                   CURRENT_VIEW->previous_window = CURRENT_VIEW->current_window;
1447                   CURRENT_VIEW->current_window = WINDOW_COMMAND;
1448                   where_row = 0;
1449                   break;
1450             }
1451             break;
1452          case WHERE_WINDOW_PREFIX_LEFT:
1453          case WHERE_WINDOW_PREFIX_RIGHT:
1454             switch(where_window)
1455             {
1456                case WHERE_WINDOW_FILEAREA:
1457                   CURRENT_VIEW->current_window = WINDOW_FILEAREA;
1458                   CURRENT_VIEW->focus_line = CURRENT_SCREEN.sl[where_row].line_number;
1459                   break;
1460                case WHERE_WINDOW_CMDLINE_TOP:
1461                case WHERE_WINDOW_CMDLINE_BOTTOM:
1462                   CURRENT_VIEW->previous_window = CURRENT_VIEW->current_window;
1463                   CURRENT_VIEW->current_window = WINDOW_COMMAND;
1464                   where_row = 0;
1465                   break;
1466             }
1467             break;
1468          case WHERE_WINDOW_CMDLINE_TOP:
1469          case WHERE_WINDOW_CMDLINE_BOTTOM:
1470             switch(where_window)
1471             {
1472                case WHERE_WINDOW_PREFIX_LEFT:
1473                case WHERE_WINDOW_PREFIX_RIGHT:
1474                   CURRENT_VIEW->current_window = WINDOW_PREFIX;
1475                   CURRENT_VIEW->focus_line = CURRENT_SCREEN.sl[where_row].line_number;
1476                   break;
1477                case WHERE_WINDOW_FILEAREA:
1478                   CURRENT_VIEW->current_window = WINDOW_FILEAREA;
1479                   CURRENT_VIEW->focus_line = CURRENT_SCREEN.sl[where_row].line_number;
1480                   break;
1481             }
1482             break;
1483       }
1484    }
1485    wmove(CURRENT_WINDOW,where_row,0);
1486    TRACE_RETURN();
1487    return(rc);
1488 }
1489 /***********************************************************************/
1490 #ifdef HAVE_PROTO
get_cursor_position(LINETYPE * screen_line,LENGTHTYPE * screen_column,LINETYPE * file_line,LENGTHTYPE * file_column)1491 void get_cursor_position(LINETYPE *screen_line, LENGTHTYPE *screen_column, LINETYPE *file_line, LENGTHTYPE *file_column)
1492 #else
1493 void get_cursor_position(screen_line,screen_column,file_line,file_column)
1494 LINETYPE *screen_line,*file_line;
1495 LENGTHTYPE *screen_column,*file_column;
1496 #endif
1497 /***********************************************************************/
1498 {
1499    unsigned short y=0,x=0;
1500    unsigned short begy=0,begx=0;
1501 
1502    TRACE_FUNCTION("cursor.c:  get_cursor_position");
1503    if (curses_started)
1504    {
1505       getyx(CURRENT_WINDOW,y,x);
1506       getbegyx(CURRENT_WINDOW,begy,begx);
1507       *screen_line = (LINETYPE)(y + begy + 1L);
1508       *screen_column = (LENGTHTYPE)(x + begx + 1L);
1509    }
1510    else
1511       *screen_line = *screen_column = (-1L);
1512    switch(CURRENT_VIEW->current_window)
1513    {
1514       case WINDOW_FILEAREA:
1515          *file_line = CURRENT_VIEW->focus_line;
1516          *file_column = CURRENT_VIEW->verify_col + x;
1517          break;
1518       case WINDOW_PREFIX:
1519          *file_line = CURRENT_VIEW->focus_line;
1520          *file_column = (-1L);
1521          break;
1522       default:   /* command line */
1523          *file_line = *file_column = (-1L);
1524          break;
1525    }
1526    TRACE_RETURN();
1527    return;
1528 }
1529 /***********************************************************************/
1530 #ifdef HAVE_PROTO
advance_focus_line(LINETYPE num_lines)1531 short advance_focus_line(LINETYPE num_lines)
1532 #else
1533 short advance_focus_line(num_lines)
1534 LINETYPE num_lines;
1535 #endif
1536 /***********************************************************************/
1537 {
1538    unsigned short y=0,x=0;
1539    LINE *curr=NULL;
1540    LINETYPE actual_lines=num_lines;
1541    short direction=DIRECTION_FORWARD,rc=RC_OK;
1542 
1543    TRACE_FUNCTION("cursor.c:  advance_focus_line");
1544    if (num_lines < 0L)
1545    {
1546       actual_lines = -num_lines;
1547       direction = DIRECTION_BACKWARD;
1548    }
1549    post_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,(LINE *)NULL,TRUE);
1550    curr = lll_find(CURRENT_FILE->first_line,CURRENT_FILE->last_line,CURRENT_VIEW->focus_line,CURRENT_FILE->number_lines);
1551    while(actual_lines>0)
1552    {
1553       if (direction == DIRECTION_BACKWARD)
1554          curr = curr->prev;
1555       else
1556          curr = curr->next;
1557       if (curr == NULL)
1558          break;
1559       CURRENT_VIEW->focus_line += (LINETYPE)direction;
1560       if (CURRENT_VIEW->scope_all
1561       ||  IN_SCOPE(CURRENT_VIEW,curr))
1562          actual_lines--;
1563    }
1564    if (!line_in_view(current_screen,CURRENT_VIEW->focus_line))
1565       CURRENT_VIEW->current_line = CURRENT_VIEW->focus_line;
1566    pre_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,(LINE *)NULL);
1567    build_screen(current_screen);
1568    display_screen(current_screen);
1569    if (curses_started)
1570    {
1571       getyx(CURRENT_WINDOW,y,x);
1572       y = get_row_for_focus_line(current_screen,CURRENT_VIEW->focus_line,
1573                                CURRENT_VIEW->current_row);
1574       wmove(CURRENT_WINDOW,y,x);
1575    }
1576    if (FOCUS_TOF || FOCUS_BOF)
1577       rc = RC_TOF_EOF_REACHED;
1578    TRACE_RETURN();
1579    return rc;
1580 }
1581 /***********************************************************************/
1582 #ifdef HAVE_PROTO
advance_current_line(LINETYPE num_lines)1583 short advance_current_line(LINETYPE num_lines)
1584 #else
1585 short advance_current_line(num_lines)
1586 LINETYPE num_lines;
1587 #endif
1588 /***********************************************************************/
1589 {
1590    LINE *curr=NULL;
1591    LINETYPE actual_lines=num_lines;
1592    short direction=DIRECTION_FORWARD;
1593    short y=0,x=0,rc=RC_OK;
1594 
1595    TRACE_FUNCTION("cursor.c:  advance_current_line");
1596    if (num_lines < 0L)
1597    {
1598       actual_lines = -num_lines;
1599       direction = DIRECTION_BACKWARD;
1600    }
1601    post_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,(LINE *)NULL,TRUE);
1602    curr = lll_find(CURRENT_FILE->first_line,CURRENT_FILE->last_line,CURRENT_VIEW->current_line,CURRENT_FILE->number_lines);
1603    while(actual_lines>0)
1604    {
1605       if (direction == DIRECTION_BACKWARD)
1606          curr = curr->prev;
1607       else
1608          curr = curr->next;
1609       if (curr == NULL)
1610          break;
1611       CURRENT_VIEW->current_line += (LINETYPE)direction;
1612       if (CURRENT_VIEW->scope_all
1613       ||  IN_SCOPE(CURRENT_VIEW,curr))
1614          actual_lines--;
1615    }
1616    build_screen(current_screen);
1617    if (!line_in_view(current_screen,CURRENT_VIEW->focus_line))
1618    {
1619       if (compatible_feel == COMPAT_XEDIT)
1620          THEcursor_cmdline( current_screen, CURRENT_VIEW, 1 );
1621       CURRENT_VIEW->focus_line = CURRENT_VIEW->current_line;
1622       pre_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,(LINE *)NULL);
1623    }
1624    if (CURRENT_VIEW->current_window != WINDOW_COMMAND)
1625    {
1626       if (CURRENT_VIEW->current_window == WINDOW_FILEAREA)
1627          getyx(CURRENT_WINDOW,y,x);
1628       y = get_row_for_focus_line(current_screen,CURRENT_VIEW->focus_line,CURRENT_VIEW->current_row);
1629       /* THEcursor_move(TRUE,FALSE,y+1,x+1); */
1630       THEcursor_move( current_screen, CURRENT_VIEW, TRUE,TRUE, (short)(y+1), (short)(x+1) );
1631    }
1632    pre_process_line(CURRENT_VIEW,CURRENT_VIEW->focus_line,(LINE *)NULL);
1633    build_screen(current_screen);
1634    display_screen(current_screen);
1635    if (CURRENT_TOF || CURRENT_BOF)
1636       rc = RC_TOF_EOF_REACHED;
1637    TRACE_RETURN();
1638    return rc;
1639 }
1640 /***********************************************************************/
1641 #ifdef HAVE_PROTO
advance_current_or_focus_line(LINETYPE num_lines)1642 short advance_current_or_focus_line(LINETYPE num_lines)
1643 #else
1644 short advance_current_or_focus_line(num_lines)
1645 LINETYPE num_lines;
1646 #endif
1647 /***********************************************************************/
1648 {
1649    short rc=RC_OK;
1650 
1651    TRACE_FUNCTION("cursor.c:  advance_current_or_focus_line");
1652    if (CURRENT_VIEW->current_window == WINDOW_COMMAND
1653    ||  compatible_feel == COMPAT_XEDIT)
1654       rc = advance_current_line(num_lines);
1655    else
1656       rc = advance_focus_line(num_lines);
1657    TRACE_RETURN();
1658    return(rc);
1659 }
1660 /*man***************************************************************************
1661 NAME
1662      resolve_current_and_focus_lines
1663 
1664 SYNOPSIS
1665      void resolve_current_and_focus_lines(view,num_lines,direction,respect_stay)
1666      VIEW_DETAILS *view;
1667      LINETYPE true_line;
1668      LINETYPE num_lines;
1669      short direction;
1670      bool respect_stay;
1671 
1672 DESCRIPTION
1673      This function determines the value of current_line and focus_line
1674      from the existing values of these variables, using the number of
1675      actual lines offset and direction passed as parameters.
1676 
1677      The num_lines parameter is the offset from either the focus or
1678      current line expressed in file lines (ie ignores scope - SCOPE ALL)
1679      The true_line parameter is the value of either focus or current lien.
1680 
1681      This function determines what the new values for focus_line and
1682      current_line are to be based on the status of STAY and of the
1683      current compatibility mode.  On return from this function, the
1684      screen will have been displayed with the correct positioning of
1685      the focus and current lines and the position of the cursor.
1686 
1687      If respect_stay is FALSE, then SET STAY is ignored (ie for PUT
1688      command).
1689 
1690      If sos is TRUE, then this function was called from a SOS command.
1691      All SOS commands should result in cursor movement as for THE
1692      compatibility mode.
1693 
1694 RETURN VALUE
1695      void
1696 *******************************************************************************/
1697 #ifdef HAVE_PROTO
resolve_current_and_focus_lines(CHARTYPE curr_screen,VIEW_DETAILS * view,LINETYPE true_line,LINETYPE num_lines,short direction,bool respect_stay,bool sos)1698 void resolve_current_and_focus_lines( CHARTYPE curr_screen, VIEW_DETAILS *view, LINETYPE true_line, LINETYPE num_lines, short direction, bool respect_stay, bool sos )
1699 #else
1700 void resolve_current_and_focus_lines( curr_screen, view, true_line, num_lines, direction, respect_stay, sos )
1701 CHARTYPE curr_screen;
1702 VIEW_DETAILS *view;
1703 LINETYPE true_line,num_lines;
1704 short direction;
1705 bool respect_stay;
1706 bool sos;
1707 #endif
1708 /***********************************************************************/
1709 {
1710    short y=0,x=0;
1711    short save_compatible_feel=compatible_feel;
1712 
1713    TRACE_FUNCTION("cursor.c:  resolve_current_and_focus_lines");
1714    /*
1715     * If no lines to move, don't do anything...
1716     */
1717    if ( num_lines == 0 )
1718    {
1719       build_screen( curr_screen );
1720       display_screen( curr_screen );
1721       TRACE_RETURN();
1722       return;
1723    }
1724    /*
1725     * Set the internal compatibility mode to THE for sos = TRUE.
1726     */
1727    if ( sos )
1728       save_compatible_feel = COMPAT_THE;
1729    /*
1730     * If STAY is ON, and we are respecting it, don't do anything...
1731     */
1732    if ( view->stay
1733    &&  ( respect_stay || compatible_feel != COMPAT_XEDIT ) )
1734    {
1735       build_screen( curr_screen );
1736       display_screen( curr_screen );
1737       TRACE_RETURN();
1738       return;
1739    }
1740    /*
1741     * If we are on the command line, all actions are the same irrespective
1742     * of the compatibility mode in place.
1743     */
1744    if ( view->current_window == WINDOW_COMMAND )
1745    {
1746       view->current_line = true_line+num_lines-(LINETYPE)direction;
1747       build_screen( curr_screen );
1748       display_screen( curr_screen );
1749       TRACE_RETURN();
1750       return;
1751    }
1752    /*
1753     * From here down is applicable to the cursor being in the FILEAREA or
1754     * PREFIX...
1755     */
1756    switch( save_compatible_feel )
1757    {
1758       case COMPAT_THE:
1759       case COMPAT_KEDIT:
1760       case COMPAT_KEDITW:
1761          view->focus_line = true_line+num_lines-(LINETYPE)direction;
1762          build_screen( curr_screen );
1763          if ( !line_in_view( curr_screen, view->focus_line ) )
1764             view->current_line = view->focus_line;
1765          pre_process_line( view, view->focus_line, (LINE *)NULL );
1766          build_screen( curr_screen );
1767          display_screen( curr_screen );
1768          if ( curses_started )
1769          {
1770             getyx( SCREEN_WINDOW( curr_screen ), y, x );
1771             y = get_row_for_focus_line( curr_screen, view->focus_line, view->current_row );
1772             wmove(SCREEN_WINDOW( curr_screen), y, x );
1773          }
1774          break;
1775       case COMPAT_XEDIT:
1776          view->current_line = true_line+num_lines-(LINETYPE)direction;
1777          pre_process_line( view, view->focus_line, (LINE *)NULL );
1778          build_screen( curr_screen );
1779          if ( !line_in_view( curr_screen, view->focus_line ) )
1780             THEcursor_cmdline( curr_screen, view, 1 );
1781          else
1782          {
1783             if ( curses_started )
1784             {
1785                if ( view->current_window == WINDOW_FILEAREA )
1786                   getyx( SCREEN_WINDOW( curr_screen ), y, x );
1787                y = get_row_for_focus_line( curr_screen, view->focus_line, view->current_row );
1788                THEcursor_move( curr_screen, view, TRUE, FALSE, (short)(y+1), (short)(x+1) );
1789             }
1790          }
1791          display_screen( curr_screen );
1792          break;
1793    }
1794    TRACE_RETURN();
1795    return;
1796 }
1797