Some changes to Unicode input processing

- xrdp is not now built with XRDP_IBUS to allow other input
  methods to be more easily supported.
- chansrv is only aked to start an input method if the client
  supports it.
- chansrv sends a status report back to xrdp when asked to start
  and input method.
- ./configure without --enable-ibus now works.
This commit is contained in:
matt335672 2024-04-26 11:43:18 +01:00 committed by sefler
parent b623766503
commit a2064e51c1
7 changed files with 151 additions and 60 deletions

View File

@ -74,6 +74,15 @@ enum client_resize_mode
CRMODE_MULTI_SCREEN
};
/**
* Type describing Unicode input state
*/
enum unicode_input_state
{
UIS_UNSUPPORTED = 0, ///< Client does not support Unicode
UIS_SUPPORTED, ///< Client supports Unicode, but it's not active
UIS_ACTIVE ///< Unicode input is active
};
/**
* Information about the xrdp client
*
@ -228,6 +237,8 @@ struct xrdp_client_info
// Can we resize the desktop by using a Deactivation-Reactivation Sequence?
enum client_resize_mode client_resize_mode;
enum unicode_input_state unicode_input_support;
};
enum xrdp_encoder_flags

View File

@ -422,6 +422,20 @@ xrdp_caps_process_input(struct xrdp_rdp *self, struct stream *s,
{
self->client_info.use_fast_path &= ~2;
}
// We always advertise Unicode support, so if the client supports it too,
// we can use it
if ((inputFlags & INPUT_FLAG_UNICODE) != 0)
{
self->client_info.unicode_input_support = UIS_SUPPORTED;
LOG(LOG_LEVEL_INFO, "Client supports Unicode input");
}
else
{
self->client_info.unicode_input_support = UIS_UNSUPPORTED;
LOG(LOG_LEVEL_INFO, "Client does not support Unicode input");
}
return 0;
}

View File

@ -38,11 +38,6 @@ if XRDP_RDPSNDAUDIN
AM_CPPFLAGS += -DXRDP_RDPSNDAUDIN
endif
if XRDP_IBUS
AM_CPPFLAGS += -DXRDP_IBUS $(IBUS_CFLAGS) $(GLIB2_CFLAGS)
CHANSRV_EXTRA_LIBS += $(IBUS_LIBS) $(GLIB2_LIBS)
endif
AM_CFLAGS = $(X_CFLAGS)
sbin_PROGRAMS = \
@ -78,11 +73,18 @@ xrdp_chansrv_SOURCES = \
sound.h \
xcommon.c \
xcommon.h \
input_ibus.c \
input.h \
audin.c \
audin.h
if XRDP_IBUS
AM_CPPFLAGS += -DXRDP_IBUS $(IBUS_CFLAGS) $(GLIB2_CFLAGS)
CHANSRV_EXTRA_LIBS += $(IBUS_LIBS) $(GLIB2_LIBS)
xrdp_chansrv_SOURCES += \
input_ibus.c
endif
xrdp_chansrv_LDFLAGS = \
$(X_LIBS)

View File

@ -721,6 +721,26 @@ chansrv_drdynvc_open(const char *name, int flags,
return error;
}
/*****************************************************************************/
/* tell xrdp we can do Unicode input */
static int
chansrv_advertise_unicode_input(int status)
{
struct stream *s = trans_get_out_s(g_con_trans, 8192);
if (s == NULL)
{
return 1;
}
out_uint32_le(s, 0); /* version */
out_uint32_le(s, 8 + 8 + 4);
out_uint32_le(s, 20); /* msg id */
out_uint32_le(s, 8 + 4);
out_uint32_le(s, status);
s_mark_end(s);
return trans_write_copy(g_con_trans);
}
/*****************************************************************************/
/* close call from chansrv */
int
@ -861,7 +881,18 @@ process_message_unicode_data(struct stream *s)
static int
process_message_unicode_setup(struct stream *s)
{
return xrdp_input_unicode_init();
int rv = xrdp_input_unicode_init();
if (rv == 0)
{
// Tell xrdp we can support Unicode input
rv = chansrv_advertise_unicode_input(0);
}
else
{
// Tell xrdp there's a problem starting the framework
chansrv_advertise_unicode_input(2);
}
return rv;
}
/*****************************************************************************/
@ -924,17 +955,25 @@ process_message(void)
case 19: /* drdynvc data */
rv = process_message_drdynvc_data(s);
break;
#ifdef XRDP_IBUS
case 21: /* unicode setup */
#ifdef XRDP_IBUS
rv = process_message_unicode_setup(s);
#else
// We don't support this.
rv = chansrv_advertise_unicode_input(1);
#endif
break;
case 23: /* unicode key event */
#ifdef XRDP_IBUS
rv = process_message_unicode_data(s);
#endif
break;
case 25: /* unicode shut down */
#ifdef XRDP_IBUS
rv = process_message_unicode_shutdown(s);
break;
#endif
break;
default:
LOG_DEVEL(LOG_LEVEL_ERROR, "process_message: unknown msg %d", id);
break;

