Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add ibus unicode input support #3058

Merged
merged 21 commits into from
May 20, 2024
Merged
Show file tree
Hide file tree
Changes from 18 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .cirrus.yml
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,11 @@ FreeBSD_task:
freebsd_instance:
image_family: freebsd-13-2
prepare_script:
- pkg install -y $SSL git autoconf automake libtool pkgconf opus jpeg-turbo fdk-aac pixman libX11 libXfixes libXrandr nasm fusefs-libs check imlib2 freetype2 cmocka
- pkg install -y $SSL git autoconf automake libtool pkgconf opus jpeg-turbo fdk-aac pixman libX11 libXfixes libXrandr nasm fusefs-libs check imlib2 freetype2 cmocka ibus
- git submodule update --init --recursive
configure_script:
- ./bootstrap
- env CPPFLAGS=-I/usr/local/include LDFLAGS=-L/usr/local/lib ./configure --localstatedir=/var --enable-strict-locations --with-pkgconfigdir=/usr/local/libdata/pkgconfig --enable-strict-locations --enable-ipv6 --enable-opus --enable-jpeg --enable-fdkaac --enable-painter --enable-pixman --enable-fuse --with-imlib2 --with-freetype2
- env CPPFLAGS=-I/usr/local/include LDFLAGS=-L/usr/local/lib ./configure --localstatedir=/var --enable-strict-locations --with-pkgconfigdir=/usr/local/libdata/pkgconfig --enable-strict-locations --enable-ibus --enable-ipv6 --enable-opus --enable-jpeg --enable-fdkaac --enable-painter --enable-pixman --enable-fuse --with-imlib2 --with-freetype2
build_script:
- make -j $(sysctl -n hw.ncpu || echo 4)
check_script:
Expand Down
14 changes: 7 additions & 7 deletions .github/workflows/build.yml
Original file line number Diff line number Diff line change
Expand Up @@ -111,14 +111,14 @@ jobs:
CONF_FLAGS_amd64_min: "--disable-ipv6 --disable-jpeg --disable-fuse --disable-mp3lame
--disable-fdkaac --disable-opus --disable-rfxcodec --disable-painter
--disable-pixman --disable-utmp"
CONF_FLAGS_amd64_max: "--enable-ipv6 --enable-jpeg --enable-fuse --enable-mp3lame
--enable-fdkaac --enable-opus --enable-rfxcodec --enable-painter
--enable-pixman --enable-utmp
CONF_FLAGS_amd64_max: "--enable-ibus --enable-ipv6 --enable-jpeg --enable-fuse
--enable-mp3lame --enable-fdkaac --enable-opus --enable-rfxcodec
--enable-painter --enable-pixman --enable-utmp
--with-imlib2 --with-freetype2 --enable-tests"
CONF_FLAGS_i386_max: "--enable-ipv6 --enable-jpeg --enable-mp3lame
--enable-opus --enable-rfxcodec --enable-painter
--disable-pixman --with-imlib2 --with-freetype2
--host=i686-linux --enable-tests"
CONF_FLAGS_i386_max: "--enable-ibus --enable-ipv6 --enable-jpeg
--enable-mp3lame --enable-opus --enable-rfxcodec
--enable-painter --disable-pixman --with-imlib2
--with-freetype2 --host=i686-linux --enable-tests"

PKG_CONFIG_PATH_i386: "/usr/lib/i386-linux-gnu/pkgconfig"
CFLAGS_i386: "-m32"
Expand Down
11 changes: 11 additions & 0 deletions common/xrdp_client_info.h
Original file line number Diff line number Diff line change
Expand Up @@ -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
*
Expand Down Expand Up @@ -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
Expand Down
16 changes: 16 additions & 0 deletions configure.ac
Original file line number Diff line number Diff line change
Expand Up @@ -164,6 +164,10 @@ AC_ARG_ENABLE(mp3lame, AS_HELP_STRING([--enable-mp3lame],
[Build lame mp3(audio codec) (default: no)]),
[], [enable_mp3lame=no])
AM_CONDITIONAL(XRDP_MP3LAME, [test x$enable_mp3lame = xyes])
AC_ARG_ENABLE(ibus, AS_HELP_STRING([--enable-ibus],
[Allow unicode input via IBus) (default: no)]),
[], [enable_ibus=no])
AM_CONDITIONAL(XRDP_IBUS, [test x$enable_ibus = xyes])
AC_ARG_ENABLE(pixman, AS_HELP_STRING([--enable-pixman],
[Use pixman library (default: no)]),
[], [enable_pixman=no])
Expand Down Expand Up @@ -472,6 +476,17 @@ then
[AC_MSG_ERROR([please install libmp3lame-dev or lamemp3-devel])])
fi

# checking for ibus includes
if test "x$enable_ibus" = "xyes"
then
PKG_CHECK_MODULES([IBUS], [ibus-1.0 >= 1.5], [],
[AC_MSG_ERROR([please install libibus-1.0-dev or ibus-devel])])

# ibus uses dbus which depends on glib
PKG_CHECK_MODULES([GLIB2], [glib-2.0 >= 2.56], [],
[AC_MSG_ERROR([please install libglib2.0-dev or glib2.0-devel])])
fi

