void Android_OnTouch(int touch_device_id_in, int pointer_finger_id_in, int action, float x, float y, float p) 
{
    SDL_TouchID touchDeviceId = 0;
    SDL_FingerID fingerId = 0;
    
    if (!Android_Window) {
        return;
    }
    
    touchDeviceId = (SDL_TouchID)touch_device_id_in;
    if (!SDL_GetTouch(touchDeviceId)) {
        SDL_Touch touch;
        memset( &touch, 0, sizeof(touch) );
        touch.id = touchDeviceId;
        touch.x_min = 0.0f;
        touch.x_max = (float)Android_ScreenWidth;
        touch.native_xres = touch.x_max - touch.x_min;
        touch.y_min = 0.0f;
        touch.y_max = (float)Android_ScreenHeight;
        touch.native_yres = touch.y_max - touch.y_min;
        touch.pressure_min = 0.0f;
        touch.pressure_max = 1.0f;
        touch.native_pressureres = touch.pressure_max - touch.pressure_min;
        if (SDL_AddTouch(&touch, "") < 0) {
             SDL_Log("error: can't add touch %s, %d", __FILE__, __LINE__);
        }
    }

    
    fingerId = (SDL_FingerID)pointer_finger_id_in;
    switch (action) {
        case ACTION_DOWN:
        case ACTION_POINTER_1_DOWN:
			SDL_SendMouseMotion(Android_Window, 0, x, y);
			SDL_SendMouseButton(Android_Window, SDL_PRESSED, SDL_BUTTON_LEFT);
			SDL_SendFingerDown(touchDeviceId, fingerId, SDL_TRUE, x, y, p);
            break;
        case ACTION_MOVE:
			SDL_SendMouseMotion(Android_Window, 0, x, y);
            SDL_SendTouchMotion(touchDeviceId, fingerId, SDL_FALSE, x, y, p);
            break;
        case ACTION_UP:
        case ACTION_POINTER_1_UP:
			SDL_SendMouseButton(Android_Window, SDL_RELEASED, SDL_BUTTON_LEFT);
            SDL_SendFingerDown(touchDeviceId, fingerId, SDL_FALSE, x, y, p);
            break;
        default:
            break;
    } 
}
extern void SDL_ANDROID_MainThreadPushMultitouchButton(int id, int pressed, int x, int y, int force)
{
#if SDL_VERSION_ATLEAST(1,3,0)
	SDL_SendFingerDown(0, id, pressed ? 1 : 0, (float)x / (float)window->w, (float)y / (float)window->h, force);
#endif
}
void
X11_PumpEvents(_THIS)
{
    SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;

    /* Update activity every 30 seconds to prevent screensaver */
    if (_this->suspend_screensaver) {
        Uint32 now = SDL_GetTicks();
        if (!data->screensaver_activity ||
            (int) (now - data->screensaver_activity) >= 30000) {
            XResetScreenSaver(data->display);
            data->screensaver_activity = now;
        }
    }

    /* Keep processing pending events */
    while (X11_Pending(data->display)) {
        X11_DispatchEvent(_this);
    }

#ifdef SDL_INPUT_LINUXEV
    /* Process Touch events - TODO When X gets touch support, use that instead*/
    int i = 0,rd;
    char name[256];
    struct input_event ev[64];
    int size = sizeof (struct input_event);

    for(i = 0;i < SDL_GetNumTouch();++i) {
	SDL_Touch* touch = SDL_GetTouchIndex(i);
	if(!touch) printf("Touch %i/%i DNE\n",i,SDL_GetNumTouch());
	EventTouchData* data;
	data = (EventTouchData*)(touch->driverdata);
	if(data == NULL) {
	  printf("No driver data\n");
	  continue;
	}
	if(data->eventStream <= 0) 
	    printf("Error: Couldn't open stream\n");
	rd = read(data->eventStream, ev, size * 64);
	//printf("Got %i/%i bytes\n",rd,size);
	if(rd >= size) {
	    for (i = 0; i < rd / sizeof(struct input_event); i++) {
		switch (ev[i].type) {
		case EV_ABS:
		    //printf("Got position x: %i!\n",data->x);
		    switch (ev[i].code) {
			case ABS_X:
			    data->x = ev[i].value;
			    break;
			case ABS_Y:
			    data->y = ev[i].value;
			    break;
			case ABS_PRESSURE:
			    data->pressure = ev[i].value;
			    if(data->pressure < 0) data->pressure = 0;
			    break;
			case ABS_MISC:
			    if(ev[i].value == 0)
			        data->up = SDL_TRUE;			    
			    break;
			}
		    break;
		case EV_MSC:
		    if(ev[i].code == MSC_SERIAL)
			data->finger = ev[i].value;
		    break;
		case EV_SYN:
		  //printf("Id: %i\n",touch->id); 
		  if(data->up) {
		      SDL_SendFingerDown(touch->id,data->finger,
			  	       SDL_FALSE,data->x,data->y,
				       data->pressure);		    
		  }
		  else if(data->x >= 0 || data->y >= 0)
		    SDL_SendTouchMotion(touch->id,data->finger, 
					SDL_FALSE,data->x,data->y,
					data->pressure);
		  
		    //printf("Synched: %i tx: %i, ty: %i\n",
		    //	   data->finger,data->x,data->y);
		  data->x = -1;
		  data->y = -1;
		  data->pressure = -1;
		  data->finger = 0;
		  data->up = SDL_FALSE;
		    
		  break;		
		}
	    }
	}
    }
#endif
}
Example #4
0
void
X11_PumpEvents(_THIS)
{
    SDL_VideoData *data = (SDL_VideoData *) _this->driverdata;

    /* Update activity every 30 seconds to prevent screensaver */
    if (_this->suspend_screensaver) {
        Uint32 now = SDL_GetTicks();
        if (!data->screensaver_activity ||
            (int) (now - data->screensaver_activity) >= 30000) {
            XResetScreenSaver(data->display);

            #if SDL_USE_LIBDBUS
            SDL_dbus_screensaver_tickle(_this);
            #endif

            data->screensaver_activity = now;
        }
    }   

    /* Keep processing pending events */
    while (X11_Pending(data->display)) {
        X11_DispatchEvent(_this);
    }

    /* FIXME: Only need to do this when there are pending focus changes */
    X11_HandleFocusChanges(_this);

    /*Dont process evtouch events if XInput2 multitouch is supported*/
    if(X11_Xinput2IsMultitouchSupported()) {
        return;
    }

#ifdef SDL_INPUT_LINUXEV
    /* Process Touch events*/
    int i = 0,rd;
    struct input_event ev[64];
    int size = sizeof (struct input_event);

/* !!! FIXME: clean the tabstops out of here. */
    for(i = 0;i < SDL_GetNumTouch();++i) {
	SDL_Touch* touch = SDL_GetTouchIndex(i);
	if(!touch) printf("Touch %i/%i DNE\n",i,SDL_GetNumTouch());
	EventTouchData* data;
	data = (EventTouchData*)(touch->driverdata);
	if(data == NULL) {
	  printf("No driver data\n");
	  continue;
	}
	if(data->eventStream <= 0) 
	    printf("Error: Couldn't open stream\n");
	rd = read(data->eventStream, ev, size * 64);
	if(rd >= size) {
	    for (i = 0; i < rd / sizeof(struct input_event); i++) {
		switch (ev[i].type) {
		case EV_ABS:
		    switch (ev[i].code) {
			case ABS_X:
			    data->x = ev[i].value;
			    break;
			case ABS_Y:
			    data->y = ev[i].value;
			    break;
			case ABS_PRESSURE:
			    data->pressure = ev[i].value;
			    if(data->pressure < 0) data->pressure = 0;
			    break;
			case ABS_MISC:
			    if(ev[i].value == 0)
			        data->up = SDL_TRUE;			    
			    break;
			}
		    break;
		case EV_MSC:
			if(ev[i].code == MSC_SERIAL)
				data->finger = ev[i].value;
			break;
		case EV_KEY:
			if(ev[i].code == BTN_TOUCH)
			    if(ev[i].value == 0)
			        data->up = SDL_TRUE;
			break;
		case EV_SYN:
		  if(!data->down) {
		      data->down = SDL_TRUE;
		      SDL_SendFingerDown(touch->id,data->finger,
		    		  data->down, data->x, data->y,
		    		  data->pressure);
		  }
		  else if(!data->up)
		    SDL_SendTouchMotion(touch->id,data->finger, 
					SDL_FALSE, data->x,data->y,
					data->pressure);
		  else
		  {
		      data->down = SDL_FALSE;
			  SDL_SendFingerDown(touch->id,data->finger,
					  data->down, data->x,data->y,
					  data->pressure);
			  data->x = -1;
			  data->y = -1;
			  data->pressure = -1;
			  data->finger = 0;
			  data->up = SDL_FALSE;
		  }
		  break;		
		}
	    }
	}
    }
#endif
}
Example #5
0
int
SDL_SendTouchMotion(SDL_TouchID id, SDL_FingerID fingerid, int relative, 
                    float xin, float yin, float pressurein)
{
    SDL_Touch *touch;
    SDL_Finger *finger;
    int posted;
    Sint16 xrel, yrel;
    Uint16 x;
    Uint16 y;
    Uint16 pressure;
    
    touch = SDL_GetTouch(id);
    if (!touch) {
      return SDL_TouchNotFoundError(id);
    }

    //scale to Integer coordinates
    x = (Uint16)((xin+touch->x_min)*(touch->xres)/(touch->native_xres));
    y = (Uint16)((yin+touch->y_min)*(touch->yres)/(touch->native_yres));
    pressure = (Uint16)((pressurein+touch->pressure_min)*(touch->pressureres)/(touch->native_pressureres));
    if(touch->flush_motion) {
        return 0;
    }
    
    finger = SDL_GetFinger(touch,fingerid);
    if(finger == NULL || !finger->down) {
        return SDL_SendFingerDown(id,fingerid,SDL_TRUE,xin,yin,pressurein);        
    } else {
        /* the relative motion is calculated regarding the last position */
        if (relative) {
            xrel = x;
            yrel = y;
            x = (finger->last_x + x);
            y = (finger->last_y + y);
        } else {
            if(xin < touch->x_min) x = finger->last_x; /*If movement is only in one axis,*/
            if(yin < touch->y_min) y = finger->last_y; /*The other is marked as -1*/
            if(pressurein < touch->pressure_min) pressure = finger->last_pressure;
            xrel = x - finger->last_x;
            yrel = y - finger->last_y;
            //printf("xrel,yrel (%i,%i)\n",(int)xrel,(int)yrel);
        }
        
        /* Drop events that don't change state */
        if (!xrel && !yrel) {
#if 0
            printf("Touch event didn't change state - dropped!\n");
#endif
            return 0;
        }
        
        /* Update internal touch coordinates */
        
        finger->x = x;
        finger->y = y;
        
        /*Should scale to window? Normalize? Maintain Aspect?*/
        //SDL_GetWindowSize(touch->focus, &x_max, &y_max);
        
        /* make sure that the pointers find themselves inside the windows */
        /* only check if touch->xmax is set ! */
        /*
          if (x_max && touch->x > x_max) {
          touch->x = x_max;
          } else if (touch->x < 0) {
          touch->x = 0;
          }
          
          if (y_max && touch->y > y_max) {
          touch->y = y_max;
          } else if (touch->y < 0) {
          touch->y = 0;
          }
        */
        finger->xdelta = xrel;
        finger->ydelta = yrel;
        finger->pressure = pressure;
        
        
        
        /* Post the event, if desired */
        posted = 0;
        if (SDL_GetEventState(SDL_FINGERMOTION) == SDL_ENABLE) {
            SDL_Event event;
            event.tfinger.type = SDL_FINGERMOTION;
            event.tfinger.touchId = id;
            event.tfinger.fingerId = fingerid;
            event.tfinger.x = x;
            event.tfinger.y = y;
            event.tfinger.dx = xrel;
            event.tfinger.dy = yrel;            
                
            event.tfinger.pressure = pressure;
            event.tfinger.state = touch->buttonstate;
            event.tfinger.windowID = touch->focus ? touch->focus->id : 0;
            posted = (SDL_PushEvent(&event) > 0);
        }
        finger->last_x = finger->x;
        finger->last_y = finger->y;
        finger->last_pressure = finger->pressure;
        return posted;
    }
}
/* We need our own event queue, because Free Heroes 2 game uses
 * SDL_SetEventFilter(), and it calls SDL_Flip() from inside
 * it's custom filter function, and SDL_Flip() does not work
 * when it's not called from the main() thread.
 * So we, like, push the events into our own queue,
 * read each event from that queue inside SDL_ANDROID_PumpEvents(),
 * unlock the mutex, and push the event to SDL queue,
 * which is then immediately read by SDL from the same thread,
 * and then SDL invokes event filter function from FHeroes2.
 * FHeroes2 call SDL_Flip() from inside that event filter function,
 * and it works, because it is called from the main() thread.
 */
