Skip to content
Projects
Groups
Snippets
Help
Loading...
Help
Contribute to GitLab
Sign in
Toggle navigation
N
noVNC
Project
Project
Details
Activity
Cycle Analytics
Repository
Repository
Files
Commits
Branches
Tags
Contributors
Graph
Compare
Charts
Issues
0
Issues
0
List
Board
Labels
Milestones
Merge Requests
0
Merge Requests
0
CI / CD
CI / CD
Pipelines
Jobs
Schedules
Charts
Wiki
Wiki
Members
Members
Collapse sidebar
Close sidebar
Activity
Graph
Charts
Create a new issue
Jobs
Commits
Issue Boards
Open sidebar
rasky
noVNC
Commits
205d1a11
Commit
205d1a11
authored
Mar 05, 2015
by
Samuel
Browse files
Options
Browse Files
Download
Plain Diff
Merge pull request #451 from kanaka/feature/scaling
Introduce Local Autoscaling
parents
7e161007
72747869
Changes
5
Show whitespace changes
Inline
Side-by-side
Showing
5 changed files
with
180 additions
and
41 deletions
+180
-41
display.js
include/display.js
+35
-25
ui.js
include/ui.js
+51
-12
util.js
include/util.js
+7
-3
test.display.js
tests/test.display.js
+78
-0
vnc.html
vnc.html
+9
-1
No files found.
include/display.js
View file @
205d1a11
...
@@ -518,38 +518,48 @@ var Display;
...
@@ -518,38 +518,48 @@ var Display;
return
this
.
_fb_height
;
return
this
.
_fb_height
;
},
},
// Private Methods
autoscale
:
function
(
containerWidth
,
containerHeight
,
downscaleOnly
)
{
_rescale
:
function
(
factor
)
{
var
targetAspectRatio
=
containerWidth
/
containerHeight
;
var
canvas
=
this
.
_target
;
var
fbAspectRatio
=
this
.
_fb_width
/
this
.
_fb_height
;
var
properties
=
[
'transform'
,
'WebkitTransform'
,
'MozTransform'
];
var
transform_prop
;
while
((
transform_prop
=
properties
.
shift
()))
{
if
(
typeof
canvas
.
style
[
transform_prop
]
!==
'undefined'
)
{
break
;
}
}
if
(
transform_prop
===
null
)
{
var
scaleRatio
;
Util
.
Debug
(
"No scaling support"
);
if
(
fbAspectRatio
>=
targetAspectRatio
)
{
return
;
scaleRatio
=
containerWidth
/
this
.
_fb_width
;
}
else
{
scaleRatio
=
containerHeight
/
this
.
_fb_height
;
}
}
if
(
typeof
(
factor
)
===
"undefined"
)
{
var
targetW
,
targetH
;
factor
=
this
.
_scale
;
if
(
scaleRatio
>
1.0
&&
downscaleOnly
)
{
}
else
if
(
factor
>
1.0
)
{
targetW
=
this
.
_fb_width
;
factor
=
1.0
;
targetH
=
this
.
_fb_height
;
}
else
if
(
factor
<
0.1
)
{
scaleRatio
=
1.0
;
factor
=
0.1
;
}
else
if
(
fbAspectRatio
>=
targetAspectRatio
)
{
targetW
=
containerWidth
;
targetH
=
Math
.
round
(
containerWidth
/
fbAspectRatio
);
}
else
{
targetW
=
Math
.
round
(
containerHeight
*
fbAspectRatio
);
targetH
=
containerHeight
;
}
}
if
(
this
.
_scale
===
factor
)
{
// NB(directxman12): If you set the width directly, or set the
return
;
// style width to a number, the canvas is cleared.
}
// However, if you set the style width to a string
// ('NNNpx'), the canvas is scaled without clearing.
this
.
_target
.
style
.
width
=
targetW
+
'px'
;
this
.
_target
.
style
.
height
=
targetH
+
'px'
;
this
.
_scale
=
scaleRatio
;
return
scaleRatio
;
// so that the mouse, etc scale can be set
},
// Private Methods
_rescale
:
function
(
factor
)
{
this
.
_scale
=
factor
;
this
.
_scale
=
factor
;
var
x
=
canvas
.
width
-
(
canvas
.
width
*
factor
);
var
y
=
canvas
.
height
-
(
canvas
.
height
*
factor
)
;
this
.
_target
.
style
.
width
=
Math
.
round
(
factor
*
this
.
_fb_width
)
+
'px'
;
canvas
.
style
[
transform_prop
]
=
'scale('
+
this
.
_scale
+
') translate(-'
+
x
+
'px, -'
+
y
+
'px)
'
;
this
.
_target
.
style
.
height
=
Math
.
round
(
factor
*
this
.
_fb_height
)
+
'px
'
;
},
},
_setFillColor
:
function
(
color
)
{
_setFillColor
:
function
(
color
)
{
...
...
include/ui.js
View file @
205d1a11
...
@@ -46,15 +46,29 @@ var UI;
...
@@ -46,15 +46,29 @@ var UI;
},
},
onresize
:
function
(
callback
)
{
onresize
:
function
(
callback
)
{
if
(
UI
.
getSetting
(
'resize'
))
{
var
innerW
=
window
.
innerWidth
;
var
innerW
=
window
.
innerWidth
;
var
innerH
=
window
.
innerHeight
;
var
innerH
=
window
.
innerHeight
;
var
controlbarH
=
$D
(
'noVNC-control-bar'
).
offsetHeight
;
var
controlbarH
=
$D
(
'noVNC-control-bar'
).
offsetHeight
;
// For some unknown reason the container is higher than the canvas,
// For some unknown reason the container is higher than the canvas,
// 5px higher in Firefox and 4px higher in Chrome
// 5px higher in Firefox and 4px higher in Chrome
var
padding
=
5
;
var
padding
=
5
;
if
(
innerW
!==
undefined
&&
innerH
!==
undefined
)
var
effectiveH
=
innerH
-
controlbarH
-
padding
;
UI
.
rfb
.
setDesktopSize
(
innerW
,
innerH
-
controlbarH
-
padding
);
var
display
=
UI
.
rfb
.
get_display
();
if
(
innerW
!==
undefined
&&
innerH
!==
undefined
)
{
var
scaleType
=
UI
.
getSetting
(
'resize'
);
if
(
scaleType
===
'remote'
)
{
// use remote resizing
Util
.
Debug
(
'Attempting setDesktopSize('
+
innerW
+
', '
+
effectiveH
+
')'
);
UI
.
rfb
.
setDesktopSize
(
innerW
,
effectiveH
);
}
else
if
(
scaleType
===
'scale'
||
scaleType
===
'downscale'
)
{
// use local scaling
var
downscaleOnly
=
scaleType
===
'downscale'
;
var
scaleRatio
=
display
.
autoscale
(
innerW
,
effectiveH
,
downscaleOnly
);
UI
.
rfb
.
get_mouse
().
set_scale
(
scaleRatio
);
Util
.
Debug
(
'Scaling by '
+
UI
.
rfb
.
get_mouse
().
get_scale
());
}
}
}
},
},
...
@@ -104,7 +118,7 @@ var UI;
...
@@ -104,7 +118,7 @@ var UI;
UI
.
initSetting
(
'encrypt'
,
(
window
.
location
.
protocol
===
"https:"
));
UI
.
initSetting
(
'encrypt'
,
(
window
.
location
.
protocol
===
"https:"
));
UI
.
initSetting
(
'true_color'
,
true
);
UI
.
initSetting
(
'true_color'
,
true
);
UI
.
initSetting
(
'cursor'
,
!
UI
.
isTouchDevice
);
UI
.
initSetting
(
'cursor'
,
!
UI
.
isTouchDevice
);
UI
.
initSetting
(
'resize'
,
false
);
UI
.
initSetting
(
'resize'
,
'off'
);
UI
.
initSetting
(
'shared'
,
true
);
UI
.
initSetting
(
'shared'
,
true
);
UI
.
initSetting
(
'view_only'
,
false
);
UI
.
initSetting
(
'view_only'
,
false
);
UI
.
initSetting
(
'path'
,
'websockify'
);
UI
.
initSetting
(
'path'
,
'websockify'
);
...
@@ -237,6 +251,11 @@ var UI;
...
@@ -237,6 +251,11 @@ var UI;
$D
(
"noVNC_apply"
).
onclick
=
UI
.
settingsApply
;
$D
(
"noVNC_apply"
).
onclick
=
UI
.
settingsApply
;
$D
(
"noVNC_connect_button"
).
onclick
=
UI
.
connect
;
$D
(
"noVNC_connect_button"
).
onclick
=
UI
.
connect
;
$D
(
"noVNC_resize"
).
onchange
=
function
()
{
var
connected
=
UI
.
rfb_state
===
'normal'
?
true
:
false
;
UI
.
enableDisableClip
(
connected
);
};
},
},
// Read form control compatible setting from cookie
// Read form control compatible setting from cookie
...
@@ -510,8 +529,14 @@ var UI;
...
@@ -510,8 +529,14 @@ var UI;
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
(
'resize'
);
UI
.
saveSetting
(
'resize'
);
if
(
UI
.
getSetting
(
'resize'
)
===
'downscale'
||
UI
.
getSetting
(
'resize'
)
===
'scale'
)
{
UI
.
forceSetting
(
'clip'
,
false
);
}
UI
.
saveSetting
(
'clip'
);
UI
.
saveSetting
(
'shared'
);
UI
.
saveSetting
(
'shared'
);
UI
.
saveSetting
(
'view_only'
);
UI
.
saveSetting
(
'view_only'
);
UI
.
saveSetting
(
'path'
);
UI
.
saveSetting
(
'path'
);
...
@@ -635,7 +660,8 @@ var UI;
...
@@ -635,7 +660,8 @@ var UI;
UI
.
updateSetting
(
'cursor'
,
!
UI
.
isTouchDevice
);
UI
.
updateSetting
(
'cursor'
,
!
UI
.
isTouchDevice
);
$D
(
'noVNC_cursor'
).
disabled
=
true
;
$D
(
'noVNC_cursor'
).
disabled
=
true
;
}
}
$D
(
'noVNC_clip'
).
disabled
=
connected
||
UI
.
isTouchDevice
;
UI
.
enableDisableClip
(
connected
);
$D
(
'noVNC_resize'
).
disabled
=
connected
;
$D
(
'noVNC_resize'
).
disabled
=
connected
;
$D
(
'noVNC_shared'
).
disabled
=
connected
;
$D
(
'noVNC_shared'
).
disabled
=
connected
;
$D
(
'noVNC_view_only'
).
disabled
=
connected
;
$D
(
'noVNC_view_only'
).
disabled
=
connected
;
...
@@ -697,6 +723,19 @@ var UI;
...
@@ -697,6 +723,19 @@ var UI;
}
}
},
},
enableDisableClip
:
function
(
connected
)
{
var
resizeElem
=
$D
(
'noVNC_resize'
);
if
(
resizeElem
.
value
===
'downscale'
||
resizeElem
.
value
===
'scale'
)
{
UI
.
forceSetting
(
'clip'
,
false
);
$D
(
'noVNC_clip'
).
disabled
=
true
;
}
else
{
$D
(
'noVNC_clip'
).
disabled
=
connected
||
UI
.
isTouchDevice
;
if
(
UI
.
isTouchDevice
)
{
UI
.
forceSetting
(
'clip'
,
true
);
}
}
},
// This resize can not be done until we know from the first Frame Buffer Update
// This resize can not be done until we know from the first Frame Buffer Update
// if it is supported or not.
// if it is supported or not.
// The resize is needed to make sure the server desktop size is updated to the
// The resize is needed to make sure the server desktop size is updated to the
...
...
include/util.js
View file @
205d1a11
...
@@ -435,8 +435,12 @@ Util.load_scripts = function (files) {
...
@@ -435,8 +435,12 @@ Util.load_scripts = function (files) {
Util
.
getPosition
=
function
(
obj
)
{
Util
.
getPosition
=
function
(
obj
)
{
"use strict"
;
"use strict"
;
// NB(sross): the Mozilla developer reference seems to indicate that
// getBoundingClientRect includes border and padding, so the canvas
// style should NOT include either.
var
objPosition
=
obj
.
getBoundingClientRect
();
var
objPosition
=
obj
.
getBoundingClientRect
();
return
{
'x'
:
objPosition
.
left
+
window
.
pageXOffset
,
'y'
:
objPosition
.
top
+
window
.
pageYOffset
};
return
{
'x'
:
objPosition
.
left
+
window
.
pageXOffset
,
'y'
:
objPosition
.
top
+
window
.
pageYOffset
,
'width'
:
objPosition
.
width
,
'height'
:
objPosition
.
height
};
};
};
...
@@ -462,8 +466,8 @@ Util.getEventPosition = function (e, obj, scale) {
...
@@ -462,8 +466,8 @@ Util.getEventPosition = function (e, obj, scale) {
}
}
var
realx
=
docX
-
pos
.
x
;
var
realx
=
docX
-
pos
.
x
;
var
realy
=
docY
-
pos
.
y
;
var
realy
=
docY
-
pos
.
y
;
var
x
=
Math
.
max
(
Math
.
min
(
realx
,
obj
.
width
-
1
),
0
);
var
x
=
Math
.
max
(
Math
.
min
(
realx
,
pos
.
width
-
1
),
0
);
var
y
=
Math
.
max
(
Math
.
min
(
realy
,
obj
.
height
-
1
),
0
);
var
y
=
Math
.
max
(
Math
.
min
(
realy
,
pos
.
height
-
1
),
0
);
return
{
'x'
:
x
/
scale
,
'y'
:
y
/
scale
,
'realx'
:
realx
/
scale
,
'realy'
:
realy
/
scale
};
return
{
'x'
:
x
/
scale
,
'y'
:
y
/
scale
,
'realx'
:
realx
/
scale
,
'realy'
:
realy
/
scale
};
};
};
...
...
tests/test.display.js
View file @
205d1a11
...
@@ -154,6 +154,84 @@ describe('Display/Canvas Helper', function () {
...
@@ -154,6 +154,84 @@ describe('Display/Canvas Helper', function () {
});
});
});
});
describe
(
'rescaling'
,
function
()
{
var
display
;
var
canvas
;
beforeEach
(
function
()
{
display
=
new
Display
({
target
:
document
.
createElement
(
'canvas'
),
prefer_js
:
false
,
viewport
:
true
});
display
.
resize
(
4
,
3
);
canvas
=
display
.
get_target
();
document
.
body
.
appendChild
(
canvas
);
});
afterEach
(
function
()
{
document
.
body
.
removeChild
(
canvas
);
});
it
(
'should not change the bitmap size of the canvas'
,
function
()
{
display
.
set_scale
(
0.5
);
expect
(
canvas
.
width
).
to
.
equal
(
4
);
expect
(
canvas
.
height
).
to
.
equal
(
3
);
});
it
(
'should change the effective rendered size of the canvas'
,
function
()
{
display
.
set_scale
(
0.5
);
expect
(
canvas
.
clientWidth
).
to
.
equal
(
2
);
expect
(
canvas
.
clientHeight
).
to
.
equal
(
2
);
});
});
describe
(
'autoscaling'
,
function
()
{
var
display
;
var
canvas
;
beforeEach
(
function
()
{
display
=
new
Display
({
target
:
document
.
createElement
(
'canvas'
),
prefer_js
:
false
,
viewport
:
true
});
display
.
resize
(
4
,
3
);
canvas
=
display
.
get_target
();
document
.
body
.
appendChild
(
canvas
);
});
afterEach
(
function
()
{
document
.
body
.
removeChild
(
canvas
);
});
it
(
'should preserve aspect ratio while autoscaling'
,
function
()
{
display
.
autoscale
(
16
,
9
);
expect
(
canvas
.
clientWidth
/
canvas
.
clientHeight
).
to
.
equal
(
4
/
3
);
});
it
(
'should use width to determine scale when the current aspect ratio is wider than the target'
,
function
()
{
expect
(
display
.
autoscale
(
9
,
16
)).
to
.
equal
(
9
/
4
);
expect
(
canvas
.
clientWidth
).
to
.
equal
(
9
);
expect
(
canvas
.
clientHeight
).
to
.
equal
(
7
);
// round 9 / (4 / 3)
});
it
(
'should use height to determine scale when the current aspect ratio is taller than the target'
,
function
()
{
expect
(
display
.
autoscale
(
16
,
9
)).
to
.
equal
(
3
);
// 9 / 3
expect
(
canvas
.
clientWidth
).
to
.
equal
(
12
);
// 16 * (4 / 3)
expect
(
canvas
.
clientHeight
).
to
.
equal
(
9
);
});
it
(
'should not change the bitmap size of the canvas'
,
function
()
{
display
.
autoscale
(
16
,
9
);
expect
(
canvas
.
width
).
to
.
equal
(
4
);
expect
(
canvas
.
height
).
to
.
equal
(
3
);
});
it
(
'should not upscale when downscaleOnly is true'
,
function
()
{
expect
(
display
.
autoscale
(
2
,
2
,
true
)).
to
.
equal
(
0.5
);
expect
(
canvas
.
clientWidth
).
to
.
equal
(
2
);
expect
(
canvas
.
clientHeight
).
to
.
equal
(
2
);
expect
(
display
.
autoscale
(
16
,
9
,
true
)).
to
.
equal
(
1.0
);
expect
(
canvas
.
clientWidth
).
to
.
equal
(
4
);
expect
(
canvas
.
clientHeight
).
to
.
equal
(
3
);
});
});
describe
(
'drawing'
,
function
()
{
describe
(
'drawing'
,
function
()
{
// TODO(directxman12): improve the tests for each of the drawing functions to cover more than just the
// TODO(directxman12): improve the tests for each of the drawing functions to cover more than just the
...
...
vnc.html
View file @
205d1a11
...
@@ -157,10 +157,18 @@
...
@@ -157,10 +157,18 @@
<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_clip"
type=
"checkbox"
>
Clip to Window
</li>
<li><input
id=
"noVNC_resize"
type=
"checkbox"
>
Resize Remote 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_view_only"
type=
"checkbox"
>
View Only
</li>
<li><input
id=
"noVNC_view_only"
type=
"checkbox"
>
View Only
</li>
<hr>
<li><input
id=
"noVNC_path"
type=
"input"
value=
"websockify"
>
Path
</li>
<li><input
id=
"noVNC_path"
type=
"input"
value=
"websockify"
>
Path
</li>
<li><label>
<select
id=
"noVNC_resize"
name=
"vncResize"
>
<option
value=
"off"
>
None
</option>
<option
value=
"scale"
>
Local Scaling
</option>
<option
value=
"downscale"
>
Local Downscaling
</option>
<option
value=
"remote"
>
Remote Resizing
</option>
</select>
Scaling Mode
</label>
</li>
<li><input
id=
"noVNC_repeaterID"
type=
"input"
value=
""
>
Repeater ID
</li>
<li><input
id=
"noVNC_repeaterID"
type=
"input"
value=
""
>
Repeater ID
</li>
<hr>
<hr>
<!-- Stylesheet selection dropdown -->
<!-- Stylesheet selection dropdown -->
...
...
Write
Preview
Markdown
is supported
0%
Try again
or
attach a new file
Attach a file
Cancel
You are about to add
0
people
to the discussion. Proceed with caution.
Finish editing this message first!
Cancel
Please
register
or
sign in
to comment