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