so much things...

This commit is contained in:
JosePereira 2012-06-12 04:11:34 +01:00
parent 1574f13190
commit cedbda842c
56 changed files with 353 additions and 6528 deletions

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
package="org.onaips.vnc"
android:versionCode="56"
android:versionName="1.0a3" >
android:versionCode="57"
android:versionName="1.1RC0" >
<uses-sdk android:minSdkVersion="5" />

View File

@ -1,7 +1,10 @@
v1.1a
- ICS support
- Changed to official libvncserver v0.9.9.
- Decoupled native screen grabber from jni sources, you wont need to have AOSP anymore, just the precompiled libs.
- Fixed misc random segfault
- Added display rotation to 180, for zte
v1.0a

3
README
View File

@ -17,7 +17,7 @@ Connects to the daemon using local IPC.
-------------- Compile C daemon ---------------------
On project folder:
$ ndk-build
$ cp libs/armeabi/androidvncserver /res/raw
$ mv libs/armeabi/androidvncserver /res/raw/androidvncserver.mp3 :O mp3 overcomes the 1MB limitation on some resources
-------------- Compile Wrapper libs -----------------
$ cd <aosp_folder>
@ -27,6 +27,7 @@ On project folder:
To build:
$ mm external/nativeMethods
$ cp <droid-vnc-folder>/nativeMethods/lib/* <droid-vnc-folder>/res/raw
-------------- Compile GUI------- -------------------

Binary file not shown.

Binary file not shown.

View File

@ -71,6 +71,6 @@ LOCAL_C_INCLUDES += \
LOCAL_STATIC_LIBRARIES := libjpeg libpng libssl_static libcrypto_static
LOCAL_MODULE:= androidvncserver
LOCAL_MODULE := androidvncserver
include $(BUILD_EXECUTABLE)

View File

@ -437,9 +437,9 @@
/* #undef LIBVNCSERVER_HAVE_XTESTGRABCONTROL */
/* Enable IPv6 support */
#ifndef LIBVNCSERVER_IPv6
/*#ifndef LIBVNCSERVER_IPv6
#define LIBVNCSERVER_IPv6 1
#endif
#endif*/
/* Define to 1 if `lstat' dereferences a symlink specified with a trailing
slash. */

View File

@ -47,9 +47,10 @@ unsigned int *vncbuf;
static rfbScreenInfoPtr vncscr;
uint32_t idle = 0;
uint32_t standby = 0;
uint32_t standby = 1;
uint16_t rotation = 0;
uint16_t scaling = 100;
uint8_t display_rotate_180 = 0;
//reverse connection
char *rhost = NULL;
@ -80,11 +81,6 @@ inline int getCurrentRotation()
return rotation;
}
inline int isIdle()
{
return idle;
}
void setIdle(int i)
{
idle=i;
@ -175,8 +171,9 @@ void initVncServer(int argc, char **argv)
vncscr->passwordCheck = rfbCheckPasswordByList;
}
vncscr->httpDir="/data/data/org.onaips.vnc/files/";
vncscr->sslcertfile="self.pem";
vncscr->httpDir = "webclients/";
// vncscr->httpEnableProxyConnect = TRUE;
vncscr->sslcertfile = "self.pem";
vncscr->serverFormat.redShift = screenformat.redShift;
vncscr->serverFormat.greenShift = screenformat.greenShift;
@ -206,7 +203,8 @@ void initVncServer(int argc, char **argv)
vncscr->serverFormat.bitsPerPixel);
sendMsgToGui("~SHOW|Unsupported pixel depth, please send bug report.\n");
return;
close_app();
exit(-1);
}
/* Mark as dirty since we haven't sent any updates at all yet. */
@ -218,7 +216,7 @@ void initVncServer(int argc, char **argv)
void rotate(int value)
{
L("rotate()");
L("rotate()\n");
if (value == -1 ||
((value == 90 || value == 270) && (rotation == 0 || rotation == 180)) ||
@ -302,16 +300,22 @@ void initGrabberMethod()
method = GRALLOC;
else if (initFB() != -1) {
method = FRAMEBUFFER;
} else if (initADB() != -1) {
}
#if 0
else if (initADB() != -1) {
method = ADB;
readBufferADB();
}
#endif
} else if (method == FRAMEBUFFER)
initFB();
#if 0
else if (method == ADB) {
initADB();
readBufferADB();
} else if (method == GRALLOC)
}
#endif
else if (method == GRALLOC)
initGralloc();
else if (method == FLINGER)
initFlinger();
@ -326,7 +330,8 @@ void printUsage(char **argv)
"-p <password>\t- Password to access server\n"
"-r <rotation>\t- Screen rotation (degrees) (0,90,180,270)\n"
"-R <host:port>\t- Host for reverse connection\n"
"-s <scale>\t- Scale percentage (20,30,50,100,150)\n\n" );
"-s <scale>\t- Scale percentage (20,30,50,100,150)\n"
"-z\t- Rotate display 180º (for zte compatibility)\n\n");
}
@ -336,6 +341,7 @@ int main(int argc, char **argv)
signal(SIGINT, close_app);
signal(SIGKILL, close_app);
signal(SIGILL, close_app);
long usec;
if(argc > 1) {
int i=1;
@ -355,6 +361,10 @@ int main(int argc, char **argv)
i++;
FB_setDevice(argv[i]);
break;
case 'z':
i++;
display_rotate_180=1;
break;
case 'P':
i++;
VNC_PORT=atoi(argv[i]);
@ -396,12 +406,12 @@ int main(int argc, char **argv)
} else {
L("Grab method \"%s\" not found, sticking with auto-detection.\n",argv[i]);
}
break;
}
}
i++;
}
}
break;
}
}
i++;
}
}
L("Initializing grabber method...\n");
initGrabberMethod();
@ -440,10 +450,9 @@ i++;
}
}
rfbRunEventLoop(vncscr,-1,TRUE);
while (1) {
usleep(300000*(standby/2.0));
usec=vncscr->deferUpdateTime*2000*standby;
rfbProcessEvents(vncscr,usec);
if (idle)
standby++;
@ -451,9 +460,13 @@ i++;
standby=2;
if (vncscr->clientHead == NULL)
{
idle=1;
standby=50;
continue;
}
update_screen();
}
close_app();
}
}

View File

@ -105,7 +105,7 @@ void *handle_connections()
n = recvfrom(hServerSocket,pBuffer,BUFFER_SIZE,0,(struct sockaddr *)&from,&fromlen);
if (n < 0) perror("recvfrom");
L("Recebido: %s\n",pBuffer);
//L("Recebido: %s\n",pBuffer);
if (strstr(pBuffer,"~PING|")!=NULL)
{

View File

@ -31,12 +31,22 @@ getscreenformat_fn_type getscreenformat_flinger = NULL;
int initFlinger(void)
{
L("--Loading flinger native lib--\n");
int i,len;
char lib_name[64];
flinger_lib = dlopen("/data/libdvnc_flinger_sdk14.so", RTLD_NOW);
if(flinger_lib == NULL) {
L("Couldnt load library! Error string: %s\n",dlerror());
len=ARR_LEN(compiled_sdks);
for (i=0;i<len;i++) {
sprintf(lib_name, DVNC_FILES_PATH "/libdvnc_flinger_sdk%d.so",compiled_sdks[i]);
L("Loading lib: %s\n",lib_name);
flinger_lib = dlopen(lib_name, RTLD_NOW);
if (flinger_lib != NULL)
break;
else if(i+1 == len) {
L("Couldnt load any flinger library! Error string: %s\n",dlerror());
return -1;
}
}
init_fn_type init_flinger = dlsym(flinger_lib,"init_flinger");
if(init_flinger == NULL) {
@ -61,12 +71,15 @@ int initFlinger(void)
L("Couldn't load get_screenformat! Error string: %s\n",dlerror());
return -1;
}
L("AKI1\n");
int ret = init_flinger();
L("AKII12");
if (ret == -1) {
L("flinger method not supported by this device!\n");
return -1;
}
L("AKI2\n");
screenformat = getScreenFormatFlinger();
if ( screenformat.width <= 0 ) {
@ -78,7 +91,6 @@ int initFlinger(void)
L("Error: Could not read surfaceflinger buffer!\n");
return -1;
}
return 0;
}

View File

@ -45,6 +45,10 @@ void update_fb_info(void)
}
}
inline int roundUpToPageSize(int x) {
return (x + (PAGE_SIZE-1)) & ~(PAGE_SIZE-1);
}
int initFB(void)
{
L("--Initializing framebuffer access method--\n");
@ -124,8 +128,3 @@ unsigned int *readBufferFB(void)
update_fb_info();
return fbmmap;
}
inline int roundUpToPageSize(int x) {
return (x + (PAGE_SIZE-1)) & ~(PAGE_SIZE-1);
}

View File

