Kobo mini – doing without the official reader software.

The mini is a great ereader, I love the fact that its size makes it even more convenient than a pulp paperback, best of all I love that the internal boot media is a removable SD card, while its not a terrible inconvenience to use something like a bus pirate to modify a flash chip it is a fair bit easier to write to a removable device! additionally its a snap to upgrade, which if you’re going to mess with your Kobo I’d really recommend you do.

You need to be sure you can recreate and backup an original Kobo boot SD, then you can store the old SD card as a backup, as well as keep backup of the first 10MB of the disk, also an image of the first partition (at least!) and keep this separate backup on your HD.

Once you’ve made and tested your newly cloned SD card you can start modifying it.

First of all you want to install the launcher software you may be interested in some of the other software he bundles with the launcher and if you are using it regularly you might consider a donation…

Of course the bit we’re interested in is his port of coolreader (I can’t seem to find any source for his modifications which is a pity, but I’ll admit I’ve not looked too hard)

Coolreader is much better than it used to me and unlike the “official” reader its able to cope with large collections without slowing to a crawl, you may have to wait 10 secs or so if you open a file selection dialog in a folder with a few thousand or more files – but frankly I really should curate my collection better than just bunging most stuff in one general folder!…

Customization is a snap, for example I have the launcher “autoboot” straight into coolreader, changing screensaver images is very simple (images live in the sleep folder) and unlike the “official” reader the text actually fills the screen.  Just one small gottcha if you want complete control over how the document is displayed you’ll have to disable auto text formatting…

kobo-coolreaderAssuming you’re happy with coolreader, and why wouldn’t you be! notice you get a whole screen full of text rather than large variable gaps at the top and bottom of the screen… (don’t worry about it being inverse – I’m trying it out for a while to see if I like it, you don’t have to!), the next step is to stop the “official” software from ever running (this is not obligatory but good riddance an’ all that!)

The boot sequence they are using is slightly none standard but thankfully simple to modify…

Most modification is in within /etc/init.d/rcS

First I commented out just the section that executes the updates (any hacks that use KoboRoot.tgz I install – and check – manually)

Next to go is the boot animation, frankly in the 3-4 seconds it takes to boot linux and the 3-4 seconds the launcher/coolreader takes to run its superfluous anyhow, so I couldn’t be bothered to kill it rather I simply commented it out

# ( usleep 400000; /etc/init.d/on-animator.sh ) &

My next modifications are all at the bottom of the file

# disable the flashing led
echo "ch 3" > /sys/devices/platform/pmic_light.1/lit
echo "cur 0" > /sys/devices/platform/pmic_light.1/lit
echo "dc 0" > /sys/devices/platform/pmic_light.1/lit

I found this from the boot sequence of xcsoar and stopping it here means while Linux is booting we’ll have some visual conformation via the power LED

# run dropbear in background
( /mnt/onboard/.kobo/vlasovsoft/usbnet-silent.sh ) &

Because I’m I want dropbear running all the time, I run a modified version of the usbnet script that comes with the launcher (more on this later)

finally we can run the launcher itself…

/mnt/onboard/.kobo/vlasovsoft/launcher.sh

Because the usbnet script isn’t being run by the launcher but by the bootscript it won’t have the environment variables set that it expects.  First copy and rename the usbnet.sh (so the original can still be used by the Launcher menu as normal) first we need to supply the ROOT variable, our first modification (of the COPY!) is at the top of the script

# used during boot, only show msgbox if there is an error
ROOT=/mnt/onboard/.kobo/vlasovsoft
root=$ROOT/usbnet

last near the end of the script we just need to comment out the success message box

    # msgbox "usbnet" "usb network started!"

and thats about it!

The caveats

Obviously nothing is perfect, first off usb mass storage, now its eminently possible to get this working but frankly I couldn’t be bothered, with dropbear you can log in with filezilla for GUI file management.

Also not utilised is WIFI but for an ereader I increasingly find this less than relevant, while the Kobo’s web browser is a nice try, its not really up to the job, and if I’m browsing I’d rather be using a device better suited.

All in all I’m happy with the recent advances made with Coolreader (I hadn’t looked in quite some time!) and certainly glad to be rid of the “official” software…

 

Posted in Uncategorized | Leave a comment

Java Jni wrapping a simple callback machanism

Here we’re going to look at a very simple callback in C an how you might wrap it for Java. Let’s dive straight in with some example code

