PageRenderTime 681ms CodeModel.GetById 473ms app.highlight 95ms RepoModel.GetById 106ms app.codeStats 0ms

/src/backend/native/ftk_source_input.c

http://ftk.googlecode.com/
C | 346 lines | 279 code | 32 blank | 35 comment | 33 complexity | 838819008c858a987a384aa24e1ce83a MD5 | raw file
  1/*
  2 * File: ftk_source_input.c    
  3 * Author:  Li XianJing <xianjimli@hotmail.com>
  4 * Brief:   source to handle /dev/input/xx
  5 *
  6 * Copyright (c) 2009 - 2010  Li XianJing <xianjimli@hotmail.com>
  7 *
  8 * Licensed under the Academic Free License version 2.1
  9 *
 10 * This program is free software; you can redistribute it and/or modify
 11 * it under the terms of the GNU General Public License as published by
 12 * the Free Software Foundation; either version 2 of the License, or
 13 * (at your option) any later version.
 14 *
 15 * This program is distributed in the hope that it will be useful,
 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 18 * GNU General Public License for more details.
 19 *
 20 * You should have received a copy of the GNU General Public License
 21 * along with this program; if not, write to the Free Software
 22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
 23 */
 24
 25/*
 26 * History:
 27 * ================================================================
 28 * 2009-10-03 Li XianJing <xianjimli@hotmail.com> created
 29 *
 30 */
 31
 32#include "ftk_log.h"
 33#include "ftk_globals.h"
 34#include "ftk_key.h"
 35#include "ftk_display.h"
 36#include <linux/input.h>
 37#include "ftk_source_input.h"
 38
 39#ifndef EV_SYN
 40#define EV_SYN 0x00
 41#endif
 42
 43typedef struct _PrivInfo
 44{
 45	int fd;
 46	int x;
 47	int y;
 48	FtkEvent event;
 49	FtkOnEvent on_event;
 50	void* user_data;
 51	char filename[64];
 52}PrivInfo;
 53
 54#include <linux/input.h>
 55
 56/*FIXME: complete the keymap table.*/
 57static unsigned short s_key_map[0x100] = 
 58{
 59	[KEY_1]           =  FTK_KEY_1,
 60	[KEY_2]           =  FTK_KEY_2,
 61	[KEY_3]           =  FTK_KEY_3,
 62	[KEY_4]           =  FTK_KEY_4,
 63	[KEY_5]           =  FTK_KEY_5,
 64	[KEY_6]           =  FTK_KEY_6,
 65	[KEY_7]           =  FTK_KEY_7,
 66	[KEY_8]           =  FTK_KEY_8,
 67	[KEY_9]           =  FTK_KEY_9,
 68	[KEY_0]           =  FTK_KEY_0,
 69	[KEY_A]           =  FTK_KEY_a,
 70	[KEY_B]           =  FTK_KEY_b,
 71	[KEY_C]           =  FTK_KEY_c,
 72	[KEY_D]           =  FTK_KEY_d,
 73	[KEY_E]           =  FTK_KEY_e,
 74	[KEY_F]           =  FTK_KEY_f,
 75	[KEY_G]           =  FTK_KEY_g,
 76	[KEY_H]           =  FTK_KEY_h,
 77	[KEY_I]           =  FTK_KEY_i,
 78	[KEY_J]           =  FTK_KEY_j,
 79	[KEY_K]           =  FTK_KEY_k,
 80	[KEY_L]           =  FTK_KEY_l,
 81	[KEY_M]           =  FTK_KEY_m,
 82	[KEY_N]           =  FTK_KEY_n,
 83	[KEY_O]           =  FTK_KEY_o,
 84	[KEY_P]           =  FTK_KEY_p,
 85	[KEY_Q]           =  FTK_KEY_q,
 86	[KEY_R]           =  FTK_KEY_r,
 87	[KEY_S]           =  FTK_KEY_s,
 88	[KEY_T]           =  FTK_KEY_t,
 89	[KEY_U]           =  FTK_KEY_u,
 90	[KEY_V]           =  FTK_KEY_v,
 91	[KEY_W]           =  FTK_KEY_w,
 92	[KEY_X]           =  FTK_KEY_x,
 93	[KEY_Y]           =  FTK_KEY_y,
 94	[KEY_Z]           =  FTK_KEY_z,
 95	[KEY_RIGHTCTRL]   =  FTK_KEY_RIGHTCTRL,
 96	[KEY_RIGHTALT]    =  FTK_KEY_RIGHTALT,
 97	[KEY_HOME]        =  FTK_KEY_HOME,
 98	[KEY_UP]          =  FTK_KEY_UP,
 99	[KEY_PAGEUP]      =  FTK_KEY_PAGEUP,
100	[KEY_LEFT]        =  FTK_KEY_LEFT,
101	[KEY_RIGHT]       =  FTK_KEY_RIGHT,
102	[KEY_END]         =  FTK_KEY_END,
103	[KEY_DOWN]        =  FTK_KEY_DOWN,
104	[KEY_PAGEDOWN]    =  FTK_KEY_PAGEDOWN,
105	[KEY_INSERT]      =  FTK_KEY_INSERT,
106	[KEY_DELETE]      =  FTK_KEY_DELETE,
107	[KEY_F1]          =  FTK_KEY_F1,
108	[KEY_F2]          =  FTK_KEY_F2,
109	[KEY_F3]          =  FTK_KEY_F3,
110	[KEY_F4]          =  FTK_KEY_F4,
111	[KEY_F5]          =  FTK_KEY_F5,
112	[KEY_F6]          =  FTK_KEY_F6,
113	[KEY_F7]          =  FTK_KEY_F7,
114	[KEY_F8]          =  FTK_KEY_F8,
115	[KEY_F9]          =  FTK_KEY_F9,
116	[KEY_F10]         =  FTK_KEY_F10,
117	[KEY_COMMA]       =  FTK_KEY_COMMA,
118	[KEY_DOT]         =  FTK_KEY_DOT,
119	[KEY_SLASH]       =  FTK_KEY_SLASH,
120	[KEY_RIGHTSHIFT]  =  FTK_KEY_RIGHTSHIFT,
121	[KEY_LEFTALT]     =  FTK_KEY_LEFTALT,
122	[KEY_SPACE]       =  FTK_KEY_SPACE,
123	[KEY_CAPSLOCK]    =  FTK_KEY_CAPSLOCK,
124	[KEY_SEMICOLON]   =  FTK_KEY_SEMICOLON,
125	[KEY_LEFTSHIFT]   =  FTK_KEY_LEFTSHIFT,
126	[KEY_BACKSLASH]   =  FTK_KEY_BACKSLASH,
127	[KEY_LEFTBRACE]   =  FTK_KEY_LEFTBRACE,
128	[KEY_RIGHTBRACE]  =  FTK_KEY_RIGHTBRACE,
129	[KEY_ENTER]       =  FTK_KEY_ENTER,
130	[KEY_LEFTCTRL]    =  FTK_KEY_LEFTCTRL,
131	[KEY_MINUS]       =  FTK_KEY_MINUS,
132	[KEY_EQUAL]       =  FTK_KEY_EQUAL,
133	[KEY_BACKSPACE]   =  FTK_KEY_BACKSPACE,
134	[KEY_TAB]         =  FTK_KEY_TAB,
135	[KEY_ESC]         =  FTK_KEY_ESC,
136	[139]             =  FTK_KEY_F2, /*map menu to f2*/
137//	[KEY_SEND]        =  FTK_KEY_SEND,
138//	[KEY_REPLY]       =  FTK_KEY_REPLY,
139//	[KEY_SAVE]        =  FTK_KEY_SAVE,
140	[KEY_POWER]       =  FTK_KEY_POWER
141};
142
143static int ftk_source_input_get_fd(FtkSource* thiz)
144{
145	DECL_PRIV(thiz, priv);
146
147	return priv->fd;
148}
149
150static int ftk_key_map(FtkSource* thiz, int key)
151{
152	return s_key_map[key] != 0 ? s_key_map[key] : key;
153}
154
155static int ftk_source_input_check(FtkSource* thiz)
156{
157	return -1;
158}
159
160static Ret ftk_source_input_dispatch(FtkSource* thiz)
161{
162	int ret = 0;
163	DECL_PRIV(thiz, priv);
164	struct input_event ievent;
165	return_val_if_fail(priv->fd > 0, RET_FAIL);	
166	ret = read(priv->fd, &ievent, sizeof(ievent));
167
168	if(ret != sizeof(ievent))
169	{
170		ftk_logd("%s:%d read from %s failed(ret=%d, errno=%d)\n", __func__, __LINE__, priv->filename, ret, errno);
171	}
172
173	return_val_if_fail(ret == sizeof(ievent), RET_FAIL);
174
175	switch(ievent.type)
176	{
177		case EV_KEY:
178		{
179			if(ievent.code == BTN_LEFT || ievent.code == BTN_RIGHT 
180				|| ievent.code == BTN_MIDDLE || ievent.code == BTN_TOUCH)
181			{
182				priv->event.type = ievent.value ? FTK_EVT_MOUSE_DOWN : FTK_EVT_MOUSE_UP;
183			}
184			else
185			{
186				priv->event.type = ievent.value ? FTK_EVT_KEY_DOWN : FTK_EVT_KEY_UP;
187				priv->event.u.key.code = ftk_key_map(thiz, ievent.code);
188				if(priv->on_event != NULL && priv->event.type != FTK_EVT_NOP)
189				{
190					priv->on_event(priv->user_data, &priv->event);
191					priv->event.type = FTK_EVT_NOP;
192				}
193				ftk_logd("%s: %02x --> %02x\n", __func__, ievent.code, priv->event.u.key.code);
194			}
195
196			break;
197		}
198		case EV_ABS:
199		{
200			switch(ievent.code)
201			{
202				case ABS_X:
203				{
204					priv->x = ievent.value;
205					break;
206				}
207				case ABS_Y:
208				{
209					priv->y = ievent.value;
210					break;
211				}
212				default:break;
213			}
214			if(priv->event.type == FTK_EVT_NOP)
215			{
216				priv->event.type = FTK_EVT_MOUSE_MOVE;
217			}
218
219			break;
220		}
221		case EV_REL:
222		{
223			switch(ievent.code)
224			{
225				case REL_X:
226				{
227					priv->x += ievent.value;
228					break;
229				}
230				case REL_Y:
231				{
232					priv->y += ievent.value;
233					break;
234				}
235				default:break;
236			}
237
238			if(priv->event.type == FTK_EVT_NOP)
239			{
240				priv->event.type = FTK_EVT_MOUSE_MOVE;
241			}
242
243			break;
244		}
245		case EV_SYN:
246		{
247			switch(priv->event.type)
248			{
249				case FTK_EVT_MOUSE_DOWN:
250				case FTK_EVT_MOUSE_UP:
251				case FTK_EVT_MOUSE_MOVE:
252				{
253					int max_x = ftk_display_width(ftk_default_display());
254					int max_y = ftk_display_height(ftk_default_display());
255
256					priv->x = priv->x > 0 ? priv->x : 0;
257					priv->y = priv->y > 0 ? priv->y : 0;
258					priv->x = priv->x < max_x ? priv->x : max_x;
259					priv->y = priv->y < max_y ? priv->y : max_y;
260
261					priv->event.u.mouse.x = priv->x;
262					priv->event.u.mouse.y = priv->y;
263					break;
264				}
265				default:break;
266			}
267			if(priv->on_event != NULL && priv->event.type != FTK_EVT_NOP)
268			{
269				priv->on_event(priv->user_data, &priv->event);
270				priv->event.type = FTK_EVT_NOP;
271			}
272			break;
273		}
274		default:break;
275	}
276
277	return RET_OK;
278}
279
280static void ftk_source_input_destroy(FtkSource* thiz)
281{
282	if(thiz != NULL)
283	{
284		DECL_PRIV(thiz, priv);
285
286		close(priv->fd);
287		FTK_ZFREE(thiz, sizeof(thiz) + sizeof(PrivInfo));
288	}
289
290	return;
291}
292
293FtkSource* ftk_source_input_create(const char* filename, FtkOnEvent on_event, void* user_data)
294{
295	FtkSource* thiz = (FtkSource*)FTK_ZALLOC(sizeof(FtkSource) + sizeof(PrivInfo));
296
297	if(thiz != NULL)
298	{
299		int grab = 0;
300		char name[100] = {0};
301		DECL_PRIV(thiz, priv);
302		thiz->get_fd   = ftk_source_input_get_fd;
303		thiz->check    = ftk_source_input_check;
304		thiz->dispatch = ftk_source_input_dispatch;
305		thiz->destroy  = ftk_source_input_destroy;
306
307		thiz->ref = 1;
308		priv->fd = open(filename, O_RDONLY);
309		ftk_strncpy(priv->filename, filename, sizeof(priv->filename));
310
311		if(priv->fd < 0)
312		{
313			FTK_ZFREE(thiz, sizeof(thiz) + sizeof(PrivInfo));
314			return NULL;
315		}
316#ifdef PC_EMU
317		/*use uinput only.*/
318		if(ioctl(priv->fd, EVIOCGNAME(sizeof(name) - 1), &name) < 0 || name[0] != 'v')
319		{
320			close(priv->fd);
321			priv->fd = -1;
322
323			FTK_ZFREE(thiz, sizeof(thiz) + sizeof(PrivInfo));
324			return NULL;
325		}
326
327		/*grab uinput to prevent event broadcasting*/
328		if(ioctl(priv->fd, EVIOCGRAB, &grab) < 0)
329		{
330			close(priv->fd);
331			priv->fd = -1;
332			FTK_ZFREE(thiz, sizeof(thiz) + sizeof(PrivInfo));
333			return NULL;
334		}
335#else
336		(void)name;
337		(void)grab;
338#endif
339		priv->on_event = on_event;
340		priv->user_data = user_data;
341		printf("%s: %d=%s priv->user_data=%p\n", __func__, priv->fd, filename, priv->user_data);
342	}
343
344	return thiz;
345}
346