diff --git a/base b/base index ad7b25a68..9063f782f 160000 --- a/base +++ b/base @@ -1 +1 @@ -Subproject commit ad7b25a68032b9f24d24329e738c293827114965 +Subproject commit 9063f782f6d7e3068ab89e0b4b2b11f843e8302f diff --git a/frontend/apps/reader/modules/readerrolling.lua b/frontend/apps/reader/modules/readerrolling.lua index 08b221364..1190677c6 100644 --- a/frontend/apps/reader/modules/readerrolling.lua +++ b/frontend/apps/reader/modules/readerrolling.lua @@ -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() diff --git a/frontend/apps/reader/modules/readerview.lua b/frontend/apps/reader/modules/readerview.lua index d8176ab8b..37f52eadf 100644 --- a/frontend/apps/reader/modules/readerview.lua +++ b/frontend/apps/reader/modules/readerview.lua @@ -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 diff --git a/frontend/device/cervantes/powerd.lua b/frontend/device/cervantes/powerd.lua index 61e793b1b..d2fc72b06 100644 --- a/frontend/device/cervantes/powerd.lua +++ b/frontend/device/cervantes/powerd.lua @@ -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' } diff --git a/frontend/device/input.lua b/frontend/device/input.lua index bd96fe612..19c175f2d 100755 --- a/frontend/device/input.lua +++ b/frontend/device/input.lua @@ -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: diff --git a/frontend/device/kobo/device.lua b/frontend/device/kobo/device.lua index fd19a7cdc..4dbea2617 100644 --- a/frontend/device/kobo/device.lua +++ b/frontend/device/kobo/device.lua @@ -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() diff --git a/frontend/device/kobo/nickel_conf.lua b/frontend/device/kobo/nickel_conf.lua index 5bbaf3211..395d5ac90 100644 --- a/frontend/device/kobo/nickel_conf.lua +++ b/frontend/device/kobo/nickel_conf.lua @@ -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) diff --git a/frontend/device/kobo/powerd.lua b/frontend/device/kobo/powerd.lua index eb7c9ad2c..205b0f176 100644 --- a/frontend/device/kobo/powerd.lua +++ b/frontend/device/kobo/powerd.lua @@ -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() diff --git a/frontend/device/sysfs_light.lua b/frontend/device/sysfs_light.lua index 0252741ed..c1ddd2c54 100644 --- a/frontend/device/sysfs_light.lua +++ b/frontend/device/sysfs_light.lua @@ -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,29 +60,42 @@ 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 + end - white = math.max(white, 0) - red = math.max(red, 0) - green = math.max(green, 0) + 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:_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 self.current_brightness = brightness self.current_warmth = warmth diff --git a/frontend/ui/data/koptoptions.lua b/frontend/ui/data/koptoptions.lua index 13c23a82e..4ce4f67d1 100644 --- a/frontend/ui/data/koptoptions.lua +++ b/frontend/ui/data/koptoptions.lua @@ -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, } } diff --git a/frontend/ui/widget/frontlightwidget.lua b/frontend/ui/widget/frontlightwidget.lua index 94ab712b2..2a2722dea 100644 --- a/frontend/ui/widget/frontlightwidget.lua +++ b/frontend/ui/widget/frontlightwidget.lua @@ -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() diff --git a/platform/kobo/koreader.sh b/platform/kobo/koreader.sh index 96dc01417..ab0e0191d 100755 --- a/platform/kobo/koreader.sh +++ b/platform/kobo/koreader.sh @@ -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 diff --git a/platform/kobo/nickel.sh b/platform/kobo/nickel.sh index 00207bc38..883a4d4e8 100755 --- a/platform/kobo/nickel.sh +++ b/platform/kobo/nickel.sh @@ -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 diff --git a/plugins/kobolight.koplugin/main.lua b/plugins/kobolight.koplugin/main.lua index bd6206264..641e3b72f 100644 --- a/plugins/kobolight.koplugin/main.lua +++ b/plugins/kobolight.koplugin/main.lua @@ -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