From: notaz Date: Wed, 23 Nov 2011 00:16:23 +0000 (+0200) Subject: Add touchscreen coordinate translation X-Git-Url: https://notaz.gp2x.de/cgi-bin/gitweb.cgi?p=sdl_omap.git;a=commitdiff_plain;h=5f4b1fd346a57d90ffda9eaba68c7b0b0aa8acab Add touchscreen coordinate translation also refactor config stuff a bit --- diff --git a/README.OMAP b/README.OMAP index b39fb33..e1ddb06 100644 --- a/README.OMAP +++ b/README.OMAP @@ -54,6 +54,10 @@ SDL_OMAP_FORCE_DOUBLEBUF: Note that if app isn't updating whole buffer each frame, it will glitch. This is the same as specifying SDL_DOUBLEBUF to SDL_SetVideoMode. +SDL_OMAP_NO_TS_TRANSLATE: + Disable automatic touchscreen screen -> layer coordinate translation, + return real screen coordinates. + Config file ----------- @@ -68,6 +72,9 @@ force_vsync = 1/0 # same as SDL_OMAP_FORCE_DOUBLEBUF force_doublebuf = 1/0 +# same as SDL_OMAP_NO_TS_TRANSLATE +no_ts_translate = 1/0 + # can be used to bind a key to SDL keysym, good for quick ports. # Example: # bind ev_home = sdlk_space diff --git a/src/video/omapdss/config.c b/src/video/omapdss/config.c index adedaef..a1eb5fd 100644 --- a/src/video/omapdss/config.c +++ b/src/video/omapdss/config.c @@ -13,9 +13,6 @@ #include "omapsdl.h" -int gcfg_force_vsync; -int gcfg_force_doublebuf; - static char *sskip(char *p) { while (*p && isspace(*p)) @@ -52,7 +49,7 @@ static int check_token_eq(char **p_, const char *token) return ret; } -void omapsdl_config(void) +void omapsdl_config(struct SDL_PrivateVideoData *pdata) { char buff[256]; FILE *f; @@ -87,11 +84,15 @@ void omapsdl_config(void) continue; } else if (check_token_eq(&p, "force_vsync")) { - gcfg_force_vsync = strtol(p, NULL, 0); + pdata->cfg_force_vsync = !!strtol(p, NULL, 0); continue; } else if (check_token_eq(&p, "force_doublebuf")) { - gcfg_force_doublebuf = strtol(p, NULL, 0); + pdata->cfg_force_doublebuf = !!strtol(p, NULL, 0); + continue; + } + else if (check_token_eq(&p, "no_ts_translate")) { + pdata->cfg_no_ts_translate = !!strtol(p, NULL, 0); continue; } @@ -101,15 +102,18 @@ bad: fclose(f); } -void omapsdl_config_from_env(void) +void omapsdl_config_from_env(struct SDL_PrivateVideoData *pdata) { const char *tmp; tmp = getenv("SDL_OMAP_VSYNC"); if (tmp != NULL) - gcfg_force_vsync = strtol(tmp, NULL, 0); + pdata->cfg_force_vsync = !!strtol(tmp, NULL, 0); tmp = getenv("SDL_OMAP_FORCE_DOUBLEBUF"); if (tmp != NULL) - gcfg_force_doublebuf = strtol(tmp, NULL, 0); + pdata->cfg_force_doublebuf = !!strtol(tmp, NULL, 0); + tmp = getenv("SDL_OMAP_NO_TS_TRANSLATE"); + if (tmp != NULL) + pdata->cfg_no_ts_translate = !!strtol(tmp, NULL, 0); } diff --git a/src/video/omapdss/omapsdl.h b/src/video/omapdss/omapsdl.h index 3f15bb7..1f937c0 100644 --- a/src/video/omapdss/omapsdl.h +++ b/src/video/omapdss/omapsdl.h @@ -28,8 +28,17 @@ struct SDL_PrivateVideoData { struct vout_fbdev *fbdev; void *saved_layer; - int screen_w, screen_h; + /* physical screen size, should match touchscreen */ + int phys_w, phys_h; + /* layer */ + int layer_x, layer_y, layer_w, layer_h; + /* phys -> layer coord multipliers (16.16) */ + int ts_xmul, ts_ymul; + /* misc/config */ unsigned int xenv_up:1; + unsigned int cfg_force_vsync:1; + unsigned int cfg_force_doublebuf:1; + unsigned int cfg_no_ts_translate:1; }; int osdl_video_set_mode(struct SDL_PrivateVideoData *pdata, @@ -46,12 +55,9 @@ int omapsdl_input_get_events(int timeout_ms, void *cb_arg); void omapsdl_input_finish(void); -void omapsdl_config(void); -void omapsdl_config_from_env(void); +void omapsdl_config(struct SDL_PrivateVideoData *pdata); +void omapsdl_config_from_env(struct SDL_PrivateVideoData *pdata); /* functions for standalone */ void do_clut(void *dest, void *src, unsigned short *pal, int count); -/* config */ -extern int gcfg_force_vsync; -extern int gcfg_force_doublebuf; diff --git a/src/video/omapdss/osdl_video.c b/src/video/omapdss/osdl_video.c index d00b6b9..fce7eea 100644 --- a/src/video/omapdss/osdl_video.c +++ b/src/video/omapdss/osdl_video.c @@ -42,6 +42,9 @@ static int osdl_setup_omapfb(int fd, int enabled, int x, int y, int w, int h, in struct omapfb_mem_info mi; int ret; + memset(&pi, 0, sizeof(pi)); + memset(&mi, 0, sizeof(mi)); + ret = ioctl(fd, OMAPFB_QUERY_PLANE, &pi); if (ret != 0) { err_perror("QUERY_PLANE"); @@ -123,6 +126,8 @@ int osdl_video_detect_screen(struct SDL_PrivateVideoData *pdata) int w, h; FILE *f; + pdata->phys_w = pdata->phys_h = 0; + fbname = get_fb_device(); /* Figure out screen resolution, we need to know default resolution @@ -190,8 +195,8 @@ int osdl_video_detect_screen(struct SDL_PrivateVideoData *pdata) log("detected %dx%d '%s' (%d) screen attached to fb %d and overlay %d", w, h, screen_name, screen_id, fb_id, overlay_id); - pdata->screen_w = w; - pdata->screen_h = h; + pdata->phys_w = w; + pdata->phys_h = h; return 0; skip_screen: @@ -214,8 +219,8 @@ skip_screen: return -1; } - pdata->screen_w = fbvar.xres; - pdata->screen_h = fbvar.yres; + pdata->phys_w = fbvar.xres; + pdata->phys_h = fbvar.yres; return 0; } @@ -228,10 +233,12 @@ static int osdl_setup_omap_layer(struct SDL_PrivateVideoData *pdata, const char *tmp; int ret, fd; - if (pdata->screen_w != 0) - screen_w = pdata->screen_w; - if (pdata->screen_h != 0) - screen_h = pdata->screen_h; + pdata->layer_x = pdata->layer_y = pdata->layer_w = pdata->layer_h = 0; + + if (pdata->phys_w != 0) + screen_w = pdata->phys_w; + if (pdata->phys_h != 0) + screen_h = pdata->phys_h; fd = open(fbname, O_RDWR); if (fd == -1) { @@ -285,6 +292,12 @@ static int osdl_setup_omap_layer(struct SDL_PrivateVideoData *pdata, x = screen_w / 2 - w / 2; y = screen_h / 2 - h / 2; ret = osdl_setup_omapfb(fd, 1, x, y, w, h, width * height * ((bpp + 7) / 8) * 2); + if (ret == 0) { + pdata->layer_x = x; + pdata->layer_y = y; + pdata->layer_w = w; + pdata->layer_h = h; + } close(fd); return ret; @@ -325,7 +338,7 @@ void *osdl_video_flip(struct SDL_PrivateVideoData *pdata) if (pdata->fbdev == NULL) return NULL; - if (gcfg_force_vsync) + if (pdata->cfg_force_vsync) vout_fbdev_wait_vsync(pdata->fbdev); return vout_fbdev_flip(pdata->fbdev); diff --git a/src/video/omapdss/sdlif.c b/src/video/omapdss/sdlif.c index fd4925c..a4443c8 100644 --- a/src/video/omapdss/sdlif.c +++ b/src/video/omapdss/sdlif.c @@ -39,7 +39,7 @@ static int omap_VideoInit(SDL_VideoDevice *this, SDL_PixelFormat *vformat) vformat->BitsPerPixel = 16; omapsdl_input_init(); - omapsdl_config(); + omapsdl_config(this->hidden); tmp = getenv("SDL_OMAP_DEFAULT_MODE"); if (tmp != NULL && sscanf(tmp, "%dx%d", &w, &h) == 2) { @@ -47,8 +47,8 @@ static int omap_VideoInit(SDL_VideoDevice *this, SDL_PixelFormat *vformat) this->info.current_h = h; } else if (osdl_video_detect_screen(this->hidden) == 0) { - this->info.current_w = this->hidden->screen_w; - this->info.current_h = this->hidden->screen_h; + this->info.current_w = this->hidden->phys_w; + this->info.current_h = this->hidden->phys_h; } this->handles_any_size = 1; @@ -91,13 +91,14 @@ static SDL_Rect **omap_ListModes(SDL_VideoDevice *this, SDL_PixelFormat *format, static SDL_Surface *omap_SetVideoMode(SDL_VideoDevice *this, SDL_Surface *current, int width, int height, int bpp, Uint32 flags) { + struct SDL_PrivateVideoData *pdata = this->hidden; SDL_PixelFormat *format; Uint32 unhandled_flags; int ret; trace("%d, %d, %d, %08x", width, height, bpp, flags); - omapsdl_config_from_env(); + omapsdl_config_from_env(pdata); switch (bpp) { case 16: @@ -116,12 +117,12 @@ static SDL_Surface *omap_SetVideoMode(SDL_VideoDevice *this, SDL_Surface *curren if (format == NULL) return NULL; - if (!(flags & SDL_DOUBLEBUF) && gcfg_force_doublebuf) { + if (!(flags & SDL_DOUBLEBUF) && pdata->cfg_force_doublebuf) { log("forcing SDL_DOUBLEBUF"); flags |= SDL_DOUBLEBUF; } - ret = osdl_video_set_mode(this->hidden, width, height, bpp, + ret = osdl_video_set_mode(pdata, width, height, bpp, (flags & SDL_DOUBLEBUF) ? 1 : 0); if (ret < 0) return NULL; @@ -138,7 +139,12 @@ static SDL_Surface *omap_SetVideoMode(SDL_VideoDevice *this, SDL_Surface *curren current->h = height; current->pitch = SDL_CalculatePitch(current); - current->pixels = osdl_video_flip(this->hidden); + if (pdata->layer_w != 0 && pdata->layer_h != 0) { + pdata->ts_xmul = (width << 16) / pdata->layer_w; + pdata->ts_ymul = (height << 16) / pdata->layer_h; + } + + current->pixels = osdl_video_flip(pdata); return current; } @@ -208,9 +214,24 @@ static int key_event_cb(void *cb_arg, int sdl_kc, int is_pressed) SDL_PrivateKeyboard(is_pressed, &keysym); } +/* clamp x to min..max-1 */ +#define clamp(x, min, max) \ + 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 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 = (x - pdata->layer_x) * pdata->ts_xmul >> 16; + y = (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); @@ -228,7 +249,7 @@ static void omap_PumpEvents(SDL_VideoDevice *this) trace(); - omapsdl_input_get_events(0, key_event_cb, ts_event_cb, NULL); + omapsdl_input_get_events(0, key_event_cb, ts_event_cb, this); // XXX: we might want to process some X events too if (pdata->xenv_up)