diff --git a/AndroidManifest.xml b/AndroidManifest.xml index fb61f03..681f7af 100644 --- a/AndroidManifest.xml +++ b/AndroidManifest.xml @@ -1,28 +1,48 @@ - - - - - - + android:versionName="0.89" android:versionCode="40" package="org.onaips.vnc_donate"> + + + + + + - - - + + + - - + + - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + \ No newline at end of file diff --git a/bin/avnc.apk b/bin/avnc.apk index 53aacc2..3e13a2a 100644 Binary files a/bin/avnc.apk and b/bin/avnc.apk differ diff --git a/bin/avnc_signed.apk b/bin/avnc_signed.apk new file mode 100644 index 0000000..eef3bc2 Binary files /dev/null and b/bin/avnc_signed.apk differ diff --git a/bin/classes.dex b/bin/classes.dex index 1582b15..df0fcc1 100644 Binary files a/bin/classes.dex and b/bin/classes.dex differ diff --git a/bin/ndk/local/armeabi/androidvncserver b/bin/ndk/local/armeabi/androidvncserver index 296e5a3..3fb4d36 100755 Binary files a/bin/ndk/local/armeabi/androidvncserver and b/bin/ndk/local/armeabi/androidvncserver differ diff --git a/bin/ndk/local/armeabi/libjpeg.a b/bin/ndk/local/armeabi/libjpeg.a index e006ed8..27650b3 100644 Binary files a/bin/ndk/local/armeabi/libjpeg.a and b/bin/ndk/local/armeabi/libjpeg.a differ diff --git a/bin/ndk/local/armeabi/objs/androidvncserver/fbvncserver.o b/bin/ndk/local/armeabi/objs/androidvncserver/fbvncserver.o index 23b2119..f5ae126 100644 Binary files a/bin/ndk/local/armeabi/objs/androidvncserver/fbvncserver.o and b/bin/ndk/local/armeabi/objs/androidvncserver/fbvncserver.o differ diff --git a/bin/org/onaips/vnc_donate/MainActivity$1.class b/bin/org/onaips/vnc_donate/MainActivity$1.class new file mode 100644 index 0000000..c6ba76c Binary files /dev/null and b/bin/org/onaips/vnc_donate/MainActivity$1.class differ diff --git a/bin/org/onaips/vnc_donate/MainActivity$10.class b/bin/org/onaips/vnc_donate/MainActivity$10.class new file mode 100644 index 0000000..9ea2695 Binary files /dev/null and b/bin/org/onaips/vnc_donate/MainActivity$10.class differ diff --git a/bin/org/onaips/vnc_donate/MainActivity$11.class b/bin/org/onaips/vnc_donate/MainActivity$11.class new file mode 100644 index 0000000..c213b81 Binary files /dev/null and b/bin/org/onaips/vnc_donate/MainActivity$11.class differ diff --git a/bin/org/onaips/vnc_donate/MainActivity$2$1.class b/bin/org/onaips/vnc_donate/MainActivity$2$1.class new file mode 100644 index 0000000..6b218cf Binary files /dev/null and b/bin/org/onaips/vnc_donate/MainActivity$2$1.class differ diff --git a/bin/org/onaips/vnc_donate/MainActivity$2.class b/bin/org/onaips/vnc_donate/MainActivity$2.class new file mode 100644 index 0000000..785991b Binary files /dev/null and b/bin/org/onaips/vnc_donate/MainActivity$2.class differ diff --git a/bin/org/onaips/vnc_donate/MainActivity$3.class b/bin/org/onaips/vnc_donate/MainActivity$3.class new file mode 100644 index 0000000..a4fad5f Binary files /dev/null and b/bin/org/onaips/vnc_donate/MainActivity$3.class differ diff --git a/bin/org/onaips/vnc_donate/MainActivity$4.class b/bin/org/onaips/vnc_donate/MainActivity$4.class new file mode 100644 index 0000000..d961210 Binary files /dev/null and b/bin/org/onaips/vnc_donate/MainActivity$4.class differ diff --git a/bin/org/onaips/vnc_donate/MainActivity$5.class b/bin/org/onaips/vnc_donate/MainActivity$5.class new file mode 100644 index 0000000..144525f Binary files /dev/null and b/bin/org/onaips/vnc_donate/MainActivity$5.class differ diff --git a/bin/org/onaips/vnc_donate/MainActivity$6$1.class b/bin/org/onaips/vnc_donate/MainActivity$6$1.class new file mode 100644 index 0000000..b9183df Binary files /dev/null and b/bin/org/onaips/vnc_donate/MainActivity$6$1.class differ diff --git a/bin/org/onaips/vnc_donate/MainActivity$6.class b/bin/org/onaips/vnc_donate/MainActivity$6.class new file mode 100644 index 0000000..8aa0cb4 Binary files /dev/null and b/bin/org/onaips/vnc_donate/MainActivity$6.class differ diff --git a/bin/org/onaips/vnc_donate/MainActivity$7.class b/bin/org/onaips/vnc_donate/MainActivity$7.class new file mode 100644 index 0000000..515ab30 Binary files /dev/null and b/bin/org/onaips/vnc_donate/MainActivity$7.class differ diff --git a/bin/org/onaips/vnc_donate/MainActivity$8.class b/bin/org/onaips/vnc_donate/MainActivity$8.class new file mode 100644 index 0000000..77692bd Binary files /dev/null and b/bin/org/onaips/vnc_donate/MainActivity$8.class differ diff --git a/bin/org/onaips/vnc_donate/MainActivity$9.class b/bin/org/onaips/vnc_donate/MainActivity$9.class new file mode 100644 index 0000000..69300d3 Binary files /dev/null and b/bin/org/onaips/vnc_donate/MainActivity$9.class differ diff --git a/bin/org/onaips/vnc_donate/MainActivity$mReceiver.class b/bin/org/onaips/vnc_donate/MainActivity$mReceiver.class new file mode 100644 index 0000000..f5def33 Binary files /dev/null and b/bin/org/onaips/vnc_donate/MainActivity$mReceiver.class differ diff --git a/bin/org/onaips/vnc_donate/MainActivity.class b/bin/org/onaips/vnc_donate/MainActivity.class new file mode 100644 index 0000000..0cbc8b0 Binary files /dev/null and b/bin/org/onaips/vnc_donate/MainActivity.class differ diff --git a/bin/org/onaips/vnc_donate/R$array.class b/bin/org/onaips/vnc_donate/R$array.class new file mode 100644 index 0000000..2dcec7e Binary files /dev/null and b/bin/org/onaips/vnc_donate/R$array.class differ diff --git a/bin/org/onaips/vnc_donate/R$attr.class b/bin/org/onaips/vnc_donate/R$attr.class new file mode 100644 index 0000000..70a54a3 Binary files /dev/null and b/bin/org/onaips/vnc_donate/R$attr.class differ diff --git a/bin/org/onaips/vnc_donate/R$drawable.class b/bin/org/onaips/vnc_donate/R$drawable.class new file mode 100644 index 0000000..2369cd6 Binary files /dev/null and b/bin/org/onaips/vnc_donate/R$drawable.class differ diff --git a/bin/org/onaips/vnc_donate/R$id.class b/bin/org/onaips/vnc_donate/R$id.class new file mode 100644 index 0000000..9fbb5d1 Binary files /dev/null and b/bin/org/onaips/vnc_donate/R$id.class differ diff --git a/bin/org/onaips/vnc_donate/R$layout.class b/bin/org/onaips/vnc_donate/R$layout.class new file mode 100644 index 0000000..c2c6bc8 Binary files /dev/null and b/bin/org/onaips/vnc_donate/R$layout.class differ diff --git a/bin/org/onaips/vnc_donate/R$menu.class b/bin/org/onaips/vnc_donate/R$menu.class new file mode 100644 index 0000000..eaa3a7b Binary files /dev/null and b/bin/org/onaips/vnc_donate/R$menu.class differ diff --git a/bin/org/onaips/vnc_donate/R$raw.class b/bin/org/onaips/vnc_donate/R$raw.class new file mode 100644 index 0000000..c513a2b Binary files /dev/null and b/bin/org/onaips/vnc_donate/R$raw.class differ diff --git a/bin/org/onaips/vnc_donate/R$string.class b/bin/org/onaips/vnc_donate/R$string.class new file mode 100644 index 0000000..eec2e30 Binary files /dev/null and b/bin/org/onaips/vnc_donate/R$string.class differ diff --git a/bin/org/onaips/vnc_donate/R$styleable.class b/bin/org/onaips/vnc_donate/R$styleable.class new file mode 100644 index 0000000..e82bf77 Binary files /dev/null and b/bin/org/onaips/vnc_donate/R$styleable.class differ diff --git a/bin/org/onaips/vnc_donate/R$xml.class b/bin/org/onaips/vnc_donate/R$xml.class new file mode 100644 index 0000000..35272f5 Binary files /dev/null and b/bin/org/onaips/vnc_donate/R$xml.class differ diff --git a/bin/org/onaips/vnc_donate/R.class b/bin/org/onaips/vnc_donate/R.class new file mode 100644 index 0000000..486b762 Binary files /dev/null and b/bin/org/onaips/vnc_donate/R.class differ diff --git a/bin/org/onaips/vnc_donate/StartAtBootService.class b/bin/org/onaips/vnc_donate/StartAtBootService.class new file mode 100644 index 0000000..2e94cb9 Binary files /dev/null and b/bin/org/onaips/vnc_donate/StartAtBootService.class differ diff --git a/bin/org/onaips/vnc_donate/StartAtBootServiceReceiver.class b/bin/org/onaips/vnc_donate/StartAtBootServiceReceiver.class new file mode 100644 index 0000000..8f4a1b3 Binary files /dev/null and b/bin/org/onaips/vnc_donate/StartAtBootServiceReceiver.class differ diff --git a/bin/org/onaips/vnc_donate/preferences.class b/bin/org/onaips/vnc_donate/preferences.class new file mode 100644 index 0000000..0d0cb50 Binary files /dev/null and b/bin/org/onaips/vnc_donate/preferences.class differ diff --git a/bin/resources.ap_ b/bin/resources.ap_ index 360a8e9..198b6e5 100644 Binary files a/bin/resources.ap_ and b/bin/resources.ap_ differ diff --git a/gen/org/onaips/vnc_donate/R.java b/gen/org/onaips/vnc_donate/R.java new file mode 100644 index 0000000..6f5b982 --- /dev/null +++ b/gen/org/onaips/vnc_donate/R.java @@ -0,0 +1,198 @@ +/* AUTO-GENERATED FILE. DO NOT MODIFY. + * + * This class was automatically generated by the + * aapt tool from the resource data it found. It + * should not be modified by hand. + */ + +package org.onaips.vnc_donate; + +public final class R { + public static final class array { + public static final int rotation_values=0x7f070000; + public static final int scale_strings=0x7f070002; + public static final int scale_values=0x7f070001; + public static final int sleep_strings=0x7f070003; + public static final int startonboot_values=0x7f070004; + } + public static final class attr { + /**

Must be a color value, in the form of "#rgb", "#argb", +"#rrggbb", or "#aarrggbb". +

This may also be a reference to a resource (in the form +"@[package:]type:name") or +theme attribute (in the form +"?[package:][type:]name") +containing a value of this type. + */ + public static final int backgroundColor=0x7f010000; + /**

Must be a string value, using '\\;' to escape characters such as '\\n' or '\\uxxxx' for a unicode character. +

This may also be a reference to a resource (in the form +"@[package:]type:name") or +theme attribute (in the form +"?[package:][type:]name") +containing a value of this type. + */ + public static final int keywords=0x7f010003; + /**

Must be a color value, in the form of "#rgb", "#argb", +"#rrggbb", or "#aarrggbb". +

This may also be a reference to a resource (in the form +"@[package:]type:name") or +theme attribute (in the form +"?[package:][type:]name") +containing a value of this type. + */ + public static final int primaryTextColor=0x7f010001; + /**

Must be an integer value, such as "100". +

This may also be a reference to a resource (in the form +"@[package:]type:name") or +theme attribute (in the form +"?[package:][type:]name") +containing a value of this type. + */ + public static final int refreshInterval=0x7f010004; + /**

Must be a color value, in the form of "#rgb", "#argb", +"#rrggbb", or "#aarrggbb". +

This may also be a reference to a resource (in the form +"@[package:]type:name") or +theme attribute (in the form +"?[package:][type:]name") +containing a value of this type. + */ + public static final int secondaryTextColor=0x7f010002; + } + public static final class drawable { + public static final int bg=0x7f020000; + public static final int btnstart=0x7f020001; + public static final int btnstart_normal=0x7f020002; + public static final int btnstart_pressed=0x7f020003; + public static final int btnstop=0x7f020004; + public static final int btnstop_normal=0x7f020005; + public static final int btnstop_pressed=0x7f020006; + public static final int droidvnclogo=0x7f020007; + public static final int icon=0x7f020008; + } + public static final class id { + public static final int Button01=0x7f090000; + public static final int Button02=0x7f090001; + public static final int TextView01=0x7f090002; + public static final int TextView02=0x7f090004; + public static final int preferences=0x7f090005; + public static final int stateLabel=0x7f090003; + } + public static final class layout { + public static final int main=0x7f030000; + } + public static final class menu { + public static final int menu=0x7f080000; + } + public static final class raw { + public static final int androidvncserver=0x7f050000; + public static final int indexvnc=0x7f050001; + public static final int vncviewer=0x7f050002; + } + public static final class string { + public static final int app_name=0x7f060000; + public static final int device_info_fmt=0x7f060001; + public static final int package_name=0x7f060002; + } + public static final class xml { + public static final int preferences=0x7f040000; + } + public static final class styleable { + /** Attributes that can be used with a com_admob_android_ads_AdView. +

Includes the following attributes:

+ + + + + + + + + +
AttributeDescription
{@link #com_admob_android_ads_AdView_backgroundColor org.onaips.vnc_donate:backgroundColor}
{@link #com_admob_android_ads_AdView_keywords org.onaips.vnc_donate:keywords}
{@link #com_admob_android_ads_AdView_primaryTextColor org.onaips.vnc_donate:primaryTextColor}
{@link #com_admob_android_ads_AdView_refreshInterval org.onaips.vnc_donate:refreshInterval}
{@link #com_admob_android_ads_AdView_secondaryTextColor org.onaips.vnc_donate:secondaryTextColor}
+ @see #com_admob_android_ads_AdView_backgroundColor + @see #com_admob_android_ads_AdView_keywords + @see #com_admob_android_ads_AdView_primaryTextColor + @see #com_admob_android_ads_AdView_refreshInterval + @see #com_admob_android_ads_AdView_secondaryTextColor + */ + public static final int[] com_admob_android_ads_AdView = { + 0x7f010000, 0x7f010001, 0x7f010002, 0x7f010003, + 0x7f010004 + }; + /** +

This symbol is the offset where the {@link org.onaips.vnc_donate.R.attr#backgroundColor} + attribute's value can be found in the {@link #com_admob_android_ads_AdView} array. + + +

Must be a color value, in the form of "#rgb", "#argb", +"#rrggbb", or "#aarrggbb". +

This may also be a reference to a resource (in the form +"@[package:]type:name") or +theme attribute (in the form +"?[package:][type:]name") +containing a value of this type. + @attr name android:backgroundColor + */ + public static final int com_admob_android_ads_AdView_backgroundColor = 0; + /** +

This symbol is the offset where the {@link org.onaips.vnc_donate.R.attr#keywords} + attribute's value can be found in the {@link #com_admob_android_ads_AdView} array. + + +

Must be a string value, using '\\;' to escape characters such as '\\n' or '\\uxxxx' for a unicode character. +

This may also be a reference to a resource (in the form +"@[package:]type:name") or +theme attribute (in the form +"?[package:][type:]name") +containing a value of this type. + @attr name android:keywords + */ + public static final int com_admob_android_ads_AdView_keywords = 3; + /** +

This symbol is the offset where the {@link org.onaips.vnc_donate.R.attr#primaryTextColor} + attribute's value can be found in the {@link #com_admob_android_ads_AdView} array. + + +

Must be a color value, in the form of "#rgb", "#argb", +"#rrggbb", or "#aarrggbb". +

This may also be a reference to a resource (in the form +"@[package:]type:name") or +theme attribute (in the form +"?[package:][type:]name") +containing a value of this type. + @attr name android:primaryTextColor + */ + public static final int com_admob_android_ads_AdView_primaryTextColor = 1; + /** +

This symbol is the offset where the {@link org.onaips.vnc_donate.R.attr#refreshInterval} + attribute's value can be found in the {@link #com_admob_android_ads_AdView} array. + + +

Must be an integer value, such as "100". +

This may also be a reference to a resource (in the form +"@[package:]type:name") or +theme attribute (in the form +"?[package:][type:]name") +containing a value of this type. + @attr name android:refreshInterval + */ + public static final int com_admob_android_ads_AdView_refreshInterval = 4; + /** +

This symbol is the offset where the {@link org.onaips.vnc_donate.R.attr#secondaryTextColor} + attribute's value can be found in the {@link #com_admob_android_ads_AdView} array. + + +

Must be a color value, in the form of "#rgb", "#argb", +"#rrggbb", or "#aarrggbb". +

This may also be a reference to a resource (in the form +"@[package:]type:name") or +theme attribute (in the form +"?[package:][type:]name") +containing a value of this type. + @attr name android:secondaryTextColor + */ + public static final int com_admob_android_ads_AdView_secondaryTextColor = 2; + }; +} diff --git a/jni/vnc/Android.mk b/jni/vnc/Android.mk index 449093e..6c2f228 100755 --- a/jni/vnc/Android.mk +++ b/jni/vnc/Android.mk @@ -1,8 +1,8 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) -#LOCAL_CFLAGS += -DDONATE_VERSION -LOCAL_CFLAGS := -O3 -Wall +LOCAL_CFLAGS += -DDONATE_VERSION +LOCAL_CFLAGS += -Wall LOCAL_SRC_FILES:= \ @@ -51,4 +51,4 @@ LOCAL_MODULE:= androidvncserver LOCAL_LDLIBS := -lz -llog -include $(BUILD_EXECUTABLE) \ No newline at end of file +include $(BUILD_EXECUTABLE) diff --git a/jni/vnc/Android.mk~ b/jni/vnc/Android.mk~ index ae52dfc..28afae9 100755 --- a/jni/vnc/Android.mk~ +++ b/jni/vnc/Android.mk~ @@ -2,7 +2,7 @@ LOCAL_PATH:= $(call my-dir) include $(CLEAR_VARS) #LOCAL_CFLAGS += -DDONATE_VERSION -LOCAL_CFLAGS := -O3 +LOCAL_CFLAGS += -Wall LOCAL_SRC_FILES:= \ @@ -51,4 +51,4 @@ LOCAL_MODULE:= androidvncserver LOCAL_LDLIBS := -lz -llog -include $(BUILD_EXECUTABLE) \ No newline at end of file +include $(BUILD_EXECUTABLE) diff --git a/jni/vnc/LibVNCServer-0.9.7/examples/rotatetemplate.c b/jni/vnc/LibVNCServer-0.9.7/examples/rotatetemplate.c index 6f6710e..57dc052 100755 --- a/jni/vnc/LibVNCServer-0.9.7/examples/rotatetemplate.c +++ b/jni/vnc/LibVNCServer-0.9.7/examples/rotatetemplate.c @@ -1,19 +1,33 @@ #define OUT_T CONCAT3E(uint,OUT,_t) #define FUNCTION CONCAT2E(FUNCNAME,OUT) -static void rfbRotate(rfbScreenInfoPtr vncbuf,rfbScreenInfoPtr fbmmap) +static void FUNCTION(rfbScreenInfoPtr screen) { - uint_32_t * buffer = (uint_32_t*)screen->frameBuffer; + OUT_T* buffer = (OUT_T*)screen->frameBuffer; int i, j, w = screen->width, h = screen->height; - uint_32_t * newBuffer = (uint_32_t*)malloc(w * h * sizeof(uint_32_t)); + OUT_T* newBuffer = (OUT_T*)malloc(w * h * sizeof(OUT_T)); for (j = 0; j < h; j++) for (i = 0; i < w; i++) - newBuffer[(h - 1 - j + i * h)] = buffer[i + j * w]; + newBuffer[FUNC(i, j)] = buffer[i + j * w]; - memcpy(buffer, newBuffer, w * h * sizeof(uint_32_t)); + memcpy(buffer, newBuffer, w * h * sizeof(OUT_T)); free(newBuffer); +#ifdef SWAPDIMENSIONS + screen->width = h; + screen->paddedWidthInBytes = h * OUT / 8; + screen->height = w; + + { + rfbClientIteratorPtr iterator; + rfbClientPtr cl; + iterator = rfbGetClientIterator(screen); + while ((cl = rfbClientIteratorNext(iterator)) != NULL) + cl->newFBSizePending = 1; + } +#endif + rfbMarkRectAsModified(screen, 0, 0, screen->width, screen->height); } diff --git a/jni/vnc/LibVNCServer-0.9.7/examples/rotatetemplate.c~ b/jni/vnc/LibVNCServer-0.9.7/examples/rotatetemplate.c~ index ce3be0a..6f6710e 100755 --- a/jni/vnc/LibVNCServer-0.9.7/examples/rotatetemplate.c~ +++ b/jni/vnc/LibVNCServer-0.9.7/examples/rotatetemplate.c~ @@ -1,7 +1,7 @@ #define OUT_T CONCAT3E(uint,OUT,_t) #define FUNCTION CONCAT2E(FUNCNAME,OUT) -static void rfbRotate(rfbScreenInfoPtr vncbuf,rfbScreenInfoPtr screen) +static void rfbRotate(rfbScreenInfoPtr vncbuf,rfbScreenInfoPtr fbmmap) { uint_32_t * buffer = (uint_32_t*)screen->frameBuffer; int i, j, w = screen->width, h = screen->height; diff --git a/jni/vnc/fbvncserver.1c b/jni/vnc/fbvncserver.1c new file mode 100644 index 0000000..1b64eae --- /dev/null +++ b/jni/vnc/fbvncserver.1c @@ -0,0 +1,761 @@ +/* + * $Id$ + * + * This program is free software; you can redistribute it and/or modify it + * under the terms of the GNU General Public License as published by the + * Free Software Foundation; either version 2, or (at your option) any + * later version.* + * + * This program is distributed in the hope that it will be useful, but + * WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * General Public License for more details. + * + * This project is an adaptation of the original fbvncserver for the iPAQ + * and Zaurus. + * + * This is a modification from letsgoustc source, to handle uinput events and more + * + */ +#include +#include +#include +#include + +#include +#include +#include + +#include +#include /* For makedev() */ + +#include +#include +#include + +#include +#include +//android log +#include + +/* libvncserver */ +#include "rfb/rfb.h" +#include "libvncserver/scale.h" +#include "rfb/keysym.h" +#include "suinput.h" + +#define CONCAT2(a,b) a##b +#define CONCAT2E(a,b) CONCAT2(a,b) +#define CONCAT3(a,b,c) a##b##c +#define CONCAT3E(a,b,c) CONCAT3(a,b,c) + + +#define BUS_VIRTUAL 0x06 + + +/*****************************************************************************/ +/* Android does not use /dev/fb0. */ +#define FB_DEVICE "/dev/graphics/fb0" +static char VNC_PASSWORD[256] = ""; + +static struct fb_var_screeninfo scrinfo; +static struct fb_fix_screeninfo fscrinfo; +static int fbfd = -1; +static int inputfd = -1; + +static unsigned int *fbmmap = MAP_FAILED; +static unsigned int *vncbuf; +static unsigned int *cmpbuf; + +/* Android already has 5900 bound natively. */ +#define VNC_PORT 5901 +static rfbScreenInfoPtr vncscr; + +int idle=0,standby=0,change=0; +static int rotation=0,scaling=0; +/*****************************************************************************/ + +static void (*update_screen)(void)=NULL; +static void keyevent(rfbBool down, rfbKeySym key, rfbClientPtr cl); +static void ptrevent(int buttonMask, int x, int y, rfbClientPtr cl); +static void rotate(); + +/*****************************************************************************/ + +void update_fb_info() +{ + + if (ioctl(fbfd, FBIOGET_VSCREENINFO, &scrinfo) != 0) + { + __android_log_print(ANDROID_LOG_INFO,"VNC","ioctl error\n"); + exit(EXIT_FAILURE); + } +} + +int aki(int i,int j) +{ + + + return (j+scrinfo.yoffset)*scrinfo.xres_virtual+i+scrinfo.xoffset; +} + +#define PIXEL_TO_VIRTUALPIXEL(i,j) ((j+scrinfo.yoffset)*scrinfo.xres_virtual+i+scrinfo.xoffset) +#define ROTATE90 + +#define OUT 32 +#include "update_screen.c" +#define OUT 8 +#include "update_screen.c" +#define OUT 16 +#include "update_screen.c" + +static void init_fb(void) +{ + size_t pixels; + size_t bytespp; + + if ((fbfd = open(FB_DEVICE, O_RDWR)) == -1) + { + __android_log_print(ANDROID_LOG_INFO,"VNC","cannot open fb device %s\n", FB_DEVICE); + return; + // exit(EXIT_FAILURE); + } + + update_fb_info(); + + if (ioctl(fbfd, FBIOGET_FSCREENINFO, &fscrinfo) != 0) + { + __android_log_print(ANDROID_LOG_INFO,"VNC","ioctl error\n"); + exit(EXIT_FAILURE); + } + + pixels = scrinfo.xres * scrinfo.yres; + bytespp = scrinfo.bits_per_pixel /CHAR_BIT; + + __android_log_print(ANDROID_LOG_INFO,"VNC", "line_lenght=%d xres=%d, yres=%d, xresv=%d, yresv=%d, xoffs=%d, yoffs=%d, bpp=%d\n", + (int)fscrinfo.line_length,(int)scrinfo.xres, (int)scrinfo.yres, + (int)scrinfo.xres_virtual, (int)scrinfo.yres_virtual, + (int)scrinfo.xoffset, (int)scrinfo.yoffset, + (int)scrinfo.bits_per_pixel); + +// off_t o=0; + + //now handled with double buffer detection +// if (scrinfo.xres==480 && scrinfo.yres==854 && scrinfo.xres_virtual==480 +// && scrinfo.yres_virtual==854 && scrinfo.xoffset==448 && scrinfo.yoffset==1710) +/*if (scrinfo.bits_per_pixel==32) + // tweak for motorola droid + { + int off=scrinfo.xres*scrinfo.yres*scrinfo.bits_per_pixel/CHAR_BIT; + + int resto= off % sysconf(_SC_PAGE_SIZE); + o= off / sysconf(_SC_PAGE_SIZE); + if (resto) + o+=1; + + } */ + +// __android_log_print(ANDROID_LOG_INFO,"VNC","buffer offset=%d * %d\n",o,(int)sysconf(_SC_PAGE_SIZE)); +// +// fbmmap = mmap(NULL, (scrinfo.xres_virtual*scrinfo.yres_virtual)* bytespp , PROT_READ|PROT_READ , MAP_PRIVATE , fbfd, o*sysconf(_SC_PAGE_SIZE)); + fbmmap = mmap(NULL, (scrinfo.xres_virtual*scrinfo.yres_virtual)* bytespp , PROT_READ|PROT_READ , MAP_PRIVATE , fbfd, 0); + + + if (fbmmap == MAP_FAILED) + { + __android_log_print(ANDROID_LOG_INFO,"VNC","mmap failed\n"); + exit(EXIT_FAILURE); + } +} + +static void cleanup_fb(void) +{ + if(fbfd != -1) + { + close(fbfd); + } +} + +static void init_input() +{ + struct input_id id = { + BUS_VIRTUAL, /* Bus type. */ + 1, /* Vendor id. */ + 1, /* Product id. */ + 1 /* Version id. */ + }; + + if((inputfd = suinput_open("qwerty", &id)) == -1) + { + __android_log_print(ANDROID_LOG_INFO,"VNC","cannot create virtual kbd device.\n"); + // exit(EXIT_FAILURE); do not exit, so we still can see the framebuffer + } +} + +static void cleanup_kbd() +{ + if(inputfd != -1) + { + suinput_close(inputfd); + } +} + +/*****************************************************************************/ + +static rfbNewClientHookPtr clientHook(rfbClientPtr cl) +{ + if (scaling!=0 && scaling!=100) + { + rfbScalingSetup(cl, vncscr->width*scaling/100.0, vncscr->height*scaling/100.0); + + } + + return RFB_CLIENT_ACCEPT; +} + + +static void init_fb_server(int argc, char **argv) +{ + + __android_log_print(ANDROID_LOG_INFO,"VNC","Initializing server...\n"); + + vncbuf = calloc(scrinfo.xres * scrinfo.yres, scrinfo.bits_per_pixel/CHAR_BIT); + cmpbuf = calloc(scrinfo.xres * scrinfo.yres, scrinfo.bits_per_pixel/CHAR_BIT); + + assert(vncbuf != NULL); + assert(cmpbuf != NULL); + + + + if (rotation==0 || rotation==180) + vncscr = rfbGetScreen(&argc, argv, scrinfo.xres, scrinfo.yres, 0 /* not used */ , 3, scrinfo.bits_per_pixel/CHAR_BIT); + else + vncscr = rfbGetScreen(&argc, argv, scrinfo.yres, scrinfo.xres, 0 /* not used */ , 3, scrinfo.bits_per_pixel/CHAR_BIT); + + assert(vncscr != NULL); + + vncscr->desktopName = "Android"; + vncscr->frameBuffer =(char *)vncbuf; + vncscr->port = VNC_PORT; + + vncscr->kbdAddEvent = keyevent; + vncscr->ptrAddEvent = ptrevent; + vncscr->newClientHook = clientHook; + + if (strcmp(VNC_PASSWORD,"")!=0) + { + char **passwords = (char **)malloc(2 * sizeof(char **)); + passwords[0] = VNC_PASSWORD; + passwords[1] = NULL; + vncscr->authPasswdData = passwords; + vncscr->passwordCheck = rfbCheckPasswordByList; + } + +#ifdef DONATE_VERSION + vncscr->httpDir="/data/data/org.onaips.vnc_donate/"; +#else + vncscr->httpDir="/data/data/org.onaips.vnc/"; +#endif + vncscr->serverFormat.redShift=scrinfo.red.offset; + vncscr->serverFormat.greenShift=scrinfo.green.offset; + vncscr->serverFormat.blueShift=scrinfo.blue.offset; + + vncscr->serverFormat.redMax=((1<serverFormat.greenMax=((1<serverFormat.blueMax=((1<alwaysShared = TRUE; + vncscr->handleEventsEagerly = TRUE; + vncscr->deferUpdateTime = 5; + + rfbInitServer(vncscr); + + //assign update_screen depending on bpp + if (vncscr->serverFormat.bitsPerPixel == 32) + { + __android_log_print(ANDROID_LOG_INFO,"VNC","I'm on update_screen_32"); + update_screen=&CONCAT2E(update_screen_,32); + } + else if (vncscr->serverFormat.bitsPerPixel == 16) + { + __android_log_print(ANDROID_LOG_INFO,"VNC","I'm on update_screen_16"); + update_screen=&CONCAT2E(update_screen_,16); + } + else if (vncscr->serverFormat.bitsPerPixel == 8) + { + __android_log_print(ANDROID_LOG_INFO,"VNC","I'm on update_screen_8"); + update_screen=&CONCAT2E(update_screen_,8); + } + else { + rfbErr("Unsupported pixel depth: %d\n", + vncscr->serverFormat.bitsPerPixel); + return; + } + + + /* Mark as dirty since we haven't sent any updates at all yet. */ + + rfbMarkRectAsModified(vncscr, 0, 0, scrinfo.xres, scrinfo.yres); + rfbProcessEvents(vncscr, 100000); + +} + +static int keysym2scancode(rfbBool down, rfbKeySym c, rfbClientPtr cl, int *sh, int *alt); + + +static void keyevent(rfbBool down, rfbKeySym key, rfbClientPtr cl) +{ + int code; + + __android_log_print(ANDROID_LOG_INFO,"VNC","Got keysym: %04x (down=%d)\n", (unsigned int)key, (int)down); + + int sh = 0; + int alt = 0; + + if ((code = keysym2scancode(down, key, cl,&sh,&alt))) + { + + int ret; + + if (key && down) + { + if (sh) suinput_press(inputfd, 42); //left shift + if (alt) suinput_press(inputfd, 56); //left alt + + ret=suinput_press(inputfd,code); + ret=suinput_release(inputfd,code); + + if (alt) suinput_release(inputfd, 56); //left alt + if (sh) suinput_release(inputfd, 42); //left shift + } + else + ;//ret=suinput_release(inputfd,code); + + //__android_log_print(ANDROID_LOG_INFO,"VNC","injectKey (%d, %d) ret=%d\n", code , down,ret); + } +} + +// keyboard code modified from remote input by http://www.math.bme.hu/~morap/RemoteInput/ + +// q,w,e,r,t,y,u,i,o,p,a,s,d,f,g,h,j,k,l,z,x,c,v,b,n,m +int qwerty[] = {30,48,46,32,18,33,34,35,23,36,37,38,50,49,24,25,16,19,31,20,22,47,17,45,21,44}; +// ,!,",#,$,%,&,',(,),*,+,,,-,.,/ +int spec1[] = {57,2,40,4,5,6,8,40,10,11,9,13,51,12,52,52}; +int spec1sh[] = {0,1,1,1,1,1,1,0,1,1,1,1,0,0,0,1}; +// :,;,<,=,>,?,@ +int spec2[] = {39,39,227,13,228,53,215}; +int spec2sh[] = {1,0,1,1,1,1,0}; +// [,\,],^,_,` +int spec3[] = {26,43,27,7,12,399}; +int spec3sh[] = {0,0,0,1,1,0}; +// {,|,},~ +int spec4[] = {26,43,27,215,14}; +int spec4sh[] = {1,1,1,1,0}; + +static int keysym2scancode(rfbBool down, rfbKeySym c, rfbClientPtr cl, int *sh, int *alt) +{ + int real=1; + if ('a' <= c && c <= 'z') + return qwerty[c-'a']; + if ('A' <= c && c <= 'Z') + { + (*sh)=1; + return qwerty[c-'A']; + } + if ('1' <= c && c <= '9') + return c-'1'+2; + if (c == '0') + return 11; + if (32 <= c && c <= 47) + { + (*sh) = spec1sh[c-32]; + return spec1[c-32]; + } + if (58 <= c && c <= 64) + { + (*sh) = spec2sh[c-58]; + return spec2[c-58]; + } + if (91 <= c && c <= 96) + { + (*sh) = spec3sh[c-91]; + return spec3[c-91]; + } + if (123 <= c && c <= 127) + { + (*sh) = spec4sh[c-123]; + return spec4[c-123]; + } + switch(c) + { + case 0xff08: return 14;// backspace + case 0xff09: return 15;// tab + case 1: (*alt)=1; return 34;// ctrl+a + case 3: (*alt)=1; return 46;// ctrl+c + case 4: (*alt)=1; return 32;// ctrl+d + case 18: (*alt)=1; return 31;// ctrl+r + case 0xff0D: return 28;// enter + case 0xff1B: return 158;// esc -> back + case 0xFF51: return 105;// left -> DPAD_LEFT + case 0xFF53: return 106;// right -> DPAD_RIGHT + case 0xFF54: return 108;// down -> DPAD_DOWN + case 0xFF52: return 103;// up -> DPAD_UP + // case 360: return 232;// end -> DPAD_CENTER (ball click) + case 0xff50: return KEY_HOME;// home + case 0xFFC8: rfbShutdownServer(cl->screen,TRUE); return 0; //F11 disconnect + case 0xFFC9: + __android_log_print(ANDROID_LOG_INFO,"VNC","F12 closing..."); + exit(0); //F10 closes daemon + break; + case 0xffc1: down?rotate():0; return 0; // F4 rotate + case 0xffff: return 158;// del -> back + case 0xff55: return 229;// PgUp -> menu + case 0xffcf: return 127;// F2 -> search + case 0xff56: return 61;// PgUp -> call + case 0xff57: return 107;// End -> endcall + case 0xffc2: return 211;// F5 -> focus + case 0xffc3: return 212;// F6 -> camera + case 0xffc4: return 150;// F7 -> explorer + case 0xffc5: return 155;// F8 -> envelope + + case 50081: + case 225: (*alt)=1; + if (real) return 48; //a with acute + return 30; //a with acute -> a with ring above + case 50049: + case 193:(*sh)=1; (*alt)=1; + if (real) return 48; //A with acute + return 30; //A with acute -> a with ring above + case 50089: + case 233: (*alt)=1; return 18; //e with acute + case 50057: + case 201:(*sh)=1; (*alt)=1; return 18; //E with acute + case 50093: + case 0xffbf: (*alt)=1; + if (real) return 36; //i with acute + return 23; //i with acute -> i with grave + case 50061: + case 205: (*sh)=1; (*alt)=1; + if (real) return 36; //I with acute + return 23; //I with acute -> i with grave + case 50099: + case 243:(*alt)=1; + if (real) return 16; //o with acute + return 24; //o with acute -> o with grave + case 50067: + case 211:(*sh)=1; (*alt)=1; + if (real) return 16; //O with acute + return 24; //O with acute -> o with grave + case 50102: + case 246: (*alt)=1; return 25; //o with diaeresis + case 50070: + case 214: (*sh)=1; (*alt)=1; return 25; //O with diaeresis + case 50577: + case 245:(*alt)=1; + if (real) return 19; //Hungarian o + return 25; //Hungarian o -> o with diaeresis + case 50576: + case 213: (*sh)=1; (*alt)=1; + if (real) return 19; //Hungarian O + return 25; //Hungarian O -> O with diaeresis + case 50106: + // case 0xffbe: (*alt)=1; + // if (real) return 17; //u with acute + // return 22; //u with acute -> u with grave + case 50074: + case 218: (*sh)=1; (*alt)=1; + if (real) return 17; //U with acute + return 22; //U with acute -> u with grave + case 50108: + case 252: (*alt)=1; return 47; //u with diaeresis + case 50076: + case 220:(*sh)=1; (*alt)=1; return 47; //U with diaeresis + case 50609: + case 251: (*alt)=1; + if (real) return 45; //Hungarian u + return 47; //Hungarian u -> u with diaeresis + case 50608: + case 219: (*sh)=1; (*alt)=1; + if (real) return 45; //Hungarian U + return 47; //Hungarian U -> U with diaeresis + + } + return 0; +} + +// old key code, i'll need it for some missing things +/* +static int _keysym2scancode(rfbBool down, rfbKeySym key, rfbClientPtr cl) +{ + int scancode = 0; + + int code = (int)key; + if (code>='0' && code<='9') { + + scancode = (code & 0xF) - 1; + if (scancode<0) scancode += 10; + scancode += KEY_1; + } else if (code>=0xFF50 && code<=0xFF58) { + static const uint16_t map[] = + { KEY_HOME, KEY_LEFT, KEY_UP, KEY_RIGHT, KEY_DOWN, + KEY_SOFT1, KEY_SOFT2, KEY_END, 0 }; + + scancode = map[code & 0xF]; + } else if (code>=0xFFE1 && code<=0xFFEE) { + + + static const uint16_t map[] = + { KEY_LEFTSHIFT, KEY_LEFTSHIFT, + KEY_COMPOSE, KEY_COMPOSE, + KEY_LEFTSHIFT, KEY_LEFTSHIFT, + 0,0, + KEY_LEFTALT, KEY_RIGHTALT, + 0, 0, 0, 0 }; + scancode = map[code & 0xF]; + } else if ((code>='A' && code<='Z') || (code>='a' && code<='z')) { + + static const uint16_t map[] = { + KEY_A, KEY_B, KEY_C, KEY_D, KEY_E, + KEY_F, KEY_G, KEY_H, KEY_I, KEY_J, + KEY_K, KEY_L, KEY_M, KEY_N, KEY_O, + KEY_P, KEY_Q, KEY_R, KEY_S, KEY_T, + KEY_U, KEY_V, KEY_W, KEY_X, KEY_Y, KEY_Z }; + scancode = map[(code & 0x5F) - 'A']; + } else { + + switch (code) { + case 0x0003: scancode = KEY_CENTER; break; + case 0x0020: scancode = KEY_SPACE; break; + case 0x0023: scancode = KEY_SHARP; break; + case 0x0033: scancode = KEY_SHARP; break; + case 0x002C: scancode = KEY_COMMA; break; + case 0x003C: scancode = KEY_COMMA; break; + case 0x002E: scancode = KEY_DOT; break; + case 0x003E: scancode = KEY_DOT; break; + case 0x002F: scancode = KEY_SLASH; break; + case 0x003F: scancode = KEY_SLASH; break; + case 0x0032: scancode = KEY_EMAIL; break; + case 0x0040: scancode = KEY_EMAIL; break; + case 0xFF08: scancode = KEY_BACKSPACE; break; + case 0xFF1B: scancode = KEY_BACK; break; + case 0xFF09: scancode = KEY_TAB; break; + case 0xFF0D: scancode = KEY_ENTER; break; + case 0xFE51: scancode = 399; break; + case 0x002A: scancode = KEY_STAR; break; + case 0xFFBE: scancode = KEY_F1; break; // F1 + case 0xFFBF: scancode = KEY_F2; break; // F2 + case 0xFFC0: scancode = KEY_F3; break; // F3 + case 0xFFC1: down?rotate():0; break; // F4 rotate + case 0xFFC5: scancode = KEY_F4; break; // F8 + case 0xFFC8: rfbShutdownServer(cl->screen,TRUE); break; // F11 + } + } + + return scancode; +} +*/ + + +inline void transform_touch_coordinates(int *x, int *y) +{ + int scale=4096.0; + int old_x=*x,old_y=*y; + + if (rotation==0) + { + *x = old_x*scale/scrinfo.xres-scale/2.0; + *y = old_y*scale/scrinfo.yres-scale/2.0; + } + else if (rotation==90) + { + *x =old_y*scale/scrinfo.xres-scale/2.0; + *y = (scrinfo.yres - old_x)*scale/scrinfo.yres-scale/2.0; + } + else if (rotation==180) + { + *x =(scrinfo.xres - old_x)*scale/scrinfo.xres-scale/2.0; + *y =(scrinfo.yres - old_y)*scale/scrinfo.yres-scale/2.0; + } + else if (rotation==270) + { + *y =old_x*scale/scrinfo.yres-scale/2.0; + *x =(scrinfo.xres - old_y)*scale/scrinfo.xres-scale/2.0; + } + +} + +static void ptrevent(int buttonMask, int x, int y, rfbClientPtr cl) +{ + static int leftClicked=0,rightClicked=0,middleClicked=0; + + transform_touch_coordinates(&x,&y); + + if((buttonMask & 1)&& leftClicked) {//left btn clicked and moving + static int i=0; + i=i+1; + + if (i%10==1)//some tweak to not report every move event + { + suinput_write(inputfd, EV_ABS, ABS_X, x); + suinput_write(inputfd, EV_ABS, ABS_Y, y); + suinput_write(inputfd, EV_SYN, SYN_REPORT, 0); + } + } + else if (buttonMask & 1)//left btn clicked + { + leftClicked=1; + + suinput_write(inputfd, EV_ABS, ABS_X, x); + suinput_write(inputfd, EV_ABS, ABS_Y, y); + suinput_write(inputfd,EV_KEY,BTN_TOUCH,1); + suinput_write(inputfd, EV_SYN, SYN_REPORT, 0); + + + } + else if (leftClicked)//left btn released + { + leftClicked=0; + suinput_write(inputfd, EV_ABS, ABS_X, x); + suinput_write(inputfd, EV_ABS, ABS_Y, y); + suinput_write(inputfd,EV_KEY,BTN_TOUCH,0); + suinput_write(inputfd, EV_SYN, SYN_REPORT, 0); + } + + if (buttonMask & 4)//right btn clicked + { + rightClicked=1; + suinput_press(inputfd,158); //back key + } + else if (rightClicked)//right button released + { + rightClicked=0; + suinput_release(inputfd,158); + } + + if (buttonMask & 2)//mid btn clicked + { + middleClicked=1; + suinput_press( inputfd,KEY_END); + } + else if (middleClicked)// mid btn released + { + middleClicked=0; + suinput_release( inputfd,KEY_END); + } +} + +void sigproc() +{ + __android_log_print(ANDROID_LOG_INFO,"VNC","Cleaning up...\n"); + cleanup_fb(); + cleanup_kbd(); + exit(0); /* normal exit status */ +} + + + +static void rotate() +{ + rotation+=90; + rotation=rotation%360; + + + if (rotation==90 || rotation==270) + rfbNewFramebuffer(vncscr,(char*)vncbuf, scrinfo.yres, scrinfo.xres,0 /* not used */ , 3, scrinfo.bits_per_pixel/CHAR_BIT); + else + rfbNewFramebuffer(vncscr,(char*)vncbuf, scrinfo.xres, scrinfo.yres,0 /* not used */ , 3, scrinfo.bits_per_pixel/CHAR_BIT); + + vncscr->serverFormat.redShift=scrinfo.red.offset; + vncscr->serverFormat.greenShift=scrinfo.green.offset; + vncscr->serverFormat.blueShift=scrinfo.blue.offset; + + vncscr->serverFormat.redMax=((1<serverFormat.greenMax=((1<serverFormat.blueMax=((1<width, vncscr->height); + +} + +void print_usage(char **argv) +{ + __android_log_print(ANDROID_LOG_INFO,"VNC","androidvncserver [-p password] [-h]\n" + "-p password: Password to access server\n" + "-r rotation: Screen rotation (degrees) (0,90,180,270)\n" + "-s screen scale: percentage (20,30,50,100,150)\n" + "-h : print this help\n"); +} + + +int main(int argc, char **argv) +{ + signal(SIGINT, sigproc);//pipe signals + signal(SIGKILL, sigproc); + signal(SIGILL, sigproc); + + if(argc > 1) + { + int i=1; + int r; + while(i < argc) + { + if(*argv[i] == '-') + { + switch(*(argv[i] + 1)) + { + case 'h': + print_usage(argv); + exit(0); + break; + case 'p': + i++; + strcpy(VNC_PASSWORD,argv[i]); + break; + case 'r': + i++; + r=atoi(argv[i]); + if (r==0 || r==90 || r==180 || r==270) + rotation=r; + __android_log_print(ANDROID_LOG_INFO,"VNC","rotating to %d degrees\n",rotation); + break; + case 's': + i++; + r=atoi(argv[i]); + if (r>=1 && r <= 150) + scaling=r; + else + scaling=100; + __android_log_print(ANDROID_LOG_INFO,"VNC","scaling to %d percent\n",scaling); + break; + } + } + i++; + } + } + + __android_log_print(ANDROID_LOG_INFO,"VNC","Initializing framebuffer device " FB_DEVICE "...\n"); + init_fb(); + + __android_log_print(ANDROID_LOG_INFO,"VNC","Initializing virtual keyboard and touch device...\n"); + init_input(); + + __android_log_print(ANDROID_LOG_INFO,"VNC","Initializing VNC server:\n"); + __android_log_print(ANDROID_LOG_INFO,"VNC"," width: %d\n", (int)scrinfo.xres); + __android_log_print(ANDROID_LOG_INFO,"VNC"," height: %d\n", (int)scrinfo.yres); + __android_log_print(ANDROID_LOG_INFO,"VNC"," bpp: %d\n", (int)scrinfo.bits_per_pixel); + __android_log_print(ANDROID_LOG_INFO,"VNC"," port: %d\n", (int)VNC_PORT); + init_fb_server(argc, argv); + + while (1) + { + + while (vncscr->clientHead == NULL) + rfbProcessEvents(vncscr, 100000); + + update_screen(); + } + + __android_log_print(ANDROID_LOG_INFO,"VNC","Cleaning up...\n"); + cleanup_fb(); + cleanup_kbd(); +} diff --git a/jni/vnc/fbvncserver.c b/jni/vnc/fbvncserver.c index b660d5a..f243634 100755 --- a/jni/vnc/fbvncserver.c +++ b/jni/vnc/fbvncserver.c @@ -52,11 +52,12 @@ #define BUS_VIRTUAL 0x06 - /*****************************************************************************/ /* Android does not use /dev/fb0. */ -#define FB_DEVICE "/dev/graphics/fb0" -static char VNC_PASSWORD[256] = ""; + +char VNC_PASSWORD[256] = ""; +char framebuffer_device[256] = "/dev/graphics/fb0"; +int VNC_PORT=5901; static struct fb_var_screeninfo scrinfo; static struct fb_fix_screeninfo fscrinfo; @@ -68,9 +69,10 @@ static unsigned int *vncbuf; static unsigned int *cmpbuf; /* Android already has 5900 bound natively. */ -#define VNC_PORT 5901 + static rfbScreenInfoPtr vncscr; + int idle=0,standby=0,change=0; static int rotation=0,scaling=0; /*****************************************************************************/ @@ -79,12 +81,12 @@ static void (*update_screen)(void)=NULL; static void keyevent(rfbBool down, rfbKeySym key, rfbClientPtr cl); static void ptrevent(int buttonMask, int x, int y, rfbClientPtr cl); static void rotate(); - + /*****************************************************************************/ void update_fb_info() { - + if (ioctl(fbfd, FBIOGET_VSCREENINFO, &scrinfo) != 0) { __android_log_print(ANDROID_LOG_INFO,"VNC","ioctl error\n"); @@ -93,25 +95,33 @@ void update_fb_info() } +#define PIXEL_TO_VIRTUALPIXEL(i,j) ((j+scrinfo.yoffset)*scrinfo.xres_virtual+i) +// #define PIXEL_TO_VIRTUALPIXEL(i,j) ((j+scrinfo.yoffset)*scrinfo.xres_virtual+i+scrinfo.xoffset) + #define OUT 32 #include "update_screen.c" #define OUT 8 #include "update_screen.c" #define OUT 16 #include "update_screen.c" - + + +inline size_t roundUpToPageSize(size_t x) { + return (x + (PAGE_SIZE-1)) & ~(PAGE_SIZE-1); +} + static void init_fb(void) { size_t pixels; size_t bytespp; - if ((fbfd = open(FB_DEVICE, O_RDWR)) == -1) + if ((fbfd = open(framebuffer_device, O_RDWR)) == -1) { - __android_log_print(ANDROID_LOG_INFO,"VNC","cannot open fb device %s\n", FB_DEVICE); + __android_log_print(ANDROID_LOG_INFO,"VNC","cannot open fb device %s\n", framebuffer_device); return; // exit(EXIT_FAILURE); } - + update_fb_info(); if (ioctl(fbfd, FBIOGET_FSCREENINFO, &fscrinfo) != 0) @@ -123,33 +133,17 @@ static void init_fb(void) pixels = scrinfo.xres * scrinfo.yres; bytespp = scrinfo.bits_per_pixel /CHAR_BIT; - __android_log_print(ANDROID_LOG_INFO,"VNC", "xres=%d, yres=%d, xresv=%d, yresv=%d, xoffs=%d, yoffs=%d, bpp=%d\n", - (int)scrinfo.xres, (int)scrinfo.yres, + __android_log_print(ANDROID_LOG_INFO,"VNC", "line_lenght=%d xres=%d, yres=%d, xresv=%d, yresv=%d, xoffs=%d, yoffs=%d, bpp=%d\n", + (int)fscrinfo.line_length,(int)scrinfo.xres, (int)scrinfo.yres, (int)scrinfo.xres_virtual, (int)scrinfo.yres_virtual, (int)scrinfo.xoffset, (int)scrinfo.yoffset, (int)scrinfo.bits_per_pixel); - -// off_t o=0; - - //now handled with double buffer detection -// if (scrinfo.xres==480 && scrinfo.yres==854 && scrinfo.xres_virtual==480 -// && scrinfo.yres_virtual==854 && scrinfo.xoffset==448 && scrinfo.yoffset==1710) -/*if (scrinfo.bits_per_pixel==32) - // tweak for motorola droid - { - int off=scrinfo.xres*scrinfo.yres*scrinfo.bits_per_pixel/CHAR_BIT; - - int resto= off % sysconf(_SC_PAGE_SIZE); - o= off / sysconf(_SC_PAGE_SIZE); - if (resto) - o+=1; - - } */ - -// __android_log_print(ANDROID_LOG_INFO,"VNC","buffer offset=%d * %d\n",o,(int)sysconf(_SC_PAGE_SIZE)); -// -// fbmmap = mmap(NULL, (scrinfo.xres_virtual*scrinfo.yres_virtual)* bytespp , PROT_READ|PROT_READ , MAP_PRIVATE , fbfd, o*sysconf(_SC_PAGE_SIZE)); - fbmmap = mmap(NULL, (scrinfo.xres_virtual*scrinfo.yres_virtual)* bytespp , PROT_READ|PROT_READ , MAP_PRIVATE , fbfd, 0); + + printf("AKII\n"); + + size_t fbSize = roundUpToPageSize(fscrinfo.line_length * scrinfo.yres_virtual); + + fbmmap = mmap(NULL, fbSize , PROT_READ|PROT_WRITE , MAP_SHARED , fbfd, 0); if (fbmmap == MAP_FAILED) @@ -232,6 +226,7 @@ static void init_fb_server(int argc, char **argv) vncscr->kbdAddEvent = keyevent; vncscr->ptrAddEvent = ptrevent; vncscr->newClientHook = clientHook; + if (strcmp(VNC_PASSWORD,"")!=0) { @@ -258,7 +253,7 @@ static void init_fb_server(int argc, char **argv) vncscr->alwaysShared = TRUE; vncscr->handleEventsEagerly = TRUE; vncscr->deferUpdateTime = 5; - + rfbInitServer(vncscr); //assign update_screen depending on bpp @@ -286,9 +281,7 @@ static void init_fb_server(int argc, char **argv) /* Mark as dirty since we haven't sent any updates at all yet. */ - rfbMarkRectAsModified(vncscr, 0, 0, scrinfo.xres, scrinfo.yres); - rfbProcessEvents(vncscr, 100000); - + rfbMarkRectAsModified(vncscr, 0, 0, scrinfo.xres, scrinfo.yres); } static int keysym2scancode(rfbBool down, rfbKeySym c, rfbClientPtr cl, int *sh, int *alt); @@ -670,11 +663,12 @@ static void rotate() void print_usage(char **argv) { - __android_log_print(ANDROID_LOG_INFO,"VNC","androidvncserver [-p password] [-h]\n" + printf("androidvncserver [-p password] [-h]\n" "-p password: Password to access server\n" "-r rotation: Screen rotation (degrees) (0,90,180,270)\n" "-s screen scale: percentage (20,30,50,100,150)\n" - "-h : print this help\n"); + "-h : print this help\n" + "-f select framebuffer device\n;"); } @@ -702,6 +696,14 @@ int main(int argc, char **argv) i++; strcpy(VNC_PASSWORD,argv[i]); break; + case 'f': + i++; + strcpy(framebuffer_device,argv[i]); + break; + case 'P': + i++; + VNC_PORT=atoi(argv[i]); + break; case 'r': i++; r=atoi(argv[i]); @@ -711,10 +713,10 @@ int main(int argc, char **argv) break; case 's': i++; - r=atoi(argv[i]); + r=atoi(argv[i]); if (r>=1 && r <= 150) scaling=r; - else + else scaling=100; __android_log_print(ANDROID_LOG_INFO,"VNC","scaling to %d percent\n",scaling); break; @@ -722,9 +724,9 @@ int main(int argc, char **argv) } i++; } - } - - __android_log_print(ANDROID_LOG_INFO,"VNC","Initializing framebuffer device " FB_DEVICE "...\n"); + } + + __android_log_print(ANDROID_LOG_INFO,"VNC","Initializing framebuffer device...\n"); init_fb(); __android_log_print(ANDROID_LOG_INFO,"VNC","Initializing virtual keyboard and touch device...\n"); @@ -736,17 +738,44 @@ int main(int argc, char **argv) __android_log_print(ANDROID_LOG_INFO,"VNC"," bpp: %d\n", (int)scrinfo.bits_per_pixel); __android_log_print(ANDROID_LOG_INFO,"VNC"," port: %d\n", (int)VNC_PORT); init_fb_server(argc, argv); + /* + rfbRunEventLoop(vncscr,-1,TRUE); while (1) { + while (vncscr->clientHead == NULL) + sleep(1); + + if (standby>60) + sleep(2); + else if (standby>30) + sleep(1); + else + usleep(100000); - while (vncscr->clientHead == NULL) + update_screen(); + }*/ + + while (1) + { + while (vncscr->clientHead == NULL) rfbProcessEvents(vncscr, 100000); - - update_screen(); + + rfbMarkRectAsModified(vncscr, 0, 0, vncscr->width, vncscr->height); + + if (standby>60) + rfbProcessEvents(vncscr, 200000); + else if (standby>30) + rfbProcessEvents(vncscr, 100000); + else + rfbProcessEvents(vncscr, 10000); + + + update_screen(); } + __android_log_print(ANDROID_LOG_INFO,"VNC","Cleaning up...\n"); cleanup_fb(); cleanup_kbd(); -} \ No newline at end of file +} diff --git a/jni/vnc/fbvncserver.c~ b/jni/vnc/fbvncserver.c~ index a287cc3..049c81f 100755 --- a/jni/vnc/fbvncserver.c~ +++ b/jni/vnc/fbvncserver.c~ @@ -52,11 +52,12 @@ #define BUS_VIRTUAL 0x06 - /*****************************************************************************/ /* Android does not use /dev/fb0. */ -#define FB_DEVICE "/dev/graphics/fb0" -static char VNC_PASSWORD[256] = ""; + +char VNC_PASSWORD[256] = ""; +char framebuffer_device[256] = "/dev/graphics/fb0"; +char VNC_PORT[10]="5901"; static struct fb_var_screeninfo scrinfo; static struct fb_fix_screeninfo fscrinfo; @@ -68,9 +69,10 @@ static unsigned int *vncbuf; static unsigned int *cmpbuf; /* Android already has 5900 bound natively. */ -#define VNC_PORT 5901 + static rfbScreenInfoPtr vncscr; + int idle=0,standby=0,change=0; static int rotation=0,scaling=0; /*****************************************************************************/ @@ -79,12 +81,12 @@ static void (*update_screen)(void)=NULL; static void keyevent(rfbBool down, rfbKeySym key, rfbClientPtr cl); static void ptrevent(int buttonMask, int x, int y, rfbClientPtr cl); static void rotate(); - + /*****************************************************************************/ void update_fb_info() { - + if (ioctl(fbfd, FBIOGET_VSCREENINFO, &scrinfo) != 0) { __android_log_print(ANDROID_LOG_INFO,"VNC","ioctl error\n"); @@ -93,25 +95,33 @@ void update_fb_info() } +#define PIXEL_TO_VIRTUALPIXEL(i,j) ((j+scrinfo.yoffset)*scrinfo.xres_virtual+i) +// #define PIXEL_TO_VIRTUALPIXEL(i,j) ((j+scrinfo.yoffset)*scrinfo.xres_virtual+i+scrinfo.xoffset) + #define OUT 32 #include "update_screen.c" #define OUT 8 #include "update_screen.c" #define OUT 16 #include "update_screen.c" - + + +inline size_t roundUpToPageSize(size_t x) { + return (x + (PAGE_SIZE-1)) & ~(PAGE_SIZE-1); +} + static void init_fb(void) { size_t pixels; size_t bytespp; - if ((fbfd = open(FB_DEVICE, O_RDWR)) == -1) + if ((fbfd = open(framebuffer_device, O_RDWR)) == -1) { - __android_log_print(ANDROID_LOG_INFO,"VNC","cannot open fb device %s\n", FB_DEVICE); + __android_log_print(ANDROID_LOG_INFO,"VNC","cannot open fb device %s\n", framebuffer_device); return; // exit(EXIT_FAILURE); } - + update_fb_info(); if (ioctl(fbfd, FBIOGET_FSCREENINFO, &fscrinfo) != 0) @@ -123,33 +133,17 @@ static void init_fb(void) pixels = scrinfo.xres * scrinfo.yres; bytespp = scrinfo.bits_per_pixel /CHAR_BIT; - __android_log_print(ANDROID_LOG_INFO,"VNC", "xres=%d, yres=%d, xresv=%d, yresv=%d, xoffs=%d, yoffs=%d, bpp=%d\n", - (int)scrinfo.xres, (int)scrinfo.yres, + __android_log_print(ANDROID_LOG_INFO,"VNC", "line_lenght=%d xres=%d, yres=%d, xresv=%d, yresv=%d, xoffs=%d, yoffs=%d, bpp=%d\n", + (int)fscrinfo.line_length,(int)scrinfo.xres, (int)scrinfo.yres, (int)scrinfo.xres_virtual, (int)scrinfo.yres_virtual, (int)scrinfo.xoffset, (int)scrinfo.yoffset, (int)scrinfo.bits_per_pixel); - -// off_t o=0; - - //now handled with double buffer detection -// if (scrinfo.xres==480 && scrinfo.yres==854 && scrinfo.xres_virtual==480 -// && scrinfo.yres_virtual==854 && scrinfo.xoffset==448 && scrinfo.yoffset==1710) -/*if (scrinfo.bits_per_pixel==32) - // tweak for motorola droid - { - int off=scrinfo.xres*scrinfo.yres*scrinfo.bits_per_pixel/CHAR_BIT; - - int resto= off % sysconf(_SC_PAGE_SIZE); - o= off / sysconf(_SC_PAGE_SIZE); - if (resto) - o+=1; - - } */ - -// __android_log_print(ANDROID_LOG_INFO,"VNC","buffer offset=%d * %d\n",o,(int)sysconf(_SC_PAGE_SIZE)); -// -// fbmmap = mmap(NULL, (scrinfo.xres_virtual*scrinfo.yres_virtual)* bytespp , PROT_READ|PROT_READ , MAP_PRIVATE , fbfd, o*sysconf(_SC_PAGE_SIZE)); - fbmmap = mmap(NULL, (scrinfo.xres_virtual*scrinfo.yres_virtual)* bytespp , PROT_READ|PROT_READ , MAP_PRIVATE , fbfd, 0); + + printf("AKII\n"); + + size_t fbSize = roundUpToPageSize(fscrinfo.line_length * scrinfo.yres_virtual); + + fbmmap = mmap(NULL, fbSize , PROT_READ|PROT_WRITE , MAP_SHARED , fbfd, 0); if (fbmmap == MAP_FAILED) @@ -198,7 +192,7 @@ static rfbNewClientHookPtr clientHook(rfbClientPtr cl) if (scaling!=0 && scaling!=100) { rfbScalingSetup(cl, vncscr->width*scaling/100.0, vncscr->height*scaling/100.0); - rfbSendNewScaleSize(cl); + } return RFB_CLIENT_ACCEPT; @@ -232,6 +226,7 @@ static void init_fb_server(int argc, char **argv) vncscr->kbdAddEvent = keyevent; vncscr->ptrAddEvent = ptrevent; vncscr->newClientHook = clientHook; + if (strcmp(VNC_PASSWORD,"")!=0) { @@ -258,7 +253,7 @@ static void init_fb_server(int argc, char **argv) vncscr->alwaysShared = TRUE; vncscr->handleEventsEagerly = TRUE; vncscr->deferUpdateTime = 5; - + rfbInitServer(vncscr); //assign update_screen depending on bpp @@ -286,9 +281,7 @@ static void init_fb_server(int argc, char **argv) /* Mark as dirty since we haven't sent any updates at all yet. */ - rfbMarkRectAsModified(vncscr, 0, 0, scrinfo.xres, scrinfo.yres); - rfbProcessEvents(vncscr, 100000); - + rfbMarkRectAsModified(vncscr, 0, 0, scrinfo.xres, scrinfo.yres); } static int keysym2scancode(rfbBool down, rfbKeySym c, rfbClientPtr cl, int *sh, int *alt); @@ -670,11 +663,12 @@ static void rotate() void print_usage(char **argv) { - __android_log_print(ANDROID_LOG_INFO,"VNC","androidvncserver [-p password] [-h]\n" + printf("androidvncserver [-p password] [-h]\n" "-p password: Password to access server\n" "-r rotation: Screen rotation (degrees) (0,90,180,270)\n" "-s screen scale: percentage (20,30,50,100,150)\n" - "-h : print this help\n"); + "-h : print this help\n" + "-f select framebuffer device\n;"); } @@ -702,6 +696,14 @@ int main(int argc, char **argv) i++; strcpy(VNC_PASSWORD,argv[i]); break; + case 'f': + i++; + strcpy(framebuffer_device,argv[i]); + break; + case 'P': + i++; + VNC_PORT=atoi(argv[i]); + break; case 'r': i++; r=atoi(argv[i]); @@ -711,10 +713,10 @@ int main(int argc, char **argv) break; case 's': i++; - r=atoi(argv[i]); + r=atoi(argv[i]); if (r>=1 && r <= 150) scaling=r; - else + else scaling=100; __android_log_print(ANDROID_LOG_INFO,"VNC","scaling to %d percent\n",scaling); break; @@ -722,9 +724,9 @@ int main(int argc, char **argv) } i++; } - } - - __android_log_print(ANDROID_LOG_INFO,"VNC","Initializing framebuffer device " FB_DEVICE "...\n"); + } + + __android_log_print(ANDROID_LOG_INFO,"VNC","Initializing framebuffer device...\n"); init_fb(); __android_log_print(ANDROID_LOG_INFO,"VNC","Initializing virtual keyboard and touch device...\n"); @@ -736,17 +738,44 @@ int main(int argc, char **argv) __android_log_print(ANDROID_LOG_INFO,"VNC"," bpp: %d\n", (int)scrinfo.bits_per_pixel); __android_log_print(ANDROID_LOG_INFO,"VNC"," port: %d\n", (int)VNC_PORT); init_fb_server(argc, argv); + /* + rfbRunEventLoop(vncscr,-1,TRUE); while (1) { + while (vncscr->clientHead == NULL) + sleep(1); + + if (standby>60) + sleep(2); + else if (standby>30) + sleep(1); + else + usleep(100000); - while (vncscr->clientHead == NULL) + update_screen(); + }*/ + + while (1) + { + while (vncscr->clientHead == NULL) rfbProcessEvents(vncscr, 100000); - - update_screen(); + + rfbMarkRectAsModified(vncscr, 0, 0, vncscr->width, vncscr->height); + + if (standby>60) + rfbProcessEvents(vncscr, 200000); + else if (standby>30) + rfbProcessEvents(vncscr, 100000); + else + rfbProcessEvents(vncscr, 10000); + + + update_screen(); } + __android_log_print(ANDROID_LOG_INFO,"VNC","Cleaning up...\n"); cleanup_fb(); cleanup_kbd(); -} \ No newline at end of file +} diff --git a/jni/vnc/update_screen.c b/jni/vnc/update_screen.c index 28c2829..45b3ebd 100644 --- a/jni/vnc/update_screen.c +++ b/jni/vnc/update_screen.c @@ -1,9 +1,12 @@ #define OUT_T CONCAT3E(uint,OUT,_t) #define FUNCTION CONCAT2E(update_screen_,OUT) + + + void FUNCTION(void) { - static int i,j,offset; + static int i,j; update_fb_info(); @@ -14,9 +17,9 @@ void FUNCTION(void) // offset=scrinfo.xres*scrinfo.yoffset; // else // offset=0; +// offset = scrinfo.xres * scrinfo.yoffset + scrinfo.xoffset * scrinfo.bits_per_pixel / CHAR_BIT; - offset = scrinfo.xres * scrinfo.yoffset + scrinfo.xoffset * scrinfo.bits_per_pixel / CHAR_BIT; - + OUT_T* a = (OUT_T*)cmpbuf; OUT_T* b = (OUT_T*)fbmmap; @@ -30,9 +33,9 @@ void FUNCTION(void) { for (i = 0; i < scrinfo.xres; i++) { - if (a[i + j * scrinfo.xres]!=b[i + j * scrinfo.xres + offset ]) + if (a[i + j * scrinfo.xres]!=b[PIXEL_TO_VIRTUALPIXEL(i,j)]) { - a[i + j * scrinfo.xres]=b[i + j * scrinfo.xres + offset]; + a[i + j * scrinfo.xres]=b[PIXEL_TO_VIRTUALPIXEL(i,j)]; if (i>max_x) max_x=i; @@ -56,9 +59,9 @@ void FUNCTION(void) { for (i = 0; i < scrinfo.xres; i++) { - if (a[(scrinfo.yres - 1 - j + i * scrinfo.yres)] != b[i + j * scrinfo.xres + offset]) + if (a[(scrinfo.yres - 1 - j + i * scrinfo.yres)] != b[PIXEL_TO_VIRTUALPIXEL(i,j)]) { - a[(scrinfo.yres - 1 - j + i * scrinfo.yres)] = b[i + j * scrinfo.xres + offset ]; + a[(scrinfo.yres - 1 - j + i * scrinfo.yres)] = b[PIXEL_TO_VIRTUALPIXEL(i,j)]; if (i>max_y) max_y=i; @@ -84,19 +87,22 @@ void FUNCTION(void) { for (i = 0; i < scrinfo.xres; i++) { - if (a[i + j * scrinfo.xres]!=b[scrinfo.yres*scrinfo.xres - (i + j * scrinfo.xres ) + offset ]) + if (a[((scrinfo.xres - 1 - i) + (scrinfo.yres - 1 - j) * scrinfo.xres)]!=b[PIXEL_TO_VIRTUALPIXEL(i,j)]) { - a[i + j * scrinfo.xres]=b[scrinfo.yres*scrinfo.xres - (i + j * scrinfo.xres) + offset ]; + a[((scrinfo.xres - 1 - i) + (scrinfo.yres - 1 - j) * scrinfo.xres)]=b[PIXEL_TO_VIRTUALPIXEL(i,j)]; + if (i>max_x) max_x=i; if (imax_y) - max_y=j; - if (j max_y) + max_y=scrinfo.yres-j; if (idle) idle=0; @@ -111,20 +117,19 @@ void FUNCTION(void) for (i = 0; i < scrinfo.xres; i++) { - if(a[(scrinfo.yres - 1 - j + i * scrinfo.yres)] != b[ scrinfo.yres * scrinfo.xres - (i + j * scrinfo.xres) + offset ]) + if(a[j + (scrinfo.xres - 1 - i) * scrinfo.yres] != b[PIXEL_TO_VIRTUALPIXEL(i,j)]) { - a[(scrinfo.yres - 1 - j + i * scrinfo.yres)] = b[ scrinfo.yres * scrinfo.xres - (i + j * scrinfo.xres) + offset ]; + a[j + (scrinfo.xres - 1 - i) * scrinfo.yres] = b[PIXEL_TO_VIRTUALPIXEL(i,j)]; + if (i>max_y) max_y=i; if (i max_x) - max_x=scrinfo.yres-j; + if (j < min_x) + min_x=j; + if (j > max_x) + max_x=j; if (idle) idle=0; @@ -136,40 +141,25 @@ void FUNCTION(void) memcpy(vncbuf,a,vncscr->width*vncscr->height*scrinfo.bits_per_pixel/CHAR_BIT); - - if (min_x!=9999 && min_y!=9999 && max_x!=-1 && max_y!=-1) { -// min_x--; max_x++; -// min_y--; max_y++; rfbMarkRectAsModified(vncscr, min_x, min_y, max_x, max_y); - rfbProcessEvents(vncscr, 10000); - } -// rfbMarkRectAsModified(vncscr, 0, 0, scrinfo.yres,scrinfo.xres); -// rfbProcessEvents(vncscr, 10000); - - + } + if (idle) { standby=standby+1; - - if (standby>30) - rfbProcessEvents(vncscr, 1000000); - else - rfbProcessEvents(vncscr, 100000); - -// __android_log_print(ANDROID_LOG_INFO,"VNC","standby %d xoff=%d yoff=%d\n",standby,scrinfo.xoffset,scrinfo.yoffset); +//__android_log_print(ANDROID_LOG_INFO,"VNC","standby %d xoff=%d yoff=%d offset=%d\n",standby,scrinfo.xoffset,scrinfo.yoffset,PIXEL_TO_VIRTUALPIXEL(i,j)); change=0; } else { change=change+1; standby=0; - rfbProcessEvents(vncscr, 100000); -// __android_log_print(ANDROID_LOG_INFO,"VNC","change %d\tmin_x=%d max_x=%d min_y=%d max_y=%d xoff=%d yoff=%d\n",change,min_x,max_x,min_y,max_y,scrinfo.xoffset,scrinfo.yoffset); +// __android_log_print(ANDROID_LOG_INFO,"VNC","change %d\tmin_x=%d max_x=%d min_y=%d max_y=%d xoff=%d yoff=%d offset=%d\n",change,min_x,max_x,min_y,max_y,scrinfo.xoffset,scrinfo.yoffset,PIXEL_TO_VIRTUALPIXEL(i,j)); } } diff --git a/jni/vnc/update_screen.c~ b/jni/vnc/update_screen.c~ index d8bedfb..e791324 100644 --- a/jni/vnc/update_screen.c~ +++ b/jni/vnc/update_screen.c~ @@ -1,9 +1,12 @@ #define OUT_T CONCAT3E(uint,OUT,_t) #define FUNCTION CONCAT2E(update_screen_,OUT) + + + void FUNCTION(void) { - static int i,j,offset; + static int i,j; update_fb_info(); @@ -14,9 +17,9 @@ void FUNCTION(void) // offset=scrinfo.xres*scrinfo.yoffset; // else // offset=0; +// offset = scrinfo.xres * scrinfo.yoffset + scrinfo.xoffset * scrinfo.bits_per_pixel / CHAR_BIT; - offset = scrinfo.xres * scrinfo.yoffset + scrinfo.xoffset * scrinfo.bits_per_pixel / CHAR_BIT; - + OUT_T* a = (OUT_T*)cmpbuf; OUT_T* b = (OUT_T*)fbmmap; @@ -30,9 +33,9 @@ void FUNCTION(void) { for (i = 0; i < scrinfo.xres; i++) { - if (a[i + j * scrinfo.xres]!=b[i + j * scrinfo.xres + offset ]) + if (a[i + j * scrinfo.xres]!=b[PIXEL_TO_VIRTUALPIXEL(i,j)]) { - a[i + j * scrinfo.xres]=b[i + j * scrinfo.xres + offset]; + a[i + j * scrinfo.xres]=b[PIXEL_TO_VIRTUALPIXEL(i,j)]; if (i>max_x) max_x=i; @@ -56,9 +59,9 @@ void FUNCTION(void) { for (i = 0; i < scrinfo.xres; i++) { - if (a[(scrinfo.yres - 1 - j + i * scrinfo.yres)] != b[i + j * scrinfo.xres + offset]) + if (a[(scrinfo.yres - 1 - j + i * scrinfo.yres)] != b[PIXEL_TO_VIRTUALPIXEL(i,j)]) { - a[(scrinfo.yres - 1 - j + i * scrinfo.yres)] = b[i + j * scrinfo.xres + offset ]; + a[(scrinfo.yres - 1 - j + i * scrinfo.yres)] = b[PIXEL_TO_VIRTUALPIXEL(i,j)]; if (i>max_y) max_y=i; @@ -84,19 +87,22 @@ void FUNCTION(void) { for (i = 0; i < scrinfo.xres; i++) { - if (a[i + j * scrinfo.xres]!=b[scrinfo.yres*scrinfo.xres - (i + j * scrinfo.xres ) + offset ]) + if (a[((scrinfo.xres - 1 - i) + (scrinfo.yres - 1 - j) * scrinfo.xres)]!=b[PIXEL_TO_VIRTUALPIXEL(i,j)]) { - a[i + j * scrinfo.xres]=b[scrinfo.yres*scrinfo.xres - (i + j * scrinfo.xres) + offset ]; + a[((scrinfo.xres - 1 - i) + (scrinfo.yres - 1 - j) * scrinfo.xres)]=b[PIXEL_TO_VIRTUALPIXEL(i,j)]; + if (i>max_x) max_x=i; if (imax_y) - max_y=j; - if (j max_y) + max_y=scrinfo.yres-j; if (idle) idle=0; @@ -111,20 +117,19 @@ void FUNCTION(void) for (i = 0; i < scrinfo.xres; i++) { - if(a[(scrinfo.yres - 1 - j + i * scrinfo.yres)] != b[ scrinfo.yres * scrinfo.xres - (i + j * scrinfo.xres) + offset ]) + if(a[j + (scrinfo.xres - 1 - i) * scrinfo.yres] != b[PIXEL_TO_VIRTUALPIXEL(i,j)]) { - a[(scrinfo.yres - 1 - j + i * scrinfo.yres)] = b[ scrinfo.yres * scrinfo.xres - (i + j * scrinfo.xres) + offset ]; + a[j + (scrinfo.xres - 1 - i) * scrinfo.yres] = b[PIXEL_TO_VIRTUALPIXEL(i,j)]; + if (i>max_y) max_y=i; if (i max_x) - max_x=scrinfo.yres-j; + if (j < min_x) + min_x=j; + if (j > max_x) + max_x=j; if (idle) idle=0; @@ -136,40 +141,25 @@ void FUNCTION(void) memcpy(vncbuf,a,vncscr->width*vncscr->height*scrinfo.bits_per_pixel/CHAR_BIT); - - if (min_x!=9999 && min_y!=9999 && max_x!=-1 && max_y!=-1) { -// min_x--; max_x++; -// min_y--; max_y++; rfbMarkRectAsModified(vncscr, min_x, min_y, max_x, max_y); - rfbProcessEvents(vncscr, 10000); + rfbProcessEvents(vncscr, 100000); } - -// rfbMarkRectAsModified(vncscr, 0, 0, scrinfo.yres,scrinfo.xres); -// rfbProcessEvents(vncscr, 10000); - - + if (idle) { standby=standby+1; - - if (standby>30) - rfbProcessEvents(vncscr, 1000000); - else - rfbProcessEvents(vncscr, 100000); - - __android_log_print(ANDROID_LOG_INFO,"VNC","standby %d xoff=%d yoff=%d\n",standby,scrinfo.xoffset,scrinfo.yoffset); +//__android_log_print(ANDROID_LOG_INFO,"VNC","standby %d xoff=%d yoff=%d offset=%d\n",standby,scrinfo.xoffset,scrinfo.yoffset,PIXEL_TO_VIRTUALPIXEL(i,j)); change=0; } else { change=change+1; standby=0; - rfbProcessEvents(vncscr, 100000); - __android_log_print(ANDROID_LOG_INFO,"VNC","change %d\tmin_x=%d max_x=%d min_y=%d max_y=%d xoff=%d yoff=%d\n",change,min_x,max_x,min_y,max_y,scrinfo.xoffset,scrinfo.yoffset); +// __android_log_print(ANDROID_LOG_INFO,"VNC","change %d\tmin_x=%d max_x=%d min_y=%d max_y=%d xoff=%d yoff=%d offset=%d\n",change,min_x,max_x,min_y,max_y,scrinfo.xoffset,scrinfo.yoffset,PIXEL_TO_VIRTUALPIXEL(i,j)); } } diff --git a/jni/vnc/update_screen1.c b/jni/vnc/update_screen1.c new file mode 100644 index 0000000..28c2829 --- /dev/null +++ b/jni/vnc/update_screen1.c @@ -0,0 +1,175 @@ +#define OUT_T CONCAT3E(uint,OUT,_t) +#define FUNCTION CONCAT2E(update_screen_,OUT) + +void FUNCTION(void) +{ + static int i,j,offset; + + update_fb_info(); + +// // detect active buffer +// offset= (scrinfo.xoffset) * (scrinfo.bits_per_pixel/8) + +// (scrinfo.yoffset) * scrinfo.xres; +// if (scrinfo.yoffset) +// offset=scrinfo.xres*scrinfo.yoffset; +// else +// offset=0; + + offset = scrinfo.xres * scrinfo.yoffset + scrinfo.xoffset * scrinfo.bits_per_pixel / CHAR_BIT; + + OUT_T* a = (OUT_T*)cmpbuf; + OUT_T* b = (OUT_T*)fbmmap; + + int max_x=-1,max_y=-1, min_x=9999, min_y=9999; + idle=1; + + if (rotation==0) + { + //memcpy(vncbuf,fbmmap,vncscr->width*vncscr->height*scrinfo.bits_per_pixel/CHAR_BIT); + for (j = 0; j < scrinfo.yres; j++) + { + for (i = 0; i < scrinfo.xres; i++) + { + if (a[i + j * scrinfo.xres]!=b[i + j * scrinfo.xres + offset ]) + { + a[i + j * scrinfo.xres]=b[i + j * scrinfo.xres + offset]; + + if (i>max_x) + max_x=i; + if (imax_y) + max_y=j; + if (jmax_y) + max_y=i; + if (i max_x) + max_x=scrinfo.yres-j; + + if (idle) + idle=0; + } + } + } + } + else if (rotation==180) + { + for (j = 0; j < scrinfo.yres; j++) + { + for (i = 0; i < scrinfo.xres; i++) + { + if (a[i + j * scrinfo.xres]!=b[scrinfo.yres*scrinfo.xres - (i + j * scrinfo.xres ) + offset ]) + { + a[i + j * scrinfo.xres]=b[scrinfo.yres*scrinfo.xres - (i + j * scrinfo.xres) + offset ]; + + if (i>max_x) + max_x=i; + if (imax_y) + max_y=j; + if (jmax_y) + max_y=i; + if (i max_x) + max_x=scrinfo.yres-j; + + if (idle) + idle=0; + } + } + } + +} + +memcpy(vncbuf,a,vncscr->width*vncscr->height*scrinfo.bits_per_pixel/CHAR_BIT); + + + + if (min_x!=9999 && min_y!=9999 && max_x!=-1 && max_y!=-1) + { +// min_x--; + max_x++; +// min_y--; + max_y++; + + rfbMarkRectAsModified(vncscr, min_x, min_y, max_x, max_y); + rfbProcessEvents(vncscr, 10000); + } + +// rfbMarkRectAsModified(vncscr, 0, 0, scrinfo.yres,scrinfo.xres); +// rfbProcessEvents(vncscr, 10000); + + + if (idle) + { + standby=standby+1; + + if (standby>30) + rfbProcessEvents(vncscr, 1000000); + else + rfbProcessEvents(vncscr, 100000); + +// __android_log_print(ANDROID_LOG_INFO,"VNC","standby %d xoff=%d yoff=%d\n",standby,scrinfo.xoffset,scrinfo.yoffset); + change=0; + } + else + { + change=change+1; + standby=0; + rfbProcessEvents(vncscr, 100000); +// __android_log_print(ANDROID_LOG_INFO,"VNC","change %d\tmin_x=%d max_x=%d min_y=%d max_y=%d xoff=%d yoff=%d\n",change,min_x,max_x,min_y,max_y,scrinfo.xoffset,scrinfo.yoffset); + } +} diff --git a/libs/armeabi/androidvncserver b/libs/armeabi/androidvncserver index 8bfbfcc..7ffb525 100755 Binary files a/libs/armeabi/androidvncserver and b/libs/armeabi/androidvncserver differ diff --git a/libs/mobclix.jar b/libs/mobclix.jar index 2ec57bf..6bad49f 100755 Binary files a/libs/mobclix.jar and b/libs/mobclix.jar differ diff --git a/res/layout/main.xml b/res/layout/main.xml index 5b51a40..47322ee 100644 --- a/res/layout/main.xml +++ b/res/layout/main.xml @@ -8,8 +8,9 @@ - - + android:shadowColor="#111" + android:gravity="center" +> + - + diff --git a/res/raw/androidvncserver b/res/raw/androidvncserver index 8bfbfcc..7ffb525 100755 Binary files a/res/raw/androidvncserver and b/res/raw/androidvncserver differ diff --git a/res/values/strings.xml b/res/values/strings.xml index b209906..740d90a 100644 --- a/res/values/strings.xml +++ b/res/values/strings.xml @@ -1,7 +1,6 @@ droid VNC server - 0 90 180 @@ -21,7 +20,14 @@ 30 % 20 % - + +On +Off + + +True +False + droid VNC version: %s\n Device model: %s\n @@ -29,4 +35,5 @@ Firmware version: %s\n Kernel version: %s\n Build number: %s\n +org.onaips.vnc diff --git a/res/xml/preferences.xml b/res/xml/preferences.xml index b1e5258..4420343 100644 --- a/res/xml/preferences.xml +++ b/res/xml/preferences.xml @@ -1,10 +1,12 @@ - - - - - + + + + + + + diff --git a/src/org/onaips/vnc_donate/MainActivity.java b/src/org/onaips/vnc_donate/MainActivity.java new file mode 100644 index 0000000..ddf69f6 --- /dev/null +++ b/src/org/onaips/vnc_donate/MainActivity.java @@ -0,0 +1,821 @@ +/* + * Copyright (C) 2009 The Android Open Source Project + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ +package org.onaips.vnc_donate; + +import java.io.BufferedReader; +import java.io.File; +import java.io.FileOutputStream; +import java.io.FileReader; +import java.io.IOException; +import java.io.InputStream; +import java.io.InputStreamReader; +import java.io.OutputStream; +import java.net.InetAddress; +import java.net.NetworkInterface; +import java.net.SocketException; +import java.util.Enumeration; +import java.util.List; +import java.util.Timer; +import java.util.TimerTask; +import java.util.regex.Matcher; +import java.util.regex.Pattern; + + + +import android.app.Activity; +import android.app.AlertDialog; +import android.app.ProgressDialog; +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.DialogInterface; +import android.content.Intent; +import android.content.IntentFilter; +import android.content.SharedPreferences; +import android.content.pm.PackageInfo; +import android.content.pm.PackageManager; +import android.content.pm.ResolveInfo; +import android.content.pm.PackageManager.NameNotFoundException; +import android.graphics.Color; +import android.net.ConnectivityManager; +import android.net.DhcpInfo; +import android.net.NetworkInfo; +import android.net.Uri; +import android.net.NetworkInfo.DetailedState; +import android.net.wifi.WifiInfo; +import android.net.wifi.WifiManager; +import android.os.Build; +import android.os.Bundle; +import android.os.PowerManager; +import android.preference.PreferenceManager; +import android.text.Html; +import android.util.Log; +import android.view.Menu; +import android.view.MenuInflater; +import android.view.MenuItem; +import android.view.View; +import android.view.View.OnClickListener; +import android.widget.Button; +import android.widget.TextView; +import android.widget.Toast; + +public class MainActivity extends Activity +{ + private static final int MENU_QUIT = 0; + private static final int MENU_HELP = 1; + private static final int MENU_ONAIPS = 2; + private static final int MENU_SENDLOG = 3; + private static final int MENU_CHANGELOG = 4; + private static final String changelog="-PLEASE GIVE FEEDBACK! (send debug info in menu)

