Saturday, January 16, 2016

ACSM file convertion

Use ADE - ADOBE DIGITAL EDITIONS to open the ACSM file, which will actually download the file on your computer.
On windows, the files will be downloaded in the user "My Documents" folder in the subdirectory "My Digital Editions" and will get the .PDF extension.
Then add the PDF files to Calibre, it will be imported and the DRM will be removed.
Prior to using Calibre, the "DRM Removal Tools" plugin from "Apprentice Alf" must be installed.

How to install "DRM Removal Tools" on Calibre 
  1. Download it from DeDRM tools including plugin for Calibre
  2. Follow the instructions from the blog: here

Friday, May 09, 2014

Run native binaries on Android: or run cross-compiled NDK application on an Android device.

What if you would like to run a program you cross compile with the NDK on your android device?

As requirements / assumptions:
  • You have a nice standalone application (e.g. a prefered GNU application) written e.g. in C or C++
  • Usualy, you run it on Linux or Cygwin. 
  • You want it on your mobile phone or tablet, 
    • BUT your phone runs Android 
    • AND it should be programmed with Java.
  • You don't want to write it anew in Java
  • You have cross compiled it with NDK
  • You don't want to root your phone or to make people root their phone to use your application. 
In this article I describe the steps that let you run your cross compiled binaries from an Android application. Since I assume you already have a cross compiled binary, I use a shell script as a binary.

  1. create an Android application for our experiment
  2. make a shell script
  3. modify the application in order to copy binaries from assets
  4. run the script
Create an Android application for our experiment using eclipse:
File>New Project...
Android> Android Application Project
Application Name: Test3
NEXT
NEXT
NEXT
NEXT
FINISH

Wait while eclipse is preparing the project... may take a bit of time...

To test it on your phone, if it is correctly configured for USB debugging...
Right click on Test3 in the Project Explorer tab in eclipse.
Run As>1. Android Application

Make a shell script:
Right click on the assets directory of your Test3 project.
New>File...
Give the File name: go.sh
Close the window that may just have opened.
Rightclick on it, open with>Test editor
Write the following in the file:
#!/system/bin/sh
echo "Hello from script"
exit 0


Close the file.

Modify the application in order to copy binaries from assets:
Open MainActivity.java
Add the following method in MainActivity class:
    /**
     * copy a file from the assets directory to the application dedicated
     * directory on the phone
     */
    private void copyAssets(String filename) {
        AssetManager assetManager = getAssets();

        InputStream src = null;
        OutputStream dst = null;
        Log.d(USER_SERVICE, "Copy from asset: " + filename);

        try {
            // get the destination path
            // i.e. path to where the application has write permissions
            String appFileDirectory = getFilesDir().getPath();
            Log.d(USER_SERVICE, "to: " + appFileDirectory);

            // open the source file
            src = assetManager.open(filename);

            // create destination file
            File outFile = new File(appFileDirectory, filename);
            dst = new FileOutputStream(outFile);

            // copy the file
            byte[] buf = new byte[4096];
            int rd_status;
            // copy until read EOF
            while ((rd_status = src.read(buf)) != -1) {
                dst.write(buf, 0, rd_status);
            }

            src.close();
            src = null;
            dst.flush();
            dst.close();
            dst = null;
        } catch (IOException e) {
            Log.e(USER_SERVICE, "ERROR while copying asset file: " + filename, e);
        }
        Log.d(USER_SERVICE, "Copy ok: " + filename);
    }


In method onCreate, call the copyAssets function:
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (savedInstanceState == null) {
            getSupportFragmentManager().beginTransaction()
                    .add(R.id.container, new PlaceholderFragment()).commit();
        }
       
        copyAssets("go.sh");
    }


This will copy the script from the assets directory to the directory where the application has write permission.