@ -33,11 +33,22 @@ int initGralloc(void)
{
L("--Loading gralloc native lib--\n");
gralloc_lib = dlopen("/data/libdvnc_gralloc_sdk14.so", RTLD_NOW);
if(gralloc_lib == NULL) {
int i,len;
char lib_name[64];
len=ARR_LEN(compiled_sdks);
for (i=0;i<len;i++) {
sprintf(lib_name, DVNC_FILES_PATH "/libdvnc_gralloc_sdk%d.so",compiled_sdks[i]);
L("Loading lib: %s\n",lib_name);
gralloc_lib = dlopen(lib_name, RTLD_NOW);
if (gralloc_lib != NULL)
break;
else if(i+1 == len) {
L("Couldnt load library! Error string: %s\n",dlerror());
return -1;
}
}
init_fn_type init_gralloc = dlsym(gralloc_lib,"init_gralloc");
if(init_gralloc == NULL) {

View File

@ -24,12 +24,17 @@ Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
void FUNCTION(void)
{
int i,j;
int i,j,r;
int offset=0,pixelToVirtual;
OUT_T* a;
OUT_T* b=0;
struct fb_var_screeninfo scrinfo; //we'll need this to detect double FB on framebuffer
if (display_rotate_180){
r=rotation;
rotation+=180;
}
if (method==FRAMEBUFFER) {
scrinfo = FB_getscrinfo();
b = (OUT_T*) readBufferFB();
@ -177,6 +182,8 @@ void FUNCTION(void)
rfbMarkRectAsModified(vncscr, min_x, min_y, max_x, max_y);
}
if (display_rotate_180)
rotation=r;
}

Binary file not shown.

View File

@ -75,4 +75,9 @@ void setIdle(int i);
void close_app();
screenFormat screenformat;
#define DVNC_FILES_PATH "/data/data/org.onaips.vnc/files/"
#define ARR_LEN(a) (sizeof(a)/sizeof(a)[0])
static int compiled_sdks[] = {10, 14};
#endif

View File

@ -19,6 +19,8 @@ ifeq ($(PLATFORM_SDK_VERSION),9)
LOCAL_SHARED_LIBRARIES := libsurfaceflinger_client libui libbinder libutils libcutils #libcrypto libssl libhardware
else ifeq ($(PLATFORM_SDK_VERSION),10)
LOCAL_SHARED_LIBRARIES := libsurfaceflinger_client libui libbinder libutils libcutils #libcrypto libssl libhardware
else ifeq ($(PLATFORM_SDK_VERSION),14)
LOCAL_SHARED_LIBRARIES := libgui libui libbinder libcutils
else ifeq ($(PLATFORM_SDK_VERSION),15)
LOCAL_SHARED_LIBRARIES := libgui libui libbinder libcutils
else

View File

@ -65,13 +65,14 @@ extern "C" int init_flinger()
L("--Initializing gingerbread access method--\n");
screenshotClient=new ScreenshotClient();
errno=screenshotClient->update();
screenshotClient = new ScreenshotClient();
errno = screenshotClient->update();
if (!screenshotClient->getPixels())
return -1;
if (errno != NO_ERROR) {
L("screen capture failed: %s\n", strerror(-errno));
return -1;
}
return 0;
}

Binary file not shown.

View File

@ -1,13 +1,10 @@
<?xml version="1.0" encoding="utf-8"?>
<set>
<rotate
<alpha
xmlns:android="http://schemas.android.com/apk/res/android"
android:fromDegrees="0"
android:toDegrees="359"
android:pivotX="50%"
android:pivotY="50%"
android:repeatCount="infinite"
android:duration="1200"
android:interpolator="@android:anim/linear_interpolator"
/>
android:fromAlpha="0.0"
android:toAlpha="1.0"
android:duration="500"
android:repeatMode="reverse"
android:repeatCount="infinite" />
</set>

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 12 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.5 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 13 KiB

After

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 11 KiB

Binary file not shown.

Before

Width:  |  Height:  |  Size: 3.4 KiB

View File

@ -1,32 +1,94 @@
<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout
xmlns:android="http://schemas.android.com/apk/res/android"
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
xmlns:ads="http://schemas.android.com/apk/lib/com.google.ads"
android:layout_height="fill_parent" android:orientation="vertical"
android:background="@drawable/bg" android:layout_width="match_parent" android:gravity="bottom">
android:layout_width="match_parent"
android:layout_height="fill_parent"
android:background="@drawable/bg"
android:gravity="bottom"
android:orientation="vertical" >
<LinearLayout
android:layout_width="fill_parent"
android:orientation="horizontal" android:layout_centerHorizontal="true"
<LinearLayout
android:id="@+id/layout1"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:layout_centerVertical="true" android:id="@+id/layout1">
<LinearLayout android:layout_width="wrap_content" android:layout_height="match_parent" android:id="@+id/linearLayout1" android:orientation="vertical" android:weightSum="1">
<ImageView android:layout_width="260dp" android:src="@drawable/droidvnclogo" android:layout_weight="0.01" android:layout_height="wrap_content"></ImageView>
<TextView android:id="@+id/stateLabel" android:layout_height="wrap_content" android:text="@+id/TextView01" android:textSize="30sp" android:paddingTop="10dp" android:typeface="sans" android:layout_gravity="center_horizontal" android:layout_width="wrap_content"></TextView>
<TextView android:layout_width="wrap_content" android:gravity="center" android:shadowRadius="0.5" android:id="@+id/TextView01" android:layout_height="wrap_content" android:text="@+id/TextView02" android:shadowDy="1.0" android:shadowColor="#111" android:textSize="15sp" android:paddingTop="10dp" android:typeface="sans" android:layout_gravity="center_horizontal"></TextView>
android:layout_centerHorizontal="true"
android:layout_centerVertical="true"
android:orientation="horizontal" >
<LinearLayout
android:id="@+id/linearLayout1"
android:layout_width="wrap_content"
android:layout_height="match_parent"
android:gravity="center_horizontal|center_vertical"
android:orientation="vertical" >
<ImageView
android:layout_width="260dp"
android:layout_height="wrap_content"
android:src="@drawable/droidvnclogo" >
</ImageView>
<TextView
android:id="@+id/stateLabel"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:paddingTop="10dp"
android:text="@+id/TextView01"
android:textSize="30sp"
android:typeface="sans" >
</TextView>
<TextView
android:id="@+id/TextView01"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_gravity="center_horizontal"
android:gravity="center"
android:paddingTop="10dp"
android:shadowColor="#111"
android:shadowDy="1.0"
android:shadowRadius="0.5"
android:text="@+id/TextView02"
android:textSize="15sp"
android:typeface="sans" >
</TextView>
</LinearLayout>
<RelativeLayout android:id="@+id/relativeLayout1" android:layout_height="177dp" android:layout_gravity="center" android:layout_width="match_parent">
<Button android:background="@drawable/btnstart" android:layout_width="150dp" android:layout_centerInParent="true" android:id="@+id/Button01" android:layout_height="150dp"></Button>
<Button android:layout_alignParentBottom="true" android:background="@drawable/restart_normal" android:id="@+id/Button02" android:layout_toRightOf="@id/Button01" android:layout_height="30dp" android:layout_width="30dp"></Button>
<RelativeLayout
android:id="@+id/relativeLayout1"
android:layout_width="wrap_content"
android:layout_height="177dp"
android:gravity="center_horizontal|center_vertical"
android:layout_gravity="center" >
<Button
android:id="@+id/Button01"
android:layout_width="150dp"
android:layout_height="150dp"
android:layout_centerInParent="true"
android:background="@drawable/btnstart" >
</Button>
<Button
android:id="@+id/Button02"
android:layout_width="30dp"
android:layout_height="30dp"
android:layout_alignParentBottom="true"
android:layout_toRightOf="@id/Button01"
android:background="@drawable/restart_normal" >
</Button>
</RelativeLayout>
</LinearLayout>
</LinearLayout>
<com.google.ads.AdView android:id="@+id/adView"
<com.google.ads.AdView
android:id="@+id/adView"
android:layout_width="wrap_content"
android:layout_height="wrap_content"
android:layout_alignParentBottom="true"
android:layout_centerHorizontal="true"
ads:adUnitId="a14c45a1d8a1817"
ads:adSize="BANNER"/>
ads:adSize="BANNER"
ads:adUnitId="a14c45a1d8a1817" />
</RelativeLayout>

Binary file not shown.

Binary file not shown.

View File

@ -1,147 +0,0 @@
/*
* Modified from:
* http://lxr.mozilla.org/mozilla/source/extensions/xml-rpc/src/nsXmlRpcClient.js#956
*/
/* ***** BEGIN LICENSE BLOCK *****
* Version: MPL 1.1/GPL 2.0/LGPL 2.1
*
* The contents of this file are subject to the Mozilla Public License Version
* 1.1 (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.mozilla.org/MPL/
*
* Software distributed under the License is distributed on an "AS IS" basis,
* WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
* for the specific language governing rights and limitations under the
* License.
*
* The Original Code is Mozilla XML-RPC Client component.
*
* The Initial Developer of the Original Code is
* Digital Creations 2, Inc.
* Portions created by the Initial Developer are Copyright (C) 2000
* the Initial Developer. All Rights Reserved.
*
* Contributor(s):
* Martijn Pieters <mj@digicool.com> (original author)
* Samuel Sieb <samuel@sieb.net>
*
* Alternatively, the contents of this file may be used under the terms of
* either the GNU General Public License Version 2 or later (the "GPL"), or
* the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
* in which case the provisions of the GPL or the LGPL are applicable instead
* of those above. If you wish to allow use of your version of this file only
* under the terms of either the GPL or the LGPL, and not to allow others to
* use your version of this file under the terms of the MPL, indicate your
* decision by deleting the provisions above and replace them with the notice
* and other provisions required by the GPL or the LGPL. If you do not delete
* the provisions above, a recipient may use your version of this file under
* the terms of any one of the MPL, the GPL or the LGPL.
*
* ***** END LICENSE BLOCK ***** */
/*jslint white: false, bitwise: false, plusplus: false */
/*global console */
var Base64 = {
/* Convert data (an array of integers) to a Base64 string. */
toBase64Table : 'ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/',
base64Pad : '=',
encode: function (data) {
"use strict";
var result = '',
chrTable = Base64.toBase64Table.split(''),
pad = Base64.base64Pad,
length = data.length,
i;
// Convert every three bytes to 4 ascii characters.
for (i = 0; i < (length - 2); i += 3) {
result += chrTable[data[i] >> 2];
result += chrTable[((data[i] & 0x03) << 4) + (data[i+1] >> 4)];
result += chrTable[((data[i+1] & 0x0f) << 2) + (data[i+2] >> 6)];
result += chrTable[data[i+2] & 0x3f];
}
// Convert the remaining 1 or 2 bytes, pad out to 4 characters.
if (length%3) {
i = length - (length%3);
result += chrTable[data[i] >> 2];
if ((length%3) === 2) {
result += chrTable[((data[i] & 0x03) << 4) + (data[i+1] >> 4)];
result += chrTable[(data[i+1] & 0x0f) << 2];
result += pad;
} else {
result += chrTable[(data[i] & 0x03) << 4];
result += pad + pad;
}
}
return result;
},
/* Convert Base64 data to a string */
toBinaryTable : [
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,-1,
-1,-1,-1,-1, -1,-1,-1,-1, -1,-1,-1,62, -1,-1,-1,63,
52,53,54,55, 56,57,58,59, 60,61,-1,-1, -1, 0,-1,-1,
-1, 0, 1, 2, 3, 4, 5, 6, 7, 8, 9,10, 11,12,13,14,
15,16,17,18, 19,20,21,22, 23,24,25,-1, -1,-1,-1,-1,
-1,26,27,28, 29,30,31,32, 33,34,35,36, 37,38,39,40,
41,42,43,44, 45,46,47,48, 49,50,51,-1, -1,-1,-1,-1
],
decode: function (data, offset) {
"use strict";
offset = typeof(offset) !== 'undefined' ? offset : 0;
var binTable = Base64.toBinaryTable,
pad = Base64.base64Pad,
result, result_length, idx, i, c, padding,
leftbits = 0, // number of bits decoded, but yet to be appended
leftdata = 0, // bits decoded, but yet to be appended
data_length = data.indexOf('=') - offset;
if (data_length < 0) { data_length = data.length - offset; }
/* Every four characters is 3 resulting numbers */
result_length = (data_length >> 2) * 3 + Math.floor((data_length%4)/1.5);
result = new Array(result_length);
// Convert one by one.
for (idx = 0, i = offset; i < data.length; i++) {
c = binTable[data.charCodeAt(i) & 0x7f];
padding = (data.charAt(i) === pad);
// Skip illegal characters and whitespace
if (c === -1) {
console.error("Illegal character '" + data.charCodeAt(i) + "'");
continue;
}
// Collect data into leftdata, update bitcount
leftdata = (leftdata << 6) | c;
leftbits += 6;
// If we have 8 or more bits, append 8 bits to the result
if (leftbits >= 8) {
leftbits -= 8;
// Append if not padding.
if (!padding) {
result[idx++] = (leftdata >> leftbits) & 0xff;
}
leftdata &= (1 << leftbits) - 1;
}
}
// If there are any bits left, the base64 string was corrupted
if (leftbits) {
throw {name: 'Base64-Error',
message: 'Corrupted base64 string'};
}
return result;
}
}; /* End of Base64 namespace */

View File

@ -1,124 +0,0 @@
body {
margin: 0px;
font-size: 13px;
color: #111;
font-family: "Helvetica";
}
#VNC_controls {
background: #111;
line-height: 1em;
color: #FFF;
overflow: hidden;
padding: 4px 24px;
}
#VNC_controls ul {
list-style:none;
list-style-position: outside;
margin: 0px;
padding: 0px;
}
#VNC_controls li {
margin-right: 15px;
padding: 2px 0px;
float: left;
}
#VNC_controls li input[type=text],
#VNC_controls li input[type=password] {
border: 2px solid #333;
}
#VNC_host {
width: 100px;
}
#VNC_port {
width: 50px;
}
#VNC_password {
width: 80px;
}
#VNC_encrypt {
}
#VNC_connect_button {
width: 100px;
}
#VNC_status_bar td {
padding: 0px;
margin: 0px;
}
#VNC_status_bar div {
font-size: 12px;
font-weight: bold;
text-align: center;
margin: 0px;
padding: 1em;
}
.VNC_status_button {
font-size: 10px;
margin: 0px;
padding: 0px;
}
#VNC_status {
text-align: center;
}
#VNC_settings_menu {
display: none;
position: absolute;
width: 13em;
border: 1px solid #888;
color: #111;
font-weight: normal;
background-color: #f0f2f6;
padding: 5px; margin: 3px;
z-index: 100; opacity: 1;
text-align: left; white-space: normal;
}
#VNC_settings_menu ul {
list-style: none;
margin: 0px;
padding: 0px;
}
.VNC_buttons_right {
text-align: right;
}
.VNC_buttons_left {
text-align: left;
}
.VNC_status_normal {
background: #111;
color: #fff;
}
.VNC_status_error {
background: #111;
color: #f44;
}
.VNC_status_warn {
background: #111;
color: #ff4;
}
#VNC_screen {
-webkit-border-radius: 10px;
-moz-border-radius: 10px;
border-radius: 10px;
background: #111;
padding: 20px;
margin: 0 auto;
color: #FFF;
margin-top: 20px;
text-align: center;
/* This causes the width of the outer div(#screen) honor the size of the inner (#vnc) div */
display: table;
table-layout: auto;
}
#VNC_canvas {
background: #111;
margin: 0 auto;
}
#VNC_clipboard {
display: none;
}

View File

