]>
git.proxmox.com Git - mirror_novnc.git/blob - include/canvas.js
2 * noVNC: HTML5 VNC client
3 * Copyright (C) 2010 Joel Martin
4 * Licensed under LGPL-3 (see LICENSE.LGPL-3)
6 * See README.md for usage and integration instructions.
10 /*global window, $, Browser */
12 // Everything namespaced inside Canvas
25 mouseDown: function (e
) {
26 var evt
= e
.event
|| window
.event
;
28 console
.log('mouse ' + evt
.which
+ '/' + evt
.button
+ ' down:' +
29 (evt
.clientX
- Canvas
.c_x
) + "," + (evt
.clientY
- Canvas
.c_y
));
32 mouseUp: function (e
) {
33 var evt
= e
.event
|| window
.event
;
35 console
.log('mouse ' + evt
.which
+ '/' + evt
.button
+ ' up:' +
36 (evt
.clientX
- Canvas
.c_x
) + "," + (evt
.clientY
- Canvas
.c_y
));
39 mouseMove: function (e
) {
40 var evt
= e
.event
|| window
.event
;
41 console
.log('mouse ' + evt
.which
+ '/' + evt
.button
+ ' up:' +
42 (evt
.clientX
- Canvas
.c_x
) + "," + (evt
.clientY
- Canvas
.c_y
));
45 mouseWheel: function (e
) {
46 var evt
= e
.event
|| window
.event
;
47 //e = e ? e : window.event;
48 var wheelData
= evt
.detail
? evt
.detail
* -1 : evt
.wheelDelta
/ 40;
49 console
.log('mouse scroll by ' + wheelData
+ ':' +
50 (evt
.clientX
- Canvas
.c_x
) + "," + (evt
.clientY
- Canvas
.c_y
));
54 keyDown: function (e
) {
56 console
.log("keydown: " + e
.key
+ "(" + e
.code
+ ")");
59 keyUp : function (e
) {
61 console
.log("keyup: " + e
.key
+ "(" + e
.code
+ ")");
64 ctxDisable: function (e
) {
65 var evt
= e
.event
|| window
.event
;
66 /* Stop propagation if inside canvas area */
67 if ((evt
.clientX
>= Canvas
.c_x
) &&
68 (evt
.clientY
>= Canvas
.c_y
) &&
69 (evt
.clientX
< (Canvas
.c_x
+ Canvas
.c_wx
)) &&
70 (evt
.clientY
< (Canvas
.c_y
+ Canvas
.c_wy
))) {
77 init: function (id
, width
, height
, keyDown
, keyUp
,
78 mouseDown
, mouseUp
, mouseMove
, mouseWheel
) {
79 console
.log(">> Canvas.init");
83 if (! keyDown
) { keyDown
= Canvas
.keyDown
; }
84 if (! keyUp
) { keyUp
= Canvas
.keyUp
; }
85 if (! mouseDown
) { mouseDown
= Canvas
.mouseDown
; }
86 if (! mouseUp
) { mouseUp
= Canvas
.mouseUp
; }
87 if (! mouseMove
) { mouseMove
= Canvas
.mouseMove
; }
88 if (! mouseWheel
) { mouseWheel
= Canvas
.mouseWheel
; }
91 document
.addEvent('keydown', keyDown
);
92 document
.addEvent('keyup', keyUp
);
93 c
.addEvent('mousedown', mouseDown
);
94 c
.addEvent('mouseup', mouseUp
);
95 c
.addEvent('mousemove', mouseMove
);
96 c
.addEvent('mousewheel', mouseWheel
);
98 /* Work around right and middle click browser behaviors */
99 document
.addEvent('click', Canvas
.ctxDisable
);
100 document
.body
.addEvent('contextmenu', Canvas
.ctxDisable
);
104 Canvas
.c_x
= c
.getPosition().x
;
105 Canvas
.c_y
= c
.getPosition().y
;
106 Canvas
.c_wx
= c
.getSize().x
;
107 Canvas
.c_wy
= c
.getSize().y
;
109 if (! c
.getContext
) { return; }
110 Canvas
.ctx
= c
.getContext('2d');
112 Canvas
.prevStyle
= "";
114 if (Browser
.Engine
.webkit
) {
115 Canvas
.prefer_js
= true;
118 console
.log("<< Canvas.init");
122 Canvas
.ctx
.clearRect(0, 0, Canvas
.c_wx
, Canvas
.c_wy
);
123 var c
= $(Canvas
.id
);
129 var c
= $(Canvas
.id
);
130 document
.removeEvents('keydown');
131 document
.removeEvents('keyup');
132 c
.removeEvents('mousedown');
133 c
.removeEvents('mouseup');
134 c
.removeEvents('mousemove');
135 c
.removeEvents('DOMMouseScroll');
137 /* Work around right and middle click browser behaviors */
138 document
.removeEvents('click');
139 document
.body
.removeEvents('contextmenu');
143 * Tile rendering functions optimized for rendering engines.
145 * - In Chrome/webkit, Javascript image data array manipulations are
146 * faster than direct Canvas fillStyle, fillRect rendering. In
147 * gecko, Javascript array handling is much slower.
149 getTile: function(x
, y
, width
, height
, color
) {
150 var img
, data
, p
, red
, green
, blue
, j
, i
;
151 img
= {'x': x
, 'y': y
, 'width': width
, 'height': height
,
153 if (Canvas
.prefer_js
) {
158 for (j
= 0; j
< height
; j
++) {
159 for (i
= 0; i
< width
; i
++) {
160 p
= (i
+ (j
* width
) ) * 4;
161 img
.data
[p
+ 0] = red
;
162 img
.data
[p
+ 1] = green
;
163 img
.data
[p
+ 2] = blue
;
164 //img.data[p + 3] = 255; // Set Alpha
168 Canvas
.fillRect(x
, y
, width
, height
, color
);
173 setTile: function(img
, x
, y
, w
, h
, color
) {
174 var data
, p
, red
, green
, blue
, width
, j
, i
;
175 if (Canvas
.prefer_js
) {
181 for (j
= 0; j
< h
; j
++) {
182 for (i
= 0; i
< w
; i
++) {
183 p
= (x
+ i
+ ((y
+ j
) * width
) ) * 4;
187 //img.data[p + 3] = 255; // Set Alpha
191 Canvas
.fillRect(img
.x
+ x
, img
.y
+ y
, w
, h
, color
);
195 putTile: function(img
) {
196 if (Canvas
.prefer_js
) {
197 Canvas
.rgbxImage(img
.x
, img
.y
, img
.width
, img
.height
, img
.data
, 0);
198 //Canvas.ctx.putImageData(img, img.x, img.y);
200 // No-op, under gecko already done by setTile
205 rgbxImage: function(x
, y
, width
, height
, arr
, offset
) {
207 //console.log("rfbxImage: img: " + img + " x: " + x + " y: " + y + " width: " + width + " height: " + height);
208 /* Old firefox and Opera don't support createImageData */
209 img
= Canvas
.ctx
.getImageData(0, 0, width
, height
);
211 for (i
=0; i
< (width
* height
* 4); i
=i
+4) {
213 data
[i
+ 0] = arr
[j
+ 0];
214 data
[i
+ 1] = arr
[j
+ 1];
215 data
[i
+ 2] = arr
[j
+ 2];
216 data
[i
+ 3] = 255; // Set Alpha
218 Canvas
.ctx
.putImageData(img
, x
, y
);
222 fillRect: function(x
, y
, width
, height
, color
) {
223 var newStyle
= "rgb(" + color
[0] + "," + color
[1] + "," + color
[2] + ")";
224 if (newStyle
!== Canvas
.prevStyle
) {
225 Canvas
.ctx
.fillStyle
= newStyle
;
226 Canvas
.prevStyle
= newStyle
;
228 Canvas
.ctx
.fillRect(x
, y
, width
, height
);
231 copyImage: function(old_x
, old_y
, new_x
, new_y
, width
, height
) {
232 Canvas
.ctx
.drawImage($(Canvas
.id
), old_x
, old_y
, width
, height
,
233 new_x
, new_y
, width
, height
);
236 /* Translate DOM key event to keysym value */
237 getKeysym: function(e
) {
239 evt
= e
.event
|| window
.event
;
241 /* Remap modifier and special keys */
242 switch ( evt
.keyCode
) {
243 case 8 : keysym
= 0xFF08; break; // BACKSPACE
244 case 9 : keysym
= 0xFF09; break; // TAB
245 case 13 : keysym
= 0xFF0D; break; // ENTER
246 case 27 : keysym
= 0xFF1B; break; // ESCAPE
247 case 45 : keysym
= 0xFF63; break; // INSERT
248 case 46 : keysym
= 0xFFFF; break; // DELETE
249 case 36 : keysym
= 0xFF50; break; // HOME
250 case 35 : keysym
= 0xFF57; break; // END
251 case 33 : keysym
= 0xFF55; break; // PAGE_UP
252 case 34 : keysym
= 0xFF56; break; // PAGE_DOWN
253 case 37 : keysym
= 0xFF51; break; // LEFT
254 case 38 : keysym
= 0xFF52; break; // UP
255 case 39 : keysym
= 0xFF53; break; // RIGHT
256 case 40 : keysym
= 0xFF54; break; // DOWN
257 case 112 : keysym
= 0xFFBE; break; // F1
258 case 113 : keysym
= 0xFFBF; break; // F2
259 case 114 : keysym
= 0xFFC0; break; // F3
260 case 115 : keysym
= 0xFFC1; break; // F4
261 case 116 : keysym
= 0xFFC2; break; // F5
262 case 117 : keysym
= 0xFFC3; break; // F6
263 case 118 : keysym
= 0xFFC4; break; // F7
264 case 119 : keysym
= 0xFFC5; break; // F8
265 case 120 : keysym
= 0xFFC6; break; // F9
266 case 121 : keysym
= 0xFFC7; break; // F10
267 case 122 : keysym
= 0xFFC8; break; // F11
268 case 123 : keysym
= 0xFFC9; break; // F12
269 case 16 : keysym
= 0xFFE1; break; // SHIFT
270 case 17 : keysym
= 0xFFE3; break; // CONTROL
271 case 18 : keysym
= 0xFFE7; break; // ALT
272 default : keysym
= evt
.keyCode
; break;
277 case 186 : keysym
= 59; break; // ; (IE)
278 case 187 : keysym
= 61; break; // = (IE)
279 case 188 : keysym
= 44; break; // , (Mozilla, IE)
280 case 109 : // - (Mozilla)
281 if (Browser
.Engine
.gecko
) {
284 case 189 : keysym
= 45; break; // - (IE)
285 case 190 : keysym
= 46; break; // . (Mozilla, IE)
286 case 191 : keysym
= 47; break; // / (Mozilla, IE)
287 case 192 : keysym
= 96; break; // ` (Mozilla, IE)
288 case 219 : keysym
= 91; break; // [ (Mozilla, IE)
289 case 220 : keysym
= 92; break; // \ (Mozilla, IE)
290 case 221 : keysym
= 93; break; // ] (Mozilla, IE)
291 case 222 : keysym
= 39; break; // ' (Mozilla, IE)
294 /* Remap shifted and unshifted keys */
295 if (!!evt
.shiftKey
) {
297 case 48 : keysym
= 41 ; break; // ) (shifted 0)
298 case 49 : keysym
= 33 ; break; // ! (shifted 1)
299 case 50 : keysym
= 64 ; break; // @ (shifted 2)
300 case 51 : keysym
= 35 ; break; // # (shifted 3)
301 case 52 : keysym
= 36 ; break; // $ (shifted 4)
302 case 53 : keysym
= 37 ; break; // % (shifted 5)
303 case 54 : keysym
= 94 ; break; // ^ (shifted 6)
304 case 55 : keysym
= 38 ; break; // & (shifted 7)
305 case 56 : keysym
= 42 ; break; // * (shifted 8)
306 case 57 : keysym
= 40 ; break; // ( (shifted 9)
308 case 59 : keysym
= 58 ; break; // : (shifted `)
309 case 61 : keysym
= 43 ; break; // + (shifted ;)
310 case 44 : keysym
= 60 ; break; // < (shifted ,)
311 case 45 : keysym
= 95 ; break; // _ (shifted -)
312 case 46 : keysym
= 62 ; break; // > (shifted .)
313 case 47 : keysym
= 63 ; break; // ? (shifted /)
314 case 96 : keysym
= 126; break; // ~ (shifted `)
315 case 91 : keysym
= 123; break; // { (shifted [)
316 case 92 : keysym
= 124; break; // | (shifted \)
317 case 93 : keysym
= 125; break; // } (shifted ])
318 case 39 : keysym
= 34 ; break; // " (shifted ')
320 } else if ((keysym
>= 65) && (keysym
<=90)) {
321 /* Remap unshifted A-Z */