JNIEXPORT void JNICALL Java_Bogus_setCallback
  (JNIEnv *e, jclass c, jobject inst, jstring method) 
{
    const char *cbn = (*e)->GetStringUTFChars(e, method, 0);
    bcbclass = (*e)->GetObjectClass(e, inst);
    bcbmethod = (*e)->GetMethodID(e, bcbclass, cbn, "(III)V");
    (*e)->ReleaseStringUTFChars(e, method, cbn);  
    bcbe=e;
    if (bcbmethod == 0) return;
    BogusSetCallback(bogusCallBack);
      
}

We’re using a class instance and a method name to identify where the callback method is, additionally we’re caching the object class and method id, even if you’re not caching this info its still a good idea to do a dry run on the method id here, as if something is wrong with the method name JNI will issue an exception (which is why we return without need of error message) – WAIT…. JNI causing an exception – what no throwing the dummy out the pram seg fault behaviour…. I know shocking!

Don’t forget you can always use javap to help determine what the method signature should be.

Internally to our wrapper we will need a C function to actually receive the callback and dispatch it off to our Java version

void bogusCallBack(int a, int b, int c)
{
 (*bcbe)->CallVoidMethod(bcbe, bcbclass, bcbmethod, a, b, c);
}

So we have a number of cached values here that if you need a callback per C “object” you’ll need to lookup on the fly. bcbclass being the instance class and bcbmethod being the method ID.  If the library you’re wrapping is multi-threaded you’ll need to read up on attach thread take a look at the documentation here

Enjoy!

Posted in Uncategorized | Leave a comment

Wrapping a returned C struct from inside JNI (and other JNI stuff)

First off I don’t claim to be any kind of JNI guru and frankly I like to touch C as little as possible – C’s memory management model is only marginally better than C++’s (shudder) – that should get me a few flames >:)

That said I did struggle to find any easy to digest info that did just what I wanted, so I thought I’d document my solution, just to muddy the waters further!

When using JNI its important to remember that you’ve been spoilt rotten by Java’s garbage collection, things in C are all together more hairy and its all too easy to forget that passing a local variable back through the  “JNI barrier” is gonna cause you nothing but pain…

Its common to have a C or C++ objects wrapped in a Java object with its own close or delete method,leaving you responsible for calling it before the Java Object is GC’d.  This isn’t particularly a very “Java way” to do things and in some cases it can be avoided.

It’s not uncommon to see C stucts returned from functions and if they are simple structures for example just containing ints and floats (basically you’re sure they don’t contain references to allocated memory you are responsible for freeing) then they are a very good candidate for encapsulating within a Java class, that can be automagically GC’d

The first thing you need is a buffer in your wrapping class, this needs to be created in a particular way to ensure stuff doesn’t get mangled, if the struct for example only holds floats, you can write pure Java accessors which directly get or put to a FloatBuffer.  Lets look at how the buffer needs to be created.

buff = ByteBuffer.allocateDirect(16).order(ByteOrder.nativeOrder());

In the constructor I’m creating a buffer big enough for 4 Floats, you could argue that you should have a native function that returns the size in bytes of the structure, but in our case we’re going to assume that the structure is only going to be four floats….forever….

notice two things its allocated as a “direct” buffer and the byte order is set to the machines current native order, its returned as a float buffer in this case as we’ll be directly manipulating it from Java as well as creating it in C.

Don’t worry if your struct has mixed (native) types consider this code

        bb=ByteBuffer.allocateDirect(8).order(ByteOrder.nativeOrder());
        
        ib = bb.asIntBuffer();
        fb = bb.asFloatBuffer();
        
        System.out.println("ib 0 ="+ib.get(0));
        System.out.println("bb 0 ="+bb.get(0)+","+bb.get(1)+","+bb.get(2)+","+bb.get(3));
        fb.put(0,1.1f);
        System.out.println("ib 0 ="+ib.get(0));
        System.out.println("bb 0 ="+bb.get(0)+","+bb.get(1)+","+bb.get(2)+","+bb.get(3));

Crucially here ByteBuffers asIntBuffer and asFloatBuffer doesn’t make a copy of the byte buffer but rather its a different “view” of the same ByteBuffer, so as you can see you have a fair bit of scope for accessing values directly from Java even if there are mixed types in the structure…

First lets look at the worst case where there isn’t an existing Java object and we need to create one from C

jobject createBogusJobject(JNIEnv *e) {
    jclass cls = (*e)->FindClass(e, "wrapper$Bogus");
    jmethodID constructor = (*e)->GetMethodID(e, cls, "<init>", "()V");    
    jobject bogus = (*e)->NewObject(e, cls, constructor);
    return bogus;
}

There is no error checking here, however assuming that you have the right class and field name, then all should be well… (but it probably is a good idea to check the new object was actually created.)

