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