View File

@ -15,8 +15,7 @@ AM_CPPFLAGS = \
-I$(top_srcdir)/libipm \
-I$(top_srcdir)/libxrdp \
-I$(top_srcdir)/third_party \
-I$(top_srcdir)/third_party/tomlc99 \
$(IBUS_CFLAGS)
-I$(top_srcdir)/third_party/tomlc99
XRDP_EXTRA_LIBS =
@ -38,10 +37,6 @@ AM_CPPFLAGS += -I$(top_srcdir)/libpainter/include
XRDP_EXTRA_LIBS += $(top_builddir)/libpainter/src/.libs/libpainter.a
endif
if XRDP_IBUS
AM_CPPFLAGS += -DXRDP_IBUS
endif
sbin_PROGRAMS = \
xrdp

View File

@ -43,10 +43,8 @@ xrdp_mm_chansrv_connect(struct xrdp_mm *self, const char *port);
static void
xrdp_mm_connect_sm(struct xrdp_mm *self);
#ifdef XRDP_IBUS
static int
xrdp_mm_send_unicode_shutdown(struct xrdp_mm *self, struct trans *trans);
#endif
/*****************************************************************************/
struct xrdp_mm *
@ -151,10 +149,8 @@ xrdp_mm_delete(struct xrdp_mm *self)
return;
}
#ifdef XRDP_IBUS
/* shutdown input method */
xrdp_mm_send_unicode_shutdown(self, self->chan_trans);
#endif
/* free any module stuff */
xrdp_mm_module_cleanup(self);
@ -667,7 +663,6 @@ xrdp_mm_trans_process_channel_data(struct xrdp_mm *self, struct stream *s)
return rv;
}
#ifdef XRDP_IBUS
/*****************************************************************************/
static int
xrdp_mm_send_unicode_shutdown(struct xrdp_mm *self, struct trans *trans)
@ -691,19 +686,28 @@ xrdp_mm_send_unicode_shutdown(struct xrdp_mm *self, struct trans *trans)
static int
xrdp_mm_send_unicode_setup(struct xrdp_mm *self, struct trans *trans)
{
struct stream *s = trans_get_out_s(self->chan_trans, 8192);
if (s == NULL)
int rv = 0;
if (self->wm->client_info->unicode_input_support == UIS_SUPPORTED)
{
return 1;
struct stream *s = trans_get_out_s(self->chan_trans, 8192);
if (s == NULL)
{
rv = 1;
}
else
{
out_uint32_le(s, 0); /* version */
out_uint32_le(s, 8 + 8); /* size */
out_uint32_le(s, 21); /* msg id */
out_uint32_le(s, 8); /* size */
s_mark_end(s);
rv = trans_write_copy(self->chan_trans);
}
}
out_uint32_le(s, 0); /* version */
out_uint32_le(s, 8 + 8); /* size */
out_uint32_le(s, 21); /* msg id */
out_uint32_le(s, 8); /* size */
s_mark_end(s);
return trans_write_copy(self->chan_trans);
return rv;
}
/******************************************************************************/
@ -725,7 +729,6 @@ int xrdp_mm_send_unicode_to_chansrv(struct xrdp_mm *self,
s_mark_end(s);
return trans_write_copy(self->chan_trans);
}
#endif
/*****************************************************************************/
/* returns error
@ -2465,6 +2468,39 @@ xrdp_mm_trans_process_drdynvc_data(struct xrdp_mm *self,
return 0;
}
/*****************************************************************************/
/* Acknowledgement from chansrv that Unicode input is supported
*/
static int
xrdp_mm_trans_process_unicode_ack(struct xrdp_mm *self,
struct stream *s)
{
int status;
if (!s_check_rem(s, 4))
{
return 1;
}
in_uint32_le(s, status);
switch (status)
{
case 0:
LOG(LOG_LEVEL_INFO, "Chansrv is handling Unicode input");
self->wm->client_info->unicode_input_support = UIS_ACTIVE;
break;
case 1:
LOG(LOG_LEVEL_INFO, "Chansrv does not support Unicode input");
break;
default:
LOG(LOG_LEVEL_INFO,
"Chansrv reported an error starting the Unicode input method");
break;
}
return 0;
}
/*****************************************************************************/
/* returns error
process a message for the channel handler */
@ -2517,6 +2553,9 @@ xrdp_mm_chan_process_msg(struct xrdp_mm *self, struct trans *trans,
case 18:
rv = xrdp_mm_trans_process_drdynvc_data(self, s);
break;
case 20:
rv = xrdp_mm_trans_process_unicode_ack(self, s);
default:
LOG(LOG_LEVEL_ERROR, "xrdp_mm_chan_process_msg: unknown id %d", id);
break;
@ -3034,30 +3073,19 @@ xrdp_mm_chansrv_connect(struct xrdp_mm *self, const char *port)
trans_delete(self->chan_trans);
self->chan_trans = NULL;
}
else if (xrdp_mm_send_unicode_setup(self, self->chan_trans) != 0)
{
LOG(LOG_LEVEL_ERROR, "xrdp_mm_chansrv_connect: error in "
"xrdp_mm_send_unicode_setup");
trans_delete(self->chan_trans);
self->chan_trans = NULL;
}
else
{
LOG(LOG_LEVEL_DEBUG, "xrdp_mm_chansrv_connect: chansrv "
"connect successful");
}
#ifdef XRDP_IBUS
/* if client supports unicode input, initialize the input method */
if (1)
{
LOG(LOG_LEVEL_INFO, "xrdp_mm_chansrv_connect: chansrv "
"client support unicode input, init the input method");
if (xrdp_mm_send_unicode_setup(self, self->chan_trans) != 0)
{
LOG(LOG_LEVEL_ERROR, "xrdp_mm_chansrv_connect: error in "
"xrdp_mm_send_unicode_setup");
/* disable unicode input */
// self->wm->client_info->unicode_input = 0;
}
}
#endif
return 0;
}

