]> git.kernelconcepts.de Git - karo-tx-redboot.git/blob - packages/services/gfx/mw/v2_0/src/drivers/mou_yopy.c
Initial revision
[karo-tx-redboot.git] / packages / services / gfx / mw / v2_0 / src / drivers / mou_yopy.c
1 /*
2  * Microwindows touch screen driver for G.Mate YOPY
3  *
4  * Copyright (c) 2000 Century Software Embedded Technologies
5  *
6  * Requires /dev/yopy-ts kernel mouse driver.
7  */
8 #include <stdio.h>
9 #include <stdlib.h>
10 #include <unistd.h>
11 #include <errno.h>
12 #include <fcntl.h>
13 #include <math.h>
14 #include <sys/ioctl.h>
15 #include "device.h"
16
17 /* file descriptor for touch panel */
18 static int pd_fd = -1;
19
20 /* Hack extern to used when hiding the mouse cursor
21  * There needs to be a better way to do this
22 */
23 extern SCREENDEVICE scrdev;
24
25 static int cal[7];
26
27 typedef struct {
28         int x, y;
29 } XYPOINT;
30
31 #define TRANSFORMATION_UNITS_PER_PIXEL 4
32 static int GetPointerCalibrationData(void)
33 {
34   /*
35    * Read the calibration data from the calibration file.
36    * Calibration file format is seven coefficients separated by spaces.
37    */
38   
39   /* Get pointer calibration data from this file */
40   const char cal_filename[] = "/etc/ts.conf";
41
42   int items;
43
44   FILE* f = fopen(cal_filename, "r");
45   if ( f == NULL )
46     {
47       EPRINTF("Error %d opening pointer calibration file %s.\n",
48               errno, cal_filename);
49       return -1;
50     }
51
52   items = fscanf(f, "%d %d %d %d %d %d %d",
53                  &cal[0], &cal[1], &cal[2], &cal[3], &cal[4], &cal[5], &cal[6]);
54   if ( items != 7 )
55     {
56       EPRINTF("Improperly formatted pointer calibration file %s.\n",
57               cal_filename);
58       return -1;
59     }
60
61 #ifdef TEST
62   EPRINTF("a=%d b=%d c=%d d=%d e=%d f=%d s=%d\n",
63           cal[0], cal[1], cal[2], cal[3], cal[4], cal[5], cal[6]);
64 #endif
65
66   return 0;
67 }
68
69 static XYPOINT DeviceToScreen(XYPOINT p)
70 {
71   /*
72    * Transform device coordinates to screen coordinates.
73    * Take a point p in device coordinates and return the corresponding
74    * point in screen coodinates.
75    * This can scale, translate, rotate and/or skew, based on the coefficients
76    * calculated above based on the list of screen vs. device coordinates.
77    */
78   
79   static XYPOINT prev;
80   /* set slop at 3/4 pixel */
81   const short slop = TRANSFORMATION_UNITS_PER_PIXEL * 3 / 4;
82   XYPOINT new, out;
83   
84   /* transform */
85   new.x = (cal[0] * p.x + cal[1] * p.y + cal[2]) / cal[6];
86   new.y = (cal[3] * p.x + cal[4] * p.y + cal[5]) / cal[6];
87   
88   /* hysteresis (thanks to John Siau) */
89   if ( abs(new.x - prev.x) >= slop )
90     out.x = (new.x | 0x3) ^ 0x3;
91   else
92     out.x = prev.x;
93   
94   if ( abs(new.y - prev.y) >= slop )
95     out.y = (new.y | 0x3) ^ 0x3;
96   else
97     out.y = prev.y;
98   
99   prev = out;
100   
101   return out;
102 }
103
104 static int PD_Open(MOUSEDEVICE *pmd)
105 {
106   /*
107    * open up the touch-panel device.
108    * Return the fd if successful, or negative if unsuccessful.
109    */
110   
111   pd_fd = open("/dev/yopy-ts", O_NONBLOCK);
112   if (pd_fd < 0) {
113     EPRINTF("Error %d opening touch panel\n", errno);
114     return -1;
115   }
116   
117   GetPointerCalibrationData();
118   GdHideCursor(&scrdev);
119   
120   return pd_fd;
121 }
122
123 static void PD_Close(void)
124 {
125   /* Close the touch panel device. */
126   if (pd_fd >= 0)
127     close(pd_fd);
128   pd_fd = -1;
129 }
130
131 static int PD_GetButtonInfo(void)
132 {
133   /* get "mouse" buttons supported */
134   return MWBUTTON_L;
135 }
136
137 static void PD_GetDefaultAccel(int *pscale,int *pthresh)
138 {
139   /*
140    * Get default mouse acceleration settings
141    * This doesn't make sense for a touch panel.
142    * Just return something inconspicuous for now.
143    */
144   *pscale = 3;
145   *pthresh = 5;
146 }
147
148
149 static int PD_Read(MWCOORD *px, MWCOORD *py, MWCOORD *pz, int *pb)
150 {
151   /* read a data point */
152
153   unsigned long data;
154   int bytes_read;
155
156   XYPOINT transformed;
157
158   bytes_read = read(pd_fd, &data, sizeof(data));
159
160   if (bytes_read != sizeof(data)) {
161     if (errno == EINTR || errno == EAGAIN) {
162       return 0;
163     }
164     return 0;
165   }
166         
167   transformed.x = (data & 0x3ff);
168   transformed.y = (data >> 10) & 0x3ff;
169         
170   transformed = DeviceToScreen(transformed);
171         
172   transformed.x >>= 2;
173   transformed.y >>= 2;
174
175   *px = transformed.x;
176   *py = transformed.y;
177
178   *pb = (((data >> 31) & 0x1) ? MWBUTTON_L : 0);
179
180   *pz = 0;
181
182   if(! *pb )
183     return 3;                   /* only have button data */
184   else 
185     return 2;                   /* have full set of data */
186 }
187
188 MOUSEDEVICE mousedev = {
189   PD_Open,
190   PD_Close,
191   PD_GetButtonInfo,
192   PD_GetDefaultAccel,
193   PD_Read,
194   NULL
195 };
196
197 #ifdef TEST
198 int main(int argc, char ** v)
199 {
200   MWCOORD x, y, z;
201   int   b;
202   int result;
203   int mouse = -1;
204   DPRINTF("Opening touch panel...\n");
205   
206   if((result=PD_Open(0)) < 0)
207     DPRINTF("Error %d, result %d opening touch-panel\n", errno, result);
208   
209   while(1) {
210     result = PD_Read(&x, &y, &z, &b);
211     if( result > 0) {
212       if(mouse != b) {
213         mouse = b;
214         if(mouse) 
215           DPRINTF("Pen Down\n");
216         else
217           DPRINTF("Pen Up\n");
218       }
219       DPRINTF("%d,%d,%d,%d,%d\n", result, x, y, z, b);
220     }
221   }
222 }
223 #endif