]> git.lyx.org Git - lyx.git/blob - src/lyxlookup.C
citation patch from Angus
[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 1
168                 if (XFilterEvent (event, None)) {
169                         lyxerr[Debug::KEY] <<"XFilterEvent" << endl;
170                         *keysym_return = NoSymbol;
171                         return 0;
172                 }
173 #endif
174                 if (event->type != KeyPress)
175                         lyxerr << "LyXLookupString: wrong event type" 
176                                <<  event->type << endl;
177                 Status status_return = 0;
178                 
179                 result =  XmbLookupString(xic, &event->xkey, buffer_return,
180                                        bytes_buffer, keysym_return,
181                                        &status_return);
182                 switch(status_return) {
183                 case XBufferOverflow:
184                         lyxerr[Debug::KEY] << "XBufferOverflow" << endl;
185                         break;
186                 case XLookupBoth:
187                         lyxerr[Debug::KEY] << "XLookupBoth"
188                                            << string(buffer_return, result)
189                                            << endl;
190                         break;
191                 case XLookupChars:
192                         lyxerr[Debug::KEY] << "XLookupChars "
193                                            << string(buffer_return, result)
194                                            << endl;
195                         
196                         *keysym_return = NoSymbol;
197                         break;
198                 case XLookupKeySym:
199                         lyxerr[Debug::KEY] << "XLookupKeySym" << endl;
200                         result = 0;
201                         break;
202                 case XLookupNone:
203                         lyxerr[Debug::KEY] << "XLookupNone" << endl;
204                         *keysym_return = NoSymbol;
205                         result = 0;
206                         break;
207                 default:
208                         lyxerr << "Unknown status_return from"
209                                 " XmbLookupString" << endl;
210                         break;
211                 }
212         } else {
213                 result = XLookupString(&event->xkey, buffer_return,
214                                   bytes_buffer, keysym_return,
215                                   &compose_status);
216         }
217         return result;
218 }
219
220
221 // This is called after the main window has been destroyed
222 void CloseLyXLookup() 
223 {
224         if (xic) {
225                 lyxerr[Debug::KEY] << "CloseLyXLookup: destroying input context"
226                                << endl;
227                 XDestroyIC(xic);
228                 xic = 0;
229                 XCloseIM(xim);
230         }
231 }
232
233
234 #else // We do not have XOpenIM, so we stick with normal XLookupString
235
236 #include <X11/Xlib.h>
237 #include <X11/Xutil.h>
238
239 XComposeStatus compose_status= {0, 0};
240
241 // This is called after the main LyX window has been created
242 void InitLyXLookup(Display *, Window ) 
243 {
244         //Nothing to do.
245 }
246
247 // This is called instead of XLookupString(). I this particular case,
248 // this *is* XLookupString...
249 int LyXLookupString(XEvent * event,    
250                     char * buffer_return, int bytes_buffer,
251                     KeySym * keysym_return) 
252 {
253         return XLookupString(&event->xkey, buffer_return,
254                                   bytes_buffer, keysym_return,
255                                   &compose_status);
256 }
257
258 // This is called after the main window has been destroyed
259 void CloseLyXLookup() 
260 {
261         // Nothing to do
262 }
263
264 #endif // HAVE_XOPENIM