2015-03-11 14:17:42 +00:00
"use strict" ;
/ *
Copyright ( C ) 2013 by Jeremy P . White < jwhite @ codeweavers . com >
This file is part of spice - html5 .
spice - html5 is free software : you can redistribute it and / or modify
it under the terms of the GNU Lesser General Public License as published by
the Free Software Foundation , either version 3 of the License , or
( at your option ) any later version .
spice - html5 is distributed in the hope that it will be useful ,
but WITHOUT ANY WARRANTY ; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE . See the
GNU Lesser General Public License for more details .
You should have received a copy of the GNU Lesser General Public License
along with spice - html5 . If not , see < http : //www.gnu.org/licenses/>.
* /
/ * - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
* * SpiceSimulateCursor
* * Internet Explorer 10 does not support data uri ' s in cursor assignment .
* * This file provides a number of gimmicks to compensate . First , if there
* * is a preloaded cursor available , we will use that . Failing that , we will
* * simulate a cursor using an image that is moved around the screen .
* * -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- -- * /
2020-01-23 12:49:43 +00:00
import { SpiceDataView } from './spicedataview.js' ;
import { hex _sha1 } from './thirdparty/sha1.js' ;
2015-03-11 14:17:42 +00:00
var SpiceSimulateCursor = {
cursors : new Array ( ) ,
unknown _cursors : new Array ( ) ,
warned : false ,
add _cursor : function ( sha1 , value )
{
SpiceSimulateCursor . cursors [ sha1 ] = value ;
} ,
unknown _cursor : function ( sha1 , curdata )
{
if ( ! SpiceSimulateCursor . warned )
{
SpiceSimulateCursor . warned = true ;
alert ( "Internet Explorer does not support dynamic cursors. " +
"This page will now simulate cursors with images, " +
"which will be imperfect. We recommend using Chrome or Firefox instead. " +
"\n\nIf you need to use Internet Explorer, you can create a static cursor " +
"file for each cursor your application uses. " +
"View the console log for more information on creating static cursors for your environment." ) ;
}
if ( ! SpiceSimulateCursor . unknown _cursors [ sha1 ] )
{
SpiceSimulateCursor . unknown _cursors [ sha1 ] = curdata ;
console . log ( 'Unknown cursor. Simulation required. To avoid simulation for this cursor, create and include a custom javascript file, and add the following line:' ) ;
console . log ( 'SpiceCursorSimulator.add_cursor("' + sha1 + '"), "<your filename here>.cur");' ) ;
console . log ( 'And then run following command, redirecting output into <your filename here>.cur:' ) ;
console . log ( 'php -r "echo urldecode(\'' + curdata + '\');"' ) ;
}
} ,
simulate _cursor : function ( spicecursor , cursor , screen , pngstr )
{
var cursor _sha = hex _sha1 ( pngstr + ' ' + cursor . header . hot _spot _x + ' ' + cursor . header . hot _spot _y ) ;
if ( typeof SpiceSimulateCursor . cursors != 'undefined' )
if ( typeof SpiceSimulateCursor . cursors [ cursor _sha ] != 'undefined' )
{
var curstr = 'url(' + SpiceSimulateCursor . cursors [ cursor _sha ] + '), default' ;
screen . style . cursor = curstr ;
}
if ( window . getComputedStyle ( screen , null ) . cursor == 'auto' )
{
2018-08-08 11:00:35 +00:00
SpiceSimulateCursor . unknown _cursor ( cursor _sha ,
2015-03-11 14:17:42 +00:00
SpiceSimulateCursor . create _icondir ( cursor . header . width , cursor . header . height ,
cursor . data . byteLength , cursor . header . hot _spot _x , cursor . header . hot _spot _y ) + pngstr ) ;
document . getElementById ( spicecursor . parent . screen _id ) . style . cursor = 'none' ;
if ( ! spicecursor . spice _simulated _cursor )
{
spicecursor . spice _simulated _cursor = document . createElement ( 'img' ) ;
spicecursor . spice _simulated _cursor . style . position = 'absolute' ;
spicecursor . spice _simulated _cursor . style . display = 'none' ;
spicecursor . spice _simulated _cursor . style . overflow = 'hidden' ;
spicecursor . spice _simulated _cursor . spice _screen = document . getElementById ( spicecursor . parent . screen _id ) ;
spicecursor . spice _simulated _cursor . addEventListener ( 'mousemove' , SpiceSimulateCursor . handle _sim _mousemove ) ;
spicecursor . spice _simulated _cursor . spice _screen . appendChild ( spicecursor . spice _simulated _cursor ) ;
}
spicecursor . spice _simulated _cursor . src = 'data:image/png,' + pngstr ;
spicecursor . spice _simulated _cursor . spice _hot _x = cursor . header . hot _spot _x ;
spicecursor . spice _simulated _cursor . spice _hot _y = cursor . header . hot _spot _y ;
spicecursor . spice _simulated _cursor . style . pointerEvents = "none" ;
}
else
2018-08-08 11:00:35 +00:00
{
2015-03-11 14:17:42 +00:00
if ( spicecursor . spice _simulated _cursor )
{
spicecursor . spice _simulated _cursor . spice _screen . removeChild ( spicecursor . spice _simulated _cursor ) ;
delete spicecursor . spice _simulated _cursor ;
}
}
} ,
handle _sim _mousemove : function ( e )
{
var retval ;
var f = SpiceSimulateCursor . duplicate _mouse _event ( e , this . spice _screen ) ;
return this . spice _screen . dispatchEvent ( f ) ;
} ,
duplicate _mouse _event : function ( e , target )
{
var evt = document . createEvent ( "mouseevent" ) ;
evt . initMouseEvent ( e . type , true , true , e . view , e . detail ,
e . screenX , e . screenY , e . clientX , e . clientY ,
e . ctrlKey , e . altKey , e . shiftKey , e . metaKey , e . button , e . relatedTarget ) ;
return evt ;
} ,
ICONDIR : function ( )
{
} ,
ICONDIRENTRY : function ( width , height , bytes , hot _x , hot _y )
{
this . width = width ;
this . height = height ;
this . bytes = bytes ;
this . hot _x = hot _x ;
this . hot _y = hot _y ;
} ,
create _icondir : function ( width , height , bytes , hot _x , hot _y )
{
var i ;
var header = new SpiceSimulateCursor . ICONDIR ( ) ;
var entry = new SpiceSimulateCursor . ICONDIRENTRY ( width , height , bytes , hot _x , hot _y ) ;
var mb = new ArrayBuffer ( header . buffer _size ( ) + entry . buffer _size ( ) ) ;
var at = header . to _buffer ( mb ) ;
at = entry . to _buffer ( mb , at ) ;
var u8 = new Uint8Array ( mb ) ;
var str = "" ;
for ( i = 0 ; i < at ; i ++ )
{
str += "%" ;
if ( u8 [ i ] < 16 )
str += "0" ;
str += u8 [ i ] . toString ( 16 ) ;
}
return str ;
} ,
} ;
2018-08-08 11:00:35 +00:00
SpiceSimulateCursor . ICONDIR . prototype =
2015-03-11 14:17:42 +00:00
{
to _buffer : function ( a , at )
{
at = at || 0 ;
var dv = new SpiceDataView ( a ) ;
dv . setUint16 ( at , 0 , true ) ; at += 2 ;
dv . setUint16 ( at , 2 , true ) ; at += 2 ;
dv . setUint16 ( at , 1 , true ) ; at += 2 ;
return at ;
} ,
buffer _size : function ( )
{
return 6 ;
}
} ;
SpiceSimulateCursor . ICONDIRENTRY . prototype =
{
to _buffer : function ( a , at )
{
at = at || 0 ;
var dv = new SpiceDataView ( a ) ;
dv . setUint8 ( at , this . width ) ; at ++ ;
dv . setUint8 ( at , this . height ) ; at ++ ;
dv . setUint8 ( at , 0 ) ; at ++ ; /* color palette count, unused */
dv . setUint8 ( at , 0 ) ; at ++ ; /* reserved */
dv . setUint16 ( at , this . hot _x , true ) ; at += 2 ;
dv . setUint16 ( at , this . hot _y , true ) ; at += 2 ;
dv . setUint32 ( at , this . bytes , true ) ; at += 4 ;
dv . setUint32 ( at , at + 4 , true ) ; at += 4 ; /* Offset to bytes */
return at ;
} ,
buffer _size : function ( )
{
return 16 ;
}
} ;
2020-01-23 12:49:43 +00:00
export { SpiceSimulateCursor } ;