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