102-key Terminal Model M (1394802) on linux

User avatar
Parjánya

29 Nov 2015, 21:04

I've received last friday a 102-key Terminal Model M, most likely assembled in Brazil, and so with an unusual stick on the back stating to be a model 1394802, of which I didn't find much information:
back
back
20151129_161548-menor.jpg (619.38 KiB) Viewed 2569 times
here is the front:
front
front
20151129_161215-menor.jpg (859.96 KiB) Viewed 2569 times
And here is a warranty seal... is it original?
seal
seal
20151129_163924-menor.jpg (507.45 KiB) Viewed 2569 times
Now, I wanted to test if it was working before doing anything else with it. As it has this seal, and I don't have the screw, I didn't open it. I could test using Soarer's converter for instance, but I don't have any appropriate microcontroller around. Also it was friday already and there was no convenient place to buy the stuff.

After some quality time I've managed to build this ungodly thing, using a female-female RJ-45 connector:
rj-45 to ps/2
rj-45 to ps/2
20151129_162034-menor.jpg (864.25 KiB) Viewed 2569 times
I've used a breadboard because I wasn't sure which wire went with whom. Also I'm a linguist, so I'm surprised nothing ended up blowing me to pieces : o ).

First I checked which RJ-45 wire corresponded to which one on the keyboard connector, and then I checked the PS/2 wiring using an Arduino Uno to read it, and plot the reading using the plotter of the arduino framework. One thing to bear in mind is that the idle state on every pin, except the ground of course, is on high.

There is an Arduino library, to read ps/2 events, called PS2Keyboard (http://playground.arduino.cc/Main/PS2Keyboard). It was trivial to use it to read the keyboard once I got the wiring right; since it takes the scancodes set 2 for granted, it doesn't translate everything right, but fiddling with the library can make it output the raw scancodes, specifically on this function:

Code: Select all

static inline uint8_t get_scan_code(void)
{
	uint8_t c, i;

	i = tail;
	if (i == head) return 0;
	i++;
	if (i >= BUFFER_SIZE) i = 0;
	c = buffer[i];
	tail = i;
	//Serial.print(' ');
	//Serial.print(c);
	//Serial.print(' ');

	return c;
}
The commented lines are the ones I've added.

Early in my attempts I had managed to make the kernel complaing about unknown keys, but I have no idea how to reproduce this:

Code: Select all

Nov 27 02:01:35 svar kernel: atkbd_interrupt: 221 callbacks suppressed
Nov 27 02:01:35 svar kernel: atkbd serio0: Spurious NAK on isa0060/serio0. Some program might be trying to access h
Nov 27 02:05:43 svar kernel: input: AT Translated Set 2 keyboard as /devices/platform/i8042/serio0/input/input8140
Nov 27 02:21:28 svar kernel: input: AT Translated Set 2 keyboard as /devices/platform/i8042/serio0/input/input12156
Nov 27 02:32:21 svar kernel: input: AT Translated Set 2 keyboard as /devices/platform/i8042/serio0/input/input14460
Nov 27 02:36:10 svar kernel: atkbd serio0: Unknown key pressed (translated set 2, code 0x64 on isa0060/serio0).
Nov 27 02:36:10 svar kernel: atkbd serio0: Use 'setkeycodes 64 <keycode>' to make it known.
Further digging showed that I could make the keyboard work using some commands in the kernel boot options (http://lightrush.ndoytchev.com/random-1 ... irkoptions), specially appending

Code: Select all

i8042.dumbkbd=1
to it. So far I didn't notice any change using

Code: Select all

i8042.direct=1
.

With this option in the kernel boot I, to my amazement, could log in using my keyboard as normal. It seems it's being used with set 2 scancodes, which is odd...

Code: Select all

# evtest
No device specified, trying to scan all of /dev/input/event*
Available devices:
/dev/input/event0:      AT Raw Set 2 keyboard (with i8042.direct=1)
(...)
That seems very easy to fix, as far as the terminal goes. Things get much uglier on X though: here it works only intermittently. It seems the X server translates the scancodes differently, using some driver. The usual one nowadays is called evdev, an older one is kbd, from the xf86-input-keyboard package. Information on how both work is very scanty, or my google-fu is failing me.

Using evdev the keyboard seldoms registers, and when it does, the key keeps being pressed, as if it didn't register the release scancode. Using kbd it always spits completely random stuff. Something very weird seems to be happening in the scancode translation.

Did anyone go past this? I'll probably just get an USB converter, but it's frustrating to come so close to make the keyboard work by itself.

User avatar
idollar
i$

29 Nov 2015, 21:51

Respect

KRKS

29 Nov 2015, 22:02

Just wondering, would it actually work if you just plugged it into an internet port?

Please wait for somebody who knows this stuff better to confirm it wouldn't do any damage though, I have exactly zero experience with terminal keyboards.

User avatar
scottc

29 Nov 2015, 23:55

No... How could that work?!?

While this is a very commendable effort, it's probably just easier to get a microcontroller based on an AtMega 32u4. You can use a Teensy, Ardnuino Leonardo, Pro Micro, etc etc.
Last edited by scottc on 29 Nov 2015, 23:59, edited 1 time in total.

User avatar
fohat
Elder Messenger

29 Nov 2015, 23:57

It takes a lot more than connecting wires and plugs.

Soarer's Converter probably works great with these, but it takes money and effort.

User avatar
Parjánya

30 Nov 2015, 00:46

@ idollar

Thanks :)

@ KRKS

It wouldn't work : / The wiring is completely different, and the computer wouldn't expect seeing a keyboard where a network should be : o ).

