sam: first pass at adding the input layer and mouse interface
authorAlan Cox <alan@linux.intel.com>
Sun, 18 Nov 2018 00:17:32 +0000 (00:17 +0000)
committerAlan Cox <alan@linux.intel.com>
Sun, 18 Nov 2018 00:17:32 +0000 (00:17 +0000)
Hook up mouse and also keyboard raw event support

Kernel/platform-sam/Makefile
Kernel/platform-sam/config.h
Kernel/platform-sam/devinput.c [new file with mode: 0644]
Kernel/platform-sam/devtty.c
Kernel/platform-sam/devtty.h
Kernel/platform-sam/fuzix.lnk
Kernel/platform-sam/sam.s

index 292f5fe..7a5acc9 100644 (file)
@@ -1,5 +1,5 @@
 
-CSRCS = devlpr.c devtty.c devfd.c devatom.c msm6242b.c
+CSRCS = devlpr.c devtty.c devfd.c devatom.c msm6242b.c devinput.c
 CSRCS += devices.c main.c
 
 DSRCS = ../dev/devide.c ../dev/mbr.c ../dev/blkdev.c
index 635314e..04cbbd8 100644 (file)
@@ -1,5 +1,3 @@
-#define CONFIG_RTC
-#define CONFIG_RTC_FULL
 /* Enable to make ^Z dump the inode table for debug */
 #undef CONFIG_IDUMP
 /* Enable to make ^A drop back into the monitor */
 
 #define CONFIG_BANKS   2       /* 2 x 32K */
 
+/* Full RTC support */
+#define CONFIG_RTC
+#define CONFIG_RTC_FULL
+
+/* Input layer support */
+#define CONFIG_INPUT
+#define CONFIG_INPUT_GRABMAX   3
+
 /* Video terminal, not a serial tty */
 #define CONFIG_VT
 /* Fonts are pre-expanded as we have reasonable amounts of memory and
diff --git a/Kernel/platform-sam/devinput.c b/Kernel/platform-sam/devinput.c
new file mode 100644 (file)
index 0000000..e06d30c
--- /dev/null
@@ -0,0 +1,84 @@
+#include <kernel.h>
+#include <kdata.h>
+#include <input.h>
+#include <devtty.h>
+
+uint8_t mousein[7];
+uint8_t mouse_present;
+static int16_t mousedx, mousedy;
+static uint8_t mousebuttons;
+static uint8_t mousemod;
+
+static char buf[32];
+
+static struct s_queue kqueue = {
+    buf, buf, buf, sizeof(buf), 0, sizeof(buf) / 2
+};
+
+/* Queue a character to the input device */
+void queue_input(uint8_t c)
+{
+    insq(&kqueue, c);
+    wakeup(&kqueue);
+}
+
+static int8_t clampdec(int16_t *v)
+{
+    int8_t r;
+    if (*v > 127) {
+        *v -= 127;
+        return 127;
+    }
+    if (*v < -127) {
+        *v += 127;
+        return -127;
+    }
+    r = *v;
+    return r;
+}
+
+int platform_input_read(uint8_t *slot)
+{
+    uint8_t r, k;
+    if (remq(&kqueue, &r)) {
+        remq(&kqueue, &k);
+       *slot++ = KEYPRESS_CODE | r;
+       *slot++ = k;
+       return 2;
+    }
+    if (mousemod) {
+        *slot++ = MOUSE_REL|mousebuttons;
+        *slot++ = clampdec(&mousedx);
+        *slot++ = clampdec(&mousedy);
+        mousemod = !!(mousedx | mousedy);
+        return 3;
+    }
+    return 0;
+}
+
+void platform_input_wait(void)
+{
+    psleep(&kqueue);
+}
+
+int platform_input_write(uint8_t flag)
+{
+    flag;
+    udata.u_error = EINVAL;
+    return -1;
+}
+
+void poll_input(void)
+{
+       if (mouse_present) {
+               mousescan();
+               mousedy += mouse12(mousein + 1);
+               mousedx += mouse12(mousein + 4);
+               if (mousebuttons != *mousein || mousedy || mousedx) {
+                       mousebuttons = *mousein;
+                       mousemod = 1;
+                       wakeup(&kqueue);
+               }
+       }
+
+}
index 50c2179..4b9cc7b 100644 (file)
@@ -5,6 +5,7 @@
 #include <tty.h>
 #include <vt.h>
 #include <graphics.h>
+#include <input.h>
 #include <devtty.h>
 #include <stdarg.h>
 
