2015-07-23 15:45:28 -04:00
// Communicate with the Scratch Native Messaging Host through an extension.
window . ScratchDeviceHost = new ( function ( ) {
var self = this ;
var isConnected = false ;
self . isAvailable = function ( ) {
return isConnected ;
} ;
2016-10-07 12:09:17 -07:00
if ( ! ( window . chrome && window . chrome . runtime && window . chrome . runtime . connect ) ) {
return ;
}
2015-07-23 15:45:28 -04:00
var extensionID = 'clmabinlolakdafkoajkfjjengcdmnpm' ;
var callNumber = 0 ;
var port = chrome . runtime . connect ( extensionID ) ;
console . assert ( port , "Failed to create port" ) ;
var messageHandlers = { } ;
port . onMessage . addListener ( function ( message ) {
var messageName = message [ 0 ] ;
if ( messageName == "@" ) {
var callbackToken = message [ 1 ] ;
var returnValue = message [ 2 ] ;
var callback = pendingCallbacks [ callbackToken ] ;
delete pendingCallbacks [ callbackToken ] ;
if ( callback ) callback ( returnValue ) ;
} else {
var handler = messageHandlers [ messageName ] ;
if ( handler ) {
handler ( message ) ;
} else {
console . log ( "SDH-Page: Unrecognized message " + message ) ;
}
}
} ) ;
messageHandlers [ "serialRecv" ] = function ( message ) {
var path = message [ 1 ] ;
var data = message [ 2 ] ;
var device = serialDevices [ path ] ;
if ( device && device . receiveHandler ) {
device . receiveHandler ( data ) ;
}
} ;
messageHandlers [ "serialError" ] = function ( message ) {
var path = message [ 1 ] ;
var errorMessage = message [ 2 ] ;
var device = serialDevices [ path ] ;
if ( device && device . errorHandler ) {
device . errorHandler ( errorMessage ) ;
}
} ;
var pendingCallbacks = { } ;
2016-08-02 00:49:34 -07:00
2015-07-23 15:45:28 -04:00
function sendMessage ( message , callback ) {
var callbackToken = ( callNumber ++ ) . toString ( ) ;
pendingCallbacks [ callbackToken ] = callback ;
port . postMessage ( [ callbackToken , message ] ) ;
}
sendMessage ( [ "version" ] , function ( version ) {
isConnected = true ;
} ) ;
self . hid _list = function ( callback , opt _vendorID , opt _productID ) {
var message = [ "hid_list" , opt _vendorID || 0 , opt _productID || 0 ] ;
sendMessage ( message , function ( deviceList ) {
if ( callback ) callback ( deviceList ) ;
} ) ;
} ;
self . hid _open = function ( path , callback ) {
var message = [ "hid_open_raw" , path ] ;
sendMessage ( message , function ( result ) {
var device ;
if ( result ) {
device = new HidDevice ( path ) ;
ScratchProxies . AddHidProxies ( device ) ;
var claimMessage = [ "claim" , path ] ;
sendMessage ( claimMessage ) ;
}
if ( callback ) callback ( device ) ;
} ) ;
} ;
self . serial _list = function ( callback ) {
sendMessage ( [ "serial_list" ] , function ( deviceList ) {
if ( callback ) callback ( deviceList ) ;
} ) ;
} ;
self . serial _open = function ( path , opts , callback ) {
var message = [ "serial_open_raw" , path ] ;
if ( opts ) message . push ( opts ) ;
sendMessage ( message , function ( result ) {
var device ;
if ( result ) {
device = new SerialDevice ( path ) ;
ScratchProxies . AddSerialProxies ( device ) ;
var claimMessage = [ "claim" , path ] ;
sendMessage ( claimMessage ) ;
}
if ( callback ) callback ( device ) ;
} ) ;
} ;
self . reset = function ( ) {
sendMessage ( [ "reset" ] ) ;
} ;
self . version = function ( callback ) {
sendMessage ( [ "version" ] , function ( result ) {
if ( callback ) callback ( result ) ;
} ) ;
} ;
function HidDevice ( path ) {
var self = this ;
self . write _raw = function ( arrayBuffer , callback ) {
var message = [ "write_raw" , path , arrayBuffer ] ;
sendMessage ( message , function ( result ) {
if ( callback ) callback ( result ) ;
} ) ;
} ;
self . send _feature _report _raw = function ( arrayBuffer , callback ) {
var message = [ "send_feature_report_raw" , path , arrayBuffer ] ;
sendMessage ( message , function ( result ) {
if ( callback ) callback ( result ) ;
} ) ;
} ;
self . read _raw = function ( size , callback ) {
var message = [ "read_raw" , path , size ] ;
sendMessage ( message , function ( data ) {
if ( callback ) callback ( data ) ;
} ) ;
} ;
self . get _feature _report _raw = function ( size , callback ) {
var message = [ "get_feature_report_raw" , path , size ] ;
sendMessage ( message , function ( data ) {
if ( callback ) callback ( data ) ;
} ) ;
} ;
self . set _nonblocking = function ( flag , callback ) {
var message = [ "set_nonblocking" , path , flag ] ;
sendMessage ( message , function ( result ) {
if ( callback ) callback ( result ) ;
} ) ;
} ;
self . close = function ( ) {
sendMessage ( [ "close" , path ] ) ;
} ;
}
var serialDevices = { } ; // path -> SerialDevice
function SerialDevice ( path ) {
var self = this ;
self . receiveHandler = undefined ;
self . errorHandler = undefined ;
serialDevices [ path ] = self ;
self . send _raw = function ( data ) {
var message = [ "serial_send_raw" , path , data ] ;
sendMessage ( message ) ;
} ;
self . close = function ( ) {
var message = [ "serial_close" , path ] ;
sendMessage ( message ) ;
} ;
self . is _open = function ( callback ) {
var message = [ "serial_is_open" , path ] ;
sendMessage ( message , function ( result ) {
if ( callback ) callback ( result ) ;
} ) ;
} ;
self . set _receive _handler _raw = function ( callback ) {
self . receiveHandler = callback ;
var message = [ "serial_recv_start" , path ] ;
sendMessage ( message ) ;
} ;
self . set _error _handler = function ( callback ) {
self . errorHandler = callback ;
} ;
}
} ) ( ) ;