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