@ scottc & forhat

I fear the only way to fix this would be writing a module to X, so that the translation was done properly. It's really way too much work. I might ask on some linux forums (fora? ; ) ), but I got so few hits searching for people doing this that the likelihood of someone knowing what I am doing and how to help seems too slim :`(.

Even so, I'm surprised I got this far...

The kernel seems to have something to cope with scancodes from set 3, in atkbd.c:

Code: Select all

785 /*
786  * atkbd_select_set checks if a keyboard has a working Set 3 support, and
787  * sets it into that. Unfortunately there are keyboards that can be switched
788  * to Set 3, but don't work well in that (BTC Multimedia ...)
789  */
790 
791 static int atkbd_select_set(struct atkbd *atkbd, int target_set, int allow_extra)
792 {
793         struct ps2dev *ps2dev = &atkbd->ps2dev;
794         unsigned char param[2];
795 
796         atkbd->extra = false;
797 /*
798  * For known special keyboards we can go ahead and set the correct set.
799  * We check for NCD PS/2 Sun, NorthGate OmniKey 101 and
800  * IBM RapidAccess / IBM EzButton / Chicony KBP-8993 keyboards.
801  */
802 
803         if (atkbd->translated)
804                 return 2;
805 
806         if (atkbd->id == 0xaca1) {
807                 param[0] = 3;
808                 ps2_command(ps2dev, param, ATKBD_CMD_SSCANSET);
809                 return 3;
(...)
... but I have no clue on how to trigger this...

User avatar
Parjánya

01 Dec 2015, 14:32

And... I've managed to make it work : ).

There is a python library called evdev (https://github.com/gvalkov/python-evdev) that grabs the kernel events directly. Using the non-translated option in the kernel invocation, I was able to read all key presses and translate them to what I wanted, like this:

Code: Select all

	if this_event == [4, 4, int("0x2d", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_R, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_R, 0)
		output.syn()
The library creates a virtual input device to output these events. Now I can even think of expanding this with pedals, or some leds to show the keyboard states and everything :-D. I'm writing with it now... so far it's behaving nicely : D.

User avatar
idollar
i$

01 Dec 2015, 15:32

May I ask you to summarize how the changes in full ?

I may want to replicate what you have done.

I should improve my statement before: "lot of respect"

User avatar
fohat
Elder Messenger

02 Dec 2015, 01:43

idollar wrote:
I should improve my statement before: "lot of respect"
Same here. I could not have, and would not have, done what you did, but you made it happen. Kudos!

Now, I have a nice NMB terminal with an odd (RJ-14?) connector that I would really like to use, but it does not respond even to Soarer's WYSE Converter .....

orihalcon

02 Dec 2015, 04:57

fohat wrote:
idollar wrote:
I should improve my statement before: "lot of respect"
Same here. I could not have, and would not have, done what you did, but you made it happen. Kudos!

Now, I have a nice NMB terminal with an odd (RJ-14?) connector that I would really like to use, but it does not respond even to Soarer's WYSE Converter .....
Easiest thing to do for that is to wire either the existing matrix or make a new one to a Soarer's Controller or xWhatsit. I would have probably just used a regular PS/2 controller from a different model M for this one, then used a Soarer's Converter with that, but I'm sure it was much more mentally rewarding to figure out existing hardware yourself. Soarer himself would be proud! Fine work indeed!

User avatar
Parjánya

02 Dec 2015, 06:42

@ orihalcon: Thanks :) and I completely agree; this was pure masochism : o ), way too hackish to be generally useful.

@idolar & fohat (hopefully):

I don't know much about wiring to give any decent instructions, but an arduino board connected to either the clock or the data wires should give a clue about if it's working. For instance, with this code:

Code: Select all

int analogPin = 3;     // potentiometer wiper (middle terminal) connected to analog pin 3
int val = 0;           // variable to store the value read
int valold = 0;

void setup()

{
  Serial.begin(9600);          //  setup serial
}

void loop()

{
  val = analogRead(analogPin);    // read the input pin
  //if ( val != valold){
  Serial.println(val);             // debug value
  //valold = val;
  //}
}

Just hooking up the analog 3rd pin to it, you can get graphs like this, using the serial plotter:
Spoiler:
graph
graph
2015-12-02-023823_1278x1048_scrot.png (30.86 KiB) Viewed 2401 times
In this case the x-axis was around 1000 (1000 what...?) with spikes when I pressed anything, that were the clock and the data signals senting information to the computer. This site was very helpful: http://www.computer-engineering.org/ps2protocol/.

Now, having connected the keyboard, one needs to check if it is being recognized by the kernel. On linux every input device is a file named `eventXX` in `/dev/input/`. You can check which is which with the `evtest` command:

Code: Select all

No device specified, trying to scan all of /dev/input/event*
Available devices:
/dev/input/event0:      AT Raw Set 2 keyboard
/dev/input/event1:      Microsoft Basic Optical Mouse
This program also listens to the device events, like this:

Code: Select all

Event: time 1449033008.874522, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70004
Event: time 1449033008.874522, type 1 (EV_KEY), code 30 (KEY_A), value 1
Event: time 1449033008.874522, -------------- SYN_REPORT ------------
Event: time 1449033008.946467, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70004
Event: time 1449033008.946467, type 1 (EV_KEY), code 30 (KEY_A), value 0
Event: time 1449033008.946467, -------------- SYN_REPORT ------------
Event: time 1449033011.570519, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70014
Event: time 1449033011.570519, type 1 (EV_KEY), code 16 (KEY_Q), value 1
Event: time 1449033011.570519, -------------- SYN_REPORT ------------
Event: time 1449033011.642508, type 4 (EV_MSC), code 4 (MSC_SCAN), value 70014
Event: time 1449033011.642508, type 1 (EV_KEY), code 16 (KEY_Q), value 0
Event: time 1449033011.642508, -------------- SYN_REPORT ------------
This is my PS/2 keyboard. Note the "code" part, saying that code 16 is being translated to KEY_Q, and code 30 to KEY_A; these codes are being shown in hexadecimal. "Value" 0 signals a key was released, value 1 that it was pressed, and value 2 that it's being holded down.

My terminal keyboard doesn't generate any hold signals, and only the value 1 ones for most keys, and the same event value both for when I press a key and when I release it; I'm not sure this is how it should be. This will be a problem below : o ).

Now, to translate the scancodes into keypresses, as I said, I've used the evdev Python library. It's straightforward: you declare the input you will listen to, then open a virtual device to output what you want, and then start reading the input in a loop:

Code: Select all

#! /usr/bin/python3

import evdev

modelm = evdev.InputDevice('/dev/input/event0')
modelm.grab() # this makes the output go to our script only

output = evdev.UInput()


for event in modelm.read_loop():
	this_event = [event.type, event.code, event.value]
The only thing to do is to tell the script what to do and when. For instance:

Code: Select all

	if this_event == [4, 4, int("0x08", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_ESC, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_ESC, 0)
		output.syn()
The "this_event" is a list with three items: the event type, the code, and the value, as I declared in the end of the last snippet. If the event the script receives is this one, the script outputs the ESC key being pressed (with value 1) and then released. Finaly it sends everything in one go by synchronizing the events with the virtual input. This way of dealing with a single scancode for the key might cause problems in any key one needs to *hold* for it to work... this would force me to write some trick to infer when the key is still being pressed, perhaps based on the timing of the event.

A trick I already had to do was with the ALT keys. They generate just one scancode, but for key combinations like alt+a to work, alt needs to still be in the pressed state when the A key gets pressed to. This is what I came out with:

Code: Select all

	if this_event == [4, 4, int("0x19", 0)]:
		try:
			if leftalt == 1:
				leftalt = 0
				output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_LEFTALT, 0)
			else:
				leftalt = 1
				output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_LEFTALT, 1)
		except:
			leftalt = 1
			output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_LEFTALT, 1)
		output.syn()
