diff options
| author | Po Lu | 2022-10-03 20:18:22 +0800 |
|---|---|---|
| committer | Po Lu | 2022-10-03 20:18:37 +0800 |
| commit | da02b9edadbc809b25ac83eccf64089f1cf3b160 (patch) | |
| tree | 084641cd35e268b195b51ba7d09352207c52eb16 /src | |
| parent | e245c4f226979ccb717cccc8f82b2b0a0f96bdac (diff) | |
| download | emacs-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.c | 6 | ||||
| -rw-r--r-- | src/xfns.c | 33 | ||||
| -rw-r--r-- | src/xterm.c | 34 | ||||
| -rw-r--r-- | src/xterm.h | 9 |
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. |
| 12018 | Also used for decoding keyboard input on X Window system, and for | 12018 | Potentially also used for decoding keyboard input on X Windows, and is |
| 12019 | encoding standard output and error streams. */); | 12019 | used 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 | ||
| 3359 | static Lisp_Object | 3360 | static Lisp_Object |
| 3360 | x_xim_text_to_utf8_unix_1 (ptrdiff_t nargs, | 3361 | x_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 | ||
| 3384 | static Lisp_Object | 3392 | static Lisp_Object |
| 3385 | x_xim_text_to_utf8_unix_2 (Lisp_Object val, | 3393 | x_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. */ |
| 3402 | static char * | 3409 | static char * |
| 3403 | x_xim_text_to_utf8_unix (XIMText *text, ptrdiff_t *length) | 3410 | x_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 | |||
| 3441 | xic_preedit_draw_callback (XIC xic, XPointer client_data, | 3450 | xic_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) | |||
| 25488 | static void | 25488 | static void |
| 25489 | xim_open_dpy (struct x_display_info *dpyinfo, char *resource_name) | 25489 | xim_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. | |||
| 30385 | In addition, when this variable is a list, only preserve the | 30397 | In addition, when this variable is a list, only preserve the |
| 30386 | selections whose names are contained within. */); | 30398 | selections 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. | ||
| 30403 | If a symbol and non-nil, this is the coding system that will be used | ||
| 30404 | to decode input from X input methods. It does not affect input from | ||
| 30405 | GTK 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. | ||
| 30410 | It should accept a single argument, a string describing the locale of | ||
| 30411 | the input method, and return a coding system that can decode keyboard | ||
| 30412 | input 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 | ||