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