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