Disable automatic touchscreen screen -> layer coordinate translation,
return real screen coordinates.
+SDL_OMAP_TS_FORCE_TSLIB:
+ Always use tslib to read touchscreen. Without this, use X events when they
+ are available (this gives external input device support).
+
Config file
-----------
# same as SDL_OMAP_NO_TS_TRANSLATE
no_ts_translate = 1/0
+# same as SDL_OMAP_TS_FORCE_TSLIB
+ts_force_tslib = 1/0
+
# can be used to bind a key to SDL keysym, good for quick ports.
# Example:
# bind ev_home = sdlk_space
pdata->cfg_no_ts_translate = !!strtol(p, NULL, 0);
continue;
}
+ else if (check_token_eq(&p, "ts_force_tslib")) {
+ pdata->cfg_ts_force_tslib = !!strtol(p, NULL, 0);
+ continue;
+ }
bad:
err("config: failed to parse: %s", line);
tmp = getenv("SDL_OMAP_NO_TS_TRANSLATE");
if (tmp != NULL)
pdata->cfg_no_ts_translate = !!strtol(tmp, NULL, 0);
+ tmp = getenv("SDL_OMAP_TS_FORCE_TSLIB");
+ if (tmp != NULL)
+ pdata->cfg_ts_force_tslib = !!strtol(tmp, NULL, 0);
tmp = getenv("SDL_OMAP_BORDER_CUT");
if (tmp != NULL) {
int l, r, t, b;
/*
- * (C) Gražvydas "notaz" Ignotas, 2009-2011
+ * (C) Gražvydas "notaz" Ignotas, 2009-2012
*
* This work is licensed under the terms of any of these licenses
* (at your option):
attributes.cursor = transparent_cursor(&g_xstuff, display, win);
g_xstuff.pXChangeWindowAttributes(display, win, CWOverrideRedirect | CWCursor, &attributes);
- g_xstuff.pXSelectInput(display, win, ExposureMask | FocusChangeMask | KeyPressMask | KeyReleaseMask);
+ g_xstuff.pXSelectInput(display, win, ExposureMask | FocusChangeMask | KeyPressMask
+ | KeyReleaseMask | ButtonPressMask | ButtonReleaseMask | PointerMotionMask);
g_xstuff.pXMapWindow(display, win);
g_xstuff.pXGrabKeyboard(display, win, False, GrabModeAsync, GrabModeAsync, CurrentTime);
g_xstuff.pXkbSetDetectableAutoRepeat(display, 1, NULL);
return -1;
}
-static int x11h_update(int *is_down)
+static void x11h_update(int (*key_cb)(void *cb_arg, int kc, int is_pressed),
+ int (*mouseb_cb)(void *cb_arg, int x, int y, int button, int is_pressed),
+ int (*mousem_cb)(void *cb_arg, int x, int y),
+ void *cb_arg)
{
XEvent evt;
+ int keysym;
while (g_xstuff.pXPending(g_xstuff.display))
{
g_xstuff.pXNextEvent(g_xstuff.display, &evt);
switch (evt.type)
{
- case Expose:
- while (g_xstuff.pXCheckTypedEvent(g_xstuff.display, Expose, &evt))
- ;
- break;
-
- case KeyPress:
- *is_down = 1;
- return g_xstuff.pXLookupKeysym(&evt.xkey, 0);
-
- case KeyRelease:
- *is_down = 0;
- return g_xstuff.pXLookupKeysym(&evt.xkey, 0);
- // printf("press %d\n", evt.xkey.keycode);
+ case Expose:
+ while (g_xstuff.pXCheckTypedEvent(g_xstuff.display, Expose, &evt))
+ ;
+ break;
+
+ case KeyPress:
+ keysym = g_xstuff.pXLookupKeysym(&evt.xkey, 0);
+ if (key_cb != NULL)
+ key_cb(cb_arg, keysym, 1);
+ break;
+
+ case KeyRelease:
+ keysym = g_xstuff.pXLookupKeysym(&evt.xkey, 0);
+ if (key_cb != NULL)
+ key_cb(cb_arg, keysym, 0);
+ break;
+
+ case ButtonPress:
+ if (mouseb_cb != NULL)
+ mouseb_cb(cb_arg, evt.xbutton.x, evt.xbutton.y,
+ evt.xbutton.button, 1);
+ break;
+
+ case ButtonRelease:
+ if (mouseb_cb != NULL)
+ mouseb_cb(cb_arg, evt.xbutton.x, evt.xbutton.y,
+ evt.xbutton.button, 0);
+ break;
+
+ case MotionNotify:
+ if (mousem_cb != NULL)
+ mousem_cb(cb_arg, evt.xmotion.x, evt.xmotion.y);
+ break;
}
}
-
- return NoSymbol;
}
static struct termios g_kbd_termios_saved;
g_kbdfd = -1;
}
-int xenv_init(void)
+int xenv_init(int *have_mouse_events)
{
+ int have_mouse = 0;
int ret;
ret = x11h_init();
- if (ret == 0)
- return 0;
+ if (ret == 0) {
+ have_mouse = 1;
+ goto out;
+ }
ret = tty_init();
if (ret == 0)
- return 0;
+ goto out;
fprintf(stderr, PFX "error: both x11h_init and tty_init failed\n");
- return -1;
+ ret = -1;
+out:
+ if (have_mouse_events != NULL)
+ *have_mouse_events = have_mouse;
+ return ret;
}
-int xenv_update(int *is_down)
+int xenv_update(int (*key_cb)(void *cb_arg, int kc, int is_pressed),
+ int (*mouseb_cb)(void *cb_arg, int x, int y, int button, int is_pressed),
+ int (*mousem_cb)(void *cb_arg, int x, int y),
+ void *cb_arg)
{
- if (g_xstuff.display)
- return x11h_update(is_down);
+ if (g_xstuff.display) {
+ x11h_update(key_cb, mouseb_cb, mousem_cb, cb_arg);
+ return 0;
+ }
// TODO: read tty?
return -1;
-int xenv_init(void);
-int xenv_update(int *is_down);
+int xenv_init(int *have_mouse_events);
+
+/* read events from X, calling key_cb for key, mouseb_cb for mouse button
+ * and mousem_cb for mouse motion events */
+int xenv_update(int (*key_cb)(void *cb_arg, int kc, int is_pressed),
+ int (*mouseb_cb)(void *cb_arg, int x, int y, int button, int is_pressed),
+ int (*mousem_cb)(void *cb_arg, int x, int y),
+ void *cb_arg);
+
void xenv_finish(void);
int ts_xmul, ts_ymul;
/* misc/config */
unsigned int xenv_up:1;
+ unsigned int xenv_mouse:1;
unsigned int app_uses_flip:1;
unsigned int cfg_force_vsync:1;
unsigned int cfg_force_doublebuf:1;
unsigned int cfg_no_ts_translate:1;
+ unsigned int cfg_ts_force_tslib:1;
};
void *osdl_video_set_mode(struct SDL_PrivateVideoData *pdata,
goto fail;
if (!pdata->xenv_up) {
- ret = xenv_init();
- if (ret == 0)
+ int xenv_mouse = 0;
+ ret = xenv_init(&xenv_mouse);
+ if (ret == 0) {
pdata->xenv_up = 1;
+ pdata->xenv_mouse = xenv_mouse;
+ }
}
if (buffers_try != buffers_set) {
if (x < (min)) x = min; \
if (x >= (max)) x = max
-static int ts_event_cb(void *cb_arg, int x, int y, unsigned int pressure)
+static void translate_mouse(SDL_VideoDevice *this, int *x, int *y)
{
- static int was_pressed;
- SDL_VideoDevice *this = cb_arg;
struct SDL_PrivateVideoData *pdata = this->hidden;
- int xoffs;
if (!pdata->cfg_no_ts_translate && pdata->layer_w != 0 && pdata->layer_h != 0) {
- x = pdata->border_l + ((x - pdata->layer_x) * pdata->ts_xmul >> 16);
- y = pdata->border_t + ((y - pdata->layer_y) * pdata->ts_ymul >> 16);
- clamp(x, 0, this->screen->w);
- clamp(y, 0, this->screen->h);
+ *x = pdata->border_l + ((*x - pdata->layer_x) * pdata->ts_xmul >> 16);
+ *y = pdata->border_t + ((*y - pdata->layer_y) * pdata->ts_ymul >> 16);
+ clamp(*x, 0, this->screen->w);
+ clamp(*y, 0, this->screen->h);
}
+}
- SDL_PrivateMouseMotion(0, 0, x, y);
+static int ts_event_cb(void *cb_arg, int x, int y, unsigned int pressure)
+{
+ static int was_pressed;
+ SDL_VideoDevice *this = cb_arg;
+ struct SDL_PrivateVideoData *pdata = this->hidden;
+
+ translate_mouse(this, &x, &y);
pressure = !!pressure;
if (pressure != was_pressed) {
- SDL_PrivateMouseButton(pressure ? SDL_PRESSED : SDL_RELEASED, 1, 0, 0);
+ SDL_PrivateMouseButton(pressure ? SDL_PRESSED : SDL_RELEASED, 1, x, y);
was_pressed = pressure;
}
+ else
+ SDL_PrivateMouseMotion(0, 0, x, y);
+}
+
+static int mouseb_event_cb(void *cb_arg, int x, int y, int button, int is_pressed)
+{
+ SDL_VideoDevice *this = cb_arg;
+ struct SDL_PrivateVideoData *pdata = this->hidden;
+
+ translate_mouse(this, &x, &y);
+ SDL_PrivateMouseButton(is_pressed ? SDL_PRESSED : SDL_RELEASED, button, x, y);
+}
+
+static int mousem_event_cb(void *cb_arg, int x, int y)
+{
+ SDL_VideoDevice *this = cb_arg;
+ struct SDL_PrivateVideoData *pdata = this->hidden;
+
+ translate_mouse(this, &x, &y);
+ SDL_PrivateMouseMotion(0, 0, x, y);
}
static void omap_PumpEvents(SDL_VideoDevice *this)
{
struct SDL_PrivateVideoData *pdata = this->hidden;
- int dummy;
+ int read_tslib = 1;
trace();
- omapsdl_input_get_events(0, key_event_cb, ts_event_cb, this);
+ if (pdata->xenv_up) {
+ if (!pdata->cfg_ts_force_tslib) {
+ xenv_update(NULL, mouseb_event_cb, mousem_event_cb, this);
+ if (pdata->xenv_mouse)
+ read_tslib = 0;
+ }
+ else {
+ /* just flush X event queue */
+ xenv_update(NULL, NULL, NULL, NULL);
+ }
+ }
- // XXX: we might want to process some X events too
- if (pdata->xenv_up)
- xenv_update(&dummy);
+ omapsdl_input_get_events(0, key_event_cb,
+ read_tslib ? ts_event_cb : NULL, this);
}
static SDL_VideoDevice *omap_create(int devindex)