View File

@ -1722,6 +1722,7 @@ get_unicode_character(struct xrdp_wm *self, int device_flags, char16_t c16)
static int
xrdp_wm_key_unicode(struct xrdp_wm *self, int device_flags, char32_t c16)
{
int index;
char32_t c32 = get_unicode_character(self, device_flags, c16);
if (c32 == 0)
@ -1729,8 +1730,19 @@ xrdp_wm_key_unicode(struct xrdp_wm *self, int device_flags, char32_t c16)
return 0;
}
int index;
// Send the character to chansrv if it's capable of doing something
// with it
if (self->mm->chan_trans != NULL &&
self->client_info->unicode_input_support == UIS_ACTIVE &&
self->mm->chan_trans->status == TRANS_STATUS_UP)
{
xrdp_mm_send_unicode_to_chansrv(self->mm,
!(device_flags & KBD_FLAG_UP), c32);
return 0;
}
// Fallback - see if we can find the character in the existing keymap,
// and if so, generate a normal key event.
for (index = XR_MIN_KEY_CODE; index < XR_MAX_KEY_CODE; index++)
{
if (c32 == self->keymap.keys_noshift[index].chr)
@ -1799,16 +1811,6 @@ xrdp_wm_key_unicode(struct xrdp_wm *self, int device_flags, char32_t c16)
}
}
#ifdef XRDP_IBUS
if (self->mm->chan_trans != NULL &&
self->mm->chan_trans->status == TRANS_STATUS_UP)
{
xrdp_mm_send_unicode_to_chansrv(self->mm,
!(device_flags & KBD_FLAG_UP), c32);
return 0;
}
#endif
return 0;
}