]> git.lyx.org Git - lyx.git/blob - src/screen.C
19c1c0d56aca05ca64d1c75bca3855acf49ed89b
[lyx.git] / src / screen.C
1 /* This file is part of
2 * ====================================================== 
3
4 *           LyX, The Document Processor
5 *        
6 *           Copyright 1995 Matthias Ettrich
7 *           Copyright 1995-1998 The LyX Team
8 *
9 * ====================================================== */
10
11 #include <config.h>
12
13 #ifdef __GNUG__
14 #pragma implementation "lyxscreen.h"
15 #endif
16
17 #include "lyxscreen.h"
18 #include "lyxtext.h"
19 #include "lyxrow.h"
20 #include "BufferView.h"
21 #include "Painter.h"
22 #ifndef USE_PAINTER
23 #include "lyxdraw.h"
24 #endif
25
26 #ifdef MONO
27 extern int mono_video;
28 extern int fast_selection;
29 #endif
30
31 #ifdef USE_PAINTER
32 static
33 GC createGC()
34 {
35         XGCValues val;
36         val.foreground = BlackPixel(fl_display, 
37                                     DefaultScreen(fl_display));
38         
39         val.function=GXcopy;
40         val.graphics_exposures = false;
41         val.line_style = LineSolid;
42         val.line_width = 0;
43         return XCreateGC(fl_display, RootWindow(fl_display, 0), 
44                          GCForeground | GCFunction | GCGraphicsExposures
45                          | GCLineWidth | GCLineStyle , &val);
46 }
47 #endif
48
49
50 // Constructor
51 LyXScreen::LyXScreen(BufferView * o, Window window,
52                      Pixmap p,
53                      Dimension width, 
54                      Dimension height,
55                      Dimension offset_x,
56                      Dimension offset_y,
57                      LyXText *text_ptr)
58         : owner(o), text(text_ptr), _window(window), 
59         _width(width), _height(height),
60         _offset_x(offset_x), _offset_y(offset_y)
61 {
62         first = 0;
63    
64         /* the cursor isnt yet visible */ 
65         cursor_visible = false;
66         screen_refresh_y = -1;
67
68         /* create the foreground pixmap */
69         foreground = p;
70
71         cursor_pixmap = 0;
72         cursor_pixmap_x = 0;
73         cursor_pixmap_y = 0;
74         cursor_pixmap_w = 0;
75         cursor_pixmap_h = 0;
76
77 #ifdef USE_PAINTER
78         // We need this GC
79         gc_copy = createGC();
80 #endif
81 }
82
83
84 // Destructor
85 LyXScreen::~LyXScreen() {}
86
87
88 void LyXScreen::Redraw()
89 {
90         DrawFromTo(0, _height);
91         screen_refresh_y = -1;
92         expose(0, 0, _width, _height);
93         if (cursor_visible) {
94                 cursor_visible = false;
95                 ShowCursor();
96         }
97 }
98
99
100 #ifdef USE_PAINTER
101 void LyXScreen::expose(int x, int y, int exp_width, int exp_height)
102 {
103         XCopyArea(fl_display,
104                   foreground,
105                   _window,
106                   gc_copy,
107                   x, y,
108                   exp_width, exp_height,
109                   x+_offset_x, y+_offset_y);
110 }
111 #else
112 void LyXScreen::expose(int x, int y, int exp_width, int exp_height)
113 {
114         XCopyArea(fl_display,
115                   foreground,
116                   _window,
117                   getGC(gc_copy),
118                   x, y,
119                   exp_width, exp_height,
120                   x+_offset_x, y+_offset_y);
121 }
122 #endif
123
124
125 #ifdef USE_PAINTER
126 void LyXScreen::DrawFromTo(int y1, int y2)
127 {
128         long y_text = first + y1;
129    
130         /* get the first needed row */ 
131         Row * row = text->GetRowNearY(y_text);
132         /* y_text is now the real beginning of the row */
133    
134         long y = y_text - first;
135         /* y1 is now the real beginning of row on the screen */
136         
137         while (row != 0 && y < y2) {
138
139                 text->GetVisibleRow(y, row, y + first);
140                 y += row->height;
141                 row = row -> next;
142
143         }
144    
145         /* maybe we have to clear the screen at the bottom */ 
146         if (y < y2) {
147                 owner->painter().fillRectangle(0, y, _width, y2 - y,
148                                                LColor::bottomarea);
149         }
150 }
151 #else
152 void LyXScreen::DrawFromTo(int y1, int y2)
153 {
154         long y_text = first + y1;
155    
156         /* get the first needed row */ 
157         Row * row = text->GetRowNearY(y_text);
158         /* y_text is now the real beginning of the row */
159    
160         long y = y_text - first;
161         /* y1 is now the real beginning of row on the screen */
162         
163         while (row != 0 && y < y2) {
164
165                 text->GetVisibleRow(*this, y, row, y + first);
166                 y += row->height;
167                 row = row -> next;
168
169         }
170    
171         /* maybe we have to clear the screen at the bottom */ 
172         if (y < y2) {
173                 fillRectangle(gc_lighted,
174                               0,
175                               y,
176                               _width,
177                               y2 - y);
178         }
179 }
180 #endif
181
182
183 void LyXScreen::DrawOneRow(Row * row, long & y_text)
184 {
185         long y = y_text - first;
186       
187         if (y + row->height > 0 && y - row->height <= _height) {
188                 /* ok there is something visible */
189 #ifdef USE_PAINTER
190                 text->GetVisibleRow(y, row, y + first);
191 #else
192                 text->GetVisibleRow(*this, y, row, y + first);
193 #endif
194         }
195         y_text+= row->height;
196 }
197
198
199 /* draws the screen, starting with textposition y. uses as much already
200 * printed pixels as possible */
201 #ifdef USE_PAINTER
202 void LyXScreen::Draw(long  y)
203 {
204         if (cursor_visible) HideCursor();
205
206         if (y < 0) y = 0;
207         long old_first = first;
208         first = y;
209
210         /* is any optimiziation possible? */ 
211         if ((y - old_first) < _height 
212             && (old_first - y) < _height) {
213                 if (first < old_first) {
214                         DrawFromTo(0, old_first - first);
215                         XCopyArea (fl_display,
216                                    _window,
217                                    _window,
218                                    gc_copy,
219                                    _offset_x, _offset_y, 
220                                    _width , _height - old_first + first,
221                                    _offset_x, _offset_y + old_first - first);
222                         // expose the area drawn
223                         expose(0, 0, _width, old_first - first);
224                 } else  {
225                         DrawFromTo(_height + old_first - first, _height);
226                         XCopyArea (fl_display,
227                                    _window,
228                                    _window,
229                                    gc_copy,
230                                    _offset_x, _offset_y + first - old_first, 
231                                    _width , _height + old_first - first, 
232                                    _offset_x, _offset_y);
233                         // expose the area drawn
234                         expose(0, _height + old_first - first, 
235                                _width, first - old_first);
236                 }
237         } else {
238                 /* make a dumb new-draw */ 
239                 DrawFromTo(0, _height);
240                 expose(0, 0, _width, _height);
241         }
242 }
243 #else
244 void LyXScreen::Draw(long  y)
245 {
246         if (cursor_visible) HideCursor();
247
248         if (y < 0) y = 0;
249         long old_first = first;
250         first = y;
251
252         /* is any optimiziation possible? */ 
253         if ((y - old_first) < _height 
254             && (old_first - y) < _height) {
255                 if (first < old_first) {
256                         DrawFromTo(0, old_first - first);
257                         XCopyArea (fl_display,
258                                    _window,
259                                    _window,
260                                    getGC(gc_copy),
261                                    _offset_x, _offset_y, 
262                                    _width , _height - old_first + first,
263                                    _offset_x, _offset_y + old_first - first);
264                         // expose the area drawn
265                         expose(0, 0, _width, old_first - first);
266                 } else  {
267                         DrawFromTo(_height + old_first - first, _height);
268                         XCopyArea (fl_display,
269                                    _window,
270                                    _window,
271                                    getGC(gc_copy),
272                                    _offset_x, _offset_y + first - old_first, 
273                                    _width , _height + old_first - first, 
274                                    _offset_x, _offset_y);
275                         // expose the area drawn
276                         expose(0, _height + old_first - first, 
277                                _width, first - old_first);
278                 }
279         } else {
280                 /* make a dumb new-draw */ 
281                 DrawFromTo(0, _height);
282                 expose(0, 0, _width, _height);
283         }
284 }
285 #endif
286
287
288 void LyXScreen::ShowCursor()
289 {
290         long x = 0;
291         long y1 = 0;
292         long y2 = 0;
293    
294         if (cursor_visible) return;
295    
296         x = text->cursor.x;
297         
298         y1 = text->cursor.y - text->real_current_font.maxAscent() - first;
299         if (y1 < 0) y1 = 0;
300         
301         y2 = text->cursor.y + text->real_current_font.maxDescent() - first;
302         if (y2 > _height) y2 = _height;
303
304         // Secure against very strange situations
305         if (y2 < y1) y2 = y1;
306
307 #ifndef USE_PAINTER
308         if (fast_selection || mono_video) {
309                 if (y2 > 0 && y1 < _height) {
310                         XDrawLine(fl_display,
311                                   _window, getGC(gc_select),
312                                   x + _offset_x,
313                                   y1 + _offset_y,
314                                   x + _offset_x,
315                                   y2 + _offset_y);
316                         cursor_visible = true;
317                 }
318         } else {
319 #endif
320                 if (cursor_pixmap){
321                         XFreePixmap(fl_display, cursor_pixmap);
322                         cursor_pixmap = 0;
323                 }
324    
325                 if (y2 > 0 && y1 < _height) {
326                         cursor_pixmap_w = 1;
327                         cursor_pixmap_h = y2 - y1 + 1;
328                         cursor_pixmap_x = x;
329                         cursor_pixmap_y = y1;
330                         cursor_pixmap = 
331                                 XCreatePixmap(fl_display,
332                                               fl_root,
333                                               cursor_pixmap_w,
334                                               cursor_pixmap_h,
335                                               fl_get_visual_depth());
336 #ifdef USE_PAINTER
337                         XCopyArea(fl_display,
338                                   _window,
339                                   cursor_pixmap,
340                                   gc_copy,
341                                   _offset_x + cursor_pixmap_x, 
342                                   _offset_y + cursor_pixmap_y,
343                                   cursor_pixmap_w, cursor_pixmap_h,
344                                   0, 0);
345                         XDrawLine(fl_display,
346                                   _window, gc_copy,
347                                   x + _offset_x,
348                                   y1 + _offset_y,
349                                   x + _offset_x,
350                                   y2 + _offset_y);
351 #else
352                         XCopyArea(fl_display,
353                                   _window,
354                                   cursor_pixmap,
355                                   getGC(gc_copy),
356                                   _offset_x + cursor_pixmap_x, 
357                                   _offset_y + cursor_pixmap_y,
358                                   cursor_pixmap_w, cursor_pixmap_h,
359                                   0, 0);
360                         XDrawLine(fl_display,
361                                   _window,
362                                   getGC(gc_copy),
363                                   x + _offset_x,
364                                   y1 + _offset_y,
365                                   x + _offset_x,
366                                   y2 + _offset_y);
367 #endif
368                         cursor_visible = true;
369                 }
370 #ifndef USE_PAINTER
371         }
372 #endif
373 }
374
375
376 /* returns 1 if first has changed, otherwise 0 */ 
377 int LyXScreen::FitManualCursor(long /*x*/, long y, int asc, int desc)
378 {
379         long  newtop = first;
380   
381         if (y + desc  - first >= _height)
382                 newtop = y - 3*_height / 4;   /* the scroll region must be so big!! */
383         else if (y - asc < first 
384                  && first > 0) {
385                 newtop = y - _height / 4;
386         }
387         if (newtop < 0)
388                 newtop = 0;
389   
390         if (newtop != first){
391                 Draw(newtop);
392                 first = newtop;
393                 return 1;
394         }
395         return 0;
396 }
397
398
399 void  LyXScreen::HideManualCursor(long x, long y, int asc, int desc)
400 {
401 #ifdef MONO
402         if (fast_selection || mono_video)
403                 ShowManualCursor(x, y, asc, desc);
404         else
405 #endif
406                 HideCursor();
407 }
408
409
410 void  LyXScreen::ShowManualCursor(long x, long y, int asc, int desc)
411 {
412         long y1 = 0;
413         long y2 = 0;
414         
415         y1 = y - first - asc;
416         if (y1 < 0)
417                 y1 = 0;
418         y2 = y -first + desc;
419         if (y2 > _height)
420                 y2 = _height;
421
422 #ifndef USE_PAINTER
423         if (fast_selection || mono_video) {
424                 if (y2 > 0 && y1 < _height) {
425                         XDrawLine(fl_display,
426                                   _window, getGC(gc_select),
427                                   x+_offset_x,
428                                   y1+_offset_y,
429                                   x+_offset_x,
430                                   y2+_offset_y);
431                 }
432         } else {
433 #endif
434                 if (cursor_pixmap){
435                         XFreePixmap(fl_display, cursor_pixmap);
436                         cursor_pixmap = 0;
437                 }
438                 
439                 if (y2 > 0 && y1 < _height) {
440                         cursor_pixmap_w = 1;
441                         cursor_pixmap_h = y2 - y1 + 1;
442                         cursor_pixmap_x = x,
443                                 cursor_pixmap_y = y1;
444                         cursor_pixmap = 
445                                 XCreatePixmap (fl_display,
446                                                fl_root,
447                                                cursor_pixmap_w,
448                                                cursor_pixmap_h,
449                                                fl_get_visual_depth());
450 #ifdef USE_PAINTER
451                         XCopyArea (fl_display,
452                                    _window,
453                                    cursor_pixmap,
454                                    gc_copy,
455                                    _offset_x + cursor_pixmap_x,
456                                    _offset_y + cursor_pixmap_y,
457                                    cursor_pixmap_w,
458                                    cursor_pixmap_h,
459                                    0, 0);
460                         XDrawLine(fl_display,
461                                   _window, gc_copy,
462                                   x+_offset_x,
463                                   y1+_offset_y,
464                                   x+_offset_x,
465                                   y2+_offset_y);
466 #else
467                         XCopyArea (fl_display,
468                                    _window,
469                                    cursor_pixmap,
470                                    getGC(gc_copy),
471                                    _offset_x + cursor_pixmap_x,
472                                    _offset_y + cursor_pixmap_y,
473                                    cursor_pixmap_w,
474                                    cursor_pixmap_h,
475                                    0, 0);
476                         XDrawLine(fl_display,
477                                   _window,
478                                   getGC(gc_copy),
479                                   x+_offset_x,
480                                   y1+_offset_y,
481                                   x+_offset_x,
482                                   y2+_offset_y);
483 #endif
484                 }
485                 cursor_visible = true;
486 #ifndef USE_PAINTER
487         }
488 #endif
489 }
490
491
492 void LyXScreen::HideCursor()
493 {
494         if (!cursor_visible) return;
495
496 #ifndef USE_PAINTER
497         if (fast_selection || mono_video) {
498                 cursor_visible = false;
499                 ShowCursor();
500                 cursor_visible = false;
501         } else {
502 #endif
503                 if (cursor_pixmap){
504 #ifdef USE_PAINTER
505                         XCopyArea (fl_display, 
506                                    cursor_pixmap,
507                                    _window,
508                                    gc_copy,
509                                    0, 0, 
510                                    cursor_pixmap_w, cursor_pixmap_h,
511                                    cursor_pixmap_x + _offset_x,
512                                    cursor_pixmap_y + _offset_y);
513 #else
514                         XCopyArea (fl_display, 
515                                    cursor_pixmap,
516                                    _window,
517                                    getGC(gc_copy),
518                                    0, 0, 
519                                    cursor_pixmap_w, cursor_pixmap_h,
520                                    cursor_pixmap_x + _offset_x,
521                                    cursor_pixmap_y + _offset_y);
522 #endif
523                 }
524                 cursor_visible = false;
525 #ifndef USE_PAINTER
526         }
527 #endif
528 }
529
530
531 void LyXScreen::CursorToggle()
532 {
533         if (cursor_visible)
534                 HideCursor();
535         else
536                 ShowCursor();
537 }
538
539
540 /* returns a new top so that the cursor is visible */ 
541 long LyXScreen::TopCursorVisible()
542 {
543         long newtop = first;
544
545         if (text->cursor.y
546             - text->cursor.row->baseline
547             + text->cursor.row->height
548             - first >= _height) {
549                 if (text->cursor.row->height < _height
550                     && text->cursor.row->height > _height/4)
551                         newtop = text->cursor.y
552                                 + text->cursor.row->height
553                                 - text->cursor.row->baseline - _height;
554                 else
555                         newtop = text->cursor.y
556                                 - 3*_height / 4;   /* the scroll region must be so big!! */
557         } else if (text->cursor.y - text->cursor.row->baseline < first 
558                    && first > 0) {
559                 if (text->cursor.row->height < _height
560                     && text->cursor.row->height > _height/4)
561                         newtop = text->cursor.y - text->cursor.row->baseline;
562                 else {
563                         newtop = text->cursor.y - _height / 4;
564                         if (newtop > first)
565                                 newtop = first;
566                 }
567         }
568         if (newtop < 0)
569                 newtop = 0;
570         
571         return newtop;
572 }
573
574
575 /* scrolls the screen so that the cursor is visible, if necessary.
576 * returns 1 if a change was made, otherwise 0 */ 
577 int LyXScreen::FitCursor()
578 {
579         /* is a change necessary */ 
580         long  newtop = TopCursorVisible();
581         int result = (newtop != first);
582         if (result)
583                 Draw(newtop);
584         return result;
585 }
586
587    
588 void LyXScreen::Update()
589 {
590         long y = 0;
591
592         if (text->status == LyXText::NEED_MORE_REFRESH
593             || screen_refresh_y > -1 ) {
594                 if (screen_refresh_y > -1
595                     && screen_refresh_y < text->refresh_y)
596                         y = screen_refresh_y;
597                 else
598                         y = text->refresh_y;
599                 
600                 if (y < first) y = first;
601                 
602                 DrawFromTo(y - first, _height);
603                 text->refresh_y = 0;
604                 text->status = LyXText::UNCHANGED;
605                 screen_refresh_y = -1;
606                 expose(0, y-first, _width, _height - (y - first));
607         } else if (text->status == LyXText::NEED_VERY_LITTLE_REFRESH) {
608                 /* ok I will update the current cursor row */
609                 y = text->refresh_y;
610                 DrawOneRow(text->refresh_row, y);
611                 text->status = LyXText::UNCHANGED;
612                 expose(0, text->refresh_y-first,
613                        _width, text->refresh_row->height);
614         }
615 }
616
617
618 void LyXScreen::SmallUpdate()
619 {
620         Row * row = 0;
621         long y = 0;
622         long y2 = 0;
623         
624         if (text->status == LyXText::NEED_MORE_REFRESH){
625                 /* ok I will update till the current cursor row */
626                 row = text->refresh_row;
627                 y = text->refresh_y;
628                 y2 = y;
629       
630                 if (y > text->cursor.y) {
631                         Update();
632                         return;
633                 }
634          
635                 while (row && row != text->cursor.row && y < first + _height) {
636                         DrawOneRow(row, y);
637                         row = row->next;
638                 }
639       
640                 DrawOneRow(row, y);
641                 screen_refresh_y = y;
642                 screen_refresh_row = row->next;
643                 text->status = LyXText::UNCHANGED;
644                 // Is the right regin exposed?
645                 expose(0, y2-first, _width, y-y2);
646         } else if (text->status == LyXText::NEED_VERY_LITTLE_REFRESH) {
647                 /* ok I will update the current cursor row */
648                 row = text->refresh_row;
649                 y = text->refresh_y;
650                 DrawOneRow(row, y);
651                 text->status = LyXText::UNCHANGED;
652                 expose(0, text->refresh_y - first,
653                        _width, row->height);
654         }
655 }
656
657
658 void LyXScreen::ToggleSelection(bool kill_selection)
659 {
660         /* only if there is a selection */ 
661         if (!text->selection)
662                 return;
663
664         long top = 0;
665         long bottom = 0;
666    
667 #ifndef USE_PAINTER
668         if (fast_selection || mono_video) {
669                 
670                 /* selection only in one row ?*/ 
671                 if (text->sel_start_cursor.y == text->sel_end_cursor.y) {
672                         
673                         /* only if something is visible */ 
674                         if (text->sel_start_cursor.y
675                             - text->sel_start_cursor.row->baseline
676                             - first < _height
677                             && text->sel_start_cursor.y
678                             - text->sel_start_cursor.row->baseline + 
679                             text->sel_start_cursor.row->height - first > 0) {
680                                 top = text->sel_start_cursor.y
681                                         - text->sel_start_cursor.row->baseline
682                                         - first;
683                                 bottom = top
684                                         + text->sel_start_cursor.row->height;
685                                 if (top<0)
686                                         top = 0;
687                                 if (bottom > _height)
688                                         bottom = _height;
689                                 XFillRectangle(fl_display, _window,
690                                                getGC(gc_select),
691                                                text->sel_start_cursor.x
692                                                +_offset_x, 
693                                                top+_offset_y,
694                                                text->sel_end_cursor.x
695                                                - text->sel_start_cursor.x,
696                                                bottom - top);
697                         }
698                 } else {
699                         /* the sel_start_cursor row first */ 
700                         /* only if anything is visible */ 
701                         if (text->sel_start_cursor.y
702                             - text->sel_start_cursor.row->baseline
703                             - first < _height
704                             && text->sel_start_cursor.y
705                             - text->sel_start_cursor.row->baseline + 
706                             text->sel_start_cursor.row->height - first > 0) {
707                                 top = text->sel_start_cursor.y
708                                         - text->sel_start_cursor.row->baseline
709                                         - first;
710                                 bottom = top
711                                         + text->sel_start_cursor.row->height;
712                                 if (top<0)
713                                         top = 0;
714                                 if (bottom > _height)
715                                         bottom = _height;
716                                 XFillRectangle(fl_display, _window,
717                                                getGC(gc_select),
718                                                text->sel_start_cursor.x
719                                                +_offset_x, 
720                                                top+_offset_y,
721                                                _width
722                                                - text->sel_start_cursor.x,
723                                                bottom - top);
724                         }
725                         
726                         /* the main body */ 
727                         
728                         if (text->sel_start_cursor.row->next != 
729                             text->sel_end_cursor.row) {
730                                 top = text->sel_start_cursor.y
731                                         - text->sel_start_cursor.row->baseline
732                                         + text->sel_start_cursor.row->height;
733                                 bottom = text->sel_end_cursor.y
734                                         - text->sel_end_cursor.row->baseline;
735                                 
736                                 if (top - first < 0)
737                                         top = first;
738                                 if (bottom - first < 0)
739                                         bottom = first;
740                                 
741                                 if (bottom - first > _height)
742                                         bottom = first + _height;
743                                 if (top - first > _height)
744                                         top = first + _height;
745                                 
746                                 if (top != bottom) {
747                                         XFillRectangle(fl_display,
748                                                        _window,
749                                                        getGC(gc_select),
750                                                        0+_offset_x, 
751                                                        top - first+_offset_y,
752                                                        _width,
753                                                        bottom - top);
754                                 }
755                         }
756                         
757                         /* the sel_end_cursor row last */ 
758                         if (text->sel_end_cursor.y
759                             - text->sel_end_cursor.row->baseline
760                             - first < _height
761                             && text->sel_end_cursor.y
762                             - text->sel_end_cursor.row->baseline +
763                             text->sel_end_cursor.row->height - first > 0) {
764                                 top = text->sel_end_cursor.y
765                                         - text->sel_end_cursor.row->baseline
766                                         - first;
767                                 bottom = top
768                                         + text->sel_end_cursor.row->height;
769                                 if (top<0)
770                                         top = 0;
771                                 if (bottom > _height)
772                                         bottom = _height;
773                                 XFillRectangle(fl_display, _window,
774                                                getGC(gc_select),
775                                                0+_offset_x, 
776                                                top+_offset_y,
777                                                text->sel_end_cursor.x,
778                                                bottom - top);
779                         }
780                 }
781         } else {
782 #endif
783                 top = text->sel_start_cursor.y
784                         - text->sel_start_cursor.row->baseline;
785                 bottom = text->sel_end_cursor.y
786                         - text->sel_end_cursor.row->baseline 
787                         + text->sel_end_cursor.row->height;
788                 
789                 if (top - first < 0)
790                         top = first;
791                 if (bottom - first < 0)
792                         bottom = first;
793                 
794                 if (bottom - first > _height)
795                         bottom = first + _height;
796                 if (top - first > _height)
797                         top = first + _height;
798                 
799                 if (kill_selection)
800                         text->selection = 0;
801                 DrawFromTo(top - first, bottom - first);
802                 expose(0, top - first, _width, bottom - first - (top - first));
803 #ifndef USE_PAINTER
804         }
805 #endif
806 }
807   
808    
809 void LyXScreen::ToggleToggle()
810 {
811         long top = 0;
812         long bottom = 0;
813         
814         if (text->toggle_cursor.par == text->toggle_end_cursor.par
815             && text->toggle_cursor.pos == text->toggle_end_cursor.pos)
816                 return;
817
818 #ifndef USE_PAINTER
819         if (fast_selection || mono_video) {
820                 
821                 /* selection only in one row ?*/ 
822                 if (text->toggle_cursor.y == text->toggle_end_cursor.y) {
823                         
824                         /* only if anything is visible */ 
825                         if (text->toggle_cursor.y - text->toggle_cursor.row->baseline - first < _height
826                             && text->toggle_cursor.y - text->toggle_cursor.row->baseline + 
827                             text->toggle_cursor.row->height - first > 0) {
828                                 top = text->toggle_cursor.y - text->toggle_cursor.row->baseline - first;
829                                 bottom = top + text->toggle_cursor.row->height;
830                                 if (top < 0) top = 0;
831                                 if (bottom > _height) bottom = _height;
832                                 XFillRectangle(fl_display, _window,
833                                                getGC(gc_select),
834                                                text->toggle_cursor.x+_offset_x, 
835                                                top+_offset_y,
836                                                text->toggle_end_cursor.x  -
837                                                text->toggle_cursor.x,
838                                                bottom - top);
839                         }
840                 } else {
841                         /* the toggle_cursor row first */ 
842                         /* only if anything is visible */ 
843                         if (text->toggle_cursor.y - text->toggle_cursor.row->baseline - first < _height
844                             && text->toggle_cursor.y - text->toggle_cursor.row->baseline + 
845                             text->toggle_cursor.row->height - first > 0) {
846                                 top = text->toggle_cursor.y - text->toggle_cursor.row->baseline - first;
847                                 bottom = top + text->toggle_cursor.row->height;
848                                 if (top<0)
849                                         top = 0;
850                                 if (bottom > _height)
851                                         bottom = _height;
852                                 XFillRectangle(fl_display, _window,
853                                                getGC(gc_select),
854                                                text->toggle_cursor.x+_offset_x, 
855                                                top+_offset_y,
856                                                _width - text->toggle_cursor.x,
857                                                bottom - top);
858                         }
859                         
860                         /* the main body */ 
861                         
862                         if (text->toggle_cursor.row->next != 
863                             text->toggle_end_cursor.row) {
864                                 top = text->toggle_cursor.y
865                                         - text->toggle_cursor.row->baseline
866                                         + text->toggle_cursor.row->height;
867                                 bottom = text->toggle_end_cursor.y
868                                         - text->toggle_end_cursor.row->baseline;
869                                 
870                                 if (top - first < 0)
871                                         top = first;
872                                 if (bottom - first < 0)
873                                         bottom = first;
874                                 
875                                 if (bottom - first > _height)
876                                         bottom = first + _height;
877                                 if (top - first > _height)
878                                         top = first + _height;
879                                 
880                                 if (top != bottom) {
881                                         XFillRectangle(fl_display, _window,
882                                                        getGC(gc_select),
883                                                        0+_offset_x, 
884                                                        top - first+_offset_y,
885                                                        _width,
886                                                        bottom - top);
887                                 }
888                         }
889                         
890                         /* the toggle_end_cursor row last */ 
891                         if (text->toggle_end_cursor.y - text->toggle_end_cursor.row->baseline - first < _height
892                             && text->toggle_end_cursor.y - text->toggle_end_cursor.row->baseline +
893                             text->toggle_end_cursor.row->height - first > 0) {
894                                 top = text->toggle_end_cursor.y
895                                         - text->toggle_end_cursor.row->baseline
896                                         - first;
897                                 bottom = top
898                                         + text->toggle_end_cursor.row->height;
899                                 if (top<0)
900                                         top = 0;
901                                 if (bottom > _height)
902                                         bottom = _height;
903                                 XFillRectangle(fl_display, _window,
904                                                getGC(gc_select),
905                                                0+_offset_x, 
906                                                top+_offset_y,
907                                                text->toggle_end_cursor.x,
908                                                bottom - top);
909                         }
910                 }
911         } else {
912 #endif
913                 top = text->toggle_cursor.y
914                         - text->toggle_cursor.row->baseline;
915                 bottom = text->toggle_end_cursor.y
916                         - text->toggle_end_cursor.row->baseline 
917                         + text->toggle_end_cursor.row->height;
918                 
919                 if (top - first < 0)
920                         top = first;
921                 if (bottom - first < 0)
922                         bottom = first;
923                 
924                 if (bottom - first > _height)
925                         bottom = first + _height;
926                 if (top - first > _height)
927                         top = first + _height;
928                 
929                 DrawFromTo(top - first, bottom - first);
930                 expose(0, top - first, _width, bottom - first - (top - first));
931 #ifndef USE_PAINTER
932         }
933 #endif
934 }
935
936
937 #ifndef USE_PAINTER
938 void LyXScreen::drawTableLine(int baseline, int x, int length, bool on_off)
939 {
940         GC gc;
941         if (on_off)
942                 gc = getGC(gc_thin_on_off_line);
943         else
944                 gc = getGC(gc_copy);
945         drawLine(gc,
946                  x,
947                  baseline,
948                  x + length,
949                  baseline);
950 }
951 #endif
952
953
954 #ifndef USE_PAINTER
955 void LyXScreen::drawVerticalTableLine(int x, int y1, int y2, bool on_off)
956 {
957         GC gc;
958         if (on_off)
959                 gc = getGC(gc_thin_on_off_line);
960         else
961                 gc = getGC(gc_copy);
962         drawLine(gc,
963                  x,
964                  y1,
965                  x,
966                  y2);
967 }
968 #endif
969
970
971 #ifndef USE_PAINTER
972 void LyXScreen::drawFrame(int /*ft*/, int x, int y, int w, int h,
973                           FL_COLOR /*col*/, int /*b*/)
974 {
975 // Implement this using X11 calls, and the repaint problems are gone!
976 // At least, I think that should do it since we only have them after
977 // one of these buttons are displayed now! Lars, it seems you've hit the
978 // nail :-) (Asger)
979 //      fl_winset(foreground);
980 //      fl_drw_frame(ft, x,  y,  w,  h, col, b);
981         // This should be changed to draw a button like frame, in the
982         // mean time we'll just use a regular rectangle
983      
984          // I want the buttons back before 0.12. OK, this is very simple,
985          // like what is done in xforms sources.  (Ale)
986
987         // This one is too dirty. Get rid of it.
988         extern GC fl_gc;
989
990         // Please comment this annonymous variable.
991         int d = 2;
992
993         // I think these calls to fl_color might make xforms sometimes
994         // draw the wrong color on other objects.
995         fl_color(FL_TOP_BCOL);
996         XFillRectangle(fl_display, foreground, fl_gc,
997                        x - d, y - d, w + 2 * d, d);
998         fl_color(FL_BOTTOM_BCOL);
999         XFillRectangle(fl_display, foreground, fl_gc,
1000                        x - d, y + h, w + 2 * d, d);
1001  
1002         // Now a couple of trapezoids
1003         XPoint pl[4], pr[4]; 
1004  
1005         pl[0].x = x - d;   pl[0].y = y - d;
1006         pl[1].x = x - d;   pl[1].y = y + h + d;
1007         pl[2].x = x;     pl[2].y = y + h;
1008         pl[3].x = x;     pl[3].y = y;
1009         
1010         pr[0].x = x + w + d; pr[0].y = y - d;
1011         pr[1].x = x + w + d; pr[1].y = y + h + d;
1012         pr[2].x = x + w;   pr[2].y = y + h;
1013         pr[3].x = x + w;   pr[3].y = y;
1014         
1015         fl_color(FL_LEFT_BCOL);
1016         XFillPolygon(fl_display,
1017                      foreground,
1018                      fl_gc, pl, 4,
1019                      Convex, CoordModeOrigin); 
1020         fl_color(FL_RIGHT_BCOL);
1021         XFillPolygon(fl_display,
1022                      foreground,
1023                      fl_gc, pr, 4,
1024                      Convex, CoordModeOrigin); 
1025 }
1026 #endif