Sign in Join
Wiki copytemporary

Lazarus IDE with Nostromo Keypad on Linux: what changed

Revision 0 to 1. Removed lines have a minus sign; added lines have a plus sign.

Title: Lazarus IDE with Nostromo Keypad on Linux

OldNewLine
1+On occasion, particularly if exploring rarely-visited legacy code, it might be necessary to do an inordinate amount of single stepping. Particularly if afflicted with some degree of RSI, continual use of a PC keyboard's function keys- not to mention obscure control combinations- can become surprisingly uncomfortable.
2+
3+There are many utility programs on both Windows and Linux that map events from various kinds of game controller to the keyboard. However many of these, not to mention hardware solutions like the Logitech G600 gamer's mouse, are unable to generate function key presses and releases qualified by the control key etc. On Linux it is possible instead to map events either at the kernel or at the X11 level, neither is particularly well documented and it is possible to end up- particularly in the X11 case- having to use one program to detect an event and a separate one to emit a keyboard sequence.
4+
5+The example below uses the MXK program <http://welz.org.za/projects/mxk> to map eight buttons from a Belkin Nostromo gamer's keypad <https://softsolder.files.wordpress.com/2013/02/dsc00056-belkin-nostromo-n52-speedpad.jpg> to the key combinations most commonly used during debugging. In addition it has part-coded mappings for the wheel and directional pad, but these have not yet been finalised pending defining local shortcut key combinations.
6+
7+``` bash
8+#!/usr/local/bin/mxk -dp
9+
10+# Experimental mapping from Belkin/Razer Nostromo to Lazarus debugger. For
11+# Debian 12 ("Bookworm") with Linux kernel v6 and later invoke like
12+#
13+# mxk -dp /etc/nostromo-to-lazarus.mxk
14+#
15+# For older versions it might be necessary to invoke like
16+#
17+# mxk -dzp /etc/nostromo-to-lazarus.mxk
18+#
19+# and remove the 'quit' command from the end.
20+#
21+# In either case, terminate by running interactively using mxk -a and
22+# issuing the halt command.
23+#
24+# Refer to http://welz.org.za/projects/mxk/mxk-tutorial.pdf MarkMLl.
25+
26+# The mxk executable can, in fact usefully be a script like
27+#
28+# #!/bin/sh
29+#
30+# /usr/local/bin/mxk-release -u $HOME/.mxk $@
31+#
32+# which will allow it to be run by any member of the input group.
33+
34+# The Nostromo implements two HID devices. The first, which hosts most of the
35+# buttons etc. is a cut-down keyboard supporting EV_KEY, EV_MSC and EV_LED,
36+# the second is basically a scroll wheel supporting EV_KEY, EV_REL and EV_MSC.
37+# Unfortunately there is insufficient information in the device name (as shown
38+# by evtest etc.) and capabilities to be able to distinguish between the two
39+# and there's always the risk of picking up something else entirely; also it's
40+# probably unwise to make any assumptions about which enumerates first so
41+# about all we can do is open both devices and lump the events in together...
42+# fortunately there doesn't appear to be any overlap.
43+
44+# 01 Tab virt1 Run F9
45+# 02 Q virt2 Step into F7
46+# 03 W virt3 Step out Shift + F8
47+# 04 E virt4 Step to cursor F4
48+# 05 R virt5 Stop Ctrl + F2
49+# 06 Caps Lock virt6 Compile Ctrl + F9
50+# 07 A virt7 Build Shift + F9
51+# 08 S virt8 Call stack Ctrl + Alt + S
52+# 09 D virt9 Breakpoints Ctrl + Alt + B
53+# 10 F virt10 Watchpoints Ctrl + Alt + W
54+# 11 Left Shift virt11 Save All Shift + Ctrl + S
55+# 12 Z virt12 Find in Files Ctrl + Shift + F
56+# 13 X virt13 Insert ToDo Ctrl + Shift + T
57+# 14 C virt14 Attach TBD
58+# 15 Space virt15 Step over F8
59+# Pad 12 o'clck Cursor Up virt20 Window back TBD Note arrow marker
60+# Pad 3 o'clock Cursor Right virt21 Window fwds TBD
61+# Pad 6 o'clock Cursor down virt22 Tab back TBD
62+# Pad 9 o'clock Cursor Left virt23 Tab fwds TBD
63+# Wheel Back -1 virt30 Next bookmark TBD
64+# Wheel Fwd +1 virt31 Prev bookmark TBD
65+# Wheel click Middle button virt32
66+# Pad Button Left Alt virt99
67+
68+# The LEDs next to button 15 are blue, red and green (i.e. single-colour rather
69+# then RGB) and indicate one of eight states when controlled by the standard
70+# (Windows-based) software. Together with the backlight brightness they appear
71+# to be managed using USB control messages, i.e. rather than via the HID API.
72+# https://sourceforge.net/projects/nostromodriver/ appears to embed relevant
73+# constants etc.
74+
75+# Note that Lazarus's default Stop Ctrl + F2 clashes with KDE's System Settings
76+# -> Shortcuts -> Global Shortcuts -> System Settings -> Switch to Desktop 2.
77+
78+# The source is identified by a (partial) match of the name, assume that running
79+# more than one Nostromo-branded device on the same system is foolhardy.
80+
81+# Open both sources, assuming that they can't be distinguished reliably by
82+# capabilities etc.
83+
84+name-source 0 Nostromo
85+name-source 1 Nostromo
86+
87+# Wire the two input devices to a first-stage translation which should work
88+# irrespective of the enumeration order and makes sure that none of the
89+# buttons interfere with the primary keyboard and mouse.
90+
91+start-array 0
92+
93+press-array 0 tab virt1/press sync:
94+release-array 0 tab virt1/release sync:
95+
96+press-array 0 q virt2/press sync:
97+release-array 0 q virt2/release sync:
98+
99+press-array 0 w virt3/press sync:
100+release-array 0 w virt3/release sync:
101+
102+press-array 0 e virt4/press sync:
103+release-array 0 e virt4/release sync:
104+
105+press-array 0 r virt5/press sync:
106+release-array 0 r virt5/release sync:
107+
108+press-array 0 capslock virt6/press sync:
109+release-array 0 capslock virt6/release sync:
110+
111+press-array 0 a virt7/press sync:
112+release-array 0 a virt7/release sync:
113+
114+press-array 0 s virt8/press sync:
115+release-array 0 s virt8/release sync:
116+
117+press-array 0 d virt9/press sync:
118+release-array 0 d virt9/release sync:
119+
120+press-array 0 f virt10/press sync:
121+release-array 0 f virt10/release sync:
122+
123+press-array 0 leftshift virt11/press sync:
124+release-array 0 leftshift virt11/release sync:
125+
126+press-array 0 z virt12/press sync:
127+release-array 0 z virt12/release sync:
128+
129+press-array 0 x virt13/press sync:
130+release-array 0 x virt13/release sync:
131+
132+press-array 0 c virt14/press sync:
133+release-array 0 c virt14/release sync:
134+
135+press-array 0 space virt15/press sync:
136+release-array 0 space virt15/release sync:
137+
138+press-array 0 up virt20/press sync:
139+release-array 0 up virt20/release sync:
140+
141+press-array 0 right virt21/press sync:
142+release-array 0 right virt21/release sync:
143+
144+press-array 0 down virt22/press sync:
145+release-array 0 down virt22/release sync:
146+
147+press-array 0 left virt23/press sync:
148+release-array 0 left virt23/release sync:
149+
150+press-array 0 middlebutton virt32/press sync:
151+release-array 0 middlebutton virt32/release sync:
152+
153+press-array 0 leftalt virt99/press sync:
154+release-array 0 leftalt virt99/release sync:
155+
156+start-single 0 relative wheel virt30 virt31
157+
158+# This is the second-stage translation which regenerates keystrokes.
159+# I believe that there's a way of indicating that start-array should
160+# be qualified by a button state but haven't worked out the details,
161+# I haven't put significant effort into sorting out the branch
162+# facility so that two (or possibly more) arrays can be used here,
163+# and I obviously haven't experimented with LED handling (other than
164+# to determine that the kernel's /sys/class/leds facility might not
165+# be relevant).
166+
167+start-array 1
168+
169+press-array 1 virt1 f9/press sync:
170+release-array 1 virt1 f9/release sync:
171+
172+press-array 1 virt2 f7/press sync:
173+release-array 1 virt2 f7/release sync:
174+
175+press-array 1 virt3 leftshift/press f8/press sync:
176+release-array 1 virt3 f8/release leftshift/release sync:
177+
178+press-array 1 virt4 f4/press sync:
179+release-array 1 virt4 f4/release sync:
180+
181+press-array 1 virt5 leftcontrol/press f2/press sync:
182+release-array 1 virt5 f2/release leftcontrol/release sync:
183+
184+press-array 1 virt6 leftcontrol/press f9/press sync:
185+release-array 1 virt6 f9/release leftcontrol/release sync:
186+
187+press-array 1 virt7 leftshift/press f9/press sync:
188+release-array 1 virt7 f9/release leftshift/release sync:
189+
190+press-array 1 virt8 leftcontrol/press leftalt/press s/press sync:
191+release-array 1 virt8 s/release leftalt/release leftcontrol/release sync:
192+
193+press-array 1 virt9 leftcontrol/press leftalt/press b/press sync:
194+release-array 1 virt9 b/release leftalt/release leftcontrol/release sync:
195+
196+press-array 1 virt10 leftcontrol/press leftalt/press w/press sync:
197+release-array 1 virt10 w/release leftalt/release leftcontrol/release sync:
198+
199+press-array 1 virt11 leftcontrol/press leftshift/press s/press sync:
200+release-array 1 virt11 s/release leftshift/release leftcontrol/release sync:
201+
202+press-array 1 virt12 leftcontrol/press leftshift/press f/press sync:
203+release-array 1 virt12 f/release leftshift/release leftcontrol/release sync:
204+
205+press-array 1 virt13 leftcontrol/press leftshift/press t/press sync:
206+release-array 1 virt13 t/release leftshift/release leftcontrol/release sync:
207+
208+# Virt 14 reserved for attach when I work out which keys I want to use
209+
210+press-array 1 virt14 leftcontrol/press leftshift/press t/press sync:
211+release-array 1 virt14 t/release leftshift/release leftcontrol/release sync:
212+
213+press-array 1 virt15 f8/press sync:
214+release-array 1 virt15 f8/release sync:
215+
216+# ... fill in more stuff here
217+
218+# Declare which keys the target may emit, then wire the nodes together.
219+
220+start-target 0 key:f2 key:f4 key:f7 key:f8 key:f9 key:leftshift key:leftcontrol key:leftalt key:b key:f key:s key:t key:w
221+
222+connect-node source:0 array:0
223+connect-node source:0 single:0
224+connect-node source:1 array:0
225+connect-node source:1 single:0
226+connect-node array:0 array:1
227+connect-node single:0 array:1
228+connect-node array:1 target:0
229+lock-source 0
230+
231+quit
232+
233+# This script normally lives at http://wiki.freepascal.org/Lazarus_IDE_with_Nostromo_Keypad_on_Linux
234+```
235+
236+Save that as /etc/nostromo-to-Lazarus.mxk, it may be used both as a script and a configuration file.
237+
238+In principle this could be extended to handle two or more mapping banks controlled by (probably) the button adjacent to the directional pad (virtual key 99), but this is left as an exercise for the reader.
239+
240+With thanks to Neal Stephenson's "Dr. X" for the initial inspiration, and to Marc Welz for help with the fiddly detail.
241+
242+Also see [[Lazarus IDE with Gamepad on Linux]]
243+
244+---
245+*From the Free Pascal wiki, page "Lazarus IDE with Nostromo Keypad on Linux", as it stood on 2024-05-10 after a change by Alextp, out of the wiki's dump of 2024-05-26. Copyright stays with the author who wrote it, according to the old wiki's [[Licensing]] page. If you have concerns about this material, [message the admin](/wiki-contact).*
246+Category: Lazarus

Back to history