On the Java side of our imaginary wrapper, our Bogus class is a static sub class of a singleton wrapper class (I’ll leave it to you to work out why).  When actually creating the object the NewObject function needs to know which constructor to call,  method signatures are probably not terribly intuitive, but you can use javap to tell you, for example :-

javap -s jni/wrapper\$Bogus.class

will tell you all you need to know, notice that the $ is escaped (and the path separator is a *nix one, yours could be different…!).

Now we have our object either new or it could be passed from Java, we need to get a pointer to our object’s buffer and copy our C struct into it.

Lets see how we do this with an existing Java class

JNIEXPORT void JNICALL Java_wrapper__1_1bogusOp
  (JNIEnv *e, jclass c, jobject jbogus, jfloat x, jfloat y, jfloat z)
{
    Bogus b = aBogusOp(x, y, z);
    Bogus* dp = getBuffPtr(e,jbogus);
    *dp = b;
}

Given a Java Bogus object and some parameters, we can call a native routine that passes back a struct as a return value.  Next we need to copy it into our Java object for which we need a pointer to the ByteBuffer (more on that in a moment) By dereferencing the ByteBuffer pointer we can then copy the local bogus variable into the buffer.

The last piece of this particular puzzle is to get a pointer to our ByteBuffer.

void* getBuffPtr(JNIEnv *e, jobject jo)
{
    jobject cls = (*e)->GetObjectClass(e, jo);
    jfieldID fid = (*e)->GetFieldID(e, cls,"buff","Ljava/nio/ByteBuffer;");
    jobject jbuff = (*e)->GetObjectField(e, jo, fid);
    return (*e)->GetDirectBufferAddress(e, jbuff);
}

I use this routine for a number of different Classes, for this reason their ByteBuffers must all be called “buff” again we need an arcane field signature but javap will help out.  Again there is nothing in the way of error checking here!

On the subject of error checking your biggest ally is the Java compiler, its fairly difficult to supply the wrong type of parameter and checking for NULL references will stop many of the more spectacular dummy throwing JNI can do.  Remember that its much better to check what you are supplying to JNI in the first place….

with that in mind I use a very simple macro when I need to pass an jobject to C

#define checkJO(JO, MSG) if (JO==NULL) { printf(MSG); fflush(stdout); return; }

The first thing I do is check all user supplied java objects passed to my C JNI function for example

checkJO(jbogus,"\nbogusOp was passed a NULL bogus!\n");

Two things to note, first off the 2 carriage returns, basically we’re sharing a terminal with Java’s error reporting and even flushing the buffer you can still get any message you emit munged up with a JVM error message such as an uncaught NULL pointer exception.

Lastly the macro returns from the function immediately so if you have a none void returning JNI function you’ll need a macro that returns NULL which can be tested later so you know there’s a problem… Don’t forget in this example I’m using an existing Java object to pass back return values but you could easily be returning Java object created in C.

Well theres a fair bit to digest there! so probably best we leave it here, don’t forget to check out the JNI documentation

Enjoy!

Posted in Uncategorized | Leave a comment

Jnanovg initial release!

I posted last time about my discovery of nanovg a lightweight vector graphic library, and mentioned that I was wrapping it for Java.

Well now its in a working condition I put it up on github

Enjoy!

 

 

Posted in Uncategorized | Leave a comment

nanovg a lightweight vector graphics library

I stumbled on a really nice vector graphics library, its not all featured but the big advantage its both lightweight and simple and makes some nice graphics as can be seen by a screen shot

nanovg

Its not an actual gui just a mock up, but there is some animation to the demo, and it looks very easy to render some nice content….

I was so impressed I’ve decided to wrap it for Java, while my primary usage will be for my own GLES 2.0 wrapper (Jgles2) I’m being careful to only make the example for the wrapper reliant on it, with a simple change it will be easy to recompile the wrapper for OpenGL (instead of GLES 2.0) and then use it with for example Lwjgl…

I’ve got as far as rendering some quadratic / bezier and even straight lines and animating them

Jnanovg

This in no way troubles the cpu load meter and looking at the speed of the C example I can see that you should be able to render a full GUI while rendering a 3d scene without any problems at all….

So far the Java wrapper has almost written itself as I watch some naff TV…. there’s no callbacks and the various structures seem simple and hopefully shouldn’t present a problem. What a nice find…..

 

Posted in Uncategorized | Leave a comment

Jgles2 new example

Jgles2-shotI looked at using Lwjgl’s framework for creating a GLES 2.0 wrapper, but failed miserably (several times) at even working out how you’d even tell it there was a new library… instead I decided to port my Lwjgl3 example to an existing GLES 2.0 wrapper…

