-
-
Notifications
You must be signed in to change notification settings - Fork 1.2k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Dev docs #2730
Dev docs #2730
Changes from 5 commits
2134f8a
e5f0f88
9a4760e
adb62f1
bf5fac0
9976d9d
7fd0bb6
f36bcce
1f230d9
030adb5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,135 @@ | ||
# Development Guide | ||
|
||
The whole frontend part of KOReader is scripted in [Lua](http://www.lua.org/about.html) programming language which means you can start development with just a decent text editor. Instructions about how to get and compile the source of the backend part on a linux OS are [here](https://github.com/koreader/koreader#building-prerequisites) | ||
|
||
The source tree of frontend looks like this: | ||
``` | ||
frontend | ||
├── apps | ||
│ ├── filemanager | ||
│ │ ├── filemanagerhistory.lua | ||
│ │ ├── filemanager.lua | ||
│ │ └── filemanagermenu.lua | ||
│ └── reader * | ||
│ ├── modules | ||
│ │ ├── readeractivityindicator.lua | ||
│ │ ├── readerbookmark.lua | ||
│ │ ├── readerconfig.lua | ||
│ │ ├── readercoptlistener.lua | ||
│ │ ├── readercropping.lua | ||
│ │ ├── readerdictionary.lua | ||
│ │ ├── readerdogear.lua | ||
│ │ ├── readerflipping.lua | ||
│ │ ├── readerfont.lua | ||
│ │ ├── readerfooter.lua | ||
│ │ ├── readerfrontlight.lua | ||
│ │ ├── readergoto.lua | ||
│ │ ├── readerhighlight.lua | ||
│ │ ├── readerhinting.lua | ||
│ │ ├── readerhyphenation.lua | ||
│ │ ├── readerkoptlistener.lua | ||
│ │ ├── readerlink.lua | ||
│ │ ├── readermenu.lua | ||
│ │ ├── readerpaging.lua | ||
│ │ ├── readerpanning.lua | ||
│ │ ├── readerrolling.lua | ||
│ │ ├── readerrotation.lua | ||
│ │ ├── readerscreenshot.lua | ||
│ │ ├── readertoc.lua | ||
│ │ ├── readertypeset.lua | ||
│ │ ├── readerview.lua | ||
│ │ └── readerzooming.lua | ||
│ ├── pluginloader.lua | ||
│ └── readerui.lua | ||
├── cacheitem.lua | ||
├── cache.lua | ||
├── configurable.lua | ||
├── dbg.lua | ||
├── docsettings.lua | ||
├── document * | ||
│ ├── credocument.lua | ||
│ ├── djvudocument.lua | ||
│ ├── document.lua | ||
│ ├── documentregistry.lua | ||
│ ├── koptinterface.lua | ||
│ ├── pdfdocument.lua | ||
│ ├── picdocument.lua | ||
│ └── tilecacheitem.lua | ||
├── gettext.lua | ||
├── JSON.lua | ||
├── optmath.lua | ||
└── ui | ||
├── data | ||
│ ├── creoptions.lua | ||
│ ├── koptoptions.lua | ||
│ └── strings.lua | ||
├── device | ||
│ ├── basepowerd.lua | ||
│ ├── kindlepowerd.lua | ||
│ ├── kobopowerd.lua | ||
│ └── screen.lua | ||
├── device.lua | ||
├── event.lua | ||
├── font.lua | ||
├── geometry.lua | ||
├── gesturedetector.lua | ||
├── gesturerange.lua | ||
├── input.lua | ||
├── language.lua | ||
├── rendertext.lua | ||
├── screen.lua | ||
├── timeval.lua | ||
├── uimanager.lua | ||
└── widget * | ||
├── bboxwidget.lua | ||
├── buttondialog.lua | ||
├── button.lua | ||
├── buttontable.lua | ||
├── closebutton.lua | ||
├── configdialog.lua | ||
├── confirmbox.lua | ||
├── container | ||
│ ├── bottomcontainer.lua | ||
│ ├── centercontainer.lua | ||
│ ├── framecontainer.lua | ||
│ ├── inputcontainer.lua | ||
│ ├── leftcontainer.lua | ||
│ ├── rightcontainer.lua | ||
│ ├── underlinecontainer.lua | ||
│ └── widgetcontainer.lua | ||
├── dictquicklookup.lua | ||
├── eventlistener.lua | ||
├── filechooser.lua | ||
├── fixedtextwidget.lua | ||
├── focusmanager.lua | ||
├── horizontalgroup.lua | ||
├── horizontalspan.lua | ||
├── iconbutton.lua | ||
├── imagewidget.lua | ||
├── infomessage.lua | ||
├── inputdialog.lua | ||
├── inputtext.lua | ||
├── linewidget.lua | ||
├── menu.lua | ||
├── notification.lua | ||
├── overlapgroup.lua | ||
├── progresswidget.lua | ||
├── rectspan.lua | ||
├── scrolltextwidget.lua | ||
├── textboxwidget.lua | ||
├── textwidget.lua | ||
├── toggleswitch.lua | ||
├── touchmenu.lua | ||
├── verticalgroup.lua | ||
├── verticalscrollbar.lua | ||
├── verticalspan.lua | ||
├── virtualkeyboard.lua | ||
└── widget.lua | ||
``` | ||
in which you will find the asterisked `frontend/document`, `frontend/apps/reader` and `frontend/ui/widget` the most interesting parts. | ||
|
||
### document: API for document parsing and rendering | ||
|
||
### reader: reader functionality implementation | ||
|
||
### widget: a light-weight widget toolkit |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,6 +1,23 @@ | ||
Hacking | ||
======= | ||
|
||
## How to Debug | ||
|
||
We have a helper function called `logger.dbg` to help with debugging. You can use that function to print string and tables: | ||
|
||
```lua | ||
local logger = require("logger") | ||
a = {"1", "2", "3"} | ||
logger.dbg("table a: ", a) | ||
``` | ||
|
||
Anything printed by `logger.dbg` starts with a `#` sign. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is the behavior for the deprecated DEBUG function. New logger prints in the following format now:
|
||
|
||
## Bug hunting in kpv | ||
|
||
A real example for hunting bug in KPV's cache system: https://github.com/koreader/kindlepdfviewer/pull/475 | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. KPV! Is this still relevant to KOReader? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I barely even read it diagonally after making the link to point to the right repository, but it looked like the comments around koreader/kindlepdfviewer#475 (comment) might still be somewhat relevant to #2502. I'd never even heard of KOReader at the time (or kindlepdfviewer) and you added it to the wiki, so it's up to you. :-) |
||
|
||
|
||
## Developing UI widgets ## | ||
|
||
`tools/wbuilder.lua` is your friend, if you need to create new UI widgets. It | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,94 @@ | ||
# Porting | ||
|
||
This page aims to provide guidance on how to port KOReader to other platforms. | ||
|
||
There are mainly two modules that you need to take care of: input and output. | ||
After you finish these two, KOReader should have no problem running on your | ||
platform. Feel free to open issues in our issue tracker if you need further help on this topic :) | ||
|
||
|
||
## Output Module | ||
|
||
KOReader uses framebuffer to control EInk devices, so the output module here is | ||
[einkfb.c][einkfb-c]. You can find this file in koreader-base framework. The | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This section is out of date now. einkfb has been ported to lua under There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Right, a couple of the links point to outdated locations. Is there anything substantial that's off? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. How about something like this? I removed the final two paragraphs and for the rest basically kept the text. KOReader uses framebuffer to control EInk devices, so the output module here is Following are the framebuffers that
For 4BPP framebuffer, it means every pixel is represented with 4 bits, so we For 16 scale 8BPP framebuffer, it means each pixel is instead stored in 1 byte, If your device's framebuffer does not fit into any of the categories above, The
KOReader will handle the 4BPP shadow buffer for you, all you need to do is to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. looks good to me :) |
||
koreader-base framework used to be part of KOReader, but we later factored it | ||
out and use it in KOReader as submodule. | ||
|
||
Following are the framebuffers that `einkfb.c` currently supports: | ||
* 4BPP inverted framebuffer | ||
* 16 scale 8BPP inverted framebuffer | ||
* 16 scale 8BPP framebuffer | ||
|
||
For 4BPP framebuffer, it means every pixel is represented with 4 bits, so we | ||
have 2 pixels in 1 byte. So the color depth is 16. The inverted part means all | ||
the bits are flipped in the framebuffer. For example, two pixels `[0x00, 0xf0]` | ||
will be stored as `0xff0f` in framebuffer. | ||
|
||
For 16 scale 8BPP framebuffer, it means each pixel is instead stored in 1 byte, | ||
but the color depth is still 16 (4bits). Since 1 byte has 8 bits, so to fill | ||
up the remaining space, the most significant 4 bits is a copy of the least | ||
significant one. For example, pixel with grey scale 15 will be represented as | ||
`0xffff`. If it's a inverted 16 scale 8BPP framebuffer, then all the bits are | ||
flipped in the same way as 4BPP inverted framebuffer does. | ||
|
||
If your device's framebuffer does not fit into any of the categories above, | ||
then you need to add a new transformation function in `einkfb.c`. | ||
|
||
The `einkfb.c` module works in following ways for non 4BPP framebuffers; | ||
* a shadow buffer is created and structured as 4BPP inverted framebuffer. | ||
* all updates on screen bitmap are temporally written into the shadow buffer. | ||
* each time we want to reflect the updated bitmap on screen, we translate | ||
the shadow buffer into a format that the real framebuffer understands and | ||
write into the mapped memory region. (varies on devices) | ||
* call ioctl system call to refresh EInk screen. (varies on devices) | ||
|
||
KOReader will handle the 4BPP shadow buffer for you, all you need to do is to | ||
teach `einkfb.c` how to control the EInk screen and translate the 4BPP inverted | ||
bitmap into the format that your framebuffer understands. | ||
|
||
In `openFrameBuffer()` function, the value for a function pointer | ||
`einkUpdateFunc` is assigned according to devices' model. This function is | ||
called on every screen refresh. It transforms the shadow buffer and write the | ||
result into framebuffer. Then it calls ioctl to refresh the screen. | ||
|
||
So you need to write a einkUpdateFunction for your device's framebuffer and | ||
assigned it to `einkUpdateFunc` on eink open. You may want to refer to | ||
`kindle51einkUpdate()`, `kindle4einkUpdate()` and `kindle3einkUpdate()` | ||
functions for real examples. | ||
|
||
|
||
|
||
## Input Module | ||
|
||
We have a `input.c` module in [koreader-base][kb-framework] that reads input | ||
events from Linux's input system and pass to Lua frontend. Basically, you don't | ||
need to change on that module because it should support most of the events. | ||
|
||
For this part, the file you have to hack on is [`koreader/frontend/ui/input.lua`](https://github.com/koreader/koreader/blob/master/frontend/ui/input.lua). | ||
|
||
Firstly, you need to tell which input device to open on KOReader start. All the | ||
input devices are opened in `Input:init()` function. | ||
|
||
Next, you might need to define `Input:eventAdjustHook()` function in | ||
`Input:init()` method. We use this hook function to translates events into a | ||
format that KOReader understands. You can look at the KindleTouch initialization code for real example. | ||
|
||
For Kobo devices (Mini, Touch, Glo and Aura HD) the function `Input:eventAdjustHook()` was skipped and the functions `Input:init()` and `Input:handleTypeBTouchEv` were changed to allow the single touch protocol. For Kobo Aura with multitouch support an extra function `Input:handlePhoenixTouchEv` was added. | ||
|
||
Linux supports two kinds of Multi-touch protocols: | ||
* http://www.kernel.org/doc/Documentation/input/multi-touch-protocol.txt | ||
|
||
Currently, KOReader supports gesture detection of protocol B, so if your device sends out | ||
protocol A, you need to make a variant of function `Input:handleTouchEv()` (like `Input:handleTypeBTouchEv` and `Input:handlePhoenixTouchEv`) and simulate protocol B. | ||
Also you are welcome to send a PR that adds protocol A support to KOReader. | ||
|
||
More information on Linux's input system: | ||
* http://www.kernel.org/doc/Documentation/input/event-codes.txt | ||
* http://www.kernel.org/doc/Documentation/input/input.txt | ||
|
||
|
||
|
||
[einkfb-c]:https://github.com/koreader/koreader-base/blob/master/einkfb.c | ||
[kb-framework]:https://github.com/koreader/koreader-base | ||
[inputev]:https://github.com/koreader/koreader/blob/master/frontend/ui/inputevent.lua | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
s/True/true. Or s/True/
true
.