AS_IF( [test "x$enable_pixman" = "xyes"] , [PKG_CHECK_MODULES(PIXMAN, pixman-1 >= 0.1.0)] )

# checking for TurboJPEG
Expand Down Expand Up @@ -646,6 +661,7 @@ echo " fuse $enable_fuse"
echo " ipv6 $enable_ipv6"
echo " ipv6only $enable_ipv6only"
echo " vsock $enable_vsock"
echo " ibus $enable_ibus"
echo " auth mechanism $auth_mech"
echo " rdpsndaudin $enable_rdpsndaudin"
echo " utmp support $enable_utmp"
Expand Down
14 changes: 14 additions & 0 deletions libxrdp/xrdp_caps.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In my client, resizing the window repeatedly triggers the function xrdp_caps_process_input. The original UIS_ACTIVE state is reset to UIS_SUPPORTED, which results in subsequent failure to deliver.

Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks @poetic-edge - that's a good spot.

The way we're currently doing client resizes involves using the RDP Deactivation-Reactivation Sequence

Can you try this patch? I've run out of time today.

--- a/libxrdp/xrdp_caps.c
+++ b/libxrdp/xrdp_caps.c
@@ -424,16 +424,23 @@ xrdp_caps_process_input(struct xrdp_rdp *self, struct stream *s,
     }
 
     // We always advertise Unicode support, so if the client supports it too,
-    // we can use it
-    if ((inputFlags & INPUT_FLAG_UNICODE) != 0)
+    // we can use it.
+    //
+    // If Unicode support is already active, the CAPSTYPE_INPUT
+    // PDU has been received as part of a Deactivation-Reactivation sequence.
+    // In this case, ignore the flag.
+    if (self->client_info.unicode_input_support != UIS_ACTIVE)
     {
-        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");
+        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;

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thank you. It is now functioning properly.

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Okay. I'll apply the patch.

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;
}

Expand Down
2 changes: 2 additions & 0 deletions scripts/install_xrdp_build_dependencies_with_apt.sh
Original file line number Diff line number Diff line change
Expand Up @@ -93,6 +93,7 @@ in
libjpeg-dev \
libmp3lame-dev \
libfdk-aac-dev \
libibus-1.0-dev \
libimlib2-dev \
libopus-dev \
libpixman-1-dev"
Expand All @@ -118,6 +119,7 @@ in
$LIBFREETYPE_DEV:i386 \
libgl1-mesa-dev:i386 \
libglu1-mesa-dev:i386 \
libibus-1.0-dev:i386 \
libjpeg-dev:i386 \
libimlib2-dev:i386 \
libmp3lame-dev:i386 \
Expand Down
9 changes: 9 additions & 0 deletions sesman/chansrv/Makefile.am
Original file line number Diff line number Diff line change
Expand Up @@ -73,9 +73,18 @@ xrdp_chansrv_SOURCES = \
sound.h \
xcommon.c \
xcommon.h \
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)

Expand Down
99 changes: 99 additions & 0 deletions sesman/chansrv/chansrv.c
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,10 @@
#include <config_ac.h>
#endif

#ifdef XRDP_IBUS
#include "input.h"
#endif

#include "arch.h"
#include "os_calls.h"
#include "string_calls.h"
Expand Down Expand Up @@ -717,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
Expand Down Expand Up @@ -823,6 +847,62 @@ chansrv_drdynvc_send_data(int chan_id, const char *data, int data_bytes)
return 0;
}

#ifdef XRDP_IBUS
/*****************************************************************************/
static int
process_message_unicode_data(struct stream *s)
{
int rv = 0;
int key_down;
char32_t unicode;

LOG_DEVEL(LOG_LEVEL_DEBUG, "process_message_unicode_keypress:");
if (!s_check_rem(s, 8))
{
rv = 1;
}
else
{
in_uint32_le(s, key_down);
in_uint32_le(s, unicode);

LOG_DEVEL(LOG_LEVEL_DEBUG, "process_message_unicode_keypress: received unicode %i", unicode);

if (key_down)
{
xrdp_input_send_unicode(unicode);
}
}

return rv;
}

/*****************************************************************************/
static int
process_message_unicode_setup(struct stream *s)
{
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;
}

/*****************************************************************************/
static int
process_message_unicode_shutdown(struct stream *s)
{
return xrdp_input_unicode_destroy();
}
#endif

/*****************************************************************************/
/* returns error */
static int
Expand Down Expand Up @@ -875,6 +955,25 @@ process_message(void)
case 19: /* drdynvc data */
rv = process_message_drdynvc_data(s);
break;
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);
#endif
break;

default:
LOG_DEVEL(LOG_LEVEL_ERROR, "process_message: unknown msg %d", id);
break;
Expand Down
34 changes: 34 additions & 0 deletions sesman/chansrv/input.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
/**
* xrdp: A Remote Desktop Protocol server.
*
* Copyright (C) Jay Sorg 2004-2014
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
#if !defined(INPUT_H)
#define INPUT_H

#include "arch.h"
#include "parse.h"

int
xrdp_input_send_unicode(char32_t unicode);

int
xrdp_input_unicode_init(void);

int
xrdp_input_unicode_destroy(void);

#endif
Loading