1 /*
2    (c) Copyright 2001-2009  The world wide DirectFB Open Source Community (directfb.org)
3    (c) Copyright 2000-2004  Convergence (integrated media) GmbH
4 
5    All rights reserved.
6 
7    Written by Nikita Egorov <nikego@gmail.com>
8 
9    Calibration utility for PenMount's touchscreen panel. Run the program
10    and touch to center of left/top cross ( active cross is blinked ).
11    Then touch to right/bottom cross. The program will create four values for
12    penmout's driver. The values will be printed to the console.
13 
14    This file is subject to the terms and conditions of the MIT License:
15 
16    Permission is hereby granted, free of charge, to any person
17    obtaining a copy of this software and associated documentation
18    files (the "Software"), to deal in the Software without restriction,
19    including without limitation the rights to use, copy, modify, merge,
20    publish, distribute, sublicense, and/or sell copies of the Software,
21    and to permit persons to whom the Software is furnished to do so,
22    subject to the following conditions:
23 
24    The above copyright notice and this permission notice shall be
25    included in all copies or substantial portions of the Software.
26 
27    THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
28    EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
29    MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.
30    IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
31    CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT,
32    TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
33    SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
34 */
35 
36 #include <directfb.h>
37 
38 #include <time.h>
39 #include <stdio.h>
40 #include <stdlib.h>
41 #include <unistd.h>
42 #include <sys/types.h>
43 #include <fcntl.h>
44 #include <string.h>
45 
46 static IDirectFB *dfb;
47 static IDirectFBSurface *primary;
48 static IDirectFBEventBuffer *buffer;
49 static int sx,sy;
50 
51 int
main(int argc,char * argv[])52 main( int argc, char *argv[] )
53 {
54      int quit = 0;
55      DFBResult err;
56      DFBGraphicsDeviceDescription gdesc;
57 
58      char init_str[64];
59      const char* dev = "/dev/ttyS0";
60      char buf[4096]={0};
61 
62      char *home = getenv( "HOME" );
63      int   file;
64 
65      int leftx, topy, rightx, bottomy, ofs;
66      int mouse_x, mouse_y, tx1, ty1;
67      int touch, count, color;
68 	struct timespec rqtp,rmtp;
69 
70      if(home)
71          sprintf(init_str,"%s/.directfbrc",home);
72 	 else
73 	     strcpy(init_str,"root/.directfbrc");
74 
75 	 file = open ( init_str, O_RDONLY );
76 	 if ( file != -1 ){
77 	 	 char *pos, *pos2;
78            read(file, buf, sizeof(buf));
79 		 close(file);
80 
81 		 pos = strstr( buf, "penmount-device" );
82 		 if(pos){
83 	 		 pos = strchr(pos,'=');
84 		 	 if(pos){
85 		 	 	*pos++ = '\0';
86 	 		 	if( (pos2=strchr(pos,':'))||(pos2=strchr(pos,'\n')) )
87 	 	 			*pos2 = '\0';
88 		 	 	dev = pos;
89 		 	 }
90 		 }
91 	 }
92 	 printf( "penmount device '%s'\n", dev );
93 
94 	 sprintf( init_str,"--dfb:penmount-device=%s:raw", dev);
95 	 argv[argc++] = init_str;
96 
97      if (DirectFBInit( &argc, &argv ) != DFB_OK)
98           return 1;
99 
100      if (DirectFBCreate( &dfb ) != DFB_OK)
101           return 1;
102 
103      dfb->GetDeviceDescription( dfb, &gdesc );
104 
105 	 err = dfb->SetCooperativeLevel( dfb, DFSCL_FULLSCREEN );
106      if (err != DFB_OK)
107           DirectFBError( "Failed requesting exclusive access", err );
108 
109      err = dfb->CreateInputEventBuffer( dfb, DICAPS_ALL, DFB_FALSE, &buffer );
110      if (err != DFB_OK) {
111           DirectFBError( "CreateInputEventBuffer failed", err );
112           dfb->Release( dfb );
113           return 1;
114      }
115 
116      {
117           DFBSurfaceDescription dsc;
118 
119           dsc.flags = DSDESC_CAPS;
120           dsc.caps = (gdesc.drawing_flags & DSDRAW_BLEND) ?
121                          DSCAPS_PRIMARY | DSCAPS_FLIPPING :
122                          DSCAPS_PRIMARY | DSCAPS_FLIPPING | DSCAPS_SYSTEMONLY;
123 
124           err = dfb->CreateSurface( dfb, &dsc, &primary );
125           if (err != DFB_OK) {
126                DirectFBError( "Failed creating primary surface", err );
127                buffer->Release( buffer );
128                dfb->Release( dfb );
129                return 1;
130           }
131 
132           primary->GetSize( primary, &sx, &sy );
133      }
134 
135      primary->Clear( primary, 0x0, 0x0, 0x0, 0xFF );
136 
137      leftx = sx/10;
138      topy = sy/10;
139      rightx = sx*9/10;
140      bottomy = sy*9/10;
141      ofs = 10;
142 
143      primary->SetColor( primary,0xFF,0,0,0xFF );
144    	 primary->DrawLine( primary,rightx-ofs,bottomy,rightx+ofs,bottomy );
145      primary->DrawLine( primary,rightx,bottomy-ofs,rightx,bottomy+ofs );
146 
147      err = primary->Flip( primary, NULL, 0 );
148      if (err != DFB_OK) {
149           DirectFBError( "Failed flipping the primary surface", err );
150           primary->Release( primary );
151           buffer->Release( buffer );
152           dfb->Release( dfb );
153           return 1;
154      }
155 
156 	mouse_x=0,mouse_y=0,tx1=0,ty1=0;
157 	touch=0,count=0,color=0;
158 
159      while (!quit) {
160           DFBInputEvent evt;
161           rqtp.tv_nsec = 10000;
162           rqtp.tv_sec = 0;
163           nanosleep( &rqtp,&rmtp );
164           if (count++ >= 30){
165           	count = 0;
166           	color = !color;
167           	if (color)
168           		primary->SetColor( primary,0x00,0xFF,0,0xFF );
169           	else
170           		primary->SetColor( primary,0xFF,0x00,0,0xFF );
171 
172           	switch(touch){
173           		case 0:
174           			primary->DrawLine( primary,leftx-ofs,topy,leftx+ofs,topy );
175      				primary->DrawLine( primary,leftx,topy-ofs,leftx,topy+ofs );
176      				break;
177      			case 1:
178 				    primary->DrawLine( primary,rightx-ofs,bottomy,rightx+ofs,bottomy );
179 				    primary->DrawLine( primary,rightx,bottomy-ofs,rightx,bottomy+ofs );
180      				break;
181           	}
182           	primary->Flip( primary, NULL, 0 );
183           }
184 
185           while (buffer->GetEvent( buffer, DFB_EVENT(&evt) ) == DFB_OK) {
186           	if ( evt.type == DIET_AXISMOTION){
187           		if (evt.flags & DIEF_AXISABS) {
188 	               	switch (evt.axis) {
189 	               	case DIAI_X:
190 	                    mouse_x = evt.axisabs;
191 	               		break;
192 	               	case DIAI_Y:
193 	                    mouse_y = evt.axisabs;
194 	                    break;
195 	               default:
196 	                    break;
197 	               }
198           		}
199           	}
200           	if ( evt.type == DIET_BUTTONPRESS ){
201           		switch(++touch){
202           			case 1: //save first touchscreen position
203           				tx1=mouse_x;
204           				ty1=mouse_y;
205           				break;
206           			case 2://build new calibration values and quit
207           			{
208           				float dx = ((float)mouse_x-tx1)/(rightx-leftx);
209           				float dy = ((float)mouse_y-ty1)/(bottomy-topy);
210           				printf( "Insert followed values into source code of penmount's driver\n'inputdrivers/penmount/penmount.c:96,99' and rebuild:\n" );
211           				printf( "min_x=%d min_y=%d\n",(int)(tx1-leftx*dx+.5),(int)(ty1-topy*dy+.5));
212            				printf( "max_x=%d max_y=%d\n",(int)(mouse_x+leftx*dx+.5),(int)(mouse_y+topy*dy+.5));
213  	                 	quit = 1;
214  	                 	break;
215           			}
216            		}
217            	}
218             if (evt.type == DIET_KEYPRESS  &&  evt.key_id == DIKI_ESCAPE)
219                  quit = 1;
220           }
221      }
222      primary->Release( primary );
223      buffer->Release( buffer );
224      dfb->Release( dfb );
225 
226      return 0;
227 }
228 
229