diff --git a/.cproject b/.cproject
index 3d5817da..54283f51 100644
--- a/.cproject
+++ b/.cproject
@@ -56,7 +56,6 @@
make
-
TestJNI.h
true
true
@@ -64,7 +63,6 @@
make
-
all
true
true
@@ -72,12 +70,19 @@
make
-
clean
true
true
true
+
+ make
+
+ picalculatornative.dll
+ true
+ true
+ true
+
diff --git a/MmapByteBuffer.java b/MmapByteBuffer.java
new file mode 100644
index 00000000..e2772a5a
--- /dev/null
+++ b/MmapByteBuffer.java
@@ -0,0 +1,33 @@
+package org.warp.picalculator;
+
+import java.nio.ByteBuffer;
+
+public class MmapByteBuffer {
+ private int fd;
+ private int address;
+ private int length;
+ private ByteBuffer buffer;
+
+ public MmapByteBuffer(int fd, int address, int length, ByteBuffer buffer) {
+ this.fd = fd;
+ this.address = address;
+ this.length = length;
+ this.buffer = buffer;
+ }
+
+ public int getFd() {
+ return fd;
+ }
+
+ public int getAddress() {
+ return address;
+ }
+
+ public int getLength() {
+ return length;
+ }
+
+ public ByteBuffer getBuffer() {
+ return buffer;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/warp/picalculator/MmapByteBuffer.java b/src/main/java/org/warp/picalculator/MmapByteBuffer.java
new file mode 100644
index 00000000..a12a5bf2
--- /dev/null
+++ b/src/main/java/org/warp/picalculator/MmapByteBuffer.java
@@ -0,0 +1,34 @@
+package org.warp.picalculator;
+
+
+import java.nio.ByteBuffer;
+
+public class MmapByteBuffer {
+ private int fd;
+ private int address;
+ private int length;
+ private ByteBuffer buffer;
+
+ public MmapByteBuffer(int fd, int address, int length, ByteBuffer buffer) {
+ this.fd = fd;
+ this.address = address;
+ this.length = length;
+ this.buffer = buffer;
+ }
+
+ public int getFd() {
+ return fd;
+ }
+
+ public int getAddress() {
+ return address;
+ }
+
+ public int getLength() {
+ return length;
+ }
+
+ public ByteBuffer getBuffer() {
+ return buffer;
+ }
+}
\ No newline at end of file
diff --git a/src/main/java/org/warp/picalculator/TestJNI.java b/src/main/java/org/warp/picalculator/TestJNI.java
index d2853888..b5cebb85 100644
--- a/src/main/java/org/warp/picalculator/TestJNI.java
+++ b/src/main/java/org/warp/picalculator/TestJNI.java
@@ -1,21 +1,31 @@
package org.warp.picalculator;
import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.nio.file.Paths;
+import java.nio.file.StandardOpenOption;
+import org.warp.picalculator.MmapByteBuffer;
-import cz.adamh.utils.NativeUtils;
public class TestJNI {
- static {
- try {
- NativeUtils.loadLibraryFromJar("/picalculatornative.dll");
- } catch (IOException e) {
- e.printStackTrace(); // This is probably not the best way to handle exception :-)
- }
- }
- private native void sayHello();
-
- public static void main(String[] args) {
- // invoke the native method
- new TestJNI().sayHello();
- }
+ public TestJNI() {
+
+ }
+
+ static {
+ System.load("/boot/libpicalc.so");
+ }
+
+ private native MmapByteBuffer getDisplayBuffer();
+
+ private native void disposeDisplayBuffer();
+
+ public MmapByteBuffer retrieveBuffer() {
+ return getDisplayBuffer();
+ }
+
+ public void deleteBuffer() {
+ disposeDisplayBuffer();
+ }
}
\ No newline at end of file
diff --git a/src/main/java/org/warp/picalculator/gui/graphicengine/framebuffer/FBEngine.java b/src/main/java/org/warp/picalculator/gui/graphicengine/framebuffer/FBEngine.java
index 55edce99..15eddcbe 100644
--- a/src/main/java/org/warp/picalculator/gui/graphicengine/framebuffer/FBEngine.java
+++ b/src/main/java/org/warp/picalculator/gui/graphicengine/framebuffer/FBEngine.java
@@ -8,6 +8,8 @@ import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.util.concurrent.Semaphore;
+import org.warp.picalculator.MmapByteBuffer;
+import org.warp.picalculator.TestJNI;
import org.warp.picalculator.Utils;
import org.warp.picalculator.gui.graphicengine.BinaryFont;
import org.warp.picalculator.gui.graphicengine.GraphicEngine;
@@ -27,13 +29,16 @@ public class FBEngine implements GraphicEngine {
private static final int WIDTH = 480;
private static final int HEIGHT = 320;
private static final int[] SIZE = new int[] {WIDTH, HEIGHT};
+ private TestJNI jni = new TestJNI();
public FBRenderer r;
- private MappedByteBuffer fb, realFb;
+ private MappedByteBuffer fb;
+ MmapByteBuffer realFb;
private RandomAccessFile fbFileRW;
public volatile boolean initialized = false;
public Semaphore exitSemaphore = new Semaphore(0);
private boolean resizedTrigger = false;
+
@Override
public int[] getSize() {
return SIZE;
@@ -59,22 +64,15 @@ public class FBEngine implements GraphicEngine {
@Override
public void create(Runnable onInitialized) {
resizedTrigger = true;
- File fbFile = new File("/dev/fb1");
- try {
- fbFileRW = new RandomAccessFile(fbFile, "rw");
- final long fbLen = FB_DISPLAY_HEIGHT*FB_DISPLAY_WIDTH*(FB_DISPLAY_BPP/8);
- fb = (MappedByteBuffer) MappedByteBuffer.allocateDirect((int) fbLen);
- realFb = fbFileRW.getChannel().map(FileChannel.MapMode.READ_WRITE, 0, fbLen);
-
- r = new FBRenderer(this, fb);
-
- initialized = true;
- if (onInitialized != null)
- onInitialized.run();
- } catch (IOException ex) {
- System.err.println("Cannot read framebuffer fb1");
- ex.printStackTrace();
- }
+ realFb = jni.retrieveBuffer();
+ final long fbLen = realFb.getLength();
+ fb = (MappedByteBuffer) MappedByteBuffer.allocateDirect((int) fbLen);
+
+ r = new FBRenderer(this, fb);
+
+ initialized = true;
+ if (onInitialized != null)
+ onInitialized.run();
}
@Override
@@ -144,15 +142,14 @@ public class FBEngine implements GraphicEngine {
_________________TMP = 0;
}
_________________TMP++;
- realFb.clear();
- realFb.put(fb);
+ realFb.getBuffer().clear();
+ realFb.getBuffer().put(fb);
for (int i = 0; i < fb.capacity()/2; i++) {
- realFb.put(i, (byte) (0xFF));
+ realFb.getBuffer().put(i, (byte) (0xFF));
}
for (int i = fb.capacity()/2; i < fb.capacity(); i++) {
- realFb.put(i, (byte) (0x18));
+ realFb.getBuffer().put(i, (byte) (0x18));
}
- realFb.force();
}
@Override
diff --git a/src/main/jni/.gitignore b/src/main/jni/.gitignore
new file mode 100644
index 00000000..50638950
--- /dev/null
+++ b/src/main/jni/.gitignore
@@ -0,0 +1 @@
+/buffermanager.c
diff --git a/src/main/jni/CMakeLists.txt b/src/main/jni/CMakeLists.txt
new file mode 100644
index 00000000..0ffeefd5
--- /dev/null
+++ b/src/main/jni/CMakeLists.txt
@@ -0,0 +1,17 @@
+cmake_minimum_required(VERSION 2.8)
+project(picalculatornative)
+SET(COMPILE_DEFINITIONS -Werror)
+
+find_package(JNI REQUIRED)
+include_directories(${JNI_INCLUDE_DIRS})
+
+include_directories(/opt/vc/include)
+include_directories(/opt/vc/include/interface/vcos/pthreads)
+include_directories(/opt/vc/include/interface/vmcs_host)
+include_directories(/opt/vc/include/interface/vmcs_host/linux)
+
+link_directories(/opt/vc/lib)
+
+set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -std=c++11")
+set(SOURCE_FILES TestJNI.cpp)
+add_library(picalculatornative SHARED ${SOURCE_FILES})
\ No newline at end of file
diff --git a/src/main/jni/TestJNI.c b/src/main/jni/TestJNI.c
deleted file mode 100644
index a7ca4b05..00000000
--- a/src/main/jni/TestJNI.c
+++ /dev/null
@@ -1,9 +0,0 @@
-#include
-#include
-#include "TestJNI.h"
-
-JNIEXPORT void JNICALL Java_org_warp_picalculator_TestJNI_sayHello(JNIEnv *env, jobject thisObj)
-{
- printf("Hello World!\n");
- return;
-}
diff --git a/src/main/jni/TestJNI.cpp b/src/main/jni/TestJNI.cpp
new file mode 100644
index 00000000..9a951f7a
--- /dev/null
+++ b/src/main/jni/TestJNI.cpp
@@ -0,0 +1,75 @@
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include
+#include "TestJNI.h"
+
+int fbfd = -1;
+char *fbp = nullptr;
+struct fb_var_screeninfo vinfo;
+struct fb_fix_screeninfo finfo;
+
+
+JNIEXPORT void JNICALL Java_org_warp_picalculator_TestJNI_disposeDisplayBuffer(JNIEnv *env, jobject thisObj)
+{
+ if (fbp != nullptr) {
+ munmap(fbp, finfo.smem_len);
+ fbp = nullptr;
+ }
+ if (fbfd != -1) {
+ close(fbfd);
+ fbfd = -1;
+ }
+ return;
+}
+
+JNIEXPORT jobject JNICALL Java_org_warp_picalculator_TestJNI_getDisplayBuffer(JNIEnv *env, jobject thisObj)
+{
+
+ syslog(LOG_INFO, "[JNI NATIVE] INIT");
+
+ fbfd = open("/dev/fb1", O_RDWR);
+ if (fbfd == -1) {
+ syslog(LOG_ERR, "Unable to open secondary display");
+ return NULL;
+ }
+ if (ioctl(fbfd, FBIOGET_FSCREENINFO, &finfo)) {
+ syslog(LOG_ERR, "Unable to get secondary display information");
+ return NULL;
+ }
+ if (ioctl(fbfd, FBIOGET_VSCREENINFO, &vinfo)) {
+ syslog(LOG_ERR, "Unable to get secondary display information");
+ return NULL;
+ }
+
+ syslog(LOG_INFO, "Second display is %d x %d %dbps\n", vinfo.xres, vinfo.yres, vinfo.bits_per_pixel);
+
+ fbp = (char*) mmap(0, finfo.smem_len, PROT_READ | PROT_WRITE, MAP_SHARED, fbfd, 0);
+ if (fbp <= 0) {
+ syslog(LOG_ERR, "Unable to create mamory mapping");
+ close(fbfd);
+ return NULL;
+ }
+
+ char* class_name = "org/warp/picalculator/MmapByteBuffer";
+ jclass clz = env->FindClass(class_name);
+ if (clz == NULL) {
+ printf("Error, could not find class '%s'\n", class_name);
+ return NULL;
+ }
+ char* signature = "(IIILjava/nio/ByteBuffer;)V";
+ jmethodID constructor = env->GetMethodID( clz, "", signature);
+ if (constructor == NULL) {
+ printf("Error, could not find constructor %s %s\n", class_name, signature);
+ return NULL;
+ }
+
+ syslog(LOG_INFO, "[JNI NATIVE] DONE");
+ return env->NewObject(clz, constructor, fbfd, fbp, finfo.smem_len,
+ env->NewDirectByteBuffer(fbp, finfo.smem_len));
+}
diff --git a/src/main/jni/TestJNI.h b/src/main/jni/TestJNI.h
index 65b039db..4604c785 100644
--- a/src/main/jni/TestJNI.h
+++ b/src/main/jni/TestJNI.h
@@ -9,10 +9,18 @@ extern "C" {
#endif
/*
* Class: org_warp_picalculator_TestJNI
- * Method: sayHello
+ * Method: getDisplayBuffer
+ * Signature: ()Lorg/warp/picalculator/MmapByteBuffer;
+ */
+JNIEXPORT jobject JNICALL Java_org_warp_picalculator_TestJNI_getDisplayBuffer
+ (JNIEnv *, jobject);
+
+/*
+ * Class: org_warp_picalculator_TestJNI
+ * Method: disposeDisplayBuffer
* Signature: ()V
*/
-JNIEXPORT void JNICALL Java_org_warp_picalculator_TestJNI_sayHello
+JNIEXPORT void JNICALL Java_org_warp_picalculator_TestJNI_disposeDisplayBuffer
(JNIEnv *, jobject);
#ifdef __cplusplus
diff --git a/src/main/jni/TestJNI.o b/src/main/jni/TestJNI.o
deleted file mode 100644
index 956366cc..00000000
Binary files a/src/main/jni/TestJNI.o and /dev/null differ
diff --git a/src/main/jni/makefile b/src/main/jni/makefileOLD
similarity index 62%
rename from src/main/jni/makefile
rename to src/main/jni/makefileOLD
index 947fb5ce..8c494755 100644
--- a/src/main/jni/makefile
+++ b/src/main/jni/makefileOLD
@@ -6,16 +6,24 @@ PATH1B = org.warp.picalculator
# Define a virtual path for .class in the bin directory
vpath %.class $(CLASS_PATH)/$(PATH1A)
-all : picalculatornative.dll
+all : picalculatornative.so
# $@ matches the target, $< matches the first dependancy
-picalculatornative.dll : TestJNI.o
+picalculatornative.so : TestJNI.o
+ gcc -m64 -mtune=generic -Wl,--add-stdcall-alias -shared -o ../resources/$@ $<
+
+# $@ matches the target, $< matches the first dependancy
+picalculatornative.dll : windows_TestJNI.o
x86_64-w64-mingw32-gcc.exe -m64 -mtune=generic -Wl,--add-stdcall-alias -shared -o ../resources/$@ $<
# $@ matches the target, $< matches the first dependancy
-TestJNI.o : TestJNI.c TestJNI.h
+windows_TestJNI.o : TestJNI.c TestJNI.h
x86_64-w64-mingw32-gcc.exe -m64 -mtune=generic -I"G:\Program Files\Java\jdk1.8.0_144\include" -I"G:\Program Files\Java\jdk1.8.0_144\include\win32" -c $< -o $@
+# $@ matches the target, $< matches the first dependancy
+TestJNI.o : TestJNI.c TestJNI.h
+ gcc -m64 -mtune=generic -I"G:\Program Files\Java\jdk1.8.0_144\include" -I"G:\Program Files\Java\jdk1.8.0_144\include\win32" -c $< -o $@
+
# $* matches the target filename without the extension
TestJNI.h : TestJNI.class
javah -o "$*.h" -classpath "$(CLASS_PATH)" $(PATH1B).$*
diff --git a/src/main/resources/picalculatornative.dll b/src/main/resources/picalculatornative.dll
index f3258dbb..796e4479 100644
Binary files a/src/main/resources/picalculatornative.dll and b/src/main/resources/picalculatornative.dll differ