- [Add] Start daemon on boot (set on prefs)
-[Add] Change port on preferences
- [Add] Changelog on menu
- [Add] Dynamic network state detection
- [Fix] HTTP client now working again
- [Rem] Initial screen is only showed on new versions
- [Add] Don't let device sleep (set on prefs)
- [Fix] Better start/stop handling"; + + private PowerManager.WakeLock wakeLock = null; + private Timer watchdogTimer=null; + + SharedPreferences preferences; + ProgressDialog dialog=null; + AlertDialog startDialog; + + + + /** Called when the activity is first created. */ + @Override + public void onCreate(Bundle savedInstanceState) + { + super.onCreate(savedInstanceState); + + setContentView(R.layout.main); + + + // Initialize preferences + preferences = PreferenceManager.getDefaultSharedPreferences(this); + + if (watchdogTimer!=null) + watchdogTimer.cancel(); + + + if (!hasRootPermission()) + { + Log.v("VNC","You don't have root permissions...!!!"); + showTextOnScreen("You don't have root permissions...Please ROOT your phone first!!!"); + //System.exit(-1); + } + + if (!hasBusybox()) + { + + showTextOnScreen("I didn't find busybox, you may not be able to close server"); + } + + showInitialScreen(false); + createBinary(); + + + boolean serverRunning=isAndroidServerRunning(); + + + if (("On".equals(preferences.getString("sleep", "Off"))) && serverRunning) + { + PowerManager pm = (PowerManager) getSystemService(Context.POWER_SERVICE); + wakeLock = pm.newWakeLock(PowerManager.SCREEN_DIM_WAKE_LOCK,"droid VNC"); + wakeLock.acquire(); + } + else + { + if (wakeLock!=null) + wakeLock.release(); + } + + + // register wifi event receiver + mReceiver receiver=new mReceiver(); + this.registerReceiver(receiver, new IntentFilter(ConnectivityManager.CONNECTIVITY_ACTION)); + + + findViewById(R.id.Button01).setOnClickListener(new OnClickListener() { + @Override + public void onClick(View arg0) { + + startServerButtonClicked(); + + + return; + } + }) ; + findViewById(R.id.Button02).setOnClickListener(new OnClickListener() { + @Override + public void onClick(View arg0) { + if (!isAndroidServerRunning()) + { + showTextOnScreen("Server is not running"); + return; + } + + + + prepareWatchdog("Stopping server. Please wait...","Couldn't Stop server",false); + + Thread t=new Thread(){ + public void run() + { + stopServer(); + + } + }; + t.start(); + + return; + } + }); + } + + public String packageVersion() + { + String version = ""; + try { + PackageInfo pi = getPackageManager().getPackageInfo(getPackageName(), 0); + version = pi.versionName; + } catch (NameNotFoundException e) { + // TODO Auto-generated catch block + Log.v("VNC","onOptionsItemSelected: "+ e.getMessage()); + }; + return version; + } + + public boolean free_version() + { + return getPackageName().equals("org.onaips.vnc"); + } + + public void showInitialScreen(boolean forceShow) + { + // Initialize preferences + preferences = PreferenceManager.getDefaultSharedPreferences(this ); + SharedPreferences.Editor editor = preferences.edit(); + + String version=packageVersion(); + + { + if (forceShow) + ; + else if (version.equals(preferences.getString("version", ""))) + return; + editor.putString("version", version); + editor.commit(); + } + + startDialog = new AlertDialog.Builder(this).create(); + startDialog.setTitle("Changelog"); + startDialog.setMessage(Html.fromHtml(changelog)); + startDialog.setIcon(R.drawable.icon); + + if (free_version()) + { + startDialog.setButton(AlertDialog.BUTTON1,"OK", new DialogInterface.OnClickListener() { + + @Override + public void onClick(DialogInterface arg0, int arg1) { + startDialog.dismiss(); + } + }); + + + + startDialog.setButton2("Donate Version", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface arg0, int arg1) { + Intent myIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://details?id=org.onaips.vnc_donate")); + startActivity(myIntent); + + } + }); + + startDialog.show(); + } + else + startDialog.show(); + } + + static void writeCommand(OutputStream os, String command) throws Exception + { + os.write((command + "\n").getBytes("ASCII")); + } + + + + public void showTextOnScreen(final String t) + { + runOnUiThread(new Runnable(){ + public void run() { + Toast.makeText(MainActivity.this,t,Toast.LENGTH_LONG).show(); + } + }); + } + + public boolean onCreateOptionsMenu(Menu menu) { + MenuInflater inflater = getMenuInflater(); + inflater.inflate(R.menu.menu, menu); + + menu.add(0,MENU_SENDLOG,0,"Send debug info"); + menu.add(0,MENU_CHANGELOG,0,"Changelog"); + menu.add(0,MENU_ONAIPS,0,"About"); + menu.add(0, MENU_HELP, 0, "Help"); + menu.add(0, MENU_QUIT, 0, "Close"); + + return true; + } + + public void prepareWatchdog(final String s1,final String s2, final boolean running) + { + dialog=ProgressDialog.show(MainActivity.this, "",s1, true); + + watchdogTimer=new Timer(); + watchdogTimer.schedule(new TimerTask() { + @Override + public void run() { + runOnUiThread(new Runnable(){ + public void run() { + if (isAndroidServerRunning() == (running==false)) + { + try { + dialog.dismiss(); + } + catch(IllegalArgumentException a) + { + Log.v("VNC","IllegalArgumentException, should be avoided"); + } + showTextOnScreen(s2); + } + } + }); + } + }, (long)5000); + } + + + public void setStateLabels(boolean state) + { + TextView stateLabel=(TextView)findViewById(R.id.stateLabel); + stateLabel.setText(state?"Running":"Stopped"); + stateLabel.setTextColor(state?Color.GREEN:Color.RED); + + TextView t=(TextView)findViewById(R.id.TextView01); + + if (state) + { + String port=preferences.getString("port", "5901"); + String httpport; + try + { + int port1=Integer.parseInt(port); + port=String.valueOf(port1); + httpport=String.valueOf(port1-100); + } + catch(NumberFormatException e) + { + port="5901"; + httpport="5801"; + } + + String ip=getIpAddress(); + if (ip.equals("")) + t.setText("Not connected to a network"); + else + t.setText(Html.fromHtml("Connect to:
" + getIpAddress()+":" + port + "
or
http://" + getIpAddress() + ":" + httpport + "
")); + + } + else + t.setText(""); + + } + + public String getIpAddress() { + try { + for (Enumeration en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) { + NetworkInterface intf = en.nextElement(); + for (Enumeration enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) { + InetAddress inetAddress = enumIpAddr.nextElement(); + if (!inetAddress.isLoopbackAddress()) { + return inetAddress.getHostAddress().toString(); + } + } + } + } catch (SocketException ex) { + Log.e("VNC", ex.toString()); + } + return ""; + } + + boolean wifiConnected() + { + WifiManager wifi = (WifiManager) getSystemService(Context.WIFI_SERVICE); + WifiInfo info = wifi.getConnectionInfo(); + + return info.getBSSID()!=null; + } + + private String intToIp(int i) { + return ( i & 0xFF) + "." + ((i >> 8 ) & 0xFF) + "." + ((i >> 16 ) & 0xFF) + "." + ((i >> 24 ) & 0xFF); + } + + public void stopServer() + { + try{ + Process sh; + + sh = Runtime.getRuntime().exec("su"); + OutputStream os = sh.getOutputStream(); + + + if (hasBusybox()) + { + writeCommand(os, "busybox killall androidvncserver"); + writeCommand(os, "busybox killall -KILL androidvncserver"); + } + else + { + writeCommand(os, "killall androidvncserver"); + writeCommand(os, "killall -KILL androidvncserver"); + } + + writeCommand(os, "exit"); + + os.flush(); + os.close(); + } catch (IOException e) { + showTextOnScreen("stopServer()" + e.getMessage()); + Log.v("VNC","stopServer()" + e.getMessage()); + } catch (Exception e) { + Log.v("VNC","stopServer()" + e.getMessage()); + } + + } + + public void startServerButtonClicked() + { + if (isAndroidServerRunning()) + { + + showTextOnScreen("Server is already running, stop it first"); + } + else + { + prepareWatchdog("Starting server. Please wait...","Couldn't Start server", true); + + Thread t=new Thread(){ + public void run() + { + startServer(); + } + }; + t.start(); + } + } + + + public void startServer() + { + try{ + Process sh; + + String password=preferences.getString("password", ""); + String password_check=""; + if (!password.equals("")) + password_check="-p " + password; + + + String rotation=preferences.getString("rotation", "0"); + rotation="-r " + rotation; + + String scaling=preferences.getString("scale", "100"); + String scaling_string=""; + if (!scaling.equals("0")) + scaling_string="-s " + scaling; + + String port=preferences.getString("port", "5901"); + try + { + int port1=Integer.parseInt(port); + port=String.valueOf(port1); + } + catch(NumberFormatException e) + { + port="5901"; + } + String port_string="-P " + port; + + + sh = Runtime.getRuntime().exec("su"); + OutputStream os = sh.getOutputStream(); + writeCommand(os, "chmod 777 /data/data/"+getPackageName()+"/androidvncserver"); + writeCommand(os, "/data/data/"+getPackageName()+"/androidvncserver "+ password_check + " " + rotation + " " + scaling_string + " " + port_string); + + + } catch (IOException e) { + Log.v("VNC","startServer():" + e.getMessage()); + showTextOnScreen("startServer():" + e.getMessage()); + } catch (Exception e) { + Log.v("VNC","startServer():" + e.getMessage()); + showTextOnScreen("startServer():" + e.getMessage()); + } + + } + + + + public void copyBinary(int id,String path) + { + try { + InputStream ins = getResources().openRawResource(id); + int size = ins.available(); + + // Read the entire resource into a local byte buffer. + byte[] buffer = new byte[size]; + ins.read(buffer); + ins.close(); + + FileOutputStream fos = new FileOutputStream(path); + fos.write(buffer); + fos.close(); + } + catch (Exception e) + { + Log.v("VNC","public void createBinary(): " + e.getMessage()); + } + + + } + public void createBinary() + { + copyBinary(R.raw.androidvncserver, "/data/data/" + getPackageName() + "/androidvncserver"); + copyBinary(R.raw.vncviewer, "/data/data/"+getPackageName()+"/VncViewer.jar"); + copyBinary(R.raw.indexvnc, "/data/data/"+getPackageName()+"/index.vnc"); + } + + public void showHelp() + { + new AlertDialog.Builder(this) + .setTitle("Help") + .setMessage(Html.fromHtml("Mouse Mappings:

Right Click -> Back
Middle Click -> End Call
Left Click -> Touch

Keyboard Mappings

" + + "Home Key -> Home
Escape -> Back
Page Up ->Menu
Left Ctrl -> Search
PgDown -> Start Call
" + + "End Key -> End Call
F4 -> Rotate
F11 -> Disconnect Server
F12 -> Stop Server Daemon")) + .setPositiveButton("Fechar", null) + .setNegativeButton("Open Website", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface arg0, int arg1) { + Intent myIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://onaips.blogspot.com")); + startActivity(myIntent); + } + }) + .show(); + } + + // This method is called once the menu is selected + public boolean onOptionsItemSelected(MenuItem item) { + switch (item.getItemId()) { + // We have only one menu option + case R.id.preferences: + // Launch Preference activity + Intent i = new Intent(MainActivity.this, preferences.class); + startActivity(i); + + showTextOnScreen("Don't forget to stop/start the server after changes"); + + break; + case MENU_CHANGELOG: + showInitialScreen(true); + break; + case MENU_QUIT: + System.exit(1); + break; + case MENU_HELP: + showHelp(); + break; + case MENU_SENDLOG: + collectAndSendLog(); + break; + case MENU_ONAIPS: + + new AlertDialog.Builder(this) + .setTitle("About") + .setMessage(Html.fromHtml("version " + packageVersion() + "

