1 /* Various functions for internationalizing SXEmacs
2 Copyright (C) 1993, 1994, 1995 Board of Trustees, University of Illinois.
4 This file is part of SXEmacs
6 SXEmacs is free software: you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation, either version 3 of the License, or
9 (at your option) any later version.
11 SXEmacs is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>. */
20 /* Synched up with: Not in FSF. */
22 /* This stuff is far, far from working. */
28 #include "ui/device.h"
30 #if defined (HAVE_X_WINDOWS) && defined (HAVE_X11_XLOCALE_H)
31 #include <X11/Xlocale.h>
41 unsigned long input_method_event_mask;
44 /* init_input -- Set things up for i18n level 4 input.
46 void init_input(const char *res_name, const char *res_class, Display * display)
52 input_method_style = 0;
53 initial_input_context = 0;
54 input_method_event_mask = 0;
56 input_method = XOpenIM(display, NULL,
57 (char *)res_name, (char *)res_class);
60 stderr_out("WARNING: XOpenIM() failed...no input server\n");
64 /* Query input method for supported input styles and pick one.
65 Right now, we choose a style which supports root-window preediting. */
66 XGetIMValues(input_method, XNQueryInputStyle, &styles, NULL);
67 for (i = 0; i < styles->count_styles; i++) {
68 if (styles->supported_styles[i] ==
69 (XIMPreeditNothing | XIMStatusNothing)) {
70 input_method_style = styles->supported_styles[i];
75 if (!input_method_style) {
76 stderr_out("WARNING: Could not find suitable input style.\n");
80 initial_input_context = XCreateIC(input_method,
81 XNInputStyle, input_method_style,
83 if (!initial_input_context) {
84 stderr_out("WARNING: Could not create input context.\n");
85 char *envvar = getenv("LANG");
90 envvar = getenv("XMODIFIERS");
92 stderr_out("XMODIFIERS=");
98 XGetICValues(initial_input_context,
99 XNFilterEvents, &input_method_event_mask, NULL);
101 /* Get a new atom for wide character client messages. */
102 wc_atom = XInternAtom(display, "Wide Character Event", False);
105 /*static widechar_string composed_input_buf = EMPTY_WIDECHAR_STRING;*/
107 #define XIM_Composed_Text_BUFSIZE 64
108 typedef struct XIM_Composed_Text {
110 wchar_t data[XIM_Composed_Text_BUFSIZE];
112 static XIM_Composed_Text composed_input_buf =
113 { XIM_Composed_Text_BUFSIZE, {0} };
114 /*static wcidechar composed_input_buf [64] = {0};*/
115 Window main_window; /* Convenient way to refer to main Era window. */
117 /* x_get_composed_input -- Process results of input method composition.
119 This function copies the results of the input method composition to
120 composed_input_buf. Then for each character, a custom event of type
121 wc_atom is sent with the character as its data.
123 It is probably more efficient to copy the composition results to some
124 allocated memory and send a single event pointing to that memory.
125 That would cut down on the event processing as well as allow quick
126 insertion into the buffer of the whole string. It might require some
127 care, though, to avoid fragmenting memory through the allocation and
128 freeing of many small chunks. Maybe the existing system for
129 (single-byte) string allocation can be used, multiplying the length by
130 sizeof (wchar_t) to get the right size.
133 x_get_composed_input(XKeyPressedEvent * x_key_event, XIC context,
140 XClientMessageEvent new_event;
143 len = XwcLookupString(context, x_key_event, composed_input_buf.data,
144 composed_input_buf.size, &keysym, &status);
146 case XBufferOverflow:
147 /* GROW_WC_STRING (&composed_input_buf, 32); mrb */
155 new_event.type = ClientMessage;
156 new_event.display = x_key_event->display;
157 new_event.window = x_key_event->window;
158 new_event.message_type = wc_atom;
159 new_event.format = 32; /* 32-bit wide data */
160 new_event.data.l[2] = new_event.data.l[3] = new_event.data.l[4] = 0L;
161 new_event.data.l[0] = x_key_event->time;
162 for (i = 0; i < len; i++) {
163 new_event.data.l[1] = ((wchar_t *) composed_input_buf.data)[i];
164 XSendEvent(display, main_window, False, 0L,
165 (XEvent *) & new_event);
170 Lisp_Object Qdefer_gettext;
172 DEFUN("ignore-defer-gettext", Fignore_defer_gettext, 1, 1, 0, /*
173 If OBJECT is of the form (defer-gettext "string"), return the string.
174 The purpose of the defer-gettext symbol is to identify strings which
175 are translated when they are referenced instead of when they are defined.
180 Lisp_Object tmp = Fcar(object);
181 if (SYMBOLP(tmp) && EQ(tmp, Qdefer_gettext)) {
182 return Fcar(Fcdr(object));
188 DEFUN("gettext", Fgettext, 1, 1, 0, /*
189 Look up STRING in the default message domain and return its translation.
190 This function does nothing if I18N3 was not enabled when Emacs was compiled.
195 /* #### What should happen here is:
197 1) If the string has no `string-translatable' property or its value
198 is nil, no translation takes place. The `string-translatable' property
199 only gets added when a constant string is read in from a .el or .elc
200 file, to avoid excessive translation. (The user can also explicitly
201 add this property to a string.)
202 2) If the string's `string-translatable' property is a string,
203 that string should be returned. `format' add this property.
204 This allows translation to take place at the proper time but
205 avoids excessive translation if the string is not destined for
206 a translating stream. (See print_internal().)
207 3) If gettext() returns the same string, then Fgettext() should return
208 the same object, minus the 'string-translatable' property. */
210 if (STRINGP(string)) {
212 stderr_out("\nFgettext (%s) called.\n", XSTRING_DATA(string));
214 return build_string(gettext((char *)XSTRING_DATA(string)));
225 /* #### add the function `force-gettext', perhaps in Lisp. This
226 ignores the `string-translatable' property and simply calls gettext()
227 on the string. Add the functions `set-string-translatable' and
228 `set-stream-translating'. */
232 DEFUN("dgettext", Fdgettext, 2, 2, 0, /*
233 Look up STRING in the specified message domain and return its translation.
234 This function does nothing if I18N3 was not enabled when Emacs was compiled.
238 CHECK_STRING(domain);
239 CHECK_STRING(string);
241 return build_string(dgettext((char *)XSTRING_DATA(domain),
242 (char *)XSTRING_DATA(string)));
248 DEFUN("bind-text-domain", Fbind_text_domain, 2, 2, 0, /*
249 Associate a pathname with a message domain.
250 Here's how the path to message files is constructed under SunOS 5.0:
251 {pathname}/{LANG}/LC_MESSAGES/{domain}.mo
252 This function does nothing if I18N3 was not enabled when Emacs was compiled.
256 CHECK_STRING(domain);
257 CHECK_STRING(pathname);
259 return build_string(bindtextdomain((char *)XSTRING_DATA(domain),
260 (char *)XSTRING_DATA(pathname)));
266 extern int load_in_progress;
268 DEFUN("set-domain", Fset_domain, 1, 1, 0, /*
269 Specify the domain used for translating messages in this source file.
270 The domain declaration may only appear at top-level, and should precede
271 all function and variable definitions.
273 The presence of this declaration in a compiled file effectively sets the
274 domain of all functions and variables which are defined in that file.
275 Bug: it has no effect on source (.el) files, only compiled (.elc) files.
279 CHECK_STRING(domain_name);
280 if (load_in_progress)
281 return (domain_name);
286 /************************************************************************/
288 /************************************************************************/
290 void init_intl_very_early(void)
292 #if defined (I18N2) || defined (I18N3) || defined (I18N4)
293 setlocale(LC_ALL, "");
294 setlocale(LC_NUMERIC, "C");
302 void syms_of_intl(void)
304 /* defer-gettext is defined as a symbol because when it is used in menu
305 specification strings, it is not evaluated as a function by
306 menu_item_descriptor_to_widget_value(). */
307 defsymbol(&Qdefer_gettext, "defer-gettext");
309 DEFSUBR(Fignore_defer_gettext);
312 DEFSUBR(Fbind_text_domain);
313 DEFSUBR(Fset_domain);
316 void vars_of_intl(void)
319 Fprovide(intern("i18n2"));
322 Fprovide(intern("i18n3"));