From 7fe60435bce6595a9c58a9bfd8244d74b5320e96 Mon Sep 17 00:00:00 2001 From: Benjamin Franzke Date: Tue, 15 Jan 2013 08:46:13 +0100 Subject: Import DirectFB141_2k11R3_beta5 --- Source/DirectFB/inputdrivers/dynapro/dynapro.c | 356 +++++++++++++++++++++++++ 1 file changed, 356 insertions(+) create mode 100755 Source/DirectFB/inputdrivers/dynapro/dynapro.c (limited to 'Source/DirectFB/inputdrivers/dynapro/dynapro.c') diff --git a/Source/DirectFB/inputdrivers/dynapro/dynapro.c b/Source/DirectFB/inputdrivers/dynapro/dynapro.c new file mode 100755 index 0000000..11ab3fb --- /dev/null +++ b/Source/DirectFB/inputdrivers/dynapro/dynapro.c @@ -0,0 +1,356 @@ +/* + Written by Pär Degerman + + This library is free software; you can redistribute it and/or + modify it under the terms of the GNU Lesser General Public + License as published by the Free Software Foundation; either + version 2 of the License, or (at your option) any later version. + + This library is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + Lesser General Public License for more details. + + You should have received a copy of the GNU Lesser General Public + License along with this library; if not, write to the + Free Software Foundation, Inc., 59 Temple Place - Suite 330, + Boston, MA 02111-1307, USA. + + + NOTES + ===== + This driver is based heavily on code from two other DirectFB + drivers, namely mutouch.c by Simon Ueng and elo.c by Byron + Stanoszek and Brandon Reynolds, so a lot of credit should go + to those people and not me. + + INSTRUCTIONS + ============ + You should change DYNAPRO_MIN_X and DYNAPRO_MIN_Y to match + the orientation of your touchscreen. + +*/ + +#include + +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include + +DFB_INPUT_DRIVER( dynapro ) + +#define DYNAPRO_DEVICE "/dev/ttyS0" +#define DYNAPRO_BAUD B9600 +#define DYNAPRO_PACKET_SIZE 5 + +#define DYNAPRO_SCREENWIDTH 800 +#define DYNAPRO_SCREENHEIGHT 600 +#define DYNAPRO_MINX 800 +#define DYNAPRO_MINY 600 + +#define DYNAPRO_CMD_TOUCH 0x81 +#define DYNAPRO_CMD_UNTOUCH 0x80 + +typedef struct __dynaproData__ { + int fd; + DirectThread *thread; + CoreInputDevice *device; + + unsigned short screen_width; + unsigned short screen_height; + unsigned short min_x; + unsigned short min_y; + + unsigned short x; + unsigned short y; + unsigned char action; +} dynaproData; + +/* Read a packet from touchcontroller */ +static inline unsigned char *dynapro_getpck(int fd) +{ + static unsigned char packet[DYNAPRO_PACKET_SIZE]; + static unsigned int len = 0, start = 0; + + while(1) { + if (read(fd, &packet[len++], 1) < 1) { + break; + } + + if (0 == start) { + if (packet[len-1] & 0x80) { + /* Packet start found */ + start = 1; + continue; + } else { + /* Continue searching for packet start */ + len = 0; + start = 0; + continue; + } + } else if (len < DYNAPRO_PACKET_SIZE) { + /* Continue until we have a full packet */ + start = 1; + continue; + } + + /* A full packet received */ + len = 0; + start = 0; + return packet; + } + + return NULL; +} + +/* Remove all input translations over tty serial controller. + * + * set=1: Saves current settings then turns rawmode on. + * set=0: Restores controller to previous saved value. + */ +static void tty_rawmode(int fd, int set) +{ + static struct termios tbuf, termios_save; + + if(set) { + tcgetattr(fd, &termios_save); + tbuf = termios_save; + + tbuf.c_iflag = 0; /* No input processing */ + tbuf.c_oflag = 0; /* No output processing */ + tbuf.c_lflag = 0; /* Disable erase/kill, signals, and echo */ + + /* Set baud & 1-char read mode */ + tbuf.c_cflag = DYNAPRO_BAUD | CS8 | CLOCAL | CREAD; + + tcsetattr(fd, TCSANOW, &tbuf); + } else { + tcsetattr(fd, TCSANOW, &termios_save); + } +} + +/* Open file descriptor to touch device */ +static int dynaproOpenDevice(char *device) +{ + int fd; + + if((fd = open(device, O_RDWR|O_NOCTTY)) == -1) { + D_PERROR("DirectFB/dynbapro: Error opening '%s'!\n",device); + return -1; + } + + if((flock(fd, LOCK_EX|LOCK_NB)) == -1) { + D_PERROR("DirectFB/dynbapro: Error locking '%s'!\n",device); + close(fd); + return -1; + } + + tty_rawmode(fd,1); + + return fd; +} + + +static int dynaproGetEvent(dynaproData *event) +{ + unsigned char *ptr; + unsigned int cmd, x, y; + + /* read packet */ + if(!(ptr = dynapro_getpck(event->fd))) { + return -1; + } + + /* Get command (touch/untouch) and coordinates */ + cmd = ptr[0]; + x = (event->screen_width * ((ptr[3] << 8) + ptr[4])) / 0x0fff; + y = (event->screen_height* ((ptr[1] << 8) + ptr[2])) / 0x0fff; + + if (event->min_x) + x = event->min_x - x; + if (event->min_y) + y = event->min_y - y; + + event->action = cmd; + event->x = x; + event->y = y; + + return 0; +} + + +/* The main routine for dynapro */ +static void *dynaproTouchEventThread(DirectThread *thread, void *driver_data) +{ + dynaproData *data = (dynaproData *) driver_data; + + /* Read data */ + while (1) { + DFBInputEvent evt; + + if(dynaproGetEvent(data) == -1) { + continue; + } + direct_thread_testcancel(thread); + + /* Dispatch axis */ + evt.type = DIET_AXISMOTION; + evt.flags = DIEF_AXISABS; + evt.axis = DIAI_X; + evt.axisabs = data->x; + dfb_input_dispatch(data->device, &evt); + + evt.type = DIET_AXISMOTION; + evt.flags = DIEF_AXISABS; + evt.axis = DIAI_Y; + evt.axisabs = data->y; + dfb_input_dispatch(data->device, &evt); + + /* Dispatch touch event */ + if (DYNAPRO_CMD_UNTOUCH == data->action) + evt.type = DIET_BUTTONRELEASE; + else + evt.type = DIET_BUTTONPRESS; + + evt.flags = DIEF_NONE; + evt.button = DIBI_LEFT; + + dfb_input_dispatch(data->device, &evt); + direct_thread_testcancel(thread); + } + + return NULL; +} + + +/* exported symbols */ +static int driver_get_available( void ) +{ + int fd; + + fd = dynaproOpenDevice(DYNAPRO_DEVICE); + if (fd < 0) { + return 0; + } + close(fd); + + return 1; +} + +static void driver_get_info( InputDriverInfo *info ) +{ + /* fill driver info structure */ + snprintf(info->name, DFB_INPUT_DRIVER_INFO_NAME_LENGTH, + "dynapro" ); + snprintf(info->vendor, DFB_INPUT_DRIVER_INFO_VENDOR_LENGTH, + "3M" ); + + info->version.major = 0; + info->version.minor = 1; +} + +static DFBResult driver_open_device(CoreInputDevice *device, + unsigned int number, + InputDeviceInfo *info, + void **driver_data) +{ + int fd; + dynaproData *data; + + /* open device */ + fd = dynaproOpenDevice(DYNAPRO_DEVICE); + if(fd < 0) { + D_PERROR("DirectFB/dynapro: Error opening '"DYNAPRO_DEVICE"'!\n"); + return DFB_INIT; + } + + data = D_CALLOC(1, sizeof(dynaproData)); + if (!data) { + tty_rawmode(fd, 0); + close(fd); + return D_OOM(); + } + + data->fd = fd; + data->device = device; + + /* FIXME! Use settings instead? */ + data->screen_width = DYNAPRO_SCREENWIDTH; + data->screen_height = DYNAPRO_SCREENHEIGHT; + data->min_x = DYNAPRO_MINX; + data->min_y = DYNAPRO_MINY; + + /* fill device info structure */ + snprintf(info->desc.name, DFB_INPUT_DEVICE_DESC_NAME_LENGTH, + "dynapro"); + snprintf(info->desc.vendor, DFB_INPUT_DEVICE_DESC_VENDOR_LENGTH, + "3M"); + + info->prefered_id = DIDID_MOUSE; + info->desc.type = DIDTF_MOUSE; + info->desc.caps = DICAPS_AXES | DICAPS_BUTTONS; + info->desc.max_axis = DIAI_Y; + info->desc.max_button = DIBI_LEFT; + + /* start input thread */ + data->thread = direct_thread_create(DTT_INPUT, + dynaproTouchEventThread, + data, + "Dynapro Touch Input"); + + /* set private data pointer */ + *driver_data = data; + + return DFB_OK; +} + +/* + * Fetch one entry from the device's keymap if supported. + */ +static DFBResult driver_get_keymap_entry(CoreInputDevice *device, + void *driver_data, + DFBInputDeviceKeymapEntry *entry) +{ + return DFB_UNSUPPORTED; +} + +static void driver_close_device(void *driver_data) +{ + dynaproData *data = (dynaproData *)driver_data; + + /* stop input thread */ + direct_thread_cancel(data->thread); + direct_thread_join(data->thread); + direct_thread_destroy(data->thread); + + /* restore termnial settings for the port */ + tty_rawmode(data->fd, 0); + + /* close device */ + close(data->fd); + + /* free private data */ + D_FREE(data); +} -- cgit