fixed half screen update, server scale support
This commit is contained in:
parent
2acc4b6cca
commit
f58601cc1b
@ -1,6 +1,6 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:versionName="0.7" android:versionCode="29" package="org.onaips.vnc_donate">
|
||||
package="org.onaips.vnc" android:versionCode="31" android:versionName="0.72">
|
||||
<uses-sdk android:minSdkVersion="4" />
|
||||
<application android:debuggable="false" android:icon="@drawable/icon" android:label="droid VNC server">
|
||||
<activity android:name=".MainActivity" android:label="@string/app_name" android:icon="@drawable/icon" android:launchMode="singleInstance" android:screenOrientation="portrait">
|
||||
|
BIN
bin/avnc.apk
BIN
bin/avnc.apk
Binary file not shown.
BIN
bin/classes.dex
BIN
bin/classes.dex
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
@ -90,6 +90,7 @@
|
||||
/home/onaips/Desktop/android_dev/android-ndk-r4/build/platforms/android-5/arch-arm/usr/include/asm/signal.h \
|
||||
/home/onaips/Desktop/android_dev/android-ndk-r4/build/platforms/android-5/arch-arm/usr/include/asm-generic/signal.h \
|
||||
/home/onaips/Desktop/android_dev/android-ndk-r4/build/platforms/android-5/arch-arm/usr/include/sched.h \
|
||||
/home/onaips/Dropbox/projectos/workspace/avnc/jni/vnc/LibVNCServer-0.9.7/libvncserver/scale.h \
|
||||
/home/onaips/Dropbox/projectos/workspace/avnc/jni/vnc/LibVNCServer-0.9.7/rfb/keysym.h \
|
||||
/home/onaips/Dropbox/projectos/workspace/avnc/jni/vnc/suinput.h \
|
||||
/home/onaips/Desktop/android_dev/android-ndk-r4/build/platforms/android-5/arch-arm/usr/include/linux/uinput.h \
|
||||
@ -275,6 +276,8 @@
|
||||
|
||||
/home/onaips/Desktop/android_dev/android-ndk-r4/build/platforms/android-5/arch-arm/usr/include/sched.h:
|
||||
|
||||
/home/onaips/Dropbox/projectos/workspace/avnc/jni/vnc/LibVNCServer-0.9.7/libvncserver/scale.h:
|
||||
|
||||
/home/onaips/Dropbox/projectos/workspace/avnc/jni/vnc/LibVNCServer-0.9.7/rfb/keysym.h:
|
||||
|
||||
/home/onaips/Dropbox/projectos/workspace/avnc/jni/vnc/suinput.h:
|
||||
|
BIN
bin/org/onaips/vnc/MainActivity$1$1.class
Normal file
BIN
bin/org/onaips/vnc/MainActivity$1$1.class
Normal file
Binary file not shown.
BIN
bin/org/onaips/vnc/MainActivity$1.class
Normal file
BIN
bin/org/onaips/vnc/MainActivity$1.class
Normal file
Binary file not shown.
BIN
bin/org/onaips/vnc/MainActivity$10.class
Normal file
BIN
bin/org/onaips/vnc/MainActivity$10.class
Normal file
Binary file not shown.
BIN
bin/org/onaips/vnc/MainActivity$11.class
Normal file
BIN
bin/org/onaips/vnc/MainActivity$11.class
Normal file
Binary file not shown.
BIN
bin/org/onaips/vnc/MainActivity$12.class
Normal file
BIN
bin/org/onaips/vnc/MainActivity$12.class
Normal file
Binary file not shown.
BIN
bin/org/onaips/vnc/MainActivity$2$1.class
Normal file
BIN
bin/org/onaips/vnc/MainActivity$2$1.class
Normal file
Binary file not shown.
BIN
bin/org/onaips/vnc/MainActivity$2.class
Normal file
BIN
bin/org/onaips/vnc/MainActivity$2.class
Normal file
Binary file not shown.
BIN
bin/org/onaips/vnc/MainActivity$3.class
Normal file
BIN
bin/org/onaips/vnc/MainActivity$3.class
Normal file
Binary file not shown.
BIN
bin/org/onaips/vnc/MainActivity$4.class
Normal file
BIN
bin/org/onaips/vnc/MainActivity$4.class
Normal file
Binary file not shown.
BIN
bin/org/onaips/vnc/MainActivity$5$1.class
Normal file
BIN
bin/org/onaips/vnc/MainActivity$5$1.class
Normal file
Binary file not shown.
BIN
bin/org/onaips/vnc/MainActivity$5.class
Normal file
BIN
bin/org/onaips/vnc/MainActivity$5.class
Normal file
Binary file not shown.
BIN
bin/org/onaips/vnc/MainActivity$6.class
Normal file
BIN
bin/org/onaips/vnc/MainActivity$6.class
Normal file
Binary file not shown.
BIN
bin/org/onaips/vnc/MainActivity$7.class
Normal file
BIN
bin/org/onaips/vnc/MainActivity$7.class
Normal file
Binary file not shown.
BIN
bin/org/onaips/vnc/MainActivity$8.class
Normal file
BIN
bin/org/onaips/vnc/MainActivity$8.class
Normal file
Binary file not shown.
BIN
bin/org/onaips/vnc/MainActivity$9.class
Normal file
BIN
bin/org/onaips/vnc/MainActivity$9.class
Normal file
Binary file not shown.
BIN
bin/org/onaips/vnc/MainActivity.class
Normal file
BIN
bin/org/onaips/vnc/MainActivity.class
Normal file
Binary file not shown.
BIN
bin/org/onaips/vnc/R$array.class
Normal file
BIN
bin/org/onaips/vnc/R$array.class
Normal file
Binary file not shown.
BIN
bin/org/onaips/vnc/R$attr.class
Normal file
BIN
bin/org/onaips/vnc/R$attr.class
Normal file
Binary file not shown.
BIN
bin/org/onaips/vnc/R$drawable.class
Normal file
BIN
bin/org/onaips/vnc/R$drawable.class
Normal file
Binary file not shown.
BIN
bin/org/onaips/vnc/R$id.class
Normal file
BIN
bin/org/onaips/vnc/R$id.class
Normal file
Binary file not shown.
BIN
bin/org/onaips/vnc/R$layout.class
Normal file
BIN
bin/org/onaips/vnc/R$layout.class
Normal file
Binary file not shown.
BIN
bin/org/onaips/vnc/R$menu.class
Normal file
BIN
bin/org/onaips/vnc/R$menu.class
Normal file
Binary file not shown.
BIN
bin/org/onaips/vnc/R$raw.class
Normal file
BIN
bin/org/onaips/vnc/R$raw.class
Normal file
Binary file not shown.
BIN
bin/org/onaips/vnc/R$string.class
Normal file
BIN
bin/org/onaips/vnc/R$string.class
Normal file
Binary file not shown.
BIN
bin/org/onaips/vnc/R$styleable.class
Normal file
BIN
bin/org/onaips/vnc/R$styleable.class
Normal file
Binary file not shown.
BIN
bin/org/onaips/vnc/R$xml.class
Normal file
BIN
bin/org/onaips/vnc/R$xml.class
Normal file
Binary file not shown.
BIN
bin/org/onaips/vnc/R.class
Normal file
BIN
bin/org/onaips/vnc/R.class
Normal file
Binary file not shown.
BIN
bin/org/onaips/vnc/preferences.class
Normal file
BIN
bin/org/onaips/vnc/preferences.class
Normal file
Binary file not shown.
Binary file not shown.
197
gen/org/onaips/vnc/R.java
Normal file
197
gen/org/onaips/vnc/R.java
Normal file
@ -0,0 +1,197 @@
|
||||
/* 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;
|
||||
|
||||
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 class attr {
|
||||
/** <p>Must be a color value, in the form of "<code>#<i>rgb</i></code>", "<code>#<i>argb</i></code>",
|
||||
"<code>#<i>rrggbb</i></code>", or "<code>#<i>aarrggbb</i></code>".
|
||||
<p>This may also be a reference to a resource (in the form
|
||||
"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
|
||||
theme attribute (in the form
|
||||
"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
|
||||
containing a value of this type.
|
||||
*/
|
||||
public static final int backgroundColor=0x7f010000;
|
||||
/** <p>Must be a string value, using '\\;' to escape characters such as '\\n' or '\\uxxxx' for a unicode character.
|
||||
<p>This may also be a reference to a resource (in the form
|
||||
"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
|
||||
theme attribute (in the form
|
||||
"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
|
||||
containing a value of this type.
|
||||
*/
|
||||
public static final int keywords=0x7f010003;
|
||||
/** <p>Must be a color value, in the form of "<code>#<i>rgb</i></code>", "<code>#<i>argb</i></code>",
|
||||
"<code>#<i>rrggbb</i></code>", or "<code>#<i>aarrggbb</i></code>".
|
||||
<p>This may also be a reference to a resource (in the form
|
||||
"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
|
||||
theme attribute (in the form
|
||||
"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
|
||||
containing a value of this type.
|
||||
*/
|
||||
public static final int primaryTextColor=0x7f010001;
|
||||
/** <p>Must be an integer value, such as "<code>100</code>".
|
||||
<p>This may also be a reference to a resource (in the form
|
||||
"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
|
||||
theme attribute (in the form
|
||||
"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
|
||||
containing a value of this type.
|
||||
*/
|
||||
public static final int refreshInterval=0x7f010004;
|
||||
/** <p>Must be a color value, in the form of "<code>#<i>rgb</i></code>", "<code>#<i>argb</i></code>",
|
||||
"<code>#<i>rrggbb</i></code>", or "<code>#<i>aarrggbb</i></code>".
|
||||
<p>This may also be a reference to a resource (in the form
|
||||
"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
|
||||
theme attribute (in the form
|
||||
"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
|
||||
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 banner_adview=0x7f090005;
|
||||
public static final int preferences=0x7f090006;
|
||||
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=0x7f060002;
|
||||
public static final int password=0x7f060001;
|
||||
}
|
||||
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.
|
||||
<p>Includes the following attributes:</p>
|
||||
<table>
|
||||
<colgroup align="left" />
|
||||
<colgroup align="left" />
|
||||
<tr><th>Attribute</th><th>Description</th></tr>
|
||||
<tr><td><code>{@link #com_admob_android_ads_AdView_backgroundColor org.onaips.vnc:backgroundColor}</code></td><td></td></tr>
|
||||
<tr><td><code>{@link #com_admob_android_ads_AdView_keywords org.onaips.vnc:keywords}</code></td><td></td></tr>
|
||||
<tr><td><code>{@link #com_admob_android_ads_AdView_primaryTextColor org.onaips.vnc:primaryTextColor}</code></td><td></td></tr>
|
||||
<tr><td><code>{@link #com_admob_android_ads_AdView_refreshInterval org.onaips.vnc:refreshInterval}</code></td><td></td></tr>
|
||||
<tr><td><code>{@link #com_admob_android_ads_AdView_secondaryTextColor org.onaips.vnc:secondaryTextColor}</code></td><td></td></tr>
|
||||
</table>
|
||||
@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
|
||||
};
|
||||
/**
|
||||
<p>This symbol is the offset where the {@link org.onaips.vnc.R.attr#backgroundColor}
|
||||
attribute's value can be found in the {@link #com_admob_android_ads_AdView} array.
|
||||
|
||||
|
||||
<p>Must be a color value, in the form of "<code>#<i>rgb</i></code>", "<code>#<i>argb</i></code>",
|
||||
"<code>#<i>rrggbb</i></code>", or "<code>#<i>aarrggbb</i></code>".
|
||||
<p>This may also be a reference to a resource (in the form
|
||||
"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
|
||||
theme attribute (in the form
|
||||
"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
|
||||
containing a value of this type.
|
||||
@attr name android:backgroundColor
|
||||
*/
|
||||
public static final int com_admob_android_ads_AdView_backgroundColor = 0;
|
||||
/**
|
||||
<p>This symbol is the offset where the {@link org.onaips.vnc.R.attr#keywords}
|
||||
attribute's value can be found in the {@link #com_admob_android_ads_AdView} array.
|
||||
|
||||
|
||||
<p>Must be a string value, using '\\;' to escape characters such as '\\n' or '\\uxxxx' for a unicode character.
|
||||
<p>This may also be a reference to a resource (in the form
|
||||
"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
|
||||
theme attribute (in the form
|
||||
"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
|
||||
containing a value of this type.
|
||||
@attr name android:keywords
|
||||
*/
|
||||
public static final int com_admob_android_ads_AdView_keywords = 3;
|
||||
/**
|
||||
<p>This symbol is the offset where the {@link org.onaips.vnc.R.attr#primaryTextColor}
|
||||
attribute's value can be found in the {@link #com_admob_android_ads_AdView} array.
|
||||
|
||||
|
||||
<p>Must be a color value, in the form of "<code>#<i>rgb</i></code>", "<code>#<i>argb</i></code>",
|
||||
"<code>#<i>rrggbb</i></code>", or "<code>#<i>aarrggbb</i></code>".
|
||||
<p>This may also be a reference to a resource (in the form
|
||||
"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
|
||||
theme attribute (in the form
|
||||
"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
|
||||
containing a value of this type.
|
||||
@attr name android:primaryTextColor
|
||||
*/
|
||||
public static final int com_admob_android_ads_AdView_primaryTextColor = 1;
|
||||
/**
|
||||
<p>This symbol is the offset where the {@link org.onaips.vnc.R.attr#refreshInterval}
|
||||
attribute's value can be found in the {@link #com_admob_android_ads_AdView} array.
|
||||
|
||||
|
||||
<p>Must be an integer value, such as "<code>100</code>".
|
||||
<p>This may also be a reference to a resource (in the form
|
||||
"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
|
||||
theme attribute (in the form
|
||||
"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
|
||||
containing a value of this type.
|
||||
@attr name android:refreshInterval
|
||||
*/
|
||||
public static final int com_admob_android_ads_AdView_refreshInterval = 4;
|
||||
/**
|
||||
<p>This symbol is the offset where the {@link org.onaips.vnc.R.attr#secondaryTextColor}
|
||||
attribute's value can be found in the {@link #com_admob_android_ads_AdView} array.
|
||||
|
||||
|
||||
<p>Must be a color value, in the form of "<code>#<i>rgb</i></code>", "<code>#<i>argb</i></code>",
|
||||
"<code>#<i>rrggbb</i></code>", or "<code>#<i>aarrggbb</i></code>".
|
||||
<p>This may also be a reference to a resource (in the form
|
||||
"<code>@[<i>package</i>:]<i>type</i>:<i>name</i></code>") or
|
||||
theme attribute (in the form
|
||||
"<code>?[<i>package</i>:][<i>type</i>:]<i>name</i></code>")
|
||||
containing a value of this type.
|
||||
@attr name android:secondaryTextColor
|
||||
*/
|
||||
public static final int com_admob_android_ads_AdView_secondaryTextColor = 2;
|
||||
};
|
||||
}
|
@ -1,8 +1,8 @@
|
||||
LOCAL_PATH:= $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
|
||||
LOCAL_CFLAGS := -DDONATE_VERSION
|
||||
#LOCAL_CFLAGS += -DDONATE_VERSION
|
||||
LOCAL_CFLAGS := -O3 -Wall
|
||||
|
||||
|
||||
LOCAL_SRC_FILES:= \
|
||||
|
54
jni/vnc/Android.mk~
Executable file
54
jni/vnc/Android.mk~
Executable file
@ -0,0 +1,54 @@
|
||||
LOCAL_PATH:= $(call my-dir)
|
||||
include $(CLEAR_VARS)
|
||||
|
||||
#LOCAL_CFLAGS += -DDONATE_VERSION
|
||||
LOCAL_CFLAGS := -O3
|
||||
|
||||
|
||||
LOCAL_SRC_FILES:= \
|
||||
fbvncserver.c \
|
||||
suinput.c \
|
||||
LibVNCServer-0.9.7/libvncserver/main.c \
|
||||
LibVNCServer-0.9.7/libvncserver/rfbserver.c \
|
||||
LibVNCServer-0.9.7/libvncserver/rfbregion.c \
|
||||
LibVNCServer-0.9.7/libvncserver/auth.c \
|
||||
LibVNCServer-0.9.7/libvncserver/sockets.c \
|
||||
LibVNCServer-0.9.7/libvncserver/stats.c \
|
||||
LibVNCServer-0.9.7/libvncserver/corre.c \
|
||||
LibVNCServer-0.9.7/libvncserver/hextile.c \
|
||||
LibVNCServer-0.9.7/libvncserver/rre.c \
|
||||
LibVNCServer-0.9.7/libvncserver/translate.c \
|
||||
LibVNCServer-0.9.7/libvncserver/cutpaste.c \
|
||||
LibVNCServer-0.9.7/libvncserver/httpd.c \
|
||||
LibVNCServer-0.9.7/libvncserver/cursor.c \
|
||||
LibVNCServer-0.9.7/libvncserver/font.c \
|
||||
LibVNCServer-0.9.7/libvncserver/draw.c \
|
||||
LibVNCServer-0.9.7/libvncserver/selbox.c \
|
||||
LibVNCServer-0.9.7/libvncserver/d3des.c \
|
||||
LibVNCServer-0.9.7/libvncserver/vncauth.c \
|
||||
LibVNCServer-0.9.7/libvncserver/cargs.c \
|
||||
LibVNCServer-0.9.7/libvncserver/minilzo.c \
|
||||
LibVNCServer-0.9.7/libvncserver/ultra.c \
|
||||
LibVNCServer-0.9.7/libvncserver/scale.c \
|
||||
LibVNCServer-0.9.7/libvncserver/zlib.c \
|
||||
LibVNCServer-0.9.7/libvncserver/zrle.c \
|
||||
LibVNCServer-0.9.7/libvncserver/zrleoutstream.c \
|
||||
LibVNCServer-0.9.7/libvncserver/zrlepalettehelper.c \
|
||||
LibVNCServer-0.9.7/libvncserver/zywrletemplate.c \
|
||||
LibVNCServer-0.9.7/libvncserver/tight.c
|
||||
|
||||
LOCAL_C_INCLUDES := \
|
||||
$(LOCAL_PATH) \
|
||||
$(LOCAL_PATH)/LibVNCServer-0.9.7/libvncserver \
|
||||
$(LOCAL_PATH)/LibVNCServer-0.9.7 \
|
||||
$(LOCAL_PATH)/../jpeg
|
||||
|
||||
|
||||
LOCAL_STATIC_LIBRARIES := jpeg
|
||||
|
||||
LOCAL_MODULE:= androidvncserver
|
||||
|
||||
LOCAL_LDLIBS := -lz -llog
|
||||
|
||||
|
||||
include $(BUILD_EXECUTABLE)
|
@ -351,12 +351,12 @@ void rfbScalingSetup(rfbClientPtr cl, int width, int height)
|
||||
/* Update it! */
|
||||
if (ptr->scaledScreenRefCount<1)
|
||||
rfbScaledScreenUpdateRect(cl->screen, ptr, 0, 0, cl->screen->width, cl->screen->height);
|
||||
/*
|
||||
* rfbLog("Taking one from %dx%d-%d and adding it to %dx%d-%d\n",
|
||||
* cl->scaledScreen->width, cl->scaledScreen->height,
|
||||
* cl->scaledScreen->scaledScreenRefCount,
|
||||
* ptr->width, ptr->height, ptr->scaledScreenRefCount);
|
||||
*/
|
||||
|
||||
rfbLog("Taking one from %dx%d-%d and adding it to %dx%d-%d\n",
|
||||
cl->scaledScreen->width, cl->scaledScreen->height,
|
||||
cl->scaledScreen->scaledScreenRefCount,
|
||||
ptr->width, ptr->height, ptr->scaledScreenRefCount);
|
||||
|
||||
|
||||
LOCK(cl->updateMutex);
|
||||
cl->scaledScreen->scaledScreenRefCount--;
|
||||
|
420
jni/vnc/LibVNCServer-0.9.7/libvncserver/scale.c~
Executable file
420
jni/vnc/LibVNCServer-0.9.7/libvncserver/scale.c~
Executable file
@ -0,0 +1,420 @@
|
||||
/*
|
||||
* scale.c - deal with server-side scaling.
|
||||
*/
|
||||
|
||||
/*
|
||||
* Copyright (C) 2005 Rohit Kumar, Johannes E. Schindelin
|
||||
* Copyright (C) 2002 RealVNC Ltd.
|
||||
* OSXvnc Copyright (C) 2001 Dan McGuirk <mcguirk@incompleteness.net>.
|
||||
* Original Xvnc code Copyright (C) 1999 AT&T Laboratories Cambridge.
|
||||
* All Rights Reserved.
|
||||
*
|
||||
* This 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 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* This software 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.
|
||||
*
|
||||
* You should have received a copy of the GNU General Public License
|
||||
* along with this software; if not, write to the Free Software
|
||||
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307,
|
||||
* USA.
|
||||
*/
|
||||
|
||||
#ifdef __STRICT_ANSI__
|
||||
#define _BSD_SOURCE
|
||||
#endif
|
||||
#include <string.h>
|
||||
#include <rfb/rfb.h>
|
||||
#include <rfb/rfbregion.h>
|
||||
#include "private.h"
|
||||
|
||||
#ifdef LIBVNCSERVER_HAVE_FCNTL_H
|
||||
#include <fcntl.h>
|
||||
#endif
|
||||
|
||||
#ifdef WIN32
|
||||
#define write(sock,buf,len) send(sock,buf,len,0)
|
||||
#else
|
||||
#ifdef LIBVNCSERVER_HAVE_UNISTD_H
|
||||
#include <unistd.h>
|
||||
#endif
|
||||
#include <pwd.h>
|
||||
#ifdef LIBVNCSERVER_HAVE_SYS_SOCKET_H
|
||||
#include <sys/socket.h>
|
||||
#endif
|
||||
#ifdef LIBVNCSERVER_HAVE_NETINET_IN_H
|
||||
#include <netinet/in.h>
|
||||
#include <netinet/tcp.h>
|
||||
#include <arpa/inet.h>
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#ifdef CORBA
|
||||
#include <vncserverctrl.h>
|
||||
#endif
|
||||
|
||||
#ifdef DEBUGPROTO
|
||||
#undef DEBUGPROTO
|
||||
#define DEBUGPROTO(x) x
|
||||
#else
|
||||
#define DEBUGPROTO(x)
|
||||
#endif
|
||||
|
||||
/****************************/
|
||||
#define CEIL(x) ( (double) ((int) (x)) == (x) ? \
|
||||
(double) ((int) (x)) : (double) ((int) (x) + 1) )
|
||||
#define FLOOR(x) ( (double) ((int) (x)) )
|
||||
|
||||
|
||||
int ScaleX(rfbScreenInfoPtr from, rfbScreenInfoPtr to, int x)
|
||||
{
|
||||
if ((from==to) || (from==NULL) || (to==NULL)) return x;
|
||||
return ((int)(((double) x / (double)from->width) * (double)to->width ));
|
||||
}
|
||||
|
||||
int ScaleY(rfbScreenInfoPtr from, rfbScreenInfoPtr to, int y)
|
||||
{
|
||||
if ((from==to) || (from==NULL) || (to==NULL)) return y;
|
||||
return ((int)(((double) y / (double)from->height) * (double)to->height ));
|
||||
}
|
||||
|
||||
/* So, all of the encodings point to the ->screen->frameBuffer,
|
||||
* We need to change this!
|
||||
*/
|
||||
void rfbScaledCorrection(rfbScreenInfoPtr from, rfbScreenInfoPtr to, int *x, int *y, int *w, int *h, char *function)
|
||||
{
|
||||
double x1,y1,w1,h1, x2, y2, w2, h2;
|
||||
double scaleW = ((double) to->width) / ((double) from->width);
|
||||
double scaleH = ((double) to->height) / ((double) from->height);
|
||||
|
||||
|
||||
/*
|
||||
* rfbLog("rfbScaledCorrection(%p -> %p, %dx%d->%dx%d (%dXx%dY-%dWx%dH)\n",
|
||||
* from, to, from->width, from->height, to->width, to->height, *x, *y, *w, *h);
|
||||
*/
|
||||
|
||||
/* If it's the original framebuffer... */
|
||||
if (from==to) return;
|
||||
|
||||
x1 = ((double) *x) * scaleW;
|
||||
y1 = ((double) *y) * scaleH;
|
||||
w1 = ((double) *w) * scaleW;
|
||||
h1 = ((double) *h) * scaleH;
|
||||
|
||||
|
||||
/*cast from double to int is same as "*x = floor(x1);" */
|
||||
x2 = FLOOR(x1);
|
||||
y2 = FLOOR(y1);
|
||||
|
||||
/* include into W and H the jitter of scaling X and Y */
|
||||
w2 = CEIL(w1 + ( x1 - x2 ));
|
||||
h2 = CEIL(h1 + ( y1 - y2 ));
|
||||
|
||||
/*
|
||||
* rfbLog("%s (%dXx%dY-%dWx%dH -> %fXx%fY-%fWx%fH) {%dWx%dH -> %dWx%dH}\n",
|
||||
* function, *x, *y, *w, *h, x2, y2, w2, h2,
|
||||
* from->width, from->height, to->width, to->height);
|
||||
*/
|
||||
|
||||
/* simulate ceil() without math library */
|
||||
*x = (int)x2;
|
||||
*y = (int)y2;
|
||||
*w = (int)w2;
|
||||
*h = (int)h2;
|
||||
|
||||
/* Small changes for a thumbnail may be scaled to zero */
|
||||
if (*w==0) (*w)++;
|
||||
if (*h==0) (*h)++;
|
||||
/* scaling from small to big may overstep the size a bit */
|
||||
if (*x+*w > to->width) *w=to->width - *x;
|
||||
if (*y+*h > to->height) *h=to->height - *y;
|
||||
}
|
||||
|
||||
void rfbScaledScreenUpdateRect(rfbScreenInfoPtr screen, rfbScreenInfoPtr ptr, int x0, int y0, int w0, int h0)
|
||||
{
|
||||
int x,y,w,v,z;
|
||||
int x1, y1, w1, h1;
|
||||
int bitsPerPixel, bytesPerPixel, bytesPerLine, areaX, areaY, area2;
|
||||
unsigned char *srcptr, *dstptr;
|
||||
|
||||
/* Nothing to do!!! */
|
||||
if (screen==ptr) return;
|
||||
|
||||
x1 = x0;
|
||||
y1 = y0;
|
||||
w1 = w0;
|
||||
h1 = h0;
|
||||
|
||||
rfbScaledCorrection(screen, ptr, &x1, &y1, &w1, &h1, "rfbScaledScreenUpdateRect");
|
||||
x0 = ScaleX(ptr, screen, x1);
|
||||
y0 = ScaleY(ptr, screen, y1);
|
||||
w0 = ScaleX(ptr, screen, w1);
|
||||
h0 = ScaleY(ptr, screen, h1);
|
||||
|
||||
bitsPerPixel = screen->bitsPerPixel;
|
||||
bytesPerPixel = bitsPerPixel / 8;
|
||||
bytesPerLine = w1 * bytesPerPixel;
|
||||
srcptr = (unsigned char *)(screen->frameBuffer +
|
||||
(y0 * screen->paddedWidthInBytes + x0 * bytesPerPixel));
|
||||
dstptr = (unsigned char *)(ptr->frameBuffer +
|
||||
( y1 * ptr->paddedWidthInBytes + x1 * bytesPerPixel));
|
||||
/* The area of the source framebuffer for each destination pixel */
|
||||
areaX = ScaleX(ptr,screen,1);
|
||||
areaY = ScaleY(ptr,screen,1);
|
||||
area2 = areaX*areaY;
|
||||
|
||||
|
||||
/* Ensure that we do not go out of bounds */
|
||||
if ((x1+w1) > (ptr->width))
|
||||
{
|
||||
if (x1==0) w1=ptr->width; else x1 = ptr->width - w1;
|
||||
}
|
||||
if ((y1+h1) > (ptr->height))
|
||||
{
|
||||
if (y1==0) h1=ptr->height; else y1 = ptr->height - h1;
|
||||
}
|
||||
/*
|
||||
* rfbLog("rfbScaledScreenUpdateRect(%dXx%dY-%dWx%dH -> %dXx%dY-%dWx%dH <%dx%d>) {%dWx%dH -> %dWx%dH} 0x%p\n",
|
||||
* x0, y0, w0, h0, x1, y1, w1, h1, areaX, areaY,
|
||||
* screen->width, screen->height, ptr->width, ptr->height, ptr->frameBuffer);
|
||||
*/
|
||||
|
||||
if (screen->serverFormat.trueColour) { /* Blend neighbouring pixels together */
|
||||
unsigned char *srcptr2;
|
||||
unsigned long pixel_value, red, green, blue;
|
||||
unsigned int redShift = screen->serverFormat.redShift;
|
||||
unsigned int greenShift = screen->serverFormat.greenShift;
|
||||
unsigned int blueShift = screen->serverFormat.blueShift;
|
||||
unsigned long redMax = screen->serverFormat.redMax;
|
||||
unsigned long greenMax = screen->serverFormat.greenMax;
|
||||
unsigned long blueMax = screen->serverFormat.blueMax;
|
||||
|
||||
/* for each *destination* pixel... */
|
||||
for (y = 0; y < h1; y++) {
|
||||
for (x = 0; x < w1; x++) {
|
||||
red = green = blue = 0;
|
||||
/* Get the totals for rgb from the source grid... */
|
||||
for (w = 0; w < areaX; w++) {
|
||||
for (v = 0; v < areaY; v++) {
|
||||
srcptr2 = &srcptr[(((x * areaX) + w) * bytesPerPixel) +
|
||||
(v * screen->paddedWidthInBytes)];
|
||||
pixel_value = 0;
|
||||
|
||||
|
||||
switch (bytesPerPixel) {
|
||||
case 4: pixel_value = *((unsigned int *)srcptr2); break;
|
||||
case 2: pixel_value = *((unsigned short *)srcptr2); break;
|
||||
case 1: pixel_value = *((unsigned char *)srcptr2); break;
|
||||
default:
|
||||
/* fixme: endianess problem? */
|
||||
for (z = 0; z < bytesPerPixel; z++)
|
||||
pixel_value += (srcptr2[z] << (8 * z));
|
||||
break;
|
||||
}
|
||||
/*
|
||||
srcptr2 += bytesPerPixel;
|
||||
*/
|
||||
|
||||
red += ((pixel_value >> redShift) & redMax);
|
||||
green += ((pixel_value >> greenShift) & greenMax);
|
||||
blue += ((pixel_value >> blueShift) & blueMax);
|
||||
|
||||
}
|
||||
}
|
||||
/* We now have a total for all of the colors, find the average! */
|
||||
red /= area2;
|
||||
green /= area2;
|
||||
blue /= area2;
|
||||
/* Stuff the new value back into memory */
|
||||
pixel_value = ((red & redMax) << redShift) | ((green & greenMax) << greenShift) | ((blue & blueMax) << blueShift);
|
||||
|
||||
switch (bytesPerPixel) {
|
||||
case 4: *((unsigned int *)dstptr) = (unsigned int) pixel_value; break;
|
||||
case 2: *((unsigned short *)dstptr) = (unsigned short) pixel_value; break;
|
||||
case 1: *((unsigned char *)dstptr) = (unsigned char) pixel_value; break;
|
||||
default:
|
||||
/* fixme: endianess problem? */
|
||||
for (z = 0; z < bytesPerPixel; z++)
|
||||
dstptr[z]=(pixel_value >> (8 * z)) & 0xff;
|
||||
break;
|
||||
}
|
||||
dstptr += bytesPerPixel;
|
||||
}
|
||||
srcptr += (screen->paddedWidthInBytes * areaY);
|
||||
dstptr += (ptr->paddedWidthInBytes - bytesPerLine);
|
||||
}
|
||||
} else
|
||||
{ /* Not truecolour, so we can't blend. Just use the top-left pixel instead */
|
||||
for (y = y1; y < (y1+h1); y++) {
|
||||
for (x = x1; x < (x1+w1); x++)
|
||||
memcpy (&ptr->frameBuffer[(y *ptr->paddedWidthInBytes) + (x * bytesPerPixel)],
|
||||
&screen->frameBuffer[(y * areaY * screen->paddedWidthInBytes) + (x *areaX * bytesPerPixel)], bytesPerPixel);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void rfbScaledScreenUpdate(rfbScreenInfoPtr screen, int x1, int y1, int x2, int y2)
|
||||
{
|
||||
/* ok, now the task is to update each and every scaled version of the framebuffer
|
||||
* and we only have to do this for this specific changed rectangle!
|
||||
*/
|
||||
rfbScreenInfoPtr ptr;
|
||||
int count=0;
|
||||
|
||||
/* We don't point to cl->screen as it is the original */
|
||||
for (ptr=screen->scaledScreenNext;ptr!=NULL;ptr=ptr->scaledScreenNext)
|
||||
{
|
||||
/* Only update if it has active clients... */
|
||||
if (ptr->scaledScreenRefCount>0)
|
||||
{
|
||||
rfbScaledScreenUpdateRect(screen, ptr, x1, y1, x2-x1, y2-y1);
|
||||
count++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/* Create a new scaled version of the framebuffer */
|
||||
rfbScreenInfoPtr rfbScaledScreenAllocate(rfbClientPtr cl, int width, int height)
|
||||
{
|
||||
rfbScreenInfoPtr ptr;
|
||||
ptr = malloc(sizeof(rfbScreenInfo));
|
||||
if (ptr!=NULL)
|
||||
{
|
||||
/* copy *everything* (we don't use most of it, but just in case) */
|
||||
memcpy(ptr, cl->screen, sizeof(rfbScreenInfo));
|
||||
ptr->width = width;
|
||||
ptr->height = height;
|
||||
ptr->paddedWidthInBytes = (ptr->bitsPerPixel/8)*ptr->width;
|
||||
|
||||
/* Need to by multiples of 4 for Sparc systems */
|
||||
ptr->paddedWidthInBytes += (ptr->paddedWidthInBytes % 4);
|
||||
|
||||
/* Reset the reference count to 0! */
|
||||
ptr->scaledScreenRefCount = 0;
|
||||
|
||||
ptr->sizeInBytes = ptr->paddedWidthInBytes * ptr->height;
|
||||
ptr->serverFormat = cl->screen->serverFormat;
|
||||
|
||||
ptr->frameBuffer = malloc(ptr->sizeInBytes);
|
||||
if (ptr->frameBuffer!=NULL)
|
||||
{
|
||||
/* Reset to a known condition: scale the entire framebuffer */
|
||||
rfbScaledScreenUpdateRect(cl->screen, ptr, 0, 0, cl->screen->width, cl->screen->height);
|
||||
/* Now, insert into the chain */
|
||||
LOCK(cl->updateMutex);
|
||||
ptr->scaledScreenNext = cl->screen->scaledScreenNext;
|
||||
cl->screen->scaledScreenNext = ptr;
|
||||
UNLOCK(cl->updateMutex);
|
||||
}
|
||||
else
|
||||
{
|
||||
/* Failed to malloc the new frameBuffer, cleanup */
|
||||
free(ptr);
|
||||
ptr=NULL;
|
||||
}
|
||||
}
|
||||
return ptr;
|
||||
}
|
||||
|
||||
/* Find an active scaled version of the framebuffer
|
||||
* TODO: implement a refcount per scaled screen to prevent
|
||||
* unreferenced scaled screens from hanging around
|
||||
*/
|
||||
rfbScreenInfoPtr rfbScalingFind(rfbClientPtr cl, int width, int height)
|
||||
{
|
||||
rfbScreenInfoPtr ptr;
|
||||
/* include the original in the search (ie: fine 1:1 scaled version of the frameBuffer) */
|
||||
for (ptr=cl->screen; ptr!=NULL; ptr=ptr->scaledScreenNext)
|
||||
{
|
||||
if ((ptr->width==width) && (ptr->height==height))
|
||||
return ptr;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
/* Future needs "scale to 320x240, as that's the client's screen size */
|
||||
void rfbScalingSetup(rfbClientPtr cl, int width, int height)
|
||||
{
|
||||
rfbScreenInfoPtr ptr;
|
||||
|
||||
ptr = rfbScalingFind(cl,width,height);
|
||||
if (ptr==NULL)
|
||||
ptr = rfbScaledScreenAllocate(cl,width,height);
|
||||
/* Now, there is a new screen available (if ptr is not NULL) */
|
||||
if (ptr!=NULL)
|
||||
{
|
||||
/* Update it! */
|
||||
if (ptr->scaledScreenRefCount<1)
|
||||
rfbScaledScreenUpdateRect(cl->screen, ptr, 0, 0, cl->screen->width, cl->screen->height);
|
||||
/*
|
||||
* rfbLog("Taking one from %dx%d-%d and adding it to %dx%d-%d\n",
|
||||
* cl->scaledScreen->width, cl->scaledScreen->height,
|
||||
* cl->scaledScreen->scaledScreenRefCount,
|
||||
* ptr->width, ptr->height, ptr->scaledScreenRefCount);
|
||||
*/
|
||||
|
||||
LOCK(cl->updateMutex);
|
||||
cl->scaledScreen->scaledScreenRefCount--;
|
||||
ptr->scaledScreenRefCount++;
|
||||
cl->scaledScreen=ptr;
|
||||
cl->newFBSizePending = TRUE;
|
||||
UNLOCK(cl->updateMutex);
|
||||
|
||||
rfbLog("Scaling to %dx%d (refcount=%d)\n",width,height,ptr->scaledScreenRefCount);
|
||||
}
|
||||
else
|
||||
rfbLog("Scaling to %dx%d failed, leaving things alone\n",width,height);
|
||||
}
|
||||
|
||||
int rfbSendNewScaleSize(rfbClientPtr cl)
|
||||
{
|
||||
/* if the client supports newFBsize Encoding, use it */
|
||||
if (cl->useNewFBSize && cl->newFBSizePending)
|
||||
return FALSE;
|
||||
|
||||
LOCK(cl->updateMutex);
|
||||
cl->newFBSizePending = FALSE;
|
||||
UNLOCK(cl->updateMutex);
|
||||
|
||||
if (cl->PalmVNC==TRUE)
|
||||
{
|
||||
rfbPalmVNCReSizeFrameBufferMsg pmsg;
|
||||
pmsg.type = rfbPalmVNCReSizeFrameBuffer;
|
||||
pmsg.pad1 = 0;
|
||||
pmsg.desktop_w = Swap16IfLE(cl->screen->width);
|
||||
pmsg.desktop_h = Swap16IfLE(cl->screen->height);
|
||||
pmsg.buffer_w = Swap16IfLE(cl->scaledScreen->width);
|
||||
pmsg.buffer_h = Swap16IfLE(cl->scaledScreen->height);
|
||||
pmsg.pad2 = 0;
|
||||
|
||||
rfbLog("Sending a response to a PalmVNC style frameuffer resize event (%dx%d)\n", cl->scaledScreen->width, cl->scaledScreen->height);
|
||||
if (rfbWriteExact(cl, (char *)&pmsg, sz_rfbPalmVNCReSizeFrameBufferMsg) < 0) {
|
||||
rfbLogPerror("rfbNewClient: write");
|
||||
rfbCloseClient(cl);
|
||||
rfbClientConnectionGone(cl);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
rfbResizeFrameBufferMsg rmsg;
|
||||
rmsg.type = rfbResizeFrameBuffer;
|
||||
rmsg.pad1=0;
|
||||
rmsg.framebufferWidth = Swap16IfLE(cl->scaledScreen->width);
|
||||
rmsg.framebufferHeigth = Swap16IfLE(cl->scaledScreen->height);
|
||||
rfbLog("Sending a response to a UltraVNC style frameuffer resize event (%dx%d)\n", cl->scaledScreen->width, cl->scaledScreen->height);
|
||||
if (rfbWriteExact(cl, (char *)&rmsg, sz_rfbResizeFrameBufferMsg) < 0) {
|
||||
rfbLogPerror("rfbNewClient: write");
|
||||
rfbCloseClient(cl);
|
||||
rfbClientConnectionGone(cl);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
return TRUE;
|
||||
}
|
||||
/****************************/
|
@ -40,6 +40,7 @@
|
||||
|
||||
/* libvncserver */
|
||||
#include "rfb/rfb.h"
|
||||
#include "libvncserver/scale.h"
|
||||
#include "rfb/keysym.h"
|
||||
#include "suinput.h"
|
||||
|
||||
@ -58,23 +59,20 @@
|
||||
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;
|
||||
static unsigned int *cmpbuf_rot;
|
||||
|
||||
/* Android already has 5900 bound natively. */
|
||||
#define VNC_PORT 5901
|
||||
static rfbScreenInfoPtr vncscr;
|
||||
|
||||
int xmin, xmax;
|
||||
int ymin, ymax;
|
||||
int idle=0,standby=0;
|
||||
int change=0;
|
||||
static int rotation=0;
|
||||
int idle=0,standby=0,change=0;
|
||||
static int rotation=0,scaling=0;
|
||||
/*****************************************************************************/
|
||||
|
||||
static void (*update_screen)(void)=NULL;
|
||||
@ -116,6 +114,12 @@ static void init_fb(void)
|
||||
|
||||
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;
|
||||
|
||||
@ -125,8 +129,9 @@ static void init_fb(void)
|
||||
(int)scrinfo.xoffset, (int)scrinfo.yoffset,
|
||||
(int)scrinfo.bits_per_pixel);
|
||||
|
||||
off_t o=0;
|
||||
// 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)
|
||||
@ -141,11 +146,11 @@ static void init_fb(void)
|
||||
|
||||
} */
|
||||
|
||||
__android_log_print(ANDROID_LOG_INFO,"VNC","buffer offset=%d * %d\n",o,sysconf(_SC_PAGE_SIZE));
|
||||
// __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);
|
||||
|
||||
fbmmap = mmap(NULL, (scrinfo.xres_virtual*scrinfo.yres_virtual)* bytespp , PROT_READ|PROT_READ , MAP_PRIVATE , fbfd, o*sysconf(_SC_PAGE_SIZE));
|
||||
|
||||
printf("aki %d\n",o*sysconf(_SC_PAGE_SIZE));
|
||||
|
||||
if (fbmmap == MAP_FAILED)
|
||||
{
|
||||
@ -187,27 +192,32 @@ static void cleanup_kbd()
|
||||
}
|
||||
|
||||
/*****************************************************************************/
|
||||
/* response is cl->authChallenge vncEncrypted with passwd */
|
||||
static rfbBool rfbDefaultPasswordCheck(rfbClientPtr cl,const char* response,int len)
|
||||
|
||||
static rfbNewClientHookPtr clientHook(rfbClientPtr cl)
|
||||
{
|
||||
if (strcmp(response,VNC_PASSWORD)==0)
|
||||
return (TRUE);
|
||||
return(FALSE);
|
||||
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);
|
||||
cmpbuf_rot = 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
|
||||
@ -221,6 +231,7 @@ static void init_fb_server(int argc, char **argv)
|
||||
|
||||
vncscr->kbdAddEvent = keyevent;
|
||||
vncscr->ptrAddEvent = ptrevent;
|
||||
vncscr->newClientHook = clientHook;
|
||||
|
||||
if (strcmp(VNC_PASSWORD,"")!=0)
|
||||
{
|
||||
@ -232,9 +243,9 @@ static void init_fb_server(int argc, char **argv)
|
||||
}
|
||||
|
||||
#ifdef DONATE_VERSION
|
||||
vncscr->httpDir="/data/data/org.onaips.vnc/";
|
||||
#else
|
||||
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;
|
||||
@ -566,9 +577,6 @@ inline void transform_touch_coordinates(int *x, int *y)
|
||||
|
||||
static void ptrevent(int buttonMask, int x, int y, rfbClientPtr cl)
|
||||
{
|
||||
struct input_event ev;
|
||||
|
||||
|
||||
static int leftClicked=0,rightClicked=0,middleClicked=0;
|
||||
|
||||
transform_touch_coordinates(&x,&y);
|
||||
@ -662,14 +670,14 @@ static void rotate()
|
||||
|
||||
void print_usage(char **argv)
|
||||
{
|
||||
__android_log_print(ANDROID_LOG_INFO,"VNC","%s [-p password] [-h]\n"
|
||||
__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
|
||||
@ -700,6 +708,16 @@ int main(int argc, char **argv)
|
||||
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++;
|
||||
|
752
jni/vnc/fbvncserver.c~
Executable file
752
jni/vnc/fbvncserver.c~
Executable file
@ -0,0 +1,752 @@
|
||||
/*
|
||||
* $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 <dirent.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include <unistd.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/ioctl.h>
|
||||
|
||||
#include <sys/stat.h>
|
||||
#include <sys/sysmacros.h> /* For makedev() */
|
||||
|
||||
#include <fcntl.h>
|
||||
#include <linux/fb.h>
|
||||
#include <linux/input.h>
|
||||
|
||||
#include <assert.h>
|
||||
#include <errno.h>
|
||||
//android log
|
||||
#include <android/log.h>
|
||||
|
||||
/* 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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
#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", "xres=%d, yres=%d, xresv=%d, yresv=%d, xoffs=%d, yoffs=%d, bpp=%d\n",
|
||||
(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);
|
||||
rfbSendNewScaleSize(cl);
|
||||
}
|
||||
|
||||
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<<scrinfo.red.length)-1);
|
||||
vncscr->serverFormat.greenMax=((1<<scrinfo.green.length)-1);
|
||||
vncscr->serverFormat.blueMax=((1<<scrinfo.blue.length)-1);
|
||||
|
||||
vncscr->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<<scrinfo.red.length)-1);
|
||||
vncscr->serverFormat.greenMax=((1<<scrinfo.green.length)-1);
|
||||
vncscr->serverFormat.blueMax=((1<<scrinfo.blue.length)-1);
|
||||
|
||||
rfbMarkRectAsModified(vncscr, 0, 0, vncscr->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();
|
||||
}
|
@ -7,11 +7,15 @@ void FUNCTION(void)
|
||||
|
||||
update_fb_info();
|
||||
|
||||
//detect active buffer
|
||||
if (scrinfo.yoffset)
|
||||
offset=scrinfo.xres*scrinfo.yres;
|
||||
else
|
||||
offset=0;
|
||||
// // 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;
|
||||
@ -61,10 +65,12 @@ void FUNCTION(void)
|
||||
if (i<min_y)
|
||||
min_y=i;
|
||||
|
||||
if (j>max_x)
|
||||
max_x=j;
|
||||
if (j<min_x)
|
||||
min_x=j;
|
||||
int h=scrinfo.yres-j;
|
||||
|
||||
if (h < min_x)
|
||||
min_x=scrinfo.yres-j;
|
||||
if (h > max_x)
|
||||
max_x=scrinfo.yres-j;
|
||||
|
||||
if (idle)
|
||||
idle=0;
|
||||
@ -113,10 +119,12 @@ void FUNCTION(void)
|
||||
if (i<min_y)
|
||||
min_y=i;
|
||||
|
||||
if (j>max_x)
|
||||
max_x=j;
|
||||
if (j<min_x)
|
||||
min_x=j;
|
||||
int h=scrinfo.yres-j;
|
||||
|
||||
if (h < min_x)
|
||||
min_x=scrinfo.yres-j;
|
||||
if (h > max_x)
|
||||
max_x=scrinfo.yres-j;
|
||||
|
||||
if (idle)
|
||||
idle=0;
|
||||
@ -124,16 +132,17 @@ 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--;
|
||||
// min_x--;
|
||||
max_x++;
|
||||
min_y--;
|
||||
// min_y--;
|
||||
max_y++;
|
||||
|
||||
rfbMarkRectAsModified(vncscr, min_x, min_y, max_x, max_y);
|
||||
@ -143,6 +152,7 @@ memcpy(vncbuf,a,vncscr->width*vncscr->height*scrinfo.bits_per_pixel/CHAR_BIT);
|
||||
// rfbMarkRectAsModified(vncscr, 0, 0, scrinfo.yres,scrinfo.xres);
|
||||
// rfbProcessEvents(vncscr, 10000);
|
||||
|
||||
|
||||
if (idle)
|
||||
{
|
||||
standby=standby+1;
|
||||
@ -152,7 +162,7 @@ memcpy(vncbuf,a,vncscr->width*vncscr->height*scrinfo.bits_per_pixel/CHAR_BIT);
|
||||
else
|
||||
rfbProcessEvents(vncscr, 100000);
|
||||
|
||||
// printf("standby %d xoff=%d yoff=%d\n",standby,scrinfo.xres,scrinfo.yres);
|
||||
// __android_log_print(ANDROID_LOG_INFO,"VNC","standby %d xoff=%d yoff=%d\n",standby,scrinfo.xoffset,scrinfo.yoffset);
|
||||
change=0;
|
||||
}
|
||||
else
|
||||
@ -160,6 +170,6 @@ memcpy(vncbuf,a,vncscr->width*vncscr->height*scrinfo.bits_per_pixel/CHAR_BIT);
|
||||
change=change+1;
|
||||
standby=0;
|
||||
rfbProcessEvents(vncscr, 100000);
|
||||
// printf("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\n",change,min_x,max_x,min_y,max_y,scrinfo.xoffset,scrinfo.yoffset);
|
||||
}
|
||||
}
|
||||
|
175
jni/vnc/update_screen.c~
Normal file
175
jni/vnc/update_screen.c~
Normal file
@ -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 (i<min_x)
|
||||
min_x=i;
|
||||
|
||||
if (j>max_y)
|
||||
max_y=j;
|
||||
if (j<min_y)
|
||||
min_y=j;
|
||||
|
||||
if (idle)
|
||||
idle=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (rotation==90)
|
||||
{
|
||||
for (j = 0; j < scrinfo.yres; j++)
|
||||
{
|
||||
for (i = 0; i < scrinfo.xres; i++)
|
||||
{
|
||||
if (a[(scrinfo.yres - 1 - j + i * scrinfo.yres)] != b[i + j * scrinfo.xres + offset])
|
||||
{
|
||||
a[(scrinfo.yres - 1 - j + i * scrinfo.yres)] = b[i + j * scrinfo.xres + offset ];
|
||||
|
||||
if (i>max_y)
|
||||
max_y=i;
|
||||
if (i<min_y)
|
||||
min_y=i;
|
||||
|
||||
int h=scrinfo.yres-j;
|
||||
|
||||
if (h < min_x)
|
||||
min_x=scrinfo.yres-j;
|
||||
if (h > 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 (i<min_x)
|
||||
min_x=i;
|
||||
|
||||
if (j>max_y)
|
||||
max_y=j;
|
||||
if (j<min_y)
|
||||
min_y=j;
|
||||
|
||||
if (idle)
|
||||
idle=0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
else if (rotation==270)
|
||||
{
|
||||
for (j = 0; j < scrinfo.yres; j++)
|
||||
{
|
||||
|
||||
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 ])
|
||||
{
|
||||
a[(scrinfo.yres - 1 - j + i * scrinfo.yres)] = b[ scrinfo.yres * scrinfo.xres - (i + j * scrinfo.xres) + offset ];
|
||||
if (i>max_y)
|
||||
max_y=i;
|
||||
if (i<min_y)
|
||||
min_y=i;
|
||||
|
||||
int h=scrinfo.yres-j;
|
||||
|
||||
if (h < min_x)
|
||||
min_x=scrinfo.yres-j;
|
||||
if (h > 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);
|
||||
}
|
||||
}
|
Binary file not shown.
@ -53,7 +53,7 @@
|
||||
</TextView>
|
||||
|
||||
</LinearLayout>
|
||||
<!--
|
||||
|
||||
<TextView
|
||||
android:textSize="15sp"
|
||||
android:text="Click on ad to support project"
|
||||
@ -71,5 +71,5 @@ android:layout_height="50dip"
|
||||
android:layout_width="320dip"
|
||||
android:layout_gravity="bottom"
|
||||
android:layout_alignParentBottom="true"
|
||||
/> -->
|
||||
/>
|
||||
</RelativeLayout>
|
||||
|
Binary file not shown.
@ -7,6 +7,21 @@
|
||||
<item>180</item>
|
||||
<item>270</item>
|
||||
</string-array>
|
||||
<string-array name="scale_values">
|
||||
<item>150</item>
|
||||
<item>100</item>
|
||||
<item>50</item>
|
||||
<item>30</item>
|
||||
<item>20</item>
|
||||
</string-array>
|
||||
<string-array name="scale_strings">
|
||||
<item>150 %</item>
|
||||
<item>100 %</item>
|
||||
<item>50 %</item>
|
||||
<item>30 %</item>
|
||||
<item>20 %</item>
|
||||
</string-array>
|
||||
|
||||
<string name="device_info_fmt">
|
||||
droid VNC version: <xliff:g id="application_version">%s</xliff:g>\n
|
||||
Device model: <xliff:g id="device_model">%s</xliff:g>\n
|
||||
|
@ -3,6 +3,7 @@
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<EditTextPreference android:key="password" android:title="VNC password"></EditTextPreference>
|
||||
<ListPreference android:key="rotation" android:title="Rotation" android:entries="@array/rotation_values" android:entryValues="@array/rotation_values"></ListPreference>
|
||||
<ListPreference android:key="scale" android:title="Scale Screen" android:entries="@array/scale_strings" android:entryValues="@array/scale_values"></ListPreference>
|
||||
|
||||
|
||||
|
||||
|
713
src/org/onaips/vnc/MainActivity.java
Normal file
713
src/org/onaips/vnc/MainActivity.java
Normal file
@ -0,0 +1,713 @@
|
||||
/*
|
||||
* 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;
|
||||
|
||||
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.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.Context;
|
||||
import android.content.DialogInterface;
|
||||
import android.content.Intent;
|
||||
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.DhcpInfo;
|
||||
import android.net.Uri;
|
||||
import android.net.wifi.WifiInfo;
|
||||
import android.net.wifi.WifiManager;
|
||||
import android.os.Build;
|
||||
import android.os.Bundle;
|
||||
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 String changelog="-PLEASE REPORT FEEDBACK! (send debug info in menu)<br>- [Add] Server-side screen scaling (change it in preferences - BETA)<br>- [Fix] Half-screen bug<br>New icon<br>Courtesy of Sandro Forbice (@sandroforbice)<br>- [Fix] Double buffering now supported<br>- [Add] Low CPU on idle screen while connected<br>- [Fix] Update while rotated";
|
||||
|
||||
|
||||
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 (!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);
|
||||
}
|
||||
|
||||
showInitialScreen();
|
||||
createBinary();
|
||||
|
||||
|
||||
boolean serverRunning=isAndroidServerRunning();
|
||||
|
||||
setStateLabel(serverRunning);
|
||||
TextView t=(TextView)findViewById(R.id.TextView01);
|
||||
|
||||
if (serverRunning)
|
||||
t.setText("Connect to:\n" + getIpAddress()+":5901" + "\nor\nhttp://" + getIpAddress() + ":5801");
|
||||
else
|
||||
t.setText("");
|
||||
|
||||
|
||||
findViewById(R.id.Button01).setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
Thread t=new Thread(){
|
||||
public void run()
|
||||
{
|
||||
startServerButtonClicked();
|
||||
|
||||
}
|
||||
};
|
||||
t.start();
|
||||
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
for (int i=0;i<5;i++)
|
||||
{
|
||||
|
||||
if (!isAndroidServerRunning())
|
||||
Thread.sleep(1000);
|
||||
else
|
||||
break;
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
// TODO Auto-generated catch block
|
||||
Log.v("VNC","Button01_click:"+ e.getMessage());
|
||||
}
|
||||
|
||||
boolean s=isAndroidServerRunning();
|
||||
if (!s)
|
||||
showTextOnScreen("Couldn't start VNC Server");
|
||||
//setStateLabel(s);
|
||||
return;
|
||||
}
|
||||
}) ;
|
||||
findViewById(R.id.Button02).setOnClickListener(new OnClickListener() {
|
||||
@Override
|
||||
public void onClick(View arg0) {
|
||||
|
||||
Thread t=new Thread(){
|
||||
public void run()
|
||||
{
|
||||
stopServer();
|
||||
|
||||
}
|
||||
};
|
||||
t.start();
|
||||
|
||||
try {
|
||||
Thread.sleep(1000);
|
||||
|
||||
|
||||
for (int i=0;i<5;i++)
|
||||
{
|
||||
if (isAndroidServerRunning())
|
||||
Thread.sleep(1000);
|
||||
else
|
||||
break;
|
||||
}
|
||||
} catch (InterruptedException e) {
|
||||
Log.v("VNC","Button02_click:"+ e.getMessage());
|
||||
|
||||
}
|
||||
boolean s=isAndroidServerRunning();
|
||||
if (s)
|
||||
showTextOnScreen("Couldn't Stop VNC Server\nTry hitting F12 on a connected client");
|
||||
//setStateLabel(s);
|
||||
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()
|
||||
{
|
||||
// Initialize preferences
|
||||
preferences = PreferenceManager.getDefaultSharedPreferences(this );
|
||||
SharedPreferences.Editor editor = preferences.edit();
|
||||
|
||||
String message="Changelog:<br><br>" + changelog;
|
||||
|
||||
String version=packageVersion();
|
||||
|
||||
if (!free_version())
|
||||
{
|
||||
if (version.equals(preferences.getString("version", "")))
|
||||
return;
|
||||
editor.putString("version", version);
|
||||
editor.commit();
|
||||
}
|
||||
|
||||
|
||||
startDialog = new AlertDialog.Builder(this).create();
|
||||
startDialog.setTitle("droid VNC Server " + version);
|
||||
startDialog.setMessage(Html.fromHtml(message));
|
||||
startDialog.setIcon(R.drawable.icon);
|
||||
|
||||
if (free_version())
|
||||
{
|
||||
startDialog.setButton(AlertDialog.BUTTON1,"Wait...", 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.setCancelable(false);
|
||||
startDialog.show();
|
||||
|
||||
Button b=(Button)startDialog.getButton(AlertDialog.BUTTON1);
|
||||
b.setEnabled(false);
|
||||
|
||||
Timer t1=new Timer();
|
||||
t1.schedule(new TimerTask() {
|
||||
@Override
|
||||
public void run() {
|
||||
runOnUiThread(new Runnable(){
|
||||
public void run() {
|
||||
// ((DialogInterface) startDialog).dismiss();
|
||||
Button b=(Button)startDialog.getButton(AlertDialog.BUTTON1);
|
||||
b.setEnabled(true);
|
||||
b.setText("OK");
|
||||
}
|
||||
});
|
||||
}
|
||||
}, (long)10000);
|
||||
}
|
||||
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_ONAIPS,0,"About");
|
||||
menu.add(0, MENU_HELP, 0, "Help");
|
||||
menu.add(0, MENU_QUIT, 0, "Close");
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public void setStateLabel(boolean state)
|
||||
{
|
||||
TextView stateLabel=(TextView)findViewById(R.id.stateLabel);
|
||||
stateLabel.setText(state?"Running":"Stopped");
|
||||
stateLabel.setTextColor(state?Color.GREEN:Color.RED);
|
||||
}
|
||||
|
||||
public String getIpAddress()
|
||||
{
|
||||
WifiManager wifiManager = (WifiManager) getSystemService(WIFI_SERVICE);
|
||||
DhcpInfo dhcpInfo = wifiManager.getDhcpInfo();
|
||||
|
||||
|
||||
return intToIp(dhcpInfo.ipAddress);
|
||||
}
|
||||
|
||||
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();
|
||||
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())
|
||||
{
|
||||
new AlertDialog.Builder(this)
|
||||
.setTitle("Alert")
|
||||
.setMessage(Html.fromHtml("There is another daemon already running, do you want to kill it?"))
|
||||
.setPositiveButton("Yes", new DialogInterface.OnClickListener() {
|
||||
|
||||
@Override
|
||||
public void onClick(DialogInterface arg0, int arg1) {
|
||||
stopServer();
|
||||
startServer();
|
||||
}
|
||||
})
|
||||
.setNegativeButton("Cancel", new DialogInterface.OnClickListener() {
|
||||
@Override
|
||||
public void onClick(DialogInterface arg0, int arg1) {
|
||||
return;
|
||||
}
|
||||
})
|
||||
.show();
|
||||
}
|
||||
else
|
||||
startServer();
|
||||
}
|
||||
|
||||
|
||||
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;
|
||||
|
||||
|
||||
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);
|
||||
|
||||
|
||||
} 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:<br><br>Right Click -> Back<br>Middle Click -> End Call<br>Left Click -> Touch<br><br>Keyboard Mappings<br><br>" +
|
||||
"Home Key -> Home<br>Escape -> Back<br>Page Up ->Menu<br>Left Ctrl -> Search<br>PgDown -> Start Call<br>" +
|
||||
"End Key -> End Call<br>F4 -> Rotate<br>F11 -> Disconnect Server<br>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_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() + "<br><br>developed by oNaiPs<br><br>Graphics: Sandro Forbice (@sandroforbice)<br><br>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 {
|
||||
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 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();
|
||||
|
||||
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<ResolveInfo> 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;
|
||||
}
|
||||
}
|
||||
|
18
src/org/onaips/vnc/preferences.java
Normal file
18
src/org/onaips/vnc/preferences.java
Normal file
@ -0,0 +1,18 @@
|
||||
package org.onaips.vnc;
|
||||
|
||||
|
||||
|
||||
|
||||
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);
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user