@ -1,273 +0,0 @@
/*
* Ported from Flashlight VNC ActionScript implementation:
* http://www.wizhelp.com/flashlight-vnc/
*
* Full attribution follows:
*
* -------------------------------------------------------------------------
*
* This DES class has been extracted from package Acme.Crypto for use in VNC.
* The unnecessary odd parity code has been removed.
*
* These changes are:
* Copyright (C) 1999 AT&T Laboratories Cambridge. All Rights Reserved.
*
* 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.
*
* DesCipher - the DES encryption method
*
* The meat of this code is by Dave Zimmerman <dzimm@widget.com>, and is:
*
* Copyright (c) 1996 Widget Workshop, Inc. All Rights Reserved.
*
* Permission to use, copy, modify, and distribute this software
* and its documentation for NON-COMMERCIAL or COMMERCIAL purposes and
* without fee is hereby granted, provided that this copyright notice is kept
* intact.
*
* WIDGET WORKSHOP MAKES NO REPRESENTATIONS OR WARRANTIES ABOUT THE SUITABILITY
* OF THE SOFTWARE, EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
* TO THE IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
* PARTICULAR PURPOSE, OR NON-INFRINGEMENT. WIDGET WORKSHOP SHALL NOT BE LIABLE
* FOR ANY DAMAGES SUFFERED BY LICENSEE AS A RESULT OF USING, MODIFYING OR
* DISTRIBUTING THIS SOFTWARE OR ITS DERIVATIVES.
*
* THIS SOFTWARE IS NOT DESIGNED OR INTENDED FOR USE OR RESALE AS ON-LINE
* CONTROL EQUIPMENT IN HAZARDOUS ENVIRONMENTS REQUIRING FAIL-SAFE
* PERFORMANCE, SUCH AS IN THE OPERATION OF NUCLEAR FACILITIES, AIRCRAFT
* NAVIGATION OR COMMUNICATION SYSTEMS, AIR TRAFFIC CONTROL, DIRECT LIFE
* SUPPORT MACHINES, OR WEAPONS SYSTEMS, IN WHICH THE FAILURE OF THE
* SOFTWARE COULD LEAD DIRECTLY TO DEATH, PERSONAL INJURY, OR SEVERE
* PHYSICAL OR ENVIRONMENTAL DAMAGE ("HIGH RISK ACTIVITIES"). WIDGET WORKSHOP
* SPECIFICALLY DISCLAIMS ANY EXPRESS OR IMPLIED WARRANTY OF FITNESS FOR
* HIGH RISK ACTIVITIES.
*
*
* The rest is:
*
* Copyright (C) 1996 by Jef Poskanzer <jef@acme.com>. All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions
* are met:
* 1. Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* 2. Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND
* ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE
* FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
* DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
* OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
* HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
* LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
* OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*
* Visit the ACME Labs Java page for up-to-date versions of this and other
* fine Java utilities: http://www.acme.com/java/
*/
"use strict";
/*jslint white: false, bitwise: false, plusplus: false */
function DES(passwd) {
// Tables, permutations, S-boxes, etc.
var PC2 = [13,16,10,23, 0, 4, 2,27,14, 5,20, 9,22,18,11, 3,
25, 7,15, 6,26,19,12, 1,40,51,30,36,46,54,29,39,
50,44,32,47,43,48,38,55,33,52,45,41,49,35,28,31 ],
totrot = [ 1, 2, 4, 6, 8,10,12,14,15,17,19,21,23,25,27,28],
z = 0x0, a,b,c,d,e,f, SP1,SP2,SP3,SP4,SP5,SP6,SP7,SP8,
keys = [];
a=1<<16; b=1<<24; c=a|b; d=1<<2; e=1<<10; f=d|e;
SP1 = [c|e,z|z,a|z,c|f,c|d,a|f,z|d,a|z,z|e,c|e,c|f,z|e,b|f,c|d,b|z,z|d,
z|f,b|e,b|e,a|e,a|e,c|z,c|z,b|f,a|d,b|d,b|d,a|d,z|z,z|f,a|f,b|z,
a|z,c|f,z|d,c|z,c|e,b|z,b|z,z|e,c|d,a|z,a|e,b|d,z|e,z|d,b|f,a|f,
c|f,a|d,c|z,b|f,b|d,z|f,a|f,c|e,z|f,b|e,b|e,z|z,a|d,a|e,z|z,c|d];
a=1<<20; b=1<<31; c=a|b; d=1<<5; e=1<<15; f=d|e;
SP2 = [c|f,b|e,z|e,a|f,a|z,z|d,c|d,b|f,b|d,c|f,c|e,b|z,b|e,a|z,z|d,c|d,
a|e,a|d,b|f,z|z,b|z,z|e,a|f,c|z,a|d,b|d,z|z,a|e,z|f,c|e,c|z,z|f,
z|z,a|f,c|d,a|z,b|f,c|z,c|e,z|e,c|z,b|e,z|d,c|f,a|f,z|d,z|e,b|z,
z|f,c|e,a|z,b|d,a|d,b|f,b|d,a|d,a|e,z|z,b|e,z|f,b|z,c|d,c|f,a|e];
a=1<<17; b=1<<27; c=a|b; d=1<<3; e=1<<9; f=d|e;
SP3 = [z|f,c|e,z|z,c|d,b|e,z|z,a|f,b|e,a|d,b|d,b|d,a|z,c|f,a|d,c|z,z|f,
b|z,z|d,c|e,z|e,a|e,c|z,c|d,a|f,b|f,a|e,a|z,b|f,z|d,c|f,z|e,b|z,
c|e,b|z,a|d,z|f,a|z,c|e,b|e,z|z,z|e,a|d,c|f,b|e,b|d,z|e,z|z,c|d,
b|f,a|z,b|z,c|f,z|d,a|f,a|e,b|d,c|z,b|f,z|f,c|z,a|f,z|d,c|d,a|e];
a=1<<13; b=1<<23; c=a|b; d=1<<0; e=1<<7; f=d|e;
SP4 = [c|d,a|f,a|f,z|e,c|e,b|f,b|d,a|d,z|z,c|z,c|z,c|f,z|f,z|z,b|e,b|d,
z|d,a|z,b|z,c|d,z|e,b|z,a|d,a|e,b|f,z|d,a|e,b|e,a|z,c|e,c|f,z|f,
b|e,b|d,c|z,c|f,z|f,z|z,z|z,c|z,a|e,b|e,b|f,z|d,c|d,a|f,a|f,z|e,
c|f,z|f,z|d,a|z,b|d,a|d,c|e,b|f,a|d,a|e,b|z,c|d,z|e,b|z,a|z,c|e];
a=1<<25; b=1<<30; c=a|b; d=1<<8; e=1<<19; f=d|e;
SP5 = [z|d,a|f,a|e,c|d,z|e,z|d,b|z,a|e,b|f,z|e,a|d,b|f,c|d,c|e,z|f,b|z,
a|z,b|e,b|e,z|z,b|d,c|f,c|f,a|d,c|e,b|d,z|z,c|z,a|f,a|z,c|z,z|f,
z|e,c|d,z|d,a|z,b|z,a|e,c|d,b|f,a|d,b|z,c|e,a|f,b|f,z|d,a|z,c|e,
c|f,z|f,c|z,c|f,a|e,z|z,b|e,c|z,z|f,a|d,b|d,z|e,z|z,b|e,a|f,b|d];
a=1<<22; b=1<<29; c=a|b; d=1<<4; e=1<<14; f=d|e;
SP6 = [b|d,c|z,z|e,c|f,c|z,z|d,c|f,a|z,b|e,a|f,a|z,b|d,a|d,b|e,b|z,z|f,
z|z,a|d,b|f,z|e,a|e,b|f,z|d,c|d,c|d,z|z,a|f,c|e,z|f,a|e,c|e,b|z,
b|e,z|d,c|d,a|e,c|f,a|z,z|f,b|d,a|z,b|e,b|z,z|f,b|d,c|f,a|e,c|z,
a|f,c|e,z|z,c|d,z|d,z|e,c|z,a|f,z|e,a|d,b|f,z|z,c|e,b|z,a|d,b|f];
a=1<<21; b=1<<26; c=a|b; d=1<<1; e=1<<11; f=d|e;
SP7 = [a|z,c|d,b|f,z|z,z|e,b|f,a|f,c|e,c|f,a|z,z|z,b|d,z|d,b|z,c|d,z|f,
b|e,a|f,a|d,b|e,b|d,c|z,c|e,a|d,c|z,z|e,z|f,c|f,a|e,z|d,b|z,a|e,
b|z,a|e,a|z,b|f,b|f,c|d,c|d,z|d,a|d,b|z,b|e,a|z,c|e,z|f,a|f,c|e,
z|f,b|d,c|f,c|z,a|e,z|z,z|d,c|f,z|z,a|f,c|z,z|e,b|d,b|e,z|e,a|d];
a=1<<18; b=1<<28; c=a|b; d=1<<6; e=1<<12; f=d|e;
SP8 = [b|f,z|e,a|z,c|f,b|z,b|f,z|d,b|z,a|d,c|z,c|f,a|e,c|e,a|f,z|e,z|d,
c|z,b|d,b|e,z|f,a|e,a|d,c|d,c|e,z|f,z|z,z|z,c|d,b|d,b|e,a|f,a|z,
a|f,a|z,c|e,z|e,z|d,c|d,z|e,a|f,b|e,z|d,b|d,c|z,c|d,b|z,a|z,b|f,
z|z,c|f,a|d,b|d,c|z,b|e,b|f,z|z,c|f,a|e,a|e,z|f,z|f,a|d,b|z,c|e];
// Set the key.
function setKeys(keyBlock) {
var i, j, l, m, n, o, pc1m = [], pcr = [], kn = [],
raw0, raw1, rawi, KnLi;
for (j = 0, l = 56; j < 56; ++j, l-=8) {
l += l<-5 ? 65 : l<-3 ? 31 : l<-1 ? 63 : l===27 ? 35 : 0; // PC1
m = l & 0x7;
pc1m[j] = ((keyBlock[l >>> 3] & (1<<m)) !== 0) ? 1: 0;
}
for (i = 0; i < 16; ++i) {
m = i << 1;
n = m + 1;
kn[m] = kn[n] = 0;
for (o=28; o<59; o+=28) {
for (j = o-28; j < o; ++j) {
l = j + totrot[i];
if (l < o) {
pcr[j] = pc1m[l];
} else {
pcr[j] = pc1m[l - 28];
}
}
}
for (j = 0; j < 24; ++j) {
if (pcr[PC2[j]] !== 0) {
kn[m] |= 1<<(23-j);
}
if (pcr[PC2[j + 24]] !== 0) {
kn[n] |= 1<<(23-j);
}
}
}
// cookey
for (i = 0, rawi = 0, KnLi = 0; i < 16; ++i) {
raw0 = kn[rawi++];
raw1 = kn[rawi++];
keys[KnLi] = (raw0 & 0x00fc0000) << 6;
keys[KnLi] |= (raw0 & 0x00000fc0) << 10;
keys[KnLi] |= (raw1 & 0x00fc0000) >>> 10;
keys[KnLi] |= (raw1 & 0x00000fc0) >>> 6;
++KnLi;
keys[KnLi] = (raw0 & 0x0003f000) << 12;
keys[KnLi] |= (raw0 & 0x0000003f) << 16;
keys[KnLi] |= (raw1 & 0x0003f000) >>> 4;
keys[KnLi] |= (raw1 & 0x0000003f);
++KnLi;
}
}
// Encrypt 8 bytes of text
function enc8(text) {
var i = 0, b = text.slice(), fval, keysi = 0,
l, r, x; // left, right, accumulator
// Squash 8 bytes to 2 ints
l = b[i++]<<24 | b[i++]<<16 | b[i++]<<8 | b[i++];
r = b[i++]<<24 | b[i++]<<16 | b[i++]<<8 | b[i++];
x = ((l >>> 4) ^ r) & 0x0f0f0f0f;
r ^= x;
l ^= (x << 4);
x = ((l >>> 16) ^ r) & 0x0000ffff;
r ^= x;
l ^= (x << 16);
x = ((r >>> 2) ^ l) & 0x33333333;
l ^= x;
r ^= (x << 2);
x = ((r >>> 8) ^ l) & 0x00ff00ff;
l ^= x;
r ^= (x << 8);
r = (r << 1) | ((r >>> 31) & 1);
x = (l ^ r) & 0xaaaaaaaa;
l ^= x;
r ^= x;
l = (l << 1) | ((l >>> 31) & 1);
for (i = 0; i < 8; ++i) {
x = (r << 28) | (r >>> 4);
x ^= keys[keysi++];
fval = SP7[x & 0x3f];
fval |= SP5[(x >>> 8) & 0x3f];
fval |= SP3[(x >>> 16) & 0x3f];
fval |= SP1[(x >>> 24) & 0x3f];
x = r ^ keys[keysi++];
fval |= SP8[x & 0x3f];
fval |= SP6[(x >>> 8) & 0x3f];
fval |= SP4[(x >>> 16) & 0x3f];
fval |= SP2[(x >>> 24) & 0x3f];
l ^= fval;
x = (l << 28) | (l >>> 4);
x ^= keys[keysi++];
fval = SP7[x & 0x3f];
fval |= SP5[(x >>> 8) & 0x3f];
fval |= SP3[(x >>> 16) & 0x3f];
fval |= SP1[(x >>> 24) & 0x3f];
x = l ^ keys[keysi++];
fval |= SP8[x & 0x0000003f];
fval |= SP6[(x >>> 8) & 0x3f];
fval |= SP4[(x >>> 16) & 0x3f];
fval |= SP2[(x >>> 24) & 0x3f];
r ^= fval;
}
r = (r << 31) | (r >>> 1);
x = (l ^ r) & 0xaaaaaaaa;
l ^= x;
r ^= x;
l = (l << 31) | (l >>> 1);
x = ((l >>> 8) ^ r) & 0x00ff00ff;
r ^= x;
l ^= (x << 8);
x = ((l >>> 2) ^ r) & 0x33333333;
r ^= x;
l ^= (x << 2);
x = ((r >>> 16) ^ l) & 0x0000ffff;
l ^= x;
r ^= (x << 16);
x = ((r >>> 4) ^ l) & 0x0f0f0f0f;
l ^= x;
r ^= (x << 4);
// Spread ints to bytes
x = [r, l];
for (i = 0; i < 8; i++) {
b[i] = (x[i>>>2] >>> (8*(3 - (i%4)))) % 256;
if (b[i] < 0) { b[i] += 256; } // unsigned
}
return b;
}
// Encrypt 16 bytes of text using passwd as key
function encrypt(t) {
return enc8(t.slice(0,8)).concat(enc8(t.slice(8,16)));
}
setKeys(passwd); // Setup keys
return {'encrypt': encrypt}; // Public interface
} // function DES

View File

