]> git.lyx.org Git - lyx.git/blob - src/frontends/xforms/lyxlookup.C
Really dull and boring header shit
[lyx.git] / src / frontends / xforms / lyxlookup.C
1 /**
2  * \file lyxlookup.C
3  * Read the file COPYING
4  *
5  * \author unknown
6  *
7  * Full author contact details are available in file CREDITS
8  */
9
10 #ifdef __GNUG__
11 #pragma implementation
12 #endif
13
14 #include <config.h>
15
16 #ifdef HAVE_XOPENIM
17 // This part is the full blown Input Method manager for X11R5 and up.
18 // For the plain-and-old-X11R4 version, see later.
19 #include <X11/Xlib.h>
20 #include <X11/Xutil.h>
21 #include <X11/keysym.h>
22 #ifdef HAVE_LOCALE_H
23 #include <locale.h>
24 #endif
25 #include <clocale>
26
27 #include "lyxlookup.h"
28 #include "debug.h"
29 #include "lyxrc.h"
30
31 using std::endl;
32
33 namespace {
34
35 XIM xim;
36 XIC xic;
37 XComposeStatus compose_status= {0, 0};
38
39 } // namespace anon
40
41
42 // This is called after the main LyX window has been created
43 void InitLyXLookup(Display * display, Window window)
44 {
45         xic = 0;
46
47         lyxerr[Debug::KEY]
48                         << "InitLyXLookup: creating an input context."
49                         << endl;
50
51         // This part could be done before opening display
52         string oldlocale = setlocale(LC_CTYPE, 0);
53         setlocale(LC_CTYPE, "");
54         if (!XSupportsLocale()) {
55                 lyxerr[Debug::KEY]
56                         << "InitLyXLookup: X does not support this locale."
57                         << endl;
58                 return;
59         }
60         // reset the LC_CTYPE locale to previous value.
61         setlocale(LC_CTYPE, oldlocale.c_str());
62
63         char const * locmod;
64         if (!(locmod = XSetLocaleModifiers(""))) {
65                 lyxerr[Debug::KEY] << "InitLyXLookup: Could not set modifiers "
66                         "for this locale." << endl;
67                 return;
68         }
69         else
70                 lyxerr[Debug::KEY] << "InitLyXLookup: X locale modifiers are `"
71                                    << locmod << '\'' << endl;
72
73         // This part will have to be done for each frame
74         xim = XOpenIM (display, 0, 0, 0);
75         if (xim) {
76                 xic = XCreateIC(xim,
77                                 XNInputStyle,
78                                 XIMPreeditNothing|XIMStatusNothing,
79                                 XNClientWindow, window,
80                                 XNFocusWindow, window,
81                                 0);
82
83                 if (!xic) {
84                         lyxerr[Debug::KEY] << "InitLyXLookup: "
85                                 "could not create an input context" << endl;
86                         XCloseIM (xim);
87                         xim = 0;
88                 }
89         }
90         else
91                 lyxerr[Debug::KEY] << "InitLyXLookup: could not open "
92                         "an input method." << endl;
93 }
94
95
96 namespace {
97
98 bool isDeadEvent(KeySym keysym)
99 {
100         // Can this be done safely in any other way?
101         // This is all the dead keys I know of in X11R6.1
102         switch (keysym) {
103 #ifdef XK_dead_grave
104         case XK_dead_grave:
105 #endif
106 #ifdef XK_dead_acute
107         case XK_dead_acute:
108 #endif
109 #ifdef XK_dead_circumflex
110         case XK_dead_circumflex:
111 #endif
112 #ifdef XK_dead_tilde
113         case XK_dead_tilde:
114 #endif
115 #ifdef XK_dead_macron
116         case XK_dead_macron:
117 #endif
118 #ifdef XK_dead_breve
119         case XK_dead_breve:
120 #endif
121 #ifdef XK_dead_abovedot
122         case XK_dead_abovedot:
123 #endif
124 #ifdef XK_dead_diaeresis
125         case XK_dead_diaeresis:
126 #endif
127 #ifdef XK_dead_abovering
128         case XK_dead_abovering:
129 #endif
130 #ifdef XK_dead_doubleacute
131         case XK_dead_doubleacute:
132 #endif
133 #ifdef XK_dead_caron
134         case XK_dead_caron:
135 #endif
136 #ifdef XK_dead_cedilla
137         case XK_dead_cedilla:
138 #endif
139 #ifdef XK_dead_ogonek
140         case XK_dead_ogonek:
141 #endif
142 #ifdef XK_dead_iota
143         case XK_dead_iota:
144 #endif
145 #ifdef XK_dead_voiced_sound
146         case XK_dead_voiced_sound:
147 #endif
148 #ifdef XK_dead_semivoiced_sound
149         case XK_dead_semivoiced_sound:
150 #endif
151 #ifdef XK_dead_belowdot
152         case XK_dead_belowdot:
153 #endif
154                 return true;
155         default:
156                 return false;
157         }
158 }
159
160 } // namespace anon
161
162
163 // This is called instead of XLookupString()
164 int LyXLookupString(XEvent * event,
165                     char * buffer_return, int bytes_buffer,
166                     KeySym * keysym_return)
167 {
168         if (event->type != KeyPress) {
169                 lyxerr << "LyXLookupString: wrong event type: "
170                        << event->type << endl;
171                 return 0;
172         }
173
174         int result = 0;
175         if (xic) {
176 #if 1
177                 // somehow it is necessary to do the lookup. Why? (JMarc)
178                 XLookupString(&event->xkey, buffer_return,
179                               bytes_buffer, keysym_return,
180                               0);
181
182                 if (lyxrc.override_x_deadkeys &&
183                     isDeadEvent(*keysym_return)) {
184                         lyxerr[Debug::KEY]
185                                 << "LyXLookupString: found DeadEvent" << endl;
186                         return 0;
187                 }
188 #endif
189 #if 1
190                 if (XFilterEvent (event, None)) {
191                         lyxerr[Debug::KEY] <<"XFilterEvent" << endl;
192                         *keysym_return = NoSymbol;
193                         return 0;
194                 }
195 #endif
196                 Status status_return = 0;
197
198                 result =  XmbLookupString(xic, &event->xkey, buffer_return,
199                                        bytes_buffer, keysym_return,
200                                        &status_return);
201                 switch (status_return) {
202                 case XBufferOverflow:
203                         lyxerr[Debug::KEY] << "XBufferOverflow" << endl;
204                         break;
205                 case XLookupBoth:
206                         lyxerr[Debug::KEY] << "XLookupBoth "
207                                            << string(buffer_return, result)
208                                            << endl;
209                         break;
210                 case XLookupChars:
211                         lyxerr[Debug::KEY] << "XLookupChars "
212                                            << string(buffer_return, result)
213                                            << endl;
214
215                         *keysym_return = NoSymbol;
216                         break;
217                 case XLookupKeySym:
218                         lyxerr[Debug::KEY] << "XLookupKeySym" << endl;
219                         result = 0;
220                         break;
221                 case XLookupNone:
222                         lyxerr[Debug::KEY] << "XLookupNone" << endl;
223                         *keysym_return = NoSymbol;
224                         result = 0;
225                         break;
226                 default:
227                         lyxerr << "Unknown status_return from"
228                                 " XmbLookupString" << endl;
229                         break;
230                 }
231         } else {
232                 result = XLookupString(&event->xkey, buffer_return,
233                                   bytes_buffer, keysym_return,
234                                   &compose_status);
235         }
236         return result;
237 }
238
239
240 // This is called after the main window has been destroyed
241 void CloseLyXLookup()
242 {
243         if (xic) {
244                 lyxerr[Debug::KEY] << "CloseLyXLookup: destroying input context"
245                                << endl;
246                 XDestroyIC(xic);
247                 xic = 0;
248                 XCloseIM(xim);
249         }
250 }
251
252
253 #else // We do not have XOpenIM, so we stick with normal XLookupString
254
255 #include <X11/Xlib.h>
256 #include <X11/Xutil.h>
257
258 XComposeStatus compose_status= {0, 0};
259
260 // This is called after the main LyX window has been created
261 void InitLyXLookup(Display *, Window)
262 {
263         //Nothing to do.
264 }
265
266 // This is called instead of XLookupString(). I this particular case,
267 // this *is* XLookupString...
268 int LyXLookupString(XEvent * event,
269                     char * buffer_return, int bytes_buffer,
270                     KeySym * keysym_return)
271 {
272         return XLookupString(&event->xkey, buffer_return,
273                                   bytes_buffer, keysym_return,
274                                   &compose_status);
275 }
276
277 // This is called after the main window has been destroyed
278 void CloseLyXLookup()
279 {
280         // Nothing to do
281 }
282
283 #endif // HAVE_XOPENIM