PageRenderTime 59ms CodeModel.GetById 11ms app.highlight 43ms RepoModel.GetById 1ms app.codeStats 0ms

/src/backend/x11-emu/ftk_source_x11.c

http://ftk.googlecode.com/
C | 285 lines | 226 code | 27 blank | 32 comment | 14 complexity | 4321b841b40a6b6bbddadc430fbd8270 MD5 | raw file
  1/*
  2 * File: ftk_source_x11.c	 
  3 * Author:	Li XianJing <xianjimli@hotmail.com>
  4 * Brief:	x11 event handler
  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-06 Li XianJing <xianjimli@hotmail.com> created
 29 *
 30 */
 31#include "ftk.h"
 32#include "ftk_typedef.h"
 33#include "ftk_key.h"
 34#include "ftk_log.h"
 35#include <X11/Xlib.h>
 36#include <X11/keysym.h>
 37#include "ftk_source_x11.h"
 38#include "ftk_display_x11.h"
 39
 40typedef struct _PrivInfo
 41{
 42	int fd;
 43	Window win;
 44	FtkEvent event;
 45	FtkDisplay* display;
 46	FtkOnEvent on_event;
 47	void* ctx;
 48}PrivInfo;
 49
 50static int ftk_source_x11_get_fd(FtkSource* thiz)
 51{
 52	DECL_PRIV(thiz, priv);
 53
 54	return priv->fd;
 55}
 56
 57static int ftk_source_x11_check(FtkSource* thiz)
 58{
 59	return -1;
 60}
 61
 62static const int s_key_map[] = 
 63{
 64	[0x0a] = FTK_KEY_1,
 65	[0x0b] = FTK_KEY_2,
 66	[0x0c] = FTK_KEY_3,
 67	[0x0d] = FTK_KEY_4,
 68	[0x0e] = FTK_KEY_5,
 69	[0x0f] = FTK_KEY_6,
 70	[0x10] = FTK_KEY_7,
 71	[0x11] = FTK_KEY_8,
 72	[0x12] = FTK_KEY_9,
 73	[0x13] = FTK_KEY_0,
 74	[0x14] = FTK_KEY_MINUS,
 75	[0x15] = FTK_KEY_EQUAL,
 76	[0x16] = FTK_KEY_BACKSPACE,
 77	[0x17] = FTK_KEY_TAB,
 78	[0x18] = FTK_KEY_q,
 79	[0x19] = FTK_KEY_w,
 80	[0x1a] = FTK_KEY_e,
 81	[0x1b] = FTK_KEY_r,
 82	[0x1c] = FTK_KEY_t,
 83	[0x1d] = FTK_KEY_y,
 84	[0x1e] = FTK_KEY_u,
 85	[0x1f] = FTK_KEY_i,
 86	[0x20] = FTK_KEY_o,
 87	[0x21] = FTK_KEY_p,
 88	[0x22] = FTK_KEY_BRACKETLEFT,
 89	[0x23] = FTK_KEY_BRACKETRIGHT,
 90	[0x24] = FTK_KEY_ENTER,
 91	[0x26] = FTK_KEY_a,
 92	[0x27] = FTK_KEY_s,
 93	[0x28] = FTK_KEY_d,
 94	[0x29] = FTK_KEY_f,
 95	[0x2a] = FTK_KEY_g,
 96	[0x2b] = FTK_KEY_h,
 97	[0x2c] = FTK_KEY_j,
 98	[0x2d] = FTK_KEY_k,
 99	[0x2e] = FTK_KEY_l,
100	[0x2f] = FTK_KEY_SEMICOLON,
101	[0x30] = FTK_KEY_QUOTERIGHT,
102	[0x31] = FTK_KEY_GRAVE, 
103	[0x32] = FTK_KEY_LEFTSHIFT,
104	[0x33] = FTK_KEY_BACKSLASH,
105	[0x34] = FTK_KEY_z,
106	[0x35] = FTK_KEY_x,
107	[0x36] = FTK_KEY_c,
108	[0x37] = FTK_KEY_v,
109	[0x38] = FTK_KEY_b,
110	[0x39] = FTK_KEY_n,
111	[0x3a] = FTK_KEY_m,
112	[0x3b] = FTK_KEY_COMMA,
113	[0x3c] = FTK_KEY_DOT,
114	[0x3d] = FTK_KEY_SLASH,
115	[0x3e] = FTK_KEY_RIGHTSHIFT,
116	[0x40] = FTK_KEY_LEFTALT,
117	[0x41] = FTK_KEY_SPACE,
118	[0x42] = FTK_KEY_CAPSLOCK,
119	[0x43] = FTK_KEY_F1,
120	[0x44] = FTK_KEY_F2,
121	[0x45] = FTK_KEY_F3,
122	[0x46] = FTK_KEY_F4,
123	[0x47] = FTK_KEY_F5,
124	[0x48] = FTK_KEY_F6,
125	[0x49] = FTK_KEY_F7,
126	[0x4a] = FTK_KEY_F8,
127	[0x61] = FTK_KEY_HOME,
128	[0x62] = FTK_KEY_UP,
129	[0x63] = FTK_KEY_PAGEUP,
130	[0x64] = FTK_KEY_LEFT,
131	[0x66] = FTK_KEY_RIGHT,
132	[0x67] = FTK_KEY_END,
133	[0x68] = FTK_KEY_DOWN,
134	[0x69] = FTK_KEY_PAGEDOWN,
135	[0x6a] = FTK_KEY_INSERT,
136	[0x6b] = FTK_KEY_DELETE,
137	[0x6f] = FTK_KEY_UP,
138	[0x71] = FTK_KEY_LEFT,
139	[0x72] = FTK_KEY_RIGHT,
140	[0x74] = FTK_KEY_DOWN,
141	[0x77] = FTK_KEY_DELETE,
142//	[0x71] = FTK_KEY_RIGHTALT,
143};
144
145static int ftk_source_x11_keymap(FtkSource* thiz, Display* display, int keycode)
146{
147	ftk_logd("0x%03x --> 0x%03x %c\n", keycode, s_key_map[0xff&keycode], (char)s_key_map[0xff&keycode]);
148
149	return s_key_map[0xff&keycode] ? s_key_map[0xff&keycode] : keycode;
150}
151
152static int on_x11_error (Display* display, XErrorEvent* event)
153{
154	ftk_loge("%s\n", __func__);
155	exit(0);
156
157	return 0;
158}
159
160static Ret ftk_source_x11_dispatch(FtkSource* thiz)
161{
162	XEvent event = {0};
163	DECL_PRIV(thiz, priv);
164	Display* display = (Display*)ftk_display_x11_get_xdisplay(priv->display);
165	Atom* win_del_atom = (Atom*)ftk_display_x11_get_win_del_atom(priv->display);
166	return_val_if_fail(priv->fd > 0, RET_FAIL); 
167
168	while(XPending (display))
169	{
170		XNextEvent(display, &event);
171		switch(event.type)
172		{
173			case ConfigureNotify:
174			{
175				priv->event.type = FTK_EVT_DISPLAY_CHANGED;
176				priv->event.u.display.width = event.xconfigure.width;
177				priv->event.u.display.height = event.xconfigure.height;
178				priv->event.u.display.display = thiz;
179
180				ftk_display_x11_on_resize(priv->display, event.xconfigure.width, event.xconfigure.height);
181
182				break;
183			}
184			case Expose:
185			{
186				ftk_display_update(priv->display, NULL, NULL, 0, 0);	
187				break;
188			}
189			case KeyPress:
190			case KeyRelease:
191			{
192			 	priv->event.u.key.code = ftk_source_x11_keymap(thiz, display, event.xkey.keycode);
193				priv->event.type = event.type == KeyPress ? FTK_EVT_KEY_DOWN : FTK_EVT_KEY_UP;
194
195				break;
196			}
197			case ButtonPress:
198			{
199				//ftk_logd("%s: ButtonPress: %d %d\n", __func__, event.xbutton.x, event.xbutton.y);
200				priv->event.type = FTK_EVT_MOUSE_DOWN;
201				priv->event.u.mouse.x = event.xbutton.x;
202				priv->event.u.mouse.y = event.xbutton.y;
203				break;
204			}
205			case ButtonRelease:
206			{
207				//ftk_logd("%s: ButtonRelease: %d %d\n", __func__, event.xbutton.x, event.xbutton.y);
208				priv->event.type = FTK_EVT_MOUSE_UP;
209				priv->event.u.mouse.x = event.xbutton.x;
210				priv->event.u.mouse.y = event.xbutton.y;
211				break;
212			}
213			case MotionNotify:
214			{
215				priv->event.u.mouse.x = event.xbutton.x;
216				priv->event.u.mouse.y = event.xbutton.y;
217				priv->event.type = FTK_EVT_MOUSE_MOVE;
218				break;
219			}
220			case DestroyNotify:
221			{
222				ftk_logd("%s: window destroied\n", __func__);	
223				break;
224			}
225			case ClientMessage:
226			{
227				if ((Atom)event.xclient.data.l[0] == *win_del_atom) {
228					FTK_QUIT();
229				}
230				break;
231			}
232			default:break;
233		}
234
235		if(priv->on_event != NULL && priv->event.type != FTK_EVT_NOP)
236		{
237			priv->on_event(priv->ctx, &priv->event);
238			priv->event.type = FTK_EVT_NOP;
239		}
240	}
241
242	return RET_OK;
243}
244
245static void ftk_source_x11_destroy(FtkSource* thiz)
246{
247	if(thiz != NULL)
248	{
249		DECL_PRIV(thiz, priv);
250		close(priv->fd);
251		FTK_ZFREE(thiz, sizeof(thiz) + sizeof(PrivInfo));
252	}
253
254	return;
255}
256
257FtkSource* ftk_source_x11_create(FtkDisplay* display, FtkOnEvent on_event, void* ctx)
258{
259	FtkSource* thiz = NULL;
260	
261	return_val_if_fail(display != NULL && on_event != NULL, NULL);
262
263	thiz = (FtkSource*)FTK_ZALLOC(sizeof(FtkSource) + sizeof(PrivInfo));
264
265	if(thiz != NULL)
266	{
267		DECL_PRIV(thiz, priv);
268		thiz->get_fd   = ftk_source_x11_get_fd;
269		thiz->check	   = ftk_source_x11_check;
270		thiz->dispatch = ftk_source_x11_dispatch;
271		thiz->destroy  = ftk_source_x11_destroy;
272
273		thiz->ref = 1;
274		priv->ctx = ctx;
275		priv->on_event = on_event;
276		priv->display = display;
277		priv->fd  = ConnectionNumber(ftk_display_x11_get_xdisplay(display));
278		priv->win = (Window)ftk_display_x11_get_xwindow(display);
279
280		XSetErrorHandler(on_x11_error);
281	}
282
283	return thiz;
284}
285