@ -1,568 +0,0 @@
/*
* noVNC: HTML5 VNC client
* Copyright (C) 2011 Joel Martin
* Licensed under LGPL-3 (see LICENSE.txt)
*
* See README.md for usage and integration instructions.
*/
/*jslint browser: true, white: false, bitwise: false */
/*global Util, Base64, changeCursor */
function Display(defaults) {
"use strict";
var that = {}, // Public API methods
conf = {}, // Configuration attributes
// Private Display namespace variables
c_ctx = null,
c_forceCanvas = false,
c_imageData, c_rgbxImage, c_cmapImage,
// Predefine function variables (jslint)
imageDataCreate, imageDataGet, rgbxImageData, cmapImageData,
rgbxImageFill, cmapImageFill, setFillColor, rescale, flush,
c_width = 0,
c_height = 0,
c_prevStyle = "",
c_webkit_bug = false,
c_flush_timer = null;
// Configuration attributes
Util.conf_defaults(conf, that, defaults, [
['target', 'wo', 'dom', null, 'Canvas element for rendering'],
['context', 'ro', 'raw', null, 'Canvas 2D context for rendering (read-only)'],
['logo', 'rw', 'raw', null, 'Logo to display when cleared: {"width": width, "height": height, "data": data}'],
['true_color', 'rw', 'bool', true, 'Use true-color pixel data'],
['colourMap', 'rw', 'arr', [], 'Colour map array (when not true-color)'],
['scale', 'rw', 'float', 1.0, 'Display area scale factor 0.0 - 1.0'],
['width', 'rw', 'int', null, 'Display area width'],
['height', 'rw', 'int', null, 'Display area height'],
['render_mode', 'ro', 'str', '', 'Canvas rendering mode (read-only)'],
['prefer_js', 'rw', 'str', null, 'Prefer Javascript over canvas methods'],
['cursor_uri', 'rw', 'raw', null, 'Can we render cursor using data URI']
]);
// Override some specific getters/setters
that.get_context = function () { return c_ctx; };
that.set_scale = function(scale) { rescale(scale); };
that.set_width = function (val) { that.resize(val, c_height); };
that.get_width = function() { return c_width; };
that.set_height = function (val) { that.resize(c_width, val); };
that.get_height = function() { return c_height; };
that.set_prefer_js = function(val) {
if (val && c_forceCanvas) {
Util.Warn("Preferring Javascript to Canvas ops is not supported");
return false;
}
conf.prefer_js = val;
return true;
};
//
// Private functions
//
// Create the public API interface
function constructor() {
Util.Debug(">> Display.constructor");
var c, func, imgTest, tval, i, curDat, curSave,
has_imageData = false, UE = Util.Engine;
if (! conf.target) { throw("target must be set"); }
if (typeof conf.target === 'string') {
throw("target must be a DOM element");
}
c = conf.target;
if (! c.getContext) { throw("no getContext method"); }
if (! c_ctx) { c_ctx = c.getContext('2d'); }
Util.Debug("User Agent: " + navigator.userAgent);
if (UE.gecko) { Util.Debug("Browser: gecko " + UE.gecko); }
if (UE.webkit) { Util.Debug("Browser: webkit " + UE.webkit); }
if (UE.trident) { Util.Debug("Browser: trident " + UE.trident); }
if (UE.presto) { Util.Debug("Browser: presto " + UE.presto); }
that.clear();
/*
* Determine browser Canvas feature support
* and select fastest rendering methods
*/
tval = 0;
try {
imgTest = c_ctx.getImageData(0, 0, 1,1);
imgTest.data[0] = 123;
imgTest.data[3] = 255;
c_ctx.putImageData(imgTest, 0, 0);
tval = c_ctx.getImageData(0, 0, 1, 1).data[0];
if (tval === 123) {
has_imageData = true;
}
} catch (exc1) {}
if (has_imageData) {
Util.Info("Canvas supports imageData");
c_forceCanvas = false;
if (c_ctx.createImageData) {
// If it's there, it's faster
Util.Info("Using Canvas createImageData");
conf.render_mode = "createImageData rendering";
c_imageData = imageDataCreate;
} else if (c_ctx.getImageData) {
// I think this is mostly just Opera
Util.Info("Using Canvas getImageData");
conf.render_mode = "getImageData rendering";
c_imageData = imageDataGet;
}
Util.Info("Prefering javascript operations");
if (conf.prefer_js === null) {
conf.prefer_js = true;
}
c_rgbxImage = rgbxImageData;
c_cmapImage = cmapImageData;
} else {
Util.Warn("Canvas lacks imageData, using fillRect (slow)");
conf.render_mode = "fillRect rendering (slow)";
c_forceCanvas = true;
conf.prefer_js = false;
c_rgbxImage = rgbxImageFill;
c_cmapImage = cmapImageFill;
}
if (UE.webkit && UE.webkit >= 534.7 && UE.webkit <= 534.9) {
// Workaround WebKit canvas rendering bug #46319
conf.render_mode += ", webkit bug workaround";
Util.Debug("Working around WebKit bug #46319");
c_webkit_bug = true;
for (func in {"fillRect":1, "copyImage":1, "rgbxImage":1,
"cmapImage":1, "blitStringImage":1}) {
that[func] = (function() {
var myfunc = that[func]; // Save original function
//Util.Debug("Wrapping " + func);
return function() {
myfunc.apply(this, arguments);
if (!c_flush_timer) {
c_flush_timer = setTimeout(flush, 100);
}
};
}());
}
}
/*
* Determine browser support for setting the cursor via data URI
* scheme
*/
curDat = [];
for (i=0; i < 8 * 8 * 4; i += 1) {
curDat.push(255);
}
try {
curSave = c.style.cursor;
changeCursor(conf.target, curDat, curDat, 2, 2, 8, 8);
if (c.style.cursor) {
if (conf.cursor_uri === null) {
conf.cursor_uri = true;
}
Util.Info("Data URI scheme cursor supported");
} else {
if (conf.cursor_uri === null) {
conf.cursor_uri = false;
}
Util.Warn("Data URI scheme cursor not supported");
}
c.style.cursor = curSave;
} catch (exc2) {
Util.Error("Data URI scheme cursor test exception: " + exc2);
conf.cursor_uri = false;
}
Util.Debug("<< Display.constructor");
return that ;
}
rescale = function(factor) {
var c, tp, x, y,
properties = ['transform', 'WebkitTransform', 'MozTransform', null];
c = conf.target;
tp = properties.shift();
while (tp) {
if (typeof c.style[tp] !== 'undefined') {
break;
}
tp = properties.shift();
}
if (tp === null) {
Util.Debug("No scaling support");
return;
}
if (factor > 1.0) {
factor = 1.0;
} else if (factor < 0.1) {
factor = 0.1;
}
if (conf.scale === factor) {
//Util.Debug("Display already scaled to '" + factor + "'");
return;
}
conf.scale = factor;
x = c.width - c.width * factor;
y = c.height - c.height * factor;
c.style[tp] = "scale(" + conf.scale + ") translate(-" + x + "px, -" + y + "px)";
};
// Force canvas redraw (for webkit bug #46319 workaround)
flush = function() {
var old_val;
//Util.Debug(">> flush");
old_val = conf.target.style.marginRight;
conf.target.style.marginRight = "1px";
c_flush_timer = null;
setTimeout(function () {
conf.target.style.marginRight = old_val;
}, 1);
};
setFillColor = function(color) {
var rgb, newStyle;
if (conf.true_color) {
rgb = color;
} else {
rgb = conf.colourMap[color[0]];
}
newStyle = "rgb(" + rgb[0] + "," + rgb[1] + "," + rgb[2] + ")";
if (newStyle !== c_prevStyle) {
c_ctx.fillStyle = newStyle;
c_prevStyle = newStyle;
}
};
//
// Public API interface functions
//
that.resize = function(width, height) {
var c = conf.target;
c_prevStyle = "";
c.width = width;
c.height = height;
c_width = c.offsetWidth;
c_height = c.offsetHeight;
rescale(conf.scale);
};
that.clear = function() {
if (conf.logo) {
that.resize(conf.logo.width, conf.logo.height);
that.blitStringImage(conf.logo.data, 0, 0);
} else {
that.resize(640, 20);
c_ctx.clearRect(0, 0, c_width, c_height);
}
// No benefit over default ("source-over") in Chrome and firefox
//c_ctx.globalCompositeOperation = "copy";
};
that.fillRect = function(x, y, width, height, color) {
setFillColor(color);
c_ctx.fillRect(x, y, width, height);
};
that.copyImage = function(old_x, old_y, new_x, new_y, width, height) {
c_ctx.drawImage(conf.target, old_x, old_y, width, height,
new_x, new_y, width, height);
};
/*
* Tile rendering functions optimized for rendering engines.
*
* - In Chrome/webkit, Javascript image data array manipulations are
* faster than direct Canvas fillStyle, fillRect rendering. In
* gecko, Javascript array handling is much slower.
*/
that.getTile = function(x, y, width, height, color) {
var img, data = [], rgb, red, green, blue, i;
img = {'x': x, 'y': y, 'width': width, 'height': height,
'data': data};
if (conf.prefer_js) {
if (conf.true_color) {
rgb = color;
} else {
rgb = conf.colourMap[color[0]];
}
red = rgb[0];
green = rgb[1];
blue = rgb[2];
for (i = 0; i < (width * height * 4); i+=4) {
data[i ] = red;
data[i + 1] = green;
data[i + 2] = blue;
}
} else {
that.fillRect(x, y, width, height, color);
}
return img;
};
that.setSubTile = function(img, x, y, w, h, color) {
var data, p, rgb, red, green, blue, width, j, i, xend, yend;
if (conf.prefer_js) {
data = img.data;
width = img.width;
if (conf.true_color) {
rgb = color;
} else {
rgb = conf.colourMap[color[0]];
}
red = rgb[0];
green = rgb[1];
blue = rgb[2];
xend = x + w;
yend = y + h;
for (j = y; j < yend; j += 1) {
for (i = x; i < xend; i += 1) {
p = (i + (j * width) ) * 4;
data[p ] = red;
data[p + 1] = green;
data[p + 2] = blue;
}
}
} else {
that.fillRect(img.x + x, img.y + y, w, h, color);
}
};
that.putTile = function(img) {
if (conf.prefer_js) {
c_rgbxImage(img.x, img.y, img.width, img.height, img.data, 0);
}
// else: No-op, under gecko already done by setSubTile
};
imageDataGet = function(width, height) {
return c_ctx.getImageData(0, 0, width, height);
};
imageDataCreate = function(width, height) {
return c_ctx.createImageData(width, height);
};
rgbxImageData = function(x, y, width, height, arr, offset) {
var img, i, j, data;
img = c_imageData(width, height);
data = img.data;
for (i=0, j=offset; i < (width * height * 4); i=i+4, j=j+4) {
data[i ] = arr[j ];
data[i + 1] = arr[j + 1];
data[i + 2] = arr[j + 2];
data[i + 3] = 255; // Set Alpha
}
c_ctx.putImageData(img, x, y);
};
// really slow fallback if we don't have imageData
rgbxImageFill = function(x, y, width, height, arr, offset) {
var i, j, sx = 0, sy = 0;
for (i=0, j=offset; i < (width * height); i+=1, j+=4) {
that.fillRect(x+sx, y+sy, 1, 1, [arr[j], arr[j+1], arr[j+2]]);
sx += 1;
if ((sx % width) === 0) {
sx = 0;
sy += 1;
}
}
};
cmapImageData = function(x, y, width, height, arr, offset) {
var img, i, j, data, rgb, cmap;
img = c_imageData(width, height);
data = img.data;
cmap = conf.colourMap;
for (i=0, j=offset; i < (width * height * 4); i+=4, j+=1) {
rgb = cmap[arr[j]];
data[i ] = rgb[0];
data[i + 1] = rgb[1];
data[i + 2] = rgb[2];
data[i + 3] = 255; // Set Alpha
}
c_ctx.putImageData(img, x, y);
};
cmapImageFill = function(x, y, width, height, arr, offset) {
var i, j, sx = 0, sy = 0, cmap;
cmap = conf.colourMap;
for (i=0, j=offset; i < (width * height); i+=1, j+=1) {
that.fillRect(x+sx, y+sy, 1, 1, [arr[j]]);
sx += 1;
if ((sx % width) === 0) {
sx = 0;
sy += 1;
}
}
};
that.blitImage = function(x, y, width, height, arr, offset) {
if (conf.true_color) {
c_rgbxImage(x, y, width, height, arr, offset);
} else {
c_cmapImage(x, y, width, height, arr, offset);
}
};
that.blitStringImage = function(str, x, y) {
var img = new Image();
img.onload = function () { c_ctx.drawImage(img, x, y); };
img.src = str;
};
that.changeCursor = function(pixels, mask, hotx, hoty, w, h) {
if (conf.cursor_uri === false) {
Util.Warn("changeCursor called but no cursor data URI support");
return;
}
if (conf.true_color) {
changeCursor(conf.target, pixels, mask, hotx, hoty, w, h);
} else {
changeCursor(conf.target, pixels, mask, hotx, hoty, w, h, conf.colourMap);
}
};
that.defaultCursor = function() {
conf.target.style.cursor = "default";
};
return constructor(); // Return the public API interface
} // End of Display()
/* Set CSS cursor property using data URI encoded cursor file */
function changeCursor(target, pixels, mask, hotx, hoty, w, h, cmap) {
"use strict";
var cur = [], rgb, IHDRsz, RGBsz, ANDsz, XORsz, url, idx, alpha, x, y;
//Util.Debug(">> changeCursor, x: " + hotx + ", y: " + hoty + ", w: " + w + ", h: " + h);
// Push multi-byte little-endian values
cur.push16le = function (num) {
this.push((num ) & 0xFF,
(num >> 8) & 0xFF );
};
cur.push32le = function (num) {
this.push((num ) & 0xFF,
(num >> 8) & 0xFF,
(num >> 16) & 0xFF,
(num >> 24) & 0xFF );
};
IHDRsz = 40;
RGBsz = w * h * 4;
XORsz = Math.ceil( (w * h) / 8.0 );
ANDsz = Math.ceil( (w * h) / 8.0 );
// Main header
cur.push16le(0); // 0: Reserved
cur.push16le(2); // 2: .CUR type
cur.push16le(1); // 4: Number of images, 1 for non-animated ico
// Cursor #1 header (ICONDIRENTRY)
cur.push(w); // 6: width
cur.push(h); // 7: height
cur.push(0); // 8: colors, 0 -> true-color
cur.push(0); // 9: reserved
cur.push16le(hotx); // 10: hotspot x coordinate
cur.push16le(hoty); // 12: hotspot y coordinate
cur.push32le(IHDRsz + RGBsz + XORsz + ANDsz);
// 14: cursor data byte size
cur.push32le(22); // 18: offset of cursor data in the file
// Cursor #1 InfoHeader (ICONIMAGE/BITMAPINFO)
cur.push32le(IHDRsz); // 22: Infoheader size
cur.push32le(w); // 26: Cursor width
cur.push32le(h*2); // 30: XOR+AND height
cur.push16le(1); // 34: number of planes
cur.push16le(32); // 36: bits per pixel
cur.push32le(0); // 38: Type of compression
cur.push32le(XORsz + ANDsz); // 43: Size of Image
// Gimp leaves this as 0
cur.push32le(0); // 46: reserved
cur.push32le(0); // 50: reserved
cur.push32le(0); // 54: reserved
cur.push32le(0); // 58: reserved
// 62: color data (RGBQUAD icColors[])
for (y = h-1; y >= 0; y -= 1) {
for (x = 0; x < w; x += 1) {
idx = y * Math.ceil(w / 8) + Math.floor(x/8);
alpha = (mask[idx] << (x % 8)) & 0x80 ? 255 : 0;
if (cmap) {
idx = (w * y) + x;
rgb = cmap[pixels[idx]];
cur.push(rgb[2]); // blue
cur.push(rgb[1]); // green
cur.push(rgb[0]); // red
cur.push(alpha); // alpha
} else {
idx = ((w * y) + x) * 4;
cur.push(pixels[idx + 2]); // blue
cur.push(pixels[idx + 1]); // green
cur.push(pixels[idx ]); // red
cur.push(alpha); // alpha
}
}
}
// XOR/bitmask data (BYTE icXOR[])
// (ignored, just needs to be right size)
for (y = 0; y < h; y += 1) {
for (x = 0; x < Math.ceil(w / 8); x += 1) {
cur.push(0x00);
}
}
// AND/bitmask data (BYTE icAND[])
// (ignored, just needs to be right size)
for (y = 0; y < h; y += 1) {
for (x = 0; x < Math.ceil(w / 8); x += 1) {
cur.push(0x00);
}
}
url = "data:image/x-icon;base64," + Base64.encode(cur);
target.style.cursor = "url(" + url + ") " + hotx + " " + hoty + ", default";
//Util.Debug("<< changeCursor, cur.length: " + cur.length);
}

View File

@ -1,21 +0,0 @@
<!-- index.vnc - default html page for Java VNC viewer applet. On any file
ending in .vnc, the HTTP server embedded in Xvnc will substitute the
following variables when preceded by a dollar: USER, DESKTOP, DISPLAY,
APPLETWIDTH, APPLETHEIGHT, WIDTH, HEIGHT, PORT, PARAMS. Use two dollar
signs ($$) to get a dollar sign in the generated html. -->
<HTML>
<TITLE>
$USER's $DESKTOP desktop ($DISPLAY)
</TITLE>
<APPLET CODE=VncViewer.class ARCHIVE=VncViewer.jar
WIDTH=$APPLETWIDTH HEIGHT=$APPLETHEIGHT>
<param name=PORT value=$PORT>
<param name="Open New Window" value=yes>
</APPLET>
<BR>
Further help: <BR>
<A href="./novnc.html">noVNC version (better)</A><BR>
<A href="http://onaips.blogspot.com/">oNaiPs Blog</A><BR>
<A href="http://www.tightvnc.com/">www.TightVNC.com</A>
</HTML>

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

File diff suppressed because one or more lines are too long

View File

@ -1,34 +0,0 @@
<!DOCTYPE html>
<html>
<!--
noVNC example: simple example using default UI
Copyright (C) 2011 Joel Martin
Licensed under LGPL-3 (see LICENSE.txt)
-->
<head>
<title>droid VNC server</title>
<meta http-equiv="X-UA-Compatible" content="chrome=1">
<link rel="stylesheet" href="plain.css">
<link rel="alternate stylesheet" href="black.css" TITLE="Black">
<!--
<script type='text/javascript'
src='http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js'></script>
-->
<script src="vnc.js"></script>
<script src="ui.js.vnc"></script>
</head>
<body>
<div id='vnc'>Loading</div>
<script>
window.onload = function () {
UI.load('vnc');
};
</script>
<A id="java" href="./index.vnc">Java version (older)</A></br>
<A id="troubleshooting" href="https://github.com/kanaka/noVNC/wiki/Browser-support">Not working? Click here</A>
</body>
</html>

View File

@ -1,104 +0,0 @@
#VNC_controls {
overflow: hidden;
}
#VNC_controls ul {
list-style: none;
margin: 0px;
padding: 0px;
}
#VNC_controls li {
float: left;
margin-right: 15px;
}
#VNC_host {
width: 100px;
}
#VNC_port {
width: 50px;
}
#VNC_password {
width: 80px;
}
#VNC_encrypt {
}
#VNC_connectTimeout {
width: 30px;
}
#VNC_connect_button {
width: 110px;
}
#VNC_status_bar td {
margin-top: 15px;
padding: 0px;
margin: 0px;
}
#VNC_status_bar div {
font-size: 12px;
margin: 0px;
padding: 0px;
}
.VNC_status_button {
font-size: 10px;
margin: 0px;
padding: 0px;
}
#VNC_status {
text-align: center;
}
#java{
text-align: center;
}
#VNC_settings_menu {
display: none;
position: absolute;
width: 12em;
border: 1px solid #888;
background-color: #f0f2f6;
padding: 5px; margin: 3px;
z-index: 100; opacity: 1;
text-align: left; white-space: normal;
}
#VNC_settings_menu ul {
list-style: none;
margin: 0px;
padding: 0px;
}
.VNC_buttons_right {
text-align: right;
}
.VNC_buttons_left {
text-align: left;
}
.VNC_status_normal {
background: #eee;
}
.VNC_status_error {
background: #f44;
}
.VNC_status_warn {
background: #ff4;
}
/* Do not set width/height for VNC_screen or VNC_canvas or incorrect
* scaling will occur. Canvas resizes to remote VNC settings */
#VNC_screen {
text-align: center;
display: table;
}
#VNC_canvas {
background: #eee;
}
#VNC_clipboard_clear_button {
}
#VNC_clipboard_text {
font-size: 9px;
}

