aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorPo Lu2022-10-03 20:18:22 +0800
committerPo Lu2022-10-03 20:18:37 +0800
commitda02b9edadbc809b25ac83eccf64089f1cf3b160 (patch)
tree084641cd35e268b195b51ba7d09352207c52eb16 /src
parente245c4f226979ccb717cccc8f82b2b0a0f96bdac (diff)
downloademacs-da02b9edadbc809b25ac83eccf64089f1cf3b160.tar.gz
emacs-da02b9edadbc809b25ac83eccf64089f1cf3b160.zip
Fix coding systems used for X input methods
* doc/emacs/mule.texi (International): Refer to X Coding as well. (Communication Coding): Document that locale-coding-system is not always used on X to decode keyboard input. (X Coding): New node. * etc/NEWS: Announce change to input method coding resolution. * lisp/term/x-win.el (x-get-input-coding-system): New function. * src/coding.c (syms_of_coding): Update doc string of locale-coding-system. * src/xfns.c (struct x_xim_text_conversion_data) (x_xim_text_to_utf8_unix_1, x_xim_text_to_utf8_unix_2) (x_xim_text_to_utf8_unix): Accept dpyinfo. Use the coding system specified inside if possible. (xic_preedit_draw_callback): Pass dpyinfo. * src/xterm.c (handle_one_xevent): Use XIM coding system for IM input. (xim_open_dpy): Try to determine the input method coding system. (mark_xterm): Mark `xim_coding'. (syms_of_xterm): New variable `x-input-coding-system'. * src/xterm.h (struct x_display_info): New field `xim_coding'. (FRAME_X_XIM_CODING): New macro.
Diffstat (limited to 'src')
-rw-r--r--src/coding.c6
-rw-r--r--src/xfns.c33
-rw-r--r--src/xterm.c34
-rw-r--r--src/xterm.h9
4 files changed, 65 insertions, 17 deletions
diff --git a/src/coding.c b/src/coding.c
index 0ae8eb3282b..ab73bda8440 100644
--- a/src/coding.c
+++ b/src/coding.c
@@ -12014,9 +12014,9 @@ See also the function `find-operation-coding-system'. */);
12014 Vnetwork_coding_system_alist = Qnil; 12014 Vnetwork_coding_system_alist = Qnil;
12015 12015
12016 DEFVAR_LISP ("locale-coding-system", Vlocale_coding_system, 12016 DEFVAR_LISP ("locale-coding-system", Vlocale_coding_system,
12017 doc: /* Coding system to use with system messages. 12017 doc: /* Coding system to use with system messages.
12018Also used for decoding keyboard input on X Window system, and for 12018Potentially also used for decoding keyboard input on X Windows, and is
12019encoding standard output and error streams. */); 12019used for encoding standard output and error streams. */);
12020 Vlocale_coding_system = Qnil; 12020 Vlocale_coding_system = Qnil;
12021 12021
12022 /* The eol mnemonics are reset in startup.el system-dependently. */ 12022 /* The eol mnemonics are reset in startup.el system-dependently. */
diff --git a/src/xfns.c b/src/xfns.c
index bb75ca5ad1c..8cea93c6698 100644
--- a/src/xfns.c
+++ b/src/xfns.c
@@ -3354,22 +3354,30 @@ struct x_xim_text_conversion_data
3354{ 3354{
3355 struct coding_system *coding; 3355 struct coding_system *coding;
3356 char *source; 3356 char *source;
3357 struct x_display_info *dpyinfo;
3357}; 3358};
3358 3359
3359static Lisp_Object 3360static Lisp_Object
3360x_xim_text_to_utf8_unix_1 (ptrdiff_t nargs, 3361x_xim_text_to_utf8_unix_1 (ptrdiff_t nargs, Lisp_Object *args)
3361 Lisp_Object *args)
3362{ 3362{
3363 struct x_xim_text_conversion_data *data; 3363 struct x_xim_text_conversion_data *data;
3364 ptrdiff_t nbytes; 3364 ptrdiff_t nbytes;
3365 Lisp_Object coding_system;
3365 3366
3366 data = xmint_pointer (args[0]); 3367 data = xmint_pointer (args[0]);
3368
3369 if (SYMBOLP (Vx_input_coding_system))
3370 coding_system = Vx_input_coding_system;
3371 else if (!NILP (data->dpyinfo->xim_coding))
3372 coding_system = data->dpyinfo->xim_coding;
3373 else
3374 coding_system = Vlocale_coding_system;
3375
3367 nbytes = strlen (data->source); 3376 nbytes = strlen (data->source);
3368 3377
3369 data->coding->destination = NULL; 3378 data->coding->destination = NULL;
3370 3379
3371 setup_coding_system (Vlocale_coding_system, 3380 setup_coding_system (coding_system, data->coding);
3372 data->coding);
3373 data->coding->mode |= (CODING_MODE_LAST_BLOCK 3381 data->coding->mode |= (CODING_MODE_LAST_BLOCK
3374 | CODING_MODE_SAFE_ENCODING); 3382 | CODING_MODE_SAFE_ENCODING);
3375 data->coding->source = (const unsigned char *) data->source; 3383 data->coding->source = (const unsigned char *) data->source;
@@ -3382,8 +3390,7 @@ x_xim_text_to_utf8_unix_1 (ptrdiff_t nargs,
3382} 3390}
3383 3391
3384static Lisp_Object 3392static Lisp_Object
3385x_xim_text_to_utf8_unix_2 (Lisp_Object val, 3393x_xim_text_to_utf8_unix_2 (Lisp_Object val, ptrdiff_t nargs,
3386 ptrdiff_t nargs,
3387 Lisp_Object *args) 3394 Lisp_Object *args)
3388{ 3395{
3389 struct x_xim_text_conversion_data *data; 3396 struct x_xim_text_conversion_data *data;
@@ -3400,7 +3407,8 @@ x_xim_text_to_utf8_unix_2 (Lisp_Object val,
3400 3407
3401/* The string returned is not null-terminated. */ 3408/* The string returned is not null-terminated. */
3402static char * 3409static char *
3403x_xim_text_to_utf8_unix (XIMText *text, ptrdiff_t *length) 3410x_xim_text_to_utf8_unix (struct x_display_info *dpyinfo,
3411 XIMText *text, ptrdiff_t *length)
3404{ 3412{
3405 unsigned char *wchar_buf; 3413 unsigned char *wchar_buf;
3406 ptrdiff_t wchar_actual_length, i; 3414 ptrdiff_t wchar_actual_length, i;
@@ -3424,6 +3432,7 @@ x_xim_text_to_utf8_unix (XIMText *text, ptrdiff_t *length)
3424 3432
3425 data.coding = &coding; 3433 data.coding = &coding;
3426 data.source = text->string.multi_byte; 3434 data.source = text->string.multi_byte;
3435 data.dpyinfo = dpyinfo;
3427 3436
3428 was_waiting_for_input_p = waiting_for_input; 3437 was_waiting_for_input_p = waiting_for_input;
3429 /* Otherwise Fsignal will crash. */ 3438 /* Otherwise Fsignal will crash. */
@@ -3441,18 +3450,21 @@ static void
3441xic_preedit_draw_callback (XIC xic, XPointer client_data, 3450xic_preedit_draw_callback (XIC xic, XPointer client_data,
3442 XIMPreeditDrawCallbackStruct *call_data) 3451 XIMPreeditDrawCallbackStruct *call_data)
3443{ 3452{
3444 struct frame *f = x_xic_to_frame (xic); 3453 struct frame *f;
3445 struct x_output *output; 3454 struct x_output *output;
3446 ptrdiff_t text_length = 0; 3455 ptrdiff_t text_length;
3447 ptrdiff_t charpos; 3456 ptrdiff_t charpos;
3448 ptrdiff_t original_size; 3457 ptrdiff_t original_size;
3449 char *text; 3458 char *text;
3450 char *chg_start, *chg_end; 3459 char *chg_start, *chg_end;
3451 struct input_event ie; 3460 struct input_event ie;
3461
3462 f = x_xic_to_frame (xic);
3452 EVENT_INIT (ie); 3463 EVENT_INIT (ie);
3453 3464
3454 if (f) 3465 if (f)
3455 { 3466 {
3467 text_length = 0;
3456 output = FRAME_X_OUTPUT (f); 3468 output = FRAME_X_OUTPUT (f);
3457 3469
3458 if (!output->preedit_active) 3470 if (!output->preedit_active)
@@ -3460,7 +3472,8 @@ xic_preedit_draw_callback (XIC xic, XPointer client_data,
3460 3472
3461 if (call_data->text) 3473 if (call_data->text)
3462 { 3474 {
3463 text = x_xim_text_to_utf8_unix (call_data->text, &text_length); 3475 text = x_xim_text_to_utf8_unix (FRAME_DISPLAY_INFO (f),
3476 call_data->text, &text_length);
3464 3477
3465 if (!text) 3478 if (!text)
3466 /* Decoding the IM text failed. */ 3479 /* Decoding the IM text failed. */
diff --git a/src/xterm.c b/src/xterm.c
index d83b03d1ca6..42335f0de0e 100644
--- a/src/xterm.c
+++ b/src/xterm.c
@@ -19139,7 +19139,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
19139 &xkey, (char *) copy_bufptr, 19139 &xkey, (char *) copy_bufptr,
19140 copy_bufsiz, &keysym, 19140 copy_bufsiz, &keysym,
19141 &status_return); 19141 &status_return);
19142 coding = Qnil; 19142 coding = FRAME_X_XIM_CODING (f);
19143 if (status_return == XBufferOverflow) 19143 if (status_return == XBufferOverflow)
19144 { 19144 {
19145 copy_bufsiz = nbytes + 1; 19145 copy_bufsiz = nbytes + 1;
@@ -22828,7 +22828,7 @@ handle_one_xevent (struct x_display_info *dpyinfo,
22828 &xkey, (char *) copy_bufptr, 22828 &xkey, (char *) copy_bufptr,
22829 copy_bufsiz, &keysym, 22829 copy_bufsiz, &keysym,
22830 &status_return); 22830 &status_return);
22831 coding = Qnil; 22831 coding = FRAME_X_XIM_CODING (f);
22832 22832
22833 if (status_return == XBufferOverflow) 22833 if (status_return == XBufferOverflow)
22834 { 22834 {
@@ -25488,9 +25488,10 @@ xim_destroy_callback (XIM xim, XPointer client_data, XPointer call_data)
25488static void 25488static void
25489xim_open_dpy (struct x_display_info *dpyinfo, char *resource_name) 25489xim_open_dpy (struct x_display_info *dpyinfo, char *resource_name)
25490{ 25490{
25491#ifdef HAVE_XIM
25491 XIM xim; 25492 XIM xim;
25493 const char *locale;
25492 25494
25493#ifdef HAVE_XIM
25494 if (use_xim) 25495 if (use_xim)
25495 { 25496 {
25496 if (dpyinfo->xim) 25497 if (dpyinfo->xim)
@@ -25513,6 +25514,14 @@ xim_open_dpy (struct x_display_info *dpyinfo, char *resource_name)
25513 destroy.client_data = (XPointer)dpyinfo; 25514 destroy.client_data = (XPointer)dpyinfo;
25514 XSetIMValues (xim, XNDestroyCallback, &destroy, NULL); 25515 XSetIMValues (xim, XNDestroyCallback, &destroy, NULL);
25515#endif 25516#endif
25517
25518 locale = XLocaleOfIM (xim);
25519
25520 /* Now try to determine the coding system that should be
25521 used. locale is in Host Portable Character Encoding, and
25522 as such can be passed to build_string as is. */
25523 dpyinfo->xim_coding = safe_call1 (Vx_input_coding_function,
25524 build_string (locale));
25516 } 25525 }
25517 } 25526 }
25518 25527
@@ -29843,7 +29852,7 @@ mark_xterm (void)
29843 } 29852 }
29844 29853
29845#if defined HAVE_XINPUT2 || defined USE_TOOLKIT_SCROLL_BARS \ 29854#if defined HAVE_XINPUT2 || defined USE_TOOLKIT_SCROLL_BARS \
29846 || defined HAVE_XRANDR || defined USE_GTK 29855 || defined HAVE_XRANDR || defined USE_GTK || defined HAVE_X_I18N
29847 for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next) 29856 for (dpyinfo = x_display_list; dpyinfo; dpyinfo = dpyinfo->next)
29848 { 29857 {
29849#ifdef HAVE_XINPUT2 29858#ifdef HAVE_XINPUT2
@@ -29857,6 +29866,9 @@ mark_xterm (void)
29857#if defined HAVE_XRANDR || defined USE_GTK 29866#if defined HAVE_XRANDR || defined USE_GTK
29858 mark_object (dpyinfo->last_monitor_attributes_list); 29867 mark_object (dpyinfo->last_monitor_attributes_list);
29859#endif 29868#endif
29869#if defined HAVE_X_I18N
29870 mark_object (dpyinfo->xim_coding);
29871#endif
29860 } 29872 }
29861#endif 29873#endif
29862} 29874}
@@ -30385,4 +30397,18 @@ on the same display.
30385In addition, when this variable is a list, only preserve the 30397In addition, when this variable is a list, only preserve the
30386selections whose names are contained within. */); 30398selections whose names are contained within. */);
30387 Vx_auto_preserve_selections = list2 (QCLIPBOARD, QPRIMARY); 30399 Vx_auto_preserve_selections = list2 (QCLIPBOARD, QPRIMARY);
30400
30401 DEFVAR_LISP ("x-input-coding-system", Vx_input_coding_system,
30402 doc: /* Coding system used for input from X input methods.
30403If a symbol and non-nil, this is the coding system that will be used
30404to decode input from X input methods. It does not affect input from
30405GTK native input methods enabled through `x-gtk-use-native-input'. */);
30406 Vx_input_coding_system = Qnil;
30407
30408 DEFVAR_LISP ("x-input-coding-function", Vx_input_coding_function,
30409 doc: /* Function used to determine the coding system used by input methods.
30410It should accept a single argument, a string describing the locale of
30411the input method, and return a coding system that can decode keyboard
30412input generated by said input method. */);
30413 Vx_input_coding_function = Qnil;
30388} 30414}
diff --git a/src/xterm.h b/src/xterm.h
index f3791aa8df9..b68a234faa5 100644
--- a/src/xterm.h
+++ b/src/xterm.h
@@ -580,6 +580,9 @@ struct x_display_info
580 XIMStyles *xim_styles; 580 XIMStyles *xim_styles;
581 struct xim_inst_t *xim_callback_data; 581 struct xim_inst_t *xim_callback_data;
582 XIMStyle preferred_xim_style; 582 XIMStyle preferred_xim_style;
583
584 /* The named coding system to use for this input method. */
585 Lisp_Object xim_coding;
583#endif 586#endif
584 587
585 /* A cache mapping color names to RGB values. */ 588 /* A cache mapping color names to RGB values. */
@@ -1348,6 +1351,12 @@ extern void x_mark_frame_dirty (struct frame *f);
1348#define FRAME_X_XIM_STYLES(f) (FRAME_DISPLAY_INFO (f)->xim_styles) 1351#define FRAME_X_XIM_STYLES(f) (FRAME_DISPLAY_INFO (f)->xim_styles)
1349#define FRAME_XIC_STYLE(f) ((f)->output_data.x->xic_style) 1352#define FRAME_XIC_STYLE(f) ((f)->output_data.x->xic_style)
1350#define FRAME_XIC_FONTSET(f) ((f)->output_data.x->xic_xfs) 1353#define FRAME_XIC_FONTSET(f) ((f)->output_data.x->xic_xfs)
1354#define FRAME_X_XIM_CODING(f) \
1355 (SYMBOLP (Vx_input_coding_system) \
1356 ? Vx_input_coding_system \
1357 : (!NILP (FRAME_DISPLAY_INFO (f)->xim_coding) \
1358 ? FRAME_DISPLAY_INFO(f)->xim_coding \
1359 : Vlocale_coding_system))
1351 1360
1352/* X-specific scroll bar stuff. */ 1361/* X-specific scroll bar stuff. */
1353 1362