For a while now I’ve had a slim wrapper of GLES 2.0 for Java which is available here.  Its far from perfect but does basically what I need of it (contributions and feedback welcome)

There are some minor differences which are basically to do with Java convenience, and is leading me towards thinking that rather than excepting different types of buffers as parameters for GLES functions, I should consider just having a utility to return a pointer (as a java long) for a buffer, this would simplify some things and also make the functions very much 1:1 with the native library.

So which is best – well to be honest neither really, obviously Lwjgl will enjoy wider support and cross platform native libraries (I used to know how to compile a windows DLL from Linux – I really must get round to reimplementing this…!) but mainly the difference is just that they are *slightly* different!

 

 

Posted in Uncategorized | Leave a comment

OpenGL string printer

glprint

Well… I meant to do this a lot earlier and indeed having this would have saved me flooding the console with junk – not an ideal way to debug!

I wanted a few things from my string printer, first of all I wanted it to scale with the screen (regardless of screen ratio) I decided to have characters nominally 16×16 (but the textures are larger than this, at a nominal resolution of 640×480 this gives 40×30 characters on the screen.  Because my codebase can be easily “ported” to GLES I decided to keep my texture size to a power of 2 size (512×256)

A texture of this size allows a character cell of 32×42 pixels for each characters texture, remember on a desktop the screen resolution could be large enough to need a decent sized texture. A character cell of 42 pixels high actually only uses 252 lines of the texture but we can live with 4 wasted lines. Of course if you have a more modest target you can always have a 256×128 texture with 16×22 characters…

Although I’m using a boring white font, there is no reason at all that you can’t use a multi coloured texture or even with some easy modification an animated texture.

In the example code I’ve included below and as you can see in the above screenshot, I’m using two sizes of fonts, to use my routines first you must set up the string printer

        Print printer =  new Print("data/font.png",24,32);
        Print smlPrint = new Print("data/font.png",16,16);

16×16 is our nominal font size, so simply supply a larger size when you create the string printing object if you want a BIG FONT!.

Two things need to be done before actually printing

glEnable (GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA);
printer.preRender(width,height);

first set up your blending – this is separate as you may well already be using this blending mode, leading to unnecessary state changes.  Next we tell the printer we’re just about to render, this gives the printer the opportunity to set up OpenGL the way it needs to – selecting the buffers and shaders etc.  The width and height we supply is the current size of our window (not our nominal 640×480)

Now we can actually print

printer.render(20,20,"Hello");
printer.render(60,40,"World!");

The x & y coordinate are using our nominal 640×480 resolution thats scaled to the current screen resolution.

finally allow the printer to tidy up

printer.postRender();

and thats all there is to it…

here’s the code Enjoy!

Posted in Uncategorized | Leave a comment

The dreaded gimbal lock…

noGimbal

Its common when using OpenGL to simply rotate objects by doing successive rotations around different axes, while keeping track of these rotations via 3 angles, one for each axis.  This is simple to implement and if for example you’re simply travelling over a plane or surface then you’re unlikely to have much in the way of difficulty.

However if your needs are more complex you will soon notice a number of problems.  The first and possibly less noticeable is that doing successive rotations creates different results depending on the order you apply the rotations.  Looking at the illustration above you will see that the three axes of a cube are marked with simple pyramids, when rotating around successive axes its often possible to get into a situation where the tip of the pyramid of a rotating axis is describing circles instead of being stationary as it should.

By far the biggest issue is the so called gimbal lock, basically if you rotate one axis of rotation onto another axis, you’ll loose a degree of freedom – its easier to see, just go onto any video sharing site and search for gimbal lock, its obvious whats going on as soon as you actually see whats going on…

Many people will simply say the solutions is to use quaternions, and yes you can solve gimble lock by using quaternions but they are not some simple magic bullet – indeed if you (don’t!) know what you’re doing, you can implement all the same problems you’re trying to solve!

Its also possible to avoid gimbal lock by using a matrix too, and once you’ve seen how a quaternion is used you should be able to work out how to use a (rotation) matrix instead if you want to…

The exact details of quaternions are complex (in fact more than complex ;) !) but similarly to matrices you really don’t need to understand all the detailed minutiae to use them as a tool.

The key here is not to use 3 Euler rotations to keep track of your objects rotation but rather a single quaternion to hold the orientation of your object.

