mirror of
https://github.com/koreader/koreader.git
synced 2025-12-13 20:36:53 +01:00
Proper Forma support (#4414)
* Enforce a known rotation on startup, to make sure we handle touch input coordinates properly. * Proper FrontLight warmth support (thanks to @cairnsh & @pazos in #4291)! * Fix the PageTurn buttons mapping to match Nickel's defaults * Properly remap PageTurn buttons depending on the current rotation. * Actually enable the Mk.7 screen refresh codepath on *all* Mk.7 devices (I'd messed up the device check...). * Full accelerometer handling (includes a touch of refactoring regarding orientation handling in general). * Fix insidiously broken USBMS behavior in Nickel after we exit on FW >4.8. Fix #4291 Fix #3002
This commit is contained in:
2
base
2
base
Submodule base updated: ad7b25a680...9063f782f6
@@ -639,11 +639,12 @@ function ReaderRolling:onSetDimensions(dimen)
|
||||
self.ui.document:setViewDimen(Screen:getSize())
|
||||
end
|
||||
|
||||
function ReaderRolling:onChangeScreenMode(mode)
|
||||
function ReaderRolling:onChangeScreenMode(mode, rotation)
|
||||
-- We need to temporarily re-enable internal history as crengine
|
||||
-- uses it to reposition after resize
|
||||
self.ui.document:enableInternalHistory(true)
|
||||
self.ui:handleEvent(Event:new("SetScreenMode", mode))
|
||||
-- Flag it as interactive so we can properly swap to Inverted orientations (we usurp the second argument, which usually means rotation)
|
||||
self.ui:handleEvent(Event:new("SetScreenMode", mode, rotation or true))
|
||||
self.ui.document:setViewDimen(Screen:getSize())
|
||||
self:onChangeViewMode()
|
||||
self:onUpdatePos()
|
||||
|
||||
@@ -651,13 +651,39 @@ function ReaderView:restoreViewContext(ctx)
|
||||
end
|
||||
end
|
||||
|
||||
function ReaderView:onSetScreenMode(new_mode, rotation)
|
||||
-- NOTE: This is just a shim for koptoptions, because we want to be able to pass an optional second argument to SetScreenMode...
|
||||
-- This is also used as a sink for gsensor input events, because we can only send a single event per input,
|
||||
-- and we need to cover both CRe & KOpt...
|
||||
function ReaderView:onSwapScreenMode(new_mode, rotation)
|
||||
-- Don't do anything if an explicit rotation was requested, but it hasn't actually changed,
|
||||
-- because we may be sending this event *right before* a ChangeScreenMode in CRe (gyro)
|
||||
if rotation ~= nil and rotation ~= true and rotation == Screen:getRotationMode() then
|
||||
return true
|
||||
end
|
||||
-- CRe
|
||||
self.ui:handleEvent(Event:new("ChangeScreenMode", new_mode, rotation or true))
|
||||
-- KOpt (On CRe, since it's redundant (RR:onChangeScreenMode already sends one), this'll get discarded early)
|
||||
self.ui:handleEvent(Event:new("SetScreenMode", new_mode, rotation or true))
|
||||
end
|
||||
|
||||
function ReaderView:onSetScreenMode(new_mode, rotation, noskip)
|
||||
-- Don't do anything if an explicit rotation was requested, but it hasn't actually changed,
|
||||
-- because we may be sending this event *right after* a ChangeScreenMode in CRe (gsensor)
|
||||
-- We only want to let the onReadSettings one go through, otherwise the testsuite blows up...
|
||||
if noskip == nil and rotation ~= nil and rotation ~= true and rotation == Screen:getRotationMode() then
|
||||
return true
|
||||
end
|
||||
if new_mode == "landscape" or new_mode == "portrait" then
|
||||
self.screen_mode = new_mode
|
||||
if rotation ~= nil then
|
||||
-- NOTE: Hacky hack! If rotation is "true", that's actually an "interactive" flag for setScreenMode
|
||||
-- FIXME: That's because we can't store nils in a table, which is what Event:new attempts to do ;).
|
||||
-- c.f., https://stackoverflow.com/q/7183998/ & http://lua-users.org/wiki/VarargTheSecondClassCitizen
|
||||
-- With a fixed Event implementation, we'd instead stick "interactive" in a third argument,
|
||||
-- which we could happily pass while still keeping rotation nil ;).
|
||||
if rotation ~= nil and rotation ~= true then
|
||||
Screen:setRotationMode(rotation)
|
||||
else
|
||||
Screen:setScreenMode(new_mode)
|
||||
Screen:setScreenMode(new_mode, rotation)
|
||||
end
|
||||
UIManager:setDirty(self.dialog, "full")
|
||||
local new_screen_size = Screen:getSize()
|
||||
@@ -665,7 +691,7 @@ function ReaderView:onSetScreenMode(new_mode, rotation)
|
||||
self.ui:onScreenResize(new_screen_size)
|
||||
self.ui:handleEvent(Event:new("InitScrollPageStates"))
|
||||
end
|
||||
self.cur_rotation_mode = Screen.cur_rotation_mode
|
||||
self.cur_rotation_mode = Screen:getRotationMode()
|
||||
return true
|
||||
end
|
||||
|
||||
@@ -704,7 +730,7 @@ function ReaderView:onReadSettings(config)
|
||||
end
|
||||
if screen_mode then
|
||||
Screen:setScreenMode(screen_mode)
|
||||
self:onSetScreenMode(screen_mode, config:readSetting("rotation_mode"))
|
||||
self:onSetScreenMode(screen_mode, config:readSetting("rotation_mode"), true)
|
||||
end
|
||||
self.state.gamma = config:readSetting("gamma") or DGLOBALGAMMA
|
||||
local full_screen = config:readSetting("kopt_full_screen") or self.document.configurable.full_screen
|
||||
|
||||
@@ -12,6 +12,8 @@ local CervantesPowerD = BasePowerD:new{
|
||||
|
||||
fl_min = 0,
|
||||
fl_max = 100,
|
||||
fl_warmth_min = 0,
|
||||
fl_warmth_max = 100,
|
||||
capacity_file = battery_sysfs .. 'capacity',
|
||||
status_file = battery_sysfs .. 'status'
|
||||
}
|
||||
|
||||
@@ -61,6 +61,18 @@ local DEVICE_ORIENTATION_PORTRAIT_ROTATED = 20
|
||||
local DEVICE_ORIENTATION_LANDSCAPE = 21
|
||||
local DEVICE_ORIENTATION_LANDSCAPE_ROTATED = 22
|
||||
|
||||
-- For the events of the Forma accelerometer (MSC.code)
|
||||
local MSC_RAW = 0x03
|
||||
|
||||
-- For the events of the Forma accelerometer (MSC.value)
|
||||
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
|
||||
|
||||
-- luacheck: pop
|
||||
|
||||
local Input = {
|
||||
@@ -102,11 +114,12 @@ local Input = {
|
||||
},
|
||||
},
|
||||
|
||||
-- NOTE: When looking at the device in Portrait mode, that's assuming PgBack is on TOP, and PgFwd on the BOTTOM
|
||||
rotation_map = {
|
||||
[framebuffer.ORIENTATION_PORTRAIT] = {},
|
||||
[framebuffer.ORIENTATION_LANDSCAPE] = { Up = "Right", Right = "Down", Down = "Left", Left = "Up" },
|
||||
[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" , LPgFwd = "LPgBack", LPgBack = "LPgFwd", RPgFwd = "RPgBack", RPgBack = "RPgFwd" }
|
||||
[framebuffer.ORIENTATION_LANDSCAPE_ROTATED] = { Up = "Left", Right = "Up", Down = "Right", Left = "Down" }
|
||||
},
|
||||
|
||||
timer_callbacks = {},
|
||||
@@ -601,6 +614,51 @@ function Input:handleOasisOrientationEv(ev)
|
||||
end
|
||||
end
|
||||
|
||||
-- Accelerometer on the Forma, c.f., drivers/hwmon/mma8x5x.c
|
||||
function Input:handleMiscEvNTX(ev)
|
||||
local rotation_mode, screen_mode
|
||||
if ev.code == 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
|
||||
else
|
||||
-- Discard unhandled event codes, just to future-proof this ;).
|
||||
return
|
||||
end
|
||||
|
||||
local old_rotation_mode = self.device.screen:getRotationMode()
|
||||
local old_screen_mode = self.device.screen:getScreenMode()
|
||||
-- NOTE: Try to handle ScreenMode changes sanely, without wrecking the FM, which only supports Portrait/Inverted ;).
|
||||
-- NOTE: See the Oasis version just above us for a variant that's locked to the current ScreenMode.
|
||||
-- Might be nice to expose the two behaviors to the user, somehow?
|
||||
if rotation_mode ~= old_rotation_mode then
|
||||
if screen_mode ~= old_screen_mode then
|
||||
return Event:new("SwapScreenMode", screen_mode, rotation_mode)
|
||||
else
|
||||
self.device.screen:setRotationMode(rotation_mode)
|
||||
local UIManager = require("ui/uimanager")
|
||||
UIManager:onRotation()
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
-- helpers for touch event data management:
|
||||
|
||||
|
||||
@@ -130,7 +130,7 @@ local KoboSnow = Kobo:new{
|
||||
-- Kobo Aura H2O2, Rev2:
|
||||
-- FIXME: Check if the Clara fix actually helps here... (#4015)
|
||||
local KoboSnowRev2 = Kobo:new{
|
||||
model = "Kobo_snow",
|
||||
model = "Kobo_snow_r2",
|
||||
hasFrontlight = yes,
|
||||
touch_snow_protocol = true,
|
||||
display_dpi = 265,
|
||||
@@ -157,7 +157,7 @@ local KoboStar = Kobo:new{
|
||||
-- Kobo Aura second edition, Rev 2:
|
||||
-- FIXME: Confirm that this is accurate? If it is, and matches the Rev1, ditch the special casing.
|
||||
local KoboStarRev2 = Kobo:new{
|
||||
model = "Kobo_star",
|
||||
model = "Kobo_star_r2",
|
||||
hasFrontlight = yes,
|
||||
touch_probe_ev_epoch_time = true,
|
||||
touch_phoenix_protocol = true,
|
||||
@@ -199,24 +199,27 @@ local KoboNova = Kobo:new{
|
||||
}
|
||||
|
||||
-- Kobo Forma:
|
||||
-- FIXME: Will need initial rotation trickery like the Kindle Oasis, startup HW rota available via self.screen.fb_rota
|
||||
-- In the meantime, start KOReader with the Forma in Upright Portrait mode in order to have working touch input.
|
||||
-- (That's Portrait with the buttons on the right).
|
||||
-- c.f., #4291
|
||||
-- FIXME: FrontLight/NaturalLight is untested
|
||||
-- FIXME: touch_probe_ev_epoch_time is possibly unneeded
|
||||
-- NOTE: Right now, we enforce Portrait orientation on startup to avoid getting touch coordinates wrong,
|
||||
-- no matter the rotation we were started from (c.f., platform/kobo/koreader.sh).
|
||||
-- NOTE: For the FL, assume brightness is WO, and actual_brightness is RO!
|
||||
-- i.e., we could have a real KoboPowerD:frontlightIntensityHW() by reading actual_brightness ;).
|
||||
local KoboFrost = Kobo:new{
|
||||
model = "Kobo_frost",
|
||||
hasFrontlight = yes,
|
||||
hasKeys = yes,
|
||||
touch_probe_ev_epoch_time = true,
|
||||
touch_snow_protocol = true,
|
||||
misc_ntx_gsensor_protocol = true,
|
||||
display_dpi = 300,
|
||||
hasNaturalLight = yes,
|
||||
frontlight_settings = {
|
||||
frontlight_white = "/sys/class/backlight/mxc_msp430.0",
|
||||
frontlight_red = "/sys/class/backlight/tlc5947_bl",
|
||||
}
|
||||
frontlight_white = "/sys/class/backlight/mxc_msp430.0/brightness",
|
||||
frontlight_mixer = "/sys/class/backlight/tlc5947_bl/color",
|
||||
-- Warmth goes from 0 to 10 on the device's side (our own internal scale is still normalized to [0...100])
|
||||
-- NOTE: Those three extra keys are *MANDATORY* if frontlight_mixer is set!
|
||||
nl_min = 0,
|
||||
nl_max = 10,
|
||||
nl_inverted = true,
|
||||
},
|
||||
}
|
||||
|
||||
function Kobo:init()
|
||||
@@ -234,6 +237,7 @@ function Kobo:init()
|
||||
self.hasBGRFrameBuffer = no
|
||||
end
|
||||
self.powerd = require("device/kobo/powerd"):new{device = self}
|
||||
-- NOTE: For the Forma, with the buttons on the right, 193 is Top, 194 Bottom.
|
||||
self.input = require("device/input"):new{
|
||||
device = self,
|
||||
event_map = {
|
||||
@@ -241,8 +245,8 @@ function Kobo:init()
|
||||
[90] = "LightButton",
|
||||
[102] = "Home",
|
||||
[116] = "Power",
|
||||
[194] = "RPgBack",
|
||||
[193] = "RPgFwd",
|
||||
[193] = "RPgBack",
|
||||
[194] = "RPgFwd",
|
||||
},
|
||||
event_map_adapter = {
|
||||
SleepCover = function(ev)
|
||||
@@ -262,8 +266,8 @@ function Kobo:init()
|
||||
|
||||
Generic.init(self)
|
||||
|
||||
-- event2 is for MMA7660 sensor (3-Axis Orientation/Motion Detection)
|
||||
self.input.open("/dev/input/event0") -- Light button and sleep slider
|
||||
-- When present, event2 is the raw accelerometer data (3-Axis Orientation/Motion Detection)
|
||||
self.input.open("/dev/input/event0") -- Various HW Buttons, Switches & Synthetic NTX events
|
||||
self.input.open("/dev/input/event1")
|
||||
-- fake_events is only used for usb plug event so far
|
||||
-- NOTE: usb hotplug event is also available in /tmp/nickel-hardware-status
|
||||
@@ -392,7 +396,7 @@ function Kobo:initEventAdjustHooks()
|
||||
if self.touch_mirrored_x then
|
||||
self.input:registerEventAdjustHook(
|
||||
self.input.adjustTouchMirrorX,
|
||||
-- FIXME: what if we change the screen protrait mode?
|
||||
-- FIXME: what if we change the screen portrait mode?
|
||||
self.screen:getWidth()
|
||||
)
|
||||
end
|
||||
@@ -414,6 +418,11 @@ function Kobo:initEventAdjustHooks()
|
||||
if self.touch_phoenix_protocol then
|
||||
self.input.handleTouchEv = self.input.handleTouchEvPhoenix
|
||||
end
|
||||
|
||||
-- Accelerometer on the Forma
|
||||
if self.misc_ntx_gsensor_protocol then
|
||||
self.input.handleMiscEv = self.input.handleMiscEvNTX
|
||||
end
|
||||
end
|
||||
|
||||
function Kobo:getCodeName()
|
||||
|
||||
@@ -181,13 +181,13 @@ function NickelConf.autoColorEnabled.set(new_autocolor)
|
||||
end
|
||||
|
||||
dbg:guard(NickelConf.colorSetting, 'set',
|
||||
function(self, new_color)
|
||||
function(new_color)
|
||||
assert(new_color >= 1500 and new_color <= 6400,
|
||||
"Wrong colorSetting value given!")
|
||||
end)
|
||||
|
||||
dbg:guard(NickelConf.autoColorEnabled, 'set',
|
||||
function(self, new_autocolor)
|
||||
function(new_autocolor)
|
||||
assert(type(new_autocolor) == "boolean",
|
||||
"Wrong type for autocolor (expected boolean)!")
|
||||
end)
|
||||
|
||||
@@ -17,6 +17,7 @@ local KoboPowerD = BasePowerD:new{
|
||||
|
||||
batt_capacity_file = batt_state_folder .. "capacity",
|
||||
is_charging_file = batt_state_folder .. "status",
|
||||
fl_warmth_min = 0, fl_warmth_max = 100,
|
||||
fl_warmth = nil,
|
||||
auto_warmth = false,
|
||||
max_warmth_hour = 23,
|
||||
@@ -42,8 +43,9 @@ function KoboPowerD:_syncKoboLightOnStart()
|
||||
if self.fl_warmth ~= nil then
|
||||
local new_color = NickelConf.colorSetting.get()
|
||||
if new_color ~= nil then
|
||||
-- ColorSetting is in [1500,6400], with '1500'
|
||||
-- being maximum warmth, so normalize this to [0,100]
|
||||
-- ColorSetting is stored as a color temperature scale in Kelvin,
|
||||
-- from 1500 to 6400
|
||||
-- so normalize this to [0,100] on our end.
|
||||
new_warmth = (100 - math.floor((new_color - 1500) / 49))
|
||||
end
|
||||
auto_warmth = NickelConf.autoColorEnabled.get()
|
||||
@@ -111,8 +113,10 @@ function KoboPowerD:init()
|
||||
self.autowarmth_job_running = false
|
||||
|
||||
if self.device.hasFrontlight() then
|
||||
-- If this device has natural light (currently only KA1)
|
||||
-- use the SysFS interface, and ioctl otherwise.
|
||||
-- If this device has natural light (currently only KA1 & Forma)
|
||||
-- Use the SysFS interface, and ioctl otherwise.
|
||||
-- NOTE: On the Forma, nickel still appears to prefer using ntx_io to handle the FL,
|
||||
-- but it does use sysfs for the NL...
|
||||
if self.device.hasNaturalLight() then
|
||||
local nl_config = G_reader_settings:readSetting("natural_light_config")
|
||||
if nl_config then
|
||||
@@ -120,6 +124,9 @@ function KoboPowerD:init()
|
||||
self.device.frontlight_settings[key] = val
|
||||
end
|
||||
end
|
||||
-- Does this device's NaturalLight use a custom scale?
|
||||
self.fl_warmth_min = self.device.frontlight_settings["nl_min"] or self.fl_warmth_min
|
||||
self.fl_warmth_max = self.device.frontlight_settings["nl_max"] or self.fl_warmth_max
|
||||
self.fl = SysfsLight:new(self.device.frontlight_settings)
|
||||
self.fl_warmth = 0
|
||||
self:_syncKoboLightOnStart()
|
||||
|
||||
@@ -9,6 +9,10 @@ local SysfsLight = {
|
||||
frontlight_white = nil,
|
||||
frontlight_red = nil,
|
||||
frontlight_green = nil,
|
||||
frontlight_mixer = nil,
|
||||
nl_min = nil,
|
||||
nl_max = nil,
|
||||
nl_inverted = nil,
|
||||
current_brightness = 0,
|
||||
current_warmth = 0,
|
||||
white_gain = 25,
|
||||
@@ -56,30 +60,43 @@ function SysfsLight:setNaturalBrightness(brightness, warmth)
|
||||
warmth = self.current_warmth
|
||||
end
|
||||
|
||||
local red = 0
|
||||
local green = 0
|
||||
local white = 0
|
||||
if brightness > 0 then
|
||||
-- On Nickel, the values for white/red/green are roughly linearly dependent
|
||||
-- on the 4th root of brightness and warmth.
|
||||
white = math.min(self.white_gain * math.pow(brightness, self.exponent) *
|
||||
-- Newer devices use a mixer instead of writting values per color.
|
||||
if self.frontlight_mixer then
|
||||
-- Honor the device's scale, which may not be [0...100] (f.g., it's [0...10] on the Forma) ;).
|
||||
warmth = math.floor(warmth / self.nl_max)
|
||||
self:_write_value(self.frontlight_white, brightness)
|
||||
-- And it may be inverted... (cold is nl_max, warm is nl_min)
|
||||
if self.nl_inverted then
|
||||
self:_write_value(self.frontlight_mixer, self.nl_max - warmth)
|
||||
else
|
||||
self:_write_value(self.frontlight_mixer, warmth)
|
||||
end
|
||||
else
|
||||
local red = 0
|
||||
local green = 0
|
||||
local white = 0
|
||||
if brightness > 0 then
|
||||
-- On Nickel, the values for white/red/green are roughly linearly dependent
|
||||
-- on the 4th root of brightness and warmth.
|
||||
white = math.min(self.white_gain * math.pow(brightness, self.exponent) *
|
||||
math.pow(100 - warmth, self.exponent) + self.white_offset, 255)
|
||||
end
|
||||
if warmth > 0 then
|
||||
red = math.min(self.red_gain * math.pow(brightness, self.exponent) *
|
||||
end
|
||||
if warmth > 0 then
|
||||
red = math.min(self.red_gain * math.pow(brightness, self.exponent) *
|
||||
math.pow(warmth, self.exponent) + self.red_offset, 255)
|
||||
green = math.min(self.green_gain * math.pow(brightness, self.exponent) *
|
||||
green = math.min(self.green_gain * math.pow(brightness, self.exponent) *
|
||||
math.pow(warmth, self.exponent) + self.green_offset, 255)
|
||||
end
|
||||
|
||||
white = math.max(white, 0)
|
||||
red = math.max(red, 0)
|
||||
green = math.max(green, 0)
|
||||
|
||||
self:_set_light_value(self.frontlight_white, math.floor(white))
|
||||
self:_set_light_value(self.frontlight_green, math.floor(green))
|
||||
self:_set_light_value(self.frontlight_red, math.floor(red))
|
||||
end
|
||||
|
||||
white = math.max(white, 0)
|
||||
red = math.max(red, 0)
|
||||
green = math.max(green, 0)
|
||||
|
||||
self:_set_light_value(self.frontlight_white, math.floor(white))
|
||||
self:_set_light_value(self.frontlight_green, math.floor(green))
|
||||
self:_set_light_value(self.frontlight_red, math.floor(red))
|
||||
|
||||
self.current_brightness = brightness
|
||||
self.current_warmth = warmth
|
||||
end
|
||||
|
||||
@@ -17,7 +17,7 @@ local KoptOptions = {
|
||||
args = {"portrait", "landscape"},
|
||||
default_arg = "portrait",
|
||||
current_func = function() return Screen:getScreenMode() end,
|
||||
event = "SetScreenMode",
|
||||
event = "SwapScreenMode",
|
||||
name_text_hold_callback = optionsutil.showValues,
|
||||
}
|
||||
}
|
||||
|
||||
@@ -51,8 +51,15 @@ function FrontLightWidget:init()
|
||||
if (self.steps - 1) * self.one_step < self.fl_max - self.fl_min then
|
||||
self.steps = self.steps + 1
|
||||
end
|
||||
self.steps = math.min(self.steps , steps_fl)
|
||||
self.steps = math.min(self.steps, steps_fl)
|
||||
self.natural_light = (Device:isCervantes() or Device:isKobo()) and Device:hasNaturalLight()
|
||||
-- Handle Warmth separately, because it may use a different scale
|
||||
if self.natural_light then
|
||||
self.nl_min = self.powerd.fl_warmth_min
|
||||
self.nl_max = self.powerd.fl_warmth_max
|
||||
-- NOTE: fl_warmth is always [0...100] even when internal scale is [0...10]
|
||||
self.nl_scale = (100 / self.nl_max)
|
||||
end
|
||||
|
||||
-- button width to fit screen size
|
||||
local button_margin = Size.margin.tiny
|
||||
@@ -237,17 +244,17 @@ function FrontLightWidget:setProgress(num, step, num_warmth)
|
||||
if self.natural_light then
|
||||
-- Only insert 'brightness' caption if we also add 'warmth'
|
||||
-- widgets below.
|
||||
table.insert(vertical_group,text_br)
|
||||
table.insert(vertical_group, text_br)
|
||||
end
|
||||
table.insert(button_group_up, button_table_up)
|
||||
table.insert(button_group_down, button_table_down)
|
||||
table.insert(vertical_group,padding_span)
|
||||
table.insert(vertical_group,button_group_up)
|
||||
table.insert(vertical_group,padding_span)
|
||||
table.insert(vertical_group,fl_group)
|
||||
table.insert(vertical_group,padding_span)
|
||||
table.insert(vertical_group,button_group_down)
|
||||
table.insert(vertical_group,padding_span)
|
||||
table.insert(vertical_group, padding_span)
|
||||
table.insert(vertical_group, button_group_up)
|
||||
table.insert(vertical_group, padding_span)
|
||||
table.insert(vertical_group, fl_group)
|
||||
table.insert(vertical_group, padding_span)
|
||||
table.insert(vertical_group, button_group_down)
|
||||
table.insert(vertical_group, padding_span)
|
||||
if self.natural_light then
|
||||
-- If the device supports natural light, add the widgets for 'warmth'
|
||||
-- and a 'Configure' button
|
||||
@@ -294,8 +301,8 @@ function FrontLightWidget:addWarmthWidgets(num_warmth, step, vertical_group)
|
||||
enable_button_minus = false
|
||||
button_color = Blitbuffer.COLOR_GREY
|
||||
else
|
||||
if num_warmth == self.fl_max then enable_button_plus = false end
|
||||
if num_warmth == self.fl_min then enable_button_minus = false end
|
||||
if math.floor(num_warmth / self.nl_scale) <= self.nl_min then enable_button_minus = false end
|
||||
if math.ceil(num_warmth / self.nl_scale) >= self.nl_max then enable_button_plus = false end
|
||||
end
|
||||
|
||||
if self.natural_light and num_warmth then
|
||||
@@ -330,22 +337,22 @@ function FrontLightWidget:addWarmthWidgets(num_warmth, step, vertical_group)
|
||||
width = self.screen_width * 0.95
|
||||
}
|
||||
local button_minus = Button:new{
|
||||
text = "-1",
|
||||
text = "-" .. (1 * self.nl_scale),
|
||||
margin = Size.margin.small,
|
||||
radius = 0,
|
||||
enabled = enable_button_minus,
|
||||
width = self.screen_width * 0.20,
|
||||
show_parent = self,
|
||||
callback = function() self:setProgress(self.fl_cur, step, num_warmth - 1) end,
|
||||
callback = function() self:setProgress(self.fl_cur, step, (num_warmth - (1 * self.nl_scale))) end,
|
||||
}
|
||||
local button_plus = Button:new{
|
||||
text = "+1",
|
||||
text = "+" .. (1 * self.nl_scale),
|
||||
margin = Size.margin.small,
|
||||
radius = 0,
|
||||
enabled = enable_button_plus,
|
||||
width = self.screen_width * 0.20,
|
||||
show_parent = self,
|
||||
callback = function() self:setProgress(self.fl_cur, step, num_warmth + 1) end,
|
||||
callback = function() self:setProgress(self.fl_cur, step, (num_warmth + (1 * self.nl_scale))) end,
|
||||
}
|
||||
local item_level = TextBoxWidget:new{
|
||||
text = num_warmth,
|
||||
@@ -360,7 +367,7 @@ function FrontLightWidget:addWarmthWidgets(num_warmth, step, vertical_group)
|
||||
enabled = not self.powerd.auto_warmth,
|
||||
width = self.screen_width * 0.20,
|
||||
show_parent = self,
|
||||
callback = function() self:setProgress(self.fl_cur, step, self.fl_min) end,
|
||||
callback = function() self:setProgress(self.fl_cur, step, self.nl_min) end,
|
||||
}
|
||||
local button_max = Button:new{
|
||||
text = _("Max"),
|
||||
@@ -369,7 +376,7 @@ function FrontLightWidget:addWarmthWidgets(num_warmth, step, vertical_group)
|
||||
enabled = not self.powerd.auto_warmth,
|
||||
width = self.screen_width * 0.20,
|
||||
show_parent = self,
|
||||
callback = function() self:setProgress(self.fl_cur, step, self.fl_max) end,
|
||||
callback = function() self:setProgress(self.fl_cur, step, (self.nl_max * self.nl_scale)) end,
|
||||
}
|
||||
local empty_space = HorizontalSpan:new{
|
||||
width = (self.screen_width * 0.95 - 1.2 * button_minus.width - 1.2 * button_plus.width) / 2,
|
||||
@@ -459,7 +466,7 @@ function FrontLightWidget:addWarmthWidgets(num_warmth, step, vertical_group)
|
||||
end,
|
||||
}
|
||||
|
||||
table.insert(vertical_group,text_warmth)
|
||||
table.insert(vertical_group, text_warmth)
|
||||
table.insert(button_group_up, button_table_up)
|
||||
table.insert(button_group_down, button_table_down)
|
||||
table.insert(auto_nl_group, checkbutton_auto_nl)
|
||||
@@ -468,14 +475,14 @@ function FrontLightWidget:addWarmthWidgets(num_warmth, step, vertical_group)
|
||||
table.insert(auto_nl_group, text_hour)
|
||||
table.insert(auto_nl_group, button_plus_one_hour)
|
||||
|
||||
table.insert(vertical_group,padding_span)
|
||||
table.insert(vertical_group,button_group_up)
|
||||
table.insert(vertical_group,padding_span)
|
||||
table.insert(vertical_group,warmth_group)
|
||||
table.insert(vertical_group,padding_span)
|
||||
table.insert(vertical_group,button_group_down)
|
||||
table.insert(vertical_group,padding_span)
|
||||
table.insert(vertical_group,auto_nl_group)
|
||||
table.insert(vertical_group, padding_span)
|
||||
table.insert(vertical_group, button_group_up)
|
||||
table.insert(vertical_group, padding_span)
|
||||
table.insert(vertical_group, warmth_group)
|
||||
table.insert(vertical_group, padding_span)
|
||||
table.insert(vertical_group, button_group_down)
|
||||
table.insert(vertical_group, padding_span)
|
||||
table.insert(vertical_group, auto_nl_group)
|
||||
end
|
||||
|
||||
function FrontLightWidget:update()
|
||||
|
||||
@@ -97,7 +97,7 @@ if [ "${FROM_NICKEL}" = "true" ]; then
|
||||
sync
|
||||
# stop kobo software because it's running
|
||||
# NOTE: We don't need to kill KFMon, it's smart enough not to allow running anything else while we're up
|
||||
killall nickel hindenburg sickel fickel fmon 2>/dev/null
|
||||
killall -TERM nickel hindenburg sickel fickel fmon 2>/dev/null
|
||||
fi
|
||||
|
||||
# fallback for old fmon, KFMon and advboot users (-> if no args were passed to the script, start the FM)
|
||||
@@ -135,6 +135,22 @@ if [ ! -n "${INTERFACE}" ]; then
|
||||
fi
|
||||
# end of value check of PLATFORM
|
||||
|
||||
# If we're on a Forma, make sure we start in an orientation we know how to handle (i.e., Portrait, buttons on the Right)
|
||||
# Because NTX likes mounting panels in weird native rotations, this is actually FB_ROTATE_CCW (3).
|
||||
# And because shit gets even weirder, we have to echo 1 to get 3 (possibly because 2 is the native rotation, and 3 ^ 2 = 1).
|
||||
if [ "${PRODUCT}" = "frost" ]; then
|
||||
# Only mess with this if we were started from Nickel
|
||||
if [ "${FROM_NICKEL}" = "true" ]; then
|
||||
# Don't do anything if we're already in the right orientation.
|
||||
if [ "$(cat /sys/class/graphics/fb0/rotate)" -ne "3" ]; then
|
||||
echo 1 >/sys/class/graphics/fb0/rotate
|
||||
# Sleep a bit, for good measure
|
||||
usleep 250000
|
||||
fi
|
||||
fi
|
||||
fi
|
||||
# NOTE: We don't have to restore anything on exit, nickel's startup process will take care of everything (pickel -> nickel).
|
||||
|
||||
# Remount the SD card RW if it's inserted and currently RO
|
||||
if awk '$4~/(^|,)ro($|,)/' /proc/mounts | grep ' /mnt/sd '; then
|
||||
mount -o remount,rw /mnt/sd
|
||||
|
||||
@@ -6,6 +6,11 @@ PATH="/sbin:/bin:/usr/sbin:/usr/bin:/usr/lib:"
|
||||
# NOTE: LD_LIBRARY_PATH is the only late export from rcS we don't siphon in koreader.sh, for obvious reasons ;).
|
||||
export LD_LIBRARY_PATH="/usr/local/Kobo"
|
||||
|
||||
# Reset PWD, and clear up our own custom stuff from the env while we're there, otherwise, USBMS may become very wonky on newer FW...
|
||||
# shellcheck disable=SC2164
|
||||
cd /
|
||||
unset OLDPWD EXT_FONT_DIR TESSDATA_PREFIX FROM_NICKEL STARDICT_DATA_DIR LC_ALL
|
||||
|
||||
# Ensures fmon will restart. Note that we don't have to worry about reaping this, nickel kills on-animator.sh on start.
|
||||
(
|
||||
if [ "${PLATFORM}" = "freescale" ] || [ "${PLATFORM}" = "mx50-ntx" ] || [ "${PLATFORM}" = "mx6sl-ntx" ]; then
|
||||
@@ -35,9 +40,10 @@ sync
|
||||
|
||||
# And finally, simply restart nickel.
|
||||
# We don't care about horribly legacy stuff, because if people switch between nickel and KOReader in the first place, I assume they're using a decently recent enough FW version.
|
||||
# Last tested on an H2O running FW 4.7.x - 4.8.x
|
||||
# Last tested on an H2O & a Forma running FW 4.7.x - 4.12.x
|
||||
/usr/local/Kobo/hindenburg &
|
||||
LIBC_FATAL_STDERR_=1 /usr/local/Kobo/nickel -platform kobo -skipFontLoad &
|
||||
udevadm trigger &
|
||||
|
||||
# Handle sdcard
|
||||
if [ -e "/dev/mmcblk1p1" ]; then
|
||||
|
||||
@@ -169,8 +169,8 @@ function KoboLight:onSwipe(_, ges)
|
||||
return false -- don't consume swipe event if it's not matched
|
||||
end
|
||||
|
||||
-- when new_intensity <=0, toggle light off
|
||||
if new_intensity <=0 then
|
||||
-- when new_intensity <= 0, toggle light off
|
||||
if new_intensity <= 0 then
|
||||
if powerd.is_fl_on then
|
||||
powerd:toggleFrontlight()
|
||||
end
|
||||
|
||||
Reference in New Issue
Block a user