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
1db6fd83
Commit
1db6fd83
authored
Oct 11, 2014
by
Alexander Clouter
Committed by
Solly Ross
Feb 10, 2015
Browse files
Options
Browse Files
Download
Email Patches
Plain Diff
added aten-ikvm support
parent
729508a2
Changes
4
Show whitespace changes
Inline
Side-by-side
Showing
4 changed files
with
493 additions
and
2 deletions
+493
-2
README.md
README.md
+1
-1
keysym.js
include/keysym.js
+77
-0
rfb.js
include/rfb.js
+263
-1
test.rfb.js
tests/test.rfb.js
+152
-0
No files found.
README.md
View file @
1db6fd83
...
@@ -128,7 +128,7 @@ use a WebSockets to TCP socket proxy. There is a python proxy included
...
@@ -128,7 +128,7 @@ use a WebSockets to TCP socket proxy. There is a python proxy included
*
UI and Icons : Chris Gordon
*
UI and Icons : Chris Gordon
*
Original Logo : Michael Sersen
*
Original Logo : Michael Sersen
*
tight encoding : Michael Tinglof (Mercuri.ca)
*
tight encoding : Michael Tinglof (Mercuri.ca)
*
pixel format conversion :
[
Alexander Clouter
](
http://www.digriz.org.uk/
)
*
pixel format conversion
and ATEN iKVM support
:
[
Alexander Clouter
](
http://www.digriz.org.uk/
)
*
Included libraries:
*
Included libraries:
*
web-socket-js : Hiroshi Ichikawa (github.com/gimite/web-socket-js)
*
web-socket-js : Hiroshi Ichikawa (github.com/gimite/web-socket-js)
...
...
include/keysym.js
View file @
1db6fd83
...
@@ -376,3 +376,80 @@ XK_udiaeresis = 0x00fc, /* U+00FC LATIN SMALL LETTER U WITH DIA
...
@@ -376,3 +376,80 @@ XK_udiaeresis = 0x00fc, /* U+00FC LATIN SMALL LETTER U WITH DIA
XK_yacute
=
0x00fd
,
/* U+00FD LATIN SMALL LETTER Y WITH ACUTE */
XK_yacute
=
0x00fd
,
/* U+00FD LATIN SMALL LETTER Y WITH ACUTE */
XK_thorn
=
0x00fe
,
/* U+00FE LATIN SMALL LETTER THORN */
XK_thorn
=
0x00fe
,
/* U+00FE LATIN SMALL LETTER THORN */
XK_ydiaeresis
=
0x00ff
;
/* U+00FF LATIN SMALL LETTER Y WITH DIAERESIS */
XK_ydiaeresis
=
0x00ff
;
/* U+00FF LATIN SMALL LETTER Y WITH DIAERESIS */
var
XK2HID
=
{};
// F{1..12}
for
(
var
i
=
XK_F1
;
i
<=
XK_F12
;
i
++
)
{
XK2HID
[
i
]
=
0x3a
+
(
i
-
XK_F1
);
}
// A-Za-z
for
(
var
i
=
XK_A
;
i
<=
XK_Z
;
i
++
)
{
XK2HID
[
i
]
=
0x04
+
(
i
-
XK_A
);
XK2HID
[
i
+
(
XK_a
-
XK_A
)]
=
0x04
+
(
i
-
XK_A
);
}
// 1-9
for
(
var
i
=
XK_1
;
i
<=
XK_9
;
i
++
)
{
XK2HID
[
i
]
=
0x1e
+
(
i
-
XK_1
);
}
XK2HID
[
XK_0
]
=
0x27
;
XK2HID
[
XK_Return
]
=
0x28
;
XK2HID
[
XK_Escape
]
=
0x29
;
XK2HID
[
XK_BackSpace
]
=
0x2a
;
XK2HID
[
XK_Tab
]
=
0x2b
;
XK2HID
[
XK_space
]
=
0x2c
;
XK2HID
[
XK_minus
]
=
0x2d
;
XK2HID
[
XK_equal
]
=
0x2e
;
XK2HID
[
XK_bracketleft
]
=
0x2f
;
XK2HID
[
XK_bracketright
]
=
0x30
;
XK2HID
[
XK_backslash
]
=
0x31
;
XK2HID
[
XK_semicolon
]
=
0x33
;
XK2HID
[
XK_apostrophe
]
=
0x34
;
XK2HID
[
XK_grave
]
=
0x35
;
XK2HID
[
XK_comma
]
=
0x36
;
XK2HID
[
XK_period
]
=
0x37
;
XK2HID
[
XK_slash
]
=
0x38
;
XK2HID
[
XK_Print
]
=
0x46
;
XK2HID
[
XK_Scroll_Lock
]
=
0x47
;
XK2HID
[
XK_Pause
]
=
0x48
;
XK2HID
[
XK_Insert
]
=
0x49
;
XK2HID
[
XK_Home
]
=
0x4a
;
XK2HID
[
XK_Page_Up
]
=
0x4b
;
XK2HID
[
XK_Delete
]
=
0x4c
;
XK2HID
[
XK_End
]
=
0x4d
;
XK2HID
[
XK_Page_Down
]
=
0x4e
;
XK2HID
[
XK_Right
]
=
0x4f
;
XK2HID
[
XK_Left
]
=
0x50
;
XK2HID
[
XK_Down
]
=
0x51
;
XK2HID
[
XK_Up
]
=
0x52
;
XK2HID
[
XK_Control_L
]
=
0xe0
;
XK2HID
[
XK_Control_R
]
=
XK2HID
[
XK_Control_L
];
XK2HID
[
XK_Shift_L
]
=
0xe1
;
XK2HID
[
XK_Shift_R
]
=
XK2HID
[
XK_Shift_L
];
XK2HID
[
XK_Alt_L
]
=
0xe2
;
XK2HID
[
XK_Alt_R
]
=
XK2HID
[
XK_Alt_L
];
XK2HID
[
XK_Super_L
]
=
0xe3
;
XK2HID
[
XK_Super_R
]
=
XK2HID
[
XK_Super_L
];
XK2HID
[
XK_Caps_Lock
]
=
0x39
;
// locale hardcoded hack
XK2HID
[
XK_less
]
=
XK2HID
[
XK_comma
];
XK2HID
[
XK_greater
]
=
XK2HID
[
XK_period
];
XK2HID
[
XK_exclam
]
=
XK2HID
[
XK_1
];
XK2HID
[
XK_at
]
=
XK2HID
[
XK_2
];
XK2HID
[
XK_numbersign
]
=
XK2HID
[
XK_3
];
XK2HID
[
XK_dollar
]
=
XK2HID
[
XK_4
];
XK2HID
[
XK_percent
]
=
XK2HID
[
XK_5
];
XK2HID
[
XK_asciicircum
]
=
XK2HID
[
XK_6
];
XK2HID
[
XK_ampersand
]
=
XK2HID
[
XK_7
];
XK2HID
[
XK_asterisk
]
=
XK2HID
[
XK_8
];
XK2HID
[
XK_parenleft
]
=
XK2HID
[
XK_9
];
XK2HID
[
XK_parenright
]
=
XK2HID
[
XK_0
];
XK2HID
[
XK_underscore
]
=
XK2HID
[
XK_minus
];
XK2HID
[
XK_bar
]
=
XK2HID
[
XK_backslash
];
XK2HID
[
XK_quotedbl
]
=
XK2HID
[
XK_apostrophe
];
XK2HID
[
XK_asciitilde
]
=
XK2HID
[
XK_grave
];
include/rfb.js
View file @
1db6fd83
...
@@ -33,6 +33,7 @@ var RFB;
...
@@ -33,6 +33,7 @@ var RFB;
this
.
_rfb_auth_scheme
=
''
;
this
.
_rfb_auth_scheme
=
''
;
this
.
_rfb_tightvnc
=
false
;
this
.
_rfb_tightvnc
=
false
;
this
.
_rfb_atenikvm
=
false
;
this
.
_rfb_xvp_ver
=
0
;
this
.
_rfb_xvp_ver
=
0
;
// In preference order
// In preference order
...
@@ -43,6 +44,7 @@ var RFB;
...
@@ -43,6 +44,7 @@ var RFB;
[
'HEXTILE'
,
0x05
],
[
'HEXTILE'
,
0x05
],
[
'RRE'
,
0x02
],
[
'RRE'
,
0x02
],
[
'RAW'
,
0x00
],
[
'RAW'
,
0x00
],
[
'ATEN'
,
0x59
],
[
'DesktopSize'
,
-
223
],
[
'DesktopSize'
,
-
223
],
[
'Cursor'
,
-
239
],
[
'Cursor'
,
-
239
],
...
@@ -74,6 +76,8 @@ var RFB;
...
@@ -74,6 +76,8 @@ var RFB;
subrects
:
0
,
// RRE
subrects
:
0
,
// RRE
lines
:
0
,
// RAW
lines
:
0
,
// RAW
tiles
:
0
,
// HEXTILE
tiles
:
0
,
// HEXTILE
aten_len
:
-
1
,
// ATEN
aten_type
:
-
1
,
// ATEN
bytes
:
0
,
bytes
:
0
,
x
:
0
,
x
:
0
,
y
:
0
,
y
:
0
,
...
@@ -120,6 +124,7 @@ var RFB;
...
@@ -120,6 +124,7 @@ var RFB;
'local_cursor'
:
false
,
// Request locally rendered cursor
'local_cursor'
:
false
,
// Request locally rendered cursor
'shared'
:
true
,
// Request shared mode
'shared'
:
true
,
// Request shared mode
'view_only'
:
false
,
// Disable client mouse/keyboard
'view_only'
:
false
,
// Disable client mouse/keyboard
'aten_password_sep'
:
':'
,
// Separator for ATEN iKVM password fields
'xvp_password_sep'
:
'@'
,
// Separator for XVP password fields
'xvp_password_sep'
:
'@'
,
// Separator for XVP password fields
'disconnectTimeout'
:
3
,
// Time (s) to wait for disconnection
'disconnectTimeout'
:
3
,
// Time (s) to wait for disconnection
'wsProtocols'
:
[
'binary'
,
'base64'
],
// Protocols to use in the WebSocket connection
'wsProtocols'
:
[
'binary'
,
'base64'
],
// Protocols to use in the WebSocket connection
...
@@ -329,9 +334,12 @@ var RFB;
...
@@ -329,9 +334,12 @@ var RFB;
this
.
_FBU
.
lines
=
0
;
// RAW
this
.
_FBU
.
lines
=
0
;
// RAW
this
.
_FBU
.
tiles
=
0
;
// HEXTILE
this
.
_FBU
.
tiles
=
0
;
// HEXTILE
this
.
_FBU
.
zlibs
=
[];
// TIGHT zlib encoders
this
.
_FBU
.
zlibs
=
[];
// TIGHT zlib encoders
this
.
_FBU
.
aten_len
=
-
1
;
// ATEN
this
.
_FBU
.
aten_type
=
-
1
;
// ATEN
this
.
_mouse_buttonMask
=
0
;
this
.
_mouse_buttonMask
=
0
;
this
.
_mouse_arr
=
[];
this
.
_mouse_arr
=
[];
this
.
_rfb_tightvnc
=
false
;
this
.
_rfb_tightvnc
=
false
;
this
.
_rfb_atenikvm
=
false
;
// Clear the per connection encoding stats
// Clear the per connection encoding stats
var
i
;
var
i
;
...
@@ -683,6 +691,36 @@ var RFB;
...
@@ -683,6 +691,36 @@ var RFB;
},
},
// authentication
// authentication
_negotiate_aten_auth
:
function
()
{
var
aten_sep
=
this
.
_aten_password_sep
;
var
aten_auth
=
this
.
_rfb_password
.
split
(
aten_sep
);
if
(
aten_auth
.
length
<
2
)
{
this
.
_updateState
(
'password'
,
'ATEN iKVM credentials required (user'
+
aten_sep
+
'password) -- got only '
+
this
.
_rfb_password
);
this
.
_onPasswordRequired
(
this
);
return
false
;
}
this
.
_rfb_atenikvm
=
true
;
if
(
this
.
_rfb_tightvnc
)
{
this
.
_rfb_tightvnc
=
false
;
}
else
{
this
.
_sock
.
rQskipBytes
(
4
);
}
this
.
_sock
.
rQskipBytes
(
16
);
var
username
=
aten_auth
[
0
];
username
+=
new
Array
(
24
-
username
.
length
+
1
).
join
(
"
\
x00"
);
var
password
=
aten_auth
.
slice
(
1
).
join
(
aten_sep
);
password
+=
new
Array
(
24
-
password
.
length
+
1
).
join
(
"
\
x00"
);
this
.
_sock
.
send_string
(
username
+
password
);
this
.
_updateState
(
"SecurityResult"
);
return
true
;
},
_negotiate_xvp_auth
:
function
()
{
_negotiate_xvp_auth
:
function
()
{
var
xvp_sep
=
this
.
_xvp_password_sep
;
var
xvp_sep
=
this
.
_xvp_password_sep
;
var
xvp_auth
=
this
.
_rfb_password
.
split
(
xvp_sep
);
var
xvp_auth
=
this
.
_rfb_password
.
split
(
xvp_sep
);
...
@@ -747,9 +785,12 @@ var RFB;
...
@@ -747,9 +785,12 @@ var RFB;
},
},
_negotiate_tight_auth
:
function
()
{
_negotiate_tight_auth
:
function
()
{
var
numTunnels
;
// NB(directxman12): this is only in scope within the following block,
// or if equal to zero (necessary for ATEN iKVM support)
if
(
!
this
.
_rfb_tightvnc
)
{
// first pass, do the tunnel negotiation
if
(
!
this
.
_rfb_tightvnc
)
{
// first pass, do the tunnel negotiation
if
(
this
.
_sock
.
rQwait
(
"num tunnels"
,
4
))
{
return
false
;
}
if
(
this
.
_sock
.
rQwait
(
"num tunnels"
,
4
))
{
return
false
;
}
var
numTunnels
=
this
.
_sock
.
rQshift32
();
numTunnels
=
this
.
_sock
.
rQshift32
();
if
(
this
.
_rfb_version
===
3.8
&&
(
numTunnels
&
0xffff0ff0
)
>>>
0
===
0xaff90fb0
)
{
return
this
.
_negotiate_aten_auth
();
}
if
(
numTunnels
>
0
&&
this
.
_sock
.
rQwait
(
"tunnel capabilities"
,
16
*
numTunnels
,
4
))
{
return
false
;
}
if
(
numTunnels
>
0
&&
this
.
_sock
.
rQwait
(
"tunnel capabilities"
,
16
*
numTunnels
,
4
))
{
return
false
;
}
this
.
_rfb_tightvnc
=
true
;
this
.
_rfb_tightvnc
=
true
;
...
@@ -765,6 +806,12 @@ var RFB;
...
@@ -765,6 +806,12 @@ var RFB;
var
subAuthCount
=
this
.
_sock
.
rQshift32
();
var
subAuthCount
=
this
.
_sock
.
rQshift32
();
if
(
this
.
_sock
.
rQwait
(
"sub auth capabilities"
,
16
*
subAuthCount
,
4
))
{
return
false
;
}
if
(
this
.
_sock
.
rQwait
(
"sub auth capabilities"
,
16
*
subAuthCount
,
4
))
{
return
false
;
}
// Newer X10 Supermicro motherboards get here
if
(
this
.
_rfb_version
===
3.8
&&
numTunnels
===
0
&&
subAuthCount
===
0
)
{
Util
.
Warn
(
"Newer ATEN iKVM detected, you may get an 'unsupported encoding 87'"
);
return
this
.
_negotiate_aten_auth
();
}
var
clientSupportedTypes
=
{
var
clientSupportedTypes
=
{
'STDVNOAUTH__'
:
1
,
'STDVNOAUTH__'
:
1
,
'STDVVNCAUTH_'
:
2
'STDVVNCAUTH_'
:
2
...
@@ -851,6 +898,7 @@ var RFB;
...
@@ -851,6 +898,7 @@ var RFB;
_negotiate_server_init
:
function
()
{
_negotiate_server_init
:
function
()
{
if
(
this
.
_sock
.
rQwait
(
"server initialization"
,
24
))
{
return
false
;
}
if
(
this
.
_sock
.
rQwait
(
"server initialization"
,
24
))
{
return
false
;
}
if
(
this
.
_rfb_atenikvm
&&
this
.
_sock
.
rQwait
(
"ATEN server initialization"
,
36
))
{
return
false
;
}
/* Screen size */
/* Screen size */
this
.
_fb_width
=
this
.
_sock
.
rQshift16
();
this
.
_fb_width
=
this
.
_sock
.
rQshift16
();
...
@@ -878,6 +926,14 @@ var RFB;
...
@@ -878,6 +926,14 @@ var RFB;
if
(
this
.
_sock
.
rQwait
(
'server init name'
,
name_length
,
24
))
{
return
false
;
}
if
(
this
.
_sock
.
rQwait
(
'server init name'
,
name_length
,
24
))
{
return
false
;
}
this
.
_fb_name
=
Util
.
decodeUTF8
(
this
.
_sock
.
rQshiftStr
(
name_length
));
this
.
_fb_name
=
Util
.
decodeUTF8
(
this
.
_sock
.
rQshiftStr
(
name_length
));
if
(
this
.
_rfb_atenikvm
)
{
this
.
_sock
.
rQskipBytes
(
8
);
// unknown
this
.
_sock
.
rQskip8
();
// IKVMVideoEnable
this
.
_sock
.
rQskip8
();
// IKVMKMEnable
this
.
_sock
.
rQskip8
();
// IKVMKickEnable
this
.
_sock
.
rQskip8
();
// VUSBEnable
}
if
(
this
.
_rfb_tightvnc
)
{
if
(
this
.
_rfb_tightvnc
)
{
if
(
this
.
_sock
.
rQwait
(
'TightVNC extended server init header'
,
8
,
24
+
name_length
))
{
return
false
;
}
if
(
this
.
_sock
.
rQwait
(
'TightVNC extended server init header'
,
8
,
24
+
name_length
))
{
return
false
;
}
// In TightVNC mode, ServerInit message is extended
// In TightVNC mode, ServerInit message is extended
...
@@ -924,6 +980,83 @@ var RFB;
...
@@ -924,6 +980,83 @@ var RFB;
this
.
_convertColor
=
true
;
this
.
_convertColor
=
true
;
}
}
// ATEN 'wisdom' from chicken-aten-ikvm:lens/lens.rb
// tested against the following Supermicro motherboards
// (use 'dmidecode -s baseboard-product-name' for model):
// - X7SPA-F
// - X8DTL
// - X8SIE-F
// - X9SCL/X9SCM
// - X9SCM-F
// - X9DRD-iF
// - X9SRE/X9SRE-3F/X9SRi/X9SRi-3F
// - X9DRL-3F/X9DRL-6F
// - X10SLD
//
// Not supported (uses encoding 87):
// - X10SL7-F
// - X10SLD-F
// - X10SLM-F
// - X10SLE
//
// Simply does not work:
// Hermon (WPMC450) [hangs at login]:
// - X7SB3-F
// - X8DTU-F
// - X8STi-3F
// Peppercon (Raritan/Kira100) [connection refused]:
// - X7SBi
//
// Thanks to Brian Rak and Erik Smit for testing
if
(
this
.
_rfb_atenikvm
)
{
// we do not know the resolution till the first fbupdate so go large
// although, not necessary, saves a pointless full screen refresh
this
.
_fb_width
=
10000
;
this
.
_fb_height
=
10000
;
// lies about what it supports
Util
.
Warn
(
"ATEN iKVM lies and only does 15 bit depth with RGB555"
);
this
.
_convertColor
=
true
;
this
.
_pixelFormat
.
bpp
=
16
;
this
.
_pixelFormat
.
depth
=
15
;
this
.
_pixelFormat
.
red_max
=
(
1
<<
5
)
-
1
;
this
.
_pixelFormat
.
green_max
=
(
1
<<
5
)
-
1
;
this
.
_pixelFormat
.
blue_max
=
(
1
<<
5
)
-
1
;
this
.
_pixelFormat
.
red_shift
=
10
;
this
.
_pixelFormat
.
green_shift
=
5
;
this
.
_pixelFormat
.
blue_shift
=
0
;
// changes to protocol format
RFB
.
messages
.
keyEvent
=
function
(
keysym
,
down
)
{
if
(
XK2HID
[
keysym
]
===
undefined
)
{
Util
.
Warn
(
"XK2HID["
+
keysym
+
"] returns undefined"
);
return
;
}
var
arr
=
[
4
];
arr
.
push8
(
0
);
arr
.
push8
(
down
);
arr
.
push16
(
0
);
arr
.
push32
(
XK2HID
[
keysym
]);
arr
.
push32
(
0
);
arr
.
push32
(
0
);
arr
.
push8
(
0
);
return
arr
;
};
RFB
.
messages
.
pointerEvent
=
function
(
x
,
y
,
mask
)
{
var
arr
=
[
5
];
arr
.
push8
(
0
);
arr
.
push8
(
mask
);
arr
.
push16
(
x
);
arr
.
push16
(
y
);
arr
.
push32
(
0
);
arr
.
push32
(
0
);
arr
.
push16
(
0
);
arr
.
push8
(
0
);
return
arr
;
};
}
if
(
this
.
_convertColor
)
if
(
this
.
_convertColor
)
this
.
_display
.
set_true_color
(
this
.
_pixelFormat
.
true_color
);
this
.
_display
.
set_true_color
(
this
.
_pixelFormat
.
true_color
);
this
.
_onFBResize
(
this
,
this
.
_fb_width
,
this
.
_fb_height
);
this
.
_onFBResize
(
this
,
this
.
_fb_width
,
this
.
_fb_height
);
...
@@ -1093,6 +1226,42 @@ var RFB;
...
@@ -1093,6 +1226,42 @@ var RFB;
msg_type
=
this
.
_sock
.
rQshift8
();
msg_type
=
this
.
_sock
.
rQshift8
();
}
}
if
(
this
.
_rfb_atenikvm
)
{
switch
(
msg_type
)
{
case
4
:
// Front Ground Event
Util
.
Debug
(
"ATEN iKVM Front Ground Event"
);
this
.
_sock
.
rQskipBytes
(
20
);
return
true
;
case
22
:
// Keep Alive Event
Util
.
Debug
(
"ATEN iKVM Keep Alive Event"
);
this
.
_sock
.
rQskipBytes
(
1
);
return
true
;
case
51
:
// Video Get Info
Util
.
Debug
(
"ATEN iKVM Video Get Info"
);
this
.
_sock
.
rQskipBytes
(
4
);
return
true
;
case
55
:
// Mouse Get Info
Util
.
Debug
(
"ATEN iKVM Mouse Get Info"
);
this
.
_sock
.
rQskipBytes
(
2
);
return
true
;
case
57
:
// Session Message
Util
.
Debug
(
"ATEN iKVM Session Message"
);
this
.
_sock
.
rQskipBytes
(
4
);
// u32
this
.
_sock
.
rQskipBytes
(
4
);
// u32
this
.
_sock
.
rQskipBytes
(
256
);
return
true
;
case
60
:
// Get Viewer Lang
Util
.
Debug
(
"ATEN iKVM Get Viewer Lang"
);
this
.
_sock
.
rQskipBytes
(
8
);
return
true
;
}
}
switch
(
msg_type
)
{
switch
(
msg_type
)
{
case
0
:
// FramebufferUpdate
case
0
:
// FramebufferUpdate
var
ret
=
this
.
_framebufferUpdate
();
var
ret
=
this
.
_framebufferUpdate
();
...
@@ -1166,6 +1335,11 @@ var RFB;
...
@@ -1166,6 +1335,11 @@ var RFB;
this
.
_FBU
.
encoding
);
this
.
_FBU
.
encoding
);
return
false
;
return
false
;
}
}
// ATEN uses 0x00 even when it is meant to be 0x59
if
(
this
.
_rfb_atenikvm
&&
this
.
_FBU
.
encoding
===
0x00
)
{
this
.
_FBU
.
encoding
=
0x59
;
}
}
}
this
.
_timing
.
last_fbu
=
(
new
Date
()).
getTime
();
this
.
_timing
.
last_fbu
=
(
new
Date
()).
getTime
();
...
@@ -1309,6 +1483,7 @@ var RFB;
...
@@ -1309,6 +1483,7 @@ var RFB;
[
'local_cursor'
,
'rw'
,
'bool'
],
// Request locally rendered cursor
[
'local_cursor'
,
'rw'
,
'bool'
],
// Request locally rendered cursor
[
'shared'
,
'rw'
,
'bool'
],
// Request shared mode
[
'shared'
,
'rw'
,
'bool'
],
// Request shared mode
[
'view_only'
,
'rw'
,
'bool'
],
// Disable client mouse/keyboard
[
'view_only'
,
'rw'
,
'bool'
],
// Disable client mouse/keyboard
[
'aten_password_sep'
,
'rw'
,
'str'
],
// Separator for ATEN iKVM password fields
[
'xvp_password_sep'
,
'rw'
,
'str'
],
// Separator for XVP password fields
[
'xvp_password_sep'
,
'rw'
,
'str'
],
// Separator for XVP password fields
[
'disconnectTimeout'
,
'rw'
,
'int'
],
// Time (s) to wait for disconnection
[
'disconnectTimeout'
,
'rw'
,
'int'
],
// Time (s) to wait for disconnection
[
'wsProtocols'
,
'rw'
,
'arr'
],
// Protocols to use in the WebSocket connection
[
'wsProtocols'
,
'rw'
,
'arr'
],
// Protocols to use in the WebSocket connection
...
@@ -2008,6 +2183,93 @@ var RFB;
...
@@ -2008,6 +2183,93 @@ var RFB;
compress_lo
:
function
()
{
compress_lo
:
function
()
{
Util
.
Error
(
"Server sent compress level pseudo-encoding"
);
Util
.
Error
(
"Server sent compress level pseudo-encoding"
);
},
ATEN
:
function
()
{
if
(
this
.
_FBU
.
aten_len
===
-
1
)
{
this
.
_FBU
.
bytes
=
8
;
if
(
this
.
_sock
.
rQwait
(
"ATEN"
,
this
.
_FBU
.
bytes
))
{
return
false
;
}
this
.
_FBU
.
bytes
=
0
;
this
.
_sock
.
rQskipBytes
(
4
);
this
.
_FBU
.
aten_len
=
this
.
_sock
.
rQshift32
();
if
(
this
.
_FBU
.
width
===
64896
&&
this
.
_FBU
.
height
===
65056
)
{
Util
.
Info
(
"ATEN iKVM screen is probably off"
);
if
(
this
.
_FBU
.
aten_len
!==
10
&&
this
.
_FBU
.
aten_len
!==
0
)
{
Util
.
Debug
(
">> ATEN iKVM screen off (aten_len="
+
this
.
_FBU
.
aten_len
+
")"
);
this
.
_fail
(
'expected aten_len to be 10 when screen is off'
);
}
this
.
_FBU
.
aten_len
=
0
;
return
true
;
}
if
(
this
.
_fb_width
!==
this
.
_FBU
.
width
&&
this
.
_fb_height
!==
this
.
_FBU
.
height
)
{
Util
.
Debug
(
">> ATEN resize desktop"
);
this
.
_fb_width
=
this
.
_FBU
.
width
;
this
.
_fb_height
=
this
.
_FBU
.
height
;
this
.
_onFBResize
(
this
,
this
.
_fb_width
,
this
.
_fb_height
);
this
.
_display
.
resize
(
this
.
_fb_width
,
this
.
_fb_height
);
Util
.
Debug
(
"<< ATEN resize desktop"
);
}
}
if
(
this
.
_FBU
.
aten_type
===
-
1
)
{
this
.
_FBU
.
bytes
=
10
;
if
(
this
.
_sock
.
rQwait
(
"ATEN"
,
this
.
_FBU
.
bytes
))
{
return
false
;
}
this
.
_FBU
.
bytes
=
0
;
this
.
_FBU
.
aten_type
=
this
.
_sock
.
rQshift8
();
this
.
_sock
.
rQskip8
();
this
.
_sock
.
rQskipBytes
(
4
);
// number of subrects
if
(
this
.
_FBU
.
aten_len
!==
this
.
_sock
.
rQshift32
())
{
return
this
.
_fail
(
'ATEN RAW len mis-match'
);
}
this
.
_FBU
.
aten_len
-=
10
;
}
while
(
this
.
_FBU
.
aten_len
>
0
)
{
switch
(
this
.
_FBU
.
aten_type
)
{
case
0
:
// Subrects
this
.
_FBU
.
bytes
=
6
+
(
16
*
16
*
this
.
_pixelFormat
.
Bpp
);
// at least a subrect
if
(
this
.
_sock
.
rQwait
(
"ATEN"
,
this
.
_FBU
.
bytes
))
{
return
false
;
}
var
a
=
this
.
_sock
.
rQshift16
();
var
b
=
this
.
_sock
.
rQshift16
();
var
y
=
this
.
_sock
.
rQshift8
();
var
x
=
this
.
_sock
.
rQshift8
();
this
.
_display
.
renderQ_push
({
'type'
:
'blit'
,
'rgb'
:
true
,
// ATEN always uses convertColor
'data'
:
this
.
_convert_color
(
this
.
_sock
.
rQshiftBytes
(
this
.
_FBU
.
bytes
-
6
)),
'x'
:
x
*
16
,
'y'
:
y
*
16
,
'width'
:
16
,
'height'
:
16
});
this
.
_FBU
.
aten_len
-=
this
.
_FBU
.
bytes
;
this
.
_FBU
.
bytes
=
0
;
break
;
case
1
:
// RAW
var
olines
=
(
this
.
_FBU
.
lines
===
0
)
?
this
.
_FBU
.
height
:
this
.
_FBU
.
lines
;
this
.
_encHandlers
.
RAW
();
this
.
_FBU
.
aten_len
-=
(
olines
-
this
.
_FBU
.
lines
)
*
this
.
_FBU
.
width
*
this
.
_pixelFormat
.
Bpp
;
if
(
this
.
_FBU
.
bytes
>
0
)
return
false
;
break
;
default
:
return
this
.
_fail
(
'unknown ATEN type: '
+
this
.
_FBU
.
aten_type
);
}
}
if
(
this
.
_FBU
.
aten_len
<
0
)
{
this
.
_fail
(
'aten_len dropped below zero'
);
}
if
(
this
.
_FBU
.
aten_type
===
0
)
{
this
.
_FBU
.
rects
--
;
}
this
.
_FBU
.
aten_len
=
-
1
;
this
.
_FBU
.
aten_type
=
-
1
;
return
true
;
}
}
};
};
})();
})();
tests/test.rfb.js
View file @
1db6fd83
...
@@ -789,6 +789,51 @@ describe('Remote Frame Buffer Protocol Client', function() {
...
@@ -789,6 +789,51 @@ describe('Remote Frame Buffer Protocol Client', function() {
expect
(
client
.
_rfb_state
).
to
.
equal
(
'failed'
);
expect
(
client
.
_rfb_state
).
to
.
equal
(
'failed'
);
});
});
});
});
describe
(
'ATEN iKVM Authentication Handler'
,
function
()
{
var
client
;
beforeEach
(
function
()
{
client
=
make_rfb
();
client
.
connect
(
'host'
,
8675
);
client
.
_sock
.
_websocket
.
_open
();
client
.
_rfb_state
=
'Security'
;
client
.
_rfb_version
=
3.8
;
send_security
(
16
,
client
);
client
.
_sock
.
_websocket
.
_get_sent_data
();
// skip the security reply
client
.
_rfb_password
=
'test1:test2'
;
});
var
auth
=
[
116
,
101
,
115
,
116
,
49
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
116
,
101
,
115
,
116
,
50
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
];
it
(
'via old style method'
,
function
()
{
client
.
_sock
.
_websocket
.
_receive_data
(
new
Uint8Array
([
0xaf
,
0xf9
,
0x0f
,
0xb0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
]));
expect
(
client
.
_rfb_tightvnc
).
to
.
be
.
false
;
expect
(
client
.
_rfb_atenikvm
).
to
.
be
.
true
;
expect
(
client
.
_sock
).
to
.
have
.
sent
(
auth
);
});
it
(
'via new style method'
,
function
()
{
client
.
_sock
.
_websocket
.
_receive_data
(
new
Uint8Array
([
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
]));
expect
(
client
.
_rfb_tightvnc
).
to
.
be
.
false
;
expect
(
client
.
_rfb_atenikvm
).
to
.
be
.
true
;
expect
(
client
.
_sock
).
to
.
have
.
sent
(
auth
);
});
});
});
});
describe
(
'SecurityResult'
,
function
()
{
describe
(
'SecurityResult'
,
function
()
{
...
@@ -936,6 +981,23 @@ describe('Remote Frame Buffer Protocol Client', function() {
...
@@ -936,6 +981,23 @@ describe('Remote Frame Buffer Protocol Client', function() {
expect
(
client
.
_rfb_state
).
to
.
equal
(
'normal'
);
expect
(
client
.
_rfb_state
).
to
.
equal
(
'normal'
);
});
});
it
(
'should handle an ATEN iKVM server initialization'
,
function
()
{
client
.
_rfb_atenikvm
=
true
;
send_server_init
({
true_color
:
1
,
bpp
:
32
},
client
);
client
.
_sock
.
_websocket
.
_receive_data
(
new
Uint8Array
([
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
,
0
]));
expect
(
client
.
_pixelFormat
.
bpp
).
to
.
equal
(
16
);
expect
(
client
.
_pixelFormat
.
depth
).
to
.
equal
(
15
);
expect
(
client
.
_pixelFormat
.
red_max
).
to
.
equal
(
31
);
expect
(
client
.
_pixelFormat
.
green_max
).
to
.
equal
(
31
);
expect
(
client
.
_pixelFormat
.
blue_max
).
to
.
equal
(
31
);
expect
(
client
.
_pixelFormat
.
red_shift
).
to
.
equal
(
10
);
expect
(
client
.
_pixelFormat
.
green_shift
).
to
.
equal
(
5
);
expect
(
client
.
_pixelFormat
.
blue_shift
).
to
.
equal
(
0
);
expect
(
client
.
_pixelFormat
.
Bpp
).
to
.
equal
(
2
);
expect
(
client
.
_pixelFormat
.
Bdepth
).
to
.
equal
(
2
);
expect
(
client
.
_rfb_state
).
to
.
equal
(
'normal'
);
});
it
(
'should call the resize callback and resize the display'
,
function
()
{
it
(
'should call the resize callback and resize the display'
,
function
()
{
client
.
set_onFBResize
(
sinon
.
spy
());
client
.
set_onFBResize
(
sinon
.
spy
());
sinon
.
spy
(
client
.
_display
,
'resize'
);
sinon
.
spy
(
client
.
_display
,
'resize'
);
...
@@ -1477,6 +1539,96 @@ describe('Remote Frame Buffer Protocol Client', function() {
...
@@ -1477,6 +1539,96 @@ describe('Remote Frame Buffer Protocol Client', function() {
// TODO(directxman12): test this
// TODO(directxman12): test this
});
});
describe
(
'the ATEN encoding handler'
,
function
()
{
var
client
;
beforeEach
(
function
()
{
client
=
make_rfb
();
client
.
connect
(
'host'
,
8675
);
client
.
_sock
.
_websocket
.
_open
();
client
.
_rfb_state
=
'normal'
;
client
.
_fb_name
=
'some device'
;
client
.
_rfb_atenikvm
=
true
;
// start large, then go small
client
.
_fb_width
=
10000
;
client
.
_fb_height
=
10000
;
client
.
_display
.
_fb_width
=
10000
;
client
.
_display
.
_fb_height
=
10000
;
client
.
_display
.
_viewportLoc
.
w
=
10000
;
client
.
_display
.
_viewportLoc
.
h
=
10000
;
client
.
_convertColor
=
true
;
client
.
_pixelFormat
.
Bpp
=
2
;
client
.
_pixelFormat
.
big_endian
=
false
;
client
.
_pixelFormat
.
red_shift
=
10
;
client
.
_pixelFormat
.
red_max
=
31
;
client
.
_pixelFormat
.
green_shift
=
5
;
client
.
_pixelFormat
.
green_max
=
31
;
client
.
_pixelFormat
.
blue_shift
=
0
;
client
.
_pixelFormat
.
blue_max
=
31
;
});
var
aten_target_data_arr
=
[
0xa8
,
0xe8
,
0xf8
,
0xff
];
var
aten_target_data
;
before
(
function
()
{
for
(
var
i
=
0
;
i
<
10
;
i
++
)
{
aten_target_data_arr
=
aten_target_data_arr
.
concat
(
aten_target_data_arr
);
}
aten_target_data
=
new
Uint8Array
(
aten_target_data_arr
);
});
it
(
'should handle subtype subrect encoding'
,
function
()
{
var
info
=
[{
x
:
0
,
y
:
0
,
width
:
32
,
height
:
32
,
encoding
:
0x59
}];
var
rect
=
[];
rect
.
push32
(
0
);
// padding
rect
.
push32
(
2082
);
// 10 + 32x32x2Bpp + 6*(num of subrects)
rect
.
push8
(
0
);
// type
rect
.
push8
(
0
);
// padding
rect
.
push32
(
4
);
// num of subrects (32/16)*(32/16)
rect
.
push32
(
2082
);
// length (again)
for
(
var
y
=
0
;
y
<
2
;
y
++
)
{
for
(
var
x
=
0
;
x
<
2
;
x
++
)
{
rect
.
push16
(
0
);
// a
rect
.
push16
(
0
);
// b
rect
.
push8
(
y
);
rect
.
push8
(
x
);
for
(
var
i
=
0
;
i
<
16
*
16
;
i
++
)
{
rect
.
push16
(
0xbf57
);
}
}
}
send_fbu_msg
(
info
,
[
rect
],
client
);
expect
(
client
.
_display
).
to
.
have
.
displayed
(
aten_target_data
);
});
it
(
'should handle subtype RAW encoding'
,
function
()
{
// do not use encoding=0x59 here, as rfb.js should override it
var
info
=
[{
x
:
0
,
y
:
0
,
width
:
32
,
height
:
32
,
encoding
:
0x00
}];
var
rect
=
[];
rect
.
push32
(
0
);
// padding
rect
.
push32
(
2058
);
// 10 + 32x32x2Bpp
rect
.
push8
(
1
);
// type
rect
.
push8
(
0
);
// padding
rect
.
push32
(
0
);
// padding
rect
.
push32
(
2058
);
// length (again)
for
(
var
i
=
0
;
i
<
32
*
32
;
i
++
)
{
rect
.
push16
(
0xbf57
);
}
send_fbu_msg
(
info
,
[
rect
],
client
);
expect
(
client
.
_display
).
to
.
have
.
displayed
(
aten_target_data
);
});
});
it
(
'should handle the DesktopSize pseduo-encoding'
,
function
()
{
it
(
'should handle the DesktopSize pseduo-encoding'
,
function
()
{
client
.
set_onFBResize
(
sinon
.
spy
());
client
.
set_onFBResize
(
sinon
.
spy
());
sinon
.
spy
(
client
.
_display
,
'resize'
);
sinon
.
spy
(
client
.
_display
,
'resize'
);
...
...
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