]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/xscreen.C
Remove redundant files.
[lyx.git] / src / frontends / xforms / xscreen.C
1 /**
2  * \file xscreen.C
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author unknown
7  * \author John Levon 
8  *
9  * Full author contact details are available in file CREDITS
10  */
11
12 #include <config.h>
13
14 #ifdef __GNUG__
15 #pragma implementation
16 #endif
17
18 #include <algorithm>
19 #include <X11/Xlib.h>
20
21 #include "frontends/screen.h"
22 #include "frontends/font_metrics.h"
23 #include "XWorkArea.h"
24 #include "xscreen.h"
25 #include "lyxtext.h"
26 #include "lyxrow.h"
27 #include "Painter.h"
28 #include "WorkArea.h"
29 #include "buffer.h"
30 #include "BufferView.h"
31 #include "insets/insettext.h"
32 #include "ColorHandler.h"
33 #include "language.h"
34 #include "debug.h"
35
36 using std::endl;
37 using std::max;
38 using std::min;
39
40 namespace {
41
42 GC createGC()
43 {
44         XGCValues val;
45         val.foreground = BlackPixel(fl_get_display(),
46                                     DefaultScreen(fl_get_display()));
47
48         val.function = GXcopy;
49         val.graphics_exposures = false;
50         val.line_style = LineSolid;
51         val.line_width = 0;
52         return XCreateGC(fl_get_display(), RootWindow(fl_get_display(), 0),
53                          GCForeground | GCFunction | GCGraphicsExposures
54                          | GCLineWidth | GCLineStyle, &val);
55 }
56
57 } // namespace anon
58
59
60 XScreen::XScreen(XWorkArea & o)
61         : LyXScreen(), owner_(o)
62 {
63         // the cursor isnt yet visible
64         cursor_pixmap = 0;
65         cursor_pixmap_x = 0;
66         cursor_pixmap_y = 0;
67         cursor_pixmap_w = 0;
68         cursor_pixmap_h = 0;
69
70         // We need this GC
71         gc_copy = createGC();
72 }
73
74
75 XScreen::~XScreen()
76 {
77         XFreeGC(fl_get_display(), gc_copy);
78 }
79
80
81 void XScreen::setCursorColor()
82 {
83         if (!lyxColorHandler.get())
84                 return;
85
86         GC gc = lyxColorHandler->getGCForeground(LColor::cursor);
87
88         XGCValues val;
89         XGetGCValues(fl_get_display(),
90                      gc, GCForeground, &val);
91         XChangeGC(fl_get_display(), gc_copy, GCForeground, &val);
92 }
93
94
95 void XScreen::showManualCursor(LyXText const * text, int x, int y,
96                                  int asc, int desc, Cursor_Shape shape)
97 {
98         // Update the cursor color.
99         setCursorColor();
100
101         int const y1 = max(y - text->first_y - asc, 0);
102         int const y_tmp = min(y - text->first_y + desc,
103                               static_cast<int>(owner_.workHeight()));
104
105         // Secure against very strange situations
106         int const y2 = max(y_tmp, y1);
107
108         if (cursor_pixmap) {
109                 XFreePixmap(fl_get_display(), cursor_pixmap);
110                 cursor_pixmap = 0;
111         }
112
113         if (y2 > 0 && y1 < int(owner_.workHeight())) {
114                 cursor_pixmap_h = y2 - y1 + 1;
115                 cursor_pixmap_y = y1;
116
117                 switch (shape) {
118                 case BAR_SHAPE:
119                         cursor_pixmap_w = 1;
120                         cursor_pixmap_x = x;
121                         break;
122                 case L_SHAPE:
123                         cursor_pixmap_w = cursor_pixmap_h/3;
124                         cursor_pixmap_x = x;
125                         break;
126                 case REVERSED_L_SHAPE:
127                         cursor_pixmap_w = cursor_pixmap_h/3;
128                         cursor_pixmap_x = x - cursor_pixmap_w + 1;
129                         break;
130                 }
131
132                 cursor_pixmap =
133                         XCreatePixmap (fl_get_display(),
134                                        fl_root,
135                                        cursor_pixmap_w,
136                                        cursor_pixmap_h,
137                                        fl_get_visual_depth());
138                 XCopyArea (fl_get_display(),
139                            owner_.getWin(),
140                            cursor_pixmap,
141                            gc_copy,
142                            owner_.xpos() + cursor_pixmap_x,
143                            owner_.ypos() + cursor_pixmap_y,
144                            cursor_pixmap_w,
145                            cursor_pixmap_h,
146                            0, 0);
147                 XDrawLine(fl_get_display(),
148                           owner_.getWin(),
149                           gc_copy,
150                           x + owner_.xpos(),
151                           y1 + owner_.ypos(),
152                           x + owner_.xpos(),
153                           y2 + owner_.ypos());
154                 switch (shape) {
155                 case BAR_SHAPE:
156                         break;
157                 case L_SHAPE:
158                 case REVERSED_L_SHAPE:
159                         int const rectangle_h = (cursor_pixmap_h + 10) / 20;
160                         XFillRectangle(fl_get_display(),
161                                        owner_.getWin(),
162                                        gc_copy,
163                                        cursor_pixmap_x + owner_.xpos(),
164                                        y2 - rectangle_h + 1 + owner_.ypos(),
165                                        cursor_pixmap_w - 1, rectangle_h);
166                         break;
167                 }
168
169         }
170         cursor_visible_ = true;
171 }
172
173
174 void XScreen::hideCursor()
175 {
176         if (!cursor_visible_) return;
177
178         if (cursor_pixmap) {
179                 XCopyArea (fl_get_display(),
180                            cursor_pixmap,
181                            owner_.getWin(),
182                            gc_copy,
183                            0, 0,
184                            cursor_pixmap_w, cursor_pixmap_h,
185                            cursor_pixmap_x + owner_.xpos(),
186                            cursor_pixmap_y + owner_.ypos());
187         }
188         cursor_visible_ = false;
189 }
190
191
192 void XScreen::expose(int x, int y, int w, int h)
193 {
194         lyxerr[Debug::GUI] << "expose " << w << "x" << h
195                 << "+" << x << "+" << y << endl;
196         XCopyArea(fl_get_display(),
197                   owner_.getPixmap(),
198                   owner_.getWin(),
199                   gc_copy,
200                   x, y, w, h,
201                   x + owner_.xpos(),
202                   y + owner_.ypos());
203 }
204
205
206 void XScreen::draw(LyXText * text, BufferView * bv, unsigned int y)
207 {
208         if (cursor_visible_)
209                 hideCursor();
210
211         int const old_first = text->first_y;
212         bool const internal = (text == bv->text);
213         text->first_y = y;
214
215         // is any optimization possible?
216         if ((y - old_first) < owner_.workHeight()
217             && (old_first - y) < owner_.workHeight())
218         {
219                 if (text->first_y < old_first) {
220                         drawFromTo(text, bv, 0,
221                                    old_first - text->first_y, 0, 0, internal);
222                         XCopyArea (fl_get_display(),
223                                    owner_.getWin(),
224                                    owner_.getWin(),
225                                    gc_copy,
226                                    owner_.xpos(),
227                                    owner_.ypos(),
228                                    owner_.workWidth(),
229                                    owner_.workHeight() - old_first + text->first_y,
230                                    owner_.xpos(),
231                                    owner_.ypos() + old_first - text->first_y
232                                 );
233                         // expose the area drawn
234                         expose(0, 0,
235                                owner_.workWidth(),
236                                old_first - text->first_y);
237                 } else  {
238                         drawFromTo(text, bv,
239                                    owner_.workHeight() + old_first - text->first_y,
240                                    owner_.workHeight(), 0, 0, internal);
241                         XCopyArea (fl_get_display(),
242                                    owner_.getWin(),
243                                    owner_.getWin(),
244                                    gc_copy,
245                                    owner_.xpos(),
246                                    owner_.ypos() + text->first_y - old_first,
247                                    owner_.workWidth(),
248                                    owner_.workHeight() + old_first - text->first_y,
249                                    owner_.xpos(),
250                                    owner_.ypos());
251                         // expose the area drawn
252                         expose(0, owner_.workHeight() + old_first - text->first_y,
253                                owner_.workWidth(), text->first_y - old_first);
254                 }
255         } else {
256                 // make a dumb new-draw
257                 drawFromTo(text, bv, 0, owner_.workHeight(), 0, 0, internal);
258                 expose(0, 0, owner_.workWidth(), owner_.workHeight());
259         }
260
261         XSync(fl_get_display(), 0);
262