View File

@ -1,90 +0,0 @@
/*
* noVNC: HTML5 VNC client
* Copyright (C) 2011 Joel Martin
* Licensed under LGPL-3 (see LICENSE.LGPL-3)
*/
"use strict";
/*jslint browser: true, white: false */
/*global Util, VNC_frame_data, finish */
var rfb, mode, test_state, frame_idx, frame_length,
iteration, iterations, istart_time,
// Pre-declarations for jslint
send_array, next_iteration, queue_next_packet, do_packet;
// Override send_array
send_array = function (arr) {
// Stub out send_array
};
next_iteration = function () {
if (iteration === 0) {
frame_length = VNC_frame_data.length;
test_state = 'running';
} else {
rfb.disconnect();
}
if (test_state !== 'running') { return; }
iteration += 1;
if (iteration > iterations) {
finish();
return;
}
frame_idx = 0;
istart_time = (new Date()).getTime();
rfb.connect('test', 0, "bogus");
queue_next_packet();
};
queue_next_packet = function () {
var frame, foffset, toffset, delay;
if (test_state !== 'running') { return; }
frame = VNC_frame_data[frame_idx];
while ((frame_idx < frame_length) && (frame.charAt(0) === "}")) {
//Util.Debug("Send frame " + frame_idx);
frame_idx += 1;
frame = VNC_frame_data[frame_idx];
}
if (frame === 'EOF') {
Util.Debug("Finished, found EOF");
next_iteration();
return;
}
if (frame_idx >= frame_length) {
Util.Debug("Finished, no more frames");
next_iteration();
return;
}
if (mode === 'realtime') {
foffset = frame.slice(1, frame.indexOf('{', 1));
toffset = (new Date()).getTime() - istart_time;
delay = foffset - toffset;
if (delay < 1) {
delay = 1;
}
setTimeout(do_packet, delay);
} else {
setTimeout(do_packet, 1);
}
};
do_packet = function () {
//Util.Debug("Processing frame: " + frame_idx);
var frame = VNC_frame_data[frame_idx];
rfb.recv_message({'data' : frame.slice(frame.indexOf('{', 1) + 1)});
frame_idx += 1;
queue_next_packet();
};

File diff suppressed because it is too large Load Diff

File diff suppressed because one or more lines are too long

View File

@ -1,422 +0,0 @@
/*
* noVNC: HTML5 VNC client
* Copyright (C) 2011 Joel Martin
* Licensed under LGPL-3 (see LICENSE.txt)
*
* See README.md for usage and integration instructions.
*/
"use strict";
/*jslint white: false, browser: true */
/*global window, $D, Util, WebUtil, RFB, Display */
var UI = {
settingsOpen : false,
// Render default UI and initialize settings menu
load: function(target) {
var html = '', i, sheet, sheets, llevels;
/* Populate the 'target' DOM element with default UI */
if (!target) {
target = $D('vnc');
} else if (typeof target === 'string') {
target = $D(target);
}
if ((!document.createElement('canvas').getContext) &&
window.ActiveXObject) {
// Suggest Chrome frame for Internet Explorer users
html += '<center><div style="text-align: left; width: 400px">';
html += ' You are using a version of Internet Explorer ';
html += ' that does not have HTML5 Canvas support. ';
html += ' To use noVNC you must use a browser with HTML5 ';
html += ' Canvas support or install ';
html += ' <a href="http://google.com/chromeframe" target="cframe">';
html += ' Google Chrome Frame.</a>';
html += '</div></center>';
target.innerHTML = html;
return;
}
html += '<div id="VNC_controls">';
html += ' <ul>';
html += ' <li>Host: <input id="VNC_host"></li>';
html += ' <li>Port: <input id="VNC_port"></li>';
html += ' <li>Password: <input id="VNC_password"';
html += ' type="password"></li>';
html += ' <li><input id="VNC_connect_button" type="button"';
html += ' value="Loading" disabled></li>';
html += ' </ul>';
html += '</div>';
html += '<div id="VNC_screen">';
html += ' <div id="VNC_status_bar" class="VNC_status_bar" style="margin-top: 0px;">';
html += ' <table border=0 width=100%><tr>';
html += ' <td><div id="VNC_status">Loading</div></td>';
html += ' <td width=1%><div class="VNC_buttons_right">';
html += ' <input type=button class="VNC_status_button" value="Settings"';
html += ' id="menuButton"';
html += ' onclick="UI.clickSettingsMenu();">';
html += ' <span id="VNC_settings_menu"';
html += ' onmouseover="UI.displayBlur();"';
html += ' onmouseout="UI.displayFocus();">';
html += ' <ul>';
html += ' <li><input id="VNC_encrypt"';
html += ' type="checkbox"> Encrypt</li>';
html += ' <li><input id="VNC_true_color"';
html += ' type="checkbox" checked> True Color</li>';
html += ' <li><input id="VNC_cursor"';
html += ' type="checkbox"> Local Cursor</li>';
html += ' <li><input id="VNC_shared"';
html += ' type="checkbox"> Shared Mode</li>';
html += ' <li><input id="VNC_connectTimeout"';
html += ' type="input"> Connect Timeout (s)</li>';
html += ' <hr>';
// Stylesheet selection dropdown
html += ' <li><select id="VNC_stylesheet" name="vncStyle">';
html += ' <option value="default">default</option>';
sheet = WebUtil.selectStylesheet();
sheets = WebUtil.getStylesheets();
for (i = 0; i < sheets.length; i += 1) {
html += '<option value="' + sheets[i].title + '">' + sheets[i].title + '</option>';
}
html += ' </select> Style</li>';
// Logging selection dropdown
html += ' <li><select id="VNC_logging" name="vncLogging">';
llevels = ['error', 'warn', 'info', 'debug'];
for (i = 0; i < llevels.length; i += 1) {
html += '<option value="' + llevels[i] + '">' + llevels[i] + '</option>';
}
html += ' </select> Logging</li>';
html += ' <hr>';
html += ' <li><input type="button" id="VNC_apply" value="Apply"';
html += ' onclick="UI.settingsApply()"></li>';
html += ' </ul>';
html += ' </span></div></td>';
html += ' </tr></table>';
html += ' </div>';
html += ' <canvas id="VNC_canvas" width="640px" height="20px">';
html += ' Canvas not supported.';
html += ' </canvas>';
html += '</div>';
html += '<br><br>';
html += '<div id="VNC_clipboard">';
html += ' VNC Clipboard:';
html += ' <input id="VNC_clipboard_clear_button"';
html += ' type="button" value="Clear"';
html += ' onclick="UI.clipClear();">';
html += ' <br>';
html += ' <textarea id="VNC_clipboard_text" cols=80 rows=5';
html += ' onfocus="UI.displayBlur();"';
html += ' onblur="UI.displayFocus();"';
html += ' onchange="UI.clipSend();"></textarea>';
html += '</div>';
target.innerHTML = html;
// Settings with immediate effects
UI.initSetting('logging', 'warn');
WebUtil.init_logging(UI.getSetting('logging'));
UI.initSetting('stylesheet', 'Black');
WebUtil.selectStylesheet(null); // call twice to get around webkit bug
WebUtil.selectStylesheet(UI.getSetting('stylesheet'));
/* Populate the controls if defaults are provided in the URL */
UI.initSetting('host', 'localhost');
UI.initSetting('port', '5901');
UI.initSetting('password', '');
UI.initSetting('encrypt', false);
UI.initSetting('true_color', false);
UI.initSetting('cursor', false);
UI.initSetting('shared', true);
UI.initSetting('connectTimeout', 2);
UI.rfb = RFB({'target': $D('VNC_canvas'),
'onUpdateState': UI.updateState,
'onClipboard': UI.clipReceive});
// Unfocus clipboard when over the VNC area
$D('VNC_screen').onmousemove = function () {
var keyboard = UI.rfb.get_keyboard();
if ((! keyboard) || (! keyboard.get_focused())) {
$D('VNC_clipboard_text').blur();
}
};
var portsize=window.location.port.length+1;
if (portsize<0)
portsize=0;
document.getElementById('VNC_host').value=window.location.host.substring(0,window.location.host.length-portsize);
document.getElementById('VNC_port').value='$PORT';
},
// Read form control compatible setting from cookie
getSetting: function(name) {
var val, ctrl = $D('VNC_' + name);
val = WebUtil.readCookie(name);
if (ctrl.type === 'checkbox') {
if (val.toLowerCase() in {'0':1, 'no':1, 'false':1}) {
val = false;
} else {
val = true;
}
}
return val;
},
// Update cookie and form control setting. If value is not set, then
// updates from control to current cookie setting.
updateSetting: function(name, value) {
var i, ctrl = $D('VNC_' + name);
// Save the cookie for this session
if (typeof value !== 'undefined') {
WebUtil.createCookie(name, value);
}
// Update the settings control
value = UI.getSetting(name);
if (ctrl.type === 'checkbox') {
ctrl.checked = value;
} else if (typeof ctrl.options !== 'undefined') {
for (i = 0; i < ctrl.options.length; i += 1) {
if (ctrl.options[i].value === value) {
ctrl.selectedIndex = i;
break;
}
}
} else {
ctrl.value = value;
}
},
// Save control setting to cookie
saveSetting: function(name) {
var val, ctrl = $D('VNC_' + name);
if (ctrl.type === 'checkbox') {
val = ctrl.checked;
} else if (typeof ctrl.options !== 'undefined') {
val = ctrl.options[ctrl.selectedIndex].value;
} else {
val = ctrl.value;
}
WebUtil.createCookie(name, val);
//Util.Debug("Setting saved '" + name + "=" + val + "'");
return val;
},
// Initial page load read/initialization of settings
initSetting: function(name, defVal) {
var val;
// Check Query string followed by cookie
val = WebUtil.getQueryVar(name);
if (val === null) {
val = WebUtil.readCookie(name, defVal);
}
UI.updateSetting(name, val);
//Util.Debug("Setting '" + name + "' initialized to '" + val + "'");
return val;
},
// Toggle the settings menu:
// On open, settings are refreshed from saved cookies.
// On close, settings are applied
clickSettingsMenu: function() {
if (UI.settingsOpen) {
UI.settingsApply();
UI.closeSettingsMenu();
} else {
UI.updateSetting('encrypt');
UI.updateSetting('true_color');
if (UI.rfb.get_display().get_cursor_uri()) {
UI.updateSetting('cursor');
} else {
UI.updateSetting('cursor', false);
$D('VNC_cursor').disabled = true;
}
UI.updateSetting('shared');
UI.updateSetting('connectTimeout');
UI.updateSetting('stylesheet');
UI.updateSetting('logging');
UI.openSettingsMenu();
}
},
// Open menu
openSettingsMenu: function() {
$D('VNC_settings_menu').style.display = "block";
UI.settingsOpen = true;
},
// Close menu (without applying settings)
closeSettingsMenu: function() {
$D('VNC_settings_menu').style.display = "none";
UI.settingsOpen = false;
},
// Disable/enable controls depending on connection state
settingsDisabled: function(disabled, rfb) {
//Util.Debug(">> settingsDisabled");
$D('VNC_encrypt').disabled = disabled;
$D('VNC_true_color').disabled = disabled;
if (rfb && rfb.get_display() && rfb.get_display().get_cursor_uri()) {
$D('VNC_cursor').disabled = disabled;
} else {
UI.updateSetting('cursor', false);
$D('VNC_cursor').disabled = true;
}
$D('VNC_shared').disabled = disabled;
$D('VNC_connectTimeout').disabled = disabled;
//Util.Debug("<< settingsDisabled");
},
// Save/apply settings when 'Apply' button is pressed
settingsApply: function() {
//Util.Debug(">> settingsApply");
UI.saveSetting('encrypt');
UI.saveSetting('true_color');
if (UI.rfb.get_display().get_cursor_uri()) {
UI.saveSetting('cursor');
}
UI.saveSetting('shared');
UI.saveSetting('connectTimeout');
UI.saveSetting('stylesheet');
UI.saveSetting('logging');
// Settings with immediate (non-connected related) effect
WebUtil.selectStylesheet(UI.getSetting('stylesheet'));
WebUtil.init_logging(UI.getSetting('logging'));
//Util.Debug("<< settingsApply");
},
setPassword: function() {
UI.rfb.sendPassword($D('VNC_password').value);
return false;
},
sendCtrlAltDel: function() {
UI.rfb.sendCtrlAltDel();
},
updateState: function(rfb, state, oldstate, msg) {
var s, sb, c, klass;
s = $D('VNC_status');
sb = $D('VNC_status_bar');
c = $D('VNC_connect_button');
switch (state) {
case 'failed':
case 'fatal':
c.disabled = true;
UI.settingsDisabled(true, rfb);
klass = "VNC_status_error";
break;
case 'normal':
c.value = "Disconnect";
c.onclick = UI.disconnect;
c.disabled = false;
UI.settingsDisabled(true, rfb);
klass = "VNC_status_normal";
break;
case 'disconnected':
case 'loaded':
c.value = "Connect";
c.onclick = UI.connect;
c.disabled = false;
UI.settingsDisabled(false, rfb);
klass = "VNC_status_normal";
break;
case 'password':
c.value = "Send Password";
c.onclick = UI.setPassword;
c.disabled = false;
UI.settingsDisabled(true, rfb);
klass = "VNC_status_warn";
break;
default:
c.disabled = true;
UI.settingsDisabled(true, rfb);
klass = "VNC_status_warn";
break;
}
if (typeof(msg) !== 'undefined') {
s.setAttribute("class", klass);
sb.setAttribute("class", klass);
s.innerHTML = msg;
}
},
clipReceive: function(rfb, text) {
Util.Debug(">> UI.clipReceive: " + text.substr(0,40) + "...");
$D('VNC_clipboard_text').value = text;
Util.Debug("<< UI.clipReceive");
},
connect: function() {
var host, port, password;
UI.closeSettingsMenu();
host = $D('VNC_host').value;
port = $D('VNC_port').value;
password = $D('VNC_password').value;
if ((!host) || (!port)) {
throw("Must set host and port");
}
UI.rfb.set_encrypt(UI.getSetting('encrypt'));
UI.rfb.set_true_color(UI.getSetting('true_color'));
UI.rfb.set_local_cursor(UI.getSetting('cursor'));
UI.rfb.set_shared(UI.getSetting('shared'));
UI.rfb.set_connectTimeout(UI.getSetting('connectTimeout'));
UI.rfb.connect(host, port, password);
},
disconnect: function() {
UI.closeSettingsMenu();
UI.rfb.disconnect();
},
displayBlur: function() {
UI.rfb.get_keyboard().set_focused(false);
UI.rfb.get_mouse().set_focused(false);
},
displayFocus: function() {
UI.rfb.get_keyboard().set_focused(true);
UI.rfb.get_mouse().set_focused(true);
},
clipClear: function() {
$D('VNC_clipboard_text').value = "";
UI.rfb.clipboardPasteFrom("");
},
clipSend: function() {
var text = $D('VNC_clipboard_text').value;
Util.Debug(">> UI.clipSend: " + text.substr(0,40) + "...");
UI.rfb.clipboardPasteFrom(text);
Util.Debug("<< UI.clipSend");
}
};