Python breaks the code, throws an exception, when you refer to any variable that doesn't exist. So I wrote this: if the event has the LEFTALT scancode, it tries to check if it has been pressed... in which case leftalt is set to 1. If this is set, it means there was already another event to press it down (value 1), and so it outputs the release event (value 0). If this variable is set, but not to 1, then it's been pressed down, and we send that signal (value 1). Finally, if this variable isn't set already... that is the exception that could break the code, and it means we didn't press it down yet, so we send the press down signal too (value 1). I've attached the code I'm running now... PM me if you wish :). Comments on it are welcome... I wrote it in just an hour, it's bound to be ugly.

I hope this might be useful. Today was a very long day, and English isn't my first language...

Code: Select all

#! /usr/bin/python3

import evdev

modelm = evdev.InputDevice('/dev/input/event0')
modelm.grab()

output = evdev.UInput()


for event in modelm.read_loop():

	#print(dir(event))

	this_event = [event.type, event.code, event.value]
	#print(this_event)

# 1 ­ down
# 2 - hold
# 0 - up


######################################################################
######################################################################

# hack to make alt+anything work

#	try:
#		if leftalt == 1:
#			output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_LEFTALT, 2)
#	except:
#		pass
#
#	try:
#		if rightalt == 1:
#			output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_RIGHTALT, 2)
#	except:
#		pass