developed by oNaiPs

Graphics: Sandro Forbice (@sandroforbice)

Open-Source Software")) + .setPositiveButton("Close", null) + .setNegativeButton("Open Website", new DialogInterface.OnClickListener() { + @Override + public void onClick(DialogInterface arg0, int arg1) { + Intent myIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("http://onaips.blogspot.com")); + startActivity(myIntent); + + } + }) + .show(); + } + return true; + } + + public boolean isAndroidServerRunning() + { + + String result=""; + Process sh; + try { + if (hasBusybox()) + sh = Runtime.getRuntime().exec("busybox ps"); + else + sh = Runtime.getRuntime().exec("ps"); + + + InputStream is=sh.getInputStream(); + InputStreamReader isr = new InputStreamReader(is); + BufferedReader br = new BufferedReader(isr); + String line; + + while ((line = br.readLine()) != null) { + result+=line; + if (result.indexOf("androidvncserver")>0) + return true; + } + OutputStream os = sh.getOutputStream(); + writeCommand(os, "exit"); + os.flush(); + os.close(); + } catch (IOException e) { + Log.v("VNC"," isAndroidServerRunning():" + e.getMessage()); + } catch (Exception e) { + Log.v("VNC"," isAndroidServerRunning():" + e.getMessage()); + } + + //Log.v("VNC",result); + + return false; + } + + public static boolean hasBusybox() + { + boolean has = true; + try { + File su = new File("/system/bin/busybox"); + if (su.exists() == false) { + su = new File("/system/xbin/busybox"); + if (su.exists() == false) { + has = false; + } + } + } catch (Exception e) { + Log.v("VNC", "I didn't find busybox, you may not be able to close server - Here is what I know: "+e.getMessage()); + has = false; + } + return has; + } + + public boolean hasRootPermission() { + boolean rooted = true; + try { + File su = new File("/system/bin/su"); + if (su.exists() == false) { + su = new File("/system/xbin/su"); + if (su.exists() == false) { + rooted = false; + } + } + } catch (Exception e) { + Log.v("VNC", "Can't obtain root - Here is what I know: "+e.getMessage()); + rooted = false; + } + + + Process sh; + try { + String result=""; + + sh = Runtime.getRuntime().exec("whoami"); + + InputStream is=sh.getInputStream(); + InputStreamReader isr = new InputStreamReader(is); + BufferedReader br = new BufferedReader(isr); + String line; + + while ((line = br.readLine()) != null) { + result+=line; + if (result.indexOf("androidvncserver")>0) + return true; + } + + Process sh1=Runtime.getRuntime().exec("su"); + + //Log.v("aaaaaa","chgrp -R " + result + " /data/data/org.onaips.vnc/"); + + OutputStream os = sh1.getOutputStream(); + + if (hasBusybox()) + { + writeCommand(os, "busybox chown -R " + result + " /data/data/" + getPackageName() + "/"); + writeCommand(os, "busybox chgrp -R " + result + " /data/data/" + getPackageName() + "/"); + } + else + { + writeCommand(os, "chown -R " + result + " /data/data/" + getPackageName() + "/"); + writeCommand(os, "chgrp -R " + result + " /data/data/" + getPackageName() + "/"); + } + + os.flush(); + os.close(); + isr.close(); + is.close(); + + + } catch (IOException e) { + // TODO Auto-generated catch block + e.printStackTrace(); + }catch (Exception e) { + // TODO Auto-generated catch block + e.printStackTrace(); + } + return rooted; + } + + public static final String LOG_COLLECTOR_PACKAGE_NAME = "com.xtralogic.android.logcollector";//$NON-NLS-1$ + public static final String ACTION_SEND_LOG = "com.xtralogic.logcollector.intent.action.SEND_LOG";//$NON-NLS-1$ + public static final String EXTRA_SEND_INTENT_ACTION = "com.xtralogic.logcollector.intent.extra.SEND_INTENT_ACTION";//$NON-NLS-1$ + public static final String EXTRA_DATA = "com.xtralogic.logcollector.intent.extra.DATA";//$NON-NLS-1$ + public static final String EXTRA_ADDITIONAL_INFO = "com.xtralogic.logcollector.intent.extra.ADDITIONAL_INFO";//$NON-NLS-1$ + public static final String EXTRA_SHOW_UI = "com.xtralogic.logcollector.intent.extra.SHOW_UI";//$NON-NLS-1$ + public static final String EXTRA_FILTER_SPECS = "com.xtralogic.logcollector.intent.extra.FILTER_SPECS";//$NON-NLS-1$ + public static final String EXTRA_FORMAT = "com.xtralogic.logcollector.intent.extra.FORMAT";//$NON-NLS-1$ + public static final String EXTRA_BUFFER = "com.xtralogic.logcollector.intent.extra.BUFFER";//$NON-NLS-1$ + + void collectAndSendLog(){ + final PackageManager packageManager = getPackageManager(); + final Intent intent = new Intent(ACTION_SEND_LOG); + List list = packageManager.queryIntentActivities(intent, PackageManager.MATCH_DEFAULT_ONLY); + final boolean isInstalled = list.size() > 0; + + if (!isInstalled){ + new AlertDialog.Builder(this) + .setTitle(getString(R.string.app_name)) + .setIcon(android.R.drawable.ic_dialog_info) + .setMessage("Please install Log Collector application to collect the device log and send it to dev.") + .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener(){ + public void onClick(DialogInterface dialog, int whichButton){ + Intent marketIntent = new Intent(Intent.ACTION_VIEW, Uri.parse("market://search?q=pname:" + LOG_COLLECTOR_PACKAGE_NAME)); + marketIntent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + startActivity(marketIntent); + } + }) + .setNegativeButton(android.R.string.cancel, null) + .show(); + } + else{ + new AlertDialog.Builder(this) + .setTitle(getString(R.string.app_name)) + .setIcon(android.R.drawable.ic_dialog_info) + .setMessage("Do you want to send debug info to the dev? Please specify what problem is ocurring.\n\nMake sure you started/stopped the server before submitting") + .setPositiveButton(android.R.string.ok, new DialogInterface.OnClickListener(){ + public void onClick(DialogInterface dialog, int whichButton){ + intent.addFlags(Intent.FLAG_ACTIVITY_NEW_TASK); + intent.putExtra(EXTRA_SEND_INTENT_ACTION, Intent.ACTION_SENDTO); + final String email = "onaips@gmail.com"; + intent.putExtra(EXTRA_DATA, Uri.parse("mailto:" + email)); + intent.putExtra(EXTRA_ADDITIONAL_INFO,"Problem Description: \n\n\n\n---------DEBUG--------\n" + getString(R.string.device_info_fmt,getVersionNumber(getApplicationContext()),Build.MODEL,Build.VERSION.RELEASE, getFormattedKernelVersion(), Build.DISPLAY)); + + intent.putExtra(Intent.EXTRA_SUBJECT, "droid VNC server: Debug Info"); + + intent.putExtra(EXTRA_FORMAT, "time"); + + //The log can be filtered to contain data relevant only to your app + String[] filterSpecs = new String[4]; + filterSpecs[0] = "VNC:I"; + filterSpecs[1] = "VNC:D"; + filterSpecs[2] = "VNC:V"; + filterSpecs[3] = "*:S"; + intent.putExtra(EXTRA_FILTER_SPECS, filterSpecs); + + startActivity(intent); + } + }) + .setNegativeButton(android.R.string.cancel, null) + .show(); + } + } + + private String getFormattedKernelVersion() + { + String procVersionStr; + + try { + BufferedReader reader = new BufferedReader(new FileReader("/proc/version"), 256); + try { + procVersionStr = reader.readLine(); + } finally { + reader.close(); + } + + final String PROC_VERSION_REGEX = + "\\w+\\s+" + /* ignore: Linux */ + "\\w+\\s+" + /* ignore: version */ + "([^\\s]+)\\s+" + /* group 1: 2.6.22-omap1 */ + "\\(([^\\s@]+(?:@[^\\s.]+)?)[^)]*\\)\\s+" + /* group 2: (xxxxxx@xxxxx.constant) */ + "\\([^)]+\\)\\s+" + /* ignore: (gcc ..) */ + "([^\\s]+)\\s+" + /* group 3: #26 */ + "(?:PREEMPT\\s+)?" + /* ignore: PREEMPT (optional) */ + "(.+)"; /* group 4: date */ + + Pattern p = Pattern.compile(PROC_VERSION_REGEX); + Matcher m = p.matcher(procVersionStr); + + if (!m.matches()) { + Log.e("VNC", "Regex did not match on /proc/version: " + procVersionStr); + return "Unavailable"; + } else if (m.groupCount() < 4) { + Log.e("VNC", "Regex match on /proc/version only returned " + m.groupCount() + + " groups"); + return "Unavailable"; + } else { + return (new StringBuilder(m.group(1)).append("\n").append( + m.group(2)).append(" ").append(m.group(3)).append("\n") + .append(m.group(4))).toString(); + } + } catch (IOException e) { + Log.e("VNC", "IO Exception when getting kernel version for Device Info screen", e); + + return "Unavailable"; + } + } + + private static String getVersionNumber(Context context) + { + String version = "?"; + try + { + PackageInfo packagInfo = context.getPackageManager().getPackageInfo(context.getPackageName(), 0); + version = packagInfo.versionName; + } + catch (PackageManager.NameNotFoundException e){}; + + return version; + } + + class mReceiver extends BroadcastReceiver { + @Override public void onReceive(Context context, Intent intent) { + NetworkInfo info = intent.getParcelableExtra(ConnectivityManager.EXTRA_NETWORK_INFO); + if (info.getType() == ConnectivityManager.TYPE_MOBILE || info.getType()==ConnectivityManager.TYPE_WIFI) { + setStateLabels(isAndroidServerRunning()); + } + } + }; +} + + + + diff --git a/src/org/onaips/vnc_donate/StartAtBootService.java b/src/org/onaips/vnc_donate/StartAtBootService.java new file mode 100644 index 0000000..8ad64ce --- /dev/null +++ b/src/org/onaips/vnc_donate/StartAtBootService.java @@ -0,0 +1,91 @@ +package org.onaips.vnc_donate; + +import java.io.IOException; +import java.io.OutputStream; + +import android.app.Service; +import android.content.Intent; +import android.content.SharedPreferences; +import android.os.IBinder; +import android.preference.PreferenceManager; +import android.util.Log; + +public class StartAtBootService extends Service { + + @Override + public IBinder onBind(Intent arg0) { + // TODO Auto-generated method stub + return null; + } + + + @Override + public int onStartCommand(Intent intent, int flags, int startId) + { + startServer(); + // We want this service to continue running until it is explicitly + // stopped, so return sticky. + return START_STICKY; + } + + + public void startServer() + { + SharedPreferences preferences = PreferenceManager.getDefaultSharedPreferences(this); + + //Lets see if i need to boot daemon... + String startOnBoot=preferences.getString("startonboot", "False"); + if (startOnBoot.equals("False")) + return; + + + //this code is redundant, how to merge it? + try{ + Process sh; + + String password=preferences.getString("password", ""); + String password_check=""; + if (!password.equals("")) + password_check="-p " + password; + + + String rotation=preferences.getString("rotation", "0"); + rotation="-r " + rotation; + + String scaling=preferences.getString("scale", "100"); + String scaling_string=""; + if (!scaling.equals("0")) + scaling_string="-s " + scaling; + + String port=preferences.getString("port", "5901"); + try + { + int port1=Integer.parseInt(port); + port=String.valueOf(port1); + } + catch(NumberFormatException e) + { + port="5901"; + } + String port_string="-P " + port; + + + sh = Runtime.getRuntime().exec("su"); + OutputStream os = sh.getOutputStream(); + writeCommand(os, "chmod 777 /data/data/"+getPackageName()+"/androidvncserver"); + writeCommand(os, "/data/data/"+getPackageName()+"/androidvncserver "+ password_check + " " + rotation + " " + scaling_string + " " + port_string); + + + } catch (IOException e) { + Log.v("VNC","startServer():" + e.getMessage()); + } catch (Exception e) { + Log.v("VNC","startServer():" + e.getMessage()); + } + + } + + static void writeCommand(OutputStream os, String command) throws Exception + { + os.write((command + "\n").getBytes("ASCII")); + } +} diff --git a/src/org/onaips/vnc_donate/StartAtBootServiceReceiver.java b/src/org/onaips/vnc_donate/StartAtBootServiceReceiver.java new file mode 100644 index 0000000..0ef9005 --- /dev/null +++ b/src/org/onaips/vnc_donate/StartAtBootServiceReceiver.java @@ -0,0 +1,18 @@ +package org.onaips.vnc_donate; + +import android.content.BroadcastReceiver; +import android.content.Context; +import android.content.Intent; + +public class StartAtBootServiceReceiver extends BroadcastReceiver +{ + @Override + public void onReceive(Context context, Intent intent) + { + if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) { + Intent i = new Intent(); + i.setAction(context.getPackageName() + ".StartAtBootService"); + context.startService(i); + } + } +} \ No newline at end of file diff --git a/src/org/onaips/vnc_donate/preferences.java b/src/org/onaips/vnc_donate/preferences.java new file mode 100644 index 0000000..dcf4bf8 --- /dev/null +++ b/src/org/onaips/vnc_donate/preferences.java @@ -0,0 +1,19 @@ +package org.onaips.vnc_donate; + + + + +import android.os.Bundle; +import android.preference.PreferenceActivity; + +public class preferences extends PreferenceActivity { + + /** Called when the activity is first created. */ + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + + addPreferencesFromResource(R.xml.preferences); + } +} + \ No newline at end of file