Skip to content

Commit caef223

Browse files
raiden00plAlan Carvalho de Assis
authored andcommitted
Documentation: migrate "CNxConsole Keyboard Input" from wiki
link: https://cwiki.apache.org/confluence/display/NUTTX/CNxConsole+Keyboard+Input
1 parent 200f709 commit caef223

File tree

2 files changed

+139
-0
lines changed

2 files changed

+139
-0
lines changed
Lines changed: 133 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,133 @@
1+
=========================
2+
CNxConsole Keyboard Input
3+
=========================
4+
5+
**Players**
6+
7+
Let's look at the major players in the keyboard data transfer. This is much more
8+
complex than you might initially think:
9+
10+
**Special Drivers**
11+
NxConsole Device. The NX console input comes through a special device driver that
12+
is registered at ``/dev/nxcon0`` as part of early initialization.
13+
14+
**Kernel Threads**
15+
16+
* **NX Server Thread** The NX Server is the graphics server command. It receives
17+
messages from various sources, performs graphics actions, and forwards graphic
18+
event messages to the correct window. Most of the time, the NX Server Thread was
19+
waiting on a message queue to receive the next graphics event.
20+
21+
* **NxConsole Threads** Each NxConsole has a thread that was started when each
22+
``NxWM::CNxConsole`` instance was created by NxWM. Each ``NxWM::CNxConsole``
23+
thread opens the NxConsole driver at ``/dev/nxcon0`` and redirects stdin,
24+
stdout, and stderr to/from that special device. Normally, the ``NxWM::CNxConsole``
25+
thread is stopped, just waiting on read for keyboard input to complete.
26+
27+
**Application Threads**
28+
29+
* **NxWidgets Window Event Handler Thread** ``CNxServer::listener()`` is an
30+
application thread started by NxWidgets each time a new window is opened.
31+
It receives window messages from the NX server and dispatches the messages
32+
accordingly.
33+
34+
* **Keyboard Listener Thread** ``CKeyboard::listener()`` is an application thread
35+
that is started by NxWM. It just listens for keyboard input and forwards it through
36+
the graphics routing system.
37+
38+
Now here is the sequence of events to get keyboard input from the stdin device to
39+
the correct NxConsole.
40+
41+
#. Application Space / NxWidgets Window Event Handler Thread
42+
Let's start with the initial state of the NX Server Thread. Initially, it will
43+
just want for messages from the NX Server.
44+
45+
* ``NxWidgets/libnxwidgets/src/cnxserver.cxx``
46+
``CNxServer::listener()`` is it window listener thread. It just calls
47+
``nx_eventhandler()`` to receive and process server events. There is one
48+
such listener thread per window.
49+
50+
* ``nuttx/libnx/nxwm/nx_eventhandler``
51+
``nx_eventhandler()`` waits to receive a message from the NX server. Each
52+
window has its own message queue; each window instance has its own
53+
``nx_eventhandler()`` waiting for messages.
54+
55+
#. Application Space / Keyboard Listener Thread
56+
57+
Here are the immediate events that happen when the keyboard data is entered.
58+
The Keyboard Listener Thread wakes up and forwards the Keyboard data to the
59+
the NX Server. Only the NX Server knows which window should get the keyboard input.
60+
61+
* ``NxWidgets\nxwm\src\ckeyboard.cxx``
62+
``CKeyboard::listener()`` is a tiny thread that is started by NxWM that just
63+
listens for keyboard input. It opens the keyboard device and waits on a ``read()``
64+
from the keyboard device to receive the next keyboard input. When data is
65+
returned by reading from the keyboard device, ``CKeyboard::listener()``
66+
calls ``nx_kbdin()``
67+
68+
* ``nuttx\libnx\nxmu\nx_kbdin.c``
69+
This library function just hides the NX server messaging implementation.
70+
It sends the ``NX_SVRMSG_KBDIN`` to the NX server thread.
71+
72+
#. Kernel Space / NX Server
73+
74+
The NX Server wakes up, receives the keyboard message, and forwards it to the
75+
appropriate window.
76+
77+
* ``nuttx/graphics/nxmu/nxmu/nxmu_server.c``
78+
The receipt of the ``NX_SVRMSG_KBDIN`` message wakes up the NX server
79+
thread. The NX server thread decodes the message and calls ``nxmu_kbdin()``.
80+
81+
* ``nuttx/graphics/nxconsole/nxmu_kbdin.c``
82+
``nxmu_kbdin()`` simply sends the ``NX_CLIMSG_KBDIN`` to the appropriate
83+
windows client via the client message queue associated with the window.
84+
85+
#. Application Space / NxWidgets Window Event Handler Thread
86+
87+
The Windows client wakes up when the keyboard message is received. It forwards
88+
the keyboard data to ``/dev/nxcon0/`` so that is can be available to the
89+
NxConsole window.
90+
91+
* ``nuttx/libnx/nxwm/nx_eventhandler``
92+
The ``nx_eventhandler()`` logic running in the ``CNxServer::listener()``
93+
thread receives the ``NX_CLIMSG_KBDIN`` message and dispatches it to the
94+
kbdin callback method. In this case that callback method maps to
95+
``CCallback::newKeyboardEvent()``.
96+
97+
* ``NxWidgets/libnxwidgets/src/ccallback.cxx``
98+
For normal keyboard input, ``CCallback::newKeyboardEvent()`` directs the
99+
Keyboard to the widget with focus via the ``CWidgetControl::newKeyboardEvent()``
100+
method. But the story is different for the NxConsole window. This case,
101+
``CCallback::newKeyboardEvent()``, calls ``nxcon_kbdin()``.
102+
103+
* ``nuttx/graphics/nxconsole/nxcon_kbdin.c``
104+
``nxcon_kbdin()`` adds the keyboard data to a circular buffer and wakes up
105+
any reads on the ``/dev/nxcon0`` input device.
106+
107+
108+
NOTE: Here is a violation of the Application and Kernel Space boundaries.
109+
``nxcon_kbdin.c`` built into Kernel Space but it is called from Application
110+
Space. The solution is to (1) move ``nxcon_kbdin()`` to ``libnx/`` and (2) it
111+
should then communicate with the ``/dev/nxcon9`` driver via ioctl calls.
112+
This will become a problem some day.
113+
114+
#. Kernel Space / NxConsole Thread
115+
116+
Finally,
117+
* ``nuttx/graphics/nxconsole/nxcon_kbdin.c``
118+
The receipt and enqueuing of keyboard data by ``nxcon_kbdin()`` wakes up
119+
any threads waiting in the ``nxcon_read()`` method. This is how the
120+
NxConsole gets its keyboard input.
121+
122+
123+
**Mouse Input**
124+
Almost everything said here applies to mouse/touchscreen input as well. If we
125+
were to replace the names keyboard to mouse, kbdin to mousein, etc. you have a
126+
pretty good description of how mouse/touchscreen input works.
127+
128+
The mouse/touchscreen input is a little simpler, however: The main simplication
129+
is that the additional complexities of the NxConsole and its special input device
130+
do not apply. Mouse/touchscreen inut as always steered to widgets when the
131+
callback is received in ``CCallback::newMouseEvent`` by an unconditional call to
132+
``CWidgetControl::newMouseEvent``. There is a "fork in the road" at the
133+
corresponding point in the logic of ``CCallback::newKeyboardEvent``

Documentation/applications/graphics/nxwm/index.rst

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,12 @@ as you want. (keybard input still comes through serial).
2828
Note 1: NwWM requires ``NuttX-7.19`` or above to work with the current
2929
``NxWidgets-1.18`` release.
3030

31+
.. toctree::
32+
:maxdepth: 1
33+
:titlesonly:
34+
:caption: Contents
35+
36+
cnxconsole.rst
3137

3238
Doxygen
3339
-------

0 commit comments

Comments
 (0)