Okay, I wrote a program to do the framebuffer scrolling with wraparound. It *was* thoroughly tested and working from a USB ssh command line. It also worked from launchpad (Shift S S), but launchpad wrote status info on the display AFTER it had scrolled.
Then I decided to publish the source code too, so I "cleaned" it. I was very tired when I did that, and I (unwisely) did the code cleanup in the mobileread online comment editor. The code is *simpler* now -- I removed "inotify" code that attempted to detect framebuffer changes but only saw open/close events, and other "dead" test code. Inotify does not see kindle framework activity, but I am tempted to put it back in to detect when launchpad messes up the display so I can clean it (probably running as a daemon). Now that I cleaned the code. it only works from my kindle debian environment (chroot from a loop mounted ext3 image).
EDIT: It works in native jailbreak environment too, now that I initialized the unused buffer pointer.
The (repaired) source code is below in this message.
-----
This program accepts up to two parameters.
The first optional parameter is percent of display height to scroll (value 0 to 100, default = 10).
The second optional parameter is display update type (value 0 to 2, default = 1).
Display update types are:
0 = no flash (fast, but slight ghosting)
1 = quality (full flash update, cleanest display)
2 = speed (very fast, black and white only)
21 = negative (readability aid?)
This program can be mapped with various parameters to hotkeys using launchpad, but it scrolls launchpad residue onto the screen.
It works much better from the command line. I may need to add my own hotkey processing to this program so the launchpad feed back does not pollute the screen.
Does launchpad have a "quiet" parameter for silent operation? It would probably be faster without the visual feedback too.
Anyway, 'scroll' works [worked] fine when run from a USB telnet or ssh command line, but needs a better way to launch it. I was thinking perhaps if both the Prev(Right<) and Next(Right>) keys were down, we could do the default scroll.
To install this (preliminary) version, copy 'scroll' to the USB Drive (/mnt/us/bin), and copy scroll.ini to the launchpad folder.
Here is scroll.ini:
Here is the C source code:
Spoiler:
Code:
// scroll.c - simple framebuffer scroller for kindle with (partially)
// broken eink display
//
// usage:
// scroll [percent] [type]
//
// percent: optional percent of display height to scroll (0 to 100, default = 10).
// type : optional display update type (value 0 to 2, default = 1):
// 0 = no flash (fast, but slight ghosting)
// 1 = quality (full flash update, cleanest display)
// 2 = speed (very fast, black and white only)
//
// *** Disclaimers and whatnot:
//
// This is just a simple quick-and-dirty hack.
// It could use some error checking, and more features.
//
// There is no "secret sauce" here (such as intellectual "Property",
// whatever that is), nothing to protect, no license needed.
//
// As always, please do not sue me if you poke your eye out with
// this code, or somehow manage to injure your brain or otherwise
// maim yourself, your stuff, or your loved ones with it.
//
// Enjoy, compliments of geekmaster...
//
#include <stdio.h>
#include <stdlib.h>
#include <fcntl.h>
#include <linux/fb.h>
#include <string.h>
#include <sys/mman.h>
#include <sys/ioctl.h>
#define FB_UPDATE_AREA 0x46dd
int main(int argc, char** argv) {
int pct = 10;
int fx = 1; // full flash update
int y, height, width, width_bytes, fb_bytes;
struct fb_var_screeninfo screeninfo;
unsigned char *pfb = NULL, *psave = NULL;
struct update_area_t
{
int x1, y1, x2, y2, fx;
__u8 *buffer;
} ua;
// get optional command-line params
if (argc > 1) pct = atoi(argv[1]); // scroll percent (0-100)
if (argc > 2) fx = atoi(argv[2]); // update type (0-2)
// open framebuffer and get screen size (assume 4 bpp)
int fdFB = open("/dev/fb0", O_RDWR);
ioctl(fdFB, FBIOGET_VSCREENINFO, &screeninfo);
height = screeninfo.yres;
width = screeninfo.xres;
width_bytes = width / 2;
fb_bytes = height * width_bytes;
// map and copy framebuffer
pfb = (unsigned char*)mmap(0, fb_bytes, PROT_READ|PROT_WRITE,
MAP_SHARED, fdFB, 0);
psave = malloc(fb_bytes);
memcpy(psave, pfb, fb_bytes);
// copy swapped slices back to framebuffer
y = height * pct / 100;
memcpy(pfb + y * width_bytes, psave, (height - y) * width_bytes);
memcpy(pfb, psave + (height - y) * width_bytes, y * width_bytes);
// trigger framebuffer update
ua.x1 = 0;
ua.y1 = 0;
ua.x2 = width;
ua.y2 = height;
ua.buffer = NULL;
ua.fx = fx; // update type
ioctl(fdFB, FB_UPDATE_AREA, &ua);
// cleanup
free (psave);
munmap(pfb, fb_bytes);
close(fdFB);
}
Downloadable archive with executable, source and .ini files:
NOTE: the above code has been fixed to set ua.buffer = NULL, which got lost in the cleanup. The .gz file below still contains the old broken code.