######################################################################
#
# first row
#
######################################################################

	if this_event == [4, 4, int("0x08", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_ESC, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_ESC, 0)
		output.syn()

	if this_event == [4, 4, int("0x07", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_F1, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_F1, 0)
		output.syn()

	if this_event == [4, 4, int("0x0f", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_F2, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_F2, 0)
		output.syn()

	if this_event == [4, 4, int("0x17", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_F3, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_F3, 0)
		output.syn()

	if this_event == [4, 4, int("0x1f", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_F4, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_F4, 0)
		output.syn()

	if this_event == [4, 4, int("0x27", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_F5, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_F5, 0)
		output.syn()

	if this_event == [4, 4, int("0x2f", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_F6, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_F6, 0)
		output.syn()

	if this_event == [4, 4, int("0x37", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_F7, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_F7, 0)
		output.syn()

	if this_event == [4, 4, int("0x3f", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_F8, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_F8, 0)
		output.syn()

	if this_event == [4, 4, int("0x47", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_F9, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_F9, 0)
		output.syn()

	if this_event == [4, 4, int("0x4f", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_F10, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_F10, 0)
		output.syn()

	if this_event == [4, 4, int("0x56", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_F11, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_F11, 0)
		output.syn()

	if this_event == [4, 4, int("0x5e", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_F12, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_F12, 0)
		output.syn()

	if this_event == [4, 4, int("0x57", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_SYSRQ, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_SYSRQ, 0)
		output.syn()

	if this_event == [4, 4, int("0x5f", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_SCROLLLOCK, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_SCROLLLOCK, 0)
		output.syn()

	if this_event == [4, 4, int("0x62", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_PAUSE, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_PAUSE, 0)
		output.syn()


######################################################################
#
# second row
#
######################################################################

	if this_event == [4, 4, int("0x0e", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_GRAVE, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_GRAVE, 0)
		output.syn()

	if this_event == [4, 4, int("0x16", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_1, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_1, 0)
		output.syn()

	if this_event == [4, 4, int("0x1e", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_2, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_2, 0)
		output.syn()

	if this_event == [4, 4, int("0x26", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_3, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_3, 0)
		output.syn()

	if this_event == [4, 4, int("0x25", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_4, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_4, 0)
		output.syn()

	if this_event == [4, 4, int("0x2e", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_5, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_5, 0)
		output.syn()

	if this_event == [4, 4, int("0x36", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_6, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_6, 0)
		output.syn()

	if this_event == [4, 4, int("0x3d", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_7, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_7, 0)
		output.syn()

	if this_event == [4, 4, int("0x3e", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_8, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_8, 0)
		output.syn()

	if this_event == [4, 4, int("0x46", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_9, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_9, 0)
		output.syn()

	if this_event == [4, 4, int("0x45", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_0, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_0, 0)
		output.syn()

	if this_event == [4, 4, int("0x4e", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_MINUS, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_MINUS, 0)
		output.syn()

	if this_event == [4, 4, int("0x55", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_EQUAL, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_EQUAL, 0)
		output.syn()

	if this_event == [4, 4, int("0x66", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_BACKSPACE, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_BACKSPACE, 0)
		output.syn()

	if this_event == [4, 4, int("0x67", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_INSERT, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_INSERT, 0)
		output.syn()

	if this_event == [4, 4, int("0x6e", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_HOME, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_HOME, 0)
		output.syn()

	if this_event == [4, 4, int("0x6f", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_PAGEUP, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_PAGEUP, 0)
		output.syn()

	if this_event == [4, 4, int("0x76", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_NUMLOCK, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_NUMLOCK, 0)
		output.syn()

	if this_event == [4, 4, int("0x77", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_KPSLASH, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_KPSLASH, 0)
		output.syn()

	if this_event == [4, 4, int("0x7e", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_KPASTERISK, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_KPASTERISK, 0)
		output.syn()

	if this_event == [4, 4, int("0x104", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_KPMINUS, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_KPMINUS, 0)
		output.syn()

######################################################################
#
# third row
#
######################################################################

	if this_event == [4, 4, int("0x0d", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_TAB, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_TAB, 0)
		output.syn()

	if this_event == [4, 4, int("0x15", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_Q, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_Q, 0)
		output.syn()

	if this_event == [4, 4, int("0x1d", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_W, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_W, 0)
		output.syn()

	if this_event == [4, 4, int("0x24", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_E, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_E, 0)
		output.syn()

	if this_event == [4, 4, int("0x2d", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_R, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_R, 0)
		output.syn()

	if this_event == [4, 4, int("0x2c", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_T, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_T, 0)
		output.syn()

	if this_event == [4, 4, int("0x35", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_Y, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_Y, 0)
		output.syn()

	if this_event == [4, 4, int("0x3c", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_U, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_U, 0)
		output.syn()

	if this_event == [4, 4, int("0x43", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_I, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_I, 0)
		output.syn()

	if this_event == [4, 4, int("0x44", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_O, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_O, 0)
		output.syn()

	if this_event == [4, 4, int("0x4d", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_P, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_P, 0)
		output.syn()

	if this_event == [4, 4, int("0x54", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_LEFTBRACE, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_LEFTBRACE, 0)
		output.syn()

	if this_event == [4, 4, int("0x5b", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_RIGHTBRACE, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_RIGHTBRACE, 0)
		output.syn()

	if this_event == [4, 4, int("0x5c", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_BACKSLASH, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_BACKSLASH, 0)
		output.syn()

	if this_event == [4, 4, int("0x64", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_DELETE, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_DELETE, 0)
		output.syn()

	if this_event == [4, 4, int("0x65", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_END, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_END, 0)
		output.syn()

	if this_event == [4, 4, int("0x6d", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_PAGEDOWN, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_PAGEDOWN, 0)
		output.syn()

	if this_event == [4, 4, int("0x6c", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_KP7, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_KP7, 0)
		output.syn()

	if this_event == [4, 4, int("0x75", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_KP8, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_KP8, 0)
		output.syn()

	if this_event == [4, 4, int("0x7d", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_KP9, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_KP9, 0)
		output.syn()

	if this_event == [4, 4, int("0x7c", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_KPPLUS, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_KPPLUS, 0)
		output.syn()

######################################################################
#
# fourth row
#
######################################################################

#	if this_event == [4, 4, int("0x14", 0)]:
#		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_CAPSLOCK, 1)
#		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_CAPSLOCK, 0)
#		output.syn()

	if event.type == 1 and event.code == 29:
		if event.value == 1:
			output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_LEFTMETA, 1)
		else:
			output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_LEFTMETA, 0)
		output.syn()

	if this_event == [4, 4, int("0x1c", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_A, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_A, 0)
		output.syn()

	if this_event == [4, 4, int("0x1b", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_S, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_S, 0)
		output.syn()

	if this_event == [4, 4, int("0x23", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_D, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_D, 0)
		output.syn()

	if this_event == [4, 4, int("0x2b", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_F, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_F, 0)
		output.syn()

	if this_event == [4, 4, int("0x34", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_G, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_G, 0)
		output.syn()

	if this_event == [4, 4, int("0x33", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_H, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_H, 0)
		output.syn()

	if this_event == [4, 4, int("0x3b", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_J, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_J, 0)
		output.syn()

	if this_event == [4, 4, int("0x42", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_K, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_K, 0)
		output.syn()

	if this_event == [4, 4, int("0x4b", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_L, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_L, 0)
		output.syn()

	if this_event == [4, 4, int("0x4c", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_SEMICOLON, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_SEMICOLON, 0)
		output.syn()

	if this_event == [4, 4, int("0x52", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_APOSTROPHE, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_APOSTROPHE, 0)
		output.syn()

	if this_event == [4, 4, int("0x5a", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_ENTER, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_ENTER, 0)
		output.syn()

	if this_event == [4, 4, int("0x6b", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_KP4, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_KP4, 0)
		output.syn()

	if this_event == [4, 4, int("0x73", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_KP5, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_KP5, 0)
		output.syn()

	if this_event == [4, 4, int("0x77", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_KP6, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_KP6, 0)
		output.syn()

	if this_event == [4, 4, int("0x7b", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_KPDOT, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_KPDOT, 0)
		output.syn()

######################################################################
#
# fifth row
#
######################################################################

	#if this_event == [4, 4, int("0x12", 0)]:
	if event.type == 1 and event.code == 42:
		if event.value == 1:
			output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_LEFTSHIFT, 1)
		else:
			output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_LEFTSHIFT, 0)
		output.syn()

	if this_event == [4, 4, int("0x1a", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_Z, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_Z, 0)
		output.syn()

	if this_event == [4, 4, int("0x22", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_X, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_X, 0)
		output.syn()

	if this_event == [4, 4, int("0x21", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_C, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_C, 0)
		output.syn()

	if this_event == [4, 4, int("0x2a", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_V, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_V, 0)
		output.syn()

	if this_event == [4, 4, int("0x32", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_B, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_B, 0)
		output.syn()

	if this_event == [4, 4, int("0x31", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_N, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_N, 0)
		output.syn()

	if this_event == [4, 4, int("0x3a", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_M, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_M, 0)
		output.syn()

	if this_event == [4, 4, int("0x41", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_COMMA, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_COMMA, 0)
		output.syn()

	if this_event == [4, 4, int("0x49", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_DOT, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_DOT, 0)
		output.syn()

	if this_event == [4, 4, int("0x4a", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_SLASH, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_SLASH, 0)
		output.syn()

	#if this_event == [4, 4, int("0x54", 0)]:
	if event.type == 1 and event.code == 54:
		if event.value == 1:
			output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_RIGHTSHIFT, 1)
		else:
			output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_RIGHTSHIFT, 0)
		output.syn()

	if this_event == [4, 4, int("0x63", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_UP, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_UP, 0)
		output.syn()

	if this_event == [4, 4, int("0x69", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_KP1, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_KP1, 0)
		output.syn()

	if this_event == [4, 4, int("0x72", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_KP2, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_KP2, 0)
		output.syn()

	if this_event == [4, 4, int("0x7a", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_KP3, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_KP3, 0)
		output.syn()

	if this_event == [4, 4, int("0x79", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_KPENTER, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_KPENTER, 0)
		output.syn()

######################################################################
#
# sixth row
#
######################################################################

	#if this_event == [4, 4, int("0x11", 0)]:
	if event.type == 1 and event.code == 56:
		if event.value == 1:
			output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_LEFTCTRL, 1)
		else:
			output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_LEFTCTRL, 0)
		output.syn()

	if this_event == [4, 4, int("0x19", 0)]:
		try:
			if leftalt == 1:
				leftalt = 0
				output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_LEFTALT, 0)
			else:
				leftalt = 1
				output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_LEFTALT, 1)
		except:
			leftalt = 1
			output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_LEFTALT, 1)
		output.syn()

	if this_event == [4, 4, int("0x29", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_SPACE, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_SPACE, 0)
		output.syn()

	if this_event == [4, 4, int("0x39", 0)]:

		try:
			if rightalt == 1:
				rightalt = 0
				output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_RIGHTALT, 0)
			else:
				rightalt = 1
				output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_RIGHTALT, 1)
		except:
			rightalt = 1
			output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_RIGHTALT, 1)

		output.syn()

	if this_event == [4, 4, int("0x58", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_RIGHTCTRL, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_RIGHTCTRL, 0)
		output.syn()


	#if this_event == [4, 4, int("0x58", 0)]:
	if event.type == 1 and event.code == 58:
		if event.value == 1:
			output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_RIGHTCTRL, 1)
		else:
			output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_RIGHTCTRL, 0)
		output.syn()

	if this_event == [4, 4, int("0x61", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_LEFT, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_LEFT, 0)
		output.syn()

	if this_event == [4, 4, int("0x60", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_DOWN, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_DOWN, 0)
		output.syn()

	if this_event == [4, 4, int("0x6a", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_RIGHT, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_RIGHT, 0)
		output.syn()

	if this_event == [4, 4, int("0x70", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_KP0, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_KP0, 0)
		output.syn()

	if this_event == [4, 4, int("0x71", 0)]:
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_KPDOT, 1)
		output.write(evdev.ecodes.EV_KEY, evdev.ecodes.KEY_KPDOT, 0)
		output.syn()

modelm.ungrab()

User avatar
idollar
i$

06 Dec 2015, 23:33

Thanks a lot !!!!

Post Reply

Return to “Keyboards”