diff --git a/einkfb.c b/einkfb.c index 77cb5c867..4abb81b23 100644 --- a/einkfb.c +++ b/einkfb.c @@ -180,6 +180,29 @@ static int einkUpdate(lua_State *L) { return 0; } +/* NOTICE!!! You must close and reopen framebuffer after called this method. + * Otherwise, screen resolution will not be updated! */ +static int einkSetOrientation(lua_State *L) { +#ifndef EMULATE_READER + FBInfo *fb = (FBInfo*) luaL_checkudata(L, 1, "einkfb"); + int mode = luaL_optint(L, 2, 0); + + if (mode < 0 || mode > 3) { + return luaL_error(L, "Wrong rotation mode %d given!", mode); + } + + /* ioctl has a different definition for rotation mode. */ + if (mode == 1) + mode = 2; + else if (mode == 2) + mode = 1; + + ioctl(fb->fd, FBIO_EINK_SET_DISPLAY_ORIENTATION, mode); +#endif + return 0; +} + + static const struct luaL_reg einkfb_func[] = { {"open", openFrameBuffer}, {NULL, NULL} @@ -189,6 +212,7 @@ static const struct luaL_reg einkfb_meth[] = { {"close", closeFrameBuffer}, {"__gc", closeFrameBuffer}, {"refresh", einkUpdate}, + {"setOrientation", einkSetOrientation}, {"getSize", getSize}, {NULL, NULL} }; diff --git a/filechooser.lua b/filechooser.lua index c70b12613..865a0147f 100644 --- a/filechooser.lua +++ b/filechooser.lua @@ -200,11 +200,19 @@ function FileChooser:choose(ypos, height) pagedirty = true elseif ev.code == KEY_S then -- invoke search input keywords = InputBox:input(height-100, 100, "Search:") - if keywords then -- display search result according to keywords - FileSearcher:init( self.path ) - file = FileSearcher:choose(ypos, height, keywords) - if file then - return file + if keywords then + -- call FileSearcher + --[[ + This might looks a little bit dirty for using callback. + But I cannot come up with a better solution for renewing + the height arguemtn according to screen rotation mode. + + The callback might also be useful for calling system + settings menu in the future. + --]] + return nil, function() + FileSearcher:init( self.path ) + FileSearcher:choose(ypos, height, keywords) end end pagedirty = true diff --git a/filesearcher.lua b/filesearcher.lua index 814865d51..667f787f9 100644 --- a/filesearcher.lua +++ b/filesearcher.lua @@ -262,8 +262,20 @@ function FileSearcher:choose(ypos, height, keywords) elseif ev.code == KEY_ENTER or ev.code == KEY_FW_PRESS then file_entry = self.result[perpage*(self.page-1)+self.current] file_full_path = file_entry.dir .. "/" .. file_entry.name + + -- rotation mode might be changed while reading, so + -- record height_percent here + local height_percent = height/fb.bb:getHeight() openFile(file_full_path) + --reset height and item index if screen has been rotated + local old_perpage = perpage + height = math.floor(fb.bb:getHeight()*height_percent) + perpage = math.floor(height / self.spacing) - 2 + self.current = (old_perpage * (self.page - 1) + + self.current) % perpage + self.page = math.floor(self.items / perpage) + 1 + pagedirty = true elseif ev.code == KEY_BACK or ev.code == KEY_HOME then return nil diff --git a/keys.lua b/keys.lua index a04c72e33..cc630f09e 100644 --- a/keys.lua +++ b/keys.lua @@ -178,35 +178,6 @@ function set_emu_keycodes() KEY_VMINUS = 96 -- F12 end -function getRotationMode() - --[[ - return code for four kinds of rotation mode: - - 0 for no rotation, - 1 for landscape with bottom on the right side of screen, etc. - - 2 - +-----------+ - | +-------+ | - | | | | - | | | | - | | | | - 3 | | | | 1 - | | | | - | | | | - | +-------+ | - | | - +-----------+ - 0 - --]] - if KEY_FW_DOWN == 116 then -- in EMU mode always return 0 - return 0 - end - orie_fd = assert(io.open("/sys/module/eink_fb_hal_broads/parameters/bs_orientation", "r")) - updown_fd = assert(io.open("/sys/module/eink_fb_hal_broads/parameters/bs_upside_down", "r")) - mode = orie_fd:read() + (updown_fd:read() * 2) - return mode -end function adjustKeyEvents(ev) if ev.type == EV_KEY and ev.value == EVENT_VALUE_KEY_PRESS then @@ -225,9 +196,9 @@ function adjustKeyEvents(ev) -- adjust five way key according to rotation mode local code = ev.code - if getRotationMode() == 0 then + if Screen.cur_rotation_mode == 0 then return code - elseif getRotationMode() == 1 then + elseif Screen.cur_rotation_mode == 1 then if code == KEY_FW_UP then return KEY_FW_RIGHT elseif code == KEY_FW_RIGHT then @@ -239,7 +210,7 @@ function adjustKeyEvents(ev) else return code end - elseif getRotationMode() == 2 then + elseif Screen.cur_rotation_mode == 2 then if code == KEY_FW_UP then return KEY_FW_DOWN elseif code == KEY_FW_RIGHT then @@ -251,7 +222,7 @@ function adjustKeyEvents(ev) else return code end - elseif getRotationMode() == 3 then + elseif Screen.cur_rotation_mode == 3 then if code == KEY_FW_UP then return KEY_FW_LEFT elseif code == KEY_FW_RIGHT then @@ -264,4 +235,7 @@ function adjustKeyEvents(ev) return code end end + -- This should not happen. + print("# Unrecognizable rotation mode "..Screen.cur_rotation_mode.."!") + return nil end diff --git a/reader.lua b/reader.lua index da64c633c..ae48c575e 100755 --- a/reader.lua +++ b/reader.lua @@ -22,6 +22,7 @@ require "pdfreader" require "djvureader" require "filechooser" require "settings" +require "screen" -- option parsing: longopts = { @@ -111,6 +112,9 @@ end fb = einkfb.open("/dev/fb0") width, height = fb:getSize() +-- read current rotation mode +Screen:updateRotationMode() +origin_rotation_mode = Screen.cur_rotation_mode -- set up reader's setting: font reader_settings = DocSettings:open(".reader") @@ -131,11 +135,15 @@ if ARGV[optind] and lfs.attributes(ARGV[optind], "mode") == "directory" then local running = true FileChooser:setPath(ARGV[optind]) while running do - local file = FileChooser:choose(0,height) - if file ~= nil then - running = openFile(file) + local file, callback = FileChooser:choose(0,height) + if callback then + callback() else - running = false + if file ~= nil then + running = openFile(file) + else + running = false + end end end elseif ARGV[optind] and lfs.attributes(ARGV[optind], "mode") == "file" then @@ -151,6 +159,10 @@ end reader_settings:savesetting("cfont", FontChooser.cfont) reader_settings:close() +-- @TODO dirty workaround, find a way to force native system poll +-- screen orientation and upside down mode 09.03 2012 +fb:setOrientation(origin_rotation_mode) + input.closeAll() --os.execute('test -e /proc/keypad && echo "send '..KEY_HOME..'" > /proc/keypad ') if optarg["d"] ~= "emu" then diff --git a/screen.lua b/screen.lua new file mode 100644 index 000000000..158d20a63 --- /dev/null +++ b/screen.lua @@ -0,0 +1,76 @@ +--[[ + Copyright (C) 2011 Hans-Werner Hilse + + This program is free software: you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation, either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . +]]-- + +--[[ +Codes for rotation modes: + +1 for no rotation, +2 for landscape with bottom on the right side of screen, etc. + + 2 + +--------------+ + | +----------+ | + | | | | + | | Freedom! | | + | | | | + | | | | + 3 | | | | 1 + | | | | + | | | | + | +----------+ | + | | + | | + +--------------+ + 0 +--]] + + +Screen = { + cur_rotation_mode = 0, +} + +-- @ orien: 1 for clockwise rotate, -1 for anti-clockwise +function Screen:screenRotate(orien) + if orien == "clockwise" then + orien = -1 + elseif orien == "anticlockwise" then + orien = 1 + else + return + end + + self.cur_rotation_mode = (self.cur_rotation_mode + orien) % 4 + -- you have to reopen framebuffer after rotate + fb:setOrientation(self.cur_rotation_mode) + fb:close() + --local mode = self.rotation_modes[self.cur_rotation_mode] + --self.cur_rotation_mode = (self.cur_rotation_mode-1 + 1*orien)%4 + 1 + --os.execute("lipc-send-event -r 3 com.lab126.hal orientation"..mode) + fb = einkfb.open("/dev/fb0") +end + +function Screen:updateRotationMode() + if KEY_FW_DOWN == 116 then -- in EMU mode always set to 0 + self.cur_rotation_mode = 0 + else + orie_fd = assert(io.open("/sys/module/eink_fb_hal_broads/parameters/bs_orientation", "r")) + updown_fd = assert(io.open("/sys/module/eink_fb_hal_broads/parameters/bs_upside_down", "r")) + self.cur_rotation_mode = orie_fd:read() + (updown_fd:read() * 2) + end +end + + diff --git a/unireader.lua b/unireader.lua index c14f3e134..ac777cf5f 100644 --- a/unireader.lua +++ b/unireader.lua @@ -132,6 +132,16 @@ function UniReader:initGlobalSettings(settings) if pan_overlap_vertical then self.pan_overlap_vertical = pan_overlap_vertical end + + local cache_max_memsize = settings:readsetting("cache_max_memsize") + if cache_max_memsize then + self.cache_max_memsize = cache_max_memsize + end + + local cache_max_ttl = settings:readsetting("cache_max_ttl") + if cache_max_ttl then + self.cache_max_ttl = cache_max_ttl + end end -- guarantee that we have enough memory in cache @@ -199,13 +209,17 @@ function UniReader:setzoom(page) local dc = self.newDC() local pwidth, pheight = page:getSize(self.nulldc) print("# page::getSize "..pwidth.."*"..pheight); - local x0, y0, x1, y1 = page:getUsedBBox() - if x0 == 0.01 and y0 == 0.01 and x1 == -0.01 and y1 == -0.01 then - x0 = 0 - y0 = 0 - x1 = pwidth - y1 = pheight + local x0, y0, x1, y1 = 0, 0, pwidth, pheight + + -- only get usedBBox in fit to content mode + if self.globalzoommode <= self.ZOOM_FIT_TO_CONTENT and + self.globalzoommode >= self.ZOOM_FIT_TO_CONTENT_HALF_WIDTH_MARGIN then + x0, y0, x1, y1 = page:getUsedBBox() + if x0 == 0.01 and y0 == 0.01 and x1 == -0.01 and y1 == -0.01 then + x0, y0, x1, y1 = 0, 0, pwidth, pheight + end end + -- clamp to page BBox if x0 < 0 then x0 = 0 end if x1 > pwidth then x1 = pwidth end @@ -526,6 +540,14 @@ function UniReader:setrotate(rotate) self:goto(self.pageno) end +-- @ orien: 1 for clockwise rotate, -1 for anti-clockwise +function UniReader:screenRotate(orien) + Screen:screenRotate(orien) + width, height = fb:getSize() + self:clearcache() + self:goto(self.pageno) +end + function UniReader:cleanUpTOCTitle(title) return title:gsub("\13", "") end @@ -688,9 +710,17 @@ function UniReader:inputloop() self:showJumpStack() end elseif ev.code == KEY_J then - self:setrotate( self.globalrotate + 10 ) + if Keys.shiftmode then + self:screenRotate("clockwise") + else + self:setrotate( self.globalrotate + 10 ) + end elseif ev.code == KEY_K then - self:setrotate( self.globalrotate - 10 ) + if Keys.shiftmode then + self:screenRotate("anticlockwise") + else + self:setrotate( self.globalrotate - 10 ) + end elseif ev.code == KEY_HOME then if Keys.shiftmode or Keys.altmode then -- signal quit @@ -835,7 +865,6 @@ function UniReader:inputloop() self.settings:savesetting("last_page", self.pageno) self.settings:savesetting("gamma", self.globalgamma) self.settings:savesetting("jumpstack", self.jump_stack) - --self.settings:savesetting("pan_overlap_vertical", self.pan_overlap_vertical) self.settings:savesetting("bbox", self.bbox) self.settings:savesetting("globalzoom", self.globalzoom) self.settings:savesetting("globalzoommode", self.globalzoommode)