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