summaryrefslogtreecommitdiff
path: root/src/lib/ecore_fb
diff options
context:
space:
mode:
authorVincent Torri <vincent.torri@gmail.com>2012-12-02 22:35:45 +0000
committerVincent Torri <vincent.torri@gmail.com>2012-12-02 22:35:45 +0000
commit7d6010b12c47a20e492da808e3192c3f87dab619 (patch)
tree26c6fd189e046a76560c0bc740b85f4d767ae399 /src/lib/ecore_fb
parent53fc441d5475155965d92da89502fe4634a561b2 (diff)
downloadefl-7d6010b12c47a20e492da808e3192c3f87dab619.tar.gz
merge: add escape ecore, fix several bugs
SVN revision: 79995
Diffstat (limited to 'src/lib/ecore_fb')
-rw-r--r--src/lib/ecore_fb/Ecore_Fb.h100
-rw-r--r--src/lib/ecore_fb/ecore_fb.c129
-rw-r--r--src/lib/ecore_fb/ecore_fb_kbd.c326
-rw-r--r--src/lib/ecore_fb/ecore_fb_keytable.h129
-rw-r--r--src/lib/ecore_fb/ecore_fb_li.c721
-rw-r--r--src/lib/ecore_fb/ecore_fb_private.h94
-rw-r--r--src/lib/ecore_fb/ecore_fb_ps2.c223
-rw-r--r--src/lib/ecore_fb/ecore_fb_ts.c362
-rw-r--r--src/lib/ecore_fb/ecore_fb_vt.c322
9 files changed, 2406 insertions, 0 deletions
diff --git a/src/lib/ecore_fb/Ecore_Fb.h b/src/lib/ecore_fb/Ecore_Fb.h
new file mode 100644
index 0000000000..069cccdff9
--- /dev/null
+++ b/src/lib/ecore_fb/Ecore_Fb.h
@@ -0,0 +1,100 @@
+#ifndef _ECORE_FB_H
+#define _ECORE_FB_H
+
+#include <Eina.h>
+
+#ifdef EAPI
+# undef EAPI
+#endif
+
+#ifdef __GNUC__
+# if __GNUC__ >= 4
+# define EAPI __attribute__ ((visibility("default")))
+# else
+# define EAPI
+# endif
+#else
+# define EAPI
+#endif
+
+/* FIXME:
+ * maybe a new module?
+ * - code to get battery info
+ * - code to get thermal info
+ * ecore evas fb isn't good enough for weird things, like multiple fb's, same happens here.
+ * backlight support using new kernel interface
+ * absolute axis
+ * joystick
+ * ecore_fb_li_device_close_all ? or a shutdown of the subsystem?
+ *
+ */
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+/**
+ * @defgroup Ecore_FB_Group Ecore_FB - Frame buffer convenience functions.
+ *
+ * Functions used to set up and shut down the Ecore_Framebuffer functions.
+ *
+ * @{
+ */
+
+/**
+ * @typedef Ecore_Fb_Input_Device
+ * Input device handler.
+ */
+typedef struct _Ecore_Fb_Input_Device Ecore_Fb_Input_Device;
+
+/**
+ * @enum _Ecore_Fb_Input_Device_Cap
+ * Device capabilities.
+ */
+enum _Ecore_Fb_Input_Device_Cap
+{
+ ECORE_FB_INPUT_DEVICE_CAP_NONE = 0x00000000,
+ ECORE_FB_INPUT_DEVICE_CAP_RELATIVE = 0x00000001,
+ ECORE_FB_INPUT_DEVICE_CAP_ABSOLUTE = 0x00000002,
+ ECORE_FB_INPUT_DEVICE_CAP_KEYS_OR_BUTTONS = 0x00000004
+};
+
+/**
+ * @typedef Ecore_Fb_Input_Device_Cap
+ * Device capabilities.
+ */
+typedef enum _Ecore_Fb_Input_Device_Cap Ecore_Fb_Input_Device_Cap;
+
+/* ecore_fb_vt.c */
+EAPI void ecore_fb_callback_gain_set(void (*func) (void *data), void *data);
+EAPI void ecore_fb_callback_lose_set(void (*func) (void *data), void *data);
+
+/* ecore_fb_li.c */
+EAPI Ecore_Fb_Input_Device *ecore_fb_input_device_open(const char *dev);
+EAPI void ecore_fb_input_device_close(Ecore_Fb_Input_Device *dev);
+EAPI void ecore_fb_input_device_listen(Ecore_Fb_Input_Device *dev, Eina_Bool listen);
+EAPI const char *ecore_fb_input_device_name_get(Ecore_Fb_Input_Device *dev);
+EAPI Ecore_Fb_Input_Device_Cap ecore_fb_input_device_cap_get(Ecore_Fb_Input_Device *dev);
+EAPI void ecore_fb_input_device_axis_size_set(Ecore_Fb_Input_Device *dev, int w, int h);
+EAPI void ecore_fb_input_threshold_click_set(Ecore_Fb_Input_Device *dev, double threshold);
+EAPI double ecore_fb_input_threshold_click_get(Ecore_Fb_Input_Device *dev);
+EAPI void ecore_fb_input_device_window_set(Ecore_Fb_Input_Device *dev, void *window);
+
+/* ecore_fb.c */
+
+EAPI int ecore_fb_init(const char *name);
+EAPI int ecore_fb_shutdown(void);
+EAPI void ecore_fb_size_get(int *w, int *h);
+
+EAPI void ecore_fb_touch_screen_calibrate_set(int xscale, int xtrans, int yscale, int ytrans, int xyswap);
+EAPI void ecore_fb_touch_screen_calibrate_get(int *xscale, int *xtrans, int *yscale, int *ytrans, int *xyswap);
+
+/**
+ * @}
+ */
+
+#ifdef __cplusplus
+}
+#endif
+
+#endif
diff --git a/src/lib/ecore_fb/ecore_fb.c b/src/lib/ecore_fb/ecore_fb.c
new file mode 100644
index 0000000000..ff96ac8a77
--- /dev/null
+++ b/src/lib/ecore_fb/ecore_fb.c
@@ -0,0 +1,129 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "Ecore_Fb.h"
+#include "ecore_fb_private.h"
+
+static void _ecore_fb_size_get(int *w, int *h);
+
+static int _ecore_fb_init_count = 0;
+static int _ecore_fb_console_w = 0;
+static int _ecore_fb_console_h = 0;
+
+/**
+ * @addtogroup Ecore_FB_Group Ecore_FB - Frame buffer convenience functions.
+ *
+ * @{
+ */
+
+static sighandler_t oldhand = NULL;
+
+static void
+nosigint(int val EINA_UNUSED)
+{
+}
+
+/**
+ * @brief Initialize the Ecore_Fb library.
+ *
+ * @param name Device target name.
+ * @return 1 or greater on success, 0 on error.
+ *
+ * This function sets up all the Ecore_Fb library. It returns 0 on
+ * failure, otherwise it returns the number of times it has already
+ * been called.
+ *
+ * When Ecore_Fb is not used anymore, call ecore_fb_shutdown() to shut down
+ * the Ecore_Fb library.
+ */
+EAPI int
+ecore_fb_init(const char *name EINA_UNUSED)
+{
+ if (++_ecore_fb_init_count != 1)
+ return _ecore_fb_init_count;
+
+ if (!ecore_fb_vt_init())
+ return --_ecore_fb_init_count;
+
+ if (!oldhand)
+ {
+ oldhand = signal(SIGINT, nosigint);
+ }
+
+ _ecore_fb_size_get(&_ecore_fb_console_w, &_ecore_fb_console_h);
+
+ return _ecore_fb_init_count;
+}
+
+/**
+ * @brief Shut down the Ecore_Fb library.
+ *
+ * @return 0 when the library is completely shut down, 1 or
+ * greater otherwise.
+ *
+ * This function shuts down the Ecore_Fb library. It returns 0 when it has
+ * been called the same number of times than ecore_fb_init().
+ */
+EAPI int
+ecore_fb_shutdown(void)
+{
+ if (--_ecore_fb_init_count != 0)
+ return _ecore_fb_init_count;
+
+ if (oldhand)
+ {
+ signal(SIGINT, oldhand);
+ oldhand = NULL;
+ }
+
+ ecore_fb_vt_shutdown();
+
+ return _ecore_fb_init_count;
+}
+
+
+/**
+ * @brief Retrieve the width and height of the current frame buffer in
+ * pixels.
+ *
+ * @param w Pointer to an integer in which to store the width.
+ * @param h Pointer to an interge in which to store the height.
+ *
+ * This function retrieves the size of the current frame buffer in
+ * pixels. @p w and @p h can be buffers that will be filled with the
+ * corresponding values. If one of them is @c NULL, nothing will be
+ * done for that parameter.
+ */
+EAPI void
+ecore_fb_size_get(int *w, int *h)
+{
+ if (w) *w = _ecore_fb_console_w;
+ if (h) *h = _ecore_fb_console_h;
+}
+
+static void
+_ecore_fb_size_get(int *w, int *h)
+{
+ struct fb_var_screeninfo fb_var;
+ int fb;
+
+ fb = open("/dev/fb0", O_RDWR);
+ if (fb < 0)
+ goto exit;
+
+ if (ioctl(fb, FBIOGET_VSCREENINFO, &fb_var) == -1)
+ goto err_ioctl;
+
+ *w = fb_var.xres;
+ *h = fb_var.yres;
+
+err_ioctl:
+ close(fb);
+exit:
+ return;
+}
+
+/**
+ * @}
+ */
diff --git a/src/lib/ecore_fb/ecore_fb_kbd.c b/src/lib/ecore_fb/ecore_fb_kbd.c
new file mode 100644
index 0000000000..fd111db04d
--- /dev/null
+++ b/src/lib/ecore_fb/ecore_fb_kbd.c
@@ -0,0 +1,326 @@
+static void _ecore_fb_event_free_key_down(void *data, void *ev);
+static void _ecore_fb_event_free_key_up(void *data, void *ev);
+
+static const char *_ecore_fb_kbd_syms[128 * 7] =
+{
+#include "ecore_fb_keytable.h"
+};
+
+static const char *_ecore_fb_btn_syms[128] =
+{
+ "0x00",
+ "Escape",
+ "F1",
+ "F2",
+ "F3",
+ "F4",
+ "Up",
+ "Right",
+ "Left",
+ "Down",
+ "Return",
+ "0x1b",
+ "0x1c",
+ "0x1d",
+ "0x1e",
+ "0x1f",
+ "0x20",
+ "0x21",
+ "0x22",
+ "0x23",
+ "0x24",
+ "0x25",
+ "0x26",
+ "0x27",
+ "0x28",
+ "0x29",
+ "0x2a",
+ "0x2b",
+ "0x2c",
+ "0x2d",
+ "0x2e",
+ "0x2f",
+ "0x30",
+ "0x31",
+ "0x32",
+ "0x33",
+ "0x34",
+ "0x35",
+ "0x36",
+ "0x37",
+ "0x38",
+ "0x39",
+ "0x3a",
+ "0x3b",
+ "0x3c",
+ "0x3d",
+ "0x3e",
+ "0x3f",
+ "0x40",
+ "0x41",
+ "0x42",
+ "0x43",
+ "0x44",
+ "0x45",
+ "0x46",
+ "0x47",
+ "0x48",
+ "0x49",
+ "0x4a",
+ "0x4b",
+ "0x4c",
+ "0x4d",
+ "0x4e",
+ "0x4f",
+ "0x50",
+ "0x51",
+ "0x52",
+ "0x53",
+ "0x54",
+ "0x55",
+ "0x56",
+ "0x57",
+ "0x58",
+ "0x59",
+ "0x5a",
+ "0x5b",
+ "0x5c",
+ "0x5d",
+ "0x5e",
+ "0x5f",
+ "0x60",
+ "0x61",
+ "0x62",
+ "0x63",
+ "0x64",
+ "0x65",
+ "0x66",
+ "0x67",
+ "0x68",
+ "0x69",
+ "0x6a",
+ "0x6b",
+ "0x6c",
+ "0x6d",
+ "0x6e",
+ "0x6f",
+ "0x70",
+ "0x71",
+ "0x72",
+ "0x73",
+ "0x74",
+ "0x75",
+ "0x76",
+ "0x77",
+ "0x78",
+ "0x79",
+ "0x7a",
+ "0x7b",
+ "0x7c",
+ "0x7d",
+ "0x7e",
+ "0x7f"
+};
+static int _ecore_fb_kbd_fd = -1;
+static int _ecore_fb_ctrl = 0;
+static int _ecore_fb_alt = 0;
+static int _ecore_fb_shift = 0;
+static int _ecore_fb_lock = 0;
+
+static Ecore_Fd_Handler *_ecore_fb_kbd_fd_handler_handle = NULL;
+static Eina_Bool _ecore_fb_kbd_fd_handler(void *data, Ecore_Fd_Handler *fd_handler);
+
+static void
+_ecore_fb_event_free_key_down(void *data EINA_UNUSED, void *ev)
+{
+ Ecore_Fb_Event_Key_Down *e;
+ e = ev;
+ free(e->keyname);
+ if (e->keysymbol) free(e->keysymbol);
+ if (e->key_compose) free(e->key_compose);
+ free(e);
+}
+
+static void
+_ecore_fb_event_free_key_up(void *data EINA_UNUSED, void *ev)
+{
+ Ecore_Fb_Event_Key_Up *e;
+
+ e = ev;
+ free(e->keyname);
+ if (e->keysymbol) free(e->keysymbol);
+ if (e->key_compose) free(e->key_compose);
+ free(e);
+}
+
+static Eina_Bool
+_ecore_fb_kbd_fd_handler(void *data EINA_UNUSED, Ecore_Fd_Handler *fd_handler EINA_UNUSED)
+{
+ int v = 0;
+
+ do
+ {
+ unsigned char buf;
+
+ v = read(_ecore_fb_kbd_fd, &buf, 1);
+ if (v < 0) return EINA_TRUE;
+ if (v < 1) return EINA_TRUE;
+ if (!(buf & 0x80))
+ {
+ /* DOWN */
+ int vt_switch = -1;
+ Ecore_Fb_Event_Key_Down *e;
+
+ e = calloc(1, sizeof(Ecore_Fb_Event_Key_Down));
+ if (!e) goto retry;
+ if (_ecore_fb_kbd_fd == _ecore_fb_tty_fd)
+ {
+ int add = 0;
+
+ if (_ecore_fb_shift) add = 1;
+ else if (_ecore_fb_lock) add = 2;
+ e->keyname = strdup(_ecore_fb_kbd_syms[(buf & 0x7f) * 7]);
+ e->keysymbol = strdup(_ecore_fb_kbd_syms[((buf & 0x7f) * 7) + add]);
+ e->key_compose = strdup(_ecore_fb_kbd_syms[((buf & 0x7f) * 7) + 3 + add]);
+ }
+ else
+ e->keyname = strdup(_ecore_fb_btn_syms[buf & 0x7f]);
+ if (!e->keyname)
+ {
+ free(e);
+ goto retry;
+ }
+ e->window = 1;
+ e->event_window = e->window;
+ e->root_window = e->window;
+ e->same_screen = 1;
+ e->timestamp = ecore_loop_time_get() * 1000.0;
+ if (!strcmp(e->keyname, "Control_L"))
+ _ecore_fb_ctrl++;
+ else if (!strcmp(e->keyname, "Control_R"))
+ _ecore_fb_ctrl++;
+ else if (!strcmp(e->keyname, "Alt_L"))
+ _ecore_fb_alt++;
+ else if (!strcmp(e->keyname, "Alt_R"))
+ _ecore_fb_alt++;
+ else if (!strcmp(e->keyname, "Shift_L"))
+ _ecore_fb_shift++;
+ else if (!strcmp(e->keyname, "Shift_R"))
+ _ecore_fb_shift++;
+ else if (!strcmp(e->keyname, "Caps_Lock"))
+ _ecore_fb_lock++;
+ else if (!strcmp(e->keyname, "F1")) vt_switch = 0;
+ else if (!strcmp(e->keyname, "F2")) vt_switch = 1;
+ else if (!strcmp(e->keyname, "F3")) vt_switch = 2;
+ else if (!strcmp(e->keyname, "F4")) vt_switch = 3;
+ else if (!strcmp(e->keyname, "F5")) vt_switch = 4;
+ else if (!strcmp(e->keyname, "F6")) vt_switch = 5;
+ else if (!strcmp(e->keyname, "F7")) vt_switch = 6;
+ else if (!strcmp(e->keyname, "F8")) vt_switch = 7;
+ else if (!strcmp(e->keyname, "F9")) vt_switch = 8;
+ else if (!strcmp(e->keyname, "F10")) vt_switch = 9;
+ else if (!strcmp(e->keyname, "F11")) vt_switch = 10;
+ else if (!strcmp(e->keyname, "F12")) vt_switch = 11;
+ if (_ecore_fb_ctrl > 2) _ecore_fb_ctrl = 2;
+ if (_ecore_fb_alt > 2) _ecore_fb_alt = 2;
+ if ((_ecore_fb_kbd_fd == _ecore_fb_tty_fd) &&
+ (_ecore_fb_ctrl))
+ {
+ const char *ts = _ecore_fb_kbd_syms[(buf & 0x7f) + 3 + 3];
+
+ if (ts)
+ {
+ if (e->key_compose) free(e->key_compose);
+ e->key_compose = strdup(ts);
+ }
+ }
+ if ((vt_switch >= 0) &&
+ (_ecore_fb_ctrl) &&
+ (_ecore_fb_alt))
+ _ecore_fb_vt_switch(vt_switch);
+ ecore_event_add(ECORE_FB_EVENT_KEY_DOWN, e, _ecore_fb_event_free_key_down, NULL);
+ }
+ else
+ {
+ /* UP */
+ Ecore_Fb_Event_Key_Up *e;
+
+ e = calloc(1, sizeof(Ecore_Fb_Event_Key_Up));
+ if (!e) goto retry;
+ if (_ecore_fb_kbd_fd == _ecore_fb_tty_fd)
+ {
+ int add = 0;
+
+ if (_ecore_fb_shift) add = 1;
+ else if (_ecore_fb_lock) add = 2;
+ e->keyname = strdup(_ecore_fb_kbd_syms[(buf & 0x7f) * 7]);
+ e->keysymbol = strdup(_ecore_fb_kbd_syms[((buf & 0x7f) * 7) + add]);
+ e->key_compose = strdup(_ecore_fb_kbd_syms[((buf & 0x7f) * 7) + 3 + add]);
+ }
+ else
+ e->keyname = strdup(_ecore_fb_btn_syms[buf & 0x7f]);
+ if (!e->keyname)
+ {
+ free(e);
+ goto retry;
+ }
+ e->window = 1;
+ e->event_window = e->window;
+ e->root_window = e->window;
+ e->same_screen = 1;
+ e->timestamp = ecore_loop_time_get() * 1000.0;
+ ecore_event_add(ECORE_FB_EVENT_KEY_UP, e, _ecore_fb_event_free_key_up, NULL);
+ if (!strcmp(e->keyname, "Control_L"))
+ _ecore_fb_ctrl--;
+ else if (!strcmp(e->keyname, "Control_R"))
+ _ecore_fb_ctrl--;
+ else if (!strcmp(e->keyname, "Alt_L"))
+ _ecore_fb_alt--;
+ else if (!strcmp(e->keyname, "Alt_R"))
+ _ecore_fb_alt--;
+ else if (!strcmp(e->keyname, "Shift_L"))
+ _ecore_fb_shift--;
+ else if (!strcmp(e->keyname, "Shift_R"))
+ _ecore_fb_shift--;
+ else if (!strcmp(e->keyname, "Caps_Lock"))
+ _ecore_fb_lock--;
+ if (_ecore_fb_ctrl < 0) _ecore_fb_ctrl = 0;
+ if (_ecore_fb_alt < 0) _ecore_fb_alt = 0;
+ if (_ecore_fb_shift < 0) _ecore_fb_shift = 0;
+ if (_ecore_fb_lock < 0) _ecore_fb_lock = 0;
+ }
+retry:
+ ;
+ }
+ while (v > 0);
+ return EINA_TRUE;
+}
+
+int
+ecore_fb_kbd_init(void)
+{
+ int prev_flags;
+
+ prev_flags = fcntl(_ecore_fb_kbd_fd, F_GETFL);
+ fcntl(_ecore_fb_kbd_fd, F_SETFL, prev_flags | O_NONBLOCK);
+ _ecore_fb_kbd_fd_handler_handle = ecore_main_fd_handler_add(_ecore_fb_kbd_fd,
+ ECORE_FD_READ,
+ _ecore_fb_kbd_fd_handler, NULL,
+ NULL, NULL);
+ if(!_ecore_fb_kbd_fd_handler_handle) return 0;
+ return 1;
+}
+
+void
+ecore_fb_kbd_shutdown(void)
+{
+ if (_ecore_fb_kbd_fd_handler_handle)
+ ecore_main_fd_handler_del(_ecore_fb_kbd_fd_handler_handle);
+ if (_ecore_fb_kbd_fd >= 0) close(_ecore_fb_kbd_fd);
+ _ecore_fb_kbd_fd = -1;
+ _ecore_fb_kbd_fd_handler_handle = NULL;
+ _ecore_fb_ctrl = 0;
+ _ecore_fb_lock = 0;
+ _ecore_fb_shift = 0;
+ _ecore_fb_alt = 0;
+}
diff --git a/src/lib/ecore_fb/ecore_fb_keytable.h b/src/lib/ecore_fb/ecore_fb_keytable.h
new file mode 100644
index 0000000000..70bf6b9689
--- /dev/null
+++ b/src/lib/ecore_fb/ecore_fb_keytable.h
@@ -0,0 +1,129 @@
+/* this table was taken from ecore_fb, is the default en layout */
+ "0x00", "0x00", "0x00", /**/"", "", "", NULL,/***/
+ "Escape", "Escape", "Escape", /**/"", "", "", "\x1b",/***/
+ "1", "exclam", "1", /**/"1", "!", "1", NULL,/***/
+ "2", "at", "2", /**/"2", "@", "2", "",/***/
+ "3", "numbersign", "3", /**/"3", "#", "3", "\x1b",/***/
+ "4", "dollar", "4", /**/"4", "$", "4", "\x1c",/***/
+ "5", "percent", "5", /**/"5", "%", "5", "\x1d",/***/
+ "6", "asciicircumm", "6", /**/"6", "^", "6", "\x1e",/***/
+ "7", "ampersand", "7", /**/"7", "&", "7", "\x1f",/***/
+ "8", "asterisk", "8", /**/"8", "*", "8", "\x7f",/***/
+ "9", "parenleft", "9", /**/"9", "(", "9", NULL,/***/
+ "0", "parenright", "0", /**/"0", ")", "0", NULL,/***/
+ "minus", "underscore", "minus", /**/"-", "_", "-", NULL,/***/
+ "equal", "plus", "equal", /**/"=", "+", "=", NULL,/***/
+ "BackSpace", "BackSpace", "BackSpace", /**/"\010","\010","\010", NULL,/***/
+ "Tab", "ISO_Left_Tab", "Tab", /**/"\011","", "\011", NULL,/***/
+ "q", "Q", "Q", /**/"q", "Q", "Q", "\x11",/***/
+ "w", "W", "W", /**/"w", "W", "W", "\x17",/***/
+ "e", "E", "E", /**/"e", "E", "E", "\x05",/***/
+ "r", "R", "R", /**/"r", "R", "R", "\x12",/***/
+ "t", "T", "T", /**/"t", "T", "T", "\x14",/***/
+ "y", "Y", "Y", /**/"y", "Y", "Y", "\x19",/***/
+ "u", "U", "U", /**/"u", "U", "U", "\x15",/***/
+ "i", "I", "I", /**/"i", "I", "I", "\x09",/***/
+ "o", "O", "O", /**/"o", "O", "O", "\x0f",/***/
+ "p", "P", "P", /**/"p", "P", "P", "\x10",/***/
+ "bracketleft", "braceleft", "bracketleft", /**/"[", "{", "[", "\x1b",/***/
+ "bracketright", "braceright", "bracketright", /**/"]", "}", "]", "\x1d",/***/
+ "Return", "Return", "Return", /**/"\015","\015","\015", NULL,/***/
+ "Control_L", "Control_L", "Control_L", /**/"", "", "", NULL,/***/
+ "a", "A", "A", /**/"a", "A", "A", "\x01",/***/
+ "s", "S", "S", /**/"s", "S", "S", "\x13",/***/
+ "d", "D", "D", /**/"d", "D", "D", "\x04",/***/
+ "f", "F", "F", /**/"f", "F", "F", "\x06",/***/
+ "g", "G", "G", /**/"g", "G", "G", "\x07",/***/
+ "h", "h", "H", /**/"h", "H", "H", "\x08",/***/
+ "j", "J", "J", /**/"j", "J", "J", "\x0a",/***/
+ "k", "K", "K", /**/"k", "K", "K", "\x0b",/***/
+ "l", "L", "L", /**/"l", "L", "L", "\x0c",/***/
+ "semicolon", "colon", "semicolon", /**/";", ":", ";", NULL,/***/
+ "apostrophe", "quotedbl", "apostrophe", /**/"'", "\"", "'", NULL,/***/
+ "grave", "asciitilde", "grave", /**/"`", "~", "`", "",/***/
+ "Shift_L", "Shift_L", "Shift_L", /**/"", "", "", NULL,/***/
+ "backslash", "bar", "backslash", /**/"\\", "|", "\\", "\x1c",/***/
+ "z", "Z", "Z", /**/"z", "Z", "Z", "\x1a",/***/
+ "x", "X", "X", /**/"x", "X", "X", "\x18",/***/
+ "c", "C", "C", /**/"c", "C", "C", "\x03",/***/
+ "v", "V", "V", /**/"v", "V", "V", "\x16",/***/
+ "b", "B", "B", /**/"b", "B", "B", "\x02",/***/
+ "n", "N", "N", /**/"n", "N", "N", "\x0e",/***/
+ "m", "M", "M", /**/"m", "M", "M", "\x0d",/***/
+ "comma", "less", "comma", /**/",", "<", ",", NULL,/***/
+ "period", "greater", "period", /**/".", ">", ".", NULL,/***/
+ "slash", "question", "slash", /**/"/", "?", "/", "",/***/
+ "Shift_R", "Shift_R", "Shift_R", /**/"", "", "", NULL,/***/
+ "KP_Multiply", "KP_Multiply", "KP_Multiply", /**/"", "*", "", NULL,/***/
+ "Alt_L", "Alt_L", "Alt_L", /**/"", "", "", NULL,/***/
+ "space", "space", "space", /**/" ", " ", " ", "",/***/
+ "Caps_Lock", "Caps_Lock", "Caps_Lock", /**/"", "", "", NULL,/***/
+ "F1", "F1", "F1", /**/"", "", "", NULL,/***/
+ "F2", "F2", "F2", /**/"", "", "", NULL,/***/
+ "F3", "F3", "F3", /**/"", "", "", NULL,/***/
+ "F4", "F4", "F4", /**/"", "", "", NULL,/***/
+ "F5", "F5", "F5", /**/"", "", "", NULL,/***/
+ "F6", "F6", "F6", /**/"", "", "", NULL,/***/
+ "F7", "F7", "F7", /**/"", "", "", NULL,/***/
+ "F8", "F8", "F8", /**/"", "", "", NULL,/***/
+ "F9", "F9", "F9", /**/"", "", "", NULL,/***/
+ "F10", "F10", "F10", /**/"", "", "", NULL,/***/
+ "Num_Lock", "Num_Lock", "Num_Lock", /**/"", "", "", NULL,/***/
+ "Scroll_Lock", "Scroll_Lock", "Scroll_Lock", /**/"", "", "", NULL,/***/
+ "KP_Home", "KP_7", "KP_Home", /**/"", "7", "", NULL,/***/
+ "KP_Up", "KP_8", "KP_Up", /**/"", "8", "", NULL,/***/
+ "KP_Prior", "KP_9", "KP_Prior", /**/"", "9", "", NULL,/***/
+ "KP_Subtract", "KP_Subtract", "KP_Subtract", /**/"", "", "", NULL,/***/
+ "KP_Left", "KP_4", "KP_Left", /**/"", "4", "", NULL,/***/
+ "KP_Begin", "KP_5", "KP_Begin", /**/"", "5", "", NULL,/***/
+ "KP_Right", "KP_6", "KP_Right", /**/"", "6", "", NULL,/***/
+ "KP_Add", "KP_Add", "KP_Add", /**/"", "", "", NULL,/***/
+ "KP_End", "KP_1", "KP_End", /**/"", "1", "", NULL,/***/
+ "KP_Down", "KP_2", "KP_Down", /**/"", "2", "", NULL,/***/
+ "KP_Next", "KP_3", "KP_Next", /**/"", "3", "", NULL,/***/
+ "KP_Insert", "KP_0", "KP_Insert", /**/"", "0", "", NULL,/***/
+ "KP_Delete", "KP_Decimal", "KP_Delete", /**/"", ".", "", NULL,/***/
+ "0x54", "0x54", "0x54", /**/"", "", "", NULL,/***/
+ "0x55", "0x55", "0x55", /**/"", "", "", NULL,/***/
+ "0x56", "0x56", "0x56", /**/"", "", "", NULL,/***/
+ "F11", "F11", "F11", /**/"", "", "", NULL,/***/
+ "F12", "F12", "F12", /**/"", "", "", NULL,/***/
+ "0x59", "0x59", "0x59", /**/"", "", "", NULL,/***/
+ "0x5a", "0x5a", "0x5a", /**/"", "", "", NULL,/***/
+ "0x5b", "0x5b", "0x5b", /**/"", "", "", NULL,/***/
+ "0x5c", "0x5c", "0x5c", /**/"", "", "", NULL,/***/
+ "0x5d", "0x5d", "0x5d", /**/"", "", "", NULL,/***/
+ "0x5e", "0x5e", "0x5e", /**/"", "", "", NULL,/***/
+ "0x5f", "0x5f", "0x5f", /**/"", "", "", NULL,/***/
+ "KP_Enter", "KP_Enter", "KP_Enter", /**/"\015", "\015", "\015", NULL,/***/
+ "Control_R", "Control_R", "Control_R", /**/"", "", "", NULL,/***/
+ "KP_Divide", "KP_Divide", "KP_Divide", /**/"", "", "", NULL,/***/
+ "Print", "Print", "Print", /**/"", "", "", NULL,/***/
+ "Alt_R", "Alt_R", "Alt_R", /**/"", "", "", NULL,/***/
+ "0x65", "0x65", "0x65", /**/"", "", "", NULL,/***/
+ "Home", "Home", "Home", /**/"", "", "", NULL,/***/
+ "Up", "Up", "Up", /**/"", "", "", NULL,/***/
+ "Prior", "Prior", "Prior", /**/"", "", "", NULL,/***/
+ "Left", "Left", "Left", /**/"", "", "", NULL,/***/
+ "Right", "Right", "Right", /**/"", "", "", NULL,/***/
+ "End", "End", "End", /**/"", "", "", NULL,/***/
+ "Down", "Down", "Down", /**/"", "", "", NULL,/***/
+ "Next", "Next", "Next", /**/"", "", "", NULL,/***/
+ "Insert", "Insert", "Insert", /**/"", "", "", NULL,/***/
+ "Delete", "Delete", "Delete", /**/"\177","\177","\177", NULL,/***/
+ "0x70", "0x70", "0x70", /**/"", "", "", NULL,/***/
+ "0x71", "0x71", "0x71", /**/"", "", "", NULL,/***/
+ "0x72", "0x72", "0x72", /**/"", "", "", NULL,/***/
+ "0x73", "0x73", "0x73", /**/"", "", "", NULL,/***/
+ "0x74", "0x74", "0x74", /**/"", "", "", NULL,/***/
+ "0x75", "0x75", "0x75", /**/"", "", "", NULL,/***/
+ "0x76", "0x76", "0x76", /**/"", "", "", NULL,/***/
+ "Pause", "Pause", "Pause", /**/"", "", "", NULL,/***/
+ "0x78", "0x78", "0x78", /**/"", "", "", NULL,/***/
+ "0x79", "0x79", "0x79", /**/"", "", "", NULL,/***/
+ "0x7a", "0x7a", "0x7a", /**/"", "", "", NULL,/***/
+ "0x7b", "0x7b", "0x7b", /**/"", "", "", NULL,/***/
+ "0x7c", "0x7c", "0x7c", /**/"", "", "", NULL,/***/
+ "Super_L", "Super_L", "Super_L", /**/"", "", "", NULL,/***/
+ "Super_R", "Super_R", "Super_R", /**/"", "", "", NULL,/***/
+ "0x7f", "0x7f", "0x7f", /**/"", "", "", NULL, /***/
diff --git a/src/lib/ecore_fb/ecore_fb_li.c b/src/lib/ecore_fb/ecore_fb_li.c
new file mode 100644
index 0000000000..0ea0549f92
--- /dev/null
+++ b/src/lib/ecore_fb/ecore_fb_li.c
@@ -0,0 +1,721 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+
+#include "Ecore_Fb.h"
+#include "ecore_fb_private.h"
+
+#define CLICK_THRESHOLD_DEFAULT 0.25
+
+static Eina_List *_ecore_fb_li_devices = NULL;
+
+static const char *_ecore_fb_li_kbd_syms[128 * 7] =
+{
+#include "ecore_fb_keytable.h"
+};
+
+/* Initial Copyright (C) Brad Hards (1999-2002),
+ * this function is used to tell if "bit" is set in "array"
+ * it selects a byte from the array, and does a boolean AND
+ * operation with a byte that only has the relevant bit set.
+ * eg. to check for the 12th bit, we do (array[1] & 1<<4).
+ * Moved to static inline in order to force compiler to otimized
+ * the unsued part away or force a link error if long has an unexpected
+ * size.
+ * - bigeasy
+ */
+extern int long_has_neither_32_nor_64_bits(void);
+static inline int
+test_bit(int bit, unsigned long *array)
+{
+ if (sizeof(long) == 4)
+ return array[bit / 32] & (1 << (bit % 32));
+ else if (sizeof(long) == 8)
+ return array[bit / 64] & (1 << (bit % 64));
+ else long_has_neither_32_nor_64_bits();
+}
+
+static void
+_ecore_fb_li_device_event_key(Ecore_Fb_Input_Device *dev, struct input_event *iev)
+{
+ if (!dev->listen) return;
+
+ /* check for basic keyboard keys */
+ if ((iev->code >= KEY_ESC) && (iev->code <= KEY_COMPOSE))
+ {
+ int offset = 0;
+ const char *keyname = _ecore_fb_li_kbd_syms[iev->code * 7];
+
+ /* check the key table */
+ if (iev->value)
+ {
+ /* its a repeated key, dont increment */
+ if (iev->value != 2)
+ {
+ if (!strcmp(keyname, "Control_L"))
+ dev->keyboard.ctrl++;
+ else if (!strcmp(keyname, "Control_R"))
+ dev->keyboard.ctrl++;
+ else if (!strcmp(keyname, "Alt_L"))
+ dev->keyboard.alt++;
+ else if (!strcmp(keyname, "Alt_R"))
+ dev->keyboard.alt++;
+ else if (!strcmp(keyname, "Shift_L"))
+ dev->keyboard.shift++;
+ else if (!strcmp(keyname, "Shift_R"))
+ dev->keyboard.shift++;
+ else if (!strcmp(keyname, "Caps_Lock"))
+ dev->keyboard.lock = !dev->keyboard.lock;
+ if (dev->keyboard.ctrl > 2) dev->keyboard.ctrl = 2;
+ if (dev->keyboard.alt > 2) dev->keyboard.alt = 2;
+ if (dev->keyboard.shift > 2) dev->keyboard.shift = 2;
+ if (dev->keyboard.lock > 1) dev->keyboard.lock = 1;
+ }
+ }
+ else
+ {
+ if (!strcmp(keyname, "Control_L"))
+ dev->keyboard.ctrl--;
+ else if (!strcmp(keyname, "Control_R"))
+ dev->keyboard.ctrl--;
+ else if (!strcmp(keyname, "Alt_L"))
+ dev->keyboard.alt--;
+ else if (!strcmp(keyname, "Alt_R"))
+ dev->keyboard.alt--;
+ else if (!strcmp(keyname, "Shift_L"))
+ dev->keyboard.shift--;
+ else if (!strcmp(keyname, "Shift_R"))
+ dev->keyboard.shift--;
+ if (dev->keyboard.ctrl < 0) dev->keyboard.ctrl = 0;
+ if (dev->keyboard.alt < 0) dev->keyboard.alt = 0;
+ if (dev->keyboard.shift < 0) dev->keyboard.shift = 0;
+ if (dev->keyboard.lock < 0) dev->keyboard.lock = 0;
+ }
+
+ /* sending ecore_input_evas events */
+ Ecore_Event_Key *e;
+
+ if (dev->keyboard.shift) offset = 1;
+ else if (dev->keyboard.lock) offset = 2;
+
+ const char *key = _ecore_fb_li_kbd_syms[(iev->code * 7) + offset];
+ const char *compose = _ecore_fb_li_kbd_syms[(iev->code * 7) + 3 + offset];
+
+ if (dev->keyboard.ctrl)
+ {
+ const char *ts = _ecore_fb_li_kbd_syms[(iev->code * 7) + 3 + 3];
+
+ if (ts) compose = ts;
+ }
+
+ e = calloc(1, sizeof(Ecore_Event_Key) + strlen(key) +
+ strlen(keyname) + (compose ? strlen(compose) : 0) + 3);
+ e->keyname = (char *)(e + 1);
+ e->key = e->keyname + strlen(keyname) + 1;
+ e->compose = (compose) ? e->key + strlen(key) + 1 : NULL;
+ e->string = e->compose;
+
+ strcpy((char *)e->keyname, keyname);
+ strcpy((char *)e->key, key);
+ if (compose)
+ strcpy((char *)e->compose, compose);
+
+ e->modifiers = 0;
+ if (dev->keyboard.shift)
+ e->modifiers |= ECORE_EVENT_MODIFIER_SHIFT;
+ if (dev->keyboard.ctrl) e->modifiers |= ECORE_EVENT_MODIFIER_CTRL;
+ if (dev->keyboard.alt) e->modifiers |= ECORE_EVENT_MODIFIER_SHIFT;
+ if (dev->keyboard.lock) e->modifiers |= ECORE_EVENT_LOCK_CAPS;
+
+ e->timestamp = ecore_loop_time_get() * 1000.0;
+ e->window = (Ecore_Window)dev->window;
+ e->event_window = (Ecore_Window)dev->window;
+ e->root_window = (Ecore_Window)dev->window;
+ e->same_screen = 1;
+
+ if (iev->value)
+ ecore_event_add(ECORE_EVENT_KEY_DOWN, e, NULL, NULL);
+ else
+ ecore_event_add(ECORE_EVENT_KEY_UP, e, NULL, NULL);
+ }
+ /* check for mouse button events */
+ else if ((iev->code >= BTN_MOUSE) && (iev->code < BTN_JOYSTICK))
+ {
+ int button;
+ Ecore_Event_Mouse_Button *e;
+ double current = ecore_loop_time_get();
+
+ button = ((iev->code & 0x00F) + 1);
+ // swap 2 and 3 to make middle and right butotn work right.
+ if (button == 3) button = 2;
+ else if (button == 2) button = 3;
+ if (iev->value)
+ {
+ dev->mouse.did_double = EINA_FALSE;
+ dev->mouse.did_triple = EINA_FALSE;
+
+ if (((current - dev->mouse.prev) <= dev->mouse.threshold) &&
+ (button == dev->mouse.prev_button))
+ {
+ dev->mouse.did_double = EINA_TRUE;
+ if (((current - dev->mouse.last) <= (2 * dev->mouse.threshold)) &&
+ (button == dev->mouse.last_button))
+ {
+ dev->mouse.did_triple = EINA_TRUE;
+ /* reset */
+ dev->mouse.prev = 0;
+ dev->mouse.last = 0;
+ current = 0;
+ }
+ }
+ dev->mouse.last = dev->mouse.prev;
+ dev->mouse.prev = current;
+ dev->mouse.last_button = dev->mouse.prev_button;
+ dev->mouse.prev_button = button;
+ }
+
+ e = calloc(1, sizeof(Ecore_Event_Mouse_Button));
+ if (!e)
+ return;
+
+ e->timestamp = current * 1000.0;
+ e->window = (Ecore_Window)dev->window;
+ e->event_window = (Ecore_Window)dev->window;
+ e->root_window = (Ecore_Window)dev->window;
+ e->same_screen = 1;
+
+ e->modifiers = 0;
+ if (dev->keyboard.shift)
+ e->modifiers |= ECORE_EVENT_MODIFIER_SHIFT;
+ if (dev->keyboard.ctrl) e->modifiers |= ECORE_EVENT_MODIFIER_CTRL;
+ if (dev->keyboard.alt) e->modifiers |= ECORE_EVENT_MODIFIER_SHIFT;
+ if (dev->keyboard.lock) e->modifiers |= ECORE_EVENT_LOCK_CAPS;
+
+ e->x = dev->mouse.x;
+ e->y = dev->mouse.y;
+ e->root.x = e->x;
+ e->root.y = e->y;
+ e->buttons = button;
+
+ if (dev->mouse.did_double)
+ e->double_click = 1;
+ if (dev->mouse.did_triple)
+ e->triple_click = 1;
+
+ if (iev->value)
+ ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, e, NULL, NULL);
+ else
+ ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_UP, e, NULL, NULL);
+ }
+}
+
+static void
+_ecore_fb_li_device_event_rel(Ecore_Fb_Input_Device *dev, struct input_event *iev)
+{
+ if (!dev->listen) return;
+ /* dispatch the button events if they are queued */
+ switch (iev->code)
+ {
+ case REL_X:
+ case REL_Y:
+ {
+ Ecore_Event_Mouse_Move *e;
+ if (iev->code == REL_X)
+ {
+ dev->mouse.x += iev->value;
+ if (dev->mouse.x > dev->mouse.w - 1)
+ dev->mouse.x = dev->mouse.w;
+ else if(dev->mouse.x < 0)
+ dev->mouse.x = 0;
+ }
+ else
+ {
+ dev->mouse.y += iev->value;
+ if (dev->mouse.y > dev->mouse.h - 1)
+ dev->mouse.y = dev->mouse.h;
+ else if(dev->mouse.y < 0)
+ dev->mouse.y = 0;
+ }
+
+ e = calloc(1, sizeof(Ecore_Event_Mouse_Move));
+ if (!e)
+ return;
+
+ e->window = (Ecore_Window)dev->window;
+ e->event_window = (Ecore_Window)dev->window;
+ e->root_window = (Ecore_Window)dev->window;
+ e->same_screen = 1;
+
+ e->modifiers = 0;
+ if (dev->keyboard.shift) e->modifiers |= ECORE_EVENT_MODIFIER_SHIFT;
+ if (dev->keyboard.ctrl) e->modifiers |= ECORE_EVENT_MODIFIER_CTRL;
+ if (dev->keyboard.alt) e->modifiers |= ECORE_EVENT_MODIFIER_SHIFT;
+ if (dev->keyboard.lock) e->modifiers |= ECORE_EVENT_LOCK_CAPS;
+
+ e->x = dev->mouse.x;
+ e->y = dev->mouse.y;
+ e->root.x = e->x;
+ e->root.y = e->y;
+
+ e->timestamp = ecore_loop_time_get() * 1000.0;
+
+ ecore_event_add(ECORE_EVENT_MOUSE_MOVE, e, NULL, NULL);
+
+ break;
+ }
+ case REL_WHEEL:
+ case REL_HWHEEL:
+ {
+ Ecore_Event_Mouse_Wheel *e;
+
+ e = calloc(1, sizeof(Ecore_Event_Mouse_Wheel));
+ if (!e)
+ return;
+
+ e->x = dev->mouse.x;
+ e->y = dev->mouse.y;
+ if (iev->code == REL_HWHEEL) e->direction = 1;
+ e->z = iev->value;
+ e->root.x = dev->mouse.x;
+ e->root.y = dev->mouse.y;
+
+ e->window = (Ecore_Window)dev->window;
+ e->event_window = (Ecore_Window)dev->window;
+ e->root_window = (Ecore_Window)dev->window;
+ e->same_screen = 1;
+
+ e->modifiers = 0;
+ if (dev->keyboard.shift) e->modifiers |= ECORE_EVENT_MODIFIER_SHIFT;
+ if (dev->keyboard.ctrl) e->modifiers |= ECORE_EVENT_MODIFIER_CTRL;
+ if (dev->keyboard.alt) e->modifiers |= ECORE_EVENT_MODIFIER_SHIFT;
+ if (dev->keyboard.lock) e->modifiers |= ECORE_EVENT_LOCK_CAPS;
+
+ e->timestamp = ecore_loop_time_get() * 1000.0;
+
+ ecore_event_add(ECORE_EVENT_MOUSE_WHEEL, e, NULL, NULL);
+
+ break;
+ }
+ default:
+ break;
+ }
+}
+
+static void
+_ecore_fb_li_device_event_abs(Ecore_Fb_Input_Device *dev, struct input_event *iev)
+{
+ static int prev_pressure = 0;
+ int pressure;
+
+ if (!dev->listen) return;
+ switch (iev->code)
+ {
+ case ABS_X:
+ if (dev->mouse.w != 0)
+ {
+ int tmp;
+
+ tmp = (int)((double)(iev->value - dev->mouse.min_w) / dev->mouse.rel_w);
+ if (tmp < 0) dev->mouse.x = 0;
+ else if (tmp > dev->mouse.w) dev->mouse.x = dev->mouse.w;
+ else dev->mouse.x = tmp;
+ dev->mouse.event = ECORE_EVENT_MOUSE_MOVE;
+ }
+ break;
+
+ case ABS_Y:
+ if (dev->mouse.h != 0)
+ {
+ int tmp;
+
+ tmp = (int)((double)(iev->value - dev->mouse.min_h) / dev->mouse.rel_h);
+ if (tmp < 0) dev->mouse.y = 0;
+ else if (tmp > dev->mouse.h) dev->mouse.y = dev->mouse.h;
+ else dev->mouse.y = tmp;
+ dev->mouse.event = ECORE_EVENT_MOUSE_MOVE;
+ }
+ break;
+
+ case ABS_PRESSURE:
+ pressure = iev->value;
+ if ((pressure) && (!prev_pressure))
+ {
+ /* DOWN: mouse is down, but was not before */
+ dev->mouse.event = ECORE_EVENT_MOUSE_BUTTON_DOWN;
+ }
+ else if ((!pressure) && (prev_pressure))
+ {
+ /* UP: mouse was down, but is not now */
+ dev->mouse.event = ECORE_EVENT_MOUSE_BUTTON_UP;
+ }
+ prev_pressure = pressure;
+ break;
+ }
+}
+
+static void
+_ecore_fb_li_device_event_syn(Ecore_Fb_Input_Device *dev, struct input_event *iev EINA_UNUSED)
+{
+ if (!dev->listen) return;
+
+ if (dev->mouse.event == ECORE_EVENT_MOUSE_MOVE)
+ {
+ Ecore_Event_Mouse_Move *ev;
+ ev = calloc(1,sizeof(Ecore_Event_Mouse_Move));
+ ev->x = dev->mouse.x;
+ ev->y = dev->mouse.y;
+ ev->root.x = ev->x;
+ ev->root.y = ev->y;
+ ev->timestamp = ecore_loop_time_get() * 1000.0;
+ }
+ else if (dev->mouse.event == ECORE_EVENT_MOUSE_BUTTON_DOWN)
+ {
+ Ecore_Event_Mouse_Button *ev;
+ ev = calloc(1, sizeof(Ecore_Event_Mouse_Button));
+ ev->x = dev->mouse.x;
+ ev->y = dev->mouse.y;
+ ev->root.x = ev->x;
+ ev->root.y = ev->y;
+ ev->buttons = 1;
+ ev->timestamp = ecore_loop_time_get() * 1000.0;
+ ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, ev, NULL, NULL);
+ }
+ else if (dev->mouse.event == ECORE_EVENT_MOUSE_BUTTON_UP)
+ {
+ Ecore_Event_Mouse_Button *ev;
+ ev = calloc(1, sizeof(Ecore_Event_Mouse_Button));
+ ev->x = dev->mouse.x;
+ ev->y = dev->mouse.y;
+ ev->root.x = ev->x;
+ ev->root.y = ev->y;
+ ev->buttons = 1;
+ ev->timestamp = ecore_loop_time_get() * 1000.0;
+ ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_UP, ev, NULL, NULL);
+ }
+}
+
+static Eina_Bool
+_ecore_fb_li_device_fd_callback(void *data, Ecore_Fd_Handler *fdh EINA_UNUSED)
+{
+ Ecore_Fb_Input_Device *dev;
+ struct input_event ev[64];
+ int len;
+ int i;
+
+ dev = (Ecore_Fb_Input_Device*)data;
+ /* read up to 64 events at once */
+ len = read(dev->fd, &ev, sizeof(ev));
+ for(i = 0; i < (int)(len / sizeof(ev[0])); i++)
+ {
+ switch(ev[i].type)
+ {
+ case EV_SYN:
+ _ecore_fb_li_device_event_syn(dev, &ev[i]);
+ break;
+ case EV_ABS:
+ _ecore_fb_li_device_event_abs(dev, &ev[i]);
+ break;
+ case EV_REL:
+ _ecore_fb_li_device_event_rel(dev, &ev[i]);
+ break;
+ case EV_KEY:
+ _ecore_fb_li_device_event_key(dev, &ev[i]);
+ break;
+ default:
+ break;
+ }
+ }
+ return EINA_TRUE;
+}
+
+/**
+ * @addtogroup Ecore_FB_Group Ecore_FB - Frame buffer convenience functions.
+ *
+ * @{
+ */
+
+/**
+ * @brief Set the listen mode for an input device .
+ *
+ * @param dev The device to set the mode of.
+ * @param listen @c EINA_FALSE to disable listening mode, @c EINA_TRUE to
+ * enable it.
+ *
+ * This function enables or disables listening on the input device @p dev.
+ * If @p listen is @c EINA_FALSE, listening mode is disabled, if it is
+ * @c EINA_TRUE, it is enabled.
+ */
+EAPI void
+ecore_fb_input_device_listen(Ecore_Fb_Input_Device *dev, Eina_Bool listen)
+{
+ if (!dev) return;
+ if ((listen && dev->listen) || (!listen && !dev->listen)) return;
+ if (listen)
+ {
+ /* if the device already had a handler */
+ if (!dev->handler)
+ dev->handler = ecore_main_fd_handler_add(dev->fd, ECORE_FD_READ, _ecore_fb_li_device_fd_callback, dev, NULL, NULL);
+
+ }
+ dev->listen = listen;
+}
+
+#ifndef EV_CNT
+# define EV_CNT (EV_MAX+1)
+#endif
+
+/**
+ * @brief Associates an input device with the given @ref Ecore_Evas_Group.
+ *
+ * @param dev The input being associated with an @ref Ecore_Evas_Group (not @c NULL).
+ * @param window The window which this input is being associated to.
+ * @c NULL will remove any previous association.
+ *
+ * Events generated by this device will have a pointer to @p window. If this @p
+ * window is registered with ecore_event_window_register() or
+ * ecore_evas_input_event_register(), respective evas events will be delivered
+ * by the ecore_input_evas system. An example can be seen in the following code:
+ *
+ * @code
+ * Ecore_Evas *ee = ecore_evas_new(NULL, 0, 0, 800, 600, NULL);
+ *
+ * ecore_evas_input_event_register(ee);
+ *
+ * device = ecore_fb_input_device_open(device_path);
+ * if (device)
+ * ecore_fb_input_device_window_set(device, ee);
+ *
+ * @endcode
+ *
+ * On the previous code, all input captured on the mentioned device will be
+ * delivered to the @c Ecore_Evas @c ee.
+ *
+ * @since 1.1
+ */
+EAPI void
+ecore_fb_input_device_window_set(Ecore_Fb_Input_Device *dev, void *window)
+{
+ if (!dev) return;
+
+ dev->window = window;
+}
+
+/**
+ * @brief Open an input device.
+ *
+ * @param dev The device to open.
+ * @return The @ref Ecore_Fb_Input_Device object that has been opened.
+ *
+ * This function opens the input device named @p dev and returns the
+ * object for it, or returns @c NULL on failure.
+ */
+EAPI Ecore_Fb_Input_Device *
+ecore_fb_input_device_open(const char *dev)
+{
+ Ecore_Fb_Input_Device *device;
+ unsigned long event_type_bitmask[EV_CNT / 32 + 1];
+ int event_type;
+ int fd;
+
+ if (!dev) return NULL;
+ device = calloc(1, sizeof(Ecore_Fb_Input_Device));
+ if (!device) return NULL;
+
+ if ((fd = open(dev, O_RDONLY, O_NONBLOCK)) < 0)
+ {
+ fprintf(stderr, "[ecore_fb_li:device_open] %s %s", dev, strerror(errno));
+ goto error_open;
+ }
+ /* query capabilities */
+ if (ioctl(fd, EVIOCGBIT(0, EV_MAX), event_type_bitmask) < 0)
+ {
+ fprintf(stderr,"[ecore_fb_li:device_open] query capabilities %s %s", dev, strerror(errno));
+ goto error_caps;
+ }
+ /* query name */
+ device->info.name = calloc(256, sizeof(char));
+ if (ioctl(fd, EVIOCGNAME(sizeof(char) * 256), device->info.name) < 0)
+ {
+ fprintf(stderr, "[ecore_fb_li:device_open] get name %s %s", dev, strerror(errno));
+ strcpy(device->info.name, "Unknown");
+ }
+ device->fd = fd;
+ device->info.dev = strdup(dev);
+ /* common */
+ device->mouse.threshold = CLICK_THRESHOLD_DEFAULT;
+
+ /* set info */
+ for (event_type = 0; event_type < EV_MAX; event_type++)
+ {
+ if (!test_bit(event_type, event_type_bitmask))
+ continue;
+ switch (event_type)
+ {
+ case EV_SYN:
+ break;
+ case EV_KEY:
+ device->info.cap |= ECORE_FB_INPUT_DEVICE_CAP_KEYS_OR_BUTTONS;
+ break;
+ case EV_REL:
+ device->info.cap |= ECORE_FB_INPUT_DEVICE_CAP_RELATIVE;
+ break;
+ case EV_ABS:
+ device->info.cap |= ECORE_FB_INPUT_DEVICE_CAP_ABSOLUTE;
+ break;
+ case EV_MSC:
+ case EV_LED:
+ case EV_SND:
+ case EV_REP:
+ case EV_FF :
+ case EV_FF_STATUS:
+ case EV_PWR:
+ default:
+ break;
+ }
+ }
+
+ _ecore_fb_li_devices = eina_list_append(_ecore_fb_li_devices, device);
+ return device;
+
+error_caps:
+ close(fd);
+error_open:
+ free(device);
+ return NULL;
+}
+
+/**
+ * @brief Close the given device.
+ *
+ * @param dev The device to close
+ *
+ * This function closes the device @p dev. If @p dev is @c NULL, this
+ * function does nothing.
+ */
+EAPI void
+ecore_fb_input_device_close(Ecore_Fb_Input_Device *dev)
+{
+ if (!dev || dev->fd < 0) return;
+ /* close the fd */
+ close(dev->fd);
+ /* remove the element from the list */
+ _ecore_fb_li_devices = eina_list_remove(_ecore_fb_li_devices, dev);
+ free(dev);
+}
+
+
+/**
+ * @brief Set the axis size of the given device.
+ *
+ * @param dev The device to set the axis size to.
+ * @param w The width of the axis.
+ * @param h The height of the axis.
+ *
+ * This function sets set the width @p w and height @p h of the axis
+ * of device @p dev. If @p dev is a relative input device, a width and
+ * height must set for it. If its absolute set the ioctl correctly, if
+ * not, unsupported device.
+ */
+EAPI void
+ecore_fb_input_device_axis_size_set(Ecore_Fb_Input_Device *dev, int w, int h)
+{
+ if (!dev) return;
+ if ((w < 0) || (h < 0)) return;
+ /* FIXME
+ * this code is for a touchscreen device,
+ * make it configurable (ABSOLUTE | RELATIVE)
+ */
+ if (dev->info.cap & ECORE_FB_INPUT_DEVICE_CAP_ABSOLUTE)
+ {
+ /* FIXME looks like some kernels dont include this struct */
+ struct input_absinfo abs_features;
+
+ ioctl(dev->fd, EVIOCGABS(ABS_X), &abs_features);
+ dev->mouse.min_w = abs_features.minimum;
+ dev->mouse.rel_w = (double)(abs_features.maximum - abs_features.minimum)/(double)(w);
+
+ ioctl(dev->fd, EVIOCGABS(ABS_Y), &abs_features);
+ dev->mouse.min_h = abs_features.minimum;
+ dev->mouse.rel_h = (double)(abs_features.maximum - abs_features.minimum)/(double)(h);
+ }
+ else if (!(dev->info.cap & ECORE_FB_INPUT_DEVICE_CAP_RELATIVE))
+ return;
+
+ /* update the local values */
+ if (dev->mouse.x > w - 1) dev->mouse.x = w -1;
+ if (dev->mouse.y > h - 1) dev->mouse.y = h -1;
+ dev->mouse.w = w;
+ dev->mouse.h = h;
+}
+
+/**
+ * @brief Retrieve the name of the given device.
+ *
+ * @param dev The device to get the name from.
+ * @return The name of the device.
+ *
+ * This function returns the name of the device @p dev. If @p dev is
+ * @c NULL, this function returns @c NULL.
+ */
+EAPI const char *
+ecore_fb_input_device_name_get(Ecore_Fb_Input_Device *dev)
+{
+ if (!dev) return NULL;
+ return dev->info.name;
+}
+
+/**
+ * @brief Retrieve the capability of the given device.
+ *
+ * @param dev The device to get the name from.
+ * @return The capability of the device.
+ *
+ * This function returns the capability of the device @p dev. If @p dev is
+ * @c NULL, this function returns ECORE_FB_INPUT_DEVICE_CAP_NONE.
+ */
+EAPI Ecore_Fb_Input_Device_Cap
+ecore_fb_input_device_cap_get(Ecore_Fb_Input_Device *dev)
+{
+ if (!dev) return ECORE_FB_INPUT_DEVICE_CAP_NONE;
+ return dev->info.cap;
+}
+
+/**
+ * @brief Set the threshold of mouse clicks of the given device.
+ *
+ * @param dev The device to set the threshodl mouse click to.
+ * @param threshold The threshold value.
+ *
+ * This function sets the threshold of mouse clicks of the device
+ * @p dev to @p threshold. If @p dev is @c NULL, this function does
+ * nothing.
+ */
+EAPI void
+ecore_fb_input_device_threshold_click_set(Ecore_Fb_Input_Device *dev, double threshold)
+{
+ if (!dev) return;
+ if ((threshold == dev->mouse.threshold) || (threshold == 0)) return;
+ dev->mouse.threshold = threshold;
+}
+
+/**
+ * @brief Get the threshold of mouse clicks of the given device.
+ *
+ * @param dev The device to set the threshodl mouse click from.
+ * @return The threshold value.
+ *
+ * This function returns the threshold of mouse clicks of the device
+ * @p dev. If @p dev is @c NULL, this function returns 0.0.
+ */
+EAPI double
+ecore_fb_input_device_threshold_click_get(Ecore_Fb_Input_Device *dev)
+{
+ if (!dev) return 0;
+ return dev->mouse.threshold;
+}
+
+/**
+ * @}
+ */
diff --git a/src/lib/ecore_fb/ecore_fb_private.h b/src/lib/ecore_fb/ecore_fb_private.h
new file mode 100644
index 0000000000..797f86305f
--- /dev/null
+++ b/src/lib/ecore_fb/ecore_fb_private.h
@@ -0,0 +1,94 @@
+#ifndef _ECORE_FB_PRIVATE_H
+#define _ECORE_FB_PRIVATE_H
+
+#include "Ecore.h"
+#include "ecore_private.h"
+#include "Ecore_Input.h"
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <unistd.h>
+#include <termios.h>
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/ioctl.h>
+#include <linux/version.h>
+#include <linux/kd.h>
+#include <linux/vt.h>
+#include <linux/fb.h>
+#if (LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,15)) && (LINUX_VERSION_CODE < KERNEL_VERSION(2,6,18))
+ #define kernel_ulong_t unsigned long
+ #define BITS_PER_LONG 32
+ #include <linux/input.h>
+ #undef kernel_ulong_t
+ #undef BITS_PER_LONG
+#else
+ #include <linux/input.h>
+#endif
+
+#include <signal.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include <Ecore_Fb.h>
+
+/* ecore_fb_li.c */
+struct _Ecore_Fb_Input_Device
+{
+ int fd;
+ Ecore_Fd_Handler *handler;
+ int listen;
+ struct {
+ Ecore_Fb_Input_Device_Cap cap;
+ char *name;
+ char *dev;
+ } info;
+ struct
+ {
+ /* common mouse */
+ int x,y;
+ int w,h;
+
+ double last;
+ double prev;
+ double threshold;
+ Eina_Bool did_double;
+ Eina_Bool did_triple;
+ /* absolute axis */
+ int min_w, min_h;
+ double rel_w, rel_h;
+ int event;
+ int prev_button;
+ int last_button;
+ } mouse;
+ struct
+ {
+ int shift;
+ int ctrl;
+ int alt;
+ int lock;
+ } keyboard;
+ void *window;
+};
+
+/* ecore_fb_ts.c */
+EAPI int ecore_fb_ts_init(void);
+EAPI void ecore_fb_ts_shutdown(void);
+EAPI void ecore_fb_ts_events_window_set(void *window);
+EAPI void *ecore_fb_ts_events_window_get(void);
+EAPI void ecore_fb_ts_event_window_set(void *window);
+
+/* ecore_fb_vt.c */
+int ecore_fb_vt_init(void);
+void ecore_fb_vt_shutdown(void);
+
+/* hacks to stop people NEEDING #include <linux/h3600_ts.h> */
+#ifndef TS_SET_CAL
+#define TS_SET_CAL 0x4014660b
+#endif
+#ifndef TS_GET_CAL
+#define TS_GET_CAL 0x8014660a
+#endif
+
+#endif
diff --git a/src/lib/ecore_fb/ecore_fb_ps2.c b/src/lib/ecore_fb/ecore_fb_ps2.c
new file mode 100644
index 0000000000..53aa302fef
--- /dev/null
+++ b/src/lib/ecore_fb/ecore_fb_ps2.c
@@ -0,0 +1,223 @@
+typedef struct _Ecore_Fb_Ps2_Event Ecore_Fb_Ps2_Event;
+struct _Ecore_Fb_Ps2_Event
+{
+ unsigned char button;
+ unsigned char x;
+ unsigned char y;
+ unsigned char z;
+};
+
+static int _ecore_fb_ps2_event_byte_count = 0;
+static Ecore_Fb_Ps2_Event _ecore_fb_ps2_event;
+static int _ecore_fb_ps2_fd = 0;
+static Eina_Bool _ecore_fb_ps2_fd_handler(void *data, Ecore_Fd_Handler *fd_handler);
+
+int
+ecore_fb_ps2_init(void)
+{
+ _ecore_fb_ps2_fd = open("/dev/psaux", O_RDWR);
+ if (_ecore_fb_ps2_fd >= 0)
+ {
+ prev_flags = fcntl(_ecore_fb_ps2_fd, F_GETFL);
+ fcntl(_ecore_fb_ps2_fd, F_SETFL, prev_flags | O_NONBLOCK);
+ _ecore_fb_ts_fd_handler_handle = ecore_main_fd_handler_add(_ecore_fb_ps2_fd,
+ ECORE_FD_READ,
+ _ecore_fb_ps2_fd_handler, NULL, NULL, NULL);
+ if (!_ecore_fb_ts_fd_handler_handle)
+ {
+ close(_ecore_fb_ps2_fd);
+ return 0;
+ }
+ return 1;
+ }
+ return 0;
+}
+
+void
+ecore_fb_ps2_shutdown(void)
+{
+ if (_ecore_fb_ps2_fd > 0) close(_ecore_fb_ps2_fd);
+ _ecore_fb_ps2_fd = 0;
+}
+
+static Eina_Bool
+_ecore_fb_ps2_fd_handler(void *data EINA_UNUSED, Ecore_Fd_Handler *fd_handler EINA_UNUSED)
+{
+ static int prev_x = 0, prev_y = 0, prev_button = 0;
+ static double last_time = 0;
+ static double last_last_time = 0;
+ int v = 0;
+
+ do
+ {
+ int x, y, button, i;
+ int num;
+ char *ptr;
+ double t;
+ static int did_double = 0;
+ static int did_triple = 0;
+
+ ptr = (char *)&(_ecore_fb_ps2_event);
+ ptr += _ecore_fb_ps2_event_byte_count;
+ num = sizeof(Ecore_Fb_Ps2_Event) - _ecore_fb_ps2_event_byte_count;
+ v = read(_ecore_fb_ps2_fd, ptr, num);
+ if (v < 0) return EINA_TRUE;
+ _ecore_fb_ps2_event_byte_count += v;
+ if (v < num) return EINA_TRUE;
+ t = ecore_loop_time_get();
+ _ecore_fb_ps2_event_byte_count = 0;
+ if (_ecore_fb_ps2_event.button & 0x10)
+ x = prev_x + (0xffffff00 | _ecore_fb_ps2_event.x);
+ else
+ x = prev_x + _ecore_fb_ps2_event.x;
+ if (_ecore_fb_ps2_event.button & 0x20)
+ y = prev_y - (0xffffff00 | _ecore_fb_ps2_event.y);
+ else
+ y = prev_y - _ecore_fb_ps2_event.y;
+ button = _ecore_fb_ps2_event.button & 0x7;
+ if (x < 0) x = 0;
+ if (y < 0) y = 0;
+ if (x >= _ecore_fb_console_w) x = _ecore_fb_console_w - 1;
+ if (y >= _ecore_fb_console_h) y = _ecore_fb_console_h - 1;
+ /* add event to queue */
+ /* always add a move event */
+ if (1)
+ {
+ /* MOVE: mouse is down and was */
+ Ecore_Event_Mouse_Move *e;
+
+ e = calloc(1, sizeof(Ecore_Fb_Event_Mouse_Move));
+ if (!e) goto retry;
+ e->x = x;
+ e->y = y;
+ e->root.x = e->x;
+ e->root.y = e->y;
+ e->window = 1;
+ e->event_window = e->window;
+ e->root_window = e->window;
+ e->same_screen = 1;
+ e->timestamp = ecore_loop_time_get() * 1000.0;
+ ecore_event_add(ECORE_EVENT_MOUSE_MOVE, e, NULL, NULL);
+ }
+ for (i = 1; i <= 3; i++)
+ {
+ int mask;
+
+ mask = 1 << (i - 1);
+ if (((button & mask)) && (!(prev_button & mask)))
+ {
+ /* DOWN: mouse is down, but was not now */
+ Ecore_Event_Mouse_Button *e;
+
+ e = calloc(1, sizeof(Ecore_Event_Mouse_Button));
+ if (!e) goto retry;
+ e->x = x;
+ e->y = y;
+ e->root.x = e->x;
+ e->root.y = e->y;
+ e->button = i;
+ e->window = 1;
+ e->event_window = e->window;
+ e->root_window = e->window;
+ e->same_screen = 1;
+ if ((t - last_time) <= _ecore_fb_double_click_time)
+ {
+ e->double_click = 1;
+ did_double = 1;
+ }
+ else
+ {
+ did_double = 0;
+ did_triple = 0;
+ }
+ if ((t - last_last_time) <= (2 * _ecore_fb_double_click_time))
+ {
+ did_triple = 1;
+ e->triple_click = 1;
+ }
+ else
+ {
+ did_triple = 0;
+ }
+ e->timestamp = ecore_loop_time_get() * 1000.0;
+ ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, e, NULL, NULL);
+ }
+ else if ((!(button & mask)) && ((prev_button & mask)))
+ {
+ /* UP: mouse was down, but is not now */
+ Ecore_Event_Mouse_Button *e;
+
+ e = calloc(1, sizeof(Ecore_Event_Mouse_Button));
+ if (!e) goto retry;
+ e->x = x;
+ e->y = y;
+ e->root.x = e->x;
+ e->root.y = e->y;
+ e->button = i;
+ e->window = 1;
+ e->event_window = e->window;
+ e->root_window = e->window;
+ e->same_screen = 1;
+ if (did_double)
+ e->double_click = 1;
+ if (did_triple)
+ e->triple_click = 1;
+ e->timestamp = ecore_loop_time_get() * 1000.0;
+ ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_UP, e, NULL, NULL);
+ }
+ }
+ if (did_triple)
+ {
+ last_time = 0;
+ last_last_time = 0;
+ }
+ else
+ {
+ last_last_time = last_time;
+ last_time = t;
+ }
+ retry:
+ prev_x = x;
+ prev_y = y;
+ prev_button = button;
+ }
+ while (v > 0);
+ return EINA_TRUE;
+}
+/**
+ * @defgroup Ecore_FB_Click_Group Framebuffer Double Click Functions
+ *
+ * Functions that deal with the double click time of the framebuffer.
+ */
+
+/**
+ * Sets the timeout for a double and triple clicks to be flagged.
+ *
+ * This sets the time between clicks before the double_click flag is
+ * set in a button down event. If 3 clicks occur within double this
+ * time, the triple_click flag is also set.
+ *
+ * @param t The time in seconds
+ * @ingroup Ecore_FB_Click_Group
+ */
+EAPI void
+ecore_fb_double_click_time_set(double t)
+{
+ if (t < 0.0) t = 0.0;
+ _ecore_fb_double_click_time = t;
+}
+
+/**
+ * Retrieves the double and triple click flag timeout.
+ *
+ * See @ref ecore_x_double_click_time_set for more information.
+ *
+ * @return The timeout for double clicks in seconds.
+ * @ingroup Ecore_FB_Click_Group
+ */
+EAPI double
+ecore_fb_double_click_time_get(void)
+{
+ return _ecore_fb_double_click_time;
+}
+
diff --git a/src/lib/ecore_fb/ecore_fb_ts.c b/src/lib/ecore_fb/ecore_fb_ts.c
new file mode 100644
index 0000000000..ce9c733c3e
--- /dev/null
+++ b/src/lib/ecore_fb/ecore_fb_ts.c
@@ -0,0 +1,362 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#ifdef HAVE_TSLIB
+# include <tslib.h>
+# include <errno.h>
+#endif
+
+#include "Ecore_Fb.h"
+#include "ecore_fb_private.h"
+
+typedef struct _Ecore_Fb_Ts_Event Ecore_Fb_Ts_Event;
+typedef struct _Ecore_Fb_Ts_Calibrate Ecore_Fb_Ts_Calibrate;
+typedef struct _Ecore_Fb_Ts_Backlight Ecore_Fb_Ts_Backlight;
+typedef struct _Ecore_Fb_Ts_Contrast Ecore_Fb_Ts_Contrast;
+typedef struct _Ecore_Fb_Ts_Led Ecore_Fb_Ts_Led;
+typedef struct _Ecore_Fb_Ts_Flite Ecore_Fb_Ts_Flite;
+
+struct _Ecore_Fb_Ts_Event
+{
+ unsigned short pressure;
+ unsigned short x;
+ unsigned short y;
+ unsigned short _unused;
+};
+
+struct _Ecore_Fb_Ts_Calibrate
+{
+ int xscale;
+ int xtrans;
+ int yscale;
+ int ytrans;
+ int xyswap;
+};
+
+struct _Ecore_Fb_Ts_Backlight
+{
+ int on;
+ unsigned char brightness;
+};
+
+struct _Ecore_Fb_Ts_Contrast
+{
+ unsigned char contrast;
+};
+
+struct _Ecore_Fb_Ts_Led
+{
+ unsigned char on;
+ unsigned char blink_time;
+ unsigned char on_time;
+ unsigned char off_time;
+};
+
+struct _Ecore_Fb_Ts_Flite
+{
+ unsigned char mode;
+ unsigned char pwr;
+ unsigned char brightness;
+};
+
+static Eina_Bool _ecore_fb_ts_fd_handler(void *data, Ecore_Fd_Handler *fd_handler);
+static int _ecore_fb_ts_fd = -1;
+static int _ecore_fb_ts_event_byte_count = 0;
+static int _ecore_fb_ts_apply_cal = 0;
+static Ecore_Fb_Ts_Event _ecore_fb_ts_event;
+static Ecore_Fb_Ts_Calibrate _ecore_fb_ts_cal = {1,1,0,0,0};
+static Ecore_Fd_Handler *_ecore_fb_ts_fd_handler_handle = NULL;
+
+#ifdef HAVE_TSLIB
+struct tsdev *_ecore_fb_tslib_tsdev = NULL;
+struct ts_sample _ecore_fb_tslib_event;
+#endif
+
+static double _ecore_fb_double_click_time = 0.25;
+static void *_ecore_fb_ts_event_window = NULL;
+
+EAPI int
+ecore_fb_ts_init(void)
+{
+#ifdef HAVE_TSLIB
+ char *tslib_tsdevice = NULL;
+ if ( (tslib_tsdevice = getenv("TSLIB_TSDEVICE")) )
+ {
+ printf( "ECORE_FB: TSLIB_TSDEVICE = '%s'\n", tslib_tsdevice );
+ _ecore_fb_tslib_tsdev = ts_open( tslib_tsdevice, 1 ); /* 1 = nonblocking, 0 = blocking */
+
+ if ( !_ecore_fb_tslib_tsdev )
+ {
+ printf( "ECORE_FB: Can't ts_open (%s)\n", strerror( errno ) );
+ return 0;
+ }
+
+ if ( ts_config( _ecore_fb_tslib_tsdev ) )
+ {
+ printf( "ECORE_FB: Can't ts_config (%s)\n", strerror( errno ) );
+ return 0;
+ }
+ _ecore_fb_ts_fd = ts_fd( _ecore_fb_tslib_tsdev );
+ if ( _ecore_fb_ts_fd < 0 )
+ {
+ printf( "ECORE_FB: Can't open touchscreen (%s)\n", strerror( errno ) );
+ return 0;
+ }
+ }
+#else
+ _ecore_fb_ts_fd = open("/dev/touchscreen/0", O_RDONLY);
+#endif
+ if (_ecore_fb_ts_fd >= 0)
+ {
+ _ecore_fb_ts_fd_handler_handle = ecore_main_fd_handler_add(_ecore_fb_ts_fd,
+ ECORE_FD_READ,
+ _ecore_fb_ts_fd_handler, NULL,
+ NULL, NULL);
+ if (!_ecore_fb_ts_fd_handler_handle)
+ {
+ close(_ecore_fb_ts_fd);
+ return 0;
+ }
+ // FIXME _ecore_fb_kbd_fd = open("/dev/touchscreen/key", O_RDONLY);
+ return 1;
+ }
+ return 0;
+}
+
+EAPI void
+ecore_fb_ts_shutdown(void)
+{
+ if (_ecore_fb_ts_fd_handler_handle)
+ ecore_main_fd_handler_del(_ecore_fb_ts_fd_handler_handle);
+ if (_ecore_fb_ts_fd >= 0) close(_ecore_fb_ts_fd);
+ _ecore_fb_ts_fd = -1;
+ _ecore_fb_ts_fd_handler_handle = NULL;
+ _ecore_fb_ts_event_window = NULL;
+}
+
+EAPI void
+ecore_fb_ts_event_window_set(void *window)
+{
+ _ecore_fb_ts_event_window = window;
+}
+
+EAPI void *
+ecore_fb_ts_event_window_get(void)
+{
+ return _ecore_fb_ts_event_window;
+}
+
+/**
+ * @defgroup Ecore_FB_Calibrate_Group Framebuffer Calibration Functions
+ *
+ * Functions that calibrate the screen.
+ */
+
+
+/**
+ * Calibrates the touschreen using the given parameters.
+ * @param xscale X scaling, where 256 = 1.0
+ * @param xtrans X translation.
+ * @param yscale Y scaling.
+ * @param ytrans Y translation.
+ * @param xyswap Swap X & Y flag.
+ * @ingroup Ecore_FB_Calibrate_Group
+ */
+EAPI void
+ecore_fb_touch_screen_calibrate_set(int xscale, int xtrans, int yscale, int ytrans, int xyswap)
+{
+ Ecore_Fb_Ts_Calibrate cal;
+
+ if (_ecore_fb_ts_fd < 0) return;
+ cal.xscale = xscale;
+ cal.xtrans = xtrans;
+ cal.yscale = yscale;
+ cal.ytrans = ytrans;
+ cal.xyswap = xyswap;
+ if (ioctl(_ecore_fb_ts_fd, TS_SET_CAL, (void *)&cal))
+ {
+ _ecore_fb_ts_cal = cal;
+ _ecore_fb_ts_apply_cal = 1;
+ }
+}
+
+/**
+ * Retrieves the calibration parameters of the touchscreen.
+ * @param xscale Pointer to an integer in which to store the X scaling.
+ * Note that 256 = 1.0.
+ * @param xtrans Pointer to an integer in which to store the X translation.
+ * @param yscale Pointer to an integer in which to store the Y scaling.
+ * @param ytrans Pointer to an integer in which to store the Y translation.
+ * @param xyswap Pointer to an integer in which to store the Swap X & Y flag.
+ * @ingroup Ecore_FB_Calibrate_Group
+ */
+EAPI void
+ecore_fb_touch_screen_calibrate_get(int *xscale, int *xtrans, int *yscale, int *ytrans, int *xyswap)
+{
+ Ecore_Fb_Ts_Calibrate cal;
+
+ if (_ecore_fb_ts_fd < 0) return;
+ if (!_ecore_fb_ts_apply_cal)
+ {
+ if (ioctl(_ecore_fb_ts_fd, TS_GET_CAL, (void *)&cal))
+ _ecore_fb_ts_cal = cal;
+ }
+ else
+ cal = _ecore_fb_ts_cal;
+ if (xscale) *xscale = cal.xscale;
+ if (xtrans) *xtrans = cal.xtrans;
+ if (yscale) *yscale = cal.yscale;
+ if (ytrans) *ytrans = cal.ytrans;
+ if (xyswap) *xyswap = cal.xyswap;
+}
+
+static Eina_Bool
+_ecore_fb_ts_fd_handler(void *data EINA_UNUSED, Ecore_Fd_Handler *fd_handler EINA_UNUSED)
+{
+ static int prev_x = 0, prev_y = 0, prev_pressure = 0;
+ static double last_time = 0;
+ static double last_last_time = 0;
+ int v = 0;
+
+ do
+ {
+ int x, y, pressure;
+ int num;
+ char *ptr;
+ double t = 0.0;
+ static int did_double = 0;
+ static int did_triple = 0;
+
+#ifdef HAVE_TSLIB
+ if (_ecore_fb_ts_apply_cal)
+ num = ts_read_raw(_ecore_fb_tslib_tsdev, &_ecore_fb_tslib_event, 1);
+ else
+ num = ts_read(_ecore_fb_tslib_tsdev, &_ecore_fb_tslib_event, 1);
+ if (num != 1) return 1; /* no more samples at this time */
+ x = _ecore_fb_tslib_event.x;
+ y = _ecore_fb_tslib_event.y;
+ pressure = _ecore_fb_tslib_event.pressure;
+ v = 1; /* loop, there might be more samples */
+#else
+ ptr = (char *)&(_ecore_fb_ts_event);
+ ptr += _ecore_fb_ts_event_byte_count;
+ num = sizeof(Ecore_Fb_Ts_Event) - _ecore_fb_ts_event_byte_count;
+ v = read(_ecore_fb_ts_fd, ptr, num);
+ if (v < 0) return 1;
+ _ecore_fb_ts_event_byte_count += v;
+ if (v < num) return 1;
+ _ecore_fb_ts_event_byte_count = 0;
+ if (_ecore_fb_ts_apply_cal)
+ {
+ x = ((_ecore_fb_ts_cal.xscale * _ecore_fb_ts_event.x) >> 8) + _ecore_fb_ts_cal.xtrans;
+ y = ((_ecore_fb_ts_cal.yscale * _ecore_fb_ts_event.y) >> 8) + _ecore_fb_ts_cal.ytrans;
+ }
+ else
+ {
+ x = _ecore_fb_ts_event.x;
+ y = _ecore_fb_ts_event.y;
+ }
+ pressure = _ecore_fb_ts_event.pressure;
+#endif
+ t = ecore_loop_time_get();
+ /* add event to queue */
+ /* always add a move event */
+ if ((pressure) || (prev_pressure))
+ {
+ /* MOVE: mouse is down and was */
+ Ecore_Event_Mouse_Move *e;
+
+ e = calloc(1, sizeof(Ecore_Event_Mouse_Move));
+ if (!e) goto retry;
+ e->x = x;
+ e->y = y;
+ e->root.x = e->x;
+ e->root.y = e->y;
+ e->window = 1;
+ e->event_window = e->window;
+ e->root_window = e->window;
+ e->same_screen = 1;
+ e->timestamp = ecore_loop_time_get() * 1000.0;
+ ecore_event_add(ECORE_EVENT_MOUSE_MOVE, e, NULL, NULL);
+ }
+ if ((pressure) && (!prev_pressure))
+ {
+ /* DOWN: mouse is down, but was not now */
+ Ecore_Event_Mouse_Button *e;
+
+ e = calloc(1, sizeof(Ecore_Event_Mouse_Button));
+ if (!e) goto retry;
+ e->x = x;
+ e->y = y;
+ e->root.x = e->x;
+ e->root.y = e->y;
+ e->buttons = 1;
+ if ((t - last_time) <= _ecore_fb_double_click_time)
+ {
+ e->double_click = 1;
+ did_double = 1;
+ }
+ else
+ {
+ did_double = 0;
+ did_triple = 0;
+ }
+ if ((t - last_last_time) <= (2 * _ecore_fb_double_click_time))
+ {
+ did_triple = 1;
+ e->triple_click = 1;
+ }
+ else
+ {
+ did_triple = 0;
+ }
+ e->window = 1;
+ e->event_window = e->window;
+ e->root_window = e->window;
+ e->same_screen = 1;
+ e->timestamp = ecore_loop_time_get() * 1000.0;
+ ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_DOWN, e, NULL, NULL);
+ }
+ else if ((!pressure) && (prev_pressure))
+ {
+ /* UP: mouse was down, but is not now */
+ Ecore_Event_Mouse_Button *e;
+
+ e = calloc(1, sizeof(Ecore_Event_Mouse_Button));
+ if (!e) goto retry;
+ e->x = prev_x;
+ e->y = prev_y;
+ e->root.x = e->x;
+ e->root.y = e->y;
+ e->buttons = 1;
+ if (did_double)
+ e->double_click = 1;
+ if (did_triple)
+ e->triple_click = 1;
+ e->window = 1;
+ e->event_window = e->window;
+ e->root_window = e->window;
+ e->same_screen = 1;
+ e->timestamp = ecore_loop_time_get() * 1000.0;
+ ecore_event_add(ECORE_EVENT_MOUSE_BUTTON_UP, e, NULL, NULL);
+ }
+ if (did_triple)
+ {
+ last_time = 0;
+ last_last_time = 0;
+ }
+ else
+ {
+ last_last_time = last_time;
+ last_time = t;
+ }
+retry:
+ prev_x = x;
+ prev_y = y;
+ prev_pressure = pressure;
+ }
+ while (v > 0);
+ return 1;
+}
+
diff --git a/src/lib/ecore_fb/ecore_fb_vt.c b/src/lib/ecore_fb/ecore_fb_vt.c
new file mode 100644
index 0000000000..c92c087336
--- /dev/null
+++ b/src/lib/ecore_fb/ecore_fb_vt.c
@@ -0,0 +1,322 @@
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "Ecore_Fb.h"
+#include "ecore_fb_private.h"
+
+static int _ecore_fb_vt_do_switch = 0;
+
+static int _ecore_fb_vt_tty0_fd = -1;
+static int _ecore_fb_vt_tty_fd = -1;
+static int _ecore_fb_vt_current_vt = 0;
+static int _ecore_fb_vt_prev_vt = 0;
+
+static struct termios _ecore_fb_tty_prev_tio_mode;
+static struct vt_mode _ecore_fb_vt_prev_mode;
+
+static Eina_Bool _ecore_fb_signal_usr_handler(void *data, int type, void *ev);
+static Ecore_Event_Handler *_ecore_fb_user_handler = NULL;
+static int _ecore_fb_tty_prev_mode = 0;
+static int _ecore_fb_tty_prev_kd_mode = 0;
+
+/* callbacks for an attach/release of a vt */
+static void (*_ecore_fb_func_fb_lost) (void *data) = NULL;
+static void *_ecore_fb_func_fb_lost_data = NULL;
+static void (*_ecore_fb_func_fb_gain) (void *data) = NULL;
+static void *_ecore_fb_func_fb_gain_data = NULL;
+
+/* FIXME what is the filter for? */
+static Ecore_Event_Filter *_ecore_fb_filter_handler = NULL;
+
+/* prototypes */
+/* XXX: unused
+static void _ecore_fb_vt_switch(int vt);
+static void *_ecore_fb_event_filter_start(void *data);
+static Eina_Bool _ecore_fb_event_filter_filter(void *data, void *loop_data, int type, void *event);
+static void _ecore_fb_event_filter_end(void *data, void *loop_data);
+*/
+
+static Eina_Bool
+_ecore_fb_signal_usr_handler(void *data EINA_UNUSED, int type EINA_UNUSED, void *ev)
+{
+ Ecore_Event_Signal_User *e;
+
+ e = (Ecore_Event_Signal_User *)ev;
+ if (e->number == 1)
+ {
+ /* release vt */
+ if (_ecore_fb_func_fb_lost) _ecore_fb_func_fb_lost(_ecore_fb_func_fb_lost_data);
+ /* TODO stop listening from the devices? let the callback do it? */
+ ioctl(_ecore_fb_vt_tty_fd, VT_RELDISP, 1);
+ }
+ else if (e->number == 2)
+ {
+ /* attach vt */
+ if (_ecore_fb_func_fb_gain) _ecore_fb_func_fb_gain(_ecore_fb_func_fb_gain_data);
+ /* TODO reattach all devices */
+ }
+ return 1;
+}
+
+/* XXX: unused
+static void
+_ecore_fb_vt_switch(int vt)
+{
+ vt++;
+ if (_ecore_fb_vt_tty_fd != 0)
+ {
+ if (vt != _ecore_fb_vt_current_vt)
+ {
+ tcsetattr(_ecore_fb_vt_tty_fd, TCSAFLUSH, &_ecore_fb_tty_prev_tio_mode);
+ ioctl(_ecore_fb_vt_tty_fd, KDSETMODE, _ecore_fb_tty_prev_kd_mode);
+ ioctl(_ecore_fb_vt_tty_fd, KDSKBMODE, _ecore_fb_tty_prev_mode);
+ }
+ }
+ ioctl(_ecore_fb_vt_tty_fd, VT_ACTIVATE, vt);
+}
+*/
+
+static int
+_ecore_fb_vt_setup(void)
+{
+ char buf[64];
+// XXX: unused
+// struct termios tio;
+ struct vt_mode new_vtmode;
+
+ if (_ecore_fb_vt_current_vt != _ecore_fb_vt_prev_vt)
+ {
+ snprintf(buf, sizeof(buf), "/dev/tty%i", _ecore_fb_vt_current_vt);
+ if ((_ecore_fb_vt_tty_fd = open(buf, O_RDWR)) < 0)
+ {
+ printf("[ecore_fb:vt_setup] can't open tty %d\n", _ecore_fb_vt_current_vt);
+ return 0;
+ }
+ close(_ecore_fb_vt_tty0_fd);
+ _ecore_fb_vt_tty0_fd = -1;
+ /* FIXME detach the process from current tty ? */
+ }
+ else
+ _ecore_fb_vt_tty_fd = _ecore_fb_vt_tty0_fd;
+ /* for backup */
+ tcgetattr(_ecore_fb_vt_tty_fd, &_ecore_fb_tty_prev_tio_mode);
+ ioctl(_ecore_fb_vt_tty_fd, KDGETMODE, &_ecore_fb_tty_prev_kd_mode);
+ ioctl(_ecore_fb_vt_tty_fd, VT_GETMODE, &_ecore_fb_vt_prev_mode);
+
+ if (ioctl(_ecore_fb_vt_tty_fd, KDSETMODE, KD_GRAPHICS) < 0)
+ {
+ perror("[ecore_fb:vt_setup] can't set the mode to KD_GRAPHICS");
+ close(_ecore_fb_vt_tty_fd);
+ _ecore_fb_vt_tty_fd = -1;
+ return 0;
+ }
+ ioctl(_ecore_fb_vt_tty_fd, KDGKBMODE, &_ecore_fb_tty_prev_mode);
+
+ /* support of switching */
+ new_vtmode.mode = VT_PROCESS;
+ new_vtmode.waitv = 0;
+ new_vtmode.relsig = SIGUSR1;
+ new_vtmode.acqsig = SIGUSR2;
+ if (ioctl(_ecore_fb_vt_tty_fd, VT_SETMODE, &new_vtmode) < 0)
+ {
+ perror("[ecore_fb:vt_setup] can't set the tty mode");
+ close(_ecore_fb_vt_tty_fd);
+ _ecore_fb_vt_tty_fd = -1;
+ return 0;
+ }
+ /* register signal handlers when alloc/detach of vt */
+ _ecore_fb_user_handler = ecore_event_handler_add(ECORE_EVENT_SIGNAL_USER,
+ _ecore_fb_signal_usr_handler,
+ NULL);
+ /* What does this do? */
+ /*
+ _ecore_fb_filter_handler = ecore_event_filter_add(_ecore_fb_event_filter_start, _ecore_fb_event_filter_filter, _ecore_fb_event_filter_end, NULL);
+ */
+
+ usleep(40000);
+ if (ioctl(_ecore_fb_vt_tty_fd, VT_ACTIVATE, _ecore_fb_vt_current_vt) < 0)
+ {
+ perror("[ecore_fb:vt_setup] error on VT_ACTIVATE");
+ close(_ecore_fb_vt_tty_fd);
+ _ecore_fb_vt_tty_fd = -1;
+ return 0;
+ }
+ if(ioctl(_ecore_fb_vt_tty_fd, VT_WAITACTIVE, _ecore_fb_vt_current_vt) < 0)
+ {
+ perror("[ecore_fb:vt_setup] error on VT_WAITACTIVE");
+ close(_ecore_fb_vt_tty_fd);
+ _ecore_fb_vt_tty_fd = -1;
+ return 0;
+ }
+ /* FIXME assign the fb to the tty in case isn't setup */
+ return 1;
+}
+
+int
+ecore_fb_vt_init(void)
+{
+ struct vt_stat vtstat;
+
+ /* as root you can allocate another tty */
+ if (!geteuid())
+ _ecore_fb_vt_do_switch = 1;
+ if ((_ecore_fb_vt_tty0_fd = open("/dev/tty0", O_RDONLY)) < 0)
+ {
+ printf("[ecore_fb:init] can't open /dev/tty0\n");
+ return 0;
+ }
+ /* query current vt state */
+ if ((ioctl(_ecore_fb_vt_tty0_fd, VT_GETSTATE, &vtstat)) < 0)
+ {
+ printf("[ecore_fb:init] can't get current tty state\n");
+ return 0;
+ }
+ _ecore_fb_vt_prev_vt = vtstat.v_active;
+ /* switch to another tty */
+ if (_ecore_fb_vt_do_switch)
+ {
+ int vtno;
+
+ if ((ioctl(_ecore_fb_vt_tty0_fd, VT_OPENQRY, &vtno) < 0))
+ {
+ printf("[ecore_fb:init] can't query for a vt\n");
+ return 0;
+ }
+ _ecore_fb_vt_current_vt = vtno;
+ }
+ /* use current tty */
+ else
+ _ecore_fb_vt_current_vt = _ecore_fb_vt_prev_vt;
+ if (!_ecore_fb_vt_setup())
+ {
+ printf("[ecore_fb:init] can't setup the vt, restoring previous mode...\n");
+ /* TODO finish this */
+ if (_ecore_fb_vt_do_switch)
+ {
+ printf("[ecore_fb:init] switching back to vt %d\n", _ecore_fb_vt_prev_vt);
+ }
+ return 0;
+ }
+ return 1;
+}
+
+void
+ecore_fb_vt_shutdown(void)
+{
+ /* restore the previous mode */
+ if (_ecore_fb_vt_tty_fd != -1)
+ {
+ tcsetattr(_ecore_fb_vt_tty_fd, TCSAFLUSH, &_ecore_fb_tty_prev_tio_mode);
+ ioctl(_ecore_fb_vt_tty_fd, KDSETMODE, _ecore_fb_tty_prev_kd_mode);
+ ioctl(_ecore_fb_vt_tty_fd, KDSKBMODE, _ecore_fb_tty_prev_mode);
+ ioctl(_ecore_fb_vt_tty_fd, VT_SETMODE, &_ecore_fb_vt_prev_mode);
+ /* go back to previous vt */
+ close(_ecore_fb_vt_tty_fd);
+ _ecore_fb_vt_tty_fd = -1;
+ }
+
+ if (_ecore_fb_user_handler) ecore_event_handler_del(_ecore_fb_user_handler);
+ _ecore_fb_user_handler = NULL;
+
+ if (_ecore_fb_filter_handler) ecore_event_filter_del(_ecore_fb_filter_handler);
+ _ecore_fb_filter_handler = NULL;
+}
+
+/**
+ * @addtogroup Ecore_FB_Group Ecore_FB - Frame buffer convenience functions.
+ *
+ * @{
+ */
+
+/**
+ * @brief Set a callback called when a virtual terminal is gained.
+ *
+ * @param func The callback called when vt is gained.
+ * @param data The data to pass to the callback.
+ *
+ * This function sets the callback @p func which will be called when a
+ * virtual terminal is gained (for example you press Ctrl-Alt-F1 to go
+ * to vt1 and your app was using vt1). @p data will be pass to @p func if
+ * the callback is called.
+ */
+EAPI void
+ecore_fb_callback_gain_set(void (*func) (void *data), void *data)
+{
+ _ecore_fb_func_fb_gain = func;
+ _ecore_fb_func_fb_gain_data = data;
+}
+
+/**
+ * @brief Set a callback called when a virtual terminal is lost.
+ *
+ * @param func The callback called when vt is lost.
+ * @param data The data to pass to the callback.
+ *
+ * This function sets the callback @p func which will be called when a
+ * virtual terminal is lost (someone wants the tv from you and you
+ * want to give up that vt). @p data will be pass to @p func if the
+ * callback is called.
+ */
+EAPI void
+ecore_fb_callback_lose_set(void (*func) (void *data), void *data)
+{
+ _ecore_fb_func_fb_lost = func;
+ _ecore_fb_func_fb_lost_data = data;
+
+}
+
+/**
+ * @}
+ */
+
+/*
+ * This filter should take into account that the MOUSE_MOVE event can be
+ * triggered by a mouse, not just a touchscreen device, so you can't discard
+ * them (only those generated by a device that sends events with absolute
+ * coordinates).
+
+typedef struct _Ecore_Fb_Filter_Data Ecore_Fb_Filter_Data;
+
+struct _Ecore_Fb_Filter_Data
+{
+ int last_event_type;
+};
+
+static void *
+_ecore_fb_event_filter_start(void *data EINA_UNUSED)
+{
+ Ecore_Fb_Filter_Data *filter_data;
+
+ filter_data = calloc(1, sizeof(Ecore_Fb_Filter_Data));
+ return filter_data;
+}
+
+static Eina_Bool
+_ecore_fb_event_filter_filter(void *data EINA_UNUSED, void *loop_data,int type, void *event EINA_UNUSED)
+{
+ Ecore_Fb_Filter_Data *filter_data;
+
+ filter_data = loop_data;
+ if (!filter_data) return EINA_TRUE;
+ if (type == ECORE_EVENT_MOUSE_MOVE)
+ {
+ if ((filter_data->last_event_type) == ECORE_EVENT_MOUSE_MOVE)
+ {
+ filter_data->last_event_type = type;
+ return EINA_FALSE;
+ }
+ }
+ filter_data->last_event_type = type;
+ return EINA_TRUE;
+}
+
+static void
+_ecore_fb_event_filter_end(void *data EINA_UNUSED, void *loop_data)
+{
+ Ecore_Fb_Filter_Data *filter_data;
+
+ filter_data = loop_data;
+ if (filter_data) free(filter_data);
+}
+*/