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