diff -Naur kbdd/kbd.c kbdd.elektex/kbd.c
--- kbdd/kbd.c	2007-06-03 21:38:52.000000000 +0200
+++ kbdd.elektex/kbd.c	2008-11-28 21:14:06.000000000 +0100
@@ -1147,6 +1147,182 @@
 return 0;
 }
 
+#define TRUE (0==0)
+#define FALSE (0!=0)
+
+int elektex_keyboard(int mapped) {
+  int fd, pressed = 0, state = 0;
+  int shift = FALSE, ctrl = FALSE, alt = FALSE, alt_gr = FALSE;
+  unsigned char buf[16], key, pressed_key1 = 0, pressed_key2 = 0;
+  fd = open_serial(TTY_PORT, B9600);
+  if (debug) fprintf(stderr, "Elektex\n");
+  while (fd > 0) {
+    read (fd, buf, 1);
+    if (debug) fprintf(stderr, "got: %d\n", buf[0]);
+    if (buf[0]==165&&state==0&&pressed==0) {
+      state = 1;
+      if (debug) fprintf(stderr, "transitioning to state 1\n");}
+    else if (buf[0]==0&&state==1&&pressed==0) {
+      state = 2;
+      if (debug) fprintf(stderr, "transitioning to state 2\n");}
+    else if (buf[0]==1&&state==2&&pressed==0) {
+      state = 3;
+      if (debug) fprintf(stderr, "transitioning to state 3\n");}
+    else if (buf[0]==90&&state==3&&pressed==0) {
+      state = 0;
+      if (debug) fprintf(stderr, "165, 0, 1, 90 ignored\n");}
+    else if (buf[0]==255&&state==0) {
+      /* It is ambiguous as to whether this is a release of the DEL key but
+	 treat it as if it is. */
+      if (pressed==1&&pressed_key1==KEY_DELETE) {
+	pressed = 0;
+	dev_uinput_key(uindev, (unsigned short)KEY_DELETE, KEY_RELEASED);
+        if (debug) fprintf(stderr, "DEL key release\n");}
+      else if (debug) fprintf(stderr, "255 ignored\n");}
+    else if ((buf[0]&0x80)&&state==0) {
+      if (pressed==0) {
+	if (debug) fprintf(stderr, "not pressed\n");}
+      else if (pressed==1) {
+	key = elektex[buf[0]&0x7f];
+	if (key!=0) {
+	  if (key==pressed_key1) {
+	    pressed = 0;
+            if (mapped&&shift&&key==KEY_2) {
+	      dev_uinput_key(uindev,
+			     (unsigned short)KEY_APOSTROPHE,
+			     KEY_RELEASED);
+	      if (debug) fprintf(stderr, "key release \" mapped to @\n");}
+	    else if (mapped&&shift&&key==KEY_APOSTROPHE) {
+	      dev_uinput_key(uindev,
+			     (unsigned short)KEY_2,
+			     KEY_RELEASED);
+	      if (debug) fprintf(stderr, "key release @ mapped to \"\n");}
+	    else if (mapped&&shift&&key==KEY_3) {
+	      dev_uinput_key(uindev, (unsigned short)KEY_GRAVE, KEY_RELEASED);
+	      dev_uinput_key(uindev,
+			     (unsigned short)KEY_LEFTSHIFT,
+			     KEY_PRESSED);
+	      if (debug) fprintf(stderr,
+				 "key release sterling mapped to `\n");}
+	    else if (mapped&&!shift&&key==KEY_GRAVE) {
+	      dev_uinput_key(uindev, (unsigned short)KEY_3, KEY_RELEASED);
+	      dev_uinput_key(uindev,
+			     (unsigned short)KEY_LEFTSHIFT,
+			     KEY_RELEASED);
+	      if (debug) fprintf(stderr, "key release ` mapped to #\n");}
+	    else {
+	      dev_uinput_key(uindev, (unsigned short)key, KEY_RELEASED);
+	      if (debug) fprintf(stderr, "key release: %d\n", key);}
+	    if (key==KEY_LEFTSHIFT) shift = !shift;
+	    else if (key==KEY_LEFTCTRL) ctrl = !ctrl;
+	    else if (key==KEY_LEFTALT) alt = !alt;
+	    else if (key==KEY_RIGHTALT) alt_gr = !alt_gr;
+	    else {
+	      if (shift) {
+		dev_uinput_key(uindev,
+			       (unsigned short)KEY_LEFTSHIFT,
+			       KEY_RELEASED);
+		if (debug) fprintf(stderr, "prefix shift key release\n");}
+	      if (ctrl) {
+		dev_uinput_key(uindev,
+			       (unsigned short)KEY_LEFTCTRL,
+			       KEY_RELEASED);
+		if (debug) fprintf(stderr, "prefix ctrl key release\n");}
+	      if (alt) {
+		dev_uinput_key(uindev,
+			       (unsigned short)KEY_LEFTALT,
+			       KEY_RELEASED);
+		if (debug) fprintf(stderr, "prefix alt key release\n");}
+	      if (alt_gr) {
+		dev_uinput_key(uindev,
+			       (unsigned short)KEY_RIGHTALT,
+			       KEY_RELEASED);
+		if (debug) fprintf(stderr, "prefix alt_gr key release\n");}
+	      shift = FALSE;
+	      ctrl = FALSE;
+	      alt = FALSE;
+	      alt_gr = FALSE;}}
+	  else if (debug) fprintf(stderr, "unmatched press code\n");}
+	else if (debug) fprintf(stderr, "unrecognized release code\n");}
+      /* pressed==2 */
+      else {
+	key = elektex[buf[0]&0x7f];
+	if (key!=0) {
+	  if (key==pressed_key2) {
+	    pressed = 1;
+	    dev_uinput_key(uindev, (unsigned short)key, KEY_RELEASED);
+            if (debug) fprintf(stderr, "chorded key release: %d\n", key);}
+	  else if (debug) fprintf(stderr, "unmatched chorded press code\n");}
+	else if (debug) fprintf(stderr,
+				"unrecognized chorded release code\n");}}
+    else if (state==0) {
+      if (pressed==0) {
+	key = elektex[buf[0]];
+	if (key!=0) {
+	  pressed = 1;
+	  pressed_key1 = key;
+	  if (key!=KEY_LEFTSHIFT&&
+	      key!=KEY_LEFTCTRL&&
+	      key!=KEY_LEFTALT&&
+	      key!=KEY_RIGHTALT) {
+	    if (shift) {
+	      dev_uinput_key(uindev,
+			     (unsigned short)KEY_LEFTSHIFT,
+			     KEY_PRESSED);
+	      if (debug) fprintf(stderr, "prefix shift key press\n");}
+	    if (ctrl) {
+	      dev_uinput_key(uindev,
+			     (unsigned short)KEY_LEFTCTRL,
+			     KEY_PRESSED);
+	      if (debug) fprintf(stderr, "prefix ctrl key press\n");}
+	    if (alt) {
+	      dev_uinput_key(uindev, (unsigned short)KEY_LEFTALT, KEY_PRESSED);
+	      if (debug) fprintf(stderr, "prefix alt key press\n");}
+	    if (alt_gr) {
+	      dev_uinput_key(uindev,
+			     (unsigned short)KEY_RIGHTALT,
+			     KEY_PRESSED);
+	      if (debug) fprintf(stderr, "prefix alt_gr key press\n");}}
+          if (mapped&&shift&&key==KEY_2) {
+	    dev_uinput_key(uindev,
+			   (unsigned short)KEY_APOSTROPHE,
+			   KEY_PRESSED);
+	    if (debug) fprintf(stderr, "key press \" mapped to @\n");}
+	  else if (mapped&&shift&&key==KEY_APOSTROPHE) {
+	    dev_uinput_key(uindev,
+			   (unsigned short)KEY_2,
+			   KEY_PRESSED);
+	    if (debug) fprintf(stderr, "key press @ mapped to \"\n");}
+	  else if (mapped&&shift&&key==KEY_3) {
+	    dev_uinput_key(uindev,
+			   (unsigned short)KEY_LEFTSHIFT,
+			   KEY_RELEASED);
+	    dev_uinput_key(uindev, (unsigned short)KEY_GRAVE, KEY_PRESSED);
+	    if (debug) fprintf(stderr, "key press sterling mapped to `\n");}
+	  else if (mapped&&!shift&&key==KEY_GRAVE) {
+	    dev_uinput_key(uindev, (unsigned short)KEY_LEFTSHIFT, KEY_PRESSED);
+	    dev_uinput_key(uindev, (unsigned short)KEY_3, KEY_PRESSED);
+	    if (debug) fprintf(stderr, "key press ` mapped to #\n");}
+	  else {
+	    dev_uinput_key(uindev, (unsigned short)key, KEY_PRESSED);
+	    if (debug) fprintf(stderr, "key press: %d\n", key);}}
+	else if (debug) fprintf(stderr, "unrecognized press code\n");}
+      else if (pressed==1) {
+	key = elektex[buf[0]];
+	if (key!=0) {
+	  if (key==pressed_key1) {
+	    dev_uinput_key(uindev, (unsigned short)key, KEY_PRESSED);
+	    if (debug) fprintf(stderr, "repeat key press: %d\n", key);}
+	  else {
+	    pressed = 2;
+	    pressed_key2 = key;
+	    dev_uinput_key(uindev, (unsigned short)key, KEY_PRESSED);
+	    if (debug) fprintf(stderr, "chorded key press: %d\n", key);}}
+	else if (debug) fprintf(stderr, "unrecognized chorded press code\n");}
+      /* pressed==2 */
+      else if (debug) fprintf(stderr, "double bucky\n");}
+    else if (debug) fprintf(stderr, "in middle of 165, 0, 1, 90\n");}
+  return 0;}
 
 void print_usage(char *arg0)
 {
@@ -1178,7 +1354,9 @@
 	fprintf (stderr, "\tmicrokbd  - Compaq MicroKeyboard\n");
 	fprintf (stderr, "\ttargusir  - Targus Universal Wireless keyboard\n");
 	fprintf (stderr, "\tfreedom   - Freedom keyboard\n");
-	fprintf (stderr, "\tbtfoldable - HP iPAQ Bluetooth Foldable Keyboard\n\n");
+	fprintf (stderr, "\tbtfoldable - HP iPAQ Bluetooth Foldable Keyboard\n");
+	fprintf (stderr, "\telektex - Elektex Cloth Keyboard\n");
+	fprintf (stderr, "\telektex_unmapped - Elektex Cloth Keyboard (Unmapped)\n");
 	fprintf (stderr, "Example:\n\t%s -t foldable\n", arg0);
 }
 
