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, ¤t_top_row );
989 find_last_focus_line( current_screen, ¤t_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, ¤t_top_row );
1187 find_last_focus_line( current_screen, ¤t_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