From 7f4be45d4edebc300bdd76ef89d4cdd680e389ad Mon Sep 17 00:00:00 2001 From: Frans de Jonge Date: Tue, 3 Apr 2018 14:56:28 +0200 Subject: [PATCH] [chore] Handle SDL_MOUSEWHEEL and less hackish SDL events (#3826) --- base | 2 +- frontend/dbg.lua | 3 +- frontend/device/input.lua | 12 +++++- frontend/device/sdl/device.lua | 73 +++++++++++++++++++++++++++------- 4 files changed, 72 insertions(+), 18 deletions(-) diff --git a/base b/base index 4b8b61b29..7833bf177 160000 --- a/base +++ b/base @@ -1 +1 @@ -Subproject commit 4b8b61b2963eda33b67576a409a5618ad2336f5c +Subproject commit 7833bf17775b4800830f9cb3f090e5c92d7a4323 diff --git a/frontend/dbg.lua b/frontend/dbg.lua index 58f64f671..0532f42eb 100644 --- a/frontend/dbg.lua +++ b/frontend/dbg.lua @@ -83,8 +83,9 @@ function Dbg:v(...) end function Dbg:logEv(ev) + local ev_value = tostring(ev.value) local log = ev.type.."|"..ev.code.."|" - ..ev.value.."|"..ev.time.sec.."|"..ev.time.usec.."\n" + ..ev_value.."|"..ev.time.sec.."|"..ev.time.usec.."\n" if self.ev_log then self.ev_log:write(log) self.ev_log:flush() diff --git a/frontend/device/input.lua b/frontend/device/input.lua index be77ef77b..1fbe4b5ea 100755 --- a/frontend/device/input.lua +++ b/frontend/device/input.lua @@ -19,6 +19,8 @@ local EV_SYN = 0 local EV_KEY = 1 local EV_ABS = 3 local EV_MSC = 4 +-- for frontend SDL event handling +local EV_SDL = 53 -- ASCII code for S -- key press event values (KEY.value) local EVENT_VALUE_KEY_PRESS = 1 @@ -348,6 +350,10 @@ function Input:handleMiscEv(ev) -- should be handled by a misc event protocol plugin end +function Input:handleSdlEv(ev) + -- overwritten by device implementation +end + --[[-- Parse each touch ev from kernel and build up tev. tev will be sent to GestureDetector:feedEvent @@ -652,9 +658,9 @@ function Input:waitEvent(timeout_us) if DEBUG.is_on and ev then DEBUG:logEv(ev) logger.dbg(string.format( - "%s event => type: %d, code: %d(%s), value: %d, time: %d.%d", + "%s event => type: %d, code: %d(%s), value: %s, time: %d.%d", ev.type == EV_KEY and "key" or "input", - ev.type, ev.code, self.event_map[ev.code], ev.value, + ev.type, ev.code, self.event_map[ev.code], tostring(ev.value), ev.time.sec, ev.time.usec)) end self:eventAdjustHook(ev) @@ -666,6 +672,8 @@ function Input:waitEvent(timeout_us) return self:handleTouchEv(ev) elseif ev.type == EV_MSC then return self:handleMiscEv(ev) + elseif ev.type == EV_SDL then + return self:handleSdlEv(ev) else -- some other kind of event that we do not know yet return Event:new("GenericInput", ev) diff --git a/frontend/device/sdl/device.lua b/frontend/device/sdl/device.lua index a6353146f..8a404ecd4 100644 --- a/frontend/device/sdl/device.lua +++ b/frontend/device/sdl/device.lua @@ -42,34 +42,79 @@ function Device:init() self.input = require("device/input"):new{ device = self, event_map = require("device/sdl/event_map_sdl2"), - handleMiscEv = function(device_input, ev) - -- bit of a hack for passing SDL events + handleSdlEv = function(device_input, ev) + local Geom = require("ui/geometry") + local TimeVal = require("ui/timeval") + local UIManager = require("ui/uimanager") + + -- SDL events can remain cdata but are almost completely transparent + local SDL_MOUSEWHEEL = 1027 local SDL_DROPFILE = 4096 local SDL_WINDOWEVENT_RESIZED = 5 - local w = 0 - local h = 1 - if ev.code == SDL_DROPFILE then - local dropped_file_path = input.getDroppedFilePath() + if ev.code == SDL_MOUSEWHEEL then + local scrolled_x = ev.value.x + local scrolled_y = ev.value.y + + local up = 1 + local down = -1 + + local pos = Geom:new{ + x = 0, + y = 0, + w = 0, h = 0, + } + + local timev = TimeVal:new(ev.time) + + local fake_ges = { + ges = "pan", + distance = 200, + relative = { + x = 50*scrolled_x, + y = 100*scrolled_y, + }, + pos = pos, + time = timev, + } + local fake_ges_release = { + ges = "pan_release", + distance = 200, + relative = { + x = 50*scrolled_x, + y = 100*scrolled_y, + }, + pos = pos, + time = timev, + } + local fake_pan_ev = Event:new("Pan", nil, fake_ges) + local fake_release_ev = Event:new("Gesture", fake_ges_release) + + if scrolled_y == down then + fake_ges.direction = "north" + UIManager:broadcastEvent(fake_pan_ev) + UIManager:broadcastEvent(fake_release_ev) + elseif scrolled_y == up then + fake_ges.direction = "south" + UIManager:broadcastEvent(fake_pan_ev) + UIManager:broadcastEvent(fake_release_ev) + end + elseif ev.code == SDL_DROPFILE then + local dropped_file_path = ev.value if dropped_file_path and dropped_file_path ~= "" then local ReaderUI = require("apps/reader/readerui") ReaderUI:doShowReader(dropped_file_path) end - elseif ev.code == w then - device_input.new_w = ev.value - elseif ev.code == h then - device_input.new_h = ev.value elseif ev.code == SDL_WINDOWEVENT_RESIZED then - device_input.device.screen.screen_size.w = device_input.new_w - device_input.device.screen.screen_size.h = device_input.new_h - device_input.device.screen.resize(device_input.device.screen, device_input.new_w, device_input.new_h) + device_input.device.screen.screen_size.w = ev.value.data1 + device_input.device.screen.screen_size.h = ev.value.data2 + device_input.device.screen.resize(device_input.device.screen, ev.value.data1, ev.value.data2) local new_size = device_input.device.screen:getSize() logger.dbg("Resizing screen to", new_size) -- try to catch as many flies as we can -- this means we can't just return one ScreenResize or SetDimensons event - local UIManager = require("ui/uimanager") UIManager:broadcastEvent(Event:new("SetDimensions", new_size)) UIManager:broadcastEvent(Event:new("ScreenResize", new_size)) -- @TODO toggle this elsewhere based on ScreenResize?