aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2014-04-14 14:09:54 -0700
committerAlon Zakai <alonzakai@gmail.com>2014-04-14 14:09:54 -0700
commitd990bbdd04fab88828ea95d09ce68c92ae2543bc (patch)
tree105a42288641c9db37d1d7238c84443152f45ed4
parent512b7bd6689699a16a5afb6d38c786d17ec45c91 (diff)
parent2faa69a865c3d6046d7d5202f2dc747dea3229f1 (diff)
Merge pull request #2285 from juj/sdl2-touch-api-additions
Sdl2 touch api additions
-rw-r--r--src/library_browser.js46
-rw-r--r--src/library_sdl.js222
-rw-r--r--src/struct_info.json23
-rw-r--r--system/include/SDL/COPYING5
-rw-r--r--system/include/SDL/SDL_events.h70
-rw-r--r--system/include/SDL/SDL_touch.h92
-rw-r--r--tests/sdl_touch.c78
-rw-r--r--tests/test_browser.py5
-rw-r--r--tests/test_interactive.py3
9 files changed, 386 insertions, 158 deletions
diff --git a/src/library_browser.js b/src/library_browser.js
index 0808b9f0..4be7315e 100644
--- a/src/library_browser.js
+++ b/src/library_browser.js
@@ -482,6 +482,8 @@ mergeInto(LibraryManager.library, {
mouseY: 0,
mouseMovementX: 0,
mouseMovementY: 0,
+ touches: {},
+ lastTouches: {},
calculateMouseEvent: function(event) { // event should be mousemove, mousedown or mouseup
if (Browser.pointerLock) {
@@ -510,8 +512,9 @@ mergeInto(LibraryManager.library, {
// Otherwise, calculate the movement based on the changes
// in the coordinates.
var rect = Module["canvas"].getBoundingClientRect();
- var x, y;
-
+ var cw = Module["canvas"].width;
+ var ch = Module["canvas"].height;
+
// Neither .scrollX or .pageXOffset are defined in a spec, but
// we prefer .scrollX because it is currently in a spec draft.
// (see: http://www.w3.org/TR/2013/WD-cssom-view-20131217/)
@@ -522,26 +525,37 @@ mergeInto(LibraryManager.library, {
// and we have no viable fallback.
assert((typeof scrollX !== 'undefined') && (typeof scrollY !== 'undefined'), 'Unable to retrieve scroll position, mouse positions likely broken.');
#endif
- if (event.type == 'touchstart' ||
- event.type == 'touchend' ||
- event.type == 'touchmove') {
- var t = event.touches.item(0);
- if (t) {
- x = t.pageX - (scrollX + rect.left);
- y = t.pageY - (scrollY + rect.top);
- } else {
- return;
+
+ if (event.type === 'touchstart' || event.type === 'touchend' || event.type === 'touchmove') {
+ var touch = event.touch;
+ if (touch === undefined) {
+ return; // the "touch" property is only defined in SDL
+
}
- } else {
- x = event.pageX - (scrollX + rect.left);
- y = event.pageY - (scrollY + rect.top);
+ var adjustedX = touch.pageX - (scrollX + rect.left);
+ var adjustedY = touch.pageY - (scrollY + rect.top);
+
+ adjustedX = adjustedX * (cw / rect.width);
+ adjustedY = adjustedY * (ch / rect.height);
+
+ var coords = { x: adjustedX, y: adjustedY };
+
+ if (event.type === 'touchstart') {
+ Browser.lastTouches[touch.identifier] = coords;
+ Browser.touches[touch.identifier] = coords;
+ } else if (event.type === 'touchend' || event.type === 'touchmove') {
+ Browser.lastTouches[touch.identifier] = Browser.touches[touch.identifier];
+ Browser.touches[touch.identifier] = { x: adjustedX, y: adjustedY };
+ }
+ return;
}
+ var x = event.pageX - (scrollX + rect.left);
+ var y = event.pageY - (scrollY + rect.top);
+
// the canvas might be CSS-scaled compared to its backbuffer;
// SDL-using content will want mouse coordinates in terms
// of backbuffer units.
- var cw = Module["canvas"].width;
- var ch = Module["canvas"].height;
x = x * (cw / rect.width);
y = y * (ch / rect.height);
diff --git a/src/library_sdl.js b/src/library_sdl.js
index d90484ad..eedb8c48 100644
--- a/src/library_sdl.js
+++ b/src/library_sdl.js
@@ -10,7 +10,7 @@
// or otherwise).
var LibrarySDL = {
- $SDL__deps: ['$FS', '$PATH', '$Browser'],
+ $SDL__deps: ['$FS', '$PATH', '$Browser', 'SDL_GetTicks'],
$SDL: {
defaults: {
width: 320,
@@ -82,6 +82,8 @@ var LibrarySDL = {
DOMEventToSDLEvent: {},
+ TOUCH_DEFAULT_ID: 0, // Our default deviceID for touch events (we get nothing from the browser)
+
keyCodes: { // DOM code ==> SDL code. See https://developer.mozilla.org/en/Document_Object_Model_%28DOM%29/KeyboardEvent and SDL_keycode.h
// For keys that don't have unicode value, we map DOM codes with the corresponding scan codes + 1024 (using "| 1 << 10")
16: 225 | 1<<10, // shift
@@ -417,50 +419,104 @@ var LibrarySDL = {
}
},
- touchX: 0, touchY: 0,
+ // the browser sends out touchstart events with the whole group of touches
+ // even if we received a previous touchstart for a specific touch identifier.
+ // You can test this by pressing one finger to the screen, then another. You'll
+ // receive two touchstart events, the first with a touches count of 1 the second
+ // with a touches count of two.
+ // SDL sends out a new touchstart event for only each newly started touch so to
+ // emulate this, we keep track of previously started touches.
+ downFingers: {},
savedKeydown: null,
receiveEvent: function(event) {
switch(event.type) {
- case 'touchstart':
+ case 'touchstart': case 'touchmove': {
event.preventDefault();
- var touch = event.touches[0];
- touchX = touch.pageX;
- touchY = touch.pageY;
- var event = {
- type: 'mousedown',
+
+ var touches = [];
+
+ // Clear out any touchstart events that we've already processed
+ if (event.type === 'touchstart') {
+ for (var i = 0; i < event.touches.length; i++) {
+ var touch = event.touches[i];
+ if (SDL.downFingers[touch.identifier] != true) {
+ SDL.downFingers[touch.identifier] = true;
+ touches.push(touch);
+ }
+ }
+ } else {
+ touches = event.touches;
+ }
+
+ var firstTouch = touches[0];
+ if (event.type == 'touchstart') {
+ SDL.DOMButtons[0] = 1;
+ }
+ var mouseEventType;
+ switch(event.type) {
+ case 'touchstart': mouseEventType = 'mousedown'; break;
+ case 'touchmove': mouseEventType = 'mousemove'; break;
+ }
+ var mouseEvent = {
+ type: mouseEventType,
button: 0,
- pageX: touchX,
- pageY: touchY
+ pageX: firstTouch.clientX,
+ pageY: firstTouch.clientY
};
- SDL.DOMButtons[0] = 1;
- SDL.events.push(event);
- break;
- case 'touchmove':
- event.preventDefault();
- var touch = event.touches[0];
- touchX = touch.pageX;
- touchY = touch.pageY;
- event = {
- type: 'mousemove',
- button: 0,
- pageX: touchX,
- pageY: touchY
+ SDL.events.push(mouseEvent);
+
+ for (var i = 0; i < touches.length; i++) {
+ var touch = touches[i];
+ SDL.events.push({
+ type: event.type,
+ touch: touch
+ });
};
- SDL.events.push(event);
break;
- case 'touchend':
+ }
+ case 'touchend': {
event.preventDefault();
- event = {
+
+ // Remove the entry in the SDL.downFingers hash
+ // because the finger is no longer down.
+ for(var i = 0; i < event.changedTouches.length; i++) {
+ var touch = event.changedTouches[i];
+ if (SDL.downFingers[touch.identifier] === true) {
+ delete SDL.downFingers[touch.identifier];
+ }
+ }
+
+ var mouseEvent = {
type: 'mouseup',
button: 0,
- pageX: touchX,
- pageY: touchY
+ pageX: event.changedTouches[0].clientX,
+ pageY: event.changedTouches[0].clientY
};
SDL.DOMButtons[0] = 0;
- SDL.events.push(event);
+ SDL.events.push(mouseEvent);
+
+ for (var i = 0; i < event.changedTouches.length; i++) {
+ var touch = event.changedTouches[i];
+ SDL.events.push({
+ type: 'touchend',
+ touch: touch
+ });
+ };
break;
+ }
case 'mousemove':
+ if (SDL.DOMButtons[0] === 1) {
+ SDL.events.push({
+ type: 'touchmove',
+ touch: {
+ identifier: 0,
+ deviceID: {{{ cDefine('SDL_TOUCH_MOUSEID') }}},
+ pageX: event.pageX,
+ pageY: event.pageY
+ }
+ });
+ }
if (Browser.pointerLock) {
// workaround for firefox bug 750111
if ('mozMovementX' in event) {
@@ -502,6 +558,15 @@ var LibrarySDL = {
};
} else if (event.type == 'mousedown') {
SDL.DOMButtons[event.button] = 1;
+ SDL.events.push({
+ type: 'touchstart',
+ touch: {
+ identifier: 0,
+ deviceID: {{{ cDefine('SDL_TOUCH_MOUSEID') }}},
+ pageX: event.pageX,
+ pageY: event.pageY
+ }
+ });
} else if (event.type == 'mouseup') {
// ignore extra ups, can happen if we leave the canvas while pressing down, then return,
// since we add a mouseup in that case
@@ -509,6 +574,15 @@ var LibrarySDL = {
return;
}
+ SDL.events.push({
+ type: 'touchend',
+ touch: {
+ identifier: 0,
+ deviceID: {{{ cDefine('SDL_TOUCH_MOUSEID') }}},
+ pageX: event.pageX,
+ pageY: event.pageY
+ }
+ });
SDL.DOMButtons[event.button] = 0;
}
@@ -600,6 +674,10 @@ var LibrarySDL = {
event.handled = true;
switch (event.type) {
+ case 'touchstart': case 'touchend': case 'touchmove': {
+ Browser.calculateMouseEvent(event);
+ break;
+ }
case 'keydown': case 'keyup': {
var down = event.type === 'keydown';
var code = event.keyCode;
@@ -690,13 +768,19 @@ var LibrarySDL = {
if (event.type != 'mousemove') {
var down = event.type === 'mousedown';
{{{ makeSetValue('ptr', C_STRUCTS.SDL_MouseButtonEvent.type, 'SDL.DOMEventToSDLEvent[event.type]', 'i32') }}};
+ {{{ makeSetValue('ptr', C_STRUCTS.SDL_MouseButtonEvent.timestamp, '0', 'i32') }}};
+ {{{ makeSetValue('ptr', C_STRUCTS.SDL_MouseButtonEvent.windowID, '0', 'i32') }}};
+ {{{ makeSetValue('ptr', C_STRUCTS.SDL_MouseButtonEvent.which, '0', 'i32') }}};
{{{ makeSetValue('ptr', C_STRUCTS.SDL_MouseButtonEvent.button, 'event.button+1', 'i8') }}}; // DOM buttons are 0-2, SDL 1-3
{{{ makeSetValue('ptr', C_STRUCTS.SDL_MouseButtonEvent.state, 'down ? 1 : 0', 'i8') }}};
{{{ makeSetValue('ptr', C_STRUCTS.SDL_MouseButtonEvent.x, 'Browser.mouseX', 'i32') }}};
{{{ makeSetValue('ptr', C_STRUCTS.SDL_MouseButtonEvent.y, 'Browser.mouseY', 'i32') }}};
} else {
{{{ makeSetValue('ptr', C_STRUCTS.SDL_MouseMotionEvent.type, 'SDL.DOMEventToSDLEvent[event.type]', 'i32') }}};
- {{{ makeSetValue('ptr', C_STRUCTS.SDL_MouseMotionEvent.state, 'SDL.buttonState', 'i8') }}};
+ {{{ makeSetValue('ptr', C_STRUCTS.SDL_MouseMotionEvent.timestamp, '0', 'i32') }}};
+ {{{ makeSetValue('ptr', C_STRUCTS.SDL_MouseMotionEvent.windowID, '0', 'i32') }}};
+ {{{ makeSetValue('ptr', C_STRUCTS.SDL_MouseMotionEvent.which, '0', 'i32') }}};
+ {{{ makeSetValue('ptr', C_STRUCTS.SDL_MouseMotionEvent.state, 'SDL.buttonState', 'i32') }}};
{{{ makeSetValue('ptr', C_STRUCTS.SDL_MouseMotionEvent.x, 'Browser.mouseX', 'i32') }}};
{{{ makeSetValue('ptr', C_STRUCTS.SDL_MouseMotionEvent.y, 'Browser.mouseY', 'i32') }}};
{{{ makeSetValue('ptr', C_STRUCTS.SDL_MouseMotionEvent.xrel, 'Browser.mouseMovementX', 'i32') }}};
@@ -704,6 +788,33 @@ var LibrarySDL = {
}
break;
}
+ case 'touchstart': case 'touchend': case 'touchmove': {
+ var touch = event.touch;
+ var w = Module['canvas'].width;
+ var h = Module['canvas'].height;
+ var x = Browser.touches[touch.identifier].x / w;
+ var y = Browser.touches[touch.identifier].y / h;
+ var lx = Browser.lastTouches[touch.identifier].x / w;
+ var ly = Browser.lastTouches[touch.identifier].y / h;
+ var dx = x - lx;
+ var dy = y - ly;
+ if (touch['deviceID'] === undefined) touch.deviceID = SDL.TOUCH_DEFAULT_ID;
+ if (dx === 0 && dy === 0 && event.type === 'touchmove') return; // don't send these if nothing happened
+ {{{ makeSetValue('ptr', C_STRUCTS.SDL_TouchFingerEvent.type, 'SDL.DOMEventToSDLEvent[event.type]', 'i32') }}};
+ {{{ makeSetValue('ptr', C_STRUCTS.SDL_TouchFingerEvent.timestamp, '_SDL_GetTicks()', 'i32') }}};
+ {{{ makeSetValue('ptr', C_STRUCTS.SDL_TouchFingerEvent.touchId, 'touch.deviceID', 'i64') }}};
+ {{{ makeSetValue('ptr', C_STRUCTS.SDL_TouchFingerEvent.fingerId, 'touch.identifier', 'i64') }}};
+ {{{ makeSetValue('ptr', C_STRUCTS.SDL_TouchFingerEvent.x, 'x', 'float') }}};
+ {{{ makeSetValue('ptr', C_STRUCTS.SDL_TouchFingerEvent.y, 'y', 'float') }}};
+ {{{ makeSetValue('ptr', C_STRUCTS.SDL_TouchFingerEvent.dx, 'dx', 'float') }}};
+ {{{ makeSetValue('ptr', C_STRUCTS.SDL_TouchFingerEvent.dy, 'dy', 'float') }}};
+ if (touch.force !== undefined) {
+ {{{ makeSetValue('ptr', C_STRUCTS.SDL_TouchFingerEvent.pressure, 'touch.force', 'float') }}};
+ } else { // No pressure data, send a digital 0/1 pressure.
+ {{{ makeSetValue('ptr', C_STRUCTS.SDL_TouchFingerEvent.pressure, 'event.type == "touchend" ? 0 : 1', 'float') }}};
+ }
+ break;
+ }
case 'unload': {
{{{ makeSetValue('ptr', C_STRUCTS.SDL_KeyboardEvent.type, 'SDL.DOMEventToSDLEvent[event.type]', 'i32') }}};
break;
@@ -948,14 +1059,17 @@ var LibrarySDL = {
SDL.keyboardState = _malloc(0x10000); // Our SDL needs 512, but 64K is safe for older SDLs
_memset(SDL.keyboardState, 0, 0x10000);
// Initialize this structure carefully for closure
- SDL.DOMEventToSDLEvent['keydown'] = 0x300 /* SDL_KEYDOWN */;
- SDL.DOMEventToSDLEvent['keyup'] = 0x301 /* SDL_KEYUP */;
- SDL.DOMEventToSDLEvent['keypress'] = 0x303 /* SDL_TEXTINPUT */;
- SDL.DOMEventToSDLEvent['mousedown'] = 0x401 /* SDL_MOUSEBUTTONDOWN */;
- SDL.DOMEventToSDLEvent['mouseup'] = 0x402 /* SDL_MOUSEBUTTONUP */;
- SDL.DOMEventToSDLEvent['mousemove'] = 0x400 /* SDL_MOUSEMOTION */;
- SDL.DOMEventToSDLEvent['unload'] = 0x100 /* SDL_QUIT */;
- SDL.DOMEventToSDLEvent['resize'] = 0x7001 /* SDL_VIDEORESIZE/SDL_EVENT_COMPAT2 */;
+ SDL.DOMEventToSDLEvent['keydown'] = 0x300 /* SDL_KEYDOWN */;
+ SDL.DOMEventToSDLEvent['keyup'] = 0x301 /* SDL_KEYUP */;
+ SDL.DOMEventToSDLEvent['keypress'] = 0x303 /* SDL_TEXTINPUT */;
+ SDL.DOMEventToSDLEvent['mousedown'] = 0x401 /* SDL_MOUSEBUTTONDOWN */;
+ SDL.DOMEventToSDLEvent['mouseup'] = 0x402 /* SDL_MOUSEBUTTONUP */;
+ SDL.DOMEventToSDLEvent['mousemove'] = 0x400 /* SDL_MOUSEMOTION */;
+ SDL.DOMEventToSDLEvent['touchstart'] = 0x700 /* SDL_FINGERDOWN */;
+ SDL.DOMEventToSDLEvent['touchend'] = 0x701 /* SDL_FINGERUP */;
+ SDL.DOMEventToSDLEvent['touchmove'] = 0x702 /* SDL_FINGERMOTION */;
+ SDL.DOMEventToSDLEvent['unload'] = 0x100 /* SDL_QUIT */;
+ SDL.DOMEventToSDLEvent['resize'] = 0x7001 /* SDL_VIDEORESIZE/SDL_EVENT_COMPAT2 */;
// These are not technically DOM events; the HTML gamepad API is poll-based.
// However, we define them here, as the rest of the SDL code assumes that
// all SDL events originate as DOM events.
@@ -1025,7 +1139,7 @@ var LibrarySDL = {
},
SDL_SetVideoMode: function(width, height, depth, flags) {
- ['mousedown', 'mouseup', 'mousemove', 'DOMMouseScroll', 'mousewheel', 'mouseout'].forEach(function(event) {
+ ['touchstart', 'touchend', 'touchmove', 'mousedown', 'mouseup', 'mousemove', 'DOMMouseScroll', 'mousewheel', 'mouseout'].forEach(function(event) {
Module['canvas'].addEventListener(event, SDL.receiveEvent, true);
});
@@ -1476,20 +1590,28 @@ var LibrarySDL = {
return 0;
},
- SDL_PeepEvents: function(events, numEvents, action, from, to) {
+ SDL_PeepEvents: function(events, requestedEventCount, action, from, to) {
switch(action) {
case 2: { // SDL_GETEVENT
- assert(numEvents == 1);
- var got = 0;
- while (SDL.events.length > 0 && numEvents > 0) {
- var type = SDL.DOMEventToSDLEvent[SDL.events[0].type];
- if (type < from || type > to) break;
- SDL.makeCEvent(SDL.events.shift(), events);
- got++;
- numEvents--;
- // events += sizeof(..)
+ // We only handle 1 event right now
+ assert(requestedEventCount == 1);
+
+ var index = 0;
+ var retrievedEventCount = 0;
+ // this should look through the entire queue until it has filled up the events
+ // array
+ while (index < SDL.events.length && retrievedEventCount < requestedEventCount) {
+ var event = SDL.events[index];
+ var type = SDL.DOMEventToSDLEvent[event.type];
+ if (from <= type && type <= to) {
+ SDL.makeCEvent(event, events);
+ SDL.events.splice(index, 1);
+ retrievedEventCount++;
+ } else {
+ index++;
+ }
}
- return got;
+ return retrievedEventCount;
}
default: throw 'SDL_PeepEvents does not yet support that action: ' + action;
}
diff --git a/src/struct_info.json b/src/struct_info.json
index 2a2b4c64..f762bf2b 100644
--- a/src/struct_info.json
+++ b/src/struct_info.json
@@ -948,11 +948,10 @@
],
"SDL_MouseMotionEvent": [
"type",
+ "timestamp",
"windowID",
+ "which",
"state",
- "padding1",
- "padding2",
- "padding3",
"x",
"y",
"xrel",
@@ -960,7 +959,9 @@
],
"SDL_MouseButtonEvent": [
"type",
+ "timestamp",
"windowID",
+ "which",
"button",
"state",
"padding1",
@@ -983,6 +984,17 @@
"state",
"padding1"
],
+ "SDL_TouchFingerEvent": [
+ "type",
+ "timestamp",
+ "touchId",
+ "fingerId",
+ "x",
+ "y",
+ "dx",
+ "dy",
+ "pressure"
+ ],
"SDL_ResizeEvent": [
"type",
"w",
@@ -991,6 +1003,11 @@
}
},
{
+ "file": "SDL/SDL_touch.h",
+ "defines": ["SDL_TOUCH_MOUSEID"],
+ "structs": {}
+ },
+ {
"file": "SDL/SDL_audio.h",
"defines": [
"SDL_AUDIO_MASK_BITSIZE",
diff --git a/system/include/SDL/COPYING b/system/include/SDL/COPYING
index 15639581..71cc7e42 100644
--- a/system/include/SDL/COPYING
+++ b/system/include/SDL/COPYING
@@ -17,3 +17,8 @@ freely, subject to the following restrictions:
2. Altered source versions must be plainly marked as such, and must not be
misrepresented as being the original software.
3. This notice may not be removed or altered from any source distribution.
+
+---
+
+ Portions of these headers taken from SDL2 (where noted)
+ Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
diff --git a/system/include/SDL/SDL_events.h b/system/include/SDL/SDL_events.h
index 8be00ceb..183ea4b2 100644
--- a/system/include/SDL/SDL_events.h
+++ b/system/include/SDL/SDL_events.h
@@ -2,6 +2,9 @@
Simple DirectMedia Layer
Copyright (C) 1997-2011 Sam Lantinga <slouken@libsdl.org>
+ Portions of these headers taken from SDL2 (where noted)
+ Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
+
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
arising from the use of this software.
@@ -182,33 +185,43 @@ typedef struct SDL_TextInputEvent
/**
* \brief Mouse motion event structure (event.motion.*)
*/
+/*================================= IMPORTANT ================================
+ The version of SDL_MouseMotionEvent that comes in these (emscripten)
+ headers is taken from the finalized version of SDL2
+ ============================================================================*/
+
typedef struct SDL_MouseMotionEvent
{
Uint32 type; /**< ::SDL_MOUSEMOTION */
+ Uint32 timestamp;
Uint32 windowID; /**< The window with mouse focus, if any */
- Uint8 state; /**< The current button state */
- Uint8 padding1;
- Uint8 padding2;
- Uint8 padding3;
- int x; /**< X coordinate, relative to window */
- int y; /**< Y coordinate, relative to window */
- int xrel; /**< The relative motion in the X direction */
- int yrel; /**< The relative motion in the Y direction */
+ Uint32 which; /**< The mouse instance id, or SDL_TOUCH_MOUSEID */
+ Uint32 state; /**< The current button state */
+ Sint32 x; /**< X coordinate, relative to window */
+ Sint32 y; /**< Y coordinate, relative to window */
+ Sint32 xrel; /**< The relative motion in the X direction */
+ Sint32 yrel; /**< The relative motion in the Y direction */
} SDL_MouseMotionEvent;
/**
* \brief Mouse button event structure (event.button.*)
*/
+/*================================= IMPORTANT ================================
+ The version of SDL_MouseButtonEvent that comes in these (emscripten)
+ headers is taken from the finalized version of SDL2
+ ============================================================================*/
typedef struct SDL_MouseButtonEvent
{
Uint32 type; /**< ::SDL_MOUSEBUTTONDOWN or ::SDL_MOUSEBUTTONUP */
+ Uint32 timestamp;
Uint32 windowID; /**< The window with mouse focus, if any */
+ Uint32 which; /**< The mouse instance id, or SDL_TOUCH_MOUSEID */
Uint8 button; /**< The mouse button index */
Uint8 state; /**< ::SDL_PRESSED or ::SDL_RELEASED */
Uint8 padding1;
Uint8 padding2;
- int x; /**< X coordinate, relative to window */
- int y; /**< Y coordinate, relative to window */
+ Sint32 x; /**< X coordinate, relative to window */
+ Sint32 y; /**< Y coordinate, relative to window */
} SDL_MouseButtonEvent;
/**
@@ -217,9 +230,11 @@ typedef struct SDL_MouseButtonEvent
typedef struct SDL_MouseWheelEvent
{
Uint32 type; /**< ::SDL_MOUSEWHEEL */
+ Uint32 timestamp;
Uint32 windowID; /**< The window with mouse focus, if any */
- int x; /**< The amount scrolled horizontally */
- int y; /**< The amount scrolled vertically */
+ Uint32 which; /**< The mouse instance id, or SDL_TOUCH_MOUSEID */
+ Sint32 x; /**< The amount scrolled horizontally */
+ Sint32 y; /**< The amount scrolled vertically */
} SDL_MouseWheelEvent;
/**
@@ -281,24 +296,25 @@ typedef struct SDL_JoyButtonEvent
/**
- * \brief Touch finger motion/finger event structure (event.tmotion.*)
+ * \brief Touch finger motion/finger event structure (event.tfinger.*)
*/
+
+/*================================= IMPORTANT ================================
+ The version of SDL_TouchFingerEvent that comes in these (emscripten)
+ headers is taken from the finalized version of SDL2
+ ============================================================================*/
+
typedef struct SDL_TouchFingerEvent
{
- Uint32 type; /**< ::SDL_FINGERMOTION OR
- SDL_FINGERDOWN OR SDL_FINGERUP*/
- Uint32 windowID; /**< The window with mouse focus, if any */
- SDL_TouchID touchId; /**< The touch device id */
+ Uint32 type; /**< ::SDL_FINGERMOTION or ::SDL_FINGERDOWN or ::SDL_FINGERUP */
+ Uint32 timestamp;
+ SDL_TouchID touchId; /**< The touch device id */
SDL_FingerID fingerId;
- Uint8 state; /**< The current button state */
- Uint8 padding1;
- Uint8 padding2;
- Uint8 padding3;
- Uint16 x;
- Uint16 y;
- Sint16 dx;
- Sint16 dy;
- Uint16 pressure;
+ float x; /**< Normalized in the range 0...1 */
+ float y; /**< Normalized in the range 0...1 */
+ float dx; /**< Normalized in the range 0...1 */
+ float dy; /**< Normalized in the range 0...1 */
+ float pressure; /**< Normalized in the range 0...1 */
} SDL_TouchFingerEvent;
@@ -434,7 +450,7 @@ typedef union SDL_Event
SDL_QuitEvent quit; /**< Quit request event data */
SDL_UserEvent user; /**< Custom event data */
SDL_SysWMEvent syswm; /**< System dependent window event data */
- SDL_TouchFingerEvent tfinger; /**< Touch finger event data */
+ SDL_TouchFingerEvent tfinger; /**< SDL2 Touch finger event data */
SDL_TouchButtonEvent tbutton; /**< Touch button event data */
SDL_MultiGestureEvent mgesture; /**< Multi Finger Gesture data */
SDL_DollarGestureEvent dgesture; /**< Multi Finger Gesture data */
diff --git a/system/include/SDL/SDL_touch.h b/system/include/SDL/SDL_touch.h
index 587efcbf..fe238f10 100644
--- a/system/include/SDL/SDL_touch.h
+++ b/system/include/SDL/SDL_touch.h
@@ -1,6 +1,6 @@
/*
Simple DirectMedia Layer
- Copyright (C) 1997-2011 Sam Lantinga <slouken@libsdl.org>
+ Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
This software is provided 'as-is', without any express or implied
warranty. In no event will the authors be held liable for any damages
@@ -19,9 +19,15 @@
3. This notice may not be removed or altered from any source distribution.
*/
+/*
+ ================================= IMPORTANT ================================
+ This header taken from SDL2
+ ============================================================================
+*/
+
/**
* \file SDL_touch.h
- *
+ *
* Include file for SDL touch event handling.
*/
@@ -35,90 +41,52 @@
#include "begin_code.h"
/* Set up for C function definitions, even when using C++ */
#ifdef __cplusplus
-/* *INDENT-OFF* */
extern "C" {
-/* *INDENT-ON* */
#endif
-
typedef Sint64 SDL_TouchID;
typedef Sint64 SDL_FingerID;
+typedef struct SDL_Finger
+{
+ SDL_FingerID id;
+ float x;
+ float y;
+ float pressure;
+} SDL_Finger;
-struct SDL_Finger {
- SDL_FingerID id;
- Uint16 x;
- Uint16 y;
- Uint16 pressure;
- Uint16 xdelta;
- Uint16 ydelta;
- Uint16 last_x, last_y,last_pressure; /* the last reported coordinates */
- SDL_bool down;
-};
-
-typedef struct SDL_Touch SDL_Touch;
-typedef struct SDL_Finger SDL_Finger;
-
-
-struct SDL_Touch {
-
- /* Free the touch when it's time */
- void (*FreeTouch) (SDL_Touch * touch);
-
- /* data common for tablets */
- float pressure_max, pressure_min;
- float x_max,x_min;
- float y_max,y_min;
- Uint16 xres,yres,pressureres;
- float native_xres,native_yres,native_pressureres;
- float tilt; /* for future use */
- float rotation; /* for future use */
-
- /* Data common to all touch */
- SDL_TouchID id;
- SDL_Window *focus;
-
- char *name;
- Uint8 buttonstate;
- SDL_bool relative_mode;
- SDL_bool flush_motion;
-
- int num_fingers;
- int max_fingers;
- SDL_Finger** fingers;
-
- void *driverdata;
-};
-
+/* Used as the device ID for mouse events simulated with touch input */
+#define SDL_TOUCH_MOUSEID ((Uint32)-1)
/* Function prototypes */
/**
- * \brief Get the touch object at the given id.
- *
- *
+ * \brief Get the number of registered touch devices.
*/
- extern DECLSPEC SDL_Touch* SDLCALL SDL_GetTouch(SDL_TouchID id);
+extern DECLSPEC int SDLCALL SDL_GetNumTouchDevices(void);
+/**
+ * \brief Get the touch ID with the given index, or 0 if the index is invalid.
+ */
+extern DECLSPEC SDL_TouchID SDLCALL SDL_GetTouchDevice(int index);
+/**
+ * \brief Get the number of active fingers for a given touch device.
+ */
+extern DECLSPEC int SDLCALL SDL_GetNumTouchFingers(SDL_TouchID touchID);
/**
- * \brief Get the finger object of the given touch, at the given id.
- *
- *
+ * \brief Get the finger object of the given touch, with the given index.
*/
- extern
- DECLSPEC SDL_Finger* SDLCALL SDL_GetFinger(SDL_Touch *touch, SDL_FingerID id);
+extern DECLSPEC SDL_Finger * SDLCALL SDL_GetTouchFinger(SDL_TouchID touchID, int index);
/* Ends C function definitions when using C++ */
#ifdef __cplusplus
-/* *INDENT-OFF* */
}
-/* *INDENT-ON* */
#endif
#include "close_code.h"
-#endif /* _SDL_mouse_h */
+#endif /* _SDL_touch_h */
/* vi: set ts=4 sw=4 expandtab: */
diff --git a/tests/sdl_touch.c b/tests/sdl_touch.c
new file mode 100644
index 00000000..1fce1df1
--- /dev/null
+++ b/tests/sdl_touch.c
@@ -0,0 +1,78 @@
+#include <stdio.h>
+#include <SDL/SDL.h>
+#include <SDL/SDL_ttf.h>
+#include <assert.h>
+#include <emscripten.h>
+
+int result = 1;
+
+static char *TouchFingerTypeToString(int type) {
+ if (type == SDL_FINGERMOTION) return "SDL_FINGERMOTION";
+ if (type == SDL_FINGERDOWN) return "SDL_FINGERDOWN";
+ if (type == SDL_FINGERUP) return "SDL_FINGERUP";
+ return "UNKNOWN";
+}
+
+int got_down = 0;
+int got_move = 0;
+int got_up = 0;
+
+void progress() {
+ if (!got_down) printf("Hold down a finger to generate a touch down event.\n");
+ else if (!got_move) printf("Drag a finger to generate a touch move event.\n");
+ else if (!got_up) printf("Release a finger to generate a touch up event.\n");
+ else
+ {
+ int result = 0;
+#ifdef REPORT_RESULT
+ REPORT_RESULT();
+#endif
+ }
+}
+
+void loop() {
+ SDL_Event event;
+ while (SDL_PollEvent(&event)) {
+ switch(event.type) {
+ case SDL_FINGERMOTION:
+ case SDL_FINGERDOWN:
+ case SDL_FINGERUP: {
+ SDL_TouchFingerEvent *t = (SDL_TouchFingerEvent*)&event;
+ printf("type: %s, timestamp: %u, touchId: %llu, fingerId: %llu, x: %f, y: %f, dx: %f, dy: %f, pressure: %f\n",
+ TouchFingerTypeToString(event.type), t->timestamp, t->touchId, t->fingerId, t->x, t->y, t->dx, t->dy, t->pressure);
+
+ if (t->timestamp != 0 && t->x >= 0.f && t->x <= 1.f && t->y >= 0.f && t->y <= 1.f && t->pressure >= 0.f && t->pressure <= 1.f) {
+ if (event.type == SDL_FINGERDOWN) { got_down = 1; progress(); }
+ if (event.type == SDL_FINGERMOTION) { got_move = 1; progress(); }
+ if (event.type == SDL_FINGERDOWN) { got_up = 1; progress(); }
+ }
+ break;
+ }
+ }
+ }
+}
+
+int main() {
+ SDL_Init(SDL_INIT_VIDEO);
+ SDL_Surface *screen = SDL_SetVideoMode(600, 450, 32, SDL_HWSURFACE);
+
+ progress();
+
+#ifdef AUTOMATE_SUCCESS
+ EM_ASM(
+ function sendEvent(type, data) {
+ var event = document.createEvent('Event');
+ event.initEvent(type, true, true);
+ for(var d in data) event[d] = data[d];
+ Module['canvas'].dispatchEvent(event);
+ }
+ sendEvent('touchstart', { touches: [ { pageX: 300, pageY: 400, deviceID: 1, identifier: 1, force: 1 } ] });
+ sendEvent('touchmove', { touches: [ { pageX: 350, pageY: 400, deviceID: 1, identifier: 1, force: 1 } ] });
+ sendEvent('touchend', { changedTouches: [ { pageX: 350, pageY: 400, deviceID: 1, identifier: 1, force: 1 } ] });
+ );
+#endif
+
+ emscripten_set_main_loop(loop, 0, 0);
+
+ return 0;
+}
diff --git a/tests/test_browser.py b/tests/test_browser.py
index cf893eb5..c06f11ac 100644
--- a/tests/test_browser.py
+++ b/tests/test_browser.py
@@ -1793,6 +1793,11 @@ Module["preRun"].push(function () {
print opts
self.btest(path_from_root('tests', 'test_html5.c'), args=opts, expected='0')
+ def test_sdl_touch(self):
+ for opts in [[], ['-O2', '-g1', '--closure', '1']]:
+ print opts
+ self.btest(path_from_root('tests', 'sdl_touch.c'), args=opts + ['-DAUTOMATE_SUCCESS=1'], expected='0')
+
def test_html5_mouse(self):
for opts in [[], ['-O2', '-g1', '--closure', '1']]:
print opts
diff --git a/tests/test_interactive.py b/tests/test_interactive.py
index 4ac52f55..aa1d96af 100644
--- a/tests/test_interactive.py
+++ b/tests/test_interactive.py
@@ -25,6 +25,9 @@ class interactive(BrowserCore):
def test_html5_mouse(self):
self.btest(path_from_root('tests', 'test_html5_mouse.c'), expected='0')
+ def test_sdl_touch(self):
+ self.btest(path_from_root('tests', 'sdl_touch.c'), args=['-O2', '-g1', '--closure', '1'], expected='0')
+
def test_sdl_wm_togglefullscreen(self):
self.btest('sdl_wm_togglefullscreen.c', expected='1', args=['-s', 'NO_EXIT_RUNTIME=1'])