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