View File

@ -1,275 +0,0 @@
/*
* noVNC: HTML5 VNC client
* Copyright (C) 2011 Joel Martin
* Licensed under LGPL-3 (see LICENSE.txt)
*
* See README.md for usage and integration instructions.
*/
"use strict";
/*jslint bitwise: false, white: false */
/*global window, console, document, navigator, ActiveXObject */
// Globals defined here
var Util = {};
/*
* Make arrays quack
*/
Array.prototype.push8 = function (num) {
this.push(num & 0xFF);
};
Array.prototype.push16 = function (num) {
this.push((num >> 8) & 0xFF,
(num ) & 0xFF );
};
Array.prototype.push32 = function (num) {
this.push((num >> 24) & 0xFF,
(num >> 16) & 0xFF,
(num >> 8) & 0xFF,
(num ) & 0xFF );
};
/*
* ------------------------------------------------------
* Namespaced in Util
* ------------------------------------------------------
*/
/*
* Logging/debug routines
*/
Util._log_level = 'warn';
Util.init_logging = function (level) {
if (typeof level === 'undefined') {
level = Util._log_level;
} else {
Util._log_level = level;
}
if (typeof window.console === "undefined") {
if (typeof window.opera !== "undefined") {
window.console = {
'log' : window.opera.postError,
'warn' : window.opera.postError,
'error': window.opera.postError };
} else {
window.console = {
'log' : function(m) {},
'warn' : function(m) {},
'error': function(m) {}};
}
}
Util.Debug = Util.Info = Util.Warn = Util.Error = function (msg) {};
switch (level) {
case 'debug': Util.Debug = function (msg) { console.log(msg); };
case 'info': Util.Info = function (msg) { console.log(msg); };
case 'warn': Util.Warn = function (msg) { console.warn(msg); };
case 'error': Util.Error = function (msg) { console.error(msg); };
case 'none':
break;
default:
throw("invalid logging type '" + level + "'");
}
};
Util.get_logging = function () {
return Util._log_level;
};
// Initialize logging level
Util.init_logging();
// Set configuration default for Crockford style function namespaces
Util.conf_default = function(cfg, api, defaults, v, mode, type, defval, desc) {
var getter, setter;
// Default getter function
getter = function (idx) {
if ((type in {'arr':1, 'array':1}) &&
(typeof idx !== 'undefined')) {
return cfg[v][idx];
} else {
return cfg[v];
}
};
// Default setter function
setter = function (val, idx) {
if (type in {'boolean':1, 'bool':1}) {
if ((!val) || (val in {'0':1, 'no':1, 'false':1})) {
val = false;
} else {
val = true;
}
} else if (type in {'integer':1, 'int':1}) {
val = parseInt(val, 10);
} else if (type === 'func') {
if (!val) {
val = function () {};
}
}
if (typeof idx !== 'undefined') {
cfg[v][idx] = val;
} else {
cfg[v] = val;
}
};
// Set the description
api[v + '_description'] = desc;
// Set the getter function
if (typeof api['get_' + v] === 'undefined') {
api['get_' + v] = getter;
}
// Set the setter function with extra sanity checks
if (typeof api['set_' + v] === 'undefined') {
api['set_' + v] = function (val, idx) {
if (mode in {'RO':1, 'ro':1}) {
throw(v + " is read-only");
} else if ((mode in {'WO':1, 'wo':1}) &&
(typeof cfg[v] !== 'undefined')) {
throw(v + " can only be set once");
}
setter(val, idx);
};
}
// Set the default value
if (typeof defaults[v] !== 'undefined') {
defval = defaults[v];
} else if ((type in {'arr':1, 'array':1}) &&
(! (defval instanceof Array))) {
defval = [];
}
// Coerce existing setting to the right type
//Util.Debug("v: " + v + ", defval: " + defval + ", defaults[v]: " + defaults[v]);
setter(defval);
};
// Set group of configuration defaults
Util.conf_defaults = function(cfg, api, defaults, arr) {
var i;
for (i = 0; i < arr.length; i++) {
Util.conf_default(cfg, api, defaults, arr[i][0], arr[i][1],
arr[i][2], arr[i][3], arr[i][4]);
}
}
/*
* Cross-browser routines
*/
// Get DOM element position on page
Util.getPosition = function (obj) {
var x = 0, y = 0;
if (obj.offsetParent) {
do {
x += obj.offsetLeft;
y += obj.offsetTop;
obj = obj.offsetParent;
} while (obj);
}
return {'x': x, 'y': y};
};
// Get mouse event position in DOM element
Util.getEventPosition = function (e, obj, scale) {
var evt, docX, docY, pos;
//if (!e) evt = window.event;
evt = (e ? e : window.event);
if (evt.pageX || evt.pageY) {
docX = evt.pageX;
docY = evt.pageY;
} else if (evt.clientX || evt.clientY) {
docX = evt.clientX + document.body.scrollLeft +
document.documentElement.scrollLeft;
docY = evt.clientY + document.body.scrollTop +
document.documentElement.scrollTop;
}
pos = Util.getPosition(obj);
if (typeof scale === "undefined") {
scale = 1;
}
return {'x': (docX - pos.x) / scale, 'y': (docY - pos.y) / scale};
};
// Event registration. Based on: http://www.scottandrew.com/weblog/articles/cbs-events
Util.addEvent = function (obj, evType, fn){
if (obj.attachEvent){
var r = obj.attachEvent("on"+evType, fn);
return r;
} else if (obj.addEventListener){
obj.addEventListener(evType, fn, false);
return true;
} else {
throw("Handler could not be attached");
}
};
Util.removeEvent = function(obj, evType, fn){
if (obj.detachEvent){
var r = obj.detachEvent("on"+evType, fn);
return r;
} else if (obj.removeEventListener){
obj.removeEventListener(evType, fn, false);
return true;
} else {
throw("Handler could not be removed");
}
};
Util.stopEvent = function(e) {
if (e.stopPropagation) { e.stopPropagation(); }
else { e.cancelBubble = true; }
if (e.preventDefault) { e.preventDefault(); }
else { e.returnValue = false; }
};
// Set browser engine versions. Based on mootools.
Util.Features = {xpath: !!(document.evaluate), air: !!(window.runtime), query: !!(document.querySelector)};
Util.Engine = {
'presto': (function() {
return (!window.opera) ? false : ((arguments.callee.caller) ? 960 : ((document.getElementsByClassName) ? 950 : 925)); }()),
'trident': (function() {
return (!window.ActiveXObject) ? false : ((window.XMLHttpRequest) ? ((document.querySelectorAll) ? 6 : 5) : 4); }()),
'webkit': (function() {
try { return (navigator.taintEnabled) ? false : ((Util.Features.xpath) ? ((Util.Features.query) ? 525 : 420) : 419); } catch (e) { return false; } }()),
//'webkit': (function() {
// return ((typeof navigator.taintEnabled !== "unknown") && navigator.taintEnabled) ? false : ((Util.Features.xpath) ? ((Util.Features.query) ? 525 : 420) : 419); }()),
'gecko': (function() {
return (!document.getBoxObjectFor && window.mozInnerScreenX == null) ? false : ((document.getElementsByClassName) ? 19 : 18); }())
};
if (Util.Engine.webkit) {
// Extract actual webkit version if available
Util.Engine.webkit = (function(v) {
var re = new RegExp('WebKit/([0-9\.]*) ');
v = (navigator.userAgent.match(re) || ['', v])[1];
return parseFloat(v, 10);
})(Util.Engine.webkit);
}
Util.Flash = (function(){
var v, version;
try {
v = navigator.plugins['Shockwave Flash'].description;
} catch(err1) {
try {
v = new ActiveXObject('ShockwaveFlash.ShockwaveFlash').GetVariable('$version');
} catch(err2) {
v = '0 r0';
}
}
version = v.match(/\d+/g);
return {version: parseInt(version[0] || 0 + '.' + version[1], 10) || 0, build: parseInt(version[2], 10) || 0};
}());

View File

@ -1,43 +0,0 @@
/*
* noVNC: HTML5 VNC client
* Copyright (C) 2011 Joel Martin
* Licensed under LGPL-3 (see LICENSE.txt)
*
* See README.md for usage and integration instructions.
*/
/*jslint evil: true */
/*global window, document, INCLUDE_URI */
/*
* Load supporting scripts
*/
function get_INCLUDE_URI() {
return (typeof INCLUDE_URI !== "undefined") ? INCLUDE_URI : "";
}
(function () {
"use strict";
var extra = "", start, end;
start = "<script src='" + get_INCLUDE_URI();
end = "'><\/script>";
// Uncomment to activate firebug lite
//extra += "<script src='http://getfirebug.com/releases/lite/1.2/" +
// "firebug-lite-compressed.js'><\/script>";
extra += start + "util.js" + end;
extra += start + "webutil.js" + end;
extra += start + "logo.js" + end;
extra += start + "base64.js" + end;
extra += start + "websock.js" + end;
extra += start + "des.js" + end;
extra += start + "input.js" + end;
extra += start + "display.js" + end;
extra += start + "rfb.js" + end;
document.write(extra);
}());

Binary file not shown.

View File

@ -1,341 +0,0 @@
// Copyright: Hiroshi Ichikawa <http://gimite.net/en/>
// License: New BSD License
// Reference: http://dev.w3.org/html5/websockets/
// Reference: http://tools.ietf.org/html/draft-hixie-thewebsocketprotocol
(function() {
if (window.WebSocket) return;
var console = window.console;
if (!console || !console.log || !console.error) {
console = {log: function(){ }, error: function(){ }};
}
if (!swfobject.hasFlashPlayerVersion("10.0.0")) {
console.error("Flash Player >= 10.0.0 is required.");
return;
}
if (location.protocol == "file:") {
console.error(
"WARNING: web-socket-js doesn't work in file:///... URL " +
"unless you set Flash Security Settings properly. " +
"Open the page via Web server i.e. http://...");
}
/**
* This class represents a faux web socket.
* @param {string} url
* @param {string} protocol
* @param {string} proxyHost
* @param {int} proxyPort
* @param {string} headers
*/
WebSocket = function(url, protocol, proxyHost, proxyPort, headers) {
var self = this;
self.__id = WebSocket.__nextId++;
WebSocket.__instances[self.__id] = self;
self.readyState = WebSocket.CONNECTING;
self.bufferedAmount = 0;
self.__events = {};
// Uses setTimeout() to make sure __createFlash() runs after the caller sets ws.onopen etc.
// Otherwise, when onopen fires immediately, onopen is called before it is set.
setTimeout(function() {
WebSocket.__addTask(function() {
WebSocket.__flash.create(
self.__id, url, protocol, proxyHost || null, proxyPort || 0, headers || null);
});
}, 0);
};
/**
* Send data to the web socket.
* @param {string} data The data to send to the socket.
* @return {boolean} True for success, false for failure.
*/
WebSocket.prototype.send = function(data) {
if (this.readyState == WebSocket.CONNECTING) {
throw "INVALID_STATE_ERR: Web Socket connection has not been established";
}
// We use encodeURIComponent() here, because FABridge doesn't work if
// the argument includes some characters. We don't use escape() here
// because of this:
// https://developer.mozilla.org/en/Core_JavaScript_1.5_Guide/Functions#escape_and_unescape_Functions
// But it looks decodeURIComponent(encodeURIComponent(s)) doesn't
// preserve all Unicode characters either e.g. "\uffff" in Firefox.
// Note by wtritch: Hopefully this will not be necessary using ExternalInterface. Will require
// additional testing.
var result = WebSocket.__flash.send(this.__id, encodeURIComponent(data));
if (result < 0) { // success
return true;
} else {
this.bufferedAmount += result;
return false;
}
};
/**
* Close this web socket gracefully.
*/
WebSocket.prototype.close = function() {
if (this.readyState == WebSocket.CLOSED || this.readyState == WebSocket.CLOSING) {
return;
}
this.readyState = WebSocket.CLOSING;
WebSocket.__flash.close(this.__id);
};
/**
* Implementation of {@link <a href="http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-registration">DOM 2 EventTarget Interface</a>}
*
* @param {string} type
* @param {function} listener
* @param {boolean} useCapture
* @return void
*/
WebSocket.prototype.addEventListener = function(type, listener, useCapture) {
if (!(type in this.__events)) {
this.__events[type] = [];
}
this.__events[type].push(listener);
};
/**
* Implementation of {@link <a href="http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-registration">DOM 2 EventTarget Interface</a>}
*
* @param {string} type
* @param {function} listener
* @param {boolean} useCapture
* @return void
*/
WebSocket.prototype.removeEventListener = function(type, listener, useCapture) {
if (!(type in this.__events)) return;
var events = this.__events[type];
for (var i = events.length - 1; i >= 0; --i) {
if (events[i] === listener) {
events.splice(i, 1);
break;
}
}
};
/**
* Implementation of {@link <a href="http://www.w3.org/TR/DOM-Level-2-Events/events.html#Events-registration">DOM 2 EventTarget Interface</a>}
*
* @param {Event} event
* @return void
*/
WebSocket.prototype.dispatchEvent = function(event) {
var events = this.__events[event.type] || [];
for (var i = 0; i < events.length; ++i) {
events[i](event);
}
var handler = this["on" + event.type];
if (handler) handler(event);
};
/**
* Handles an event from Flash.
* @param {Object} flashEvent
*/
WebSocket.prototype.__handleEvent = function(flashEvent) {
if ("readyState" in flashEvent) {
this.readyState = flashEvent.readyState;
}
var jsEvent;
if (flashEvent.type == "open" || flashEvent.type == "error") {
jsEvent = this.__createSimpleEvent(flashEvent.type);
} else if (flashEvent.type == "close") {
// TODO implement jsEvent.wasClean
jsEvent = this.__createSimpleEvent("close");
} else if (flashEvent.type == "message") {
var data = decodeURIComponent(flashEvent.message);
jsEvent = this.__createMessageEvent("message", data);
} else {
throw "unknown event type: " + flashEvent.type;
}
this.dispatchEvent(jsEvent);
};
WebSocket.prototype.__createSimpleEvent = function(type) {
if (document.createEvent && window.Event) {
var event = document.createEvent("Event");
event.initEvent(type, false, false);
return event;
} else {
return {type: type, bubbles: false, cancelable: false};
}
};
WebSocket.prototype.__createMessageEvent = function(type, data) {
if (document.createEvent && window.MessageEvent && !window.opera) {
var event = document.createEvent("MessageEvent");
event.initMessageEvent("message", false, false, data, null, null, window, null);
return event;
} else {
// IE and Opera, the latter one truncates the data parameter after any 0x00 bytes.
return {type: type, data: data, bubbles: false, cancelable: false};
}
};
/**
* Define the WebSocket readyState enumeration.
*/
WebSocket.CONNECTING = 0;
WebSocket.OPEN = 1;
WebSocket.CLOSING = 2;
WebSocket.CLOSED = 3;
WebSocket.__flash = null;
WebSocket.__instances = {};
WebSocket.__tasks = [];
WebSocket.__nextId = 0;
/**
* Load a new flash security policy file.
* @param {string} url
*/
WebSocket.loadFlashPolicyFile = function(url){
WebSocket.__addTask(function() {
WebSocket.__flash.loadManualPolicyFile(url);
});
};
/**
* Loads WebSocketMain.swf and creates WebSocketMain object in Flash.
*/
WebSocket.__initialize = function() {
if (WebSocket.__flash) return;
if (WebSocket.__swfLocation) {
// For backword compatibility.
window.WEB_SOCKET_SWF_LOCATION = WebSocket.__swfLocation;
}
if (!window.WEB_SOCKET_SWF_LOCATION) {
console.error("[WebSocket] set WEB_SOCKET_SWF_LOCATION to location of WebSocketMain.swf");
return;
}
var container = document.createElement("div");
container.id = "webSocketContainer";
// Hides Flash box. We cannot use display: none or visibility: hidden because it prevents
// Flash from loading at least in IE. So we move it out of the screen at (-100, -100).
// But this even doesn't work with Flash Lite (e.g. in Droid Incredible). So with Flash
// Lite, we put it at (0, 0). This shows 1x1 box visible at left-top corner but this is
// the best we can do as far as we know now.
container.style.position = "absolute";
if (WebSocket.__isFlashLite()) {
container.style.left = "0px";
container.style.top = "0px";
} else {
container.style.left = "-100px";
container.style.top = "-100px";
}
var holder = document.createElement("div");
holder.id = "webSocketFlash";
container.appendChild(holder);
document.body.appendChild(container);
// See this article for hasPriority:
// http://help.adobe.com/en_US/as3/mobile/WS4bebcd66a74275c36cfb8137124318eebc6-7ffd.html
swfobject.embedSWF(
WEB_SOCKET_SWF_LOCATION,
"webSocketFlash",
"1" /* width */,
"1" /* height */,
"10.0.0" /* SWF version */,
null,
null,
{hasPriority: true, swliveconnect : true, allowScriptAccess: "always"},
null,
function(e) {
if (!e.success) {
console.error("[WebSocket] swfobject.embedSWF failed");
}
});
};
/**
* Called by Flash to notify JS that it's fully loaded and ready
* for communication.
*/
WebSocket.__onFlashInitialized = function() {
// We need to set a timeout here to avoid round-trip calls
// to flash during the initialization process.
setTimeout(function() {
WebSocket.__flash = document.getElementById("webSocketFlash");
WebSocket.__flash.setCallerUrl(location.href);
WebSocket.__flash.setDebug(!!window.WEB_SOCKET_DEBUG);
for (var i = 0; i < WebSocket.__tasks.length; ++i) {
WebSocket.__tasks[i]();
}
WebSocket.__tasks = [];
}, 0);
};
/**
* Called by Flash to notify WebSockets events are fired.
*/
WebSocket.__onFlashEvent = function() {
setTimeout(function() {
try {
// Gets events using receiveEvents() instead of getting it from event object
// of Flash event. This is to make sure to keep message order.
// It seems sometimes Flash events don't arrive in the same order as they are sent.
var events = WebSocket.__flash.receiveEvents();
for (var i = 0; i < events.length; ++i) {
WebSocket.__instances[events[i].webSocketId].__handleEvent(events[i]);
}
} catch (e) {
console.error(e);
}
}, 0);
return true;
};
// Called by Flash.
WebSocket.__log = function(message) {
console.log(decodeURIComponent(message));
};
// Called by Flash.
WebSocket.__error = function(message) {
console.error(decodeURIComponent(message));
};
WebSocket.__addTask = function(task) {
if (WebSocket.__flash) {
task();
} else {
WebSocket.__tasks.push(task);
}
};
/**
* Test if the browser is running flash lite.
* @return {boolean} True if flash lite is running, false otherwise.
*/
WebSocket.__isFlashLite = function() {
if (!window.navigator || !window.navigator.mimeTypes) {
return false;
}
var mimeType = window.navigator.mimeTypes["application/x-shockwave-flash"];
if (!mimeType || !mimeType.enabledPlugin || !mimeType.enabledPlugin.filename) {
return false;
}
return mimeType.enabledPlugin.filename.match(/flashlite/i) ? true : false;
};
if (!window.WEB_SOCKET_DISABLE_AUTO_INITIALIZATION) {
if (window.addEventListener) {
window.addEventListener("load", function(){
WebSocket.__initialize();
}, false);
} else {
window.attachEvent("onload", function(){
WebSocket.__initialize();
});
}
}
})();

