@@ -112,25 +112,111 @@ function setupFullscreen(display, canvas, options) {
112
112
}
113
113
}
114
114
115
+ function recordMouseEvent ( what , evt , canvas , display , eventQueue , options ) {
116
+ var x = ( evt . pageX - canvas . offsetLeft ) * ( canvas . width / canvas . offsetWidth ) ;
117
+ y = ( evt . pageY - canvas . offsetTop ) * ( canvas . height / canvas . offsetHeight ) ;
118
+ // subtract display offset and clamp to display size
119
+ display . mouseX = Math . max ( 0 , Math . min ( display . width , x - display . offsetX ) ) ;
120
+ display . mouseY = Math . max ( 0 , Math . min ( display . height , y - display . offsetY ) ) ;
121
+ var buttons = display . buttons & Squeak . Mouse_All ;
122
+ switch ( what ) {
123
+ case 'move' :
124
+ break ; // nothing more to do
125
+ case 'up' :
126
+ buttons = 0 ;
127
+ break ;
128
+ case 'down' :
129
+ switch ( evt . button ) {
130
+ case 0 : buttons = Squeak . Mouse_Red ; break ; // left
131
+ case 1 : buttons = Squeak . Mouse_Yellow ; break ; // middle
132
+ case 2 : buttons = Squeak . Mouse_Blue ; break ; // right
133
+ } ;
134
+ if ( options . swapButtons )
135
+ if ( buttons == Squeak . Mouse_Yellow ) buttons = Squeak . Mouse_Blue ;
136
+ else if ( buttons == Squeak . Mouse_Blue ) buttons = Squeak . Mouse_Yellow ;
137
+ break ;
138
+ }
139
+ buttons +=
140
+ ( evt . shiftKey ? Squeak . Keyboard_Shift : 0 ) +
141
+ ( evt . ctrlKey ? Squeak . Keyboard_Ctrl : 0 ) +
142
+ ( evt . altKey || evt . metaKey ? Squeak . Keyboard_Cmd : 0 ) ;
143
+ display . buttons = buttons ;
144
+ if ( eventQueue ) {
145
+ eventQueue . push ( [
146
+ Squeak . EventTypeMouse ,
147
+ evt . timeStamp , // converted to Squeak time in makeSqueakEvent()
148
+ display . mouseX ,
149
+ display . mouseY ,
150
+ display . buttons & Squeak . Mouse_All ,
151
+ display . buttons >> 3 ,
152
+ ] ) ;
153
+ if ( display . signalInputEvent )
154
+ display . signalInputEvent ( ) ;
155
+ }
156
+ }
157
+
158
+ function recordKeyboardEvent ( key , timestamp , display , eventQueue ) {
159
+ var code = ( display . buttons >> 3 ) << 8 | key ;
160
+ if ( code === display . vm . interruptKeycode ) {
161
+ display . vm . interruptPending = true ;
162
+ } else if ( eventQueue ) {
163
+ eventQueue . push ( [
164
+ Squeak . EventTypeKeyboard ,
165
+ timestamp , // converted to Squeak time in makeSqueakEvent()
166
+ key , // MacRoman
167
+ Squeak . EventKeyChar ,
168
+ display . buttons >> 3 ,
169
+ 0 , // Unicode
170
+ ] ) ;
171
+ if ( display . signalInputEvent )
172
+ display . signalInputEvent ( ) ;
173
+ } else {
174
+ // no event queue, queue keys the old-fashioned way
175
+ display . keys . push ( code ) ;
176
+ }
177
+ }
178
+
179
+ function makeSqueakEvent ( evt , sqEvtBuf , sqTimeOffset ) {
180
+ sqEvtBuf [ 0 ] = evt [ 0 ] ;
181
+ sqEvtBuf [ 1 ] = ( evt [ 1 ] - sqTimeOffset ) & Squeak . MillisecondClockMask ;
182
+ for ( var i = 2 ; i < evt . length ; i ++ )
183
+ sqEvtBuf [ i ] = evt [ i ] ;
184
+ }
185
+
115
186
function createSqueakDisplay ( canvas , options ) {
116
187
options = options || { } ;
188
+ var eventQueue = null ;
117
189
var display = {
118
190
context : canvas . getContext ( "2d" ) ,
119
191
fullscreen : false ,
192
+ offsetX : 0 ,
193
+ offsetY : 0 ,
194
+ width : - 1 ,
195
+ height : - 1 ,
120
196
mouseX : 0 ,
121
197
mouseY : 0 ,
122
198
buttons : 0 ,
123
199
keys : [ ] ,
124
200
clipboardString : '' ,
125
201
clipboardStringChanged : false ,
202
+ signalInputEvent : null , // function set by VM
203
+ getNextEvent : function firstTime ( firstEvtBuf , firstOffset ) {
204
+ eventQueue = [ ] ;
205
+ display . getNextEvent = function getNextEvent ( evtBuf , timeOffset ) {
206
+ var evt = eventQueue . shift ( ) ;
207
+ if ( evt ) makeSqueakEvent ( evt , evtBuf , timeOffset ) ;
208
+ else evtBuf [ 0 ] = Squeak . EventTypeNone ;
209
+ } ;
210
+ display . getNextEvent ( firstEvtBuf , firstOffset ) ;
211
+ } ,
126
212
} ;
127
- var checkFullscreen = setupFullscreen ( display , canvas ) ;
213
+ var checkFullscreen = setupFullscreen ( display , canvas , options ) ;
128
214
display . clear = function ( ) {
129
215
canvas . width = canvas . width ;
130
216
} ;
131
217
display . showBanner = function ( msg , style ) {
132
218
style = style || { } ;
133
- var ctx = canvas . getContext ( "2d" ) ;
219
+ var ctx = display . context ;
134
220
ctx . clearRect ( 0 , 0 , canvas . width , canvas . height ) ;
135
221
ctx . fillStyle = style . color || "#F90" ;
136
222
ctx . font = style . font || 'bold 48px sans-serif' ;
@@ -156,60 +242,61 @@ function createSqueakDisplay(canvas, options) {
156
242
canvas . onmousedown = function ( evt ) {
157
243
checkFullscreen ( ) ;
158
244
canvas . focus ( ) ;
159
- var button = ( options . swapButtons ? [ 4 , 1 , 2 ] : [ 4 , 2 , 1 ] ) [ evt . button ] ;
160
- display . buttons = display . buttons & ~ 7 | button ;
245
+ recordMouseEvent ( 'down' , evt , canvas , display , eventQueue , options ) ;
246
+ display . vm . interpret ( 100 ) ;
161
247
evt . preventDefault ( ) ;
162
248
return false ;
163
249
} ;
164
250
canvas . onmouseup = function ( evt ) {
251
+ recordMouseEvent ( 'up' , evt , canvas , display , eventQueue , options ) ;
252
+ display . vm . interpret ( 100 ) ;
165
253
checkFullscreen ( ) ;
166
- display . buttons = display . buttons & ~ 7 ;
167
254
evt . preventDefault ( ) ;
168
255
} ;
169
256
canvas . onmousemove = function ( evt ) {
170
- // scale events to actual canvas extent
171
- display . mouseX = ( evt . pageX - this . offsetLeft ) * ( this . width / this . offsetWidth ) ;
172
- display . mouseY = ( evt . pageY - this . offsetTop ) * ( this . height / this . offsetHeight ) ;
257
+ recordMouseEvent ( 'move' , evt , canvas , display , eventQueue , options ) ;
258
+ evt . preventDefault ( ) ;
173
259
} ;
174
260
canvas . oncontextmenu = function ( ) {
175
261
return false ;
176
262
} ;
177
263
canvas . ontouchstart = function ( evt ) {
178
264
canvas . focus ( ) ;
179
- display . buttons = 4 ;
180
265
canvas . ontouchmove ( evt ) ;
181
266
} ;
182
267
canvas . ontouchmove = function ( evt ) {
183
268
canvas . onmousemove ( evt . touches [ 0 ] ) ;
184
269
} ;
185
270
canvas . ontouchend = function ( evt ) {
186
- display . buttons = 0 ;
187
271
canvas . ontouchmove ( evt ) ;
188
272
} ;
189
273
canvas . ontouchcancel = function ( evt ) {
190
- display . buttons = 0 ;
191
274
} ;
192
275
canvas . onkeypress = function ( evt ) {
193
- display . keys . push ( evt . charCode ) ;
276
+ recordKeyboardEvent ( evt . charCode , evt . timeStamp , display , eventQueue ) ;
194
277
evt . preventDefault ( ) ;
195
278
} ;
196
279
canvas . onkeydown = function ( evt ) {
197
280
checkFullscreen ( ) ;
198
281
var code = ( { 46 :127 , 8 :8 , 45 :5 , 9 :9 , 13 :13 , 27 :27 , 36 :1 , 35 :4 ,
199
282
33 :11 , 34 :12 , 37 :28 , 39 :29 , 38 :30 , 40 :31 } ) [ evt . keyCode ] ;
200
- if ( code ) { display . keys . push ( code ) ; return evt . preventDefault ( ) } ;
283
+ if ( code ) { // special key pressed
284
+ recordKeyboardEvent ( code , evt . timeStamp , display , eventQueue ) ;
285
+ return evt . preventDefault ( ) ;
286
+ }
201
287
var modifier = ( { 16 :8 , 17 :16 , 91 :64 , 18 :64 } ) [ evt . keyCode ] ;
202
- if ( modifier ) {
288
+ if ( modifier ) { // modifier pressed
203
289
display . buttons |= modifier ;
204
- if ( modifier > 8 ) display . keys = [ ] ;
290
+ if ( modifier > 8 ) // special
291
+ display . keys = [ ] ; // flush queued key presses
205
292
return evt . preventDefault ( ) ;
206
293
}
207
294
if ( ( evt . metaKey || evt . altKey ) && evt . which ) {
208
295
code = evt . which ;
209
296
if ( code >= 65 && code <= 90 ) if ( ! evt . shiftKey ) code += 32 ;
210
297
else if ( evt . keyIdentifier && evt . keyIdentifier . slice ( 0 , 2 ) == 'U+' )
211
298
code = parseInt ( evt . keyIdentifier . slice ( 2 ) , 16 ) ;
212
- display . keys . push ( code )
299
+ recordKeyboardEvent ( code , evt . timeStamp , display , eventQueue ) ;
213
300
return evt . preventDefault ( ) ;
214
301
}
215
302
} ;
0 commit comments