diff options
| author | Po Lu | 2021-11-21 09:22:31 +0800 |
|---|---|---|
| committer | Po Lu | 2021-11-21 09:22:31 +0800 |
| commit | b60c2a5d853b0c6478d7182920c39cb2ec96bdc7 (patch) | |
| tree | a7869c336919a7e2b7c075092f364a6f4b4128cb /src | |
| parent | 64fc94b11e361940c3c7e36f5701ec7ca26b87f4 (diff) | |
| download | emacs-b60c2a5d853b0c6478d7182920c39cb2ec96bdc7.tar.gz emacs-b60c2a5d853b0c6478d7182920c39cb2ec96bdc7.zip | |
Add XInput 2 input method support
* src/xterm.c (handle_one_xevent): Let input methods filter
events first before trying to handle an XI2 key press event.
Diffstat (limited to 'src')
| -rw-r--r-- | src/xterm.c | 145 |
1 files changed, 102 insertions, 43 deletions
diff --git a/src/xterm.c b/src/xterm.c index 9e5aed996ae..6a35b11d054 100644 --- a/src/xterm.c +++ b/src/xterm.c | |||
| @@ -10350,6 +10350,104 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 10350 | = x_x_to_emacs_modifiers (FRAME_DISPLAY_INFO (f), state); | 10350 | = x_x_to_emacs_modifiers (FRAME_DISPLAY_INFO (f), state); |
| 10351 | inev.ie.timestamp = xev->time; | 10351 | inev.ie.timestamp = xev->time; |
| 10352 | 10352 | ||
| 10353 | #ifdef HAVE_X_I18N | ||
| 10354 | XKeyPressedEvent xkey; | ||
| 10355 | |||
| 10356 | memset (&xkey, 0, sizeof xkey); | ||
| 10357 | |||
| 10358 | xkey.type = KeyPress; | ||
| 10359 | xkey.serial = 0; | ||
| 10360 | xkey.send_event = xev->send_event; | ||
| 10361 | xkey.display = xev->display; | ||
| 10362 | xkey.window = xev->event; | ||
| 10363 | xkey.root = xev->root; | ||
| 10364 | xkey.subwindow = xev->child; | ||
| 10365 | xkey.time = xev->time; | ||
| 10366 | xkey.state = state; | ||
| 10367 | xkey.keycode = keycode; | ||
| 10368 | xkey.same_screen = True; | ||
| 10369 | |||
| 10370 | if (x_filter_event (dpyinfo, (XEvent *) &xkey)) | ||
| 10371 | goto xi_done_keysym; | ||
| 10372 | |||
| 10373 | if (FRAME_XIC (f)) | ||
| 10374 | { | ||
| 10375 | Status status_return; | ||
| 10376 | nbytes = XmbLookupString (FRAME_XIC (f), | ||
| 10377 | &xkey, (char *) copy_bufptr, | ||
| 10378 | copy_bufsiz, &keysym, | ||
| 10379 | &status_return); | ||
| 10380 | |||
| 10381 | if (status_return == XBufferOverflow) | ||
| 10382 | { | ||
| 10383 | copy_bufsiz = nbytes + 1; | ||
| 10384 | copy_bufptr = alloca (copy_bufsiz); | ||
| 10385 | nbytes = XmbLookupString (FRAME_XIC (f), | ||
| 10386 | &xkey, (char *) copy_bufptr, | ||
| 10387 | copy_bufsiz, &keysym, | ||
| 10388 | &status_return); | ||
| 10389 | } | ||
| 10390 | |||
| 10391 | if (status_return == XLookupNone) | ||
| 10392 | goto xi_done_keysym; | ||
| 10393 | else if (status_return == XLookupChars) | ||
| 10394 | { | ||
| 10395 | keysym = NoSymbol; | ||
| 10396 | state = 0; | ||
| 10397 | } | ||
| 10398 | else if (status_return != XLookupKeySym | ||
| 10399 | && status_return != XLookupBoth) | ||
| 10400 | emacs_abort (); | ||
| 10401 | } | ||
| 10402 | else | ||
| 10403 | { | ||
| 10404 | #endif | ||
| 10405 | #ifdef HAVE_XKB | ||
| 10406 | int overflow = 0; | ||
| 10407 | KeySym sym = keysym; | ||
| 10408 | |||
| 10409 | if (dpyinfo->xkb_desc) | ||
| 10410 | { | ||
| 10411 | if (!(nbytes = XkbTranslateKeySym (dpyinfo->display, &sym, | ||
| 10412 | state & ~mods_rtrn, copy_bufptr, | ||
| 10413 | copy_bufsiz, &overflow))) | ||
| 10414 | goto XI_OTHER; | ||
| 10415 | } | ||
| 10416 | else | ||
| 10417 | #else | ||
| 10418 | { | ||
| 10419 | block_input (); | ||
| 10420 | char *str = XKeysymToString (keysym); | ||
| 10421 | if (!str) | ||
| 10422 | { | ||
| 10423 | unblock_input (); | ||
| 10424 | goto XI_OTHER; | ||
| 10425 | } | ||
| 10426 | nbytes = strlen (str) + 1; | ||
| 10427 | copy_bufptr = alloca (nbytes); | ||
| 10428 | strcpy (copy_bufptr, str); | ||
| 10429 | unblock_input (); | ||
| 10430 | } | ||
| 10431 | #endif | ||
| 10432 | #ifdef HAVE_XKB | ||
| 10433 | if (overflow) | ||
| 10434 | { | ||
| 10435 | overflow = 0; | ||
| 10436 | copy_bufptr = alloca (copy_bufsiz + overflow); | ||
| 10437 | keysym = sym; | ||
| 10438 | if (!(nbytes = XkbTranslateKeySym (dpyinfo->display, &sym, | ||
| 10439 | state & ~mods_rtrn, copy_bufptr, | ||
| 10440 | copy_bufsiz + overflow, &overflow))) | ||
| 10441 | goto XI_OTHER; | ||
| 10442 | |||
| 10443 | if (overflow) | ||
| 10444 | goto XI_OTHER; | ||
| 10445 | } | ||
| 10446 | #endif | ||
| 10447 | #ifdef HAVE_X_I18N | ||
| 10448 | } | ||
| 10449 | #endif | ||
| 10450 | |||
| 10353 | /* First deal with keysyms which have defined | 10451 | /* First deal with keysyms which have defined |
| 10354 | translations to characters. */ | 10452 | translations to characters. */ |
| 10355 | if (keysym >= 32 && keysym < 128) | 10453 | if (keysym >= 32 && keysym < 128) |
| @@ -10466,49 +10564,6 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 10466 | goto xi_done_keysym; | 10564 | goto xi_done_keysym; |
| 10467 | } | 10565 | } |
| 10468 | 10566 | ||
| 10469 | #ifdef HAVE_XKB | ||
| 10470 | int overflow = 0; | ||
| 10471 | KeySym sym = keysym; | ||
| 10472 | |||
| 10473 | if (dpyinfo->xkb_desc) | ||
| 10474 | { | ||
| 10475 | if (!(nbytes = XkbTranslateKeySym (dpyinfo->display, &sym, | ||
| 10476 | state & ~mods_rtrn, copy_bufptr, | ||
| 10477 | copy_bufsiz, &overflow))) | ||
| 10478 | goto XI_OTHER; | ||
| 10479 | } | ||
| 10480 | else | ||
| 10481 | #else | ||
| 10482 | { | ||
| 10483 | block_input (); | ||
| 10484 | char *str = XKeysymToString (keysym); | ||
| 10485 | if (!str) | ||
| 10486 | { | ||
| 10487 | unblock_input (); | ||
| 10488 | goto XI_OTHER; | ||
| 10489 | } | ||
| 10490 | nbytes = strlen (str) + 1; | ||
| 10491 | copy_bufptr = alloca (nbytes); | ||
| 10492 | strcpy (copy_bufptr, str); | ||
| 10493 | unblock_input (); | ||
| 10494 | } | ||
| 10495 | #endif | ||
| 10496 | #ifdef HAVE_XKB | ||
| 10497 | if (overflow) | ||
| 10498 | { | ||
| 10499 | overflow = 0; | ||
| 10500 | copy_bufptr = alloca (copy_bufsiz + overflow); | ||
| 10501 | keysym = sym; | ||
| 10502 | if (!(nbytes = XkbTranslateKeySym (dpyinfo->display, &sym, | ||
| 10503 | state & ~mods_rtrn, copy_bufptr, | ||
| 10504 | copy_bufsiz + overflow, &overflow))) | ||
| 10505 | goto XI_OTHER; | ||
| 10506 | |||
| 10507 | if (overflow) | ||
| 10508 | goto XI_OTHER; | ||
| 10509 | } | ||
| 10510 | #endif | ||
| 10511 | |||
| 10512 | for (i = 0, nchars = 0; i < nbytes; i++) | 10567 | for (i = 0, nchars = 0; i < nbytes; i++) |
| 10513 | { | 10568 | { |
| 10514 | if (ASCII_CHAR_P (copy_bufptr[i])) | 10569 | if (ASCII_CHAR_P (copy_bufptr[i])) |
| @@ -10574,6 +10629,10 @@ handle_one_xevent (struct x_display_info *dpyinfo, | |||
| 10574 | goto XI_OTHER; | 10629 | goto XI_OTHER; |
| 10575 | } | 10630 | } |
| 10576 | xi_done_keysym: | 10631 | xi_done_keysym: |
| 10632 | #ifdef HAVE_X_I18N | ||
| 10633 | if (FRAME_XIC (f) && (FRAME_XIC_STYLE (f) & XIMStatusArea)) | ||
| 10634 | xic_set_statusarea (f); | ||
| 10635 | #endif | ||
| 10577 | if (must_free_data) | 10636 | if (must_free_data) |
| 10578 | XFreeEventData (dpyinfo->display, &event->xcookie); | 10637 | XFreeEventData (dpyinfo->display, &event->xcookie); |
| 10579 | goto done_keysym; | 10638 | goto done_keysym; |