4

I'm developing application with Qt Embedded and run it in linux framebuffer. I need a way to type non-US characters. Is it possible to change keyboard layout with Qt?

I tried to run it on Qt/X11. Layout switching and input are perfectly fine there. But when I compile it with Qt/Embedded and run it in framebuffer I cannot change layout.

I searched in the documentation and didn't find anything about layout switching.

I think it has something to do with qt keyboard driver as specified at the documentation. It seems that I should develop my own keyboard driver. But I'm using standard keyboard and I think there must be a standard way to change input language?

What would you suggest?

BTW, I'm using 4.5 version. Maybe 4.6 has something to solve this issue?

Exact the same problem here:

http://lists.trolltech.com/pipermail/qt-embedded-interest/2008-August/000034.html

http://lists.trolltech.com/qt-interest/2004-02/msg00570.html

Vanuan
  • 31,770
  • 10
  • 98
  • 102

3 Answers3

7

Version 4.6 has gained keymap support. Solution:

  1. generate kmap file:

    ckbcomp -layout xx > xx.kmap

  2. convert kmap to qmap

    kmap2qmap xx.kmap xx.qmap

  3. load keymap either by

    1. specifying QWS_KEYBOARD environment variable:

      QWS_KEYBOARD="TTY:keymap=xx.qmap"

    2. or loading a keymap dynamically:

      QWSKeyboardHandler * currentKeyboardHandler =
          QKbdDriverFactory::create("TTY", "keymap=foo.qmap");
      

      Make sure that you delete created handler when you create a new one:

      delete currentKeyboardHandler;
      currentKeyboardHandler =
          QKbdDriverFactory::create("TTY", "keymap=bar.qmap");
      

Seems like Qt for Embedded linux is superseeded by Project Lighthouse. Not sure though, if it is production ready, neither I know how does it handle keyboard layout switching.

Update

Qt5 doesn't have QWS and all QWS-related APIs are removed. So you'll need some thirdparty solution. Or write a plugin for QPA.

