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