View File

@ -1,344 +0,0 @@
/*
* Websock: high-performance binary WebSockets
* Copyright (C) 2011 Joel Martin
* Licensed under LGPL-3 (see LICENSE.txt)
*
* Websock is similar to the standard WebSocket object but Websock
* enables communication with raw TCP sockets (i.e. the binary stream)
* via websockify. This is accomplished by base64 encoding the data
* stream between Websock and websockify.
*
* Websock has built-in receive queue buffering; the message event
* does not contain actual data but is simply a notification that
* there is new data available. Several rQ* methods are available to
* read binary data off of the receive queue.
*/
// Load Flash WebSocket emulator if needed
if (window.WebSocket) {
Websock_native = true;
} else {
/* no builtin WebSocket so load web_socket.js */
Websock_native = false;
(function () {
function get_INCLUDE_URI() {
return (typeof INCLUDE_URI !== "undefined") ?
INCLUDE_URI : "";
}
var start = "<script src='" + get_INCLUDE_URI(),
end = "'><\/script>", extra = "";
WEB_SOCKET_SWF_LOCATION = get_INCLUDE_URI() +
"websocketmain.swf";
if (Util.Engine.trident) {
Util.Debug("Forcing uncached load of WebSocketMain.swf");
WEB_SOCKET_SWF_LOCATION += "?" + Math.random();
}
extra += start + "swfobject.js" + end;
extra += start + "web_socket.js" + end;
document.write(extra);
}());
}
function Websock() {
"use strict";
var api = {}, // Public API
websocket = null, // WebSocket object
rQ = [], // Receive queue
rQi = 0, // Receive queue index
rQmax = 10000, // Max receive queue size before compacting
sQ = [], // Send queue
eventHandlers = {
'message' : function() {},
'open' : function() {},
'close' : function() {},
'error' : function() {}
},
test_mode = false;
//
// Queue public functions
//
function get_sQ() {
return sQ;
}
function get_rQ() {
return rQ;
}
function get_rQi() {
return rQi;
}
function set_rQi(val) {
rQi = val;
};
function rQlen() {
return rQ.length - rQi;
}
function rQpeek8() {
return (rQ[rQi] );
}
function rQshift8() {
return (rQ[rQi++] );
}
function rQunshift8(num) {
if (rQi === 0) {
rQ.unshift(num);
} else {
rQi -= 1;
rQ[rQi] = num;
}
}
function rQshift16() {
return (rQ[rQi++] << 8) +
(rQ[rQi++] );
}
function rQshift32() {
return (rQ[rQi++] << 24) +
(rQ[rQi++] << 16) +
(rQ[rQi++] << 8) +
(rQ[rQi++] );
}
function rQshiftStr(len) {
var arr = rQ.slice(rQi, rQi + len);
rQi += len;
return arr.map(function (num) {
return String.fromCharCode(num); } ).join('');
}
function rQshiftBytes(len) {
rQi += len;
return rQ.slice(rQi-len, rQi);
}
function rQslice(start, end) {
if (end) {
return rQ.slice(rQi + start, rQi + end);
} else {
return rQ.slice(rQi + start);
}
}
// Check to see if we must wait for 'num' bytes (default to FBU.bytes)
// to be available in the receive queue. Return true if we need to
// wait (and possibly print a debug message), otherwise false.
function rQwait(msg, num, goback) {
var rQlen = rQ.length - rQi; // Skip rQlen() function call
if (rQlen < num) {
if (goback) {
if (rQi < goback) {
throw("rQwait cannot backup " + goback + " bytes");
}
rQi -= goback;
}
//Util.Debug(" waiting for " + (num-rQlen) +
// " " + msg + " byte(s)");
return true; // true means need more data
}
return false;
}
//
// Private utility routines
//
function encode_message() {
/* base64 encode */
return Base64.encode(sQ);
}
function decode_message(data) {
//Util.Debug(">> decode_message: " + data);
/* base64 decode */
rQ = rQ.concat(Base64.decode(data, 0));
//Util.Debug(">> decode_message, rQ: " + rQ);
}
//
// Public Send functions
//
function flush() {
if (websocket.bufferedAmount !== 0) {
Util.Debug("bufferedAmount: " + websocket.bufferedAmount);
}
if (websocket.bufferedAmount < api.maxBufferedAmount) {
//Util.Debug("arr: " + arr);
//Util.Debug("sQ: " + sQ);
if (sQ.length > 0) {
websocket.send(encode_message(sQ));
sQ = [];
}
return true;
} else {
Util.Info("Delaying send, bufferedAmount: " +
websocket.bufferedAmount);
return false;
}
}
// overridable for testing
function send(arr) {
//Util.Debug(">> send_array: " + arr);
sQ = sQ.concat(arr);
return flush();
}
function send_string(str) {
//Util.Debug(">> send_string: " + str);
api.send(str.split('').map(
function (chr) { return chr.charCodeAt(0); } ) );
}
//
// Other public functions
function recv_message(e) {
//Util.Debug(">> recv_message: " + e.data.length);
try {
decode_message(e.data);
if (rQlen() > 0) {
eventHandlers.message();
// Compact the receive queue
if (rQ.length > rQmax) {
//Util.Debug("Compacting receive queue");
rQ = rQ.slice(rQi);
rQi = 0;
}
} else {
Util.Debug("Ignoring empty message");
}
} catch (exc) {
if (typeof exc.stack !== 'undefined') {
Util.Warn("recv_message, caught exception: " + exc.stack);
} else if (typeof exc.description !== 'undefined') {
Util.Warn("recv_message, caught exception: " + exc.description);
} else {
Util.Warn("recv_message, caught exception:" + exc);
}
if (typeof exc.name !== 'undefined') {
eventHandlers.error(exc.name + ": " + exc.message);
} else {
eventHandlers.error(exc);
}
}
//Util.Debug("<< recv_message");
}
// Set event handlers
function on(evt, handler) {
eventHandlers[evt] = handler;
}
function init() {
rQ = [];
rQi = 0;
sQ = [];
websocket = null;
}
function open(uri) {
init();
if (test_mode) {
websocket = {};
} else {
websocket = new WebSocket(uri, 'base64');
// TODO: future native binary support
//websocket = new WebSocket(uri, ['binary', 'base64']);
}
websocket.onmessage = recv_message;
websocket.onopen = function() {
Util.Debug(">> WebSock.onopen");
if (websocket.protocol) {
Util.Info("Server chose sub-protocol: " + websocket.protocol);
}
eventHandlers.open();
Util.Debug("<< WebSock.onopen");
};
websocket.onclose = function(e) {
Util.Debug(">> WebSock.onclose");
eventHandlers.close(e);
Util.Debug("<< WebSock.onclose");
};
websocket.onerror = function(e) {
Util.Debug(">> WebSock.onerror: " + e);
eventHandlers.error(e);
Util.Debug("<< WebSock.onerror");
};
}
function close() {
if (websocket) {
if ((websocket.readyState === WebSocket.OPEN) ||
(websocket.readyState === WebSocket.CONNECTING)) {
Util.Info("Closing WebSocket connection");
websocket.close();
}
websocket.onmessage = function (e) { return; };
}
}
// Override internal functions for testing
// Takes a send function, returns reference to recv function
function testMode(override_send) {
test_mode = true;
api.send = override_send;
api.close = function () {};
return recv_message;
}
function constructor() {
// Configuration settings
api.maxBufferedAmount = 200;
// Direct access to send and receive queues
api.get_sQ = get_sQ;
api.get_rQ = get_rQ;
api.get_rQi = get_rQi;
api.set_rQi = set_rQi;
// Routines to read from the receive queue
api.rQlen = rQlen;
api.rQpeek8 = rQpeek8;
api.rQshift8 = rQshift8;
api.rQunshift8 = rQunshift8;
api.rQshift16 = rQshift16;
api.rQshift32 = rQshift32;
api.rQshiftStr = rQshiftStr;
api.rQshiftBytes = rQshiftBytes;
api.rQslice = rQslice;
api.rQwait = rQwait;
api.flush = flush;
api.send = send;
api.send_string = send_string;
api.on = on;
api.init = init;
api.open = open;
api.close = close;
api.testMode = testMode;
return api;
}
return constructor();
}

Binary file not shown.

View File

@ -1,148 +0,0 @@
/*
* noVNC: HTML5 VNC client
* Copyright (C) 2011 Joel Martin
* Licensed under LGPL-3 (see LICENSE.txt)
*
* See README.md for usage and integration instructions.
*/
"use strict";
/*jslint bitwise: false, white: false */
/*global window, document */
// Globals defined here
var WebUtil = {}, $D;
/*
* Simple DOM selector by ID
*/
if (!window.$D) {
$D = function (id) {
if (document.getElementById) {
return document.getElementById(id);
} else if (document.all) {
return document.all[id];
} else if (document.layers) {
return document.layers[id];
}
return undefined;
};
}
/*
* ------------------------------------------------------
* Namespaced in WebUtil
* ------------------------------------------------------
*/
// init log level reading the logging HTTP param
WebUtil.init_logging = function() {
Util._log_level = (document.location.href.match(
/logging=([A-Za-z0-9\._\-]*)/) ||
['', Util._log_level])[1];
Util.init_logging()
}
WebUtil.init_logging();
WebUtil.dirObj = function (obj, depth, parent) {
var i, msg = "", val = "";
if (! depth) { depth=2; }
if (! parent) { parent= ""; }
// Print the properties of the passed-in object
for (i in obj) {
if ((depth > 1) && (typeof obj[i] === "object")) {
// Recurse attributes that are objects
msg += WebUtil.dirObj(obj[i], depth-1, parent + "." + i);
} else {
//val = new String(obj[i]).replace("\n", " ");
if (typeof(obj[i]) === "undefined") {
val = "undefined";
} else {
val = obj[i].toString().replace("\n", " ");
}
if (val.length > 30) {
val = val.substr(0,30) + "...";
}
msg += parent + "." + i + ": " + val + "\n";
}
}
return msg;
};
// Read a query string variable
WebUtil.getQueryVar = function(name, defVal) {
var re = new RegExp('[?][^#]*' + name + '=([^&#]*)');
if (typeof defVal === 'undefined') { defVal = null; }
return (document.location.href.match(re) || ['',defVal])[1];
};
/*
* Cookie handling. Dervied from: http://www.quirksmode.org/js/cookies.html
*/
// No days means only for this browser session
WebUtil.createCookie = function(name,value,days) {
var date, expires;
if (days) {
date = new Date();
date.setTime(date.getTime()+(days*24*60*60*1000));
expires = "; expires="+date.toGMTString();
}
else {
expires = "";
}
document.cookie = name+"="+value+expires+"; path=/";
};
WebUtil.readCookie = function(name, defaultValue) {
var i, c, nameEQ = name + "=", ca = document.cookie.split(';');
for(i=0; i < ca.length; i += 1) {
c = ca[i];
while (c.charAt(0) === ' ') { c = c.substring(1,c.length); }
if (c.indexOf(nameEQ) === 0) { return c.substring(nameEQ.length,c.length); }
}
return (typeof defaultValue !== 'undefined') ? defaultValue : null;
};
WebUtil.eraseCookie = function(name) {
WebUtil.createCookie(name,"",-1);
};
/*
* Alternate stylesheet selection
*/
WebUtil.getStylesheets = function() { var i, links, sheets = [];
links = document.getElementsByTagName("link");
for (i = 0; i < links.length; i += 1) {
if (links[i].title &&
links[i].rel.toUpperCase().indexOf("STYLESHEET") > -1) {
sheets.push(links[i]);
}
}
return sheets;
};
// No sheet means try and use value from cookie, null sheet used to
// clear all alternates.
WebUtil.selectStylesheet = function(sheet) {
var i, link, sheets = WebUtil.getStylesheets();
if (typeof sheet === 'undefined') {
sheet = 'default';
}
for (i=0; i < sheets.length; i += 1) {
link = sheets[i];
if (link.title === sheet) {
Util.Debug("Using stylesheet " + sheet);
link.disabled = false;
} else {
//Util.Debug("Skipping stylesheet " + link.title);
link.disabled = true;
}
}
return sheet;
};

