View Single Post
Old 11-30-2011, 12:39 AM   #8
geekmaster
Carpe diem, c'est la vie.
geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.geekmaster ought to be getting tired of karma fortunes by now.
 
geekmaster's Avatar
 
Posts: 6,433
Karma: 10773668
Join Date: Nov 2011
Location: Multiverse 6627A
Device: K1 to PW3
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:
Spoiler:
Code:
[Actions]
;; run framebuffer scroller with default parameters (scroll 10 1)
S S = !/mnt/us/bin/scroll &
;; run framebuffer scroller with 5% scroll
S X = !/mnt/us/bin/scroll 5 &
;; run framebuffer scroller , 10% scroll, no flash update
S A = !/mnt/us/bin/scroll 10 0 &
;; run framebuffer scroller , 10% scroll, fastest update (black and white only)
S D = !/mnt/us/bin/scroll 10 2 &

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.
Attached Files
File Type: gz scroll.tar.gz (4.3 KB, 515 views)

Last edited by geekmaster; 12-04-2011 at 02:28 PM.
geekmaster is offline   Reply With Quote