diff --git a/base b/base index 36b88873b..0d8f7076c 160000 --- a/base +++ b/base @@ -1 +1 @@ -Subproject commit 36b88873bf52b087fba59fa37e7e6a0da92efda2 +Subproject commit 0d8f7076c9904d2894c03b0a1db7c3f5a92e3267 diff --git a/frontend/apps/filemanager/filemanager.lua b/frontend/apps/filemanager/filemanager.lua index d977543bd..0aa77050a 100644 --- a/frontend/apps/filemanager/filemanager.lua +++ b/frontend/apps/filemanager/filemanager.lua @@ -75,7 +75,7 @@ FileManager.onPhysicalKeyboardDisconnected = FileManager.onPhysicalKeyboardConne function FileManager:setRotationMode() local locked = G_reader_settings:isTrue("lock_rotation") if not locked then - local rotation_mode = G_reader_settings:readSetting("fm_rotation_mode") or Screen.ORIENTATION_PORTRAIT + local rotation_mode = G_reader_settings:readSetting("fm_rotation_mode") or Screen.DEVICE_ROTATED_UPRIGHT self:onSetRotationMode(rotation_mode) end end diff --git a/frontend/apps/reader/modules/readerview.lua b/frontend/apps/reader/modules/readerview.lua index 274d3138f..f616fe7a6 100644 --- a/frontend/apps/reader/modules/readerview.lua +++ b/frontend/apps/reader/modules/readerview.lua @@ -859,9 +859,9 @@ function ReaderView:onReadSettings(config) else -- No doc specific rotation, pickup global defaults for the doc type if self.ui.paging then - rotation_mode = G_reader_settings:readSetting("kopt_rotation_mode") or Screen.ORIENTATION_PORTRAIT + rotation_mode = G_reader_settings:readSetting("kopt_rotation_mode") or Screen.DEVICE_ROTATED_UPRIGHT else - rotation_mode = G_reader_settings:readSetting("copt_rotation_mode") or Screen.ORIENTATION_PORTRAIT + rotation_mode = G_reader_settings:readSetting("copt_rotation_mode") or Screen.DEVICE_ROTATED_UPRIGHT end end end diff --git a/frontend/device/android/device.lua b/frontend/device/android/device.lua index 7b60c1b15..4e2dd6dfb 100644 --- a/frontend/device/android/device.lua +++ b/frontend/device/android/device.lua @@ -384,7 +384,8 @@ function Device:_toggleStatusBarVisibility() -- reset touchTranslate to normal self.input:registerEventAdjustHook( self.input.adjustTouchTranslate, - {x = 0 + self.viewport.x, y = 0 + self.viewport.y}) + {x = 0 + self.viewport.x, y = 0 + self.viewport.y} + ) end local viewport = Geom:new{x=0, y=statusbar_height, w=width, h=new_height} @@ -395,7 +396,8 @@ function Device:_toggleStatusBarVisibility() if is_fullscreen and self.viewport then self.input:registerEventAdjustHook( self.input.adjustTouchTranslate, - {x = 0 - self.viewport.x, y = 0 - self.viewport.y}) + {x = 0 - self.viewport.x, y = 0 - self.viewport.y} + ) end self.fullscreen = is_fullscreen diff --git a/frontend/device/cervantes/device.lua b/frontend/device/cervantes/device.lua index 4ed1aa287..860cacce3 100644 --- a/frontend/device/cervantes/device.lua +++ b/frontend/device/cervantes/device.lua @@ -107,13 +107,9 @@ local Cervantes4 = Cervantes:extend{ -- input events function Cervantes:initEventAdjustHooks() - if self.touch_switch_xy then - self.input:registerEventAdjustHook(self.input.adjustTouchSwitchXY) - end - - if self.touch_mirrored_x then + if self.touch_switch_xy and self.touch_mirrored_x then self.input:registerEventAdjustHook( - self.input.adjustTouchMirrorX, + self.input.adjustTouchSwitchAxesAndMirrorX, (self.screen:getWidth() - 1) ) end diff --git a/frontend/device/devicelistener.lua b/frontend/device/devicelistener.lua index 1141bd910..0f67161d4 100644 --- a/frontend/device/devicelistener.lua +++ b/frontend/device/devicelistener.lua @@ -214,7 +214,7 @@ if Device:hasFrontlight() then end -if Device:canToggleGSensor() then +if Device:hasGSensor() then function DeviceListener:onToggleGSensor() _toggleSetting("input_ignore_gsensor") Device:toggleGSensor(not G_reader_settings:isTrue("input_ignore_gsensor")) diff --git a/frontend/device/generic/device.lua b/frontend/device/generic/device.lua index a5da130b4..b140d042f 100644 --- a/frontend/device/generic/device.lua +++ b/frontend/device/generic/device.lua @@ -61,7 +61,6 @@ local Device = { canImportFiles = no, canShareText = no, hasGSensor = no, - canToggleGSensor = no, isGSensorLocked = no, canToggleMassStorage = no, canToggleChargingLED = no, @@ -206,7 +205,8 @@ function Device:init() self.screen:setViewport(self.viewport) self.input:registerEventAdjustHook( self.input.adjustTouchTranslate, - {x = 0 - self.viewport.x, y = 0 - self.viewport.y}) + {x = 0 - self.viewport.x, y = 0 - self.viewport.y} + ) end -- Handle button mappings shenanigans @@ -216,8 +216,13 @@ function Device:init() end end - -- Honor the gyro lock if self:hasGSensor() then + -- Setup our standard gyro event handler (EV_MSC:MSC_GYRO) + if G_reader_settings:nilOrFalse("input_ignore_gsensor") then + self.input.handleGyroEv = self.input.handleMiscGyroEv + end + + -- Honor the gyro lock if G_reader_settings:isTrue("input_lock_gsensor") then self:lockGSensor(true) end @@ -418,8 +423,17 @@ function Device:performHapticFeedback(type) end -- Device specific method for toggling input events function Device:setIgnoreInput(enable) return true end --- Device specific method for toggling the GSensor -function Device:toggleGSensor(toggle) end +-- Device agnostic method for toggling the GSensor +-- (can be reimplemented if need be, but you really, really should try not to. c.f., Kobo, Kindle & PocketBook) +function Device:toggleGSensor(toggle) + if not self:hasGSensor() then + return + end + + if self.input then + self.input:toggleGyroEvents(toggle) + end +end -- Whether or not the GSensor should be locked to the current orientation (i.e. Portrait <-> Inverted Portrait or Landscape <-> Inverted Landscape only) function Device:lockGSensor(toggle) diff --git a/frontend/device/gesturedetector.lua b/frontend/device/gesturedetector.lua index c69dec8e0..5eb42f565 100644 --- a/frontend/device/gesturedetector.lua +++ b/frontend/device/gesturedetector.lua @@ -984,7 +984,7 @@ function Contact:handlePan() if msd_distance > gesture_detector.MULTISWIPE_THRESHOLD then local pan_ev_multiswipe = pan_ev -- store a copy of pan_ev without rotation adjustment for multiswipe calculations when rotated - if gesture_detector.screen:getTouchRotation() > gesture_detector.screen.ORIENTATION_PORTRAIT then + if gesture_detector.screen:getTouchRotation() > gesture_detector.screen.DEVICE_ROTATED_UPRIGHT then pan_ev_multiswipe = util.tableDeepCopy(pan_ev) end if msd_direction ~= msd_direction_prev then @@ -1335,7 +1335,7 @@ end --]] function GestureDetector:adjustGesCoordinate(ges) local mode = self.screen:getTouchRotation() - if mode == self.screen.ORIENTATION_LANDSCAPE then + if mode == self.screen.DEVICE_ROTATED_CLOCKWISE then -- in landscape mode rotated 90 if ges.pos then ges.pos.x, ges.pos.y = (self.screen:getWidth() - ges.pos.y), (ges.pos.x) @@ -1367,7 +1367,7 @@ function GestureDetector:adjustGesCoordinate(ges) end logger.dbg("GestureDetector: Landscape translation for ges:", ges.ges, ges.direction) end - elseif mode == self.screen.ORIENTATION_LANDSCAPE_ROTATED then + elseif mode == self.screen.DEVICE_ROTATED_COUNTER_CLOCKWISE then -- in landscape mode rotated 270 if ges.pos then ges.pos.x, ges.pos.y = (ges.pos.y), (self.screen:getHeight() - ges.pos.x) @@ -1399,7 +1399,7 @@ function GestureDetector:adjustGesCoordinate(ges) end logger.dbg("GestureDetector: Inverted landscape translation for ges:", ges.ges, ges.direction) end - elseif mode == self.screen.ORIENTATION_PORTRAIT_ROTATED then + elseif mode == self.screen.DEVICE_ROTATED_UPSIDE_DOWN then -- in portrait mode rotated 180 if ges.pos then ges.pos.x, ges.pos.y = (self.screen:getWidth() - ges.pos.x), (self.screen:getHeight() - ges.pos.y) diff --git a/frontend/device/input.lua b/frontend/device/input.lua index d0643cc52..ca6e5e0a1 100644 --- a/frontend/device/input.lua +++ b/frontend/device/input.lua @@ -19,42 +19,10 @@ local C = ffi.C require("ffi/posix_h") require("ffi/linux_input_h") --- luacheck: push --- luacheck: ignore --- key press event values (KEY.value) -local EVENT_VALUE_KEY_PRESS = 1 -local EVENT_VALUE_KEY_REPEAT = 2 -local EVENT_VALUE_KEY_RELEASE = 0 - --- For Kindle Oasis orientation events (ABS.code) --- the ABS code of orientation event will be adjusted to -24 from 24 (C.ABS_PRESSURE) --- as C.ABS_PRESSURE is also used to detect touch input in KOBO devices. -local ABS_OASIS_ORIENTATION = -24 -local DEVICE_ORIENTATION_PORTRAIT_LEFT = 15 -local DEVICE_ORIENTATION_PORTRAIT_RIGHT = 17 -local DEVICE_ORIENTATION_PORTRAIT = 19 -local DEVICE_ORIENTATION_PORTRAIT_ROTATED_LEFT = 16 -local DEVICE_ORIENTATION_PORTRAIT_ROTATED_RIGHT = 18 -local DEVICE_ORIENTATION_PORTRAIT_ROTATED = 20 -local DEVICE_ORIENTATION_LANDSCAPE = 21 -local DEVICE_ORIENTATION_LANDSCAPE_ROTATED = 22 - --- Kindle Oasis 2 & 3 variant --- c.f., drivers/input/misc/accel/bma2x2.c -local UPWARD_PORTRAIT_UP_INTERRUPT_HAPPENED = 15 -local UPWARD_PORTRAIT_DOWN_INTERRUPT_HAPPENED = 16 -local UPWARD_LANDSCAPE_LEFT_INTERRUPT_HAPPENED = 17 -local UPWARD_LANDSCAPE_RIGHT_INTERRUPT_HAPPENED = 18 - --- For the events of the Forma & Libra accelerometers (MSC.value) --- c.f., drivers/hwmon/mma8x5x.c -local MSC_RAW_GSENSOR_PORTRAIT_DOWN = 0x17 -local MSC_RAW_GSENSOR_PORTRAIT_UP = 0x18 -local MSC_RAW_GSENSOR_LANDSCAPE_RIGHT = 0x19 -local MSC_RAW_GSENSOR_LANDSCAPE_LEFT = 0x1a --- Not that we care about those, but they are reported, and accurate ;). -local MSC_RAW_GSENSOR_BACK = 0x1b -local MSC_RAW_GSENSOR_FRONT = 0x1c +-- EV_KEY values +local KEY_PRESS = 1 +local KEY_REPEAT = 2 +local KEY_RELEASE = 0 -- Based on ABS_MT_TOOL_TYPE values on Elan panels local TOOL_TYPE_FINGER = 0 @@ -74,7 +42,6 @@ local linux_evdev_type_map = { [C.EV_FF] = "EV_FF", [C.EV_PWR] = "EV_PWR", [C.EV_FF_STATUS] = "EV_FF_STATUS", - [C.EV_MAX] = "EV_MAX", [C.EV_SDL] = "EV_SDL", } @@ -122,23 +89,23 @@ local linux_evdev_abs_code_map = { local linux_evdev_msc_code_map = { [C.MSC_RAW] = "MSC_RAW", + [C.MSC_GYRO] = "MSC_GYRO", } local linux_evdev_rep_code_map = { [C.REP_DELAY] = "REP_DELAY", [C.REP_PERIOD] = "REP_PERIOD", } --- luacheck: pop local _internal_clipboard_text = nil -- holds the last copied text local Input = { -- must point to the device implementation when instantiating device = nil, - -- this depends on keyboard layout and should be overridden: - event_map = {}, + -- this depends on keyboard layout and should be overridden + event_map = nil, -- hash -- adapters are post processing functions that transform a given event to another event - event_map_adapter = {}, + event_map_adapter = nil, -- hash -- EV_ABS event to honor for pressure event (if any) pressure_event = nil, @@ -193,8 +160,8 @@ local Input = { UsbDevicePlugOut = {}, }, - -- This might be overloaded or even disabled (post-init) at instance-level, so we don't want any inheritance - rotation_map = nil, -- nil or a hash + -- This might be modified at runtime, so we don't want any inheritance + rotation_map = nil, -- hash timer_callbacks = nil, -- instance-specific table, because the object may get destroyed & recreated at runtime disable_double_tap = true, @@ -260,13 +227,20 @@ function Input:init() input = self, } + if not self.event_map then + self.event_map = {} + end + if not self.event_map_adapter then + self.event_map_adapter = {} + end + -- NOTE: When looking at the device in Portrait mode, that's assuming PgBack is on TOP, and PgFwd on the BOTTOM if not self.rotation_map then self.rotation_map = { - [framebuffer.ORIENTATION_PORTRAIT] = {}, - [framebuffer.ORIENTATION_LANDSCAPE] = { Up = "Right", Right = "Down", Down = "Left", Left = "Up", LPgBack = "LPgFwd", LPgFwd = "LPgBack", RPgBack = "RPgFwd", RPgFwd = "RPgBack" }, - [framebuffer.ORIENTATION_PORTRAIT_ROTATED] = { Up = "Down", Right = "Left", Down = "Up", Left = "Right", LPgFwd = "LPgBack", LPgBack = "LPgFwd", RPgFwd = "RPgBack", RPgBack = "RPgFwd" }, - [framebuffer.ORIENTATION_LANDSCAPE_ROTATED] = { Up = "Left", Right = "Up", Down = "Right", Left = "Down" } + [framebuffer.DEVICE_ROTATED_UPRIGHT] = {}, + [framebuffer.DEVICE_ROTATED_CLOCKWISE] = { Up = "Right", Right = "Down", Down = "Left", Left = "Up", LPgBack = "LPgFwd", LPgFwd = "LPgBack", RPgBack = "RPgFwd", RPgFwd = "RPgBack" }, + [framebuffer.DEVICE_ROTATED_UPSIDE_DOWN] = { Up = "Down", Right = "Left", Down = "Up", Left = "Right", LPgFwd = "LPgBack", LPgBack = "LPgFwd", RPgFwd = "RPgBack", RPgBack = "RPgFwd" }, + [framebuffer.DEVICE_ROTATED_COUNTER_CLOCKWISE] = { Up = "Left", Right = "Up", Down = "Right", Left = "Down" }, } end @@ -301,6 +275,18 @@ function Input:init() self._inhibitInputUntil_func = function() self:inhibitInputUntil() end end +--[[-- +Setup a rotation_map that does nothing (for platforms where the events we get are already translated). +--]] +function Input:disableRotationMap() + self.rotation_map = { + [framebuffer.DEVICE_ROTATED_UPRIGHT] = {}, + [framebuffer.DEVICE_ROTATED_CLOCKWISE] = {}, + [framebuffer.DEVICE_ROTATED_UPSIDE_DOWN] = {}, + [framebuffer.DEVICE_ROTATED_COUNTER_CLOCKWISE] = {}, + } +end + --[[-- Wrapper for FFI input open. @@ -313,22 +299,35 @@ function Input.open(device, is_emu_events) end --[[-- -Different device models can implement their own hooks -and register them. +Different device models can implement their own hooks and register them. --]] function Input:registerEventAdjustHook(hook, hook_params) - local old = self.eventAdjustHook - self.eventAdjustHook = function(this, ev) - old(this, ev) - hook(this, ev, hook_params) + if self.eventAdjustHook == Input.eventAdjustHook then + -- First custom hook, skip the default NOP + self.eventAdjustHook = function(this, ev) + hook(this, ev, hook_params) + end + else + -- We've already got a custom hook, chain 'em + local old = self.eventAdjustHook + self.eventAdjustHook = function(this, ev) + old(this, ev) + hook(this, ev, hook_params) + end end end function Input:registerGestureAdjustHook(hook, hook_params) - local old = self.gestureAdjustHook - self.gestureAdjustHook = function(this, ges) - old(this, ges) - hook(this, ges, hook_params) + if self.gestureAdjustHook == Input.gestureAdjustHook then + self.gestureAdjustHook = function(this, ges) + hook(this, ges, hook_params) + end + else + local old = self.gestureAdjustHook + self.gestureAdjustHook = function(this, ges) + old(this, ges) + hook(this, ges, hook_params) + end end end @@ -341,59 +340,77 @@ function Input:gestureAdjustHook(ges) end --- Catalog of predefined hooks. -function Input:adjustTouchSwitchXY(ev) - if ev.type == C.EV_ABS then - if ev.code == C.ABS_X then - ev.code = C.ABS_Y - elseif ev.code == C.ABS_Y then - ev.code = C.ABS_X - elseif ev.code == C.ABS_MT_POSITION_X then - ev.code = C.ABS_MT_POSITION_Y - elseif ev.code == C.ABS_MT_POSITION_Y then - ev.code = C.ABS_MT_POSITION_X - end +-- These are *not* usable directly as hooks, they're just building blocks (c.f., Kobo) +function Input:adjustABS_SwitchXY(ev) + if ev.code == C.ABS_X then + ev.code = C.ABS_Y + elseif ev.code == C.ABS_Y then + ev.code = C.ABS_X + elseif ev.code == C.ABS_MT_POSITION_X then + ev.code = C.ABS_MT_POSITION_Y + elseif ev.code == C.ABS_MT_POSITION_Y then + ev.code = C.ABS_MT_POSITION_X end end -function Input:adjustTouchScale(ev, by) - if ev.type == C.EV_ABS then - if ev.code == C.ABS_X or ev.code == C.ABS_MT_POSITION_X then - ev.value = by.x * ev.value - end - if ev.code == C.ABS_Y or ev.code == C.ABS_MT_POSITION_Y then - ev.value = by.y * ev.value - end +function Input:adjustABS_Scale(ev, by) + if ev.code == C.ABS_X or ev.code == C.ABS_MT_POSITION_X then + ev.value = by.x * ev.value + elseif ev.code == C.ABS_Y or ev.code == C.ABS_MT_POSITION_Y then + ev.value = by.y * ev.value end end -function Input:adjustTouchMirrorX(ev, max_x) - if ev.type == C.EV_ABS - and (ev.code == C.ABS_X or ev.code == C.ABS_MT_POSITION_X) then +function Input:adjustABS_MirrorX(ev, max_x) + if ev.code == C.ABS_X or ev.code == C.ABS_MT_POSITION_X then ev.value = max_x - ev.value end end -function Input:adjustTouchMirrorY(ev, max_y) - if ev.type == C.EV_ABS - and (ev.code == C.ABS_Y or ev.code == C.ABS_MT_POSITION_Y) then +function Input:adjustABS_MirrorY(ev, max_y) + if ev.code == C.ABS_Y or ev.code == C.ABS_MT_POSITION_Y then ev.value = max_y - ev.value end end -function Input:adjustTouchTranslate(ev, by) +function Input:adjustABS_SwitchAxesAndMirrorX(ev, max_x) + if ev.code == C.ABS_X then + ev.code = C.ABS_Y + elseif ev.code == C.ABS_Y then + ev.code = C.ABS_X + ev.value = max_x - ev.value + elseif ev.code == C.ABS_MT_POSITION_X then + ev.code = C.ABS_MT_POSITION_Y + elseif ev.code == C.ABS_MT_POSITION_Y then + ev.code = C.ABS_MT_POSITION_X + ev.value = max_x - ev.value + end +end + +function Input:adjustABS_Translate(ev, by) + if ev.code == C.ABS_X or ev.code == C.ABS_MT_POSITION_X then + ev.value = by.x + ev.value + elseif ev.code == C.ABS_Y or ev.code == C.ABS_MT_POSITION_Y then + ev.value = by.y + ev.value + end +end + +-- These *are* usable directly as hooks +function Input:adjustTouchScale(ev, by) if ev.type == C.EV_ABS then - if ev.code == C.ABS_X or ev.code == C.ABS_MT_POSITION_X then - ev.value = by.x + ev.value - end - if ev.code == C.ABS_Y or ev.code == C.ABS_MT_POSITION_Y then - ev.value = by.y + ev.value - end + self:adjustABS_Scale(ev, by) + end +end + +function Input:adjustTouchSwitchAxesAndMirrorX(ev, max_x) + if ev.type == C.EV_ABS then + self:adjustABS_SwitchAxesAndMirrorX(ev, max_x) end end -function Input:adjustKindleOasisOrientation(ev) - if ev.type == C.EV_ABS and ev.code == C.ABS_PRESSURE then - ev.code = ABS_OASIS_ORIENTATION +function Input:adjustTouchTranslate(ev, by) + if ev.type == C.EV_ABS then + self:adjustABS_Translate(ev, by) end end @@ -548,11 +565,9 @@ function Input:handleKeyBoardEv(ev) end -- take device rotation into account - if self.rotation_map then - local rota = self.device.screen:getRotationMode() - if self.rotation_map[rota][keycode] then - keycode = self.rotation_map[rota][keycode] - end + local rota = self.device.screen:getRotationMode() + if self.rotation_map[rota][keycode] then + keycode = self.rotation_map[rota][keycode] end if self.fake_event_set[keycode] then @@ -573,9 +588,9 @@ function Input:handleKeyBoardEv(ev) if keycode == "Power" then -- Kobo generates Power keycode only, we need to decide whether it's -- power-on or power-off ourselves. - if ev.value == EVENT_VALUE_KEY_PRESS then + if ev.value == KEY_PRESS then return "PowerPress" - elseif ev.value == EVENT_VALUE_KEY_RELEASE then + elseif ev.value == KEY_RELEASE then return "PowerRelease" end end @@ -596,9 +611,9 @@ function Input:handleKeyBoardEv(ev) -- handle modifier keys if self.modifiers[keycode] ~= nil then - if ev.value == EVENT_VALUE_KEY_PRESS then + if ev.value == KEY_PRESS then self.modifiers[keycode] = true - elseif ev.value == EVENT_VALUE_KEY_RELEASE then + elseif ev.value == KEY_RELEASE then self.modifiers[keycode] = false end return @@ -606,9 +621,9 @@ function Input:handleKeyBoardEv(ev) local key = Key:new(keycode, self.modifiers) - if ev.value == EVENT_VALUE_KEY_PRESS then + if ev.value == KEY_PRESS then return Event:new("KeyPress", key) - elseif ev.value == EVENT_VALUE_KEY_REPEAT then + elseif ev.value == KEY_REPEAT then -- NOTE: We only care about repeat events from the pageturn buttons... -- And we *definitely* don't want to flood the Event queue with useless SleepCover repeats! if keycode == "LPgBack" @@ -629,7 +644,7 @@ function Input:handleKeyBoardEv(ev) self.repeat_count = 0 end end - elseif ev.value == EVENT_VALUE_KEY_RELEASE then + elseif ev.value == KEY_RELEASE then self.repeat_count = 0 return Event:new("KeyRelease", key) end @@ -662,9 +677,9 @@ function Input:handlePowerManagementOnlyEv(ev) if keycode == "Power" then -- Kobo generates Power keycode only, we need to decide whether it's -- power-on or power-off ourselves. - if ev.value == EVENT_VALUE_KEY_PRESS then + if ev.value == KEY_PRESS then return "PowerPress" - elseif ev.value == EVENT_VALUE_KEY_RELEASE then + elseif ev.value == KEY_RELEASE then return "PowerRelease" end end @@ -684,7 +699,11 @@ function Input:handleGenericEv(ev) end function Input:handleMiscEv(ev) - -- should be handled by a misc event protocol plugin + -- overwritten by device implementation +end + +function Input:handleGyroEv(ev) + -- setup by the Generic device implementation (for proper toggle handling) end function Input:handleSdlEv(ev) @@ -886,92 +905,29 @@ function Input:handleTouchEvLegacy(ev) end end -function Input:handleOasisOrientationEv(ev) - local rotation_mode, screen_mode - if self.device:isZelda() then - if ev.value == UPWARD_PORTRAIT_UP_INTERRUPT_HAPPENED then - -- i.e., UR - rotation_mode = framebuffer.ORIENTATION_PORTRAIT - screen_mode = 'portrait' - elseif ev.value == UPWARD_LANDSCAPE_LEFT_INTERRUPT_HAPPENED then - -- i.e., CW - rotation_mode = framebuffer.ORIENTATION_LANDSCAPE - screen_mode = 'landscape' - elseif ev.value == UPWARD_PORTRAIT_DOWN_INTERRUPT_HAPPENED then - -- i.e., UD - rotation_mode = framebuffer.ORIENTATION_PORTRAIT_ROTATED - screen_mode = 'portrait' - elseif ev.value == UPWARD_LANDSCAPE_RIGHT_INTERRUPT_HAPPENED then - -- i.e., CCW - rotation_mode = framebuffer.ORIENTATION_LANDSCAPE_ROTATED - screen_mode = 'landscape' - end - else - if ev.value == DEVICE_ORIENTATION_PORTRAIT - or ev.value == DEVICE_ORIENTATION_PORTRAIT_LEFT - or ev.value == DEVICE_ORIENTATION_PORTRAIT_RIGHT then - -- i.e., UR - rotation_mode = framebuffer.ORIENTATION_PORTRAIT - screen_mode = 'portrait' - elseif ev.value == DEVICE_ORIENTATION_LANDSCAPE then - -- i.e., CW - rotation_mode = framebuffer.ORIENTATION_LANDSCAPE - screen_mode = 'landscape' - elseif ev.value == DEVICE_ORIENTATION_PORTRAIT_ROTATED - or ev.value == DEVICE_ORIENTATION_PORTRAIT_ROTATED_LEFT - or ev.value == DEVICE_ORIENTATION_PORTRAIT_ROTATED_RIGHT then - -- i.e., UD - rotation_mode = framebuffer.ORIENTATION_PORTRAIT_ROTATED - screen_mode = 'portrait' - elseif ev.value == DEVICE_ORIENTATION_LANDSCAPE_ROTATED then - -- i.e., CCW - rotation_mode = framebuffer.ORIENTATION_LANDSCAPE_ROTATED - screen_mode = 'landscape' - end - end - - local old_rotation_mode = self.device.screen:getRotationMode() - if self.device:isGSensorLocked() then - local old_screen_mode = self.device.screen:getScreenMode() - if rotation_mode ~= old_rotation_mode and screen_mode == old_screen_mode then - -- Cheaper than a full SetRotationMode event, as we don't need to re-layout anything. - self.device.screen:setRotationMode(rotation_mode) - local UIManager = require("ui/uimanager") - UIManager:onRotation() - end - else - if rotation_mode ~= old_rotation_mode then - return Event:new("SetRotationMode", rotation_mode) - end - end -end - ---- Accelerometer on the Forma/Libra -function Input:handleMiscEvNTX(ev) +--- Accelerometer, in a platform-agnostic, custom format (EV_MSC:MSC_GYRO). +--- (Translation should be done via registerEventAdjustHook in Device implementations). +--- This needs to be called *via handleGyroEv* in a handleMiscEv implementation (c.f., Kobo, Kindle or PocketBook). +function Input:handleMiscGyroEv(ev) local rotation_mode, screen_mode - if ev.code == C.MSC_RAW then - if ev.value == MSC_RAW_GSENSOR_PORTRAIT_UP then - -- i.e., UR - rotation_mode = framebuffer.ORIENTATION_PORTRAIT - screen_mode = 'portrait' - elseif ev.value == MSC_RAW_GSENSOR_LANDSCAPE_RIGHT then - -- i.e., CW - rotation_mode = framebuffer.ORIENTATION_LANDSCAPE - screen_mode = 'landscape' - elseif ev.value == MSC_RAW_GSENSOR_PORTRAIT_DOWN then - -- i.e., UD - rotation_mode = framebuffer.ORIENTATION_PORTRAIT_ROTATED - screen_mode = 'portrait' - elseif ev.value == MSC_RAW_GSENSOR_LANDSCAPE_LEFT then - -- i.e., CCW - rotation_mode = framebuffer.ORIENTATION_LANDSCAPE_ROTATED - screen_mode = 'landscape' - else - -- Discard FRONT/BACK - return - end + if ev.value == C.DEVICE_ROTATED_UPRIGHT then + -- i.e., UR + rotation_mode = framebuffer.DEVICE_ROTATED_UPRIGHT + screen_mode = "portrait" + elseif ev.value == C.DEVICE_ROTATED_CLOCKWISE then + -- i.e., CW + rotation_mode = framebuffer.DEVICE_ROTATED_CLOCKWISE + screen_mode = "landscape" + elseif ev.value == C.DEVICE_ROTATED_UPSIDE_DOWN then + -- i.e., UD + rotation_mode = framebuffer.DEVICE_ROTATED_UPSIDE_DOWN + screen_mode = "portrait" + elseif ev.value == C.DEVICE_ROTATED_COUNTER_CLOCKWISE then + -- i.e., CCW + rotation_mode = framebuffer.DEVICE_ROTATED_COUNTER_CLOCKWISE + screen_mode = "landscape" else - -- Discard unhandled event codes, just to future-proof this ;). + -- Discard FRONT/BACK return end @@ -992,28 +948,24 @@ function Input:handleMiscEvNTX(ev) end --- Allow toggling the accelerometer at runtime. -function Input:toggleMiscEvNTX(toggle) +function Input:toggleGyroEvents(toggle) if toggle == true then -- Honor Gyro events - if not self.isNTXAccelHooked then - self.handleMiscEv = self.handleMiscEvNTX - self.isNTXAccelHooked = true + if self.handleGyroEv ~= self.handleMiscGyroEv then + self.handleGyroEv = self.handleMiscGyroEv end elseif toggle == false then -- Ignore Gyro events - if self.isNTXAccelHooked then - self.handleMiscEv = self.voidEv - self.isNTXAccelHooked = false + if self.handleGyroEv == self.handleMiscGyroEv then + self.handleGyroEv = self.voidEv end else -- Toggle it - if self.isNTXAccelHooked then - self.handleMiscEv = self.voidEv + if self.handleGyroEv == self.handleMiscGyroEv then + self.handleGyroEv = self.voidEv else - self.handleMiscEv = self.handleMiscEvNTX + self.handleGyroEv = self.handleMiscGyroEv end - - self.isNTXAccelHooked = not self.isNTXAccelHooked end end @@ -1096,15 +1048,15 @@ function Input:setupSlotData(value) end function Input:isEvKeyPress(ev) - return ev.value == EVENT_VALUE_KEY_PRESS + return ev.value == KEY_PRESS end function Input:isEvKeyRepeat(ev) - return ev.value == EVENT_VALUE_KEY_REPEAT + return ev.value == KEY_REPEAT end function Input:isEvKeyRelease(ev) - return ev.value == EVENT_VALUE_KEY_RELEASE + return ev.value == KEY_RELEASE end @@ -1338,11 +1290,6 @@ function Input:waitEvent(now, deadline) if handled_ev then table.insert(handled, handled_ev) end - elseif event.type == C.EV_ABS and event.code == ABS_OASIS_ORIENTATION then - local handled_ev = self:handleOasisOrientationEv(event) - if handled_ev then - table.insert(handled, handled_ev) - end elseif event.type == C.EV_ABS or event.type == C.EV_SYN then local handled_evs = self:handleTouchEv(event) -- handleTouchEv only returns an array of Events once it gets a SYN_REPORT, @@ -1393,23 +1340,17 @@ function Input:inhibitInput(toggle) self.handleKeyBoardEv = self.handlePowerManagementOnlyEv end -- And send everything else to the void - if not self._oasis_ev_handler then - self._oasis_ev_handler = self.handleOasisOrientationEv - self.handleOasisOrientationEv = self.voidEv - end if not self._abs_ev_handler then self._abs_ev_handler = self.handleTouchEv self.handleTouchEv = self.voidEv end - if not self._msc_ev_handler then - if not self.device:isPocketBook() and not self.device:isAndroid() then - -- NOTE: PocketBook is a special snowflake, synthetic Power events are sent as EV_MSC. - -- Thankfully, that's all that EV_MSC is used for on that platform. - -- NOTE: Android, on the other hand, handles a *lot* of critical stuff over EV_MSC, - -- as it's used to communicate between Android and Lua land ;). - self._msc_ev_handler = self.handleMiscEv - self.handleMiscEv = self.voidEv - end + -- NOTE: We leave handleMiscEv alone, as some platforms make extensive use of EV_MSC for critical low-level stuff: + -- e.g., on PocketBook, it is used to handle InkView task management events (i.e., PM); + -- and on Android, for the critical purpose of forwarding Android events to Lua-land. + -- The only thing we might want to skip in there are gyro events anyway, which we'll handle separately. + if not self._gyro_ev_handler then + self._gyro_ev_handler = self.handleGyroEv + self.handleGyroEv = self.voidEv end if not self._sdl_ev_handler then self._sdl_ev_handler = self.handleSdlEv @@ -1429,17 +1370,13 @@ function Input:inhibitInput(toggle) self.handleKeyBoardEv = self._key_ev_handler self._key_ev_handler = nil end - if self._oasis_ev_handler then - self.handleOasisOrientationEv = self._oasis_ev_handler - self._oasis_ev_handler = nil - end if self._abs_ev_handler then self.handleTouchEv = self._abs_ev_handler self._abs_ev_handler = nil end - if self._msc_ev_handler then - self.handleMiscEv = self._msc_ev_handler - self._msc_ev_handler = nil + if self._gyro_ev_handler then + self.handleGyroEv = self._gyro_ev_handler + self._gyro_ev_handler = nil end if self._sdl_ev_handler then self.handleSdlEv = self._sdl_ev_handler diff --git a/frontend/device/kindle/device.lua b/frontend/device/kindle/device.lua index 21ff8b2c0..5a1aec985 100644 --- a/frontend/device/kindle/device.lua +++ b/frontend/device/kindle/device.lua @@ -3,6 +3,13 @@ local time = require("ui/time") local lfs = require("libs/libkoreader-lfs") local logger = require("logger") +-- We're going to need a few & constants... +local ffi = require("ffi") +local C = ffi.C +require("ffi/linux_fb_h") +require("ffi/linux_input_h") +require("ffi/posix_h") + local function yes() return true end local function no() return false end -- luacheck: ignore @@ -823,6 +830,46 @@ function KindlePaperWhite3:init() self.input.open("fake_events") end +-- HAL for gyro orientation switches (EV_ABS:ABS_PRESSURE (?!) w/ custom values to EV_MSC:MSC_GYRO w/ our own custom values) +local function OasisGyroTranslation(this, ev) + local DEVICE_ORIENTATION_PORTRAIT_LEFT = 15 + local DEVICE_ORIENTATION_PORTRAIT_RIGHT = 17 + local DEVICE_ORIENTATION_PORTRAIT = 19 + local DEVICE_ORIENTATION_PORTRAIT_ROTATED_LEFT = 16 + local DEVICE_ORIENTATION_PORTRAIT_ROTATED_RIGHT = 18 + local DEVICE_ORIENTATION_PORTRAIT_ROTATED = 20 + local DEVICE_ORIENTATION_LANDSCAPE = 21 + local DEVICE_ORIENTATION_LANDSCAPE_ROTATED = 22 + + if ev.type == C.EV_ABS and ev.code == C.ABS_PRESSURE then + if ev.value == DEVICE_ORIENTATION_PORTRAIT + or ev.value == DEVICE_ORIENTATION_PORTRAIT_LEFT + or ev.value == DEVICE_ORIENTATION_PORTRAIT_RIGHT then + -- i.e., UR + ev.type = C.EV_MSC + ev.code = C.MSC_GYRO + ev.value = C.DEVICE_ROTATED_UPRIGHT + elseif ev.value == DEVICE_ORIENTATION_LANDSCAPE then + -- i.e., CW + ev.type = C.EV_MSC + ev.code = C.MSC_GYRO + ev.value = C.DEVICE_ROTATED_CLOCKWISE + elseif ev.value == DEVICE_ORIENTATION_PORTRAIT_ROTATED + or ev.value == DEVICE_ORIENTATION_PORTRAIT_ROTATED_LEFT + or ev.value == DEVICE_ORIENTATION_PORTRAIT_ROTATED_RIGHT then + -- i.e., UD + ev.type = C.EV_MSC + ev.code = C.MSC_GYRO + ev.value = C.DEVICE_ROTATED_UPSIDE_DOWN + elseif ev.value == DEVICE_ORIENTATION_LANDSCAPE_ROTATED then + -- i.e., CCW + ev.type = C.EV_MSC + ev.code = C.MSC_GYRO + ev.value = C.DEVICE_ROTATED_COUNTER_CLOCKWISE + end + end +end + function KindleOasis:init() self.screen = require("ffi/framebuffer_mxcfb"):new{device = self, debug = logger.dbg} self.powerd = require("device/kindle/powerd"):new{ @@ -850,14 +897,14 @@ function KindleOasis:init() "com.lab126.winmgr", "accelerometer") local rotation_mode = 0 if orientation_code then - if orientation_code == "V" then - rotation_mode = self.screen.ORIENTATION_PORTRAIT + if orientation_code == "U" then + rotation_mode = self.screen.DEVICE_ROTATED_UPRIGHT elseif orientation_code == "R" then - rotation_mode = self.screen.ORIENTATION_LANDSCAPE + rotation_mode = self.screen.DEVICE_ROTATED_CLOCKWISE elseif orientation_code == "D" then - rotation_mode = self.screen.ORIENTATION_PORTRAIT_ROTATED + rotation_mode = self.screen.DEVICE_ROTATED_UPSIDE_DOWN elseif orientation_code == "L" then - rotation_mode = self.screen.ORIENTATION_LANDSCAPE_ROTATED + rotation_mode = self.screen.DEVICE_ROTATED_COUNTER_CLOCKWISE end end @@ -872,7 +919,12 @@ function KindleOasis:init() Kindle.init(self) - self.input:registerEventAdjustHook(self.input.adjustKindleOasisOrientation) + self.input:registerEventAdjustHook(OasisGyroTranslation) + self.input.handleMiscEv = function(this, ev) + if ev.code == C.MSC_GYRO then + return this:handleGyroEv(ev) + end + end self.input.open(self.touch_dev) self.input.open("/dev/input/by-path/platform-gpiokey.0-event") @@ -890,6 +942,39 @@ function KindleOasis:init() self.input.open("fake_events") end +-- HAL for gyro orientation switches (EV_ABS:ABS_PRESSURE (?!) w/ custom values to EV_MSC:MSC_GYRO w/ our own custom values) +local function ZeldaGyroTranslation(this, ev) + -- c.f., drivers/input/misc/accel/bma2x2.c + local UPWARD_PORTRAIT_UP_INTERRUPT_HAPPENED = 15 + local UPWARD_PORTRAIT_DOWN_INTERRUPT_HAPPENED = 16 + local UPWARD_LANDSCAPE_LEFT_INTERRUPT_HAPPENED = 17 + local UPWARD_LANDSCAPE_RIGHT_INTERRUPT_HAPPENED = 18 + + if ev.type == C.EV_ABS and ev.code == C.ABS_PRESSURE then + if ev.value == UPWARD_PORTRAIT_UP_INTERRUPT_HAPPENED then + -- i.e., UR + ev.type = C.EV_MSC + ev.code = C.MSC_GYRO + ev.value = C.DEVICE_ROTATED_UPRIGHT + elseif ev.value == UPWARD_LANDSCAPE_LEFT_INTERRUPT_HAPPENED then + -- i.e., CW + ev.type = C.EV_MSC + ev.code = C.MSC_GYRO + ev.value = C.DEVICE_ROTATED_CLOCKWISE + elseif ev.value == UPWARD_PORTRAIT_DOWN_INTERRUPT_HAPPENED then + -- i.e., UD + ev.type = C.EV_MSC + ev.code = C.MSC_GYRO + ev.value = C.DEVICE_ROTATED_UPSIDE_DOWN + elseif ev.value == UPWARD_LANDSCAPE_RIGHT_INTERRUPT_HAPPENED then + -- i.e., CCW + ev.type = C.EV_MSC + ev.code = C.MSC_GYRO + ev.value = C.DEVICE_ROTATED_COUNTER_CLOCKWISE + end + end +end + function KindleOasis2:init() self.screen = require("ffi/framebuffer_mxcfb"):new{device = self, debug = logger.dbg} self.powerd = require("device/kindle/powerd"):new{ @@ -926,13 +1011,13 @@ function KindleOasis2:init() local rotation_mode = 0 if orientation_code then if orientation_code == "U" then - rotation_mode = self.screen.ORIENTATION_PORTRAIT + rotation_mode = self.screen.DEVICE_ROTATED_UPRIGHT elseif orientation_code == "R" then - rotation_mode = self.screen.ORIENTATION_LANDSCAPE + rotation_mode = self.screen.DEVICE_ROTATED_CLOCKWISE elseif orientation_code == "D" then - rotation_mode = self.screen.ORIENTATION_PORTRAIT_ROTATED + rotation_mode = self.screen.DEVICE_ROTATED_UPSIDE_DOWN elseif orientation_code == "L" then - rotation_mode = self.screen.ORIENTATION_LANDSCAPE_ROTATED + rotation_mode = self.screen.DEVICE_ROTATED_COUNTER_CLOCKWISE end end @@ -947,7 +1032,12 @@ function KindleOasis2:init() Kindle.init(self) - self.input:registerEventAdjustHook(self.input.adjustKindleOasisOrientation) + self.input:registerEventAdjustHook(ZeldaGyroTranslation) + self.input.handleMiscEv = function(this, ev) + if ev.code == C.MSC_GYRO then + return this:handleGyroEv(ev) + end + end self.input.open(self.touch_dev) self.input.open("/dev/input/by-path/platform-gpio-keys-event") @@ -997,13 +1087,13 @@ function KindleOasis3:init() local rotation_mode = 0 if orientation_code then if orientation_code == "U" then - rotation_mode = self.screen.ORIENTATION_PORTRAIT + rotation_mode = self.screen.DEVICE_ROTATED_UPRIGHT elseif orientation_code == "R" then - rotation_mode = self.screen.ORIENTATION_LANDSCAPE + rotation_mode = self.screen.DEVICE_ROTATED_CLOCKWISE elseif orientation_code == "D" then - rotation_mode = self.screen.ORIENTATION_PORTRAIT_ROTATED + rotation_mode = self.screen.DEVICE_ROTATED_UPSIDE_DOWN elseif orientation_code == "L" then - rotation_mode = self.screen.ORIENTATION_LANDSCAPE_ROTATED + rotation_mode = self.screen.DEVICE_ROTATED_COUNTER_CLOCKWISE end end @@ -1018,7 +1108,12 @@ function KindleOasis3:init() Kindle.init(self) - self.input:registerEventAdjustHook(self.input.adjustKindleOasisOrientation) + self.input:registerEventAdjustHook(ZeldaGyroTranslation) + self.input.handleMiscEv = function(this, ev) + if ev.code == C.MSC_GYRO then + return this:handleGyroEv(ev) + end + end self.input.open(self.touch_dev) self.input.open("/dev/input/by-path/platform-gpio-keys-event") diff --git a/frontend/device/kobo/device.lua b/frontend/device/kobo/device.lua index 78b14c3b9..2b26a84fa 100644 --- a/frontend/device/kobo/device.lua +++ b/frontend/device/kobo/device.lua @@ -378,9 +378,7 @@ local KoboFrost = Kobo:extend{ hasFrontlight = yes, hasKeys = yes, hasGSensor = yes, - canToggleGSensor = yes, touch_snow_protocol = true, - misc_ntx_gsensor_protocol = true, display_dpi = 300, hasNaturalLight = yes, frontlight_settings = { @@ -403,9 +401,7 @@ local KoboStorm = Kobo:extend{ hasFrontlight = yes, hasKeys = yes, hasGSensor = yes, - canToggleGSensor = yes, touch_snow_protocol = true, - misc_ntx_gsensor_protocol = true, display_dpi = 300, hasNaturalLight = yes, frontlight_settings = { @@ -446,9 +442,7 @@ local KoboEuropa = Kobo:extend{ led_uses_channel_3 = true, hasFrontlight = yes, hasGSensor = yes, - canToggleGSensor = yes, pressure_event = C.ABS_MT_PRESSURE, - misc_ntx_gsensor_protocol = true, display_dpi = 227, boot_rota = C.FB_ROTATE_CCW, battery_sysfs = "/sys/class/power_supply/battery", @@ -467,9 +461,7 @@ local KoboCadmus = Kobo:extend{ hasFrontlight = yes, hasKeys = yes, hasGSensor = yes, - canToggleGSensor = yes, pressure_event = C.ABS_MT_PRESSURE, - misc_ntx_gsensor_protocol = true, display_dpi = 300, hasNaturalLight = yes, frontlight_settings = { @@ -500,10 +492,8 @@ local KoboIo = Kobo:extend{ hasFrontlight = yes, hasKeys = yes, hasGSensor = yes, - canToggleGSensor = yes, pressure_event = C.ABS_MT_PRESSURE, touch_mirrored_x = false, - misc_ntx_gsensor_protocol = true, display_dpi = 300, hasNaturalLight = yes, frontlight_settings = { @@ -908,28 +898,73 @@ function Kobo:setTouchEventHandler() end -- Accelerometer - if self.misc_ntx_gsensor_protocol then - if G_reader_settings:isTrue("input_ignore_gsensor") then - self.input.isNTXAccelHooked = false - else - self.input.handleMiscEv = self.input.handleMiscEvNTX - self.input.isNTXAccelHooked = true + if self:hasGSensor() then + self.input.handleMiscEv = function(this, ev) + -- As generated by gyroTranslation below + if ev.code == C.MSC_GYRO then + return this:handleGyroEv(ev) + end end end end -function Kobo:initEventAdjustHooks() - -- NOTE: adjustTouchSwitchXY needs to be called before adjustTouchMirrorX - if self.touch_switch_xy then - self.input:registerEventAdjustHook(self.input.adjustTouchSwitchXY) +-- HAL for gyro orientation switches (NTX's EV_MSC:MSC_RAW w/ custom values to EV_MSC:MSC_GYRO w/ our own custom values) +local function gyroTranslation(ev) + -- c.f., include/uapi/linux/input.h, + -- implementations in drivers/hwmon/mma8x5x.c & drivers/input/touchscreen/kx122.c + local MSC_RAW_GSENSOR_PORTRAIT_DOWN = 0x17 + local MSC_RAW_GSENSOR_PORTRAIT_UP = 0x18 + local MSC_RAW_GSENSOR_LANDSCAPE_RIGHT = 0x19 + local MSC_RAW_GSENSOR_LANDSCAPE_LEFT = 0x1a + -- Not that we care about those, but they are reported, and accurate ;). + --[[ + local MSC_RAW_GSENSOR_BACK = 0x1b + local MSC_RAW_GSENSOR_FRONT = 0x1c + --]] + + if ev.value == MSC_RAW_GSENSOR_PORTRAIT_UP then + -- i.e., UR + ev.code = C.MSC_GYRO + ev.value = C.DEVICE_ROTATED_UPRIGHT + elseif ev.value == MSC_RAW_GSENSOR_LANDSCAPE_RIGHT then + -- i.e., CW + ev.code = C.MSC_GYRO + ev.value = C.DEVICE_ROTATED_CLOCKWISE + elseif ev.value == MSC_RAW_GSENSOR_PORTRAIT_DOWN then + -- i.e., UD + ev.code = C.MSC_GYRO + ev.value = C.DEVICE_ROTATED_UPSIDE_DOWN + elseif ev.value == MSC_RAW_GSENSOR_LANDSCAPE_LEFT then + -- i.e., CCW + ev.code = C.MSC_GYRO + ev.value = C.DEVICE_ROTATED_COUNTER_CLOCKWISE end +end - if self.touch_mirrored_x then - self.input:registerEventAdjustHook( - self.input.adjustTouchMirrorX, - --- NOTE: This is safe, we enforce the canonical portrait rotation on startup. - (self.screen:getWidth() - 1) - ) +function Kobo:initEventAdjustHooks() + -- Build a single composite hook, to avoid duplicated branches... + local koboInputMangling + -- NOTE: touch_switch_xy is *always* true, but not touch_mirrored_x... + if self.touch_switch_xy and self.touch_mirrored_x then + local max_x = self.screen:getWidth() - 1 + koboInputMangling = function(this, ev) + if ev.type == C.EV_ABS then + this:adjustABS_SwitchAxesAndMirrorX(ev, max_x) + elseif ev.type == C.EV_MSC and ev.code == C.MSC_RAW then + gyroTranslation(ev) + end + end + elseif self.touch_switch_xy and not self.touch_mirrored_x then + koboInputMangling = function(this, ev) + if ev.type == C.EV_ABS then + this:adjustABS_SwitchXY(ev) + elseif ev.type == C.EV_MSC and ev.code == C.MSC_RAW then + gyroTranslation(ev) + end + end + end + if koboInputMangling then + self.input:registerEventAdjustHook(koboInputMangling) end end @@ -1270,14 +1305,6 @@ function Kobo:reboot() os.execute("sleep 1 && reboot &") end -function Kobo:toggleGSensor(toggle) - if self:canToggleGSensor() and self.input then - if self.misc_ntx_gsensor_protocol then - self.input:toggleMiscEvNTX(toggle) - end - end -end - function Kobo:toggleChargingLED(toggle) -- We have no way of querying the current state from the HW! if toggle == nil then diff --git a/frontend/device/pocketbook/device.lua b/frontend/device/pocketbook/device.lua index 8bfe293f3..873e95e27 100644 --- a/frontend/device/pocketbook/device.lua +++ b/frontend/device/pocketbook/device.lua @@ -217,13 +217,15 @@ function PocketBook:init() -- Auto shutdown event from inkview framework, -- gracefully close everything and let the framework shutdown the device. return "Exit" + elseif ev.code == C.MSC_GYRO then + return this:handleGyroEv(ev) end end, } -- If InkView translates buttons for us, disable our own translation map if self.inkview_translates_buttons then - self.input.rotation_map = nil + self.input:disableRotationMap() end -- In contrast to kobo/kindle, pocketbook-devices do not use linux/input events directly. @@ -645,8 +647,8 @@ local PocketBookColorLux = PocketBook:extend{ canUseCBB = no, -- 24bpp } function PocketBookColorLux:_model_init() - self.screen.blitbuffer_rotation_mode = self.screen.ORIENTATION_PORTRAIT - self.screen.native_rotation_mode = self.screen.ORIENTATION_PORTRAIT + self.screen.blitbuffer_rotation_mode = self.screen.DEVICE_ROTATED_UPRIGHT + self.screen.native_rotation_mode = self.screen.DEVICE_ROTATED_UPRIGHT end function PocketBookColorLux._fb_init(fb, finfo, vinfo) -- Pocketbook Color Lux reports bits_per_pixel = 8, but actually uses an RGB24 framebuffer diff --git a/frontend/device/remarkable/device.lua b/frontend/device/remarkable/device.lua index 36d6033b7..2bb149642 100644 --- a/frontend/device/remarkable/device.lua +++ b/frontend/device/remarkable/device.lua @@ -159,7 +159,7 @@ function Remarkable:init() -- USB plug/unplug, battery charge/not charging are generated as fake events self.input.open("fake_events") - local rotation_mode = self.screen.ORIENTATION_PORTRAIT + local rotation_mode = self.screen.DEVICE_ROTATED_UPRIGHT self.screen.native_rotation_mode = rotation_mode self.screen.cur_rotation_mode = rotation_mode diff --git a/frontend/device/sdl/device.lua b/frontend/device/sdl/device.lua index 1c0fe7223..e35b5eeec 100644 --- a/frontend/device/sdl/device.lua +++ b/frontend/device/sdl/device.lua @@ -301,9 +301,8 @@ function Device:init() end if portrait then - self.input:registerEventAdjustHook(self.input.adjustTouchSwitchXY) self.input:registerEventAdjustHook( - self.input.adjustTouchMirrorX, + self.input.adjustTouchSwitchAxesAndMirrorX, (self.screen:getScreenWidth() - 1) ) end diff --git a/frontend/device/sony-prstux/device.lua b/frontend/device/sony-prstux/device.lua index 3ac97896f..b25810ce4 100644 --- a/frontend/device/sony-prstux/device.lua +++ b/frontend/device/sony-prstux/device.lua @@ -64,7 +64,7 @@ function SonyPRSTUX:init() self.input.open("fake_events") -- usb plug-in/out and charging/not-charging self.input:registerEventAdjustHook(adjustTouchEvt) - local rotation_mode = self.screen.ORIENTATION_LANDSCAPE_ROTATED + local rotation_mode = self.screen.DEVICE_ROTATED_COUNTER_CLOCKWISE self.screen.native_rotation_mode = rotation_mode self.screen.cur_rotation_mode = rotation_mode diff --git a/frontend/dispatcher.lua b/frontend/dispatcher.lua index b2c14c271..a345d4e4d 100644 --- a/frontend/dispatcher.lua +++ b/frontend/dispatcher.lua @@ -68,7 +68,7 @@ local settingsList = { toggle_no_flash_on_second_chapter_page = {category="none", event="ToggleNoFlashOnSecondChapterPage", title=_("Toggle flashing on chapter's 2nd page"), screen=true, condition=Device:hasEinkScreen(), separator=true}, -- Device settings - toggle_gsensor = {category="none", event="ToggleGSensor", title=_("Toggle accelerometer"), device=true, condition=Device:canToggleGSensor()}, + toggle_gsensor = {category="none", event="ToggleGSensor", title=_("Toggle accelerometer"), device=true, condition=Device:hasGSensor()}, wifi_on = {category="none", event="InfoWifiOn", title=_("Turn on Wi-Fi"), device=true, condition=Device:hasWifiToggle()}, wifi_off = {category="none", event="InfoWifiOff", title=_("Turn off Wi-Fi"), device=true, condition=Device:hasWifiToggle()}, toggle_wifi = {category="none", event="ToggleWifi", title=_("Toggle Wi-Fi"), device=true, condition=Device:hasWifiToggle()}, diff --git a/frontend/ui/data/creoptions.lua b/frontend/ui/data/creoptions.lua index 47820ab15..134bfe879 100644 --- a/frontend/ui/data/creoptions.lua +++ b/frontend/ui/data/creoptions.lua @@ -55,7 +55,7 @@ local CreOptions = { name = "rotation_mode", name_text = _("Rotation"), item_icons_func = function() - if Screen:getRotationMode() == Screen.ORIENTATION_PORTRAIT then + if Screen:getRotationMode() == Screen.DEVICE_ROTATED_UPRIGHT then -- P, 0UR return { "rotation.P.90CCW", @@ -63,7 +63,7 @@ local CreOptions = { "rotation.P.90CW", "rotation.P.180UD", } - elseif Screen:getRotationMode() == Screen.ORIENTATION_PORTRAIT_ROTATED then + elseif Screen:getRotationMode() == Screen.DEVICE_ROTATED_UPSIDE_DOWN then -- P, 180UD return { "rotation.P.90CW", @@ -71,7 +71,7 @@ local CreOptions = { "rotation.P.90CCW", "rotation.P.0UR", } - elseif Screen:getRotationMode() == Screen.ORIENTATION_LANDSCAPE then + elseif Screen:getRotationMode() == Screen.DEVICE_ROTATED_CLOCKWISE then -- L, 90CW return { "rotation.L.90CCW", @@ -92,8 +92,8 @@ local CreOptions = { -- For Dispatcher & onMakeDefault's sake labels = {C_("Rotation", "⤹ 90°"), C_("Rotation", "↑ 0°"), C_("Rotation", "⤸ 90°"), C_("Rotation", "↓ 180°")}, alternate = false, - values = {Screen.ORIENTATION_LANDSCAPE_ROTATED, Screen.ORIENTATION_PORTRAIT, Screen.ORIENTATION_LANDSCAPE, Screen.ORIENTATION_PORTRAIT_ROTATED}, - args = {Screen.ORIENTATION_LANDSCAPE_ROTATED, Screen.ORIENTATION_PORTRAIT, Screen.ORIENTATION_LANDSCAPE, Screen.ORIENTATION_PORTRAIT_ROTATED}, + values = {Screen.DEVICE_ROTATED_COUNTER_CLOCKWISE, Screen.DEVICE_ROTATED_UPRIGHT, Screen.DEVICE_ROTATED_CLOCKWISE, Screen.DEVICE_ROTATED_UPSIDE_DOWN}, + args = {Screen.DEVICE_ROTATED_COUNTER_CLOCKWISE, Screen.DEVICE_ROTATED_UPRIGHT, Screen.DEVICE_ROTATED_CLOCKWISE, Screen.DEVICE_ROTATED_UPSIDE_DOWN}, default_arg = 0, current_func = function() return Screen:getRotationMode() end, event = "SetRotationMode", diff --git a/frontend/ui/data/koptoptions.lua b/frontend/ui/data/koptoptions.lua index 5d06172da..9b1de454f 100644 --- a/frontend/ui/data/koptoptions.lua +++ b/frontend/ui/data/koptoptions.lua @@ -29,7 +29,7 @@ local KoptOptions = { name = "rotation_mode", name_text = _("Rotation"), item_icons_func = function() - if Screen:getRotationMode() == Screen.ORIENTATION_PORTRAIT then + if Screen:getRotationMode() == Screen.DEVICE_ROTATED_UPRIGHT then -- P, 0UR return { "rotation.P.90CCW", @@ -37,7 +37,7 @@ local KoptOptions = { "rotation.P.90CW", "rotation.P.180UD", } - elseif Screen:getRotationMode() == Screen.ORIENTATION_PORTRAIT_ROTATED then + elseif Screen:getRotationMode() == Screen.DEVICE_ROTATED_UPSIDE_DOWN then -- P, 180UD return { "rotation.P.90CW", @@ -45,7 +45,7 @@ local KoptOptions = { "rotation.P.90CCW", "rotation.P.0UR", } - elseif Screen:getRotationMode() == Screen.ORIENTATION_LANDSCAPE then + elseif Screen:getRotationMode() == Screen.DEVICE_ROTATED_CLOCKWISE then -- L, 90CW return { "rotation.L.90CCW", @@ -66,8 +66,8 @@ local KoptOptions = { -- For Dispatcher & onMakeDefault's sake labels = {C_("Rotation", "⤹ 90°"), C_("Rotation", "↑ 0°"), C_("Rotation", "⤸ 90°"), C_("Rotation", "↓ 180°")}, alternate = false, - values = {Screen.ORIENTATION_LANDSCAPE_ROTATED, Screen.ORIENTATION_PORTRAIT, Screen.ORIENTATION_LANDSCAPE, Screen.ORIENTATION_PORTRAIT_ROTATED}, - args = {Screen.ORIENTATION_LANDSCAPE_ROTATED, Screen.ORIENTATION_PORTRAIT, Screen.ORIENTATION_LANDSCAPE, Screen.ORIENTATION_PORTRAIT_ROTATED}, + values = {Screen.DEVICE_ROTATED_COUNTER_CLOCKWISE, Screen.DEVICE_ROTATED_UPRIGHT, Screen.DEVICE_ROTATED_CLOCKWISE, Screen.DEVICE_ROTATED_UPSIDE_DOWN}, + args = {Screen.DEVICE_ROTATED_COUNTER_CLOCKWISE, Screen.DEVICE_ROTATED_UPRIGHT, Screen.DEVICE_ROTATED_CLOCKWISE, Screen.DEVICE_ROTATED_UPSIDE_DOWN}, default_arg = 0, current_func = function() return Screen:getRotationMode() end, event = "SetRotationMode", diff --git a/frontend/ui/elements/screen_rotation_menu_table.lua b/frontend/ui/elements/screen_rotation_menu_table.lua index 2140a5bec..be3aa1006 100644 --- a/frontend/ui/elements/screen_rotation_menu_table.lua +++ b/frontend/ui/elements/screen_rotation_menu_table.lua @@ -11,7 +11,7 @@ return { sub_item_table_func = function() local rotation_table = {} - if Device:hasGSensor() and Device:canToggleGSensor() then + if Device:hasGSensor() then table.insert(rotation_table, { text = _("Ignore accelerometer rotation events"), help_text = _("This will inhibit automatic rotations triggered by your device's gyro."), @@ -64,84 +64,84 @@ When unchecked, the default rotation of the file browser and the default/saved r table.insert(rotation_table, { text_func = function() local text = C_("Rotation", "⤹ 90°") - if G_reader_settings:readSetting("fm_rotation_mode") == Screen.ORIENTATION_LANDSCAPE_ROTATED then + if G_reader_settings:readSetting("fm_rotation_mode") == Screen.DEVICE_ROTATED_COUNTER_CLOCKWISE then text = text .. " ★" end return text end, checked_func = function() - return Screen:getRotationMode() == Screen.ORIENTATION_LANDSCAPE_ROTATED + return Screen:getRotationMode() == Screen.DEVICE_ROTATED_COUNTER_CLOCKWISE end, radio = true, callback = function(touchmenu_instance) - UIManager:broadcastEvent(Event:new("SetRotationMode", Screen.ORIENTATION_LANDSCAPE_ROTATED)) + UIManager:broadcastEvent(Event:new("SetRotationMode", Screen.DEVICE_ROTATED_COUNTER_CLOCKWISE)) if touchmenu_instance then touchmenu_instance:closeMenu() end end, hold_callback = function(touchmenu_instance) - G_reader_settings:saveSetting("fm_rotation_mode", Screen.ORIENTATION_LANDSCAPE_ROTATED) + G_reader_settings:saveSetting("fm_rotation_mode", Screen.DEVICE_ROTATED_COUNTER_CLOCKWISE) if touchmenu_instance then touchmenu_instance:updateItems() end end, }) table.insert(rotation_table, { text_func = function() local text = C_("Rotation", "↑ 0°") - if G_reader_settings:readSetting("fm_rotation_mode") == Screen.ORIENTATION_PORTRAIT then + if G_reader_settings:readSetting("fm_rotation_mode") == Screen.DEVICE_ROTATED_UPRIGHT then text = text .. " ★" end return text end, checked_func = function() - return Screen:getRotationMode() == Screen.ORIENTATION_PORTRAIT + return Screen:getRotationMode() == Screen.DEVICE_ROTATED_UPRIGHT end, radio = true, callback = function(touchmenu_instance) - UIManager:broadcastEvent(Event:new("SetRotationMode", Screen.ORIENTATION_PORTRAIT)) + UIManager:broadcastEvent(Event:new("SetRotationMode", Screen.DEVICE_ROTATED_UPRIGHT)) if touchmenu_instance then touchmenu_instance:closeMenu() end end, hold_callback = function(touchmenu_instance) - G_reader_settings:saveSetting("fm_rotation_mode", Screen.ORIENTATION_PORTRAIT) + G_reader_settings:saveSetting("fm_rotation_mode", Screen.DEVICE_ROTATED_UPRIGHT) if touchmenu_instance then touchmenu_instance:updateItems() end end, }) table.insert(rotation_table, { text_func = function() local text = C_("Rotation", "⤸ 90°") - if G_reader_settings:readSetting("fm_rotation_mode") == Screen.ORIENTATION_LANDSCAPE then + if G_reader_settings:readSetting("fm_rotation_mode") == Screen.DEVICE_ROTATED_CLOCKWISE then text = text .. " ★" end return text end, checked_func = function() - return Screen:getRotationMode() == Screen.ORIENTATION_LANDSCAPE + return Screen:getRotationMode() == Screen.DEVICE_ROTATED_CLOCKWISE end, radio = true, callback = function(touchmenu_instance) - UIManager:broadcastEvent(Event:new("SetRotationMode", Screen.ORIENTATION_LANDSCAPE)) + UIManager:broadcastEvent(Event:new("SetRotationMode", Screen.DEVICE_ROTATED_CLOCKWISE)) if touchmenu_instance then touchmenu_instance:closeMenu() end end, hold_callback = function(touchmenu_instance) - G_reader_settings:saveSetting("fm_rotation_mode", Screen.ORIENTATION_LANDSCAPE) + G_reader_settings:saveSetting("fm_rotation_mode", Screen.DEVICE_ROTATED_CLOCKWISE) if touchmenu_instance then touchmenu_instance:updateItems() end end, }) table.insert(rotation_table, { text_func = function() local text = C_("Rotation", "↓ 180°") - if G_reader_settings:readSetting("fm_rotation_mode") == Screen.ORIENTATION_PORTRAIT_ROTATED then + if G_reader_settings:readSetting("fm_rotation_mode") == Screen.DEVICE_ROTATED_UPSIDE_DOWN then text = text .. " ★" end return text end, checked_func = function() - return Screen:getRotationMode() == Screen.ORIENTATION_PORTRAIT_ROTATED + return Screen:getRotationMode() == Screen.DEVICE_ROTATED_UPSIDE_DOWN end, radio = true, callback = function(touchmenu_instance) - UIManager:broadcastEvent(Event:new("SetRotationMode", Screen.ORIENTATION_PORTRAIT_ROTATED)) + UIManager:broadcastEvent(Event:new("SetRotationMode", Screen.DEVICE_ROTATED_UPSIDE_DOWN)) if touchmenu_instance then touchmenu_instance:closeMenu() end end, hold_callback = function(touchmenu_instance) - G_reader_settings:saveSetting("fm_rotation_mode", Screen.ORIENTATION_PORTRAIT_ROTATED) + G_reader_settings:saveSetting("fm_rotation_mode", Screen.DEVICE_ROTATED_UPSIDE_DOWN) if touchmenu_instance then touchmenu_instance:updateItems() end end, }) diff --git a/frontend/ui/screensaver.lua b/frontend/ui/screensaver.lua index c81d25aa7..ebc310d12 100644 --- a/frontend/ui/screensaver.lua +++ b/frontend/ui/screensaver.lua @@ -628,7 +628,7 @@ function Screensaver:show() -- Leave Portrait & Inverted Portrait alone, that works just fine. if bit.band(Device.orig_rotation_mode, 1) == 1 then -- i.e., only switch to Portrait if we're currently in *any* Landscape orientation (odd number) - Screen:setRotationMode(Screen.ORIENTATION_PORTRAIT) + Screen:setRotationMode(Screen.DEVICE_ROTATED_UPRIGHT) else Device.orig_rotation_mode = nil end diff --git a/spec/unit/device_spec.lua b/spec/unit/device_spec.lua index 4d15c9a1c..c9c423960 100644 --- a/spec/unit/device_spec.lua +++ b/spec/unit/device_spec.lua @@ -252,7 +252,7 @@ describe("device module", function() usec = 450565, sec = 1471081881 }, - code = 24, -- C.ABS_PRESSURE -> ABS_OASIS_ORIENTATION + code = 24, -- C.ABS_PRESSURE value = 16 } }) diff --git a/spec/unit/gesturedetector_spec.lua b/spec/unit/gesturedetector_spec.lua index e51523145..e2ce95b65 100644 --- a/spec/unit/gesturedetector_spec.lua +++ b/spec/unit/gesturedetector_spec.lua @@ -13,10 +13,10 @@ describe("gesturedetector module", function() multiswipe_directions = direction, } GestureDetector.screen = { - ORIENTATION_PORTRAIT = 0, - ORIENTATION_LANDSCAPE = 1, - ORIENTATION_PORTRAIT_ROTATED = 2, - ORIENTATION_LANDSCAPE_ROTATED = 3, + DEVICE_ROTATED_UPRIGHT = 0, + DEVICE_ROTATED_CLOCKWISE = 1, + DEVICE_ROTATED_UPSIDE_DOWN = 2, + DEVICE_ROTATED_COUNTER_CLOCKWISE = 3, } GestureDetector.screen.getTouchRotation = function() return rotation_mode end diff --git a/spec/unit/readerrolling_spec.lua b/spec/unit/readerrolling_spec.lua index a3438eb51..8843fd6f1 100644 --- a/spec/unit/readerrolling_spec.lua +++ b/spec/unit/readerrolling_spec.lua @@ -22,7 +22,7 @@ describe("Readerrolling module", function() describe("test in portrait screen mode", function() it("should goto portrait screen mode", function() - readerui:handleEvent(Event:new("SetRotationMode", Screen.ORIENTATION_PORTRAIT)) + readerui:handleEvent(Event:new("SetRotationMode", Screen.DEVICE_ROTATED_UPRIGHT)) end) it("should goto certain page", function() @@ -119,7 +119,7 @@ describe("Readerrolling module", function() describe("test in landscape screen mode", function() it("should go to landscape screen mode", function() - readerui:handleEvent(Event:new("SetRotationMode", Screen.ORIENTATION_LANDSCAPE)) + readerui:handleEvent(Event:new("SetRotationMode", Screen.DEVICE_ROTATED_CLOCKWISE)) end) it("should goto certain page", function() for i = 1, 10, 5 do @@ -167,27 +167,27 @@ describe("Readerrolling module", function() describe("switching screen mode should not change current page number", function() teardown(function() - readerui:handleEvent(Event:new("SetRotationMode", Screen.ORIENTATION_PORTRAIT)) + readerui:handleEvent(Event:new("SetRotationMode", Screen.DEVICE_ROTATED_UPRIGHT)) end) it("for portrait-landscape-portrait switching", function() for i = 80, 100, 10 do - readerui:handleEvent(Event:new("SetRotationMode", Screen.ORIENTATION_PORTRAIT)) + readerui:handleEvent(Event:new("SetRotationMode", Screen.DEVICE_ROTATED_UPRIGHT)) rolling:onGotoPage(i) assert.are.same(i, rolling.current_page) - readerui:handleEvent(Event:new("SetRotationMode", Screen.ORIENTATION_LANDSCAPE)) + readerui:handleEvent(Event:new("SetRotationMode", Screen.DEVICE_ROTATED_CLOCKWISE)) assert.are_not.same(i, rolling.current_page) - readerui:handleEvent(Event:new("SetRotationMode", Screen.ORIENTATION_PORTRAIT)) + readerui:handleEvent(Event:new("SetRotationMode", Screen.DEVICE_ROTATED_UPRIGHT)) assert.are.same(i, rolling.current_page) end end) it("for landscape-portrait-landscape switching", function() for i = 110, 130, 10 do - readerui:handleEvent(Event:new("SetRotationMode", Screen.ORIENTATION_LANDSCAPE)) + readerui:handleEvent(Event:new("SetRotationMode", Screen.DEVICE_ROTATED_CLOCKWISE)) rolling:onGotoPage(i) assert.are.same(i, rolling.current_page) - readerui:handleEvent(Event:new("SetRotationMode", Screen.ORIENTATION_PORTRAIT)) + readerui:handleEvent(Event:new("SetRotationMode", Screen.DEVICE_ROTATED_UPRIGHT)) assert.are_not.same(i, rolling.current_page) - readerui:handleEvent(Event:new("SetRotationMode", Screen.ORIENTATION_LANDSCAPE)) + readerui:handleEvent(Event:new("SetRotationMode", Screen.DEVICE_ROTATED_CLOCKWISE)) assert.are.same(i, rolling.current_page) end end) diff --git a/spec/unit/screenshoter_spec.lua b/spec/unit/screenshoter_spec.lua index 000ddb56c..ee00d8ccc 100644 --- a/spec/unit/screenshoter_spec.lua +++ b/spec/unit/screenshoter_spec.lua @@ -18,14 +18,14 @@ describe("ReaderScreenshot module", function() end) teardown(function() - readerui:handleEvent(Event:new("SetRotationMode", Screen.ORIENTATION_PORTRAIT)) + readerui:handleEvent(Event:new("SetRotationMode", Screen.DEVICE_ROTATED_UPRIGHT)) readerui:closeDocument() readerui:onClose() end) it("should get screenshot in portrait", function() local name = "screenshots/reader_screenshot_portrait.png" - readerui:handleEvent(Event:new("SetRotationMode", Screen.ORIENTATION_PORTRAIT)) + readerui:handleEvent(Event:new("SetRotationMode", Screen.DEVICE_ROTATED_UPRIGHT)) UIManager:quit() UIManager:show(readerui) UIManager:scheduleIn(1, function() @@ -41,7 +41,7 @@ describe("ReaderScreenshot module", function() it("should get screenshot in landscape", function() local name = "screenshots/reader_screenshot_landscape.png" - readerui:handleEvent(Event:new("SetRotationMode", Screen.ORIENTATION_LANDSCAPE)) + readerui:handleEvent(Event:new("SetRotationMode", Screen.DEVICE_ROTATED_CLOCKWISE)) UIManager:quit() UIManager:show(readerui) UIManager:scheduleIn(2, function()