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