]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/lyx_gui.C
fix some namespace issues for gcc 3.4
[lyx.git] / src / frontends / xforms / lyx_gui.C
1 /**
2  * \file xforms/lyx_gui.C
3  * This file is part of LyX, the document processor.
4  * Licence details can be found in the file COPYING.
5  *
6  * \author Lars Gullik Bjønnes
7  * \author John Levon
8  *
9  * Full author contact details are available in file CREDITS.
10  */
11
12 #include <config.h>
13
14 #include "lyx_gui.h"
15 #include "ColorHandler.h"
16 #include "xfont_loader.h"
17 #include "xforms_helpers.h"
18 #include "xformsImage.h"
19 #include "XFormsView.h"
20
21 #include "bufferlist.h"
22 #include "BufferView.h"
23 #include "debug.h"
24 #include "gettext.h"
25 #include "LColor.h"
26 #include "lyx_main.h"
27 #include "lyxfunc.h"
28 #include "lyxrc.h"
29 #include "lyxserver.h"
30
31 #include "graphics/LoaderQueue.h"
32
33 #include "support/lyxlib.h"
34 #include "support/os.h"
35 #include "support/filetools.h"
36 #include "support/path_defines.h"
37
38 #include "lyx_forms.h"
39
40 #include <boost/bind.hpp>
41
42 #include "support/std_sstream.h"
43 #include <iomanip>
44 #include <fcntl.h>
45
46 using lyx::support::AddName;
47 using lyx::support::user_lyxdir;
48
49 namespace os = lyx::support::os;
50
51 #ifndef CXX_GLOBAL_CSTD
52 using std::exit;
53 #endif
54
55 using std::dec;
56 using std::endl;
57 using std::hex;
58 using std::setbase;
59 using std::setfill;
60 using std::setw;
61 using std::ostringstream;
62 using std::vector;
63
64
65 extern BufferList bufferlist;
66
67 // FIXME: wrong place !
68 LyXServer * lyxserver;
69
70 namespace {
71
72 /// quit lyx
73 bool finished = false;
74
75 /// estimate DPI from X server
76 float getDPI()
77 {
78         Screen * scr = ScreenOfDisplay(fl_get_display(), fl_screen);
79         return ((HeightOfScreen(scr) * 25.4 / HeightMMOfScreen(scr)) +
80                 (WidthOfScreen(scr) * 25.4 / WidthMMOfScreen(scr))) / 2;
81 }
82
83
84 /// set default GUI configuration
85 void setDefaults()
86 {
87         FL_IOPT cntl;
88         cntl.buttonFontSize = FL_NORMAL_SIZE;
89         cntl.browserFontSize = FL_NORMAL_SIZE;
90         cntl.labelFontSize = FL_NORMAL_SIZE;
91         cntl.choiceFontSize = FL_NORMAL_SIZE;
92         cntl.inputFontSize = FL_NORMAL_SIZE;
93         cntl.menuFontSize  = FL_NORMAL_SIZE;
94         cntl.borderWidth = -1;
95         cntl.vclass = FL_DefaultVisual;
96         fl_set_defaults(FL_PDVisual
97                         | FL_PDButtonFontSize
98                         | FL_PDBrowserFontSize
99                         | FL_PDLabelFontSize
100                         | FL_PDChoiceFontSize
101                         | FL_PDInputFontSize
102                         | FL_PDMenuFontSize
103                         | FL_PDBorderWidth, &cntl);
104 }
105
106
107 extern "C" {
108
109 int LyX_XErrHandler(Display * display, XErrorEvent * xeev) {
110         // We don't abort on BadWindow
111         if (xeev->error_code == BadWindow) {
112                 lyxerr << "BadWindow received !" << endl;
113                 lyxerr << "If you're using xforms 1.0 or greater, "
114                         << " please report this to lyx-devel@lists.lyx.org" << endl;
115                 return 0;
116         }
117
118         // emergency cleanup
119         LyX::emergencyCleanup();
120
121         // Get the reason for the crash.
122         char etxt[513];
123         XGetErrorText(display, xeev->error_code, etxt, 512);
124         lyxerr << etxt << " id: " << xeev->resourceid << endl;
125         // By doing an abort we get a nice backtrace. (hopefully)
126         lyx::support::abort();
127         return 0;
128 }
129
130 }
131
132 /// read in geometry specification
133 char geometry[40];
134
135 } // namespace anon
136
137
138 namespace lyx_gui {
139
140 bool use_gui = true;
141
142
143 void parse_init(int & argc, char * argv[])
144 {
145         setDefaults();
146
147         FL_CMD_OPT cmdopt[] = {
148                 {"-geometry", "*.geometry", XrmoptionSepArg, "690x510"}
149         };
150
151         FL_resource res[] = {
152                 {"geometry", "geometryClass", FL_STRING, geometry, "", 40}
153         };
154
155         const int num_res = sizeof(res)/sizeof(FL_resource);
156
157         fl_initialize(&argc, argv, "LyX", cmdopt, num_res);
158
159         // It appears that, in xforms >=0.89.5, fl_initialize()
160         // calls setlocale() and ruins our LC_NUMERIC setting.
161         locale_init();
162
163         fl_get_app_resources(res, num_res);
164
165         Display * display = fl_get_display();
166
167         if (!display) {
168                 lyxerr << "LyX: unable to access X display, exiting" << endl;
169                 os::warn("Unable to access X display, exiting");
170                 ::exit(1);
171         }
172
173         fcntl(ConnectionNumber(display), F_SETFD, FD_CLOEXEC);
174
175         XSetErrorHandler(LyX_XErrHandler);
176
177         lyxColorHandler.reset(new LyXColorHandler());
178
179         using namespace lyx::graphics;
180
181         // connect the image loader based on the xforms library
182         Image::newImage = boost::bind(&xformsImage::newImage);
183         Image::loadableFormats = boost::bind(&xformsImage::loadableFormats);
184
185         // must do this /before/ lyxrc gets read
186         lyxrc.dpi = getDPI();
187
188         LoaderQueue::setPriority(10,100);
189 }
190
191
192 void parse_lyxrc()
193 {
194         XformsColor::read(AddName(user_lyxdir(), "preferences.xform"));
195
196         if (lyxrc.popup_font_encoding.empty())
197                 lyxrc.popup_font_encoding = lyxrc.font_norm;
198         // Set the font name for popups and menus
199         string boldfontname = lyxrc.popup_bold_font
200                                + "-*-*-*-?-*-*-*-*-"
201                                + lyxrc.popup_font_encoding;
202                 // "?" means "scale that font"
203         string fontname = lyxrc.popup_normal_font
204                                + "-*-*-*-?-*-*-*-*-"
205                                + lyxrc.popup_font_encoding;
206
207         int bold = fl_set_font_name(FL_BOLD_STYLE, boldfontname.c_str());
208         int normal = fl_set_font_name(FL_NORMAL_STYLE, fontname.c_str());
209         if (bold < 0)
210                 lyxerr << "Could not set menu font to "
211                        << boldfontname << endl;
212
213         if (normal < 0)
214                 lyxerr << "Could not set popup font to "
215                        << fontname << endl;
216
217         if (bold < 0 && normal < 0) {
218                 lyxerr << "Using 'helvetica' font for menus" << endl;
219                 boldfontname = "-*-helvetica-bold-r-*-*-*-?-*-*-*-*-iso8859-1";
220                 fontname = "-*-helvetica-medium-r-*-*-*-?-*-*-*-*-iso8859-1";
221                 bold = fl_set_font_name(FL_BOLD_STYLE, boldfontname.c_str());
222                 normal = fl_set_font_name(FL_NORMAL_STYLE, fontname.c_str());
223
224                 if (bold < 0 && normal < 0) {
225                         lyxerr << "Could not find helvetica font. Using 'fixed'." << endl;
226                         fl_set_font_name(FL_NORMAL_STYLE, "fixed");
227                         normal = bold = 0;
228                 }
229         }
230         if (bold < 0)
231                 fl_set_font_name(FL_BOLD_STYLE, fontname.c_str());
232         else if (normal < 0)
233                 fl_set_font_name(FL_NORMAL_STYLE, boldfontname.c_str());
234
235         fl_setpup_fontstyle(FL_NORMAL_STYLE);
236         fl_setpup_fontsize(FL_NORMAL_SIZE);
237         fl_setpup_color(FL_MCOL, FL_BLACK);
238         fl_set_goodies_font(FL_NORMAL_STYLE, FL_NORMAL_SIZE);
239         fl_set_tooltip_font(FL_NORMAL_STYLE, FL_NORMAL_SIZE);
240 }
241
242
243 void start(string const & batch, vector<string> const & files)
244 {
245         // initial geometry
246         int xpos = -1;
247         int ypos = -1;
248         unsigned int width = 690;
249         unsigned int height = 510;
250
251         int const geometryBitmask =
252                 XParseGeometry(geometry,
253                                &xpos, &ypos, &width, &height);
254
255         // if width is not set by geometry, check it against monitor width
256         if (!(geometryBitmask & WidthValue)) {
257                 Screen * scr = ScreenOfDisplay(fl_get_display(), fl_screen);
258                 if (WidthOfScreen(scr) - 8 < int(width))
259                         width = WidthOfScreen(scr) - 8;
260         }
261
262         // if height is not set by geometry, check it against monitor height
263         if (!(geometryBitmask & HeightValue)) {
264                 Screen * scr = ScreenOfDisplay(fl_get_display(), fl_screen);
265                 if (HeightOfScreen(scr) - 24 < int(height))
266                         height = HeightOfScreen(scr) - 24;
267         }
268
269         Screen * s = ScreenOfDisplay(fl_get_display(), fl_screen);
270
271         // recalculate xpos if it's not set
272         if (xpos == -1)
273                 xpos = (WidthOfScreen(s) - width) / 2;
274
275         // recalculate ypos if it's not set
276         if (ypos == -1)
277                 ypos = (HeightOfScreen(s) - height) / 2;
278
279         lyxerr[Debug::GUI] << "Creating view: " << width << 'x' << height
280                            << '+' << xpos << '+' << ypos << endl;
281
282         XFormsView view(width, height);
283         view.show(xpos, ypos, "LyX");
284         view.init();
285
286         // FIXME: some code below needs moving
287
288         lyxserver = new LyXServer(&view.getLyXFunc(), lyxrc.lyxpipes);
289
290         vector<string>::const_iterator cit = files.begin();
291         vector<string>::const_iterator end = files.end();
292         for (; cit != end; ++cit)
293                 view.view()->loadLyXFile(*cit, true);
294
295         // handle the batch commands the user asked for
296         if (!batch.empty())
297                 view.getLyXFunc().dispatch(batch);
298
299         // enter the event loop
300         while (!finished) {
301                 if (fl_check_forms() == FL_EVENT) {
302                         XEvent ev;
303                         fl_XNextEvent(&ev);
304                         lyxerr[Debug::GUI]
305                                 << "Received unhandled X11 event" << endl
306                                 << "Type: " << ev.xany.type
307                                 << " Target: 0x" << hex << ev.xany.window
308                                 << dec << endl;
309                 }
310         }
311
312         // FIXME: breaks emergencyCleanup
313         delete lyxserver;
314 }
315
316
317 void exit()
318 {
319         finished = true;
320 }
321
322
323 void sync_events()
324 {
325         // FIXME
326 }
327
328
329 FuncStatus getStatus(FuncRequest const & /*ev*/)
330 {
331         // Nothing interesting to do here
332         return FuncStatus();
333 }
334
335 string const hexname(EnumLColor col)
336 {
337         unsigned int r, g, b;
338         bool const success = getRGBColor(col, r, g, b);
339         if (!success) {
340                 lyxerr << "X can't find color for \"" << lcolor.getLyXName(col)
341                        << '"' << endl;
342                 return string();
343         }
344
345         ostringstream os;
346
347         os << setbase(16) << setfill('0')
348            << setw(2) << r
349            << setw(2) << g
350            << setw(2) << b;
351
352         return os.str();
353 }
354
355
356 void update_color(EnumLColor col)
357 {
358         lyxColorHandler->updateColor(col);
359 }
360
361
362 void update_fonts()
363 {
364         fontloader.update();
365 }
366
367
368 bool font_available(LyXFont const & font)
369 {
370         return fontloader.available(font);
371 }
372
373 namespace {
374
375 extern "C"
376 void C_read_callback(int, void * data)
377 {
378         LyXComm * comm = static_cast<LyXComm *>(data);
379         comm->read_ready();
380 }
381
382 }
383
384 void set_read_callback(int fd, LyXComm * comm)
385 {
386         fl_add_io_callback(fd, FL_READ, C_read_callback, comm);
387 }
388
389
390 void remove_read_callback(int fd)
391 {
392         fl_remove_io_callback(fd, FL_READ, C_read_callback);
393 }
394
395
396 string const roman_font_name()
397 {
398         return "times";
399 }
400
401
402 string const sans_font_name()
403 {
404         return "helvetica";
405 }
406
407
408 string const typewriter_font_name()
409 {
410         return "courier";
411 }
412
413 }; // namespace lyx_gui