run the script 
Then we want to run that script.
To do that we need a Java method that runs system binaries. Add this method in the MainActivity class:
    public Boolean execProgram(String program) {
        Log.d(USER_SERVICE, "Start Exec: " + program);
        try {
            // load the program
            Runtime rt = Runtime.getRuntime();
            Process process = rt.exec(program);
          
            // catch input and output streams of the program
            DataOutputStream os = new DataOutputStream(process.getOutputStream());
            InputStreamReader is = new InputStreamReader(process.getInputStream());
            BufferedReader reader = new BufferedReader(is);
          
            // if necessary give stdin through
            // os.writeBytes( "some input\n" );
            os.flush();

            // execute the program
            process.waitFor();
          
            // get the stdout from the program
            String output = "[";
            int nb_words = 0;
            int read;
            char[] buffer = new char[4096];
            StringBuffer progOutput = new StringBuffer();
            while ((read = reader.read(buffer)) > 0) {
                progOutput.append(buffer, 0, read);
            }
            reader.close();
            output += progOutput;
            output += "]{" + Integer.toString(nb_words) + "}";

            Log.d(USER_SERVICE, "output=" + output);
            Log.d(USER_SERVICE, "finished Exec of " + program);
        } catch (IOException e) {
            Log.e(USER_SERVICE, "IO Error while running " + program, e);
            return false;
        } catch (InterruptedException e) {
            Log.e(USER_SERVICE, "IO Error while running " + program, e);
            return false;
        }
        return true;
    }


Modify again onCreate to make go.sh executable by calling chmod and then execute go.sh:
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (savedInstanceState == null) {
            getSupportFragmentManager().beginTransaction()
                    .add(R.id.container, new PlaceholderFragment()).commit();
        }
       
        copyAssets("go.sh");
        // make go.sh executable for everyone 777 or for me 744
        execProgram("/system/bin/chmod 744 " + getFilesDir().getPath() + "/go.sh");
        // execute go.sh
        execProgram(getFilesDir().getPath() + "/go.sh");

    }


Then you'll see the output on the LogCat messages.

Wednesday, May 07, 2014

How to JNI with ADT Eclipse Android Development Toolchain

Get the toolchain:
- download ADT: e.g.: adt-bundle-linux-x86-20140321.zip
- download NDK e.g.: android-ndk-r9d-linux-x86.tar.bz2

unzip adt-bundle-linux-x86-20140321.zip
tar -xjf android-ndk-r9d-linux-x86.tar.bz2

this will create two directories:
- adt-bundle-linux-x86-20140321
- android-ndk-r9d


run eclipse:
cd adt-bundle-linux-x86-20140321/eclipse
eclipse

Configure Eclipse:
in menu: Window>Preferences
then select: Android>NDK
there you'll give the location to: fiull/path/to/android-ndk-r9d

Create an empty new project:
File>New>Project...
Android>Android Application Project

Application Name: test2
NEXT
NEXT
NEXT
Blank Activity, then NEXT
FINISH

Add support for NDK to this app:
right click on application name in project explorer "test2".
Android Tools>Add Native Support...

Keep proposed library Name: test2
Finish

two files have been created in the subfolder jni:
- test2.cpp
- Android.mk

Write the C code:
In project explorer: open jni/test2.cpp

it already contains
#include


write the following code in jni/test2.cpp:
extern "C"
{
JNIEXPORT int JNICALL Java_com_example_test2_Test2Wrapper_myfunc
      (JNIEnv * je, jobject jobj)
    {
            return (3);
    }
}

The function name must be composed as follow:
- Java_
- package name (here com.example.test2) with dots replaced by underscores
- your class name that will receive the native code (here Test2Wrapper)
- the function name (here myfunc)

The function type here is int and it returns the value 3.
The function receive two obligaroty parameters:
JNIEnv * je, jobject jobj

To have more parameters, add them after those two, like this e.g. with two integers p1 and p2:
JNIEXPORT int JNICALL Java_com_example_test2_Test2Wrapper_myfunc
      (JNIEnv * je, jobject jobj, jint p1, jint p2)

