@@ -54,6 +54,10 @@ local function SDL_Linked_Version_AtLeast(x, y, z)
54
54
return SDL_VersionNum (getSDLVersion ()) >= SDL_VersionNum (x , y , z )
55
55
end
56
56
57
+ -- Used as the device ID for mouse events simulated with touch input.
58
+ -- Defined in SDL_touch.h as #define SDL_TOUCH_MOUSEID ((Uint32)-1)
59
+ local SDL_TOUCH_MOUSEID = ffi .cast (' uint32_t' , - 1 );
60
+
57
61
local S = {
58
62
w = 0 , h = 0 ,
59
63
screen = nil ,
@@ -201,6 +205,58 @@ local function genEmuEvent(evtype, code, value)
201
205
table.insert (inputQueue , ev )
202
206
end
203
207
208
+ -- Keep track of active pointers so we can feed ABS_MT_SLOT 0 and 1 to the frontend for multitouch to work.
209
+ -- down, a boolean denoting whether the pointer is currently down for tracking mouse button status.
210
+ local pointers = {}
211
+ local function setPointerDownState (slot , down )
212
+ if not pointers [slot ] then
213
+ pointers [slot ] = { down = down }
214
+ else
215
+ pointers [slot ].down = down
216
+ end
217
+ end
218
+
219
+ -- For the moment we pretend there can only be one touchscreen/trackpad/whatever at a time.
220
+ -- It's probably close enough to the truth unless you run into a tester.
221
+ local function getFingerSlot (event )
222
+ if not pointers [tonumber (event .tfinger .fingerId )] then
223
+ local num_touch_fingers = SDL .SDL_GetNumTouchFingers (event .tfinger .touchId )
224
+ if num_touch_fingers > 1 then
225
+ for i = 0 ,num_touch_fingers - 1 do
226
+ if SDL .SDL_GetTouchFinger (event .tfinger .touchId , i ).id == event .tfinger .fingerId then
227
+ pointers [tonumber (event .tfinger .fingerId )] = { slot = i }
228
+ end
229
+ end
230
+ else
231
+ pointers [tonumber (event .tfinger .fingerId )] = { slot = 0 }
232
+ end
233
+ end
234
+ return pointers [tonumber (event .tfinger .fingerId )].slot
235
+ end
236
+
237
+ local function genTouchDownEvent (event , slot , x , y )
238
+ genEmuEvent (C .EV_ABS , C .ABS_MT_SLOT , slot )
239
+ genEmuEvent (C .EV_ABS , C .ABS_MT_TRACKING_ID , tonumber (event .tfinger .fingerId ))
240
+ genEmuEvent (C .EV_ABS , C .ABS_MT_POSITION_X , x )
241
+ genEmuEvent (C .EV_ABS , C .ABS_MT_POSITION_Y , y )
242
+ genEmuEvent (C .EV_SYN , C .SYN_REPORT , 0 )
243
+ end
244
+
245
+ local function genTouchUpEvent (event , slot , x , y )
246
+ genEmuEvent (C .EV_ABS , C .ABS_MT_SLOT , slot )
247
+ genEmuEvent (C .EV_ABS , C .ABS_MT_TRACKING_ID , - 1 )
248
+ genEmuEvent (C .EV_ABS , C .ABS_MT_POSITION_X , x )
249
+ genEmuEvent (C .EV_ABS , C .ABS_MT_POSITION_Y , y )
250
+ genEmuEvent (C .EV_SYN , C .SYN_REPORT , 0 )
251
+ end
252
+
253
+ local function genTouchMoveEvent (event , slot , x , y )
254
+ genEmuEvent (C .EV_ABS , C .ABS_MT_SLOT , slot )
255
+ genEmuEvent (C .EV_ABS , C .ABS_MT_POSITION_X , x )
256
+ genEmuEvent (C .EV_ABS , C .ABS_MT_POSITION_Y , y )
257
+ genEmuEvent (C .EV_SYN , C .SYN_REPORT , 0 )
258
+ end
259
+
204
260
local function handleWindowEvent (event_window )
205
261
-- The next buffer might always contain garbage, and on X11 without
206
262
-- compositing the buffers will be damaged just by moving the window
@@ -273,8 +329,7 @@ local function handleJoyAxisMotionEvent(event)
273
329
end
274
330
275
331
local SDL_BUTTON_LEFT = 1
276
-
277
- local is_in_touch = false
332
+ local SDL_BUTTON_RIGHT = 3
278
333
279
334
function S .waitForEvent (sec , usec )
280
335
local event = ffi .new (" union SDL_Event" )
@@ -293,64 +348,74 @@ function S.waitForEvent(sec, usec)
293
348
end
294
349
295
350
-- if we got an event, examine it here and generate events for koreader
296
- if ffi .os == " OSX" and (event .type == SDL .SDL_FINGERMOTION or
297
- event .type == SDL .SDL_FINGERDOWN or
298
- event .type == SDL .SDL_FINGERUP ) then
299
- -- noop for trackpad finger inputs which interfere with emulated mouse inputs
300
- do end -- luacheck: ignore 541
301
- elseif event .type == SDL .SDL_KEYDOWN then
351
+ if event .type == SDL .SDL_KEYDOWN then
302
352
genEmuEvent (C .EV_KEY , event .key .keysym .sym , 1 )
303
353
elseif event .type == SDL .SDL_KEYUP then
304
354
genEmuEvent (C .EV_KEY , event .key .keysym .sym , 0 )
305
355
elseif event .type == SDL .SDL_TEXTINPUT then
306
356
genEmuEvent (C .EV_SDL , SDL .SDL_TEXTINPUT , ffi .string (event .text .text ))
307
- elseif event .type == SDL .SDL_MOUSEMOTION
357
+ elseif event .type == SDL .SDL_MOUSEMOTION -- and event.motion.which ~= SDL_TOUCH_MOUSEID
308
358
or event .type == SDL .SDL_FINGERMOTION then
309
359
local is_finger = event .type == SDL .SDL_FINGERMOTION
310
- if is_in_touch then
311
- if is_finger then
312
- if event .tfinger .dx ~= 0 then
313
- genEmuEvent (C .EV_ABS , C .ABS_MT_POSITION_X ,
314
- event .tfinger .x * S .w )
315
- end
316
- if event .tfinger .dy ~= 0 then
317
- genEmuEvent (C .EV_ABS , C .ABS_MT_POSITION_Y ,
318
- event .tfinger .y * S .h )
319
- end
320
- else
321
- if event .motion .xrel ~= 0 then
322
- genEmuEvent (C .EV_ABS , C .ABS_MT_POSITION_X ,
323
- event .motion .x )
324
- end
325
- if event .motion .yrel ~= 0 then
326
- genEmuEvent (C .EV_ABS , C .ABS_MT_POSITION_Y ,
327
- event .motion .y )
328
- end
360
+ local slot
361
+
362
+ if is_finger then
363
+ slot = getFingerSlot (event )
364
+ genTouchMoveEvent (event , slot , event .tfinger .x * S .w , event .tfinger .y * S .h )
365
+ else
366
+ if pointers [0 ] and pointers [0 ].down then
367
+ slot = 0 -- left mouse button down
368
+ genTouchMoveEvent (event , slot , event .motion .x , event .motion .y )
369
+ end
370
+ if pointers [1 ] and pointers [1 ].down then
371
+ slot = 1 -- right mouse button down
372
+ genTouchMoveEvent (event , slot , event .motion .x , event .motion .y )
329
373
end
330
- genEmuEvent (C .EV_SYN , C .SYN_REPORT , 0 )
331
374
end
332
- elseif event .type == SDL .SDL_MOUSEBUTTONUP
375
+ elseif event .type == SDL .SDL_MOUSEBUTTONUP and event . button . which ~= SDL_TOUCH_MOUSEID
333
376
or event .type == SDL .SDL_FINGERUP then
334
- is_in_touch = false
335
- genEmuEvent (C .EV_ABS , C .ABS_MT_TRACKING_ID , - 1 )
336
- genEmuEvent (C .EV_SYN , C .SYN_REPORT , 0 )
337
- elseif event .type == SDL .SDL_MOUSEBUTTONDOWN
377
+ local is_finger = event .type == SDL .SDL_FINGERUP
378
+ local slot
379
+ if is_finger then
380
+ slot = getFingerSlot (event )
381
+ elseif event .button .button == SDL_BUTTON_RIGHT then
382
+ slot = 1
383
+ else -- SDL_BUTTON_LEFT
384
+ slot = 0
385
+ end
386
+
387
+ local x = is_finger and event .tfinger .x * S .w or event .button .x
388
+ local y = is_finger and event .tfinger .y * S .h or event .button .y
389
+ genTouchUpEvent (event , slot , x , y )
390
+ if is_finger then
391
+ pointers [tonumber (event .tfinger .fingerId )] = nil
392
+ else
393
+ pointers [slot ] = nil
394
+ end
395
+ elseif event .type == SDL .SDL_MOUSEBUTTONDOWN and event .button .which ~= SDL_TOUCH_MOUSEID
338
396
or event .type == SDL .SDL_FINGERDOWN then
339
397
local is_finger = event .type == SDL .SDL_FINGERDOWN
340
- if not is_finger and event .button .button ~= SDL_BUTTON_LEFT then
341
- -- Not a left-click?
398
+ if not is_finger and not ( event .button .button == SDL_BUTTON_LEFT or event . button . button == SDL_BUTTON_RIGHT ) then
399
+ -- We don't do anything with extra buttons for now.
342
400
return false , C .ENOSYS
343
401
end
402
+
344
403
-- use mouse click to simulate single tap
345
- is_in_touch = true
346
- genEmuEvent (C .EV_ABS , C .ABS_MT_TRACKING_ID , 0 )
347
- genEmuEvent (C .EV_ABS , C .ABS_MT_POSITION_X ,
348
- is_finger and event .tfinger .x * S .w or event .button .x )
349
- genEmuEvent (C .EV_ABS , C .ABS_MT_POSITION_Y ,
350
- is_finger and event .tfinger .y * S .h or event .button .y )
351
- genEmuEvent (C .EV_SYN , C .SYN_REPORT , 0 )
404
+ local slot
405
+ if is_finger then
406
+ slot = getFingerSlot (event )
407
+ elseif event .button .button == SDL_BUTTON_RIGHT then
408
+ slot = 1
409
+ else -- SDL_BUTTON_LEFT
410
+ slot = 0
411
+ end
412
+ local x = is_finger and event .tfinger .x * S .w or event .button .x
413
+ local y = is_finger and event .tfinger .y * S .h or event .button .y
414
+ setPointerDownState (slot , true )
415
+ genTouchDownEvent (event , slot , x , y )
352
416
elseif event .type == SDL .SDL_MULTIGESTURE then
353
417
genEmuEvent (C .EV_SDL , SDL .SDL_MULTIGESTURE , event .mgesture )
418
+ genEmuEvent (C .EV_SYN , C .SYN_REPORT , 0 )
354
419
elseif event .type == SDL .SDL_MOUSEWHEEL then
355
420
genEmuEvent (C .EV_SDL , SDL .SDL_MOUSEWHEEL , event .wheel )
356
421
elseif event .type == SDL .SDL_DROPFILE then
0 commit comments