Add op_test_inputs
authorGrazvydas Ignotas <notasas@gmail.com>
Fri, 9 Apr 2010 20:33:58 +0000 (23:33 +0300)
committerGrazvydas Ignotas <notasas@gmail.com>
Fri, 9 Apr 2010 20:33:58 +0000 (23:33 +0300)
Makefile
op_test_inputs.c [new file with mode: 0644]
scripts/op_test_inputs [new file with mode: 0755]

index b77ba5a..be54a6d 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -5,7 +5,7 @@ CFLAGS += -Wall -O2
 LDFLAGS += -s
 INSTALL ?= bin
 
-BIN = op_runfbapp op_gammatool
+BIN = op_runfbapp op_gammatool op_test_inputs
 
 all: $(BIN)
 
@@ -13,6 +13,7 @@ clean:
        $(RM) *.o $(BIN)
 
 op_runfbapp: LDFLAGS += -lpthread -lX11
+op_test_inputs: LDFLAGS += -lts
 
 $(INSTALL):
        mkdir -p $(INSTALL)
@@ -20,4 +21,6 @@ $(INSTALL):
 install: $(INSTALL) $(BIN)
        cp op_runfbapp $(INSTALL)/
        cp op_gammatool $(INSTALL)/op_gammatool_bin
-       cp scripts/op_gammatool $(INSTALL)/op_gammatool
+       cp op_test_inputs $(INSTALL)/op_test_inputs_bin
+       cp scripts/op_gammatool $(INSTALL)/
+       cp scripts/op_test_inputs $(INSTALL)/
diff --git a/op_test_inputs.c b/op_test_inputs.c
new file mode 100644 (file)
index 0000000..923740b
--- /dev/null
@@ -0,0 +1,460 @@
+/*
+ * Copyright (c) 2010, GraÅžvydas Ignotas
+ * All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above copyright
+ *       notice, this list of conditions and the following disclaimer in the
+ *       documentation and/or other materials provided with the distribution.
+ *     * Neither the name of the organization nor the
+ *       names of its contributors may be used to endorse or promote products
+ *       derived from this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ * ARE DISCLAIMED. IN NO EVENT SHALL COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE
+ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
+ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
+ * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
+ * CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
+ * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
+#define _GNU_SOURCE
+#include <stdio.h>
+#include <string.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
+#include <sys/mman.h>
+#include <unistd.h>
+#include <linux/input.h>
+#include <tslib.h>
+
+#include "font.c"
+
+typedef struct {
+       int x, y;
+       int code;
+       int active;
+       const char *name;
+} key_item;
+
+static key_item key_items[] =
+{
+       {  66,  26, KEY_1, 0, "1" },
+       { 133,  26, KEY_2, 0, "2" },
+       { 200,  26, KEY_3, 0, "3" },
+       { 266,  26, KEY_4, 0, "4" },
+       { 333,  26, KEY_5, 0, "5" },
+       { 400,  26, KEY_6, 0, "6" },
+       { 466,  26, KEY_7, 0, "7" },
+       { 533,  26, KEY_8, 0, "8" },
+       { 600,  26, KEY_9, 0, "9" },
+       { 666,  26, KEY_0, 0, "0" },
+       { 733,  26, KEY_BACKSPACE, 0, "DEL" },
+       //
+       {  10,  55, KEY_RIGHTSHIFT,0, "L" },
+       {  10,  75, KEY_KPPLUS,    0, "L2" },
+       { 758,  55, KEY_RIGHTCTRL, 0, "R" },
+       { 758,  75, KEY_KPMINUS,   0, "R2" },
+       {  10, 220, KEY_POWER,     0, "POWER" },
+       {  10, 240, KEY_COFFEE,    0, "HOLD" },
+       //
+       { 130,  94, KEY_UP,     0, "U" },
+       {  80, 163, KEY_LEFT,   0, "L" },
+       { 180, 163, KEY_RIGHT,  0, "R" },
+       { 130, 232, KEY_DOWN,   0, "D" },
+       { 376,  94, KEY_LEFTALT,0, "ALT" },
+       { 368, 163, KEY_LEFTCTRL,0,"CTRL" },
+       { 368, 232, KEY_MENU,   0, "MENU" },
+       { 700,  94, KEY_PAGEUP, 0, "1" },
+       { 650, 163, KEY_HOME,   0, "4" },
+       { 750, 163, KEY_END,    0, "2" },
+       { 700, 232, KEY_PAGEDOWN,0, "3" },
+       //
+       {  92, 300, KEY_Q,      0, "Q" },
+       { 158, 300, KEY_W,      0, "W" },
+       { 225, 300, KEY_E,      0, "E" },
+       { 292, 300, KEY_R,      0, "R" },
+       { 358, 300, KEY_T,      0, "T" },
+       { 425, 300, KEY_Y,      0, "Y" },
+       { 492, 300, KEY_U,      0, "U" },
+       { 558, 300, KEY_I,      0, "I" },
+       { 625, 300, KEY_O,      0, "O" },
+       { 692, 300, KEY_P,      0, "P" },
+       //
+       {  30, 369, KEY_LEFTSHIFT, 0, "SHIFT" },
+       { 133, 369, KEY_A,      0, "A" },
+       { 200, 369, KEY_S,      0, "S" },
+       { 266, 369, KEY_D,      0, "D" },
+       { 333, 369, KEY_F,      0, "F" },
+       { 400, 369, KEY_G,      0, "G" },
+       { 466, 369, KEY_H,      0, "H" },
+       { 533, 369, KEY_J,      0, "J" },
+       { 600, 369, KEY_K,      0, "K" },
+       { 666, 369, KEY_L,      0, "L" },
+       { 710, 369, KEY_ENTER,  0, "ENTER" },
+       //
+       {  25, 437, KEY_COMMA,  0, "," },
+       {  92, 437, KEY_DOT,    0, "." },
+       { 158, 437, KEY_Z,      0, "Z" },
+       { 225, 437, KEY_X,      0, "X" },
+       { 292, 437, KEY_C,      0, "C" },
+       { 358, 437, KEY_V,      0, "V" },
+       { 425, 437, KEY_B,      0, "B" },
+       { 492, 437, KEY_N,      0, "N" },
+       { 558, 437, KEY_M,      0, "M" },
+       { 625, 437, KEY_SPACE,  0, "SPACE" },
+       { 758, 437, KEY_FN,     0, "Fn" },
+};
+
+#define KI_COUNT (sizeof(key_items) / sizeof(key_items[0]))
+
+static int ts_old_x = 0, ts_old_y = 0;
+static int lid_closed = 0;
+
+static void draw_ts_cross(unsigned short *fb, unsigned short col, int x, int y)
+{
+       int i, x1, y1;
+
+       if (y >= 0 && y < 480)
+               for (x1 = x - 5, i = 0; i < 11; i++, x1++)
+                       if (x1 >= 0 && x1 < 800) fb[y * 800 + x1] = col;
+       
+       if (x >= 0 && x < 800)
+               for (y1 = y - 5, i = 0; i < 11; i++, y1++)
+                       if (y1 >= 0 && y1 < 480) fb[y1 * 800 + x] = col;
+       
+       ts_old_x = x;
+       ts_old_y = y;
+}
+
+static void text_out16(unsigned short *fb, int x, int y, unsigned short col, const char *text)
+{
+       int i,l;
+
+       fb = fb + x + y*800;
+
+       for (i = 0; i < strlen(text); i++)
+       {
+               for (l=0;l<8;l++)
+               {
+                       #define pix(fdmask,add) \
+                               if (fontdata8x8[((text[i])*8)+l]&fdmask) \
+                                       fb[l*2*800+add]=fb[l*2*800+add+1]=fb[l*2*800+800+add]=fb[l*2*800+800+add+1]=col
+                       pix(0x80,  0);
+                       pix(0x40,  2);
+                       pix(0x20,  4);
+                       pix(0x10,  6);
+                       pix(0x08,  8);
+                       pix(0x04, 10);
+                       pix(0x02, 12);
+                       pix(0x01, 14);
+                       #undef pix
+               }
+               fb += 8*2;
+       }
+}
+
+static void text_out16_small(unsigned short *fb, int x, int y, unsigned short col, const char *text)
+{
+       int i,l;
+
+       fb = fb + x + y*800;
+
+       for (i = 0; i < strlen(text); i++)
+       {
+               for (l=0;l<8;l++)
+               {
+                       #define pix(fdmask,add) \
+                               if (fontdata8x8[((text[i])*8)+l]&fdmask) \
+                                       fb[l*800+add]=fb[l*800+800+add]=col
+                       pix(0x80,  0);
+                       pix(0x40,  1);
+                       pix(0x20,  2);
+                       pix(0x10,  3);
+                       pix(0x08,  4);
+                       pix(0x04,  5);
+                       pix(0x02,  6);
+                       pix(0x01,  7);
+                       #undef pix
+               }
+               fb += 8;
+       }
+}
+
+static void redraw_nubs(unsigned short *fb, int x1, int y1, int x2, int y2)
+{
+       char buff[32];
+       int y;
+
+       fb += 90*800;
+
+       // clear areas
+       for (y = 0; y < 140; y++) {
+               memset(fb + 800*y + 200, 0, (64+8)*2*2);
+               memset(fb + 800*y + 450, 0, (64+8)*2*2);
+       }
+
+       text_out16(fb + 200, 32*2 + x1/8, 32*2 + y1/8, 0x001f, "@");
+       text_out16(fb + 450, 32*2 + x2/8, 32*2 + y2/8, 0x001f, "@");
+
+       snprintf(buff, sizeof(buff), "%2i, %2i", x1/8, y1/8);
+       text_out16_small(fb, 245, 130, 0x7bef, buff);
+       snprintf(buff, sizeof(buff), "%2i, %2i", x2/8, y2/8);
+       text_out16_small(fb, 495, 130, 0x7bef, buff);
+}
+
+static void redraw_keys_lid(unsigned short *fb)
+{
+       const key_item *key;
+       int i;
+
+       for (i = 0; i < KI_COUNT; i++)
+       {
+               key = &key_items[i];
+
+               text_out16(fb, key->x, key->y,
+                       key->active ? 0x07e0 : 0x7bef, key->name);
+       }
+
+       text_out16(fb, 10, 260, lid_closed ? 0x07e0 : 0x7bef, "LID");
+}
+
+static void setkey(int code, int val)
+{
+       key_item *key = NULL;
+       int i;
+
+       for (i = 0; i < KI_COUNT; i++)
+       {
+               if (key_items[i].code == code)
+               {
+                       key = &key_items[i];
+                       break;
+               }
+       }
+
+       if (key == NULL)
+       {
+               printf("%c unexpected key? (%i)\n", val ? '+' : '-', code);
+       }
+       else
+       {
+               key->active = val;
+               printf("%c %s\n", val ? '+' : '-', key->name);
+       }
+}
+
+enum {
+       DEV_PWRBTN,
+       DEV_KEYPAD,
+       DEV_BUTTONS,
+       DEV_TS,
+       DEV_LNUB,
+       DEV_RNUB,
+       DEVS_TOTAL
+};
+
+int main(int argc, char *argv[])
+{
+       unsigned short *screen;
+       int fbdev, ifd[DEVS_TOTAL] = { -1, -1, -1, -1, -1, -1 };
+       int i, id, imaxfd = 0, ts_x = 0, ts_y = 0;
+       int nubx[2] = {0,0}, nuby[2] = {0,0};
+       int pressed_l = 0, pressed_r = 0;
+       struct tsdev *ts = NULL;
+
+       fbdev = open("/dev/fb0", O_RDWR);
+       if (fbdev == -1)
+       {
+               perror("open(\"/dev/fb0\") failed");
+               return 1;
+       }
+
+       screen = mmap(0, 800*480*2, PROT_WRITE|PROT_READ, MAP_SHARED, fbdev, 0);
+       if (screen == MAP_FAILED)
+       {
+               perror("mmap(fbptr) failed");
+               return 1;
+       }
+
+       memset(screen, 0, 800*480*2);
+
+       for (id = 0; ; id++)
+       {
+               char fname[64];
+               char name[256] = { 0, };
+               int fd;
+
+               snprintf(fname, sizeof(fname), "/dev/input/event%i", id);
+               fd = open(fname, O_RDONLY);
+               if (fd == -1)
+               {
+                       break;
+               }
+
+               ioctl(fd, EVIOCGNAME(sizeof(name)), name);
+
+               if (strcasestr(name, "pwrbutton") != NULL)
+               {
+                       ifd[DEV_PWRBTN] = fd;
+               }
+               else if (strcasestr(name, "keypad") != NULL)
+               {
+                       ifd[DEV_KEYPAD] = fd;
+               }
+               else if (strcmp(name, "gpio-keys") == 0)
+               {
+                       ifd[DEV_BUTTONS] = fd;
+               }
+               else if (strcasestr(name, "touchscreen") != NULL)
+               {
+                       close(fd);
+                       ts = ts_open(fname, 0);
+                       if (ts == NULL)
+                       {
+                               perror("ts_open");
+                               goto end;
+                       }
+                       if (ts_config(ts))
+                       {
+                               perror("ts_config");
+                               goto end;
+                       }
+                       ifd[DEV_TS] = ts_fd(ts);
+               }
+               else if (strcmp(name, "vsense66") == 0)
+               {
+                       ifd[DEV_LNUB] = fd;
+               }
+               else if (strcmp(name, "vsense67") == 0)
+               {
+                       ifd[DEV_RNUB] = fd;
+               }
+               else
+               {
+                       printf("skipping \"%s\"\n", name);
+                       close(fd);
+                       continue;
+               }
+               if (imaxfd < fd) imaxfd = fd;
+       }
+
+       if (ifd[DEV_PWRBTN]  == -1) printf("Warning: couldn't find pwrbutton device\n");
+       if (ifd[DEV_KEYPAD]  == -1) printf("Warning: couldn't find keypad device\n");
+       if (ifd[DEV_BUTTONS] == -1) printf("Warning: couldn't find button device\n");
+       if (ifd[DEV_TS]      == -1) printf("Warning: couldn't find touchscreen device\n");
+       if (ifd[DEV_LNUB]    == -1) printf("Warning: couldn't find nub1 device\n");
+       if (ifd[DEV_RNUB]    == -1) printf("Warning: couldn't find nub2 device\n");
+
+       text_out16_small(screen, 320, 3, 0x7bef, "Press L+R to exit");
+
+       while (!pressed_l || !pressed_r)
+       {
+               struct input_event ev[64];
+               int fd = -1, rd, which, ret;
+               fd_set fdset;
+
+               draw_ts_cross(screen, 0x0000, ts_old_x, ts_old_y);
+               redraw_keys_lid(screen);
+               redraw_nubs(screen, nubx[0], nuby[0], nubx[1], nuby[1]);
+               draw_ts_cross(screen, 0xf800, ts_x, ts_y);
+
+               FD_ZERO(&fdset);
+               for (i = 0; i < DEVS_TOTAL; i++)
+                       if (ifd[i] != -1)
+                               FD_SET(ifd[i], &fdset);
+
+               ret = select(imaxfd + 1, &fdset, NULL, NULL, NULL);
+               if (ret == -1)
+               {
+                       perror("select");
+                       break;
+               }
+
+               for (i = 0; i < DEVS_TOTAL; i++)
+                       if (ifd[i] != -1 && FD_ISSET(ifd[i], &fdset))
+                               fd = ifd[i];
+
+               /* touch event? */
+               if (fd == ifd[DEV_TS])
+               {
+                       struct ts_sample samp;
+
+                       ret = ts_read(ts, &samp, 1);
+                       if (ret < 0) {
+                               perror("ts_read");
+                               break;
+                       }
+
+                       if (ret != 1)
+                               continue;
+
+                       ts_x = samp.x; ts_y = samp.y;
+                       //printf("ts: %6d %6d %6d\n", samp.x, samp.y, samp.pressure);
+                       continue;
+               }
+
+               /* buttons or keypad */
+               rd = read(fd, ev, sizeof(ev));
+               if (rd < (int) sizeof(ev[0])) {
+                       perror("\nevtest: error reading");
+                       break;
+               }
+
+               for (i = 0; i < rd / sizeof(ev[0]); i++)
+               {
+                       switch (ev[i].type) {
+                       case EV_SYN:
+                               break;
+                       case EV_KEY:
+                               setkey(ev[i].code, ev[i].value);
+                               if (ev[i].code == KEY_RIGHTSHIFT)
+                                       pressed_l = !!ev[i].value;
+                               if (ev[i].code == KEY_RIGHTCTRL)
+                                       pressed_r = !!ev[i].value;
+                               break;
+                       case EV_ABS:
+                               which = (fd == ifd[DEV_LNUB]) ? 0 : 1;
+                               if (ev[i].code == ABS_X)
+                                       nubx[which] = ev[i].value;
+                               else if (ev[i].code == ABS_Y)
+                                       nuby[which] = ev[i].value;
+                               else
+                                       printf("unexpected EV_ABS code: %i\n", ev[i].code);
+                               break;
+                       case EV_SW:
+                               if (ev[i].code == SW_LID)
+                                       lid_closed = ev[i].value;
+                               else
+                                       printf("unexpected EV_SW code: %i\n", ev[i].code);
+                               break;
+                       case EV_MSC:
+                               if (ev[i].code == MSC_SCAN)
+                                       break;
+                               /* fallthrough */
+                       default:
+                               printf("unexpected event: type %i, code %d\n", ev[i].type, ev[i].code);
+                               break;
+                       }
+               }
+       }
+
+
+end:
+       if (ts != NULL)
+               ts_close(ts);
+       for (i = 0; i < DEVS_TOTAL; i++)
+               if (i != DEV_TS && ifd[i] != -1)
+                       close(ifd[i]);
+       munmap(screen, 800*480*2);
+       close(fbdev);
+       return 0;
+}
+
diff --git a/scripts/op_test_inputs b/scripts/op_test_inputs
new file mode 100755 (executable)
index 0000000..d459b18
--- /dev/null
@@ -0,0 +1,8 @@
+#!/bin/sh
+
+OLDDEPTH=`fbset | grep geometry | awk '{ print $6 }'`
+
+fbset -depth 16
+./op_runfbapp ./op_test_inputs_bin
+
+fbset -depth $OLDDEPTH