Write makefile:
Android.mk is the makefile.
It is already written, so here, for the moment, nothing more to do ;-).
It should look like:
LOCAL_PATH := $(call my-dir)
include $(CLEAR_VARS)
LOCAL_MODULE    := test2
LOCAL_SRC_FILES := test2.cpp
include $(BUILD_SHARED_LIBRARY)


LOCAL_MODULEis given the name of the compiled library.
LOCAL_SRC_FILES is given a list of c or c++ files to be compiled.

write the Java wrapper:
For each function of the library you want to call from Java, you need to implement a native method of a wrapper class.
In our example we want to name the wrapper class: Test2Wrapper

In project explorer, open: src/com.example.test2
In this directory you have the MainActivity.java file.
Right click on  com.example.test2
new>Class
Name:  Test2Wrapper
FINISH

Modify the code as follow:
package com.example.test2;
public class Test2Wrapper {
    static {
        System.loadLibrary("test2");
    }
    public static native int func();

}







System.loadLibrary is given the name of the library compiled by Android.mk i.e. the one given to LOCAL_MODULE, here test2.


Call and use the wrapper:
Open the file: MainActivity.java
Modify the onCreate method as follow:
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);

        if (savedInstanceState == null) {
            getSupportFragmentManager().beginTransaction()
                    .add(R.id.container, new PlaceholderFragment()).commit();
        }

        // 2 lines added first to call the native function
        // then to display a message box with "3" written inside.
        String hello = Integer.toString(Test2Wrapper.func());
        new AlertDialog.Builder(this).setMessage(hello).show();

    }


Build and run the project:
Save all files. This should lead eclipse to compile automatically the files.
Right click on project name.
Run As>Android Application

That's all, folks!

Friday, February 28, 2014

remove info tips in XP explorer

HKEY_CURRENT_USER\ Software\ Microsoft\ Windows\ CurrentVersion\ Explorer\ Advanced
DWord EnableBalloonTips  = 0
DWord ShowInfoTip. = 0

Monday, December 10, 2012

VMWare keyboard issues with Linux host

For a long time, after entering the guest OS in a VMware Session, I got my keyboard configuration (key repeat, ...) messed up.
I also got wrong key configuration in the guest OS.
Recently, I found a solution in another blog from Lain (http://nthrbldyblg.blogspot.fr/2008/06/vmware-and-fubar-keyboard-effect.html)

To solve my problems, in /etc/vmware/config :

1) add the following line:
xkeymap.nokeycodeMap = true
 
2) If some keys are still not correctly mapped, add key maps like:
xkeymap.keycode.108 = 0x138 # Alt_R

Where 108 is the keycode, and 0x138 the scancode.

Keycode

Lain proposes a method to find the key codes using xev. Type xev in a console, and in the xev window, type the key from which you want the keycode. The output from xev is displayed in the console from which it was launched.
You'll get a lot of output, and one like the following:

KeyPress event, serial 34, synthetic NO, window 0x3a00001,
    root 0x2c9, subw 0x3a00002, time 1210037349, (26,59), root:(2657,596),
    state 0x2010, keycode 108 (keysym 0xfe03, ISO_Level3_Shift), same_screen YES,
    XKeysymToKeycode returns keycode: 92
    XLookupString gives 0 bytes:
    XmbLookupString gives 0 bytes:
    XFilterEvent returns: False


In this output, one can find the keycode (108 here).

Scancode

