341N/A###############################################################################
1370N/A# Copyright (c) 2008, 2013, Oracle and/or its affiliates. All rights reserved.
341N/A#
341N/A# Permission is hereby granted, free of charge, to any person obtaining a
919N/A# copy of this software and associated documentation files (the "Software"),
919N/A# to deal in the Software without restriction, including without limitation
919N/A# the rights to use, copy, modify, merge, publish, distribute, sublicense,
919N/A# and/or sell copies of the Software, and to permit persons to whom the
919N/A# Software is furnished to do so, subject to the following conditions:
919N/A#
919N/A# The above copyright notice and this permission notice (including the next
919N/A# paragraph) shall be included in all copies or substantial portions of the
919N/A# Software.
919N/A#
919N/A# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
919N/A# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
919N/A# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL
919N/A# THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
919N/A# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
919N/A# FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
919N/A# DEALINGS IN THE SOFTWARE.
341N/A#
341N/A
341N/A
1233N/Adiff --git a/src/KeyBind.c b/src/KeyBind.c
1370N/Aindex a49de3d..86bd3b6 100644
1233N/A--- a/src/KeyBind.c
1233N/A+++ b/src/KeyBind.c
1233N/A@@ -45,6 +45,7 @@ in this Software without prior written authorization from The Open Group.
341N/A #define XK_VIETNAMESE
341N/A #define XK_XKB_KEYS
1112N/A #define XK_SINHALA
341N/A+#define XK_CURRENCY
341N/A #include <X11/keysymdef.h>
341N/A #include <stdio.h>
341N/A
1233N/A@@ -56,6 +57,20 @@ in this Software without prior written authorization from The Open Group.
341N/A #include "Xresource.h"
341N/A #include "Key.h"
341N/A
341N/A+#ifdef SUNSOFT_KBD
688N/A+/* Sun: compose sequence support
688N/A+ * (state = chars_matched in XComposeStatus)
341N/A+ */
688N/A+#include "Suncompose.h"
688N/A+#include <X11/Sunkeysym.h>
341N/A+#define REJECTED -1
341N/A+#define START 0
341N/A+#define ACCEPTED1 1
341N/A+#define ACCEPTED2 2
341N/A+#define ACCEPTED3 3
341N/A+#define COMPOSE_LED 2
341N/A+#endif /* SUNSOFT_KBD */
341N/A+
341N/A #ifdef XKB
341N/A #include "XKBlib.h"
341N/A #include "XKBlibint.h"
1112N/A@@ -77,6 +92,11 @@ ComputeMaskFromKeytrans(
341N/A Display *dpy,
341N/A register struct _XKeytrans *p);
341N/A
341N/A+#ifdef SUNSOFT_KBD
341N/A+static int DoCompose();
341N/A+ void SetLed (Display *dpy, int num, int state);
341N/A+#endif /* SUNSOFT_KBD */
341N/A+
341N/A struct _XKeytrans {
341N/A struct _XKeytrans *next;/* next on list */
341N/A char *string; /* string to return when the time comes */
1233N/A@@ -98,6 +118,10 @@ KeyCodetoKeySym(register Display *dpy, KeyCode keycode, int col)
341N/A ((int)keycode < dpy->min_keycode) || ((int)keycode > dpy->max_keycode))
341N/A return NoSymbol;
341N/A
688N/A+/* Sun comment: We need not protect dpy->keysyms[], because,
688N/A+ * this is * changed only in the initialize routine and
341N/A+ * XOpenDisplay().
341N/A+ */
341N/A syms = &dpy->keysyms[(keycode - dpy->min_keycode) * per];
341N/A if (col < 4) {
341N/A if (col > 1) {
1112N/A@@ -766,6 +790,9 @@ _XTranslateKey( register Display *dpy,
341N/A int per;
341N/A register KeySym *syms;
341N/A KeySym sym, lsym, usym;
341N/A+#ifdef SUNSOFT_KBD
341N/A+ int i, column, KeypadKey;
341N/A+#endif /* SUNSOFT_KBD */
341N/A
341N/A if ((! dpy->keysyms) && (! _XKeyInitialize(dpy)))
341N/A return 0;
1112N/A@@ -780,17 +807,54 @@ _XTranslateKey( register Display *dpy,
341N/A syms = &dpy->keysyms[(keycode - dpy->min_keycode) * per];
341N/A while ((per > 2) && (syms[per - 1] == NoSymbol))
341N/A per--;
341N/A+
341N/A+#ifdef SUNSOFT_KBD
341N/A+ /* Sun: Japanese keypad support */
341N/A+ KeypadKey = 0;
688N/A+ if (per < 5)
341N/A+ {
688N/A+ /* in case of Hobo keyboards, the keypad would be
688N/A+ * superimposed on the other (qwerty) keys. So by doing
688N/A+ * this * check, we would not get the Japanese keysyms
341N/A+ * on the * Hobo keypad superimposed keys.
341N/A+ */
688N/A+ for (i=0; i < per; i++)
341N/A+ {
341N/A+ if (IsKeypadKey(syms[i]))
341N/A+ KeypadKey = 1;
341N/A+ }
341N/A+ }
341N/A+#endif /* SUNSOFT_KBD */
341N/A+
341N/A if ((per > 2) && (modifiers & dpy->mode_switch)) {
688N/A+#ifdef SUNSOFT_KBD
341N/A+/* Sun: ModeSwitch does not apply to function keys (Japanese kbd) */
341N/A+ if (!KeypadKey)
341N/A+ {
341N/A+#endif /* SUNSOFT_KBD */
341N/A syms += 2;
341N/A per -= 2;
341N/A+#ifdef SUNSOFT_KBD
341N/A+ }
341N/A+#endif /* SUNSOFT_KBD */
341N/A }
341N/A+
688N/A+#ifdef SUNSOFT_KBD
341N/A+ if ((modifiers & dpy->num_lock) &&
341N/A+ (per > 1 && (IsKeypadKey(syms[2]) ))) {
341N/A+#else
341N/A if ((modifiers & dpy->num_lock) &&
341N/A (per > 1 && (IsKeypadKey(syms[1]) || IsPrivateKeypadKey(syms[1])))) {
341N/A+#endif /* SUNSOFT_KBD */
341N/A if ((modifiers & ShiftMask) ||
341N/A ((modifiers & LockMask) && (dpy->lock_meaning == XK_Shift_Lock)))
341N/A *keysym_return = syms[0];
341N/A else
688N/A+#ifdef SUNSOFT_KBD
341N/A+ *keysym_return = syms[2];
341N/A+#else
341N/A *keysym_return = syms[1];
688N/A+#endif /* SUNSOFT_KBD */
341N/A } else if (!(modifiers & ShiftMask) &&
341N/A (!(modifiers & LockMask) || (dpy->lock_meaning == NoSymbol))) {
341N/A if ((per == 1) || (syms[1] == NoSymbol))
1112N/A@@ -818,19 +882,41 @@ _XTranslateKey( register Display *dpy,
341N/A
341N/A int
341N/A _XTranslateKeySym(
341N/A- Display *dpy,
341N/A- register KeySym symbol,
341N/A- unsigned int modifiers,
341N/A- char *buffer,
341N/A- int nbytes)
341N/A+ Display * dpy,
341N/A+#ifdef SUNSOFT_KBD
341N/A+ register KeySym * keysym,
341N/A+#else
341N/A+ register KeySym keysym,
341N/A+#endif
341N/A+ unsigned int modifiers,
341N/A+ char * buffer,
341N/A+ int nbytes
341N/A+#ifdef SUNSOFT_KBD
341N/A+ ,
341N/A+ XKeyEvent * event,
341N/A+ XComposeStatus * status
341N/A+#endif
341N/A+ )
341N/A {
688N/A register struct _XKeytrans *p;
341N/A int length;
341N/A unsigned long hiBytes;
341N/A register unsigned char c;
341N/A-
341N/A+ KeySym symbol;
341N/A+#ifdef SUNSOFT_KBD
341N/A+ int return_val;
341N/A+#endif /* SUNSOFT_KBD */
341N/A+
688N/A+#ifdef SUNSOFT_KBD
341N/A+ if (!keysym)
341N/A+ return 0;
341N/A+ else
341N/A+ symbol = *keysym;
341N/A+#else
341N/A if (!symbol)
341N/A return 0;
341N/A+#endif /* SUNSOFT_KBD */
341N/A+
341N/A /* see if symbol rebound, if so, return that string. */
341N/A for (p = dpy->key_bindings; p; p = p->next) {
341N/A if (((modifiers & AllMods) == p->state) && (symbol == p->key)) {
1112N/A@@ -844,8 +930,29 @@ _XTranslateKeySym(
341N/A hiBytes = symbol >> 8;
341N/A if (!(nbytes &&
341N/A ((hiBytes == 0) ||
341N/A+#ifdef SUNSOFT_KBD
341N/A+/* The check for 0x100500 <= hiBytes < 0x100600 is Sun-specific.
688N/A+ * This represents Sun's registered range of vendor-specific
688N/A+ * keysyms. We need the check so that Sun specific keysyms will
688N/A+ * pass through this check and onto to be handled by
688N/A+ * HandleComposeSequence.
341N/A+ */
341N/A+ ((0x100500 <= hiBytes) && (hiBytes < 0x100600)) ||
341N/A+/*
341N/A+ * The following hard-coded line is to support the euro sign for legacy apps
341N/A+ * and single byte codeset locale apps with the euro sign at 0xa4.
341N/A+ * For any other codeset locales with properly internationalized apps,
341N/A+ * one must have an entry in the Compose file of the locale that will map
341N/A+ * the XK_EuroSign keysym to the correct character code value of the locale's
341N/A+ * codeset.
341N/A+ */
341N/A+ (symbol == XK_EuroSign) ||
341N/A+#endif /* SUNSOFT_KBD */
341N/A ((hiBytes == 0xFF) &&
341N/A (((symbol >= XK_BackSpace) && (symbol <= XK_Clear)) ||
341N/A+#ifdef SUNSOFT_KBD
341N/A+ (symbol == XK_Multi_key) ||
341N/A+#endif /* SUNSOFT_KBD */
341N/A (symbol == XK_Return) ||
341N/A (symbol == XK_Escape) ||
341N/A (symbol == XK_KP_Space) ||
1112N/A@@ -856,15 +963,35 @@ _XTranslateKeySym(
341N/A (symbol == XK_Delete))))))
341N/A return 0;
341N/A
341N/A+#ifdef SUNSOFT_KBD
688N/A+ /* if this is a compose sequence, then HandleComposeSequence
341N/A+ * already deals w/ this. This is Sun-specific.
341N/A+ */
341N/A+ if (HandleComposeSequence(symbol, buffer, keysym, status, &return_val, event)) {
341N/A+ return return_val;
341N/A+ }
341N/A+#endif /* SUNSOFT_KBD */
341N/A+
341N/A /* if X keysym, convert to ascii by grabbing low 7 bits */
341N/A if (symbol == XK_KP_Space)
341N/A c = XK_space & 0x7F; /* patch encoding botch */
341N/A else if (hiBytes == 0xFF)
341N/A c = symbol & 0x7F;
341N/A+#ifdef SUNSOFT_KBD
341N/A+ else if (symbol == XK_EuroSign)
341N/A+ c = (unsigned char)0xa4; /* Latin-9 euro symbol code for legacy apps. */
341N/A+#endif /* SUNSOFT_KBD */
341N/A else
341N/A c = symbol & 0xFF;
341N/A /* only apply Control key if it makes sense, else ignore it */
341N/A if (modifiers & ControlMask) {
341N/A+
341N/A+#ifdef SUNSOFT_KBD
341N/A+ /* Sun: map control characters with high bit set */
341N/A+ if ((c >= (unsigned char)'\300' && c <= (unsigned char)'\377')) c &= 0x9F;
341N/A+#endif /* SUNSOFT_KBD */
341N/A+
341N/A+ /* MIT "standard" control character handling */
341N/A if ((c >= '@' && c < '\177') || c == ' ') c &= 0x1F;
341N/A else if (c == '2') c = '\000';
341N/A else if (c >= '3' && c <= '7') c -= ('3' - '\033');
1112N/A@@ -958,11 +1085,22 @@ XLookupString (
341N/A }
341N/A #endif
341N/A
341N/A+#ifdef SUNSOFT_KBD
341N/A+ if (keysym) {
341N/A+ *keysym = symbol;
341N/A+ return _XTranslateKeySym(event->display, keysym, event->state,
341N/A+ buffer, nbytes, event, status);
341N/A+ } else {
341N/A+ return _XTranslateKeySym(event->display, &symbol, event->state,
341N/A+ buffer, nbytes, event, status);
341N/A+ }
688N/A+#else
341N/A if (keysym)
341N/A *keysym = symbol;
341N/A /* arguable whether to use (event->state & ~modifiers) here */
341N/A return _XTranslateKeySym(event->display, symbol, event->state,
341N/A buffer, nbytes);
341N/A+#endif /* SUNSOFT_KBD */
341N/A }
341N/A
341N/A static void
1370N/A@@ -1074,3 +1212,290 @@ ComputeMaskFromKeytrans(
341N/A }
341N/A p->state &= AllMods;
341N/A }
341N/A+
341N/A+#ifdef SUNSOFT_KBD
341N/A+/* added 2 functions:
341N/A+ * HandleComposeSequence and DoCompose;
341N/A+ */
341N/A+
341N/A+/* Called from XTranslateKeySym & XkbTranslateKeySymExt
688N/A+ * Look at compose sequence and dead key sequence and try to get
688N/A+ * a Latin-1 character out of it. Return 1 if it is able to
688N/A+ * resolve the lookup based on the info it has, return 0 if it
341N/A+ * can't, then XTranslateKeySym needs to do further processing.
341N/A+ */
341N/A+
341N/A+Bool compose_led_is_on = False;
341N/A+int compose_state = START;
341N/A+
341N/A+int
341N/A+HandleComposeSequence(
341N/A+ KeySym symbol,
341N/A+ char *buffer,
341N/A+ KeySym *keysym,
341N/A+ XComposeStatus *status,
341N/A+ int *return_val,
341N/A+ XKeyEvent *event)
341N/A+{
341N/A+ static char compose_sequence[5]; /* initialized to NULL */
341N/A+ static KeyCode last_composed_keycode; /* initialized to NULL */
341N/A+ static KeySym last_composed_keysym; /* initialized to NULL */
341N/A+ static char watching_keypresses = 0;
341N/A+ static int initialized = 0;
341N/A+ int ret_val;
341N/A+
341N/A+ /*
341N/A+ * Even if the caller doesn't pass us a compose structure, we'll still
341N/A+ * support compose sequence processing. Note that the client won't be able
341N/A+ * to support multiple compose sequence clients within a single application.
688N/A+ */
341N/A+
341N/A+ /* must come first */
341N/A+ if (status != (XComposeStatus *) NULL) {
341N/A+ /*
341N/A+ * The caller provided a structure so we'll track his state * (if reasonable) and we'll point him at our private
341N/A+ * compose_sequence (at bottom). This allows him to implement
341N/A+ * multiple compose sequence clients within a single application.
341N/A+ */
341N/A+ if (! initialized) { /* start him out right */
341N/A+ compose_state = START;
341N/A+ initialized = 1;
341N/A+
341N/A+ /* bug 4247009, vivekp, set the compose LED off very first
341N/A+ time, initialization time */
341N/A+ if (compose_led_is_on)
341N/A+ SetLed (event->display,COMPOSE_LED, LedModeOff);
341N/A+
341N/A+ } else { /* then track him */
341N/A+ compose_state = status->chars_matched;
341N/A+ if (compose_state < START || compose_state > ACCEPTED3) compose_state = START;
341N/A+ }
341N/A+ }
688N/A+
341N/A+ /* must come second */
341N/A+ if (event->type == KeyPress) {
341N/A+ /* if we've ever seen a KeyPress, we're watching KeyPresses */
341N/A+ watching_keypresses = 1;
341N/A+ } else if (event->type == KeyRelease && watching_keypresses) {
341N/A+ /*
341N/A+ * don't let someone watching both KeyPresses and KeyReleases
341N/A+ * screw us unwittingly. Try to return the right thing.
341N/A+ */
341N/A+ *return_val = 0;
341N/A+ if (compose_state > START) {
341N/A+ if (compose_state == ACCEPTED3 && event->keycode == last_composed_keycode) {
341N/A+ buffer[0] = last_composed_keysym;
341N/A+ *keysym = last_composed_keysym;
341N/A+ *return_val = 1;
341N/A+ }
341N/A+ return(1);
341N/A+ }
341N/A+ if ((*keysym == XK_Multi_key) ||
341N/A+ (*keysym == SunXK_FA_Circum) ||
341N/A+ (*keysym == SunXK_FA_Tilde) ||
341N/A+ (*keysym == SunXK_FA_Grave) ||
341N/A+ (*keysym == SunXK_FA_Acute) ||
341N/A+ (*keysym == SunXK_FA_Cedilla) ||
341N/A+ (*keysym == SunXK_FA_Diaeresis))
341N/A+ return(1);
341N/A+ return(0);
341N/A+ }
341N/A+
341N/A+ /* XTranslateKeysym filters these out before we get here, but the
341N/A+ * XKB version doesn't so we need to punt these here to avoid breaking
341N/A+ * compose sequences when modifiers like the shift key are pressed.
341N/A+ */
341N/A+ if (IsModifierKey(*keysym)) {
341N/A+ return (0);
341N/A+ }
688N/A+
341N/A+ if (compose_state == ACCEPTED3)
341N/A+ compose_state = START;
688N/A+
341N/A+ /* now we're ready */
341N/A+ switch (compose_state) {
341N/A+ case START:
341N/A+ if (*keysym == XK_Multi_key) {
341N/A+ /* bug 4247009, vivekp, set the compose LED when the
341N/A+ compose key is pressed first time. */
341N/A+ SetLed (event->display,COMPOSE_LED, LedModeOn);
341N/A+ compose_state = ACCEPTED1;
341N/A+ compose_led_is_on = True;
341N/A+ }
341N/A+ else if (*keysym == SunXK_FA_Circum) {
341N/A+ compose_sequence[0] = '^';
341N/A+ compose_state = ACCEPTED2;
341N/A+ }
341N/A+ else if (*keysym == SunXK_FA_Tilde) {
341N/A+ compose_sequence[0] = '~';
341N/A+ compose_state = ACCEPTED2;
341N/A+ }
341N/A+ else if (*keysym == SunXK_FA_Grave) {
341N/A+ compose_sequence[0] = '`';
341N/A+ compose_state = ACCEPTED2;
341N/A+ }
341N/A+ else if (*keysym == SunXK_FA_Acute) {
341N/A+ compose_sequence[0] = '\'';
341N/A+ compose_state = ACCEPTED2;
341N/A+ }
341N/A+ else if (*keysym == SunXK_FA_Cedilla) {
341N/A+ compose_sequence[0] = ',';
341N/A+ compose_state = ACCEPTED2;
341N/A+ }
341N/A+ else if (*keysym == SunXK_FA_Diaeresis){
341N/A+ compose_sequence[0] = '"';
341N/A+ compose_state = ACCEPTED2;
341N/A+ }
341N/A+ /* else don't change state */
341N/A+ break;
688N/A+
688N/A+ case ACCEPTED1: /* Got Compose last time */
341N/A+ if (*keysym < ASCII_SET_SIZE) {
341N/A+ if (compose_map[*keysym] >= 0) {
341N/A+ compose_sequence[0] = *keysym;
341N/A+ compose_state = ACCEPTED2;
341N/A+ }
341N/A+ else
341N/A+ compose_state = REJECTED;
341N/A+ }
341N/A+ else
341N/A+ compose_state = REJECTED;
341N/A+ break;
688N/A+
341N/A+ case ACCEPTED2: /* Got Compose + composable char */
341N/A+
341N/A+ /* bug 4247009, vivekp, set the compose LED off after
341N/A+ compose+composable char is pressed. */
688N/A+ SetLed (event->display,COMPOSE_LED, LedModeOff);
341N/A+ compose_led_is_on = False;
341N/A+ if (*keysym < ASCII_SET_SIZE) {
341N/A+ if (compose_map[*keysym] >= 0) {
341N/A+ compose_sequence[1] = *keysym;
341N/A+/*
341N/A+ * If the second character is space, compose sequence should return * the first character. See TBITS/NCTTI-5, Section 2.1
341N/A+ * Note: <Compose>+<space>+<space> = non-breaking space
341N/A+ */
341N/A+ if (compose_sequence[1] == XK_space &&
341N/A+ compose_sequence[0] != XK_space) {
341N/A+ *keysym = compose_sequence[0];
341N/A+ compose_state = ACCEPTED3;
341N/A+ } else {
341N/A+ if (compose_sequence[0] <= compose_sequence[1])
341N/A+ ret_val = DoCompose(compose_sequence[0],
341N/A+ compose_sequence[1], keysym);
341N/A+ else
341N/A+ ret_val = DoCompose(compose_sequence[1],
341N/A+ compose_sequence[0], keysym);
341N/A+ if (ret_val == 1) {
341N/A+ compose_state = ACCEPTED3;
341N/A+ compose_sequence[2] = *keysym;
341N/A+ }
341N/A+ else
341N/A+ compose_state = REJECTED;
341N/A+ }
341N/A+ }
341N/A+ else
341N/A+ compose_state = REJECTED;
341N/A+ }
341N/A+ else
341N/A+ compose_state = REJECTED;
341N/A+ break;
688N/A+
341N/A+ default:
341N/A+ compose_state = START;
341N/A+ break;
341N/A+ }
688N/A+
341N/A+ if (compose_state == REJECTED)
341N/A+ {
341N/A+ /* bug 4247009, vivekp, set the compose LED off after the
341N/A+ compose key pressed second time or composable + 1st char +
341N/A+ 2nd char. */
341N/A+ SetLed (event->display,COMPOSE_LED, LedModeOff);
341N/A+ compose_led_is_on = False;
341N/A+ compose_state = START;
688N/A+ }
341N/A+ if (status != (XComposeStatus *) NULL) {
341N/A+ /*
341N/A+ * Ok, since the caller provided a compose structure,
341N/A+ * we need to point him at our private compose_sequence
341N/A+ * and copy the new state back to him.
341N/A+ */
341N/A+ status->compose_ptr = compose_sequence;
341N/A+ status->chars_matched = compose_state;
341N/A+ }
688N/A+
341N/A+ if (compose_state == START) {
341N/A+ compose_sequence[0] = '\0';
341N/A+ last_composed_keycode = 0;
341N/A+ last_composed_keysym = 0;
341N/A+ if ((*keysym == XK_Multi_key) ||
341N/A+ (*keysym == SunXK_FA_Circum) ||
341N/A+ (*keysym == SunXK_FA_Tilde) ||
341N/A+ (*keysym == SunXK_FA_Grave) ||
341N/A+ (*keysym == SunXK_FA_Acute) ||
341N/A+ (*keysym == SunXK_FA_Cedilla) ||
341N/A+ (*keysym == SunXK_FA_Diaeresis)) {
341N/A+ *return_val = 0;
341N/A+ return(1);
341N/A+ }
341N/A+ return(0);
341N/A+ }
688N/A+
341N/A+ compose_sequence[compose_state-1] = '\0';
341N/A+ last_composed_keycode = event->keycode;
341N/A+ last_composed_keysym = *keysym;
688N/A+
341N/A+ if (compose_state == ACCEPTED3) {
341N/A+ buffer[0] = *keysym;
341N/A+ *return_val = 1;
341N/A+ }
341N/A+ else {
1294N/A+ if (compose_state == ACCEPTED2) {
1294N/A+ buffer[0] = '\0';
1294N/A+ }
341N/A+ *return_val = 0;
341N/A+ }
688N/A+
341N/A+ return(1);
341N/A+}
688N/A+
341N/A+/*
341N/A+ * DoCompose - put result in keysym
341N/A+ */
341N/A+static int
341N/A+DoCompose(KeySym first_keysym, KeySym second_keysym, KeySym *result_keysym)
341N/A+{
1370N/A+ const ComposeTableEntry *ptr;
341N/A+
341N/A+ /* Note: this code presumes first_keysym rangecheck has
341N/A+ * been done in invoking routine.
341N/A+ */
341N/A+ ptr = &compose_table[compose_map[first_keysym]];
341N/A+ while (ptr->first == first_keysym) {
341N/A+ if (ptr->second == second_keysym) {
341N/A+ *result_keysym = ptr->result;
341N/A+ return (1);
341N/A+ }
341N/A+ ptr++;
341N/A+ }
341N/A+ return (0);
341N/A+}
341N/A+
341N/A+_X_HIDDEN void
341N/A+SetLed (Display *dpy, int num, int state)
341N/A+{
341N/A+ XKeyboardControl led_control;
341N/A+
341N/A+#ifdef XKB
341N/A+ if ((dpy->xkb_info == NULL) || (num != COMPOSE_LED) ||
341N/A+ XkbSetNamedIndicator(dpy,dpy->xkb_info->composeLED,
688N/A+ True,state,False,NULL) == False)
341N/A+#endif
341N/A+ {
341N/A+ led_control.led_mode = state;
341N/A+ led_control.led = num;
341N/A+ XChangeKeyboardControl (dpy, KBLed | KBLedMode, &led_control);
341N/A+ }
341N/A+}
341N/A+#endif /* SUNSOFT_KBD */
1294N/Adiff --git a/src/imConv.c b/src/imConv.c
1370N/Aindex c3c1974..ec8493f 100644
1294N/A--- a/src/imConv.c
1294N/A+++ b/src/imConv.c
1301N/A@@ -213,7 +213,9 @@ _XimLookupMBText(
1294N/A args, 1 ) != 0) {
1294N/A count = 0;
1294N/A } else {
1294N/A- count = nbytes - to_len;
1370N/A+ if (count != 0){
1294N/A+ count = nbytes - to_len;
1294N/A+ }
1294N/A }
1294N/A }
1294N/A }
1301N/A@@ -283,7 +285,9 @@ _XimLookupWCText(
1294N/A args, 1 ) != 0) {
1294N/A count = 0;
1294N/A } else {
1294N/A- count = nbytes - to_len;
1370N/A+ if (count != 0){
1294N/A+ count = nbytes - to_len;
1294N/A+ }
1294N/A }
1294N/A }
1294N/A } else
1301N/A@@ -344,7 +348,9 @@ _XimLookupUTF8Text(
1294N/A NULL, 0) != 0) {
1294N/A count = 0;
1294N/A } else {
1294N/A- count = nbytes - to_len;
1370N/A+ if (count != 0){
1294N/A+ count = nbytes - to_len;
1294N/A+ }
1294N/A }
1294N/A }
1294N/A /* FIXME:
1233N/Adiff --git a/src/xkb/XKBBind.c b/src/xkb/XKBBind.c
1370N/Aindex 29870b5..9e95c02 100644
1233N/A--- a/src/xkb/XKBBind.c
1233N/A+++ b/src/xkb/XKBBind.c
1370N/A@@ -51,6 +51,12 @@ from The Open Group.
1370N/A
1370N/A static int _XkbLoadDpy(Display *dpy);
1233N/A
1233N/A+static int XkbTranslateKeySymExt(
1233N/A+ register Display * dpy, register KeySym *sym_rtrn, unsigned int mods,
1233N/A+ char *buffer, int nbytes, int *extra_rtrn, XKeyEvent *event,
1233N/A+ XComposeStatus *status
1233N/A+);
1233N/A+
1233N/A struct _XKeytrans {
1370N/A struct _XKeytrans *next; /* next on list */
1370N/A char *string; /* string to return when the time comes */
1370N/A@@ -599,6 +605,20 @@ XkbTranslateKeySym(register Display *dpy,
1370N/A int nbytes,
1370N/A int *extra_rtrn)
341N/A {
1370N/A+ /* Call the new extended function but put in NULL for the extra params */
1370N/A+ return XkbTranslateKeySymExt(dpy, sym_rtrn, mods, buffer, nbytes, extra_rtrn, NULL, NULL);
341N/A+}
341N/A+
341N/A+static int
1370N/A+XkbTranslateKeySymExt(register Display *dpy,
1370N/A+ register KeySym *sym_rtrn,
1370N/A+ unsigned int mods,
1370N/A+ char *buffer,
1370N/A+ int nbytes,
1370N/A+ int *extra_rtrn,
1370N/A+ XKeyEvent *event,
1370N/A+ XComposeStatus *status)
341N/A+{
1370N/A register XkbInfoPtr xkb;
341N/A XkbKSToMBFunc cvtr;
341N/A XPointer priv;
1370N/A@@ -641,6 +661,17 @@ XkbTranslateKeySym(register Display *dpy,
341N/A
1370N/A n = (*cvtr) (priv, *sym_rtrn, buffer, nbytes, extra_rtrn);
341N/A
688N/A+ /* Add Suns specific compose key handler here. Be sure the special
688N/A+ * globals are set before calling this function.
341N/A+ */
341N/A+ {
1370N/A+ int return_val;
341N/A+
1370N/A+ if (event && HandleComposeSequence(*sym_rtrn, buffer, sym_rtrn,
1370N/A+ status, &return_val, event))
1370N/A+ return return_val;
341N/A+ }
341N/A+
1370N/A if ((!xkb->cvt.KSToUpper) && (mods & LockMask)) {
1370N/A register int i;
1370N/A int change;
1370N/A@@ -774,9 +805,9 @@ XLookupString(register XKeyEvent *event,
341N/A #endif
1370N/A for (n = len = 0; rtrn.sym[n] != XK_VoidSymbol; n++) {
1370N/A if (nbytes - len > 0) {
1370N/A- len += XkbTranslateKeySym(dpy, &rtrn.sym[n], new_mods,
1370N/A+ len += XkbTranslateKeySymExt(dpy, &rtrn.sym[n], new_mods,
1370N/A buffer + len, nbytes - len,
1370N/A- NULL);
1370N/A+ NULL, event, status);
1370N/A }
1370N/A }
1370N/A if (keysym != NULL) {
1370N/A@@ -804,15 +835,16 @@ XLookupString(register XKeyEvent *event,
1370N/A len = (int) strlen(buffer);
1370N/A }
1370N/A else {
1370N/A- len = XkbTranslateKeySym(dpy, keysym, new_mods,
1370N/A- buffer, nbytes, NULL);
1370N/A+ len = XkbTranslateKeySymExt(dpy, keysym, new_mods,
1370N/A+ buffer, nbytes, NULL,
1370N/A+ event, status);
1370N/A }
1370N/A for (n = 0; rtrn.sym[n] != XK_VoidSymbol; n++) {
1370N/A if (nbytes - len > 0) {
1370N/A- len += XkbTranslateKeySym(dpy, &rtrn.sym[n],
1370N/A+ len += XkbTranslateKeySymExt(dpy, &rtrn.sym[n],
1370N/A event->state,
1370N/A buffer + len, nbytes - len,
1370N/A- NULL);
1370N/A+ NULL, event, status);
1370N/A }
1370N/A }
1370N/A return len;
1370N/A@@ -833,7 +865,8 @@ XLookupString(register XKeyEvent *event,
1370N/A if (rtrnLen > 0)
1370N/A return rtrnLen;
341N/A
1370N/A- return XkbTranslateKeySym(dpy, keysym, new_mods, buffer, nbytes, NULL);
1370N/A+ return XkbTranslateKeySymExt(dpy ,keysym, new_mods, buffer, nbytes, NULL,
1370N/A+ event, status);
341N/A }
341N/A
341N/A
1233N/Adiff --git a/src/xkb/XKBlibint.h b/src/xkb/XKBlibint.h
1370N/Aindex ca7dc0b..70e2475 100644
1233N/A--- a/src/xkb/XKBlibint.h
1233N/A+++ b/src/xkb/XKBlibint.h
1370N/A@@ -169,10 +169,19 @@ extern int _XTranslateKey(
341N/A
1370N/A extern int _XTranslateKeySym(
1370N/A Display * /* dpy */,
341N/A+#ifdef SUNSOFT_KBD
1370N/A+ register KeySym * /* symbol */,
341N/A+#else
1370N/A register KeySym /* symbol */,
688N/A+#endif
1370N/A unsigned int /* modifiers */,
1370N/A char * /* buffer */,
1370N/A int /* nbytes */
341N/A+#ifdef SUNSOFT_KBD
1370N/A+ ,
1370N/A+ XKeyEvent * /* event */,
1370N/A+ XComposeStatus * /* status */
341N/A+#endif
341N/A );
341N/A
1370N/A extern int _XLookupString(
1370N/A@@ -332,6 +341,17 @@ extern Status _XkbReadGetGeometryReply(
341N/A
341N/A #endif
341N/A
341N/A+#ifdef SUNSOFT_KBD
341N/A+extern int HandleComposeSequence(
1370N/A+ KeySym symbol,
1370N/A+ char *buffer,
1370N/A+ KeySym *keysym,
1370N/A+ XComposeStatus *status,
1370N/A+ int *return_val,
1370N/A+ XKeyEvent *event);
341N/A+#endif /* SUNSOFT_KBD */
341N/A+
341N/A+
341N/A _XFUNCPROTOEND
341N/A
341N/A #endif /* _XKBLIBINT_H_ */
1233N/Adiff --git a/src/xlibi18n/ICWrap.c b/src/xlibi18n/ICWrap.c
1370N/Aindex 2a1d0d6..8b445ef 100644
1233N/A--- a/src/xlibi18n/ICWrap.c
1233N/A+++ b/src/xlibi18n/ICWrap.c
1064N/A@@ -67,6 +67,12 @@ from The Open Group.
341N/A #include "Xlibint.h"
341N/A #include "Xlcint.h"
341N/A
341N/A+#ifdef SUNSOFT_KBD
341N/A+#define COMPOSE_LED 2
341N/A+extern void SetLed (Display *dpy, int num, int state);
341N/A+extern int compose_state, compose_led_is_on;
341N/A+#endif
341N/A+
341N/A static int
341N/A _XIMNestedListToNestedList(
341N/A XIMArg *nlist, /* This is the new list */
1064N/A@@ -397,9 +403,23 @@ int
688N/A XmbLookupString(XIC ic, XKeyEvent *ev, char *buffer, int nbytes,
688N/A KeySym *keysym, Status *status)
341N/A {
341N/A- if (ic->core.im)
341N/A- return (*ic->methods->mb_lookup_string) (ic, ev, buffer, nbytes,
341N/A- keysym, status);
341N/A+ if (ic->core.im) {
341N/A+ int ret;
341N/A+ KeySym keysym_temp = NoSymbol;
341N/A+
341N/A+ ret = (*ic->methods->mb_lookup_string) (ic, ev, buffer, nbytes,
341N/A+ &keysym_temp, status);
341N/A+#ifdef SUNSOFT_KBD
341N/A+ if (ev->display->im_filters && !IsModifierKey(keysym_temp) &&
341N/A+ compose_led_is_on && compose_state != 0) {
341N/A+ SetLed (ev->display, COMPOSE_LED, LedModeOff);
341N/A+ compose_led_is_on = False;
341N/A+ }
341N/A+#endif
341N/A+ if (keysym)
341N/A+ *keysym = keysym_temp;
341N/A+ return ret;
341N/A+ }
341N/A return XLookupNone;
341N/A }
341N/A
1064N/A@@ -407,9 +427,23 @@ int
688N/A XwcLookupString(XIC ic, XKeyEvent *ev, wchar_t *buffer, int nchars,
688N/A KeySym *keysym, Status *status)
341N/A {
341N/A- if (ic->core.im)
341N/A- return (*ic->methods->wc_lookup_string) (ic, ev, buffer, nchars,
341N/A- keysym, status);
341N/A+ if (ic->core.im) {
341N/A+ int ret;
341N/A+ KeySym keysym_temp = NoSymbol;
341N/A+
341N/A+ ret = (*ic->methods->wc_lookup_string) (ic, ev, buffer, nchars,
341N/A+ &keysym_temp, status);
341N/A+#ifdef SUNSOFT_KBD
341N/A+ if (ev->display->im_filters && !IsModifierKey(keysym_temp) &&
341N/A+ compose_led_is_on && compose_state != 0) {
341N/A+ SetLed (ev->display, COMPOSE_LED, LedModeOff);
341N/A+ compose_led_is_on = False;
341N/A+ }
341N/A+#endif
341N/A+ if (keysym)
341N/A+ *keysym = keysym_temp;
341N/A+ return ret;
688N/A+ }
341N/A return XLookupNone;
341N/A }
341N/A
1233N/A@@ -418,12 +452,25 @@ Xutf8LookupString(XIC ic, XKeyEvent *ev, char *buffer, int nbytes,
688N/A KeySym *keysym, Status *status)
341N/A {
341N/A if (ic->core.im) {
341N/A+ int ret;
341N/A+ KeySym keysym_temp = NoSymbol;
341N/A+
341N/A if (ic->methods->utf8_lookup_string)
341N/A- return (*ic->methods->utf8_lookup_string) (ic, ev, buffer, nbytes,
341N/A- keysym, status);
341N/A+ ret = (*ic->methods->utf8_lookup_string) (ic, ev, buffer, nbytes,
341N/A+ &keysym_temp, status);
341N/A else if (ic->methods->mb_lookup_string)
341N/A- return (*ic->methods->mb_lookup_string) (ic, ev, buffer, nbytes,
341N/A- keysym, status);
341N/A+ ret = (*ic->methods->mb_lookup_string) (ic, ev, buffer, nbytes,
341N/A+ &keysym_temp, status);
341N/A+#ifdef SUNSOFT_KBD
341N/A+ if (ev->display->im_filters && !IsModifierKey(keysym_temp) &&
341N/A+ compose_led_is_on && compose_state != 0){
341N/A+ SetLed (ev->display, COMPOSE_LED, LedModeOff);
341N/A+ compose_led_is_on = False;
341N/A+ }
341N/A+#endif
341N/A+ if (keysym)
341N/A+ *keysym = keysym_temp;
688N/A+ return ret;
341N/A }
341N/A return XLookupNone;
341N/A }