View File

@ -31,14 +31,14 @@
<item>Auto-detect</item>
<item>Framebuffer</item>
<item>Gralloc (Tegra2)</item>
<item>ADB</item>
<item>Gingerbread</item>
<!-- <item>ADB</item> -->
<item>SurfaceFlinger (2.3+)</item>
</string-array>
<string-array name="display_mode_values">
<item>auto</item>
<item>fb</item>
<item>gralloc</item>
<item>adb</item>
<!-- <item>adb</item> -->
<item>gingerbread</item>
</string-array>
<string-array name="sleep_strings">

View File

@ -1,17 +1,88 @@
<?xml version="1.0" encoding="utf-8"?>
<PreferenceScreen
xmlns:android="http://schemas.android.com/apk/res/android">
<EditTextPreference android:key="password" android:title="VNC password" android:password="true" android:summary="Protect your VNC connection"></EditTextPreference>-->
<ListPreference android:defaultValue="0" android:key="rotation" android:title="Rotation" android:entries="@array/rotation_strings" android:entryValues="@array/rotation_values" android:summary="Rotate screen if you like"></ListPreference>
<ListPreference android:defaultValue="100" android:key="scale" android:title="Scale Screen" android:entries="@array/scale_strings" android:entryValues="@array/scale_values" android:summary="Only 100 and 50 working for now"></ListPreference>
<PreferenceScreen xmlns:android="http://schemas.android.com/apk/res/android" >
<EditTextPreference android:inputType="number" android:defaultValue="5901" android:key="port" android:title="VNC port" android:summary="Note: It will not show error if cannot bind port"></EditTextPreference>
<ListPreference android:title="Display Access Method" android:summary="Change if you are experiencing display issues" android:key="displaymode" android:defaultValue="auto" android:entries="@array/display_mode_strings" android:entryValues="@array/display_mode_values"></ListPreference>
<CheckBoxPreference android:summaryOn="Warning! Just activate if you have your daemon running fine." android:title="Start server on boot" android:defaultValue="false" android:summaryOff="Warning! Just activate if you have your daemon running fine." android:key="startdaemononboot"></CheckBoxPreference>
<CheckBoxPreference android:key="screenturnoff" android:title="Don't Let Screen Turn off" android:defaultValue="false"></CheckBoxPreference>
<CheckBoxPreference android:key="notifyclient" android:title="Notify When Client Connects" android:summary="Show notification on status bar" android:defaultValue="true"></CheckBoxPreference>
<CheckBoxPreference android:key="asroot" android:defaultValue="true" android:title="Execute server as root" android:summary="Unselect this if you do not want to run the server as root."></CheckBoxPreference>
<CheckBoxPreference android:key="hidead" android:defaultValue="false" android:title="Disable Bottom Ad" android:summary="Select this if you don't want to view the ad."></CheckBoxPreference>
<PreferenceCategory android:title="VNC Server settings" >
<EditTextPreference
android:key="password"
android:password="true"
android:summary="Protect your VNC connection"
android:title="VNC password" >
</EditTextPreference>
<EditTextPreference
android:defaultValue="5901"
android:inputType="number"
android:key="port"
android:summary="Note: It will not show error if cannot bind port"
android:title="VNC port" >
</EditTextPreference>
<CheckBoxPreference
android:defaultValue="false"
android:key="startdaemononboot"
android:summaryOff="Warning! Just activate if you have your daemon running fine."
android:summaryOn="Warning! Just activate if you have your daemon running fine."
android:title="Start server on boot" >
</CheckBoxPreference>
</PreferenceCategory>
<PreferenceCategory android:title="Display settings" >
<ListPreference
android:defaultValue="0"
android:entries="@array/rotation_strings"
android:entryValues="@array/rotation_values"
android:key="rotation"
android:summary="Rotate screen if you like"
android:title="Rotation" >
</ListPreference>
<ListPreference
android:defaultValue="100"
android:entries="@array/scale_strings"
android:entryValues="@array/scale_values"
android:key="scale"
android:summary="Only 100 and 50 working for now"
android:title="Scale Screen" >
</ListPreference>
<CheckBoxPreference
android:defaultValue="false"
android:key="rotate_zte"
android:summary="Some ZTE devices have the framebuffer rotated."
android:title="Rotate display by 180º" >
</CheckBoxPreference>
<ListPreference
android:defaultValue="auto"
android:entries="@array/display_mode_strings"
android:entryValues="@array/display_mode_values"
android:key="displaymode"
android:summary="Change if you are experiencing display issues"
android:title="Display Access Method" >
</ListPreference>
<CheckBoxPreference
android:defaultValue="false"
android:key="screenturnoff"
android:title="Don&apos;t Let Screen Turn off" >
</CheckBoxPreference>
<CheckBoxPreference
android:defaultValue="true"
android:key="notifyclient"
android:summary="Show notification on status bar"
android:title="Notify When Client Connects" >
</CheckBoxPreference>
</PreferenceCategory>
<PreferenceCategory android:title="Misc Settings" >
<CheckBoxPreference
android:defaultValue="true"
android:key="asroot"
android:summary="Unselect this if you do not want to run the server as root."
android:title="Execute server as root" >
</CheckBoxPreference>
<CheckBoxPreference
android:defaultValue="false"
android:key="hidead"
android:summary="Select this if you don&apos;t want to view the ad."
android:title="Disable Bottom Ad" >
</CheckBoxPreference>
</PreferenceCategory>
</PreferenceScreen>

View File

@ -16,6 +16,8 @@ import java.util.TimerTask;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.http.conn.util.InetAddressUtils;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.BroadcastReceiver;
@ -365,12 +367,14 @@ public class MainActivity extends Activity
public String getIpAddress() {
try {
String ipv4;
for (Enumeration<NetworkInterface> en = NetworkInterface.getNetworkInterfaces(); en.hasMoreElements();) {
NetworkInterface intf = en.nextElement();
for (Enumeration<InetAddress> enumIpAddr = intf.getInetAddresses(); enumIpAddr.hasMoreElements();) {
InetAddress inetAddress = enumIpAddr.nextElement();
if (!inetAddress.isLoopbackAddress()) {
return inetAddress.getHostAddress().toString();
if (!inetAddress.isLoopbackAddress() && InetAddressUtils.isIPv4Address(ipv4=inetAddress.getHostAddress()))
return ipv4;
}
}
}
@ -516,7 +520,7 @@ public class MainActivity extends Activity
new AlertDialog.Builder(this)
.setTitle("About")
.setMessage(Html.fromHtml("version " + packageVersion() + "<br><br>Code: @oNaiPs<br><br>Graphics: ricardomendes.net"))
.setMessage(Html.fromHtml("version " + packageVersion() + "<br><br>Code: @oNaiPs<br><br>Graphics: ricardomendes.net<br><br>Under the GPLv3"))
.setPositiveButton("Close", null)
.setNegativeButton("Open Website", new DialogInterface.OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
@ -613,14 +617,17 @@ public class MainActivity extends Activity
new AlertDialog.Builder(this)
.setTitle(getString(R.string.app_name))
.setIcon(android.R.drawable.ic_dialog_info)
.setMessage("Do you want to send a bug report to the dev? Please specify what problem is ocurring.\n\nMake sure you started & stopped the server before submitting")
.setMessage("Do you want to send a bug report to the dev? Please specify what problem is ocurring.\n\n" +
"Make 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(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");

View File

@ -1,6 +1,8 @@
package org.onaips.vnc;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
@ -56,32 +58,28 @@ public class MainApplication extends Application {
public void createBinaries()
{
if (Build.VERSION.SDK_INT>Build.VERSION_CODES.FROYO)
copyBinary(R.raw.androidvncserver_gingerup , getFilesDir().getAbsolutePath() + "/androidvncserver");
else
copyBinary(R.raw.androidvncserver_froyo , getFilesDir().getAbsolutePath() + "/androidvncserver");
copyBinary(R.raw.vncviewer, getFilesDir().getAbsolutePath()+"/VncViewer.jar");
copyBinary(R.raw.index, getFilesDir().getAbsolutePath()+"/index.vnc");
String filesdir = getFilesDir().getAbsolutePath()+"/";
//copy the daemon
copyBinary(R.raw.androidvncserver, filesdir + "/androidvncserver");
//copy wrapper libs as well
copyBinary(R.raw.libdvnc_flinger_sdk10, filesdir + "/libdvnc_flinger_sdk10.so");
copyBinary(R.raw.libdvnc_flinger_sdk14, filesdir + "/libdvnc_flinger_sdk14.so");
copyBinary(R.raw.libdvnc_gralloc_sdk10, filesdir + "/libdvnc_gralloc_sdk10.so");
copyBinary(R.raw.libdvnc_gralloc_sdk14, filesdir + "/libdvnc_gralloc_sdk14.so");
//copy html related stuff
copyBinary(R.raw.webclients, filesdir + "/webclients.zip");
try {
ResLoader.unpackResources(R.raw.webclients, getApplicationContext(),filesdir);
} catch (FileNotFoundException e) {
e.printStackTrace();
} catch (IOException e) {
e.printStackTrace();
}
copyBinary(R.raw.base64, getFilesDir().getAbsolutePath()+"/base64.js");
copyBinary(R.raw.black, getFilesDir().getAbsolutePath()+"/black.css");
copyBinary(R.raw.des, getFilesDir().getAbsolutePath()+"/des.js");
copyBinary(R.raw.display, getFilesDir().getAbsolutePath()+"/display.js");
copyBinary(R.raw.input, getFilesDir().getAbsolutePath()+"/input.js");
copyBinary(R.raw.logo, getFilesDir().getAbsolutePath()+"/logo.js");
copyBinary(R.raw.novnc, getFilesDir().getAbsolutePath()+"/novnc.html");
copyBinary(R.raw.plain, getFilesDir().getAbsolutePath()+"/plain.css");
copyBinary(R.raw.playback, getFilesDir().getAbsolutePath()+"/playback.js");
copyBinary(R.raw.rfb, getFilesDir().getAbsolutePath()+"/rfb.js");
copyBinary(R.raw.self, getFilesDir().getAbsolutePath()+"/self.pem");
copyBinary(R.raw.swfobject, getFilesDir().getAbsolutePath()+"/swfobject.js");
copyBinary(R.raw.ui, getFilesDir().getAbsolutePath()+"/ui.js.vnc");
copyBinary(R.raw.util, getFilesDir().getAbsolutePath()+"/util.js");
copyBinary(R.raw.vnc, getFilesDir().getAbsolutePath()+"/vnc.js");
copyBinary(R.raw.web_socket, getFilesDir().getAbsolutePath()+"/web_socket.js");
copyBinary(R.raw.websock, getFilesDir().getAbsolutePath()+"/websock.js");
copyBinary(R.raw.websocketmain, getFilesDir().getAbsolutePath()+"/websocketmain.swf");
copyBinary(R.raw.webutil, getFilesDir().getAbsolutePath()+"/webutil.js");
}
public void copyBinary(int id,String path)
@ -102,7 +100,7 @@ public class MainApplication extends Application {
}
catch (Exception e)
{
log("public void createBinary(): " + e.getMessage());
log("public void createBinary() error! : " + e.getMessage());
}

View File

@ -1,5 +1,6 @@
package org.onaips.vnc;
import java.io.File;
import java.io.IOException;
import java.io.OutputStream;
import java.net.DatagramPacket;
@ -73,6 +74,7 @@ public class ServerManager extends Service {
// Lets see if i need to boot daemon...
try {
Process sh;
String files_dir = getFilesDir().getAbsolutePath();
String password = preferences.getString("password", "");
String password_check = "";
@ -109,22 +111,25 @@ public class ServerManager extends Service {
if (!preferences.getString("displaymode", "auto").equals("auto"))
display_method = "-m " + preferences.getString("displaymode", "auto");
String display_zte="";
if (preferences.getBoolean("rotate_zte", false))
display_zte = "-z";
Runtime.getRuntime().exec(
"chmod 777 " + getFilesDir().getAbsolutePath()
+ "/androidvncserver");
boolean root=preferences.getBoolean("asroot",true);
String permission_string="chmod 777 " + getFilesDir().getAbsolutePath()+ "/androidvncserver";
String server_string=getFilesDir().getAbsolutePath()+ "/androidvncserver " + password_check + " " + rotation+ " " + scaling_string + " " + port_string + " "
+ reverse_string + " " + display_method;
String permission_string="chmod 777 " + files_dir + "/androidvncserver";
String server_string= getFilesDir().getAbsolutePath()+ "/androidvncserver " + password_check + " " + rotation+ " " + scaling_string + " " + port_string + " "
+ reverse_string + " " + display_method + " " + display_zte;
boolean root=preferences.getBoolean("asroot",true);
root &= MainActivity.hasRootPermission();
if (root)
{
log("Running as root...");
sh = Runtime.getRuntime().exec("su");
sh = Runtime.getRuntime().exec("su",null,new File(files_dir));
OutputStream os = sh.getOutputStream();
writeCommand(os, permission_string);
writeCommand(os, server_string);
@ -133,7 +138,7 @@ public class ServerManager extends Service {
{
log("Not running as root...");
Runtime.getRuntime().exec(permission_string);
Runtime.getRuntime().exec(server_string);
Runtime.getRuntime().exec(server_string,null,new File(files_dir));
}
// dont show password on logcat
log("Starting " + getFilesDir().getAbsolutePath()