-
-
Notifications
You must be signed in to change notification settings - Fork 1.7k
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
Support Unicode Keyboard events in xrdp #1990
Comments
Hi @huyifanstar I don't understand what you are trying to do. Are you trying to get a Chinese keyboard mapping working on the xrdp session? Or are you trying to get the whole locale transferred from the client to the server? |
I hope that the Chinese input from the mac client (rdp client) can be transparently transmitted to the remote instance on the mac through the client |
@matt335672 The feature he wants is called "Unicode input" / "Unicode Keyboard Events" that the client sends inputs as Unicode characters rather than scan codes. See also #441. xrdp partially supports it. It is possible to type ASCII characters in Unicode mode but further uses are not supported because the inputs are transmitted from xrdp to Xorg as keystrokes via virtual keyboard. We need to invent direct passing of Unicode characters to Xorg/Xvnc to implemtnt it. Android/iOS RDP clients support it. Also, macOS RDP client support it since last year. It will work like this. RPReplay_Final1631250814.mov |
Convert Unicode characters to Xorg/Xvnc , Is there any way I can configure it to enable support? Thank You |
You didn't read here. |
Thanks for the explanation. @huyifanstar - I'm going to change the title of this issue to reflect @metalefty's comments above. |
Adjusted to Unicode on mac, just tried it, it did not meet expectations Eventually the xrdp server will support Chinese Unicode keyboard events? Thank you! rdp.mov |
Run these commands to generate the keyboard mapping for your chosen input. sudo mv km-00000804.ini /etc/xrdp sudo chown root:root /etc/xrdp/km-00000804.ini sudo service xrdp restart That'all . Enjoy it |
Maybe Xrdp could set km-00000804.ini as default installation |
Where can I get this (km-00000804.ini)? Do I need to make special settings on the client side? Thank You! |
Just run command upon |
Tried but doesn't work. @zsj1029 Did I miss something? |
make sure u have installed Chinese input method Fcitx in your OS first |
@zsj1029 Here is the log. As you can see all keyboard maps has been found. I'm using Fcitx to use WuBi-86 input method too. Would you mind to provide the logs you have successfully enabled? |
root@S0-GPU:/etc/xrdp#xrdp-genkeymap km-00000804.ini How should this be resolved? |
Well, I digged into the code recently. You can't send unicode to remote directly at present because xrdp simply doesn't support it. It does accept unicode input at method "xrdp_wm_key_unicode()" in file "xrdp_wm.c". But it converts it into scan code by comparing the glyphs and invokes "xrdp_wm_key()". The reason xrdp module send scan code is because in the backend xorgxrdp, it simulated a virtual keyboard and uses "xf86PostKeyboardEvent()" to send keys. This function supports scan codes only. I think what @zsj1029 said it can support other keyboard layouts other than en-US. For example, you can type in Greece glyphs or Japanese hiragana with unicode input enabled. It might work because it can be mapped to keys on the board. But you can not input other unicode which is not mapped to keys. For example, the Chinese has more than 10k characters, it's impossible to map them to the keyboard directly. Therfore, a way must be found to support input unicode directly, other than simulating keypresses. As what I said, the "xf86PostKeyboardEvent()" supports scan code only. I don't know which X Window API supports it so I can upgrade the xorgxrdp input driver. @metalefty do you have any idea? |
I'm not as familiar with X11 internals as some of the other developers here, but I suspect the keycode model is too deeply embedded in X11 to implement this, at least with X11 backends. The RFB protocol used by the VNC back end is documented here:- https://github.com/rfbproto/rfbproto/blob/master/rfbproto.rst There's no provision for providing generic Unicode input as keypresses. X11 key events (which are visible to the application) are here. They are keycode dependent:- https://tronche.com/gui/x/xlib/events/keyboard-pointer/keyboard-pointer.html Despite the 'unsigned int' in the above, on the wire, X11 keycodes are only 8 bits, which gives us very limited possibilities:- https://x.org/releases/X11R7.7/doc/xproto/x11protocol.html I'll be very happy to be proved wrong here though, if anyone has better info than I have. |
@matt335672 Okay, thank you. It seems X Server API takes over of hardware abstration only. We can make another way, to take advantage of iBus or Fcitx input method APIs to generate characters. It is centain that we can implement our iBus or Fcitx engine and accepts requests from xorgxrdp to input unicode characters through IPC calls. But this approch is difficult, costly and hard to maintain. I hope there is a way to send requests to iBus directly to generate unicode characters. I'm working on it. |
That sounds doable, @seflerZ but I agree with all of "difficult, costly and hard to maintain". At the moment, the RDP input PDUs are send directly from xrdp to |
Hi, @matt335672 . I found it's much easier than I expected. We can implement a tiny iBus input engine within 100 code lines and use these functions to send unicode characters to iBus.
As for the engine, we can use "ibus_engine_desc_new()" and "ibus_component_add_engine()" APIs to create a temporary one. So the question becomes, where shall we put this implementation, in "xrdp" or "xorgxrdp" module? I think in "xrdp" is more approachable, since "xorgxrdp" is designed for dealing with X Window system. |
It really depends on how the IPC works for ibus. ibus runs on top of glib2, so it probably uses D-Bus, although I'm not sure about this. Neither xrdp or xorgxrdp have a connection to the session D-Bus. I think you'll need to get the data into That's going to be quite fiddly. By all means have a go, but if you'd like a hand let me know what branch of xrdp you're working on. |
I think @matt335672 is right, if you want to talk to ibus, chansrv is the place to do it. There is already some non channel message in chansrv. I think the rail code can send RDP orders for new window or update window for example. I don't think ibus is good for general input. I'll suggest another possibility. If we can map unicode to keysyms we could do something like xdotool. It looks if the keysym is in the current map, if it is, it uses it, if not, it looks for the first free scancode and maps the new keysym to the scancode, uses it, then removes it. |
I agree that iBus is not a general input solution. But if we implement our own input system, we'll need to deal with various window frameworks like Qt\Gtk2.0-4.0\x11\Wayland etcetera. That will be a big project... As for "keysyms", It does map unicode characters to keys on the keyboard. But as I memtioned, some language like Chinese has more than 10k characters (Japanese also use characters origin from Chinese), we must simulate a gaint keyboard with thousands of keys to hold all the unicode characters. It is doable but some what weird though. (Besides, xrdp limited the size of keys to 256 at present.) Of course, it will be great if we can find any simple and elegant approach. |
would be really great to have this implemented, modern clients more and more start to use this as they do not have a keyboard to forward but some touch interface. (using |
I can't see a simple and elegant approach myself I'm afraid:-
If we did implement something in At the same time, if @seflerZ want to try modifying chansrv for prototyping purposes I'm happy to give him a hand. We'll learn more that way about whether a robust solution can be found. |
I had a think about this over the weekend, and had a look at the code myself. It's pretty hard to find your way around it, so I thought I'd put something together quickly to get you started. That way you can focus on the immediate problem rather than worrying about how xrdp is put together. I've implemented a basic method to send unicode input from xrdp to chansrv. Code is here, based on the devel stream:- https://github.com/matt335672/xrdp/tree/initial_ibus_testing This code adds an I've added the relevant libraries to chansrv, so you should be able to expand the code in there and call ibus methods. This is pretty basic and would need more work before it went into production. After you've played with it, we can make it more robust if you think between us we can make something useful. Also, being based in the UK, I can't find a way to test this here. If you have any suggestions, please let me know. |
@matt335672 Thanks. I'm dealing with the iBus now. Got some progresses but also problems. But I think it won't take too much long. |
Hello! Good news. It is basically working now! HnVideoEditor_2024_03_29_001554912.mp4 |
That's great @seflerZ When you've had a bit more time to make sure you're happy with it feel free to raise a PR on my repo. I'll have a look and get my stuff better engineered and then we can put it out for wider review. |
@matt335672 Hi, this feature is almost done. However according to MS-RDPBCGR 2.2.7.1.6 Input Capability Set, there is a flag sent from client named TS_INPUT_CAPABILITYSET to indicate it supports unicode input service. I want to use it as a flag to decide whether the iBus component to be initialized (otherwise resource wasted). I managed to figured out I can add a new attribute named "support_unicode_input" the "struct xrdp_client_info" and set it in "xrdp_caps_process_input" method of "xrdp_caps.c". However when I add the attribute the xorgxrdp seems stopped working and go into black screen. I know the "struct xrdp_client_info" is shared by "xrdp" and "xorgxrdp", but I don't know why it can not be added easily. This may be caused by the "xrdp_client_info" structure is transferred through socks to "xorgxrdp". Would you help me to figure it out? Or we can just do the initialization no matter what the client requests. It works though. |
@seflerZ Did you rebuild xorgxrdp after you added a new attribute to xrdp_client_info with new xrdp_client_info.h? Usually, shared structures contain padding but we didn't add padding so I guess even the simple adding of new attributes may cause a glitch. |
@seflerZ - I had some thoughts on this. I'm really short of time this week, but I saw the workflow going like this:-
That puts the decision as to whether Unicode is supported into chansrv, rather than making it a bit of a mix between chansrv and xrdp. The client info structure is another way to do it of course. I'll happily add more detail when I can. In the meantime, feel free to come back to me about this. |
Yeah, there is not need to transfer the flag to xorgrdp module. I was intend to use the flag to decide whether the iBus will be initialized. Any way, I'll prepare the PR to make my question more clear. |
@matt335672 @seflerZ that might not be sufficient. RDP input capability set is sent by server to client and client to server. |
Thanks @akallabeth At the moment the server always announces Unicode support to the client. If the client then sends Unicode, there's a fallback implementation that reverse-looks up the character in the existing character map. If the character is found, the relevant keypress event is generated. We need this for the login screen, as Unicode support is negotiated before the session is started.
@seflerZ's function is replacing this fallback in the event that chansrv decides it can provide the Unicode character injection directly. |
Hello, everyone. The feature is ready. This is the branch I will raise for PR. I've tested it for two weeks and it works perfectly. For testing, just compile the "xrdp" with "./configure --enable-ibus --enable-fuse" (You need have iBus and lastest xorgxrdp devel branch installed). One of the best benefits of supporting unicode input is, you can use your phone's voice input to input long text by one time. It's just awesome (especially in small screen devices, lol)! Thanks for @matt335672 's help! SVID_20240417_220934_1.mp4Besides, I still have two questions left:
|
Hi @seflerZ In answer to your questions:-
|
|
I'll take 2) first:-
Is it possible to detect this and retry?
I think we need an additional message from chansrv to xrdp to say Unicode input (via ibus/fcitx5/whatever) is supported. When that message is received, xrdp will send any Unicode characters to chansrv. Data flow goes as follows. The first three steps are part of the current v0.9.x implementation
We don't really need to check the client flag for Unicode support. We always set the 'Unicode supported' flag in our initial attributes. We either get Unicode from the client or we don't. What do you think? |
Well, for the first part. I tried to use a loop to retry if ibus_init() resulted not connected but it's very strange that once it returns error no matter how many times you've tried the result won't change, it's not connected. |
The second part looks like this:-
So xrdp doesn't need to know anything other than whether chansrv has asked for Unicode or not. Does that make sense? |
Sorry. I made the wrong order. I'm talking about Q1. That is whether we should have a flag to init ibus input or not. Otherwise the ibus thread will be wasted. Of course, we can always consider the client support unicode input and do fall back if not. In that case, we do not need that flag and Q1 can be resolved.The Q2 is about how to remove the sleep which is necessary now. Because even ibus was installed and properly configured, if we do no sleep when the session is firstly connected, the ibus could not be connected. So if we do fall back here, it does not work as it is expected.
|
OK - I see now. If the client doesn't support ibus, we create a thread we don't use. I agree we should try not do do that. I'm a bit short of time right now, but I'll get a patch to you ASAP. |
Thank you for your contributions. You have provided me with great help.ヾ(≧▽≦*)o However, I have also discovered two bugs.
|
Hi. Not quite sure what do you mean by start a new program but iBus doesn't work. iBus should start with the user session. @poetic-edge
|
@seflerZ In a similar way to "rdesktop -s: shell / seamless application to start remotely," you can achieve the desired functionality. |
@poetic-edge - are you saying that running without a full desktop session is the problem? |
Yes, in this case, ibus will fail. |
I think it is kind of like Remote APP.
|
This might be something we need to fix outside the scope of this PR. When a modern desktop is started on Linux, there's a whole load of @seflerZ - sorry to introduce more delay to this, but I'll be away from my dev. environment for a week or so. When I get back (assuming no emergencies) I want to get this merged into |
I use this bash code, it fixes the issue without full desktop environment. I see no reason for the sleep to be in the c++ code.
|
xrdp: A Remote Desktop Protocol server.
Copyright (C) Jay Sorg 2004-2014
See http://www.xrdp.org for more information.
Version 0.9.5
In the same environment of Chinese and related dependencies, vnc is a device that can bring external Chinese into the remote ubuntu 18.04 system
I currently use the input method in ubuntu, but I hope that the Chinese from the external client can be brought into the ubuntu system
apt install -y language-pack-zh-hans fonts-droid-fallback ttf-wqy-zenhei ttf-wqy-microhei fonts-arphic-ukai fonts-arphic-ukai fonts-arphic-uming
The text was updated successfully, but these errors were encountered: