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