2
0
mirror of https://github.com/koreader/koreader synced 2024-11-11 19:11:14 +00:00
koreader/frontend/device/sony-prstux/device.lua
NiLuJe 9bf19d1bb3
Assorted bag'o tweaks & fixes (#9569)
* UIManager: Support more specialized update modes for corner-cases:
  * A2, which we'll use for the VirtualKeyboards keys (they'd... inadvertently switched to UI with the highlight refactor).
  * NO_MERGE variants of ui & partial (for sunxi). Use `[ui]` in ReaderHighlight's popup, because of a Sage kernel bug that could otherwise make it translucent, sometimes completely so (*sigh*).
* UIManager: Assorted code cleanups & simplifications.
* Logger & dbg: Unify logging style, and code cleanups.
* SDL: Unbreak suspend/resume outside of the emulator (fix #9567).
* NetworkMgr: Cache the network status, and allow it to be queried. (Used by AutoSuspend to avoid repeatedly poking the system when computing the standby schedule delay).
* OneTimeMigration: Don't forget about `NETWORK_PROXY` & `STARDICT_DATA_DIR` when migrating `defaults.persistent.lua` (fix #9573)
* WakeupMgr: Workaround an apparent limitation of the RTC found on i.MX5 Kobo devices, where setting a wakealarm further than UINT16_MAX seconds in the future would apparently overflow and wraparound... (fix #8039, many thanks to @yfede for the extensive deep-dive and for actually accurately pinpointing the issue!).
* Kobo: Handle standby transitions at full CPU clock speeds, in order to limit the latency hit.
* UIManager: Properly quit on reboot & exit. This ensures our exit code is preserved, as we exit on our own terms (instead of being killed by the init system). This is important on platforms where exit codes are semantically meaningful (e.g., Kobo).
* UIManager: Speaking of reboot & exit, make sure the Screensaver shows in all circumstances (e.g., autoshutdown, re: #9542)), and that there aren't any extraneous refreshes triggered. (Additionally, fix a minor regression since #9448 about tracking this very transient state on Kobo & Cervantes).
* Kindle: ID the upcoming Scribe.
* Bump base (https://github.com/koreader/koreader-base/pull/1524)
2022-10-02 03:01:49 +02:00

258 lines
7.1 KiB
Lua

local Generic = require("device/generic/device") -- <= look at this file!
local PluginShare = require("pluginshare")
local ffi = require("ffi")
local logger = require("logger")
local C = ffi.C
require("ffi/linux_input_h")
local function yes() return true end
local function no() return false end
local SonyPRSTUX = Generic:new{
model = "Sony PRSTUX",
isSonyPRSTUX = yes,
hasKeys = yes,
hasOTAUpdates = yes,
hasWifiManager = yes,
canReboot = yes,
canPowerOff = yes,
canSuspend = yes,
usbPluggedIn = false,
home_dir = nil,
}
-- sony's driver does not inform of ID, so we overwrite the TOUCH_MAJOR
-- event to fake an ID event. a width == 0 means the finger was lifted.
-- after all events are received, we reset the counter
local next_touch_id = 0
local adjustTouchEvt = function(self, ev)
if ev.type == C.EV_ABS and ev.code == C.ABS_MT_TOUCH_MAJOR then
ev.code = C.ABS_MT_TRACKING_ID
if ev.value ~= 0 then
ev.value = next_touch_id
else
ev.value = -1
end
next_touch_id = next_touch_id + 1
logger.dbg("adjusted id: ", ev.value)
elseif ev.type == C.EV_SYN and ev.code == C.SYN_REPORT then
next_touch_id = 0
logger.dbg("reset id: ", ev.code, ev.value)
ev.code = C.SYN_MT_REPORT
elseif ev.type == C.EV_SYN and ev.code == C.SYN_MT_REPORT then
ev.code = C.SYN_REPORT
end
end
function SonyPRSTUX:init()
self.screen = require("ffi/framebuffer_mxcfb"):new{device = self, debug = logger.dbg}
self.powerd = require("device/sony-prstux/powerd"):new{device = self}
self.input = require("device/input"):new{
device = self,
event_map = require("device/sony-prstux/event_map"),
}
self.input.open("/dev/input/event0") -- Keys
self.input.open("/dev/input/event1") -- touchscreen
self.input.open("/dev/input/event2") -- power button
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
self.screen.native_rotation_mode = rotation_mode
self.screen.cur_rotation_mode = rotation_mode
Generic.init(self)
end
function SonyPRSTUX:supportsScreensaver() return true end
function SonyPRSTUX:setDateTime(year, month, day, hour, min, sec)
if hour == nil or min == nil then return true end
local command
if year and month and day then
command = string.format("date -s '%d-%d-%d %d:%d:%d'", year, month, day, hour, min, sec)
else
command = string.format("date -s '%d:%d'",hour, min)
end
if os.execute(command) == 0 then
os.execute("hwclock -u -w")
return true
else
return false
end
end
function SonyPRSTUX:intoScreenSaver()
local Screensaver = require("ui/screensaver")
if self.screen_saver_mode == false then
Screensaver:setup()
Screensaver:show()
end
self.powerd:beforeSuspend()
self.screen_saver_mode = true
end
function SonyPRSTUX:outofScreenSaver()
if self.screen_saver_mode == true then
local Screensaver = require("ui/screensaver")
Screensaver:close()
local UIManager = require("ui/uimanager")
UIManager:nextTick(function() UIManager:setDirty("all", "full") end)
end
self.powerd:afterResume()
self.screen_saver_mode = false
end
function SonyPRSTUX:suspend()
os.execute("./suspend.sh")
end
function SonyPRSTUX:resume()
os.execute("./resume.sh")
end
function SonyPRSTUX:powerOff()
os.execute("sleep 1 && poweroff &")
end
function SonyPRSTUX:reboot()
os.execute("sleep 1 && reboot &")
end
function SonyPRSTUX:usbPlugIn()
self.usb_plugged_in = true
PluginShare.pause_auto_suspend = true
end
function SonyPRSTUX:usbPlugOut()
self.usb_plugged_in = false
PluginShare.pause_auto_suspend = false
end
function SonyPRSTUX:usbPluggedIn()
return self.usb_plugged_in
end
function SonyPRSTUX:initNetworkManager(NetworkMgr)
function NetworkMgr:turnOffWifi(complete_callback)
self:releaseIP()
os.execute("./set-wifi.sh off")
if complete_callback then
complete_callback()
end
end
function NetworkMgr:turnOnWifi(complete_callback)
os.execute("./set-wifi.sh on")
self:reconnectOrShowNetworkMenu(complete_callback)
end
function NetworkMgr:getNetworkInterfaceName()
return "wlan0"
end
NetworkMgr:setWirelessBackend("wpa_supplicant", {ctrl_interface = "/var/run/wpa_supplicant/wlan0"})
function NetworkMgr:obtainIP()
self:releaseIP()
os.execute("dhclient wlan0")
end
function NetworkMgr:releaseIP()
logger.info("killing dhclient")
os.execute("dhclient -x wlan0")
end
function NetworkMgr:restoreWifiAsync()
-- os.execute("./restore-wifi-async.sh")
end
function NetworkMgr:isWifiOn()
return 0 == os.execute("wmiconfig -i wlan0 --wlan query | grep -q enabled")
end
end
function SonyPRSTUX:getSoftwareVersion()
return ffi.string("PRSTUX")
end
function SonyPRSTUX:getDeviceModel()
return ffi.string("PRS-T2")
end
function SonyPRSTUX:setEventHandlers(UIManager)
UIManager.event_handlers.Suspend = function()
self:_beforeSuspend()
self:intoScreenSaver()
self:suspend()
end
UIManager.event_handlers.Resume = function()
self:resume()
self:outofScreenSaver()
self:_afterResume()
end
UIManager.event_handlers.PowerPress = function()
UIManager:scheduleIn(2, UIManager.poweroff_action)
end
UIManager.event_handlers.PowerRelease = function()
if not UIManager._entered_poweroff_stage then
UIManager:unschedule(UIManager.poweroff_action)
-- resume if we were suspended
if self.screen_saver_mode then
UIManager.event_handlers.Resume()
else
UIManager.event_handlers.Suspend()
end
end
end
UIManager.event_handlers.Charging = function()
self:_beforeCharging()
end
UIManager.event_handlers.NotCharging = function()
self:_afterNotCharging()
end
UIManager.event_handlers.UsbPlugIn = function()
if self.screen_saver_mode then
self:resume()
self:outofScreenSaver()
self:_afterResume()
end
self:usbPlugIn()
end
UIManager.event_handlers.UsbPlugOut = function()
self:usbPlugOut()
end
UIManager.event_handlers.__default__ = function(input_event)
-- Same as in Kobo: we want to ignore keys during suspension
if not self.screen_saver_mode then
UIManager:sendEvent(input_event)
end
end
end
-- For Sony PRS-T2
local SonyPRSTUX_T2 = SonyPRSTUX:new{
isTouchDevice = yes,
hasKeys = yes,
hasFrontlight = no,
display_dpi = 166,
}
logger.info("SoftwareVersion: ", SonyPRSTUX:getSoftwareVersion())
local codename = SonyPRSTUX:getDeviceModel()
if codename == "PRS-T2" then
return SonyPRSTUX_T2
else
error("unrecognized Sony PRSTUX model " .. codename)
end