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/penmount/penmount.c | 363 +++++++++++++++++++++++ 1 file changed, 363 insertions(+) create mode 100755 Source/DirectFB/inputdrivers/penmount/penmount.c (limited to 'Source/DirectFB/inputdrivers/penmount/penmount.c') diff --git a/Source/DirectFB/inputdrivers/penmount/penmount.c b/Source/DirectFB/inputdrivers/penmount/penmount.c new file mode 100755 index 0000000..76bce8e --- /dev/null +++ b/Source/DirectFB/inputdrivers/penmount/penmount.c @@ -0,0 +1,363 @@ +/* + (c) Copyright 2000-2002 Fulgid Technology Co., Ltd. + + All rights reserved. + + Written by Simon Ueng + Modified by Nikita Egorov + + 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. + + This driver is a re-write from the MuTouch driver. +*/ + +#include + +#include +#include +#include +#include +#include +#include + +#include + +#include +#include + +#include + +#include + +#include +#include + +#include +#include + +#include + +#include +#include +#include +#include +#include + +#include + + +DFB_INPUT_DRIVER( penmount ) + +#define BAUDRATE B19200 + +#define PeM_REPORT_SIZE 5 +#define PeM_PACKET_SIZE 10 +#define PeM_SCREENWIDTH 640 +#define PeM_SCREENHEIGHT 480 +#define PeM_MINX 0 +#define PeM_MINY 0 + +#define PEM_PANEL_TOUCH 0x01 +#define PEM_PANEL_UNTOUCH 0x00 + + +/* Event mask */ +#define PeM_PANEL_TOUCH_MASK 0x40 +#define PeM_PANEL_SYNC_MASK 0x80 + +typedef struct __PeMData__ { + int fd; + DirectThread *thread; + CoreInputDevice *device; + unsigned short x; + unsigned short y; + unsigned short screen_width; + unsigned short screen_height; + unsigned short min_x; + unsigned short min_y; + unsigned char action; +} PeMData; + +/* Global Variables */ +static unsigned char packet[PeM_PACKET_SIZE]; + + /* touchscreen values of left/top position */ +static int min_x=19,min_y=1001; + + /* touchscreen values of right/bottom position */ +static int max_x=946,max_y=62; + + +static inline void __mdelay(unsigned int msec){ + struct timespec delay; + + delay.tv_sec = 0; + delay.tv_nsec = msec * 1000000; + nanosleep (&delay, NULL); +} + +static inline void PeMSendPacket(int file, unsigned char *packet, unsigned char len){ + + write (file, packet, len); +} + +static inline void PeMReadPacket(int file, unsigned char *packet){ + int n = 0; + memset (packet, 0, PeM_PACKET_SIZE); + while ((n += read (file, packet+n, PeM_REPORT_SIZE-n)) != PeM_REPORT_SIZE); +} + +static int PeMPollDevice(const char *device){ + int file; + struct termios options; + + /* Make raw I/O */ + memset (&options, 0, sizeof (struct termios)); + + /* Open I/O port */ + file = open (device, O_RDWR | O_NOCTTY); + + options.c_cflag = BAUDRATE | CS8 | CLOCAL | CREAD; + options.c_cc[VMIN] = 1; + options.c_cc[VTIME] = 0; + + tcflush (file, TCIFLUSH); + tcsetattr (file, TCSANOW, &options); + + return file; +} + +static inline int PeMInitialize(int file){ + /* it's a stub */ + /* I dont know how get information about PenMount device... */ + + return 1; +} + +static int PeMOpenDevice(char *device){ + int fd; + int res; + + char *pos = strstr(device, ":raw"); + if (pos) {// raw data + max_x = min_x; + max_y = min_y; + *pos = 0; + } + fd = PeMPollDevice (device); + if ((res = PeMInitialize (fd)) == 0) { + close (fd); + return res; + } + return fd; +} + +static int convert_x(int x,PeMData *event){ + if (max_x != min_x) + return .5+event->screen_width*((double)x - min_x)/(max_x - min_x); + else + return x; +} + +static int convert_y(int y,PeMData *event){ + if (max_y != min_y) + return .5+event->screen_height*((double)y - min_y)/(max_y - min_y); + else + return y; +} + +#define WORD_ASSEMBLY(byte1, byte2) (((byte2) << 7) | (byte1)) + +static int PeMGetEvent(PeMData *event){ + + PeMReadPacket(event->fd, packet); + /* Sync bit always must be set to 1 */ + if ((*packet & PeM_PANEL_SYNC_MASK) == 0) + return 0; + + if (*packet & PeM_PANEL_TOUCH_MASK) + event->action = PEM_PANEL_TOUCH; + else + event->action = PEM_PANEL_UNTOUCH; + + event->y = convert_y( WORD_ASSEMBLY(packet[2], packet[1]),event); + event->x = convert_x( WORD_ASSEMBLY(packet[4], packet[3]),event); + + if (event->min_x) + event->x = event->min_x - event->x; + if (event->min_y) + event->y = event->min_y - event->y; + + return 1; +} + +/* The main routine for PenMount */ +static void *PenMountEventThread(DirectThread *thread, void *driver_data){ + + PeMData *data = (PeMData *) driver_data; + + /* Read data */ + while (1) { + DFBInputEvent evt; + static int pressed = 0; + + if (!PeMGetEvent (data)) + 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 */ + switch (data->action) { + case PEM_PANEL_TOUCH: + if (!pressed) + evt.type = DIET_BUTTONPRESS; + pressed = 1; + break; + case PEM_PANEL_UNTOUCH: + if (pressed) + evt.type = DIET_BUTTONRELEASE; + pressed = 0; + break; + } + + 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; + + if (!dfb_config->penmount_device) + return 0; + + fd = PeMOpenDevice (dfb_config->penmount_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, + "PenMount 9509" ); + snprintf(info->vendor, DFB_INPUT_DRIVER_INFO_VENDOR_LENGTH, + "AMT" ); + + 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; + PeMData *data; + + /* open device */ + fd = PeMOpenDevice (dfb_config->penmount_device); + if (fd < 0) { + D_PERROR("DirectFB/PenMount: Error opening '%s'!\n", dfb_config->penmount_device); + return DFB_INIT; + } + + data = D_CALLOC (1, sizeof(PeMData)); + if (!data) { + close (fd); + return D_OOM (); + } + + data->fd = fd; + data->device = device; + + /* Must define the correct resolution of screen */ + data->screen_width = PeM_SCREENWIDTH; + data->screen_height = PeM_SCREENHEIGHT; + + /* The following variable are defined to adjust the orientation of + * the touchscreen. Variables are either max screen height/width or 0. + */ + data->min_x = PeM_MINX; + data->min_y = PeM_MINY; + + /* fill device info structure */ + snprintf(info->desc.name, DFB_INPUT_DEVICE_DESC_NAME_LENGTH, + "PenMount 9509"); + snprintf(info->desc.vendor, DFB_INPUT_DEVICE_DESC_VENDOR_LENGTH, + "AMT"); + + 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, PenMountEventThread, data, "PenMount 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){ + PeMData *data = (PeMData *)driver_data; + + /* stop input thread */ + direct_thread_cancel (data->thread); + direct_thread_join (data->thread); + direct_thread_destroy (data->thread); + + /* close device */ + close (data->fd); + + /* free private data */ + D_FREE (data); +} -- cgit