@@ -1202,6 +1380,8 @@
 #define KBD_TYPE_BTFOLDABLE		16
 #define KBD_TYPE_FREEDOM		17
 #define KBD_TYPE_SNAPNTYPEBT		18
+#define KBD_TYPE_ELEKTEX		19
+#define KBD_TYPE_ELEKTEX_UNMAPPED	20
 
 int find_kbd_type(const char *ktype)
 {
@@ -1239,8 +1419,12 @@
 		return KBD_TYPE_TARGUSIR;
 	else if (strncmp("freedom", ktype, 7) == 0)
 		return KBD_TYPE_FREEDOM;
-	if (strncmp("btfoldable", ktype, 10) == 0)
+	else if (strncmp("btfoldable", ktype, 10) == 0)
 		return KBD_TYPE_BTFOLDABLE;
+	else if (strncmp("elektex", ktype, 7) == 0)
+		return KBD_TYPE_ELEKTEX;
+	else if (strncmp("elektex_unmapped", ktype, 16) == 0)
+		return KBD_TYPE_ELEKTEX_UNMAPPED;
 
 	fprintf(stderr, "unrecognised keyboard type %s\n", ktype);
 
@@ -1379,6 +1563,10 @@
 		targus_infrared();
 	else if (kbdtype == KBD_TYPE_FREEDOM)
 		freedom_keyboard();
+	else if (kbdtype == KBD_TYPE_ELEKTEX)
+		elektex_keyboard(TRUE);
+	else if (kbdtype == KBD_TYPE_ELEKTEX_UNMAPPED)
+		elektex_keyboard(FALSE);
 
 	dev_uinput_close(uindev);
 return 0;
diff -Naur kbdd/keyboards.h kbdd.elektex/keyboards.h
--- kbdd/keyboards.h	2006-08-27 21:16:18.000000000 +0200
+++ kbdd.elektex/keyboards.h	2008-11-28 21:11:04.000000000 +0100
@@ -881,6 +881,148 @@
 unsigned char targus_irda_normal[128] = {};
 #endif
 
+/***********************************************************************************
+ * Elextex cloth keyboard
+ *
+ * 9600 baud, 8N1
+ *
+ * Key down sends one byte:  KEY
+ * Key up sends one byte:    KEY | 0x80
+ ***********************************************************************************/
+
+unsigned char elektex[128] = {
+  /* 00 */ 0,
+  /* 01 */ 0,
+  /* 02 */ KEY_LEFTSHIFT, /* ambiguous between left and right */
+  /* 03 */ KEY_CAPSLOCK,
+  /* 04 */ 0,
+  /* 05 */ 0,
+  /* 06 */ 0,
+  /* 07 */ 0,
+  /* 08 */ KEY_BACKSPACE,
+  /* 09 */ KEY_TAB,
+  /* 10 */ 0,
+  /* 11 */ 0,
+  /* 12 */ 0,
+  /* 13 */ KEY_ENTER,
+  /* 14 */ 0,
+  /* 15 */ 0,
+  /* 16 */ 0,
+  /* 17 */ 0,
+  /* 18 */ 0,
+  /* 19 */ 0,
+  /* 20 */ KEY_UP,
+  /* 21 */ KEY_DOWN,
+  /* 22 */ KEY_LEFT,
+  /* 23 */ KEY_RIGHT,
+  /* 24 */ 0,
+  /* 25 */ 0,
+  /* 26 */ 0,
+  /* 27 */ KEY_ESC,
+  /* 28 */ 0,
+  /* 29 */ 0,
+  /* 30 */ 0,
+  /* 31 */ 0,
+  /* 32 */ KEY_SPACE,
+  /* 33 */ 0,
+  /* 34 */ 0,
+  /* 35 */ KEY_GRAVE, /* shifted or unmapped: `, unshifted and mapped: # */
+  /* 36 */ 0,
+  /* 37 */ 0,
+  /* 38 */ 0,
+  /* 39 */ KEY_APOSTROPHE, /* unshifted or unmapped: ",
+                              shifted and mapped: @ */
+  /* 40 */ 0,
+  /* 41 */ 0,
+  /* 42 */ 0,
+  /* 43 */ 0,
+  /* 44 */ KEY_COMMA,
+  /* 45 */ KEY_MINUS,
+  /* 46 */ KEY_DOT,
+  /* 47 */ KEY_SLASH,
+  /* 48 */ KEY_0,
+  /* 49 */ KEY_1,
+  /* 50 */ KEY_2, /* unshifted or unmapped: @, shifted and mapped: " */
+  /* 51 */ KEY_3, /* on keyboard: sterling, unshifted or unmapped: #,
+		     shifted and mapped: ` */
+  /* 52 */ KEY_4, /* keyboard also has euro */
+  /* 53 */ KEY_5,
+  /* 54 */ KEY_6,
+  /* 55 */ KEY_7,
+  /* 56 */ KEY_8,
+  /* 57 */ KEY_9,
+  /* 58 */ 0,
+  /* 59 */ KEY_SEMICOLON,
+  /* 60 */ 0,
+  /* 61 */ KEY_EQUAL,
+  /* 62 */ 0,
+  /* 63 */ 0,
+  /* 64 */ 0,
+  /* 65 */ KEY_A,
+  /* 66 */ KEY_B,
+  /* 67 */ KEY_C,
+  /* 68 */ KEY_D,
+  /* 69 */ KEY_E,
+  /* 70 */ KEY_F,
+  /* 71 */ KEY_G,
+  /* 72 */ KEY_H,
+  /* 73 */ KEY_I,
+  /* 74 */ KEY_J,
+  /* 75 */ KEY_K,
+  /* 76 */ KEY_L,
+  /* 77 */ KEY_M,
+  /* 78 */ KEY_N,
+  /* 79 */ KEY_O,
+  /* 80 */ KEY_P,
+  /* 81 */ KEY_Q,
+  /* 82 */ KEY_R,
+  /* 83 */ KEY_S,
+  /* 84 */ KEY_T,
+  /* 85 */ KEY_U,
+  /* 86 */ KEY_V,
+  /* 87 */ KEY_W,
+  /* 88 */ KEY_X,
+  /* 89 */ KEY_Y,
+  /* 90 */ KEY_Z,
+  /* 91 */ KEY_LEFTBRACE, /* [ */
+  /* 92 */ KEY_BACKSLASH,
+  /* 93 */ KEY_RIGHTBRACE, /* ] */
+  /* 94 */ 0,
+  /* 95 */ 0,
+  /* 96 */ 0,
+  /* 97 */ 0,
+  /* 98 */ 0,
+  /* 99 */ 0,
+  /*100 */ 0,
+  /*101 */ 0,
+  /*102 */ 0,
+  /*103 */ 0,
+  /*104 */ 0,
+  /*105 */ 0,
+  /*106 */ 0,
+  /*107 */ 0,
+  /*108 */ 0,
+  /*109 */ 0,
+  /*110 */ 0,
+  /*111 */ 0,
+  /*112 */ KEY_LEFTCTRL,
+  /*113 */ KEY_LEFTALT,
+  /*114 */ KEY_RIGHTALT,
+  /*115 */ 0,
+  /*116 */ 0,
+  /*117 */ 0,
+  /*118 */ 0,
+  /*119 */ 0,
+  /*120 */ 0,
+  /*121 */ 0,
+  /*122 */ 0,
+  /*123 */ 0,
+  /*124 */ 0,
+  /*125 */ 0,
+  /*126 */ 0,
+  /*127 */ KEY_DELETE
+};
+
 	/***********************************************************************************/
 #if 0
  struct microkbd_dev keyboards[] = {