@@ -101,8 +102,13 @@ static void keyproc(void)
                        int m = 1;
                        for (n = 0; n < 8; n++) {
                                if ((key & m) && (keymap[i] & m)) {
-                                       if (!(shiftmask[i] & m))
+                                       if (!(shiftmask[i] & m)) {
+                                               if (keyboard_grab == 3) {
+                                                       queue_input(KEYPRESS_UP);
+                                                       queue_input(keyboard[i][n]);
+                                               }
                                                keysdown--;
+                                       }
                                }
                                if ((key & m) && !(keymap[i] & m)) {
                                        if (!(shiftmask[i] & m)) {
@@ -183,15 +189,19 @@ static uint8_t capslock = 0;
 static void keydecode(void)
 {
        uint8_t c;
-
+       uint8_t m = 0;
+       
        /* We don't do anything clever for both shifts or other weird combos
           This computer isn't going to run emacs after all */
 
-       if (keymap[7] & 0x02)   /* Symbol Shift */
+        
+       if (keymap[7] & 0x02) { /* Symbol Shift */
                c = altkeyboard[keybyte][keybit];
-       else if (keymap[0] & 0x01)
+               m = KEYPRESS_ALT;
+       } else if (keymap[0] & 0x01) {
                c = shiftkeyboard[keybyte][keybit];
-       else
+               m = KEYPRESS_SHIFT;
+       } else
                c = keyboard[keybyte][keybit];
 
        if (c == KEY_CAPSLOCK) {
@@ -199,6 +209,7 @@ static void keydecode(void)
                return;
        }
        if (keymap[8] & 0x01) { /* control */
+               m |= KEYPRESS_CTRL;
                /* These map the SAM specific behaviours */
                if (c == KEY_LEFT)
                        c = KEY_HOME;
@@ -209,21 +220,37 @@ static void keydecode(void)
        }
        if (capslock && c >= 'a' && c <= 'z')
                c -= 'a' - 'A';
-       if (c)
-               vt_inproc(1, c);
+       if (c) {
+               switch (keyboard_grab) {
+               case 0:
+                       vt_inproc(1, c);
+                       break;
+               case 1:
+                       if (!input_match_meta(c)) {
+                               vt_inproc(1, c);
+                               break;
+                       }
+                       /* Fall through */
+               case 2:
+                       queue_input(KEYPRESS_DOWN);
+                       queue_input(c);
+                       break;
+               case 3:
+                       /* Queue an event giving the base key (unshifted)
+                          and the state of shift/ctrl/alt */
+                       queue_input(KEYPRESS_DOWN | m);
+                       queue_input(keyboard[keybyte][keybit]);
+                       break;
+               }
+       }
 }
 
 static uint8_t kbd_timer;
 
-uint8_t mousein[7];
-uint8_t mouse_present;
-
 void kbd_interrupt(void)
 {
        newkey = 0;
        keyproc();
-       if (mouse_present)
-               mousescan();
        if (keysdown && keysdown < 3) {
                if (newkey) {
                        keydecode();
index 92c4e78..4f359fa 100644 (file)
@@ -6,9 +6,12 @@ extern void kbd_interrupt(void);
 extern void keyscan(void);
 extern void mousescan(void);
 extern uint8_t mouse_probe(void);      /* 0 means yes */
+extern int16_t mouse12(uint8_t *) __z88dk_fastcall;
 
 extern uint8_t mouse_present;
 
+extern void queue_input(uint8_t);
+
 #define KEY_ROWS       9
 #define KEY_COLS       8
 
index 8987261..bc24c5b 100644 (file)
@@ -18,6 +18,7 @@ devio.rel
 filesys.rel
 process.rel
 inode.rel
+devinput.rel
 syscall_exec16.rel
 syscall_fs.rel
 syscall_fs2.rel
@@ -47,4 +48,5 @@ platform-sam/sam.rel
 platform-sam/sam_vt.rel
 platform-sam/tricks.rel
 platform-sam/msm6242b.rel
+platform-sam/devinput.rel
 -e
index dd2595e..1be0aac 100644 (file)
@@ -23,6 +23,7 @@
            .globl _platform_copier_h
            .globl _keyscan
            .globl _mousescan
+           .globl _mouse12
            .globl _mouse_probe
            .globl _int_disabled
 
@@ -310,6 +311,36 @@ _mousescan:
            in a,(c)            ; end
            ret                 ; hl will be non zero
 
+_mouse12:
+           ; Get the top nibble
+           ld a,(hl)
+           and #0x0f
+           ; Sign extend it if needed
+           bit 3,a
+           jr z, nosex
+           or #0xf0
+nosex:
+           ld d,a
+           ; Next nibble is bits 7-4
+           inc hl
+           ld a,(hl)
+           and #0x0f
+           rlca
+           rlca
+           rlca
+           rlca
+           ld e,a
+           ; and bits 3-0
+           inc hl
+           ld a,(hl)
+           and #0x0f
+           ; Merge to get low byte
+           or e
+           ld l,a
+           ; Get high byte
+           ld h,d
+           ret
+
            .area _DISCARD
 
 _mouse_probe: