Viewport clip/drag for mobile/touchscreen devices.
API changes (forward compatible): - Display: add 'viewport' conf option to turn on and off viewport mode. - RFB: add 'viewportDrag' option to enable/disable viewport dragging mode. Other: - Add clip mode setting to default UI. For touch devices, clipping is forced on. - Use CSS media queries to adjust visual elements based on screen size. Especially disconnected logo size/position and button text size. - Catch page unload while connected and give a confirm dialog. - Change mouse button selector to a single button that changes between ' ', 'L', 'M', 'R' when clicked (empty means mouse is just being moved and doesn't send clicks). - include/ui.js:setViewClip() routine sets the clipping of the viewport to the current size of the viewport area (if clipping is enabled). - include/ui.js:setViewDrag() toggles/enables/disables viewport dragging mode. - Add several images for the UI and for Apple devices: - images/clipboard.png: clipboard menu icon - images/connect.png: connect menu icon - images/disconnect.png: disconnect button icon - images/keyboard.png: show keyboard button - images/move.png: viewport drag/move toggle button - images/settings.png: settings menu icon - images/screen_320x460.png: iOS app/desktop link start image - images/screen_57x57.png: iOS app icon - images/screen_700x700.png: full size noVNC image
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 2.1 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 1.5 KiB |
After Width: | Height: | Size: 12 KiB |
After Width: | Height: | Size: 1.8 KiB |
After Width: | Height: | Size: 18 KiB |
After Width: | Height: | Size: 2.3 KiB |
123
include/base.css
|
@ -65,21 +65,27 @@ html {
|
||||||
z-index:200;
|
z-index:200;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#noVNC_view_drag_button {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
|
#sendCtrlAltDelButton {
|
||||||
|
display: none;
|
||||||
|
}
|
||||||
#noVNC_mobile_buttons {
|
#noVNC_mobile_buttons {
|
||||||
display: none;
|
display: none;
|
||||||
}
|
}
|
||||||
|
|
||||||
.noVNC-buttons-left {
|
.noVNC-buttons-left {
|
||||||
position:fixed;
|
float: left;
|
||||||
padding-left:10px;
|
padding-left:10px;
|
||||||
padding-top:9px;
|
padding-top:4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
.noVNC-buttons-right {
|
.noVNC-buttons-right {
|
||||||
float:right;
|
float:right;
|
||||||
right: 0px;
|
right: 0px;
|
||||||
padding-right:10px;
|
padding-right:10px;
|
||||||
padding-top:9px;
|
padding-top:4px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#noVNC_status_bar {
|
#noVNC_status_bar {
|
||||||
|
@ -93,10 +99,6 @@ html {
|
||||||
width:100%;
|
width:100%;
|
||||||
}
|
}
|
||||||
|
|
||||||
.noVNC_status_button, #clipboardbutton, #connectbutton {
|
|
||||||
font-size: 14px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#noVNC_status {
|
#noVNC_status {
|
||||||
height:20px;
|
height:20px;
|
||||||
text-align: center;
|
text-align: center;
|
||||||
|
@ -141,8 +143,14 @@ html {
|
||||||
border-bottom-right-radius: 800px 600px;
|
border-bottom-right-radius: 800px 600px;
|
||||||
/*border-top-left-radius: 800px 600px;*/
|
/*border-top-left-radius: 800px 600px;*/
|
||||||
}
|
}
|
||||||
#VNC_canvas {
|
|
||||||
background: #eee;
|
#noVNC_container, #noVNC_canvas {
|
||||||
|
margin: 0px;
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
|
||||||
|
#noVNC_canvas {
|
||||||
|
left: 0px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#VNC_clipboard_clear_button {
|
#VNC_clipboard_clear_button {
|
||||||
|
@ -152,10 +160,6 @@ html {
|
||||||
font-size: 11px;
|
font-size: 11px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#noVNC_Settings {
|
|
||||||
width:200px;
|
|
||||||
}
|
|
||||||
|
|
||||||
#noVNC_clipboard_clear_button {
|
#noVNC_clipboard_clear_button {
|
||||||
float:right;
|
float:right;
|
||||||
}
|
}
|
||||||
|
@ -211,32 +215,36 @@ html {
|
||||||
}
|
}
|
||||||
|
|
||||||
/*Bubble contents divs*/
|
/*Bubble contents divs*/
|
||||||
#noVNC_Settings {
|
#noVNC_settings {
|
||||||
margin-top:72px;
|
|
||||||
position:fixed;
|
|
||||||
right:100px;
|
|
||||||
display:none;
|
display:none;
|
||||||
|
margin-top:72px;
|
||||||
|
right:10px;
|
||||||
|
position:fixed;
|
||||||
}
|
}
|
||||||
|
|
||||||
#noVNC_controls {
|
#noVNC_controls {
|
||||||
margin-top:72px;
|
margin-top:72px;
|
||||||
position:fixed;
|
|
||||||
right:10px;
|
right:10px;
|
||||||
|
position:fixed;
|
||||||
|
}
|
||||||
|
#noVNC_controls.top:after {
|
||||||
|
right:15px;
|
||||||
}
|
}
|
||||||
|
|
||||||
#noVNC_clipboard {
|
#noVNC_clipboard {
|
||||||
display:none;
|
display:none;
|
||||||
margin-top:72px;
|
margin-top:72px;
|
||||||
|
right:20px;
|
||||||
position:fixed;
|
position:fixed;
|
||||||
right:180px;
|
}
|
||||||
|
#noVNC_clipboard.top:after {
|
||||||
|
right:85px;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*Default noVNC logo.*/
|
/*Default noVNC logo.*/
|
||||||
#noVNC_logo {
|
#noVNC_logo {
|
||||||
width:400px;
|
margin-top: 170px;
|
||||||
margin-left:auto;
|
margin-left: 10px;
|
||||||
margin-right:auto;
|
|
||||||
font-size:160px;
|
|
||||||
color:yellow;
|
color:yellow;
|
||||||
text-align:left;
|
text-align:left;
|
||||||
font-family: 'Orbitron', sans-serif;
|
font-family: 'Orbitron', sans-serif;
|
||||||
|
@ -249,17 +257,80 @@ html {
|
||||||
1px 1px 0 #000;
|
1px 1px 0 #000;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
#noVNC_logo span{
|
#noVNC_logo span{
|
||||||
color:green;
|
color:green;
|
||||||
}
|
}
|
||||||
|
|
||||||
#keyboardinput {
|
#keyboardinput {
|
||||||
width:0px;
|
width:1px;
|
||||||
height:0px;
|
height:1px;
|
||||||
background-color:#313131;
|
background-color:#6d84a2;
|
||||||
border:0;
|
border:0;
|
||||||
}
|
}
|
||||||
|
|
||||||
.noVNC_status_warn {
|
.noVNC_status_warn {
|
||||||
background-color:yellow;
|
background-color:yellow;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ----------------------------------------
|
||||||
|
* Media sizing
|
||||||
|
* ----------------------------------------
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
.noVNC_status_button {
|
||||||
|
font-size: 12px;
|
||||||
|
padding: 2px;
|
||||||
|
vertical-align: middle;
|
||||||
|
}
|
||||||
|
#noVNC_clipboard_text {
|
||||||
|
width: 500px;
|
||||||
|
border-color: red;
|
||||||
|
}
|
||||||
|
|
||||||
|
#noVNC_logo {
|
||||||
|
font-size: 180px;
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (min-width: 481px) and (max-width: 640px) {
|
||||||
|
.noVNC_status_button {
|
||||||
|
font-size: 10px;
|
||||||
|
padding: 1px;
|
||||||
|
}
|
||||||
|
#noVNC_clipboard_text {
|
||||||
|
width: 410px;
|
||||||
|
border-color: yellow;
|
||||||
|
}
|
||||||
|
#noVNC_logo {
|
||||||
|
font-size: 150px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (min-width: 321px) and (max-width: 480px) {
|
||||||
|
.noVNC_status_button {
|
||||||
|
font-size: 10px;
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
#noVNC_clipboard_text {
|
||||||
|
width: 250px;
|
||||||
|
border-color: green;
|
||||||
|
}
|
||||||
|
#noVNC_logo {
|
||||||
|
font-size: 110px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@media screen and (max-width: 320px) {
|
||||||
|
.noVNC_status_button {
|
||||||
|
font-size: 9px;
|
||||||
|
padding: 0px;
|
||||||
|
}
|
||||||
|
#noVNC_clipboard_text {
|
||||||
|
width: 220px;
|
||||||
|
border-color: blue;
|
||||||
|
}
|
||||||
|
#noVNC_logo {
|
||||||
|
font-size: 90px;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -19,3 +19,8 @@
|
||||||
background:#000;
|
background:#000;
|
||||||
color:#fff;
|
color:#fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#keyboardinput {
|
||||||
|
background-color:#000;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,3 +20,8 @@
|
||||||
background:#04073d;
|
background:#04073d;
|
||||||
color:#fff;
|
color:#fff;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#keyboardinput {
|
||||||
|
background-color:#04073d;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
|
@ -45,6 +45,7 @@ Util.conf_defaults(conf, that, defaults, [
|
||||||
['true_color', 'rw', 'bool', true, 'Use true-color pixel data'],
|
['true_color', 'rw', 'bool', true, 'Use true-color pixel data'],
|
||||||
['colourMap', 'rw', 'arr', [], 'Colour map array (when not true-color)'],
|
['colourMap', 'rw', 'arr', [], 'Colour map array (when not true-color)'],
|
||||||
['scale', 'rw', 'float', 1.0, 'Display area scale factor 0.0 - 1.0'],
|
['scale', 'rw', 'float', 1.0, 'Display area scale factor 0.0 - 1.0'],
|
||||||
|
['viewport', 'rw', 'bool', false, 'Use a viewport set with viewportChange()'],
|
||||||
['width', 'rw', 'int', null, 'Display area width'],
|
['width', 'rw', 'int', null, 'Display area width'],
|
||||||
['height', 'rw', 'int', null, 'Display area height'],
|
['height', 'rw', 'int', null, 'Display area height'],
|
||||||
|
|
||||||
|
@ -245,6 +246,14 @@ that.viewportChange = function(deltaX, deltaY, width, height) {
|
||||||
var c = conf.target, v = viewport, cr = cleanRect,
|
var c = conf.target, v = viewport, cr = cleanRect,
|
||||||
saveImg = null, saveStyle, x1, y1, vx2, vy2, w, h;
|
saveImg = null, saveStyle, x1, y1, vx2, vy2, w, h;
|
||||||
|
|
||||||
|
if (!conf.viewport) {
|
||||||
|
Util.Debug("Setting viewport to full display region");
|
||||||
|
deltaX = -v.w; // Clamped later if out of bounds
|
||||||
|
deltaY = -v.h; // Clamped later if out of bounds
|
||||||
|
width = fb_width;
|
||||||
|
height = fb_height;
|
||||||
|
}
|
||||||
|
|
||||||
if (typeof(deltaX) === "undefined") { deltaX = 0; }
|
if (typeof(deltaX) === "undefined") { deltaX = 0; }
|
||||||
if (typeof(deltaY) === "undefined") { deltaY = 0; }
|
if (typeof(deltaY) === "undefined") { deltaY = 0; }
|
||||||
if (typeof(width) === "undefined") { width = v.w; }
|
if (typeof(width) === "undefined") { width = v.w; }
|
||||||
|
@ -269,7 +278,10 @@ that.viewportChange = function(deltaX, deltaY, width, height) {
|
||||||
v.h = height;
|
v.h = height;
|
||||||
|
|
||||||
|
|
||||||
if (v.w > 0 && v.h > 0) {
|
if (v.w > 0 && v.h > 0 && c.width > 0 && c.height > 0) {
|
||||||
|
console.log("here1:",
|
||||||
|
((c.width < v.w) ? c.width : v.w),
|
||||||
|
((c.height < v.h) ? c.height : v.h));
|
||||||
saveImg = c_ctx.getImageData(0, 0,
|
saveImg = c_ctx.getImageData(0, 0,
|
||||||
(c.width < v.w) ? c.width : v.w,
|
(c.width < v.w) ? c.width : v.w,
|
||||||
(c.height < v.h) ? c.height : v.h);
|
(c.height < v.h) ? c.height : v.h);
|
||||||
|
@ -406,6 +418,13 @@ that.getCleanDirtyReset = function() {
|
||||||
'x2': v.x + v.w - 1, 'y2': v.y + v.h - 1};
|
'x2': v.x + v.w - 1, 'y2': v.y + v.h - 1};
|
||||||
|
|
||||||
return {'cleanBox': cleanBox, 'dirtyBoxes': dirtyBoxes};
|
return {'cleanBox': cleanBox, 'dirtyBoxes': dirtyBoxes};
|
||||||
|
};
|
||||||
|
|
||||||
|
that.absX = function(x) {
|
||||||
|
return x + viewport.x;
|
||||||
|
}
|
||||||
|
that.absY = function(y) {
|
||||||
|
return y + viewport.y;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -454,11 +473,9 @@ that.clear = function() {
|
||||||
|
|
||||||
if (conf.logo) {
|
if (conf.logo) {
|
||||||
that.resize(conf.logo.width, conf.logo.height);
|
that.resize(conf.logo.width, conf.logo.height);
|
||||||
that.viewportChange(0, 0, conf.logo.width, conf.logo.height);
|
|
||||||
that.blitStringImage(conf.logo.data, 0, 0);
|
that.blitStringImage(conf.logo.data, 0, 0);
|
||||||
} else {
|
} else {
|
||||||
that.resize(640, 20);
|
that.resize(640, 20);
|
||||||
that.viewportChange(0, 0, 640, 20);
|
|
||||||
c_ctx.clearRect(0, 0, viewport.w, viewport.h);
|
c_ctx.clearRect(0, 0, viewport.w, viewport.h);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -551,7 +568,15 @@ imageDataCreate = function(width, height) {
|
||||||
};
|
};
|
||||||
|
|
||||||
rgbxImageData = function(x, y, width, height, arr, offset) {
|
rgbxImageData = function(x, y, width, height, arr, offset) {
|
||||||
var img, i, j, data;
|
var img, i, j, data, v = viewport;
|
||||||
|
/*
|
||||||
|
if ((x - v.x >= v.w) || (y - v.y >= v.h) ||
|
||||||
|
(x - v.x + width < 0) || (y - v.y + height < 0)) {
|
||||||
|
//console.log("skipping, out of bounds: ", x, y);
|
||||||
|
// Skipping because outside of viewport
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
*/
|
||||||
img = c_imageData(width, height);
|
img = c_imageData(width, height);
|
||||||
data = img.data;
|
data = img.data;
|
||||||
for (i=0, j=offset; i < (width * height * 4); i=i+4, j=j+4) {
|
for (i=0, j=offset; i < (width * height * 4); i=i+4, j=j+4) {
|
||||||
|
@ -560,7 +585,7 @@ rgbxImageData = function(x, y, width, height, arr, offset) {
|
||||||
data[i + 2] = arr[j + 2];
|
data[i + 2] = arr[j + 2];
|
||||||
data[i + 3] = 255; // Set Alpha
|
data[i + 3] = 255; // Set Alpha
|
||||||
}
|
}
|
||||||
c_ctx.putImageData(img, x - viewport.x, y - viewport.y);
|
c_ctx.putImageData(img, x - v.x, y - v.y);
|
||||||
};
|
};
|
||||||
|
|
||||||
// really slow fallback if we don't have imageData
|
// really slow fallback if we don't have imageData
|
||||||
|
|
|
@ -118,7 +118,9 @@ var that = {}, // Public API methods
|
||||||
|
|
||||||
/* Mouse state */
|
/* Mouse state */
|
||||||
mouse_buttonMask = 0,
|
mouse_buttonMask = 0,
|
||||||
mouse_arr = [];
|
mouse_arr = [],
|
||||||
|
viewportDragging = false,
|
||||||
|
viewportDragPos = {};
|
||||||
|
|
||||||
// Configuration attributes
|
// Configuration attributes
|
||||||
Util.conf_defaults(conf, that, defaults, [
|
Util.conf_defaults(conf, that, defaults, [
|
||||||
|
@ -133,6 +135,8 @@ Util.conf_defaults(conf, that, defaults, [
|
||||||
['connectTimeout', 'rw', 'int', def_con_timeout, 'Time (s) to wait for connection'],
|
['connectTimeout', 'rw', 'int', def_con_timeout, 'Time (s) to wait for connection'],
|
||||||
['disconnectTimeout', 'rw', 'int', 3, 'Time (s) to wait for disconnection'],
|
['disconnectTimeout', 'rw', 'int', 3, 'Time (s) to wait for disconnection'],
|
||||||
|
|
||||||
|
['viewportDrag', 'rw', 'bool', false, 'Move the viewport on mouse drags'],
|
||||||
|
|
||||||
['check_rate', 'rw', 'int', 217, 'Timing (ms) of send/receive check'],
|
['check_rate', 'rw', 'int', 217, 'Timing (ms) of send/receive check'],
|
||||||
['fbu_req_rate', 'rw', 'int', 1413, 'Timing (ms) of frameBufferUpdate requests'],
|
['fbu_req_rate', 'rw', 'int', 1413, 'Timing (ms) of frameBufferUpdate requests'],
|
||||||
|
|
||||||
|
@ -547,7 +551,7 @@ function flushClient() {
|
||||||
// overridable for testing
|
// overridable for testing
|
||||||
checkEvents = function() {
|
checkEvents = function() {
|
||||||
var now;
|
var now;
|
||||||
if (rfb_state === 'normal') {
|
if (rfb_state === 'normal' && !viewportDragging) {
|
||||||
if (! flushClient()) {
|
if (! flushClient()) {
|
||||||
now = new Date().getTime();
|
now = new Date().getTime();
|
||||||
if (now > last_req_time + conf.fbu_req_rate) {
|
if (now > last_req_time + conf.fbu_req_rate) {
|
||||||
|
@ -572,13 +576,43 @@ mouseButton = function(x, y, down, bmask) {
|
||||||
} else {
|
} else {
|
||||||
mouse_buttonMask ^= bmask;
|
mouse_buttonMask ^= bmask;
|
||||||
}
|
}
|
||||||
mouse_arr = mouse_arr.concat( pointerEvent(x, y) );
|
|
||||||
|
if (conf.viewportDrag) {
|
||||||
|
if (down && !viewportDragging) {
|
||||||
|
viewportDragging = true;
|
||||||
|
viewportDragPos = {'x': x, 'y': y};
|
||||||
|
|
||||||
|
// Skip sending mouse events
|
||||||
|
return;
|
||||||
|
} else {
|
||||||
|
viewportDragging = false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
mouse_arr = mouse_arr.concat(
|
||||||
|
pointerEvent(display.absX(x), display.absY(y)) );
|
||||||
flushClient();
|
flushClient();
|
||||||
};
|
};
|
||||||
|
|
||||||
mouseMove = function(x, y) {
|
mouseMove = function(x, y) {
|
||||||
//Util.Debug('>> mouseMove ' + x + "," + y);
|
//Util.Debug('>> mouseMove ' + x + "," + y);
|
||||||
mouse_arr = mouse_arr.concat( pointerEvent(x, y) );
|
var deltaX, deltaY;
|
||||||
|
|
||||||
|
if (viewportDragging) {
|
||||||
|
//deltaX = x - viewportDragPos.x; // drag viewport
|
||||||
|
deltaX = viewportDragPos.x - x; // drag frame buffer
|
||||||
|
//deltaY = y - viewportDragPos.y; // drag viewport
|
||||||
|
deltaY = viewportDragPos.y - y; // drag frame buffer
|
||||||
|
viewportDragPos = {'x': x, 'y': y};
|
||||||
|
|
||||||
|
display.viewportChange(deltaX, deltaY);
|
||||||
|
|
||||||
|
// Skip sending mouse events
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
mouse_arr = mouse_arr.concat(
|
||||||
|
pointerEvent(display.absX(x), display.absY(y)) );
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
|
@ -778,7 +812,6 @@ init_msg = function() {
|
||||||
|
|
||||||
display.set_true_color(conf.true_color);
|
display.set_true_color(conf.true_color);
|
||||||
display.resize(fb_width, fb_height);
|
display.resize(fb_width, fb_height);
|
||||||
display.viewportChange(0, 0, fb_width, fb_height);
|
|
||||||
keyboard.grab();
|
keyboard.grab();
|
||||||
mouse.grab();
|
mouse.grab();
|
||||||
|
|
||||||
|
@ -1309,7 +1342,6 @@ encHandlers.DesktopSize = function set_desktopsize() {
|
||||||
fb_width = FBU.width;
|
fb_width = FBU.width;
|
||||||
fb_height = FBU.height;
|
fb_height = FBU.height;
|
||||||
display.resize(fb_width, fb_height);
|
display.resize(fb_width, fb_height);
|
||||||
display.viewportChange(0, 0, fb_width, fb_height);
|
|
||||||
timing.fbu_rt_start = (new Date()).getTime();
|
timing.fbu_rt_start = (new Date()).getTime();
|
||||||
// Send a new non-incremental request
|
// Send a new non-incremental request
|
||||||
ws.send(fbUpdateRequests());
|
ws.send(fbUpdateRequests());
|
||||||
|
|
226
include/ui.js
|
@ -12,6 +12,7 @@
|
||||||
|
|
||||||
var UI = {
|
var UI = {
|
||||||
|
|
||||||
|
rfb_state : 'loaded',
|
||||||
settingsOpen : false,
|
settingsOpen : false,
|
||||||
connSettingsOpen : true,
|
connSettingsOpen : true,
|
||||||
clipboardOpen: false,
|
clipboardOpen: false,
|
||||||
|
@ -36,8 +37,8 @@ load: function() {
|
||||||
// Settings with immediate effects
|
// Settings with immediate effects
|
||||||
UI.initSetting('logging', 'warn');
|
UI.initSetting('logging', 'warn');
|
||||||
WebUtil.init_logging(UI.getSetting('logging'));
|
WebUtil.init_logging(UI.getSetting('logging'));
|
||||||
UI.initSetting('stylesheet', 'default');
|
|
||||||
|
|
||||||
|
UI.initSetting('stylesheet', 'default');
|
||||||
WebUtil.selectStylesheet(null);
|
WebUtil.selectStylesheet(null);
|
||||||
// call twice to get around webkit bug
|
// call twice to get around webkit bug
|
||||||
WebUtil.selectStylesheet(UI.getSetting('stylesheet'));
|
WebUtil.selectStylesheet(UI.getSetting('stylesheet'));
|
||||||
|
@ -55,6 +56,7 @@ load: function() {
|
||||||
UI.rfb = RFB({'target': $D('noVNC_canvas'),
|
UI.rfb = RFB({'target': $D('noVNC_canvas'),
|
||||||
'onUpdateState': UI.updateState,
|
'onUpdateState': UI.updateState,
|
||||||
'onClipboard': UI.clipReceive});
|
'onClipboard': UI.clipReceive});
|
||||||
|
UI.updateSettingsState(false);
|
||||||
|
|
||||||
// Unfocus clipboard when over the VNC area
|
// Unfocus clipboard when over the VNC area
|
||||||
//$D('VNC_screen').onmousemove = function () {
|
//$D('VNC_screen').onmousemove = function () {
|
||||||
|
@ -66,9 +68,15 @@ load: function() {
|
||||||
|
|
||||||
// Show mouse selector buttons on touch screen devices
|
// Show mouse selector buttons on touch screen devices
|
||||||
if ('ontouchstart' in document.documentElement) {
|
if ('ontouchstart' in document.documentElement) {
|
||||||
|
// Show mobile buttons
|
||||||
$D('noVNC_mobile_buttons').style.display = "inline";
|
$D('noVNC_mobile_buttons').style.display = "inline";
|
||||||
UI.setMouseButton();
|
UI.setMouseButton();
|
||||||
window.scrollTo(0, 1);
|
// Remove the address bar
|
||||||
|
setTimeout(function() { window.scrollTo(0, 1); }, 100);
|
||||||
|
UI.initSetting('clip', true);
|
||||||
|
$D('noVNC_clip').disabled = true;
|
||||||
|
} else {
|
||||||
|
UI.initSetting('clip', false);
|
||||||
}
|
}
|
||||||
|
|
||||||
//iOS Safari does not support CSS position:fixed.
|
//iOS Safari does not support CSS position:fixed.
|
||||||
|
@ -76,11 +84,21 @@ load: function() {
|
||||||
if ((navigator.userAgent.match(/iPhone/i)) ||
|
if ((navigator.userAgent.match(/iPhone/i)) ||
|
||||||
(navigator.userAgent.match(/iPod/i)) ||
|
(navigator.userAgent.match(/iPod/i)) ||
|
||||||
(navigator.userAgent.match(/iPad/i))) {
|
(navigator.userAgent.match(/iPad/i))) {
|
||||||
UI.setOnscroll();
|
//UI.setOnscroll();
|
||||||
UI.setResize();
|
//UI.setResize();
|
||||||
}
|
}
|
||||||
|
|
||||||
$D('noVNC_host').focus();
|
$D('noVNC_host').focus();
|
||||||
|
|
||||||
|
UI.setViewClip();
|
||||||
|
Util.addEvent(window, 'resize', UI.setViewClip);
|
||||||
|
|
||||||
|
Util.addEvent(window, 'beforeunload', function () {
|
||||||
|
if (UI.rfb_state === 'normal') {
|
||||||
|
return "You are currently connected.";
|
||||||
|
}
|
||||||
|
} );
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
// Read form control compatible setting from cookie
|
// Read form control compatible setting from cookie
|
||||||
|
@ -166,7 +184,6 @@ initSetting: function(name, defVal) {
|
||||||
clickSettingsMenu: function() {
|
clickSettingsMenu: function() {
|
||||||
if (UI.settingsOpen) {
|
if (UI.settingsOpen) {
|
||||||
UI.settingsApply();
|
UI.settingsApply();
|
||||||
|
|
||||||
UI.closeSettingsMenu();
|
UI.closeSettingsMenu();
|
||||||
} else {
|
} else {
|
||||||
UI.updateSetting('encrypt');
|
UI.updateSetting('encrypt');
|
||||||
|
@ -177,6 +194,7 @@ clickSettingsMenu: function() {
|
||||||
UI.updateSetting('cursor', false);
|
UI.updateSetting('cursor', false);
|
||||||
$D('noVNC_cursor').disabled = true;
|
$D('noVNC_cursor').disabled = true;
|
||||||
}
|
}
|
||||||
|
UI.updateSetting('clip');
|
||||||
UI.updateSetting('shared');
|
UI.updateSetting('shared');
|
||||||
UI.updateSetting('connectTimeout');
|
UI.updateSetting('connectTimeout');
|
||||||
UI.updateSetting('stylesheet');
|
UI.updateSetting('stylesheet');
|
||||||
|
@ -195,32 +213,16 @@ openSettingsMenu: function() {
|
||||||
if (UI.connSettingsOpen == true) {
|
if (UI.connSettingsOpen == true) {
|
||||||
UI.connectPanelbutton();
|
UI.connectPanelbutton();
|
||||||
}
|
}
|
||||||
$D('noVNC_Settings').style.display = "block";
|
$D('noVNC_settings').style.display = "block";
|
||||||
UI.settingsOpen = true;
|
UI.settingsOpen = true;
|
||||||
},
|
},
|
||||||
|
|
||||||
// Close menu (without applying settings)
|
// Close menu (without applying settings)
|
||||||
closeSettingsMenu: function() {
|
closeSettingsMenu: function() {
|
||||||
$D('noVNC_Settings').style.display = "none";
|
$D('noVNC_settings').style.display = "none";
|
||||||
UI.settingsOpen = false;
|
UI.settingsOpen = false;
|
||||||
},
|
},
|
||||||
|
|
||||||
// Disable/enable controls depending on connection state
|
|
||||||
settingsDisabled: function(disabled, rfb) {
|
|
||||||
//Util.Debug(">> settingsDisabled");
|
|
||||||
$D('noVNC_encrypt').disabled = disabled;
|
|
||||||
$D('noVNC_true_color').disabled = disabled;
|
|
||||||
if (rfb && rfb.get_display() && rfb.get_display().get_cursor_uri()) {
|
|
||||||
$D('noVNC_cursor').disabled = disabled;
|
|
||||||
} else {
|
|
||||||
UI.updateSetting('cursor', false);
|
|
||||||
$D('noVNC_cursor').disabled = true;
|
|
||||||
}
|
|
||||||
$D('noVNC_shared').disabled = disabled;
|
|
||||||
$D('noVNC_connectTimeout').disabled = disabled;
|
|
||||||
//Util.Debug("<< settingsDisabled");
|
|
||||||
},
|
|
||||||
|
|
||||||
// Save/apply settings when 'Apply' button is pressed
|
// Save/apply settings when 'Apply' button is pressed
|
||||||
settingsApply: function() {
|
settingsApply: function() {
|
||||||
//Util.Debug(">> settingsApply");
|
//Util.Debug(">> settingsApply");
|
||||||
|
@ -229,6 +231,7 @@ settingsApply: function() {
|
||||||
if (UI.rfb.get_display().get_cursor_uri()) {
|
if (UI.rfb.get_display().get_cursor_uri()) {
|
||||||
UI.saveSetting('cursor');
|
UI.saveSetting('cursor');
|
||||||
}
|
}
|
||||||
|
UI.saveSetting('clip');
|
||||||
UI.saveSetting('shared');
|
UI.saveSetting('shared');
|
||||||
UI.saveSetting('connectTimeout');
|
UI.saveSetting('connectTimeout');
|
||||||
UI.saveSetting('stylesheet');
|
UI.saveSetting('stylesheet');
|
||||||
|
@ -237,6 +240,7 @@ settingsApply: function() {
|
||||||
// Settings with immediate (non-connected related) effect
|
// Settings with immediate (non-connected related) effect
|
||||||
WebUtil.selectStylesheet(UI.getSetting('stylesheet'));
|
WebUtil.selectStylesheet(UI.getSetting('stylesheet'));
|
||||||
WebUtil.init_logging(UI.getSetting('logging'));
|
WebUtil.init_logging(UI.getSetting('logging'));
|
||||||
|
UI.setViewClip();
|
||||||
//Util.Debug("<< settingsApply");
|
//Util.Debug("<< settingsApply");
|
||||||
},
|
},
|
||||||
|
|
||||||
|
@ -257,65 +261,60 @@ sendCtrlAltDel: function() {
|
||||||
},
|
},
|
||||||
|
|
||||||
setMouseButton: function(num) {
|
setMouseButton: function(num) {
|
||||||
var b, blist = [1,2,4], button,
|
var b, blist = [0, 1,2,4], button;
|
||||||
mouse = UI.rfb.get_mouse();
|
|
||||||
|
|
||||||
if (typeof num === 'undefined') {
|
if (typeof num === 'undefined') {
|
||||||
// Show the default
|
// Disable mouse buttons
|
||||||
num = mouse.get_touchButton();
|
num = -1;
|
||||||
} else if (num === mouse.get_touchButton()) {
|
}
|
||||||
// Set all buttons off (no clicks)
|
if (UI.rfb) {
|
||||||
mouse.set_touchButton(0);
|
UI.rfb.get_mouse().set_touchButton(num);
|
||||||
num = 0;
|
|
||||||
} else {
|
|
||||||
// Turn on one button
|
|
||||||
mouse.set_touchButton(num);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (b = 0; b < blist.length; b++) {
|
for (b = 0; b < blist.length; b++) {
|
||||||
button = $D('noVNC_mouse_button' + blist[b]);
|
button = $D('noVNC_mouse_button' + blist[b]);
|
||||||
if (blist[b] === num) {
|
if (blist[b] === num) {
|
||||||
|
button.style.display = "";
|
||||||
|
} else {
|
||||||
|
button.style.display = "none";
|
||||||
|
/*
|
||||||
button.style.backgroundColor = "black";
|
button.style.backgroundColor = "black";
|
||||||
button.style.color = "lightgray";
|
button.style.color = "lightgray";
|
||||||
} else {
|
|
||||||
button.style.backgroundColor = "";
|
button.style.backgroundColor = "";
|
||||||
button.style.color = "";
|
button.style.color = "";
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
updateState: function(rfb, state, oldstate, msg) {
|
updateState: function(rfb, state, oldstate, msg) {
|
||||||
var s, sb, c, cad, klass;
|
var s, sb, c, d, cad, vd, klass;
|
||||||
|
UI.rfb_state = state;
|
||||||
s = $D('noVNC_status');
|
s = $D('noVNC_status');
|
||||||
sb = $D('noVNC_status_bar');
|
sb = $D('noVNC_status_bar');
|
||||||
c = $D('connectPanelbutton');
|
c = $D('connectPanelbutton');
|
||||||
cad = $D('sendCtrlAltDelButton');
|
d = $D('disconnectButton');
|
||||||
switch (state) {
|
switch (state) {
|
||||||
case 'failed':
|
case 'failed':
|
||||||
case 'fatal':
|
case 'fatal':
|
||||||
c.disabled = true;
|
c.style.display = "";
|
||||||
cad.style.display = "none";
|
d.style.display = "none";
|
||||||
UI.settingsDisabled(true, rfb);
|
UI.updateSettingsState(false);
|
||||||
klass = "noVNC_status_error";
|
klass = "noVNC_status_error";
|
||||||
break;
|
break;
|
||||||
case 'normal':
|
case 'normal':
|
||||||
c.value = "Disconnect";
|
c.style.display = "none";
|
||||||
c.onclick = UI.disconnect;
|
d.style.display = "";
|
||||||
c.disabled = false;
|
UI.updateSettingsState(true);
|
||||||
cad.style.display = "";
|
|
||||||
UI.settingsDisabled(true, rfb);
|
|
||||||
klass = "noVNC_status_normal";
|
klass = "noVNC_status_normal";
|
||||||
break;
|
break;
|
||||||
case 'disconnected':
|
case 'disconnected':
|
||||||
$D('noVNC_logo').style.display = "block";
|
$D('noVNC_logo').style.display = "block";
|
||||||
c.value = "Connection";
|
|
||||||
c.onclick = UI.connectPanelbutton;
|
|
||||||
case 'loaded':
|
case 'loaded':
|
||||||
c.value = "Connection";
|
//c.value = "Connection";
|
||||||
c.onclick = UI.connectPanelbutton;
|
c.style.display = "";
|
||||||
c.disabled = false;
|
d.style.display = "none";
|
||||||
cad.style.display = "none";
|
UI.updateSettingsState(false);
|
||||||
UI.settingsDisabled(false, rfb);
|
|
||||||
klass = "noVNC_status_normal";
|
klass = "noVNC_status_normal";
|
||||||
break;
|
break;
|
||||||
case 'password':
|
case 'password':
|
||||||
|
@ -325,15 +324,15 @@ updateState: function(rfb, state, oldstate, msg) {
|
||||||
$D('noVNC_connect_button').onclick = UI.setPassword;
|
$D('noVNC_connect_button').onclick = UI.setPassword;
|
||||||
$D('noVNC_password').focus();
|
$D('noVNC_password').focus();
|
||||||
|
|
||||||
c.disabled = false;
|
c.style.display = "none";
|
||||||
cad.style.display = "none";
|
d.style.display = "";
|
||||||
UI.settingsDisabled(true, rfb);
|
UI.updateSettingsState(false);
|
||||||
klass = "noVNC_status_warn";
|
klass = "noVNC_status_warn";
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
c.disabled = true;
|
c.style.display = "none";
|
||||||
cad.style.display = "none";
|
d.style.display = "";
|
||||||
UI.settingsDisabled(true, rfb);
|
UI.updateSettingsState(false);
|
||||||
klass = "noVNC_status_warn";
|
klass = "noVNC_status_warn";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -346,6 +345,40 @@ updateState: function(rfb, state, oldstate, msg) {
|
||||||
|
|
||||||
},
|
},
|
||||||
|
|
||||||
|
// Disable/enable controls depending on connection state
|
||||||
|
updateSettingsState: function(connected) {
|
||||||
|
|
||||||
|
//Util.Debug(">> updateSettingsState");
|
||||||
|
$D('noVNC_encrypt').disabled = connected;
|
||||||
|
$D('noVNC_true_color').disabled = connected;
|
||||||
|
if (UI.rfb && UI.rfb.get_display() &&
|
||||||
|
UI.rfb.get_display().get_cursor_uri()) {
|
||||||
|
$D('noVNC_cursor').disabled = connected;
|
||||||
|
} else {
|
||||||
|
UI.updateSetting('cursor', false);
|
||||||
|
$D('noVNC_cursor').disabled = true;
|
||||||
|
}
|
||||||
|
$D('noVNC_shared').disabled = connected;
|
||||||
|
$D('noVNC_connectTimeout').disabled = connected;
|
||||||
|
|
||||||
|
if (connected) {
|
||||||
|
UI.setViewClip();
|
||||||
|
UI.setMouseButton(1);
|
||||||
|
$D('sendCtrlAltDelButton').style.display = "inline";
|
||||||
|
$D('noVNC_view_drag_button').style.display = "inline";
|
||||||
|
} else {
|
||||||
|
UI.setMouseButton();
|
||||||
|
$D('sendCtrlAltDelButton').style.display = "none";
|
||||||
|
$D('noVNC_view_drag_button').style.display = "none";
|
||||||
|
}
|
||||||
|
|
||||||
|
// State change disables viewport dragging.
|
||||||
|
// It is enabled (toggled) by direct click on the button
|
||||||
|
UI.setViewDrag(false);
|
||||||
|
//Util.Debug("<< updateSettingsState");
|
||||||
|
},
|
||||||
|
|
||||||
|
|
||||||
clipReceive: function(rfb, text) {
|
clipReceive: function(rfb, text) {
|
||||||
Util.Debug(">> UI.clipReceive: " + text.substr(0,40) + "...");
|
Util.Debug(">> UI.clipReceive: " + text.substr(0,40) + "...");
|
||||||
$D('noVNC_clipboard_text').value = text;
|
$D('noVNC_clipboard_text').value = text;
|
||||||
|
@ -412,6 +445,7 @@ clipSend: function() {
|
||||||
showClipboard: function() {
|
showClipboard: function() {
|
||||||
//Close settings if open
|
//Close settings if open
|
||||||
if (UI.settingsOpen == true) {
|
if (UI.settingsOpen == true) {
|
||||||
|
UI.settingsApply();
|
||||||
UI.closeSettingsMenu();
|
UI.closeSettingsMenu();
|
||||||
}
|
}
|
||||||
//Close connection settings if open
|
//Close connection settings if open
|
||||||
|
@ -428,31 +462,66 @@ showClipboard: function() {
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
setViewClip: function(clip) {
|
||||||
|
var display, cur_clip, pos, new_w, new_h;
|
||||||
|
|
||||||
|
if (UI.rfb) {
|
||||||
|
display = UI.rfb.get_display();
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
cur_clip = display.get_viewport();
|
||||||
|
|
||||||
|
if (typeof(clip) === 'undefined') {
|
||||||
|
// Nothing
|
||||||
|
clip = UI.getSetting('clip');
|
||||||
|
}
|
||||||
|
|
||||||
|
if (clip && !cur_clip) {
|
||||||
|
// Turn clipping on
|
||||||
|
UI.updateSetting('clip', true);
|
||||||
|
} else if (!clip && cur_clip) {
|
||||||
|
// Turn clipping off
|
||||||
|
UI.updateSetting('clip', false);
|
||||||
|
display.set_viewport(false);
|
||||||
|
$D('noVNC_canvas').style.position = 'static';
|
||||||
|
display.viewportChange();
|
||||||
|
}
|
||||||
|
if (UI.getSetting('clip')) {
|
||||||
|
// If clipping, update clipping settings
|
||||||
|
$D('noVNC_canvas').style.position = 'absolute';
|
||||||
|
pos = Util.getPosition($D('noVNC_canvas'));
|
||||||
|
new_w = window.innerWidth - pos.x;
|
||||||
|
new_h = window.innerHeight - pos.y;
|
||||||
|
display.set_viewport(true);
|
||||||
|
display.viewportChange(0, 0, new_w, new_h);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
|
setViewDrag: function(drag) {
|
||||||
|
var vmb = $D('noVNC_view_drag_button');
|
||||||
|
if (!UI.rfb) { return; }
|
||||||
|
|
||||||
|
if (typeof(drag) === "undefined") {
|
||||||
|
// If not specified, then toggle
|
||||||
|
drag = !UI.rfb.get_viewportDrag();
|
||||||
|
}
|
||||||
|
if (drag) {
|
||||||
|
vmb.style.backgroundColor = "black";
|
||||||
|
vmb.style.color = "lightgray";
|
||||||
|
UI.rfb.set_viewportDrag(true);
|
||||||
|
} else {
|
||||||
|
vmb.style.backgroundColor = "";
|
||||||
|
vmb.style.color = "";
|
||||||
|
UI.rfb.set_viewportDrag(false);
|
||||||
|
}
|
||||||
|
},
|
||||||
|
|
||||||
showKeyboard: function() {
|
showKeyboard: function() {
|
||||||
//Get Current Scroll Position
|
|
||||||
var scrollx =
|
|
||||||
(document.all)?document.body.scrollLeft:window.pageXOffset;
|
|
||||||
var scrolly =
|
|
||||||
(document.all)?document.body.scrollTop:window.pageYOffset;
|
|
||||||
|
|
||||||
//Stop browser zooming on textbox.
|
|
||||||
UI.zoomDisable();
|
|
||||||
$D('keyboardinput').focus();
|
$D('keyboardinput').focus();
|
||||||
scroll(scrollx,scrolly);
|
|
||||||
//Renable user zoom.
|
|
||||||
UI.zoomEnable();
|
|
||||||
},
|
},
|
||||||
|
|
||||||
zoomDisable: function() {
|
|
||||||
//Change viewport meta data to disable zooming.
|
|
||||||
UI.changeViewportMeta("user-scalable=0");
|
|
||||||
},
|
|
||||||
|
|
||||||
zoomEnable: function(){
|
|
||||||
//Change viewport meta data to enable user zooming.
|
|
||||||
UI.changeViewportMeta("user-scalable=1");
|
|
||||||
},
|
|
||||||
|
|
||||||
changeViewportMeta: function (newattributes) {
|
changeViewportMeta: function (newattributes) {
|
||||||
|
|
||||||
|
@ -505,6 +574,7 @@ setBarPosition: function() {
|
||||||
connectPanelbutton: function() {
|
connectPanelbutton: function() {
|
||||||
//Close connection settings if open
|
//Close connection settings if open
|
||||||
if (UI.settingsOpen == true) {
|
if (UI.settingsOpen == true) {
|
||||||
|
UI.settingsApply();
|
||||||
UI.closeSettingsMenu();
|
UI.closeSettingsMenu();
|
||||||
}
|
}
|
||||||
if (UI.clipboardOpen == true) {
|
if (UI.clipboardOpen == true) {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
<!DOCTYPE html>
|
<!DOCTYPE html>
|
||||||
<html>
|
<html>
|
||||||
<head><title>Viewport Test</title>
|
<head><title>Viewport Test</title>
|
||||||
<link rel="stylesheet" href="../include/mobile.css">
|
<link rel="stylesheet" href="viewport.css">
|
||||||
<!--
|
<!--
|
||||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||||
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
<meta name="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
||||||
|
@ -166,23 +166,35 @@
|
||||||
"," + (p.offsetHeight - padH) + "]");
|
"," + (p.offsetHeight - padH) + "]");
|
||||||
display.viewportChange(0, 0,
|
display.viewportChange(0, 0,
|
||||||
p.offsetWidth - padW, p.offsetHeight - padH);
|
p.offsetWidth - padW, p.offsetHeight - padH);
|
||||||
|
/*
|
||||||
|
var pos, new_w, new_h;pos
|
||||||
|
pos = Util.getPosition($D('canvas').parentNode);
|
||||||
|
new_w = window.innerWidth - pos.x;
|
||||||
|
new_h = window.innerHeight - pos.y;
|
||||||
|
display.viewportChange(0, 0, new_w, new_h);
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
|
|
||||||
window.onload = function() {
|
window.onload = function() {
|
||||||
detectPad();
|
detectPad();
|
||||||
|
|
||||||
display = new Display({'target': $D('canvas')});
|
display = new Display({'target': $D('canvas')});
|
||||||
display.resize(1600, 1024);
|
display.resize(1600, 1024);
|
||||||
//display.resize(800, 600);
|
display.set_viewport(true);
|
||||||
ctx = display.get_context();
|
ctx = display.get_context();
|
||||||
|
|
||||||
mouse = new Mouse({'target': $D('canvas'),
|
mouse = new Mouse({'target': $D('canvas'),
|
||||||
'onMouseButton': mouseButton,
|
'onMouseButton': mouseButton,
|
||||||
'onMouseMove': mouseMove});
|
'onMouseMove': mouseMove});
|
||||||
|
mouse.grab();
|
||||||
|
|
||||||
|
|
||||||
Util.addEvent(window, 'resize', doResize);
|
Util.addEvent(window, 'resize', doResize);
|
||||||
//doResize();
|
// Shrink viewport for first resize call so that the
|
||||||
|
// scrollbars are disabled
|
||||||
|
display.viewportChange(0, 0, 10, 10);
|
||||||
setTimeout(doResize, 1);
|
setTimeout(doResize, 1);
|
||||||
setInterval(dirtyRedraw, 50);
|
setInterval(dirtyRedraw, 50);
|
||||||
mouse.grab();
|
|
||||||
|
|
||||||
message("Display initialized");
|
message("Display initialized");
|
||||||
};
|
};
|
||||||
|
|
82
vnc.html
|
@ -15,12 +15,19 @@
|
||||||
Remove this if you use the .htaccess -->
|
Remove this if you use the .htaccess -->
|
||||||
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
<meta http-equiv="X-UA-Compatible" content="IE=edge,chrome=1">
|
||||||
|
|
||||||
<meta name="viewport" content="user-scalable=1" />
|
<!-- Apple iOS Safari settings -->
|
||||||
|
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
|
||||||
<meta name="apple-mobile-web-app-capable" content="yes" />
|
<meta name="apple-mobile-web-app-capable" content="yes" />
|
||||||
|
<meta names="apple-mobile-web-app-status-bar-style" content="black-translucent" />
|
||||||
|
<!-- App Start Icon -->
|
||||||
|
<link rel="apple-touch-startup-image" href="images/screen_320x460.png" />
|
||||||
|
<!-- For iOS devices set the icon to use if user bookmarks app on their homescreen -->
|
||||||
|
<link rel="apple-touch-icon" href="images/screen_57x57.png">
|
||||||
<!--
|
<!--
|
||||||
<meta name="viewport" content="width=device-width,height=device-height" />
|
<link rel="apple-touch-icon-precomposed" href="images/screen_57x57.png" />
|
||||||
-->
|
-->
|
||||||
|
|
||||||
|
|
||||||
<!-- Stylesheets -->
|
<!-- Stylesheets -->
|
||||||
<link rel="stylesheet" href="include/base.css" />
|
<link rel="stylesheet" href="include/base.css" />
|
||||||
<link rel="alternate stylesheet" href="include/black.css" TITLE="Black" />
|
<link rel="alternate stylesheet" href="include/black.css" TITLE="Black" />
|
||||||
|
@ -28,13 +35,6 @@
|
||||||
|
|
||||||
<!-- Google web fonts -->
|
<!-- Google web fonts -->
|
||||||
<link href='http://fonts.googleapis.com/css?family=Yanone+Kaffeesatz|Nova+Square|Orbitron:400,500,700,900|Nova+Round|Nova+Mono|Nova+Slim|Nova+Oval|Nova+Flat|Nova+Cut' rel='stylesheet' type='text/css'>
|
<link href='http://fonts.googleapis.com/css?family=Yanone+Kaffeesatz|Nova+Square|Orbitron:400,500,700,900|Nova+Round|Nova+Mono|Nova+Slim|Nova+Oval|Nova+Flat|Nova+Cut' rel='stylesheet' type='text/css'>
|
||||||
<!-- App Start Icon -->
|
|
||||||
<link rel="apple-touch-startup-image" href="images/screen_640x435.png" />
|
|
||||||
|
|
||||||
<!-- For iOS devices set the icon to use if user bookmarks app on their homescreen -->
|
|
||||||
<link rel="apple-touch-icon" href="images/mobileicon.png">
|
|
||||||
<link rel="apple-touch-icon-precomposed" href="images/mobileicon.png" />
|
|
||||||
|
|
||||||
<!--
|
<!--
|
||||||
<script type='text/javascript'
|
<script type='text/javascript'
|
||||||
src='http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js'></script>
|
src='http://getfirebug.com/releases/lite/1.2/firebug-lite-compressed.js'></script>
|
||||||
|
@ -48,43 +48,60 @@
|
||||||
<body>
|
<body>
|
||||||
<div id="noVNC-control-bar">
|
<div id="noVNC-control-bar">
|
||||||
<!--noVNC Mobile Device only Buttons-->
|
<!--noVNC Mobile Device only Buttons-->
|
||||||
<div id="noVNC_mobile_buttons" class="noVNC-buttons-left">
|
<div class="noVNC-buttons-left">
|
||||||
<nobr>
|
<input type="image" src="images/move.png"
|
||||||
<span class="noVNC_mouse_buttons">
|
id="noVNC_view_drag_button" class="noVNC_status_button"
|
||||||
|
value="Move" title="Move/Drag Viewport"
|
||||||
|
onclick="UI.setViewDrag();">
|
||||||
|
<div id="noVNC_mobile_buttons">
|
||||||
<input type="button" class="noVNC_status_button"
|
<input type="button" class="noVNC_status_button"
|
||||||
id="noVNC_mouse_button1" value="L"
|
id="noVNC_mouse_button0" value=" "
|
||||||
onclick="UI.setMouseButton(1);">
|
onclick="UI.setMouseButton(1);">
|
||||||
<input type="button" class="noVNC_status_button"
|
<input type="button" class="noVNC_status_button"
|
||||||
id="noVNC_mouse_button2" value="M"
|
id="noVNC_mouse_button1" value="L"
|
||||||
onclick="UI.setMouseButton(2);">
|
onclick="UI.setMouseButton(2);">
|
||||||
<input type="button" class="noVNC_status_button"
|
<input type="button" class="noVNC_status_button"
|
||||||
id="noVNC_mouse_button4" value="R"
|
id="noVNC_mouse_button2" value="M"
|
||||||
onclick="UI.setMouseButton(4);">
|
onclick="UI.setMouseButton(4);">
|
||||||
<input type="button" id="showKeyboard"
|
<input type="button" class="noVNC_status_button"
|
||||||
value="Keyboard" class="noVNC_status_button"
|
id="noVNC_mouse_button4" value="R"
|
||||||
|
onclick="UI.setMouseButton(0);">
|
||||||
|
<input type="image" src="images/keyboard.png"
|
||||||
|
id="showKeyboard" class="noVNC_status_button"
|
||||||
|
value="Keyboard" title="Show Keyboard"
|
||||||
onclick="UI.showKeyboard()"/>
|
onclick="UI.showKeyboard()"/>
|
||||||
</span>
|
<input type="text"
|
||||||
</nobr>
|
id="keyboardinput" class="noVNC_status_button"
|
||||||
|
onKeyDown="onKeyDown(event);"/>
|
||||||
|
</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!--noVNC Buttons-->
|
<!--noVNC Buttons-->
|
||||||
<div class="noVNC-buttons-right">
|
<div class="noVNC-buttons-right">
|
||||||
<input type="button" class="noVNC_status_button"
|
<input type="button" class="noVNC_status_button"
|
||||||
value="CtrlAltDel" id="sendCtrlAltDelButton"
|
value="CtrlAltDel" id="sendCtrlAltDelButton"
|
||||||
onclick="UI.sendCtrlAltDel();">
|
onclick="UI.sendCtrlAltDel();" />
|
||||||
<input type="button" id="clipboardbutton" value="Clipboard"
|
<input type="image" src="images/clipboard.png"
|
||||||
onclick="UI.showClipboard();"/>
|
id="clipboardButton" class="noVNC_status_button"
|
||||||
<input type="button" class="noVNC_status_button"
|
value="Clipboard" title="Clipboard"
|
||||||
value="Settings" id="menuButton"
|
onclick="UI.showClipboard();" />
|
||||||
onclick="UI.clickSettingsMenu();">
|
<input type="image" src="images/settings.png"
|
||||||
<input type="button" id="connectPanelbutton"
|
id="menuButton" class="noVNC_status_button"
|
||||||
value="Connection" class="noVNC_status_button"
|
value="Settings" title="Settings"
|
||||||
|
onclick="UI.clickSettingsMenu();" />
|
||||||
|
<input type="image" src="images/connect.png"
|
||||||
|
id="connectPanelbutton" class="noVNC_status_button"
|
||||||
|
value="Connect" title="Connect"
|
||||||
onclick="UI.connectPanelbutton()" />
|
onclick="UI.connectPanelbutton()" />
|
||||||
|
<input type="image" src="images/disconnect.png"
|
||||||
|
id="disconnectButton" class="noVNC_status_button"
|
||||||
|
value="Disconnect" title="Disconnect"
|
||||||
|
onclick="UI.disconnect()" />
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Clipboard Panel -->
|
<!-- Clipboard Panel -->
|
||||||
<div id="noVNC_clipboard" class="triangle-right top">
|
<div id="noVNC_clipboard" class="triangle-right top">
|
||||||
<textarea id="noVNC_clipboard_text" cols=88 rows=5
|
<textarea id="noVNC_clipboard_text" rows=5
|
||||||
onfocus="UI.displayBlur();" onblur="UI.displayFocus();"
|
onfocus="UI.displayBlur();" onblur="UI.displayFocus();"
|
||||||
onchange="UI.clipSend();">
|
onchange="UI.clipSend();">
|
||||||
</textarea>
|
</textarea>
|
||||||
|
@ -94,13 +111,14 @@
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- Settings Panel -->
|
<!-- Settings Panel -->
|
||||||
<div id="noVNC_Settings" class="triangle-right top">
|
<div id="noVNC_settings" class="triangle-right top">
|
||||||
<span id="noVNC_settings_menu" onmouseover="UI.displayBlur();"
|
<span id="noVNC_settings_menu" onmouseover="UI.displayBlur();"
|
||||||
onmouseout="UI.displayFocus();">
|
onmouseout="UI.displayFocus();">
|
||||||
<ul>
|
<ul>
|
||||||
<li><input id="noVNC_encrypt" type="checkbox"> Encrypt</li>
|
<li><input id="noVNC_encrypt" type="checkbox"> Encrypt</li>
|
||||||
<li><input id="noVNC_true_color" type="checkbox" checked> True Color</li>
|
<li><input id="noVNC_true_color" type="checkbox" checked> True Color</li>
|
||||||
<li><input id="noVNC_cursor" type="checkbox"> Local Cursor</li>
|
<li><input id="noVNC_cursor" type="checkbox"> Local Cursor</li>
|
||||||
|
<li><input id="noVNC_clip" type="checkbox"> Clip to window</li>
|
||||||
<li><input id="noVNC_shared" type="checkbox"> Shared Mode</li>
|
<li><input id="noVNC_shared" type="checkbox"> Shared Mode</li>
|
||||||
<li><input id="noVNC_connectTimeout" type="input"> Connect Timeout (s)</li>
|
<li><input id="noVNC_connectTimeout" type="input"> Connect Timeout (s)</li>
|
||||||
<hr>
|
<hr>
|
||||||
|
@ -143,13 +161,15 @@
|
||||||
<div id="noVNC_status">Loading</div>
|
<div id="noVNC_status">Loading</div>
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<!-- HTML5 Canvas -->
|
|
||||||
<h1 id="noVNC_logo"><span>no</span><br />VNC</h1>
|
<h1 id="noVNC_logo"><span>no</span><br />VNC</h1>
|
||||||
|
|
||||||
|
<!-- HTML5 Canvas -->
|
||||||
|
<div id="noVNC_container">
|
||||||
<canvas id="noVNC_canvas" width="640px" height="20px">
|
<canvas id="noVNC_canvas" width="640px" height="20px">
|
||||||
Canvas not supported.
|
Canvas not supported.
|
||||||
</canvas>
|
</canvas>
|
||||||
|
</div>
|
||||||
|
|
||||||
<input id="keyboardinput" type="text" onKeyDown="onKeyDown(event);"/>
|
|
||||||
</div>
|
</div>
|
||||||
|
|
||||||
<script>
|
<script>
|
||||||
|
|