]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/lyx_gui.C
Changes to make RH-7.3 be able to run lyx.
[lyx.git] / src / frontends / xforms / lyx_gui.C
1 /**
2  * \file lyx_gui.C
3  * Copyright 2002 the LyX Team
4  * Read the file COPYING
5  *
6  * \author unknown
7  * \author John Levon <moz@compsoc.man.ac.uk>
8  */
9
10 #include <config.h>
11
12 #include "lyx_gui.h"
13
14 #include "support/lyxlib.h"
15 #include "support/os.h"
16 #include "support/filetools.h"
17
18 #include "debug.h"
19 #include "gettext.h"
20
21 #include "lyx_main.h"
22 #include "lyxrc.h"
23
24 // FIXME: move this stuff out again
25 #include "bufferlist.h"
26 #include "lyxfunc.h"
27 #include "lyxserver.h"
28 #include "BufferView.h"
29 #include "XFormsView.h"
30
31 #include FORMS_H_LOCATION
32 #include "ColorHandler.h"
33 #include "xforms_helpers.h"
34 #ifdef USE_XFORMS_IMAGE_LOADER
35 #include "xformsImage.h"
36 #else
37 #include "graphics/GraphicsImageXPM.h"
38 #endif
39
40
41 #include <fcntl.h>
42
43 #include <boost/bind.hpp>
44
45 #ifndef CXX_GLOBAL_CSTD
46 using std::exit;
47 #endif
48
49 using std::vector;
50 using std::hex;
51 using std::endl;
52
53 extern bool finished;
54 extern BufferList bufferlist;
55
56 // FIXME: wrong place !
57 LyXServer * lyxserver;
58
59 namespace {
60
61 /// set default GUI configuration
62 void setDefaults()
63 {
64         FL_IOPT cntl;
65         cntl.buttonFontSize = FL_NORMAL_SIZE;
66         cntl.browserFontSize = FL_NORMAL_SIZE;
67         cntl.labelFontSize = FL_NORMAL_SIZE;
68         cntl.choiceFontSize = FL_NORMAL_SIZE;
69         cntl.inputFontSize = FL_NORMAL_SIZE;
70         cntl.menuFontSize  = FL_NORMAL_SIZE;
71         cntl.borderWidth = -1;
72         cntl.vclass = FL_DefaultVisual;
73         fl_set_defaults(FL_PDVisual
74                         | FL_PDButtonFontSize
75                         | FL_PDBrowserFontSize
76                         | FL_PDLabelFontSize
77                         | FL_PDChoiceFontSize
78                         | FL_PDInputFontSize
79                         | FL_PDMenuFontSize
80                         | FL_PDBorderWidth, &cntl);
81 }
82
83
84 extern "C" {
85
86 int LyX_XErrHandler(Display * display, XErrorEvent * xeev) {
87         // We don't abort on BadWindow
88         if (xeev->error_code == BadWindow) {
89                 lyxerr << "BadWindow received !" << endl;
90                 lyxerr << "If you're using xforms 1.0 or greater, "
91                         << " please report this to lyx-devel@lists.lyx.org" << endl;
92                 return 0;
93         }
94
95         // emergency cleanup
96         LyX::emergencyCleanup();
97
98         // Get the reason for the crash.
99         char etxt[513];
100         XGetErrorText(display, xeev->error_code, etxt, 512);
101         lyxerr << etxt << " id: " << xeev->resourceid << endl;
102         // By doing an abort we get a nice backtrace. (hopefully)
103         lyx::abort();
104         return 0;
105 }
106
107 }
108
109 /// read in geometry specification
110 char geometry[40];
111
112 } // namespace anon
113
114
115 void lyx_gui::parse_init(int & argc, char * argv[])
116 {
117         setDefaults();
118
119         FL_CMD_OPT cmdopt[] = {
120                 {"-geometry", "*.geometry", XrmoptionSepArg, "690x510"}
121         };
122
123         FL_resource res[] = {
124                 {"geometry", "geometryClass", FL_STRING, geometry, "", 40}
125         };
126
127         const int num_res = sizeof(res)/sizeof(FL_resource);
128
129         fl_initialize(&argc, argv, "LyX", cmdopt, num_res);
130
131         // It appears that, in xforms >=0.89.5, fl_initialize()
132         // calls setlocale() and ruins our LC_NUMERIC setting.
133         locale_init();
134
135         fl_get_app_resources(res, num_res);
136
137         Display * display = fl_get_display();
138
139         if (!display) {
140                 lyxerr << "LyX: unable to access X display, exiting" << endl;
141                 os::warn("Unable to access X display, exiting");
142                 ::exit(1);
143         }
144
145         fcntl(ConnectionNumber(display), F_SETFD, FD_CLOEXEC);
146
147         XSetErrorHandler(LyX_XErrHandler);
148
149         lyxColorHandler.reset(new LyXColorHandler());
150 }
151
152
153 void lyx_gui::parse_lyxrc()
154 {
155         // FIXME !!!!
156         lyxrc.dpi = 95;
157
158         XformsColor::read(AddName(user_lyxdir, "preferences.xform"));
159
160         if (lyxrc.popup_font_encoding.empty())
161                 lyxrc.popup_font_encoding = lyxrc.font_norm;
162         // Set the font name for popups and menus
163         string boldfontname = lyxrc.popup_bold_font
164                                + "-*-*-*-?-*-*-*-*-"
165                                + lyxrc.popup_font_encoding;
166                 // "?" means "scale that font"
167         string fontname = lyxrc.popup_normal_font
168                                + "-*-*-*-?-*-*-*-*-"
169                                + lyxrc.popup_font_encoding;
170
171         int bold = fl_set_font_name(FL_BOLD_STYLE, boldfontname.c_str());
172         int normal = fl_set_font_name(FL_NORMAL_STYLE, fontname.c_str());
173         if (bold < 0)
174                 lyxerr << "Could not set menu font to "
175                        << boldfontname << endl;
176
177         if (normal < 0)
178                 lyxerr << "Could not set popup font to "
179                        << fontname << endl;
180
181         if (bold < 0 && normal < 0) {
182                 lyxerr << "Using 'helvetica' font for menus" << endl;
183                 boldfontname = "-*-helvetica-bold-r-*-*-*-?-*-*-*-*-iso8859-1";
184                 fontname = "-*-helvetica-medium-r-*-*-*-?-*-*-*-*-iso8859-1";
185                 bold = fl_set_font_name(FL_BOLD_STYLE, boldfontname.c_str());
186                 normal = fl_set_font_name(FL_NORMAL_STYLE, fontname.c_str());
187
188                 if (bold < 0 && normal < 0) {
189                         lyxerr << "Could not find helvetica font. Using 'fixed'." << endl;
190                         fl_set_font_name(FL_NORMAL_STYLE, "fixed");
191                         normal = bold = 0;
192                 }
193         }
194         if (bold < 0)
195                 fl_set_font_name(FL_BOLD_STYLE, fontname.c_str());
196         else if (normal < 0)
197                 fl_set_font_name(FL_NORMAL_STYLE, boldfontname.c_str());
198
199         fl_setpup_fontstyle(FL_NORMAL_STYLE);
200         fl_setpup_fontsize(FL_NORMAL_SIZE);
201         fl_setpup_color(FL_MCOL, FL_BLACK);
202         fl_set_goodies_font(FL_NORMAL_STYLE, FL_NORMAL_SIZE);
203 #if FL_REVISION < 89
204         fl_set_oneliner_font(FL_NORMAL_STYLE, FL_NORMAL_SIZE);
205 #else
206         fl_set_tooltip_font(FL_NORMAL_STYLE, FL_NORMAL_SIZE);
207 #endif
208 }
209
210
211 void lyx_gui::start(string const & batch, vector<string> files)
212 {
213         // initial geometry
214         int xpos = -1;
215         int ypos = -1;
216         unsigned int width = 690;
217         unsigned int height = 510;
218
219         static const int geometryBitmask =
220                 XParseGeometry(geometry,
221                                 &xpos, &ypos, &width, &height);
222
223         // if width is not set by geometry, check it against monitor width
224         if (!(geometryBitmask & 4)) {
225                 Screen * scr = ScreenOfDisplay(fl_get_display(), fl_screen);
226                 if (WidthOfScreen(scr) - 8 < int(width))
227                         width = WidthOfScreen(scr) - 8;
228         }
229
230         // if height is not set by geometry, check it against monitor height
231         if (!(geometryBitmask & 8)) {
232                 Screen * scr = ScreenOfDisplay(fl_get_display(), fl_screen);
233                 if (HeightOfScreen(scr) - 24 < int(height))
234                         height = HeightOfScreen(scr) - 24;
235         }
236
237         Screen * s = ScreenOfDisplay(fl_get_display(), fl_screen);
238
239         // recalculate xpos if it's not set
240         if (xpos == -1)
241                 xpos = (WidthOfScreen(s) - width) / 2;
242
243         // recalculate ypos if it's not set
244         if (ypos == -1)
245                 ypos = (HeightOfScreen(s) - height) / 2;
246
247         lyxerr[Debug::GUI] << "Creating view: " << width << "x" << height
248                 << "+" << xpos << "+" << ypos << endl;
249
250         XFormsView view(width, height);
251         view.show(xpos, ypos, "LyX");
252         view.init();
253
254         Buffer * last = 0;
255
256         // FIXME: some code below needs moving
257
258         lyxserver = new LyXServer(view.getLyXFunc(), lyxrc.lyxpipes);
259
260         vector<string>::const_iterator cit = files.begin();
261         vector<string>::const_iterator end = files.end();
262         for (; cit != end; ++cit) {
263                 Buffer * b = bufferlist.loadLyXFile(*cit);
264                 if (b) {
265                         last = b;
266                 }
267         }
268
269         // switch to the last buffer successfully loaded
270         if (last) {
271                 view.view()->buffer(last);
272         }
273
274         // handle the batch commands the user asked for
275         if (!batch.empty()) {
276                 view.getLyXFunc()->verboseDispatch(batch, false);
277         }
278
279         // enter the event loop
280         while (!finished) {
281                 if (fl_check_forms() == FL_EVENT) {
282                         XEvent ev;
283                         fl_XNextEvent(&ev);
284                         lyxerr << "Received unhandled X11 event" << endl;
285                         lyxerr << "Type: 0x" << hex << ev.xany.type <<
286                                 " Target: 0x" << hex << ev.xany.window << endl;
287                 }
288         }
289
290         // FIXME
291         delete lyxserver;
292 }
293
294
295 // Called by the graphics cache to connect the appropriate frontend
296 // image loading routines to the LyX kernel.
297 void lyx_gui::init_graphics()
298 {
299         using namespace grfx;
300
301 #ifdef USE_XFORMS_IMAGE_LOADER
302         // connect the image loader based on the xforms library
303         Image::newImage = boost::bind(&xformsImage::newImage);
304         Image::loadableFormats = boost::bind(&xformsImage::loadableFormats);
305 #else
306         // connect the image loader based on the XPM library
307         Image::newImage = boost::bind(&ImageXPM::newImage);
308         Image::loadableFormats = boost::bind(&ImageXPM::loadableFormats);
309 #endif
310 }