Vanuan
  • 31,770
  • 10
  • 98
  • 102
  • Is it also possible to "add" the new keymap to the already loaded driver? – arne Dec 16 '11 at 06:29
  • I'm not sure what are you asking for, but if I understood correctly, no. AFAIK, there can be only one keymap per driver. http://qt.gitorious.org/qt/qt/blobs/4.7/src/gui/embedded/qkbd_qws.cpp#line81 – Vanuan Dec 16 '11 at 20:42
  • Yeah, I thought so. I got my stuff to work though, thanks to your answer. – arne Dec 19 '11 at 06:26
  • 1
    May be I will sound like a dumb. ;-)Where should I execute those command? I mean I cant execute them in bash – manmatha.roy May 10 '14 at 11:51
  • 1
    @kernel-maniac Which command? `kmap2qmap` or `ckbcomp`? `ckbcomp` should be a part of your linux distribution. `kmap2qmap` is a part of Qt. – Vanuan May 11 '14 at 03:51
  • Thanks for the explanation! I have one problem though: When I invoke the create function I get this compile-error: undefined reference to `QKbdDriverFactory::create(QString const&, QString const&) I googled a bit and in general the answer to undefined reference stuff always was "add QT += xyz to your pro-file", but even if my problem can be solved this way, I don't know what to add. – Alex Aug 12 '14 at 14:34
  • 1
    @Alex QKbdDriverFactory is a part of QtGui. So, it's `QT += QtGui` – Vanuan Aug 13 '14 at 17:34
  • Thanks, but I already included that one. Is there any other way of using qmap files or are they reserved for Qt for embedded Linux only? Btw: The include statement is Qt += gui, but just to make sure I added Qt += QtGui as well, resulting in the same error. – Alex Aug 15 '14 at 07:12
  • Firstly, project variables are case sensitive, i.e. "QT", not "Qt". Secondly, make sure your version of Qt does have the mentioned API function. It might have been removed. Thirdly, you probably need to learn some basic C++ staff before diving into such specialized topics. – Vanuan Aug 18 '14 at 21:56
  • 1) Oh right, but the case has been correct in my project file. 2) Apparently these functions are only for Qt for Embedded Linux, even though the headers can be found and QtCreator sees the functions as well, only the compiler doesn't. Is there any other way to use qmap files? 3) That was spam. A plain rude (and wrong) assumption without anything to back it up. Also you should learn how to write "stuff". – Alex Aug 19 '14 at 09:03
  • 1
    3) I apologize if I offended you. My assumption was based on that you said you have a compile-error, while it is obviously a link-error. Additionally, it seemed it's the first time you had this error, while it's a pretty common mistake. 2) Of course this is for Embedded Linux! The question states that clearly. And again, it's not a compiler! 4) You don't need qmap files if you're using Qt on desktop, there is an OS support for switching layouts. – Vanuan Aug 19 '14 at 21:28
  • The problem is, we are using Qt on a specialized Linux kernel for a certain hardware and it doesn't have support for switching keyboard layouts (bad subcontractor) so we either have to add this feature to the kernel (a complex task in our case) or Qt has to handle it if possible. Since kmap2qmap is in practically any SDK I assumed that non-embedded systems can somehow use .qmap-files, too, even if the functions above aren't available. Is there any way to do this? – Alex Aug 20 '14 at 08:00
  • Why do you need qmap? Use kmap. Does loadkeys script work? http://linux.about.com/library/cmd/blcmdl1_loadkeys.htm – Vanuan Aug 20 '14 at 08:51
  • No, the shell says "/bin/sh: loadkeys: not found" But I don't mind using either kmap or qmap or maybe an automagically generated QMap<>, generated from either of those file types? – Alex Aug 20 '14 at 14:53
  • Indeed, it seems that you linux kernel lacks kbd module: http://kbd-project.org/ Read this HOWTO to understand what you're missing: http://kbd-project.org/www.win.tue.nl/~aeb/linux/kbd/kbd.html You Haven't answered whether you're using console/framebuffer mode or X11. Linux kernel keyboard support is a complete offtopic. – Vanuan Aug 21 '14 at 08:49
  • Oh, sorry, I don't have a framebuffer plugin and we don't use any server, so no X11 either. We use a board that's described on page 1052 of the following pdf: http://www.atmel.com/images/atmel_6438_32-bit-arm926ej-s-microcontroller_sam9g45_datasheet.pdf Its output is linked to a display. I've crossread the article about the kbd-module and it does what we need, but we can't use GPL-Code. – Alex Aug 21 '14 at 13:44
  • You're already using GPL code by using Linux kernel. And kbd is a part of the kernel. – Vanuan Aug 22 '14 at 05:12
  • Ok, so does this mean that there is no way for us non-embedded users to use kmap or qmap files or change the key mapping in any way unless we install another module to the kernel (or parse a kmap by hand into a huge QMap<>)? – Alex Aug 22 '14 at 14:41
  • Of course! There is no magic! Non-embedded Qt doesn't have keymap support. So you should either use some existing solutions (e.g. kbd module) or implement your own (read keymap files and handle keyboard events). – Vanuan Aug 24 '14 at 08:11
  • It might be also interesting how input is handled in Android https://source.android.com/devices/tech/input/overview.html – Vanuan Aug 24 '14 at 08:15
  • Ok, thanks. I guess we'll try to use Qt Embedded then. – Alex Aug 25 '14 at 12:06
  • Do you know where to find example code? I can't find a tutorial on how to handle the keyboard classes. – Alex Oct 27 '14 at 13:30
  • I'm afraid you are on your own now. – Vanuan Oct 27 '14 at 18:38
3

I need a way to type non-US characters

You can change qmap, but even in Qt 4.8.0 there is no way to switch between US and russian (for example). You need to patch kmap2qmap (add AltGr_Lock support), qkbd_qws.cpp (change testmods according to state of AltGr_Lock). It's looks like no one is used QtEmbedded with keyboard. Or all keeps final patches in secret place.

SeyKo
  • 31
  • 1
0

Can't comment, so this is the answer to

You need to patch kmap2qmap (add AltGr_Lock support), qkbd_qws.cpp (change testmods according to state of AltGr_Lock).

This simple patch to qkbd_qws.cpp enables switch beteewn languages by the CapsLock button.

523,526c523,524
<             //if (d->m_locks[0] /*CapsLock*/ && (m->flags & QWSKeyboard::IsLetter))
<             //    testmods ^= QWSKeyboard::ModShift;
<             if (d->m_locks[0] /*CapsLock*/)
<                 testmods ^= QWSKeyboard::ModAltGr;
---
>             if (d->m_locks[0] /*CapsLock*/ && (m->flags & QWSKeyboard::IsLetter))
>                 testmods ^= QWSKeyboard::ModShift;