extern void SDL_ANDROID_PumpEvents()
{
	static int oldMouseButtons = 0;
	SDL_Event ev;
	SDL_ANDROID_processAndroidTrackballDampening();
	SDL_ANDROID_processMoveMouseWithKeyboard();
#if SDL_VERSION_ATLEAST(1,3,0)
	SDL_Window * window = SDL_GetFocusWindow();
	if( !window )
		return;
#endif

	if( !BufferedEventsMutex )
		BufferedEventsMutex = SDL_CreateMutex();

	SDL_mutexP(BufferedEventsMutex);
	while( BufferedEventsStart != BufferedEventsEnd )
	{
		ev = BufferedEvents[BufferedEventsStart];
		BufferedEvents[BufferedEventsStart].type = 0;
		BufferedEventsStart++;
		if( BufferedEventsStart >= MAX_BUFFERED_EVENTS )
			BufferedEventsStart = 0;
		SDL_mutexV(BufferedEventsMutex);
		
		switch( ev.type )
		{
			case SDL_MOUSEMOTION:
				SDL_SendMouseMotion( ANDROID_CurrentWindow, 0, ev.motion.x, ev.motion.y );
				break;
			case SDL_MOUSEBUTTONDOWN:
				if( ((oldMouseButtons & SDL_BUTTON(ev.button.button)) != 0) != ev.button.state )
				{
					oldMouseButtons = (oldMouseButtons & ~SDL_BUTTON(ev.button.button)) | (ev.button.state ? SDL_BUTTON(ev.button.button) : 0);
					SDL_SendMouseButton( ANDROID_CurrentWindow, ev.button.state, ev.button.button );
				}
				break;
			case SDL_KEYDOWN:
				//__android_log_print(ANDROID_LOG_INFO, "libSDL", "SDL_KEYDOWN: %i %i", ev->key.keysym.sym, ev->key.state);
				SDL_SendKeyboardKey( ev.key.state, &ev.key.keysym );
				break;
			case SDL_JOYAXISMOTION:
				if( ev.jaxis.which < MAX_MULTITOUCH_POINTERS+1 && SDL_ANDROID_CurrentJoysticks[ev.jaxis.which] )
					SDL_PrivateJoystickAxis( SDL_ANDROID_CurrentJoysticks[ev.jaxis.which], ev.jaxis.axis, ev.jaxis.value );
				break;
			case SDL_JOYBUTTONDOWN:
				if( ev.jbutton.which < MAX_MULTITOUCH_POINTERS+1 && SDL_ANDROID_CurrentJoysticks[ev.jbutton.which] )
					SDL_PrivateJoystickButton( SDL_ANDROID_CurrentJoysticks[ev.jbutton.which], ev.jbutton.button, ev.jbutton.state );
				break;
			case SDL_JOYBALLMOTION:
				if( ev.jball.which < MAX_MULTITOUCH_POINTERS+1 && SDL_ANDROID_CurrentJoysticks[ev.jbutton.which] )
					SDL_PrivateJoystickBall( SDL_ANDROID_CurrentJoysticks[ev.jball.which], ev.jball.ball, ev.jball.xrel, ev.jball.yrel );
				break;
#if SDL_VERSION_ATLEAST(1,3,0)
				//if( ANDROID_CurrentWindow )
				//	SDL_SendWindowEvent(ANDROID_CurrentWindow, SDL_WINDOWEVENT_MINIMIZED, 0, 0);
#else
			case SDL_ACTIVEEVENT:
				SDL_PrivateAppActive(ev.active.gain, ev.active.state);
				break;
#endif
#if SDL_VERSION_ATLEAST(1,3,0)
			case SDL_FINGERMOTION:
				SDL_SendTouchMotion(0, ev.tfinger.fingerId, 0, (float)ev.tfinger.x / (float)window->w, (float)ev.tfinger.y / (float)window->h, ev.tfinger.pressure);
				break;
			case SDL_FINGERDOWN:
				SDL_SendFingerDown(0, ev.tfinger.fingerId, ev.tfinger.state ? 1 : 0, (float)ev.tfinger.x / (float)window->w, (float)ev.tfinger.y / (float)window->h, ev.tfinger.pressure);
				break;
			case SDL_TEXTINPUT:
				SDL_SendKeyboardText(ev.text.text);
				break;
			case SDL_MOUSEWHEEL:
				SDL_SendMouseWheel( ANDROID_CurrentWindow, ev.wheel.x, ev.wheel.y );
				break;
#endif
		}

		SDL_mutexP(BufferedEventsMutex);
	}
	SDL_mutexV(BufferedEventsMutex);
};