]> git.lyx.org Git - features.git/blob - src/lyx_gui.C
Compaq cxx 6.5 will now compile lyx.
[features.git] / src / lyx_gui.C
1 /* This file is part of
2  * ======================================================
3  *
4  *           LyX, The Document Processor
5  *
6  *          Copyright 1995 Matthias Ettrich
7  *          Copyright 1995-2001 The LyX Team.
8  *
9  * ====================================================== */
10
11 #include <config.h>
12
13 #ifdef __GNUG__
14 #pragma implementation
15 #endif
16
17 #include "lyx_gui.h"
18 #include FORMS_H_LOCATION
19 #include "tex-strings.h"
20 #include "lyx_main.h"
21 #include "debug.h"
22 #include "version.h"
23 #include "frontends/LyXView.h"
24 #include "buffer.h"
25 #include "BufferView.h"
26 #include "lyxserver.h"
27 #include "lyxrc.h"
28 #include "gettext.h"
29 #if FL_VERSION < 1 && (FL_REVISION < 89 || (FL_REVISION == 89 && FL_FIXLEVEL < 5))
30 #include "frontends/xforms/lyxlookup.h"
31 #endif
32 #include "bufferlist.h"
33 #include "frontends/xforms/ColorHandler.h"
34
35 #include "frontends/GUIRunTime.h"
36 #include "frontends/xforms/xforms_helpers.h" // for XformColor
37
38 #include "support/filetools.h"
39 #include "support/os.h"
40 #include "support/lyxlib.h"
41
42 #include <cstdlib>
43 #include <fcntl.h>
44
45 #ifndef CXX_GLOBAL_CSTD
46 using std::exit;
47 #endif
48
49 using std::endl;
50
51 extern LyXServer * lyxserver;
52 extern bool finished;   // flag, that we are quitting the program
53 extern BufferList bufferlist;
54 extern string user_lyxdir;
55
56 FL_CMD_OPT cmdopt[] =
57 {
58         {"-geometry", "*.geometry", XrmoptionSepArg, "690x510"}
59 };
60
61 namespace {
62
63 int width  = 690;
64 int height = 510;
65 int xpos   = -1;
66 int ypos   = -1;
67 char geometry[40];
68
69 } // namespace anon
70
71
72 FL_resource res[] =
73 {
74         {"geometry", "geometryClass", FL_STRING, geometry, "", 40}
75 };
76
77
78 extern "C" {
79
80 static
81 int LyX_XErrHandler(Display * display, XErrorEvent * xeev)
82 {
83         if (xeev->error_code == BadWindow) {
84                 // We don't abort on BadWindow
85                 return 0;
86         }
87
88         // emergency cleanup
89         LyX::emergencyCleanup();
90
91         // Get the reason for the crash.
92         char etxt[513];
93         XGetErrorText(display, xeev->error_code, etxt, 512);
94         lyxerr << etxt << " id: " << xeev->resourceid << endl;
95         // By doing an abort we get a nice backtrace. (hopefully)
96         lyx::abort();
97         return 0;
98 }
99
100 }
101
102
103 LyXGUI::LyXGUI(LyX * owner, int * argc, char * argv[], bool GUI)
104         : _owner(owner), lyxViews(0)
105 {
106         gui = GUI;
107         if (!gui)
108                 return;
109
110         //
111         setDefaults();
112
113         static const int num_res = sizeof(res)/sizeof(FL_resource);
114         fl_initialize(argc, argv, "LyX", cmdopt, num_res);
115         // It appears that, in xforms >=0.89.5, fl_initialize()
116         // calls setlocale() and ruins our LC_NUMERIC setting.
117         locale_init();
118         fl_get_app_resources(res, num_res);
119
120         static const int geometryBitmask =
121                 XParseGeometry(geometry,
122                                 &xpos,
123                                 &ypos,
124                                 reinterpret_cast<unsigned int *>(&width),
125                                 reinterpret_cast<unsigned int *>(&height));
126
127         Display * display = fl_get_display();
128         if (!display) {
129                 lyxerr << "LyX: unable to access X display, exiting" << endl;
130                 os::warn("Unable to access X display, exiting");
131                 exit(1);
132         }
133         fcntl(ConnectionNumber(display), F_SETFD, FD_CLOEXEC);
134         // X Error handler install goes here
135         XSetErrorHandler(LyX_XErrHandler);
136
137         // A width less than 590 pops up an awkward main window
138         // The minimal values of width/height (590/400) are defined in
139         // src/lyx.C
140         if (width < 590) width = 590;
141         if (height < 400) height = 400;
142
143         // If width is not set by geometry, check it against monitor width
144         if (!(geometryBitmask & 4)) {
145                 Screen * scr = ScreenOfDisplay(fl_get_display(), fl_screen);
146                 if (WidthOfScreen(scr) - 8 < width)
147                         width = WidthOfScreen(scr) - 8;
148         }
149
150         // If height is not set by geometry, check it against monitor height
151         if (!(geometryBitmask & 8)) {
152                 Screen * scr = ScreenOfDisplay(fl_get_display(), fl_screen);
153                 if (HeightOfScreen(scr) - 24 < height)
154                         height = HeightOfScreen(scr) - 24;
155         }
156
157         // Recalculate xpos if it's negative
158         if (geometryBitmask & 16)
159                 xpos += WidthOfScreen(ScreenOfDisplay(fl_get_display(),
160                                                       fl_screen)) - width;
161
162         // Recalculate ypos if it's negative
163         if (geometryBitmask & 32)
164                 ypos += HeightOfScreen(ScreenOfDisplay(fl_get_display(),
165                                                        fl_screen)) - height;
166
167         // Initialize the LyXColorHandler
168         lyxColorHandler.reset(new LyXColorHandler);
169 }
170
171
172 // A destructor is always necessary  (asierra-970604)
173 LyXGUI::~LyXGUI()
174 {
175         // Lyxserver was created in this class so should be destroyed
176         // here.  asierra-970604
177         delete lyxserver;
178         lyxserver = 0;
179         delete lyxViews;
180 #if FL_VERSION < 1 && (FL_REVISION < 89 || (FL_REVISION == 89 && FL_FIXLEVEL < 5))
181         CloseLyXLookup();
182 #endif
183 }
184
185
186 void LyXGUI::setDefaults()
187 {
188         GUIRunTime::setDefaults();
189 }
190
191
192 // This is called after we have parsed lyxrc
193 void LyXGUI::init()
194 {
195         if (!gui)
196                 return;
197
198         create_forms();
199
200         if (lyxrc.popup_font_encoding.empty())
201                 lyxrc.popup_font_encoding = lyxrc.font_norm;
202         // Set the font name for popups and menus
203         string boldfontname = lyxrc.popup_bold_font
204                                + "-*-*-*-?-*-*-*-*-"
205                                + lyxrc.popup_font_encoding;
206                 // "?" means "scale that font"
207         string fontname = lyxrc.popup_normal_font
208                                + "-*-*-*-?-*-*-*-*-"
209                                + lyxrc.popup_font_encoding;
210
211         int bold = fl_set_font_name(FL_BOLD_STYLE, boldfontname.c_str());
212         int normal = fl_set_font_name(FL_NORMAL_STYLE, fontname.c_str());
213         if (bold < 0)
214                 lyxerr << "Could not set menu font to "
215                        << boldfontname << endl;
216
217         if (normal < 0)
218                 lyxerr << "Could not set popup font to "
219                        << fontname << endl;
220
221         if (bold < 0 && normal < 0) {
222                 lyxerr << "Using 'helvetica' font for menus" << endl;
223                 boldfontname = "-*-helvetica-bold-r-*-*-*-?-*-*-*-*-iso8859-1";
224                 fontname = "-*-helvetica-medium-r-*-*-*-?-*-*-*-*-iso8859-1";
225                 bold = fl_set_font_name(FL_BOLD_STYLE, boldfontname.c_str());
226                 normal = fl_set_font_name(FL_NORMAL_STYLE, fontname.c_str());
227
228                 if (bold < 0 && normal < 0) {
229                         lyxerr << "Could not find helvetica font. Using 'fixed'." << endl;
230                         fl_set_font_name(FL_NORMAL_STYLE, "fixed");
231                         normal = bold = 0;
232                 }
233         }
234         if (bold < 0)
235                 fl_set_font_name(FL_BOLD_STYLE, fontname.c_str());
236         else if (normal < 0)
237                 fl_set_font_name(FL_NORMAL_STYLE, boldfontname.c_str());
238
239         // put here (after fl_initialize) to avoid segfault. Cannot be done
240         // in setDefaults() (Matthias 140496)
241         // Moved from ::LyXGUI to ::init to allow popup font customization
242         // (petr 120997).
243         fl_setpup_fontstyle(FL_NORMAL_STYLE);
244         fl_setpup_fontsize(FL_NORMAL_SIZE);
245         fl_setpup_color(FL_MCOL, FL_BLACK);
246         fl_set_goodies_font(FL_NORMAL_STYLE, FL_NORMAL_SIZE);
247 #if FL_VERSION < 1 && FL_REVISION < 89
248         fl_set_oneliner_font(FL_NORMAL_STYLE, FL_NORMAL_SIZE);
249 #else
250         fl_set_tooltip_font(FL_NORMAL_STYLE, FL_NORMAL_SIZE);
251 #endif
252
253         // all lyxrc settings has to be done here as lyxrc has not yet
254         // been read when the GUI is created (Jug)
255
256         // Update parameters.
257         lyxViews->redraw();
258
259         // Initialize the views.
260         lyxViews->init();
261
262         // this should be moved ...
263         lyxserver = new LyXServer(lyxViews->getLyXFunc(), lyxrc.lyxpipes);
264 }
265
266
267 void LyXGUI::create_forms()
268 {
269         lyxerr[Debug::INIT] << "Initializing LyXView..." << endl;
270         lyxViews = GUIRunTime::createMainView(width, height);
271         lyxerr[Debug::INIT] << "Initializing LyXView...done" << endl;
272
273         // From here down should be done by somebody else. (Lgb)
274
275         // This is probably as good a time as any to map the xform colours,
276         // should a mapping exist.
277         string const filename = AddName(user_lyxdir, "preferences.xform");
278         XformsColor::read(filename);
279
280         // Show the main & title form
281         int main_placement = FL_PLACE_CENTER | FL_FREE_SIZE;
282         // Did we get a valid position?
283         if (xpos >= 0 && ypos >= 0) {
284                 lyxViews->setPosition(xpos, ypos);
285                 main_placement = FL_PLACE_POSITION;
286         }
287
288         lyxViews->show(main_placement, FL_FULLBORDER, "LyX");
289 }
290
291
292 void LyXGUI::runTime()
293 {
294         if (!gui) return;
295
296         GUIRunTime::runTime();
297 }
298
299
300 void LyXGUI::regBuf(Buffer * b)
301 {
302         lyxViews->view()->buffer(b);
303 }
304
305
306 LyXView * LyXGUI::getLyXView() const
307 {
308         return lyxViews;
309 }