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:
parent
b623766503
commit
a2064e51c1
@ -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
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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)
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user