--- trunk.orig/src/client.cc 2008-02-15 13:04:14.000000000 +0100 +++ enigma-1.10/src/client.cc 2008-02-16 13:06:11.000000000 +0100 @@ -51,12 +51,146 @@ using namespace ecl; using namespace std; +/* maemo build mods */ +int IS_MAEMO = 1; /* Mostly Keybinding specific stuff */ +int TOUCHSCREEN=1; +int TOUCHSCREEN_MULTIPLE=2; +int bFirstMove=1; + +/* the includes below ae required for the tiltstick interface */ +#include +#include +#include +#include +#include +#include /* linux kernel event interface */ + +int TILTSTICK_SCALE = 2; + #include "client_internal.hh" /* -------------------- Auxiliary functions -------------------- */ namespace { + int tiltstick_evif = 0; + + /* The maemo 2008 kernel does not include the joystick subsystem. */ + /* This program thus accesses the TiltStick via the even interface */ + /* the linux kernel is providing for all input devices */ + + /* open the event interface to the TiltStick */ + int evif_open(void) + { + DIR *dirp; + struct dirent *dp; + + dirp = opendir("/dev/input"); + if(!dirp) { + fprintf(stderr, "Unable to open directory /dev/input"); + return -1; + } + + /* try to find TiltStick interface */ + while ((dp = readdir(dirp)) != NULL) { + if(strncmp(dp->d_name, "event", 5) == 0) { + char tiltstick_name[256]; + + sprintf(tiltstick_name, "/dev/input/%s", dp->d_name); + if((tiltstick_evif = open(tiltstick_name, O_RDONLY)) >= 0) { + struct input_id id; + + /* suck out some device information */ + if(ioctl(tiltstick_evif, EVIOCGID, &id)) { + perror("ioctl(EVIOCGID)"); + } else { + /* only the tiltstick uses these vendor ids */ + if((id.vendor == 0x1c40) && (id.product == 0x0533)) { + printf("Found device at %s\n", tiltstick_name); + + if(ioctl(tiltstick_evif, EVIOCGNAME(sizeof(tiltstick_name)), + tiltstick_name) < 0) { + perror("ioctl(EVIOCGNAME)"); + } else + printf("Device name: %s\n", tiltstick_name); + + closedir(dirp); + return 0; + } + } + + close(tiltstick_evif); + tiltstick_evif = 0; + } else + fprintf(stderr, "Unable to open %s: %s\n", + tiltstick_name, strerror(errno)); + } + } + closedir(dirp); + return -1; + } + + int evif_poll(int *x, int *y) + { + fd_set rfds; + struct timeval tv; + int retval; + + static int xbuf = 0, ybuf = 0; + static int xrem = 0, yrem = 0; + int xcnt = 1, ycnt = 1; + + if(!tiltstick_evif) return -1; + + *x = xbuf + xrem; + *y = ybuf + yrem; + + do { + FD_ZERO(&rfds); + FD_SET(tiltstick_evif, &rfds); + + /* don't wait at all */ + tv.tv_sec = tv.tv_usec = 0; + + retval = select(FD_SETSIZE, &rfds, NULL, NULL, &tv); + + if (retval == -1) + perror("select()"); + else if (retval) { + if(FD_ISSET(tiltstick_evif, &rfds)) { + struct input_event ev; + + + if(read(tiltstick_evif, &ev, sizeof(struct input_event)) < 0) { + perror("read()"); + return -1; + } + + /* button press */ + if(ev.type == 1) printf("but: %d\n", ev.value); + + /* the TiltStick returns signed 12 bit values */ + if(ev.type == EV_ABS) { + if(!ev.code) { *x += (xbuf = ev.value); xcnt++; } + else { *y += (ybuf = ev.value); ycnt++; } + } + } + } + } while(retval > 0); /* read until no more data available */ + + *x /= xcnt; + *y /= ycnt; + + /* save remainder */ + xrem = *x % TILTSTICK_SCALE; + yrem = *y % TILTSTICK_SCALE; + + *x /= TILTSTICK_SCALE; + *y /= TILTSTICK_SCALE; + + return 0; + } + /*! Display a message and change the current mouse speed. */ void set_mousespeed (double speed) { @@ -112,6 +246,7 @@ m_cheater(false), m_user_input() { + evif_open(); m_network_host = 0; } @@ -190,22 +325,32 @@ void Client::handle_events() { SDL_Event e; + + int x, y; + evif_poll(&x, &y); + server::Msg_MouseForce ( V2 (x, y)); + while (SDL_PollEvent(&e)) { switch (e.type) { case SDL_KEYDOWN: on_keydown(e); break; case SDL_MOUSEMOTION: - if (abs(e.motion.xrel) > 300 || abs(e.motion.yrel) > 300) { - fprintf(stderr, "mouse event with %i, %i\n", e.motion.xrel, e.motion.yrel); - } - else - server::Msg_MouseForce (options::GetDouble("MouseSpeed") * - V2 (e.motion.xrel, e.motion.yrel)); + /* Ignore first moves after stylus lift (mouseup) */ + if ((TOUCHSCREEN==1) && (bFirstMove==1)) { bFirstMove = 0; } + else { + if (abs(e.motion.xrel) > 300 || abs(e.motion.yrel) > 300) { + fprintf(stderr, "mouse event with %i, %i\n", e.motion.xrel, e.motion.yrel); + } + else + server::Msg_MouseForce (options::GetDouble("MouseSpeed") * (TOUCHSCREEN?TOUCHSCREEN_MULTIPLE:1) * + V2 (e.motion.xrel, e.motion.yrel)); + } break; - case SDL_MOUSEBUTTONDOWN: + case SDL_MOUSEBUTTONDOWN: break; case SDL_MOUSEBUTTONUP: - on_mousebutton(e); + bFirstMove = 1; + if(!TOUCHSCREEN) on_mousebutton(e); break; case SDL_ACTIVEEVENT: { update_mouse_button_state(); @@ -441,9 +586,12 @@ server::Msg_Command ("suicide"); break; - case SDLK_F4: Msg_AdvanceLevel(lev::ADVANCE_STRICTLY); break; + case SDLK_F4: if (IS_MAEMO) { show_help(); } else Msg_AdvanceLevel(lev::ADVANCE_STRICTLY); break; case SDLK_F5: Msg_AdvanceLevel(lev::ADVANCE_UNSOLVED); break; - case SDLK_F6: Msg_JumpBack(); break; + case SDLK_F6: if (IS_MAEMO) { server::Msg_ActivateItem (); } else Msg_JumpBack(); break; + case SDLK_F7: if (IS_MAEMO) Msg_AdvanceLevel(lev::ADVANCE_STRICTLY); break; + case SDLK_F8: if (IS_MAEMO) rotate_inventory(+1); break; + case SDLK_F10: { lev::Proxy *level = lev::Proxy::loadedLevel();