In particular you must add cumulative rotations (as you need them) to a quaternion rather than attempting to create a quaternion from Euler angles each time you need it.  Lets look at some example code

            if (keys[GLFW_KEY_Q]) xa =- ANG_SPEED * delta;
            if (keys[GLFW_KEY_W]) xa =+ ANG_SPEED * delta;
            if (keys[GLFW_KEY_A]) ya =- ANG_SPEED * delta;
            if (keys[GLFW_KEY_S]) ya =+ ANG_SPEED * delta;
            if (keys[GLFW_KEY_Z]) za =- ANG_SPEED * delta;
            if (keys[GLFW_KEY_X]) za =+ ANG_SPEED * delta;

            model.translation( x, y, z );

            if (xa!=0) { tmpRot.axisAngle(1,0,0,xa); modelRot.multiply(tmpRot); }
            if (ya!=0) { tmpRot.axisAngle(0,1,0,ya); modelRot.multiply(tmpRot); }
            if (za!=0) { tmpRot.axisAngle(0,0,1,za); modelRot.multiply(tmpRot); }

            tmpMat.set(modelRot);
            model.multiply(tmpMat);

            mvp.set(vp);
            mvp.multiply(model);

You should always use a delta time component to achieve smooth animation, and here we can see that this means we’ll need to create a temporary quaternion (tmpRot) to hold the amount of rotation we need to be added to the current orientation quaternion (modelRot).  Aside from that once you have rotated your orientation you can apply it to your matrix calculations as you normally would.

As usual I’ve attached a fully working example, as well as the gimbal code its also an example of using lwjgl3 with GL > version 3 (ie all modern like!) so theres some utilities and math routines you might find handy.

Enjoy!

 

Posted in Uncategorized | Leave a comment

Adding startpage.com search engine to thunderbird

While I was quick to make use of the startpage.com “add search engine” button there isn’t really such a friendly method to add a search engine to thunderbird.

Long(ish) story short thunderbird and firefox use very similar methods to store your profile information, the startpage.com configuration for firefox is stored in

/home/<your user name>/.mozilla/firefox/<a random string>.default/searchplugins

I noticed one article talked about adding google as a custom search engine and mentioned creating a searchplugins directory in your thunderbird profile

/home/<your user name>/.thunderbird/<a random string>.default/searchplugins

So I copied the file startpage-https—uk.xml from the firefox profile into the thunderbird profile.

It was just then a matter of searching for something in thunderbird using the current default, clicking the searchpage icon on the left and then setting it as the default (heart icon at the bottom left)

 

Posted in Uncategorized | Leave a comment

Gentoo, portage cheat sheet.

While there is a perfectly good cheat sheet here to be honest I tend to blog as much as an aide-mémoire for myself so I’ve made my own notes and condensed it down to what I find most useful, hopefully it should be also useful for others!

Update the package db

emerge --sync

This will update all the meta information allowing the system to see if there are updated packages available compared to what you have installed

Actually updating the system

emerge --ask --update --deep --with-bdeps=y --newuse @world

Almost every occasion you use emerge always use the ––ask parameter this will do a dry run and ask if this is what’s intended, take for example this

emerge --ask glut

This would go ahead and install a load of haskel packages (something you might not have intended) as glut appears as part of dev-haskell section of packages, contrast this with

emerge --ask freeglut

and you see a different picture – and this is a minor foobar compared to what you could do by blindly running emerge

back to the update command, all the stuff you ask to be installed is recorded in the “world package set”, so updating this with a deep dependency check while also including any new USE flags, should comprehensibly update your system…

 

clean up after an update

emerge --depclean --ask

You should notice after updating your system it mentions to do this but its worth mentioning!

Find config’s needing attention

find /etc/ -name "._cfg*"

I’ll admit I couldn’t find those _cfg files for a while till realising they were hidden (dot) files – a simple find command will list them for you, its then just a case of using diff or meld to check out the differences.

Exploring dependencies

installing gentoolkit allows finding out why a package got installed.  For example what packages need to have bash installed

equery d bash

Probably more useful, to find out what packages are needed by bash

equery g bash

Although you might find you want to restrict it to a version number and changing the depth to unlimited probably isn’t a good idea…

Uninstalling

There isn’t really an automated way to uninstall a package and its dependent packages as you could potentially gut your system, however a useful command is:

emerge --ask --depclean --verbose libsdl2

in this example you’ll get a list of all the dependent sdl libs like for example sdl2-image, you can then check all these and uninstall them, eventually you can then uninstall the original package too, another alternative after you’ve checked the dependent packages is to just use  ––unmerge followed up by a depclean on its own.  Be warned you still need to use ––ask when specifying a package for depclean, as it will uninstall stuff that doesn’t have dependent packages.

Of course I’ve not even touched on USE flags – that’s a whole other minefield ballgame and depends upon what you’re doing and to a certain extent taste, so maybe something for another post.

Posted in Uncategorized | Leave a comment