+#if !GTK_CHECK_VERSION(2,0,0)
+ /*
+ * In vanilla X, and hence also GDK 1.2, the string received
+ * as part of a keyboard event is assumed to be in
+ * ISO-8859-1. (Seems woefully shortsighted in i18n terms,
+ * but it's true: see the man page for XLookupString(3) for
+ * confirmation.)
+ */
+ output_charset = CS_ISO8859_1;
+ strncpy(output+1, event->string, lenof(output)-1);
+#else
+ /*
+ * Most things can now be passed to
+ * gtk_im_context_filter_keypress without breaking anything
+ * below this point. An exception is the numeric keypad if
+ * we're in Nethack or application mode: the IM will eat
+ * numeric keypad presses if Num Lock is on, but we don't want
+ * it to.
+ */
+ if (app_keypad_mode &&
+ (event->keyval == GDK_Num_Lock ||
+ event->keyval == GDK_KP_Divide ||
+ event->keyval == GDK_KP_Multiply ||
+ event->keyval == GDK_KP_Subtract ||
+ event->keyval == GDK_KP_Add ||
+ event->keyval == GDK_KP_Enter ||
+ event->keyval == GDK_KP_0 ||
+ event->keyval == GDK_KP_Insert ||
+ event->keyval == GDK_KP_1 ||
+ event->keyval == GDK_KP_End ||
+ event->keyval == GDK_KP_2 ||
+ event->keyval == GDK_KP_Down ||
+ event->keyval == GDK_KP_3 ||
+ event->keyval == GDK_KP_Page_Down ||
+ event->keyval == GDK_KP_4 ||
+ event->keyval == GDK_KP_Left ||
+ event->keyval == GDK_KP_5 ||
+ event->keyval == GDK_KP_Begin ||
+ event->keyval == GDK_KP_6 ||
+ event->keyval == GDK_KP_Right ||
+ event->keyval == GDK_KP_7 ||
+ event->keyval == GDK_KP_Home ||
+ event->keyval == GDK_KP_8 ||
+ event->keyval == GDK_KP_Up ||
+ event->keyval == GDK_KP_9 ||
+ event->keyval == GDK_KP_Page_Up ||
+ event->keyval == GDK_KP_Decimal ||
+ event->keyval == GDK_KP_Delete)) {
+ /* app keypad; do nothing */
+ } else if (nethack_mode &&
+ (event->keyval == GDK_KP_1 ||
+ event->keyval == GDK_KP_End ||
+ event->keyval == GDK_KP_2 ||
+ event->keyval == GDK_KP_Down ||
+ event->keyval == GDK_KP_3 ||
+ event->keyval == GDK_KP_Page_Down ||
+ event->keyval == GDK_KP_4 ||
+ event->keyval == GDK_KP_Left ||
+ event->keyval == GDK_KP_5 ||
+ event->keyval == GDK_KP_Begin ||
+ event->keyval == GDK_KP_6 ||
+ event->keyval == GDK_KP_Right ||
+ event->keyval == GDK_KP_7 ||
+ event->keyval == GDK_KP_Home ||
+ event->keyval == GDK_KP_8 ||
+ event->keyval == GDK_KP_Up ||
+ event->keyval == GDK_KP_9 ||
+ event->keyval == GDK_KP_Page_Up)) {
+ /* nethack mode; do nothing */
+ } else {
+ if (gtk_im_context_filter_keypress(inst->imc, event))
+ return TRUE;
+ }
+
+ /*
+ * GDK 2.0 arranges to have done some translation for us: in
+ * GDK 2.0, event->string is encoded in the current locale.
+ *
+ * So we use the standard C library function mbstowcs() to
+ * convert from the current locale into Unicode; from there
+ * we can convert to whatever PuTTY is currently working in.
+ * (In fact I convert straight back to UTF-8 from
+ * wide-character Unicode, for the sake of simplicity: that
+ * way we can still use exactly the same code to manipulate
+ * the string, such as prefixing ESC.)
+ */
+ output_charset = CS_UTF8;
+ {
+ wchar_t widedata[32];
+ const wchar_t *wp;
+ int wlen;
+ int ulen;
+
+ wlen = mb_to_wc(DEFAULT_CODEPAGE, 0,
+ event->string, strlen(event->string),
+ widedata, lenof(widedata)-1);
+
+ wp = widedata;
+ ulen = charset_from_unicode(&wp, &wlen, output+1, lenof(output)-2,
+ CS_UTF8, NULL, NULL, 0);
+ output[1+ulen] = '\0';
+ }
+#endif
+
+ if (!output[1] &&