Function to get screen size added
[scilab.git] / scilab / routines / xsci / x_util.c
1 /*
2  *      $XConsortium: util.c,v 1.31 91/06/20 18:34:47 gildea Exp $
3  */
4
5 /*
6  * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts.
7  *
8  *                         All Rights Reserved
9  *
10  * Permission to use, copy, modify, and distribute this software and its
11  * documentation for any purpose and without fee is hereby granted,
12  * provided that the above copyright notice appear in all copies and that
13  * both that copyright notice and this permission notice appear in
14  * supporting documentation, and that the name of Digital Equipment
15  * Corporation not be used in advertising or publicity pertaining to
16  * distribution of the software without specific, written prior permission.
17  *
18  *
19  * DIGITAL DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING
20  * ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL
21  * DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR
22  * ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS,
23  * WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION,
24  * ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS
25  * SOFTWARE.
26  */
27
28 /* util.c */
29
30 #include "x_ptyxP.h"
31 #include "x_data.h"
32 #include "x_error.h"
33 #include "x_menu.h"
34 #include "../stack-c.h"
35 #include "../machine.h"
36 #include "All-extern-x.h"
37
38 #include <stdio.h>
39
40 extern int IsConsoleMode(void);
41
42 static void horizontal_copy_area();
43 static void vertical_copy_area();
44
45 /*
46  * These routines are used for the jump scroll feature
47  */
48
49 void FlushScroll(screen)
50 register TScreen *screen;
51 {
52         register int i;
53         register int shift = -screen->topline;
54         register int bot = screen->max_row - shift;
55         register int refreshtop;
56         register int refreshheight;
57         register int scrolltop;
58         register int scrollheight;
59
60         if(screen->cursor_state)
61                 HideCursor();
62         if(screen->scroll_amt > 0) {
63                 refreshheight = screen->refresh_amt;
64                 scrollheight = screen->bot_marg - screen->top_marg -
65                  refreshheight + 1;
66                 if((refreshtop = screen->bot_marg - refreshheight + 1 + shift) >
67                  (i = screen->max_row - screen->scroll_amt + 1))
68                         refreshtop = i;
69                 if(screen->scrollWidget && !screen->alternate
70                  && screen->top_marg == 0) {
71                         scrolltop = 0;
72                         if((scrollheight += shift) > i)
73                                 scrollheight = i;
74                         if((i = screen->bot_marg - bot) > 0 &&
75                          (refreshheight -= i) < screen->scroll_amt)
76                                 refreshheight = screen->scroll_amt;
77                         if((i = screen->savedlines) < screen->savelines) {
78                                 if((i += screen->scroll_amt) >
79                                   screen->savelines)
80                                         i = screen->savelines;
81                                 screen->savedlines = i;
82                                 ScrollBarDrawThumb(screen->scrollWidget);
83                         }
84                 } else {
85                         scrolltop = screen->top_marg + shift;
86                         if((i = bot - (screen->bot_marg - screen->refresh_amt +
87                          screen->scroll_amt)) > 0) {
88                                 if(bot < screen->bot_marg)
89                                         refreshheight = screen->scroll_amt + i;
90                         } else {
91                                 scrollheight += i;
92                                 refreshheight = screen->scroll_amt;
93                                 if((i = screen->top_marg + screen->scroll_amt -
94                                  1 - bot) > 0) {
95                                         refreshtop += i;
96                                         refreshheight -= i;
97                                 }
98                         }
99                 }
100         } else {
101                 refreshheight = -screen->refresh_amt;
102                 scrollheight = screen->bot_marg - screen->top_marg -
103                  refreshheight + 1;
104                 refreshtop = screen->top_marg + shift;
105                 scrolltop = refreshtop + refreshheight;
106                 if((i = screen->bot_marg - bot) > 0)
107                         scrollheight -= i;
108                 if((i = screen->top_marg + refreshheight - 1 - bot) > 0)
109                         refreshheight -= i;
110         }
111         scrolling_copy_area(screen, scrolltop+screen->scroll_amt,
112                             scrollheight, screen->scroll_amt);
113         ScrollSelection(screen, -(screen->scroll_amt));
114         screen->scroll_amt = 0;
115         screen->refresh_amt = 0;
116         if(refreshheight > 0) {
117                 XClearArea (
118                     screen->display,
119                     TextWindow(screen),
120                     (int) screen->border + screen->scrollbar,
121                     (int) refreshtop * FontHeight(screen) + screen->border,
122                     (unsigned) Width(screen),
123                     (unsigned) refreshheight * FontHeight(screen),
124                     FALSE);
125                 ScrnRefresh(screen, refreshtop, 0, refreshheight,
126                  screen->max_col + 1, False);
127         }
128 }
129
130
131 int AddToRefresh(screen)
132 register TScreen *screen;
133 {
134         register int amount = screen->refresh_amt;
135         register int row = screen->cur_row;
136
137         if(amount == 0)
138                 return(0);
139         if(amount > 0) {
140                 register int bottom;
141
142                 if(row == (bottom = screen->bot_marg) - amount) {
143                         screen->refresh_amt++;
144                         return(1);
145                 }
146                 return(row >= bottom - amount + 1 && row <= bottom);
147         } else {
148                 register int top;
149
150                 amount = -amount;
151                 if(row == (top = screen->top_marg) + amount) {
152                         screen->refresh_amt--;
153                         return(1);
154                 }
155                 return(row <= top + amount - 1 && row >= top);
156         }
157 }
158
159 /* 
160  * scrolls the screen by amount lines, erases bottom, doesn't alter 
161  * cursor position (i.e. cursor moves down amount relative to text).
162  * All done within the scrolling region, of course. 
163  * requires: amount > 0
164  */
165 void Scroll(screen, amount)
166 register TScreen *screen;
167 register int amount;
168 {
169         register int i = screen->bot_marg - screen->top_marg + 1;
170         register int shift;
171         register int bot;
172         register int refreshtop = 0;
173         register int refreshheight;
174         register int scrolltop;
175         register int scrollheight;
176
177         if(screen->cursor_state)
178                 HideCursor();
179         if (amount > i)
180                 amount = i;
181     if(screen->jumpscroll) {
182         if(screen->scroll_amt > 0) {
183                 if(screen->refresh_amt + amount > i)
184                         FlushScroll(screen);
185                 screen->scroll_amt += amount;
186                 screen->refresh_amt += amount;
187         } else {
188                 if(screen->scroll_amt < 0)
189                         FlushScroll(screen);
190                 screen->scroll_amt = amount;
191                 screen->refresh_amt = amount;
192         }
193         refreshheight = 0;
194     } else {
195         ScrollSelection(screen, -(amount));
196         if (amount == i) {
197                 ClearScreen(screen);
198                 return;
199         }
200         shift = -screen->topline;
201         bot = screen->max_row - shift;
202         scrollheight = i - amount;
203         refreshheight = amount;
204         if((refreshtop = screen->bot_marg - refreshheight + 1 + shift) >
205          (i = screen->max_row - refreshheight + 1))
206                 refreshtop = i;
207         if(screen->scrollWidget && !screen->alternate
208          && screen->top_marg == 0) {
209                 scrolltop = 0;
210                 if((scrollheight += shift) > i)
211                         scrollheight = i;
212                 if((i = screen->savedlines) < screen->savelines) {
213                         if((i += amount) > screen->savelines)
214                                 i = screen->savelines;
215                         screen->savedlines = i;
216                         ScrollBarDrawThumb(screen->scrollWidget);
217                 }
218         } else {
219                 scrolltop = screen->top_marg + shift;
220                 if((i = screen->bot_marg - bot) > 0) {
221                         scrollheight -= i;
222                         if((i = screen->top_marg + amount - 1 - bot) >= 0) {
223                                 refreshtop += i;
224                                 refreshheight -= i;
225                         }
226                 }
227         }
228
229         if (screen->multiscroll && amount == 1 &&
230             screen->topline == 0 && screen->top_marg == 0 &&
231             screen->bot_marg == screen->max_row) {
232             if (screen->incopy < 0 && screen->scrolls == 0)
233                 CopyWait(screen);
234             screen->scrolls++;
235         }
236         scrolling_copy_area(screen, scrolltop+amount, scrollheight, amount);
237         if(refreshheight > 0) {
238                 XClearArea (
239                    screen->display,
240                    TextWindow(screen),
241                    (int) screen->border + screen->scrollbar,
242                    (int) refreshtop * FontHeight(screen) + screen->border,
243                    (unsigned) Width(screen),
244                    (unsigned) refreshheight * FontHeight(screen),
245                    FALSE);
246                 if(refreshheight > shift)
247                         refreshheight = shift;
248         }
249     }
250         if(screen->scrollWidget && !screen->alternate && screen->top_marg == 0)
251                 ScrnDeleteLine(screen->allbuf, screen->bot_marg +
252                  screen->savelines, 0, amount, screen->max_col + 1);
253         else
254                 ScrnDeleteLine(screen->buf, screen->bot_marg, screen->top_marg,
255                  amount, screen->max_col + 1);
256         if(refreshheight > 0)
257                 ScrnRefresh(screen, refreshtop, 0, refreshheight,
258                  screen->max_col + 1, False);
259 }
260
261
262 /*
263  * Reverse scrolls the screen by amount lines, erases top, doesn't alter
264  * cursor position (i.e. cursor moves up amount relative to text).
265  * All done within the scrolling region, of course.
266  * Requires: amount > 0
267  */
268 void RevScroll(screen, amount)
269 register TScreen *screen;
270 register int amount;
271 {
272         register int i = screen->bot_marg - screen->top_marg + 1;
273         register int shift;
274         register int bot;
275         register int refreshtop;
276         register int refreshheight;
277         register int scrolltop;
278         register int scrollheight;
279
280         if(screen->cursor_state)
281                 HideCursor();
282         if (amount > i)
283                 amount = i;
284     if(screen->jumpscroll) {
285         if(screen->scroll_amt < 0) {
286                 if(-screen->refresh_amt + amount > i)
287                         FlushScroll(screen);
288                 screen->scroll_amt -= amount;
289                 screen->refresh_amt -= amount;
290         } else {
291                 if(screen->scroll_amt > 0)
292                         FlushScroll(screen);
293                 screen->scroll_amt = -amount;
294                 screen->refresh_amt = -amount;
295         }
296     } else {
297         shift = -screen->topline;
298         bot = screen->max_row - shift;
299         refreshheight = amount;
300         scrollheight = screen->bot_marg - screen->top_marg -
301          refreshheight + 1;
302         refreshtop = screen->top_marg + shift;
303         scrolltop = refreshtop + refreshheight;
304         if((i = screen->bot_marg - bot) > 0)
305                 scrollheight -= i;
306         if((i = screen->top_marg + refreshheight - 1 - bot) > 0)
307                 refreshheight -= i;
308
309         if (screen->multiscroll && amount == 1 &&
310             screen->topline == 0 && screen->top_marg == 0 &&
311             screen->bot_marg == screen->max_row) {
312             if (screen->incopy < 0 && screen->scrolls == 0)
313                 CopyWait(screen);
314             screen->scrolls++;
315         }
316         scrolling_copy_area(screen, scrolltop-amount, scrollheight, -amount);
317         if(refreshheight > 0)
318                 XClearArea (
319                     screen->display,
320                     TextWindow(screen),
321                     (int) screen->border + screen->scrollbar,
322                     (int) refreshtop * FontHeight(screen) + screen->border,
323                     (unsigned) Width(screen),
324                     (unsigned) refreshheight * FontHeight(screen),
325                     FALSE);
326     }
327         ScrnInsertLine (screen->buf, screen->bot_marg, screen->top_marg,
328                         amount, screen->max_col + 1);
329 }
330
331 /*
332  * If cursor not in scrolling region, returns.  Else,
333  * inserts n blank lines at the cursor's position.  Lines above the
334  * bottom margin are lost.
335  */
336 void InsertLine (screen, n)
337 register TScreen *screen;
338 register int n;
339 {
340         register int i;
341         register int shift;
342         register int bot;
343         register int refreshtop;
344         register int refreshheight;
345         register int scrolltop;
346         register int scrollheight;
347
348         if (screen->cur_row < screen->top_marg ||
349          screen->cur_row > screen->bot_marg)
350                 return;
351         if(screen->cursor_state)
352                 HideCursor();
353         screen->do_wrap = 0;
354         if (n > (i = screen->bot_marg - screen->cur_row + 1))
355                 n = i;
356     if(screen->jumpscroll) {
357         if(screen->scroll_amt <= 0 &&
358          screen->cur_row <= -screen->refresh_amt) {
359                 if(-screen->refresh_amt + n > screen->max_row + 1)
360                         FlushScroll(screen);
361                 screen->scroll_amt -= n;
362                 screen->refresh_amt -= n;
363         } else if(screen->scroll_amt)
364                 FlushScroll(screen);
365     }
366     if(!screen->scroll_amt) {
367         shift = -screen->topline;
368         bot = screen->max_row - shift;
369         refreshheight = n;
370         scrollheight = screen->bot_marg - screen->cur_row - refreshheight + 1;
371         refreshtop = screen->cur_row + shift;
372         scrolltop = refreshtop + refreshheight;
373         if((i = screen->bot_marg - bot) > 0)
374                 scrollheight -= i;
375         if((i = screen->cur_row + refreshheight - 1 - bot) > 0)
376                 refreshheight -= i;
377         vertical_copy_area(screen, scrolltop-n, scrollheight, -n);
378         if(refreshheight > 0)
379                 XClearArea (
380                     screen->display,
381                     TextWindow(screen),
382                     (int) screen->border + screen->scrollbar,
383                     (int) refreshtop * FontHeight(screen) + screen->border,
384                     (unsigned) Width(screen),
385                     (unsigned) refreshheight * FontHeight(screen),
386                     FALSE);
387     }
388         /* adjust screen->buf */
389         ScrnInsertLine(screen->buf, screen->bot_marg, screen->cur_row, n,
390                         screen->max_col + 1);
391 }
392
393 /*
394  * If cursor not in scrolling region, returns.  Else, deletes n lines
395  * at the cursor's position, lines added at bottom margin are blank.
396  */
397
398 void DeleteLine(screen, n)
399 register TScreen *screen;
400 register int n;
401 {
402         register int i;
403         register int shift;
404         register int bot;
405         register int refreshtop;
406         register int refreshheight;
407         register int scrolltop;
408         register int scrollheight;
409
410         if (screen->cur_row < screen->top_marg ||
411          screen->cur_row > screen->bot_marg)
412                 return;
413         if(screen->cursor_state)
414                 HideCursor();
415         screen->do_wrap = 0;
416         if (n > (i = screen->bot_marg - screen->cur_row + 1))
417                 n = i;
418     if(screen->jumpscroll) {
419         if(screen->scroll_amt >= 0 && screen->cur_row == screen->top_marg) {
420                 if(screen->refresh_amt + n > screen->max_row + 1)
421                         FlushScroll(screen);
422                 screen->scroll_amt += n;
423                 screen->refresh_amt += n;
424         } else if(screen->scroll_amt)
425                 FlushScroll(screen);
426     }
427     if(!screen->scroll_amt) {
428
429         shift = -screen->topline;
430         bot = screen->max_row - shift;
431         scrollheight = i - n;
432         refreshheight = n;
433         if((refreshtop = screen->bot_marg - refreshheight + 1 + shift) >
434          (i = screen->max_row - refreshheight + 1))
435                 refreshtop = i;
436         if(screen->scrollWidget && !screen->alternate && screen->cur_row == 0) {
437                 scrolltop = 0;
438                 if((scrollheight += shift) > i)
439                         scrollheight = i;
440                 if((i = screen->savedlines) < screen->savelines) {
441                         if((i += n) > screen->savelines)
442                                 i = screen->savelines;
443                         screen->savedlines = i;
444                         ScrollBarDrawThumb(screen->scrollWidget);
445                 }
446         } else {
447                 scrolltop = screen->cur_row + shift;
448                 if((i = screen->bot_marg - bot) > 0) {
449                         scrollheight -= i;
450                         if((i = screen->cur_row + n - 1 - bot) >= 0) {
451                                 refreshheight -= i;
452                         }
453                 }
454         }
455         vertical_copy_area(screen, scrolltop+n, scrollheight, n);
456         if(refreshheight > 0)
457                 XClearArea (
458                     screen->display,
459                     TextWindow(screen),
460                     (int) screen->border + screen->scrollbar,
461                     (int) refreshtop * FontHeight(screen) + screen->border,
462                     (unsigned) Width(screen),
463                     (unsigned) refreshheight * FontHeight(screen),
464                     FALSE);
465     }
466         /* adjust screen->buf */
467         if(screen->scrollWidget && !screen->alternate && screen->cur_row == 0)
468                 ScrnDeleteLine(screen->allbuf, screen->bot_marg +
469                  screen->savelines, 0, n, screen->max_col + 1);
470         else
471                 ScrnDeleteLine(screen->buf, screen->bot_marg, screen->cur_row,
472                  n, screen->max_col + 1);
473 }
474
475 /*
476  * Insert n blanks at the cursor's position, no wraparound
477  */
478
479 void InsertChar (screen, n)
480     register TScreen *screen;
481     register int n;
482 {
483         register int cx, cy;
484
485         if(screen->cursor_state)
486                 HideCursor();
487         screen->do_wrap = 0;
488         if(screen->cur_row - screen->topline <= screen->max_row) {
489             if(!AddToRefresh(screen)) {
490                 if(screen->scroll_amt)
491                         FlushScroll(screen);
492
493                 /*
494                  * prevent InsertChar from shifting the end of a line over
495                  * if it is being appended to
496                  */
497                 if (non_blank_line (screen->buf, screen->cur_row, 
498                                     screen->cur_col, screen->max_col + 1))
499                     horizontal_copy_area(screen, screen->cur_col,
500                                          screen->max_col+1 - (screen->cur_col+n),
501                                          n);
502         
503                 cx = CursorX (screen, screen->cur_col);
504                 cy = CursorY (screen, screen->cur_row);
505
506                 XFillRectangle(
507                     screen->display,
508                     TextWindow(screen), 
509                     screen->reverseGC,
510                     cx, cy,
511                     (unsigned) n * FontWidth(screen), (unsigned) FontHeight(screen));
512             }
513         }
514         /* adjust screen->buf */
515         ScrnInsertChar(screen->buf, screen->cur_row, screen->cur_col, n,
516                         screen->max_col + 1);
517 }
518
519 /*
520  * Deletes n chars at the cursor's position, no wraparound.
521  */
522 void DeleteChar (screen, n)
523     register TScreen *screen;
524     register int        n;
525 {
526         register int width;
527
528         if(screen->cursor_state)
529                 HideCursor();
530         screen->do_wrap = 0;
531         if (n > (width = screen->max_col + 1 - screen->cur_col))
532                 n = width;
533                 
534         if(screen->cur_row - screen->topline <= screen->max_row) {
535             if(!AddToRefresh(screen)) {
536                 if(screen->scroll_amt)
537                         FlushScroll(screen);
538         
539                 horizontal_copy_area(screen, screen->cur_col+n,
540                                      screen->max_col+1 - (screen->cur_col+n),
541                                      -n);
542         
543                 XFillRectangle
544                     (screen->display, TextWindow(screen),
545                      screen->reverseGC,
546                      screen->border + screen->scrollbar
547                        + Width(screen) - n*FontWidth(screen),
548                      CursorY (screen, screen->cur_row),(unsigned) n * FontWidth(screen),
549                      (unsigned) FontHeight(screen));
550             }
551         }
552         /* adjust screen->buf */
553         ScrnDeleteChar (screen->buf, screen->cur_row, screen->cur_col, n,
554                         screen->max_col + 1);
555
556 }
557
558 /*
559  * Clear from cursor position to beginning of display, inclusive.
560  */
561
562 void ClearAbove (screen)
563      register TScreen *screen;
564 {
565   register int top, height;
566
567   if(screen->cursor_state)
568                 HideCursor();
569         if((top = -screen->topline) <= screen->max_row) {
570                 if(screen->scroll_amt)
571                         FlushScroll(screen);
572                 if((height = screen->cur_row + top) > screen->max_row)
573                         height = screen->max_row;
574                 if((height -= top) > 0)
575                         XClearArea(screen->display, TextWindow(screen),
576                          screen->border + screen->scrollbar, top *
577                          FontHeight(screen) + screen->border,
578                          (unsigned)Width(screen), (unsigned)height * FontHeight(screen), FALSE);
579
580                 if(screen->cur_row - screen->topline <= screen->max_row)
581                         ClearLeft(screen);
582         }
583         ClearBufRows(screen, 0, screen->cur_row - 1);
584 }
585
586 /*
587  * Clear from cursor position to end of display, inclusive.
588  */
589
590 void ClearBelow (screen)
591 register TScreen *screen;
592 {
593   register int top;
594
595         ClearRight(screen);
596         if((top = screen->cur_row - screen->topline) <= screen->max_row) {
597                 if(screen->scroll_amt)
598                         FlushScroll(screen);
599                 if(++top <= screen->max_row)
600                         XClearArea(screen->display, TextWindow(screen),
601                          screen->border + screen->scrollbar, top *
602                          FontHeight(screen) + screen->border,
603                          (unsigned) Width(screen),(unsigned) (screen->max_row - top + 1) *
604                          FontHeight(screen), FALSE);
605         }
606         ClearBufRows(screen, screen->cur_row + 1, screen->max_row);
607 }
608
609 /* 
610  * Clear last part of cursor's line, inclusive.
611  */
612
613 void ClearRight (screen)
614 register TScreen *screen;
615 {
616         if(screen->cursor_state)
617                 HideCursor();
618         screen->do_wrap = 0;
619         if(screen->cur_row - screen->topline <= screen->max_row) {
620             if(!AddToRefresh(screen)) {
621         if(screen->scroll_amt)
622                 FlushScroll(screen);
623                 XFillRectangle(screen->display, TextWindow(screen),
624                   screen->reverseGC,
625                  CursorX(screen, screen->cur_col),
626                  CursorY(screen, screen->cur_row),
627                  (unsigned) Width(screen) - screen->cur_col * FontWidth(screen),
628                  (unsigned)FontHeight(screen));
629             }
630         }
631         bzero((char*) ( screen->buf [2 * screen->cur_row] + screen->cur_col),
632                (screen->max_col - screen->cur_col + 1));
633         bzero((char *) (screen->buf [2 * screen->cur_row + 1] + screen->cur_col),
634                (screen->max_col - screen->cur_col + 1));
635         /* with the right part cleared, we can't be wrapping */
636         screen->buf [2 * screen->cur_row + 1] [0] &= ~LINEWRAPPED;
637 }
638
639 /*
640  * Clear first part of cursor's line, inclusive.
641  */
642
643 void ClearLeft (screen)
644     register TScreen *screen;
645 {
646         int i;
647         Char *cp;
648
649         if(screen->cursor_state)
650                 HideCursor();
651         screen->do_wrap = 0;
652         if(screen->cur_row - screen->topline <= screen->max_row) {
653             if(!AddToRefresh(screen)) {
654                 if(screen->scroll_amt)
655                         FlushScroll(screen);
656                 XFillRectangle (screen->display, TextWindow(screen),
657                      screen->reverseGC,
658                      screen->border + screen->scrollbar,
659                       CursorY (screen, screen->cur_row),
660                      (unsigned)(screen->cur_col + 1) * FontWidth(screen),
661                      (unsigned)FontHeight(screen));
662             }
663         }
664         
665         for ( i=0, cp=screen->buf[2 * screen->cur_row];
666               i < screen->cur_col + 1;
667               i++, cp++)
668             *cp = ' ';
669         for ( i=0, cp=screen->buf[2 * screen->cur_row + 1];
670               i < screen->cur_col + 1;
671               i++, cp++)
672             *cp = CHARDRAWN;
673 }
674
675 /* 
676  * Erase the cursor's line.
677  */
678
679 void ClearLine(screen)
680 register TScreen *screen;
681 {
682         if(screen->cursor_state)
683                 HideCursor();
684         screen->do_wrap = 0;
685         if(screen->cur_row - screen->topline <= screen->max_row) {
686             if(!AddToRefresh(screen)) {
687                 if(screen->scroll_amt)
688                         FlushScroll(screen);
689                 XFillRectangle (screen->display, TextWindow(screen), 
690                      screen->reverseGC,
691                      screen->border + screen->scrollbar,
692                       CursorY (screen, screen->cur_row),
693                      (unsigned) Width(screen), (unsigned) FontHeight(screen));
694             }
695         }
696         bzero ((char *) (screen->buf [2 * screen->cur_row]), (screen->max_col + 1));
697         bzero ((char *) (screen->buf [2 * screen->cur_row + 1]), (screen->max_col + 1));
698 }
699
700 void ClearScreen(screen)
701      register TScreen *screen;
702 {
703         register int top;
704
705         if(screen->cursor_state)
706                 HideCursor();
707         screen->do_wrap = 0;
708         if((top = -screen->topline) <= screen->max_row) {
709                 if(screen->scroll_amt)
710                         FlushScroll(screen);
711                 if(top == 0)
712                         XClearWindow(screen->display, TextWindow(screen));
713                 else
714                         XClearArea(screen->display, TextWindow(screen),
715                          screen->border + screen->scrollbar, 
716                          top * FontHeight(screen) + screen->border,     
717                          (unsigned) Width(screen), (unsigned)(screen->max_row - top + 1) *
718                          FontHeight(screen), FALSE);
719         }
720         ClearBufRows (screen, 0, screen->max_row);
721 }
722
723 void CopyWait(screen)
724 register TScreen *screen;
725 {
726         XEvent reply;
727         XEvent *rep = &reply;
728
729         while (1) {
730                 XWindowEvent (screen->display, VWindow(screen), 
731                   ExposureMask, &reply);
732                 switch (reply.type) {
733                 case Expose:
734                         HandleExposure (screen, &reply);
735                         break;
736                 case NoExpose:
737                 case GraphicsExpose:
738                         if (screen->incopy <= 0) {
739                                 screen->incopy = 1;
740                                 if (screen->scrolls > 0)
741                                         screen->scrolls--;
742                         }
743                         if (reply.type == GraphicsExpose)
744                             HandleExposure (screen, &reply);
745
746                         if ((reply.type == NoExpose) ||
747                             ((XExposeEvent *)rep)->count == 0) {
748                             if (screen->incopy <= 0 && screen->scrolls > 0)
749                                 screen->scrolls--;
750                             if (screen->scrolls == 0) {
751                                 screen->incopy = 0;
752                                 return;
753                             }
754                             screen->incopy = -1;
755                         }
756                         break;
757                 }
758         }
759 }
760
761 /*
762  * used by vertical_copy_area and and horizontal_copy_area
763  */
764 static void
765 copy_area(screen, src_x, src_y, width, height, dest_x, dest_y)
766     TScreen *screen;
767     int src_x, src_y;
768     unsigned int width, height;
769     int dest_x, dest_y;
770 {
771     /* wait for previous CopyArea to complete unless
772        multiscroll is enabled and active */
773     if (screen->incopy  &&  screen->scrolls == 0)
774         CopyWait(screen);
775     screen->incopy = -1;
776
777     /* save for translating Expose events */
778     screen->copy_src_x = src_x;
779     screen->copy_src_y = src_y;
780     screen->copy_width = width;
781     screen->copy_height = height;
782     screen->copy_dest_x = dest_x;
783     screen->copy_dest_y = dest_y;
784
785     XCopyArea(screen->display, 
786               TextWindow(screen), TextWindow(screen),
787               screen->normalGC,
788               src_x, src_y, width, height, dest_x, dest_y);
789 }
790
791 /*
792  * use when inserting or deleting characters on the current line
793  */
794 static void
795 horizontal_copy_area(screen, firstchar, nchars, amount)
796     TScreen *screen;
797     int firstchar;              /* char pos on screen to start copying at */
798     int nchars;
799     int amount;                 /* number of characters to move right */
800 {
801     int src_x = CursorX(screen, firstchar);
802     int src_y = CursorY(screen, screen->cur_row);
803
804     copy_area(screen, src_x, src_y,
805               (unsigned)nchars*FontWidth(screen),(unsigned) FontHeight(screen),
806               src_x + amount*FontWidth(screen), src_y);
807 }
808
809 /*
810  * use when inserting or deleting lines from the screen
811  */
812 static void
813 vertical_copy_area(screen, firstline, nlines, amount)
814     TScreen *screen;
815     int firstline;              /* line on screen to start copying at */
816     int nlines;
817     int amount;                 /* number of lines to move up (neg=down) */
818 {
819     if(nlines > 0) {
820         int src_x = screen->border + screen->scrollbar;
821         int src_y = firstline * FontHeight(screen) + screen->border;
822
823         copy_area(screen, src_x, src_y,
824                   (unsigned)Width(screen),(unsigned) nlines*FontHeight(screen),
825                   src_x, src_y - amount*FontHeight(screen));
826     }
827 }
828
829 /*
830  * use when scrolling the entire screen
831  */
832
833 void scrolling_copy_area(screen, firstline, nlines, amount)
834     TScreen *screen;
835     int firstline;              /* line on screen to start copying at */
836     int nlines;
837     int amount;                 /* number of lines to move up (neg=down) */
838 {
839
840     if(nlines > 0) {
841         vertical_copy_area(screen, firstline, nlines, amount);
842     }
843 }
844
845 /*
846  * Handler for Expose events on the VT widget.
847  * Returns 1 iff the area where the cursor was got refreshed.
848  */
849
850 int HandleExposure (screen, event)
851     register TScreen *screen;
852     register XEvent *event;
853 {
854     register XExposeEvent *reply = (XExposeEvent *)event;
855
856     /* if not doing CopyArea or if this is a GraphicsExpose, don't translate */
857     if(!screen->incopy  ||  event->type != Expose)
858         return handle_translated_exposure (screen, reply->x, reply->y,
859                                            reply->width, reply->height);
860     else {
861         /* compute intersection of area being copied with
862            area being exposed. */
863         int both_x1 = Max(screen->copy_src_x, reply->x);
864         int both_y1 = Max(screen->copy_src_y, reply->y);
865         int both_x2 = Min(screen->copy_src_x+screen->copy_width,
866                           reply->x+reply->width);
867         int both_y2 = Min(screen->copy_src_y+screen->copy_height,
868                           reply->y+reply->height);
869         int value = 0;
870
871         /* was anything copied affected? */
872         if(both_x2 > both_x1  && both_y2 > both_y1) {
873             /* do the copied area */
874             value = handle_translated_exposure
875                 (screen, reply->x + screen->copy_dest_x - screen->copy_src_x,
876                  reply->y + screen->copy_dest_y - screen->copy_src_y,
877                  reply->width, reply->height);
878         }
879         /* was anything not copied affected? */
880         if(reply->x < both_x1 || reply->y < both_y1
881            || reply->x+reply->width > both_x2
882            || reply->y+reply->height > both_y2)
883             value = handle_translated_exposure (screen, reply->x, reply->y,
884                                                 reply->width, reply->height);
885
886         return value;
887     }
888 }
889
890 /*
891  * Called by the ExposeHandler to do the actual repaint after the coordinates
892  * have been translated to allow for any CopyArea in progress.
893  * The rectangle passed in is pixel coordinates.
894  */
895 int handle_translated_exposure (screen, rect_x, rect_y, rect_width, rect_height)
896     register TScreen *screen;
897     register int rect_x, rect_y;
898     register int rect_width, rect_height;
899 {
900   register int toprow, leftcol, nrows, ncols;
901
902         toprow = (rect_y - screen->border) / FontHeight(screen);
903         if(toprow < 0)
904                 toprow = 0;
905         leftcol = (rect_x - screen->border - screen->scrollbar)
906             / FontWidth(screen);
907         if(leftcol < 0)
908                 leftcol = 0;
909         nrows = (rect_y + rect_height - 1 - screen->border) / 
910                 FontHeight(screen) - toprow + 1;
911         ncols =
912          (rect_x + rect_width - 1 - screen->border - screen->scrollbar) /
913                         FontWidth(screen) - leftcol + 1;
914         toprow -= screen->scrolls;
915         if (toprow < 0) {
916                 nrows += toprow;
917                 toprow = 0;
918         }
919         if (toprow + nrows - 1 > screen->max_row)
920                 nrows = screen->max_row - toprow + 1;
921         if (leftcol + ncols - 1 > screen->max_col)
922                 ncols = screen->max_col - leftcol + 1;
923
924         if (nrows > 0 && ncols > 0) {
925                 ScrnRefresh (screen, toprow, leftcol, nrows, ncols, False);
926                 if (screen->cur_row >= toprow &&
927                     screen->cur_row < toprow + nrows &&
928                     screen->cur_col >= leftcol &&
929                     screen->cur_col < leftcol + ncols)
930                         return (1);
931
932         }
933         return (0);
934 }
935
936 void ReverseVideo (termw)
937         XtermWidget termw;
938 {
939         register TScreen *screen = &termw->screen;
940         GC tmpGC;
941         unsigned long tmp;
942
943         tmp = termw->core.background_pixel;
944         if(screen->cursorcolor == screen->foreground)
945                 screen->cursorcolor = tmp;
946         termw->core.background_pixel = screen->foreground;
947         screen->foreground = tmp;
948
949         tmp = screen->mousecolorback;
950         screen->mousecolorback = screen->mousecolor;
951         screen->mousecolor = tmp;
952
953         tmpGC = screen->normalGC;
954         screen->normalGC = screen->reverseGC;
955         screen->reverseGC = tmpGC;
956
957         tmpGC = screen->normalboldGC;
958         screen->normalboldGC = screen->reverseboldGC;
959         screen->reverseboldGC = tmpGC;
960
961         recolor_cursor (screen->pointer_cursor, 
962                         screen->mousecolor, screen->mousecolorback);
963         recolor_cursor (screen->arrow,
964                         screen->mousecolor, screen->mousecolorback);
965
966         termw->misc.re_verse = !termw->misc.re_verse;
967
968         XDefineCursor(screen->display, TextWindow(screen), screen->pointer_cursor);
969         if(screen->scrollWidget)
970                 ScrollBarReverseVideo(screen->scrollWidget);
971
972         XSetWindowBackground(screen->display, TextWindow(screen), termw->core.background_pixel);
973         XClearWindow(screen->display, TextWindow(screen));
974         ScrnRefresh (screen, 0, 0, screen->max_row + 1,
975          screen->max_col + 1, False);
976         update_reversevideo();
977 }
978
979
980 void recolor_cursor (cursor, fg, bg)
981     Cursor cursor;                      /* X cursor ID to set */
982     unsigned long fg, bg;               /* pixel indexes to look up */
983 {
984     register TScreen *screen = &term->screen;
985     register Display *dpy = screen->display;
986     XColor colordefs[2];                /* 0 is foreground, 1 is background */
987
988     colordefs[0].pixel = fg;
989     colordefs[1].pixel = bg;
990     XQueryColors (dpy, DefaultColormap (dpy, DefaultScreen (dpy)),
991                   colordefs, 2);
992     XRecolorCursor (dpy, cursor, colordefs, colordefs+1);
993     return;
994 }
995
996 /* Scilab tohome() */
997 /* Called by HomeFunction() in SCI/routines/console/zzledt.c */
998 /* V.C. 04/2004 */
999 void XHomeFunction(void)
1000 {
1001   register TScreen *screen = &term->screen;
1002   static int k=0;
1003   
1004   if (!IsConsoleMode())
1005     {
1006       /* Screen is filled with empty lines and then cleared */
1007       for(k=0;k<(Height(screen) - 1)/FontHeight(screen) - 2;k++) /* 2 is the number of rows used by tohome()\r\n */
1008         {
1009           sciprint("\r\n");
1010         }
1011       screen->cur_row = screen->topline; /* New cursor position */
1012       ClearBelow(screen); /* Screen is cleared below cursor */
1013       ScrollBarDrawThumb(screen->scrollWidget);
1014     }
1015   else
1016     {
1017       system("clear");
1018     }
1019   return;
1020 }
1021
1022
1023 /* Scilab clc() */
1024 /* Called by ClearScreenConsole() in SCI/routines/console/zzledt.c */
1025 /* V.C. 04/2004 */
1026 int XClearScreenConsole(char *fname)
1027 {
1028   register TScreen *screen = &term->screen;
1029   int l1,m1=1,n1=1,NbLines=0;
1030
1031   if (!IsConsoleMode())
1032     {
1033       CheckRhs(0,1);
1034       if (Rhs==0)
1035         {
1036           ClearScreen(screen); /* All screen is cleared */
1037           screen->savedlines = 0; /* Number of lines scrolled */
1038           screen->cur_row = screen->topline - 1; /* New cursor position */
1039           sciprint("\r\n"); /* To have a blank space above prompt */
1040           ScrollBarDrawThumb(screen->scrollWidget);
1041         }
1042       else
1043         {
1044           GetRhsVar(1,"i",&m1,&n1,&l1);
1045           NbLines = *istk(l1);
1046           if (NbLines>0)
1047             {
1048               if (screen->topline < screen->cur_row - NbLines)
1049                 {
1050                   screen->savedlines = screen->savedlines - NbLines - 2; /* Number of lines scrolled */
1051                   if (screen->savedlines < 0)
1052                     screen->savedlines=0;
1053                   screen->cur_row = screen->cur_row - NbLines - 2; /* New cursor position */
1054                   ClearBelow(screen); /* Screen is cleared below cursor */
1055                   ScrollBarDrawThumb(screen->scrollWidget);
1056                 }
1057               else
1058                 {
1059                   sciprint("\n Not in screen \n");
1060                 }
1061             }
1062           else
1063             {
1064               sciprint("\n Error %d invalid number \n",NbLines);
1065             }
1066         }
1067     }
1068   else
1069     {
1070       sciprint("\n Only in Window Mode \n");
1071     }
1072   return 0;
1073 }
1074
1075 /* Scilab get(0,"....") (root properties) */
1076 /* V.C. 08/2004 */
1077 int GetScreenProperty(char *prop, char **value)
1078 {
1079   register TScreen *screen = &term->screen;
1080
1081   if((value=calloc(1,sizeof(char)))==NULL)
1082     {
1083       Scierror(999,"GetScreenProperty: No more memory available\r\n");
1084       return -1;
1085     }
1086   if((value[0]=(char *)calloc(1,sizeof(char)*(200+1)))==NULL)
1087     {
1088       Scierror(999,"GetScreenProperty: No more memory available\r\n");
1089       return -1;
1090     }
1091     (value[0])[200]='\0';
1092
1093   if(!strcmp(prop,"screensize_px"))
1094     {
1095       sprintf(value[0],"%f|%f|%f|%f",(float)1,(float)1,
1096               (float)DisplayWidth(screen->display,DefaultScreen(screen->display)),
1097               (float)DisplayHeight(screen->display,DefaultScreen(screen->display)));
1098     }
1099   else if(!strcmp(prop,"screensize_mm"))
1100     {
1101       sprintf(value[0],"%f|%f|%f|%f",(float)0,(float)0,
1102               (float)DisplayWidthMM(screen->display,DefaultScreen(screen->display)),
1103               (float)DisplayHeightMM(screen->display,DefaultScreen(screen->display)));
1104     }
1105   else if(!strcmp(prop,"screensize_mm"))
1106     {
1107       sprintf(value[0],"%f|%f|%f|%f",(float)0,(float)0,
1108               (float)DisplayWidthMM(screen->display,DefaultScreen(screen->display)),
1109               (float)DisplayHeightMM(screen->display,DefaultScreen(screen->display)));
1110     }
1111   else if(!strcmp(prop,"screensize_cm"))
1112     {
1113       sprintf(value[0],"%f|%f|%f|%f",(float)0,(float)0,
1114               (float)DisplayWidthMM(screen->display,DefaultScreen(screen->display))/10,
1115               (float)DisplayHeightMM(screen->display,DefaultScreen(screen->display))/10);
1116     }
1117   else if(!strcmp(prop,"screensize_in"))
1118     {
1119       sprintf(value[0],"%f|%f|%f|%f",(float)0,(float)0,
1120               ((float)DisplayWidthMM(screen->display,DefaultScreen(screen->display)))/25.4,
1121               ((float)DisplayHeightMM(screen->display,DefaultScreen(screen->display)))/25.4);
1122     }
1123   else if(!strcmp(prop,"screensize_pt"))
1124     {
1125       sprintf(value[0],"%f|%f|%f|%f",(float)0,(float)0,
1126               (float)DisplayWidthMM(screen->display,DefaultScreen(screen->display))/25.4*72,
1127               (float)DisplayHeightMM(screen->display,DefaultScreen(screen->display))/25.4*72);
1128     }
1129   else if(!strcmp(prop,"screensize_norm"))
1130     {
1131       sprintf(value[0],"%f|%f|%f|%f",(float)0,(float)0,(float)1,(float)1);
1132     }
1133   else
1134     {
1135       sciprint("Unknown property %s\r\n",prop);
1136       return -1;
1137     }
1138   return 0;
1139 }