The scancode can be found here (http://www.vmware.com/support/ws55/doc/ws_devices_keymap_vscan.html).
I put a copy herein for convenience:
These are the v-scan codes for the 104-key U.S. keyboard:

Symbol Shifted symbol Location V-scan code
Esc     0x001
1 !   0x002
2 @   0x003
3 #   0x004
4 $   0x005
5 %   0x006
6 ^   0x007
7 &   0x008
8 *   0x009
9 (   0x00a
0 )   0x00b
- _   0x00c
= +   0x00d
Backspace     0x00e
Tab     0x00f
Q     0x010
W     0x011
E     0x012
R     0x013
T     0x014
Y     0x015
U     0x016
I     0x017
O     0x018
P     0x019
[ {   0x01a
] }   0x01b
Enter     0x01c
Ctrl   left 0x01d
A     0x01e
S     0x01f
D     0x020
F     0x021
G     0x022
H     0x023
J     0x024
K     0x025
L     0x026
;     0x027
'     0x028
`     0x029
Shift   left 0x02a
\ |   0x02b
Z     0x02c
X     0x02d
C     0x02e
V     0x02f
B     0x030
N     0x031
M     0x032
, <   0x033
. >   0x034
/ ?   0x035
Shift   right 0x036
*   numeric pad 0x037
Alt   left 0x038
Space bar     0x039
Caps Lock     0x03a
F1     0x03b
F2     0x03c
F3     0x03d
F4     0x03e
F5     0x03f
F6     0x040
F7     0x041
F8     0x042
F9     0x043
F10     0x044
Num Lock   numeric pad 0x045
Scroll Lock     0x046
Home 7 numeric pad 0x047
Up arrow 8 numeric pad 0x048
PgUp 9 numeric pad 0x049
-   numeric pad 0x04a
Left arrow 4 numeric pad 0x04b
5   numeric pad 0x04c
Right arrow 6 numeric pad 0x04d
+   numeric pad 0x04e
End 1 numeric pad 0x04f
Down arrow 2 numeric pad 0x050
PgDn 3 numeric pad 0x051
Ins 0 numeric pad 0x052
Del   numeric pad 0x053
F11     0x057
F12     0x058
Break Pause   0x100
Enter   numeric pad 0x11c
Ctrl   right 0x11d
/   numeric pad 0x135
SysRq Print Scrn   0x137
Alt   right 0x138
Home   function pad 0x147
Up arrow   function pad 0x148
Page Up   function pad 0x149
Left arrow   function pad 0x14b
Right arrow   function pad 0x14d
End   function pad 0x14f
Down arrow   function pad 0x150
Page Down   function pad 0x151
Insert   function pad 0x152
Delete   function pad 0x153
Windows   left 0x15b
Windows   right 0x15c
Menu     0x15d

The 84-key keyboard has a Sys Req key on the numeric pad:

Symbol Shifted symbol Location V-scan code
Sys Req   numeric pad 0x054

Keyboards outside the U.S. usually have an extra key (often < > or < > | ) next to the left shift key:

Symbol Shifted symbol Location V-scan code
< >   0x056

Sunday, October 07, 2012

pk-command-not-found 100% CPU

I can't tell why, but for some version / distrib of Linux, from time to time, one can experience a 100% CPU load. Doing a top shows that pk-command-not-found is using the CPU...
pk-command-not-found is here /usr/libexec/pk-command-not-found
It is called by /etc/profile.d/PackageKit.sh
It should launch a window asking the user to install a package containing the requested command which wasn't found by the system.
There is another way to get an error message.
Edit  /etc/profile.d/PackageKit.sh
change runcnf=1 to runcnf=0 at the beginning.
Then you'll get  bash: xxxx: command not found
Where xxxx will be the command name that was not found.

Wednesday, July 11, 2012

Rename files with spaces and other unwanted chars (like from MAC)

Some times, I get files from MAC users and... they use all that what the system bring them:
spaces, accents (é ç à è ê ...), and others (&, ° ...)

It is a not easy and time consuming to remove them by hand.
So I made a script. But dealing with spaces was a BIG deal. So I post it.

NOTE: I put my scripts in the $HOME/bin directory so they can be called from everywhere.
  • macos2linux_files.sh scans the current directory for file names to convert and do the job.
  • names_to_char7_echo_mv.sh is creating a mv command when the file name need to be renamed and and do the real hard job :"dealing with spaces"
  • names_to_char7.sh is called to convert the name

Read more »