]>
Commit | Line | Data |
---|---|---|
15046f00 JM |
1 | /* |
2 | * noVNC: HTML5 VNC client | |
d0c29bb6 | 3 | * Copyright (C) 2011 Joel Martin |
5f409eee | 4 | * Licensed under LGPL-3 (see LICENSE.txt) |
15046f00 JM |
5 | * |
6 | * See README.md for usage and integration instructions. | |
7 | */ | |
43cf7bd8 | 8 | |
15046f00 | 9 | "use strict"; |
43cf7bd8 | 10 | /*jslint white: false, browser: true */ |
d890e864 | 11 | /*global window, $D, Util, WebUtil, RFB, Display */ |
15046f00 | 12 | |
f7ec5b2c | 13 | var UI = { |
91308399 | 14 | |
da6dd893 JM |
15 | settingsOpen : false, |
16 | ||
f7ec5b2c | 17 | // Render default UI and initialize settings menu |
91308399 | 18 | load: function(target) { |
f7ec5b2c | 19 | var html = '', i, sheet, sheets, llevels; |
91308399 | 20 | |
f7ec5b2c | 21 | /* Populate the 'target' DOM element with default UI */ |
e4671910 JM |
22 | if (!target) { |
23 | target = $D('vnc'); | |
24 | } else if (typeof target === 'string') { | |
25 | target = $D(target); | |
26 | } | |
91308399 | 27 | |
e66f3f89 JM |
28 | if ((!document.createElement('canvas').getContext) && |
29 | window.ActiveXObject) { | |
30 | // Suggest Chrome frame for Internet Explorer users | |
31 | html += '<center><div style="text-align: left; width: 400px">'; | |
32 | html += ' You are using a version of Internet Explorer '; | |
33 | html += ' that does not have HTML5 Canvas support. '; | |
34 | html += ' To use noVNC you must use a browser with HTML5 '; | |
35 | html += ' Canvas support or install '; | |
36 | html += ' <a href="http://google.com/chromeframe" target="cframe">'; | |
37 | html += ' Google Chrome Frame.</a>'; | |
38 | html += '</div></center>'; | |
e4671910 | 39 | target.innerHTML = html; |
e66f3f89 JM |
40 | return; |
41 | } | |
42 | ||
91308399 JM |
43 | html += '<div id="VNC_controls">'; |
44 | html += ' <ul>'; | |
45 | html += ' <li>Host: <input id="VNC_host"></li>'; | |
46 | html += ' <li>Port: <input id="VNC_port"></li>'; | |
47 | html += ' <li>Password: <input id="VNC_password"'; | |
48 | html += ' type="password"></li>'; | |
91308399 JM |
49 | html += ' <li><input id="VNC_connect_button" type="button"'; |
50 | html += ' value="Loading" disabled></li>'; | |
51 | html += ' </ul>'; | |
52 | html += '</div>'; | |
53 | html += '<div id="VNC_screen">'; | |
63708ff5 JM |
54 | html += ' <div id="VNC_status_bar" class="VNC_status_bar" style="margin-top: 0px;">'; |
55 | html += ' <table border=0 width=100%><tr>'; | |
56 | html += ' <td><div id="VNC_status">Loading</div></td>'; | |
ad3f7624 JM |
57 | |
58 | // Mouse button selectors for touch devices | |
59 | html += ' <td width=1%><div class="VNC_buttons_right">'; | |
60 | html += ' <nobr><span id="VNC_mouse_buttons" style="display: none;">'; | |
61 | html += ' <input type="button" class="VNC_status_button"'; | |
62 | html += ' id="VNC_mouse_button1" value="L" onclick="UI.setMouseButton(1);"'; | |
63 | html += ' ><input type="button" class="VNC_status_button"'; | |
64 | html += ' id="VNC_mouse_button2" value="M" onclick="UI.setMouseButton(2);"'; | |
65 | html += ' ><input type="button" class="VNC_status_button"'; | |
66 | html += ' id="VNC_mouse_button4" value="R" onclick="UI.setMouseButton(4);">'; | |
7825b9ee | 67 | html += ' <input type="button" id="showKeyboard" onclick="showkeyboard()" value="Keyboard" />'; |
ad3f7624 JM |
68 | html += ' </span></nobr></div></td>'; |
69 | ||
70 | // Settings drop-down menu | |
da6dd893 JM |
71 | html += ' <td width=1%><div class="VNC_buttons_right">'; |
72 | html += ' <input type=button class="VNC_status_button" value="Settings"'; | |
73 | html += ' id="menuButton"'; | |
f7ec5b2c | 74 | html += ' onclick="UI.clickSettingsMenu();">'; |
da6dd893 | 75 | html += ' <span id="VNC_settings_menu"'; |
d890e864 JM |
76 | html += ' onmouseover="UI.displayBlur();"'; |
77 | html += ' onmouseout="UI.displayFocus();">'; | |
da6dd893 JM |
78 | html += ' <ul>'; |
79 | html += ' <li><input id="VNC_encrypt"'; | |
208c832b | 80 | html += ' type="checkbox"> Encrypt</li>'; |
da6dd893 JM |
81 | html += ' <li><input id="VNC_true_color"'; |
82 | html += ' type="checkbox" checked> True Color</li>'; | |
83 | html += ' <li><input id="VNC_cursor"'; | |
31a837d5 | 84 | html += ' type="checkbox"> Local Cursor</li>'; |
f1a9971c JM |
85 | html += ' <li><input id="VNC_shared"'; |
86 | html += ' type="checkbox"> Shared Mode</li>'; | |
ff36b127 JM |
87 | html += ' <li><input id="VNC_connectTimeout"'; |
88 | html += ' type="input"> Connect Timeout (s)</li>'; | |
da6dd893 JM |
89 | html += ' <hr>'; |
90 | ||
91 | // Stylesheet selection dropdown | |
92 | html += ' <li><select id="VNC_stylesheet" name="vncStyle">'; | |
93 | html += ' <option value="default">default</option>'; | |
8d5d2c82 AM |
94 | sheet = WebUtil.selectStylesheet(); |
95 | sheets = WebUtil.getStylesheets(); | |
8db09746 | 96 | for (i = 0; i < sheets.length; i += 1) { |
da6dd893 JM |
97 | html += '<option value="' + sheets[i].title + '">' + sheets[i].title + '</option>'; |
98 | } | |
99 | html += ' </select> Style</li>'; | |
100 | ||
101 | // Logging selection dropdown | |
102 | html += ' <li><select id="VNC_logging" name="vncLogging">'; | |
103 | llevels = ['error', 'warn', 'info', 'debug']; | |
8db09746 | 104 | for (i = 0; i < llevels.length; i += 1) { |
da6dd893 JM |
105 | html += '<option value="' + llevels[i] + '">' + llevels[i] + '</option>'; |
106 | } | |
107 | html += ' </select> Logging</li>'; | |
108 | ||
109 | html += ' <hr>'; | |
110 | html += ' <li><input type="button" id="VNC_apply" value="Apply"'; | |
f7ec5b2c | 111 | html += ' onclick="UI.settingsApply()"></li>'; |
da6dd893 JM |
112 | html += ' </ul>'; |
113 | html += ' </span></div></td>'; | |
ad3f7624 JM |
114 | |
115 | // CtrlAltDel Button | |
da6dd893 | 116 | html += ' <td width=1%><div class="VNC_buttons_right">'; |
ad3f7624 | 117 | html += ' <input type=button class="VNC_status_button" value="CtrlAltDel"'; |
160fabf6 | 118 | html += ' id="sendCtrlAltDelButton"'; |
f7ec5b2c | 119 | html += ' onclick="UI.sendCtrlAltDel();"></div></td>'; |
ad3f7624 | 120 | |
63708ff5 JM |
121 | html += ' </tr></table>'; |
122 | html += ' </div>'; | |
91308399 JM |
123 | html += ' <canvas id="VNC_canvas" width="640px" height="20px">'; |
124 | html += ' Canvas not supported.'; | |
125 | html += ' </canvas>'; | |
7825b9ee | 126 | html += '<input id="keyboardinput" style="border:none;" type="text" onKeyDown="onKeyDown(event);"/>'; |
91308399 JM |
127 | html += '</div>'; |
128 | html += '<br><br>'; | |
129 | html += '<div id="VNC_clipboard">'; | |
130 | html += ' VNC Clipboard:'; | |
131 | html += ' <input id="VNC_clipboard_clear_button"'; | |
132 | html += ' type="button" value="Clear"'; | |
f7ec5b2c | 133 | html += ' onclick="UI.clipClear();">'; |
91308399 JM |
134 | html += ' <br>'; |
135 | html += ' <textarea id="VNC_clipboard_text" cols=80 rows=5'; | |
d890e864 JM |
136 | html += ' onfocus="UI.displayBlur();"'; |
137 | html += ' onblur="UI.displayFocus();"'; | |
f7ec5b2c | 138 | html += ' onchange="UI.clipSend();"></textarea>'; |
91308399 | 139 | html += '</div>'; |
e4671910 | 140 | target.innerHTML = html; |
91308399 | 141 | |
da6dd893 | 142 | // Settings with immediate effects |
f7ec5b2c JM |
143 | UI.initSetting('logging', 'warn'); |
144 | WebUtil.init_logging(UI.getSetting('logging')); | |
145 | UI.initSetting('stylesheet', 'default'); | |
8db09746 | 146 | |
8d5d2c82 | 147 | WebUtil.selectStylesheet(null); // call twice to get around webkit bug |
f7ec5b2c | 148 | WebUtil.selectStylesheet(UI.getSetting('stylesheet')); |
da6dd893 | 149 | |
91308399 | 150 | /* Populate the controls if defaults are provided in the URL */ |
f7ec5b2c JM |
151 | UI.initSetting('host', ''); |
152 | UI.initSetting('port', ''); | |
153 | UI.initSetting('password', ''); | |
154 | UI.initSetting('encrypt', false); | |
155 | UI.initSetting('true_color', true); | |
156 | UI.initSetting('cursor', false); | |
157 | UI.initSetting('shared', true); | |
158 | UI.initSetting('connectTimeout', 2); | |
159 | ||
e4671910 | 160 | UI.rfb = RFB({'target': $D('VNC_canvas'), |
d890e864 JM |
161 | 'onUpdateState': UI.updateState, |
162 | 'onClipboard': UI.clipReceive}); | |
8db09746 JM |
163 | |
164 | // Unfocus clipboard when over the VNC area | |
e4671910 | 165 | $D('VNC_screen').onmousemove = function () { |
d1bd5ec7 JM |
166 | var keyboard = UI.rfb.get_keyboard(); |
167 | if ((! keyboard) || (! keyboard.get_focused())) { | |
e4671910 | 168 | $D('VNC_clipboard_text').blur(); |
3954ae14 JM |
169 | } |
170 | }; | |
8db09746 | 171 | |
ad3f7624 JM |
172 | // Show mouse selector buttons on touch screen devices |
173 | if ('ontouchstart' in document.documentElement) { | |
174 | $D('VNC_mouse_buttons').style.display = "inline"; | |
175 | UI.setMouseButton(); | |
176 | } | |
177 | ||
91308399 JM |
178 | }, |
179 | ||
da6dd893 JM |
180 | // Read form control compatible setting from cookie |
181 | getSetting: function(name) { | |
e4671910 | 182 | var val, ctrl = $D('VNC_' + name); |
8d5d2c82 | 183 | val = WebUtil.readCookie(name); |
da6dd893 JM |
184 | if (ctrl.type === 'checkbox') { |
185 | if (val.toLowerCase() in {'0':1, 'no':1, 'false':1}) { | |
186 | val = false; | |
187 | } else { | |
188 | val = true; | |
189 | } | |
190 | } | |
191 | return val; | |
192 | }, | |
193 | ||
194 | // Update cookie and form control setting. If value is not set, then | |
195 | // updates from control to current cookie setting. | |
196 | updateSetting: function(name, value) { | |
e4671910 | 197 | var i, ctrl = $D('VNC_' + name); |
da6dd893 JM |
198 | // Save the cookie for this session |
199 | if (typeof value !== 'undefined') { | |
8d5d2c82 | 200 | WebUtil.createCookie(name, value); |
da6dd893 JM |
201 | } |
202 | ||
203 | // Update the settings control | |
f7ec5b2c | 204 | value = UI.getSetting(name); |
da6dd893 JM |
205 | if (ctrl.type === 'checkbox') { |
206 | ctrl.checked = value; | |
207 | } else if (typeof ctrl.options !== 'undefined') { | |
8db09746 | 208 | for (i = 0; i < ctrl.options.length; i += 1) { |
da6dd893 JM |
209 | if (ctrl.options[i].value === value) { |
210 | ctrl.selectedIndex = i; | |
211 | break; | |
212 | } | |
213 | } | |
214 | } else { | |
215 | ctrl.value = value; | |
216 | } | |
217 | }, | |
218 | ||
219 | // Save control setting to cookie | |
220 | saveSetting: function(name) { | |
e4671910 | 221 | var val, ctrl = $D('VNC_' + name); |
da6dd893 JM |
222 | if (ctrl.type === 'checkbox') { |
223 | val = ctrl.checked; | |
224 | } else if (typeof ctrl.options !== 'undefined') { | |
225 | val = ctrl.options[ctrl.selectedIndex].value; | |
226 | } else { | |
227 | val = ctrl.value; | |
228 | } | |
8d5d2c82 | 229 | WebUtil.createCookie(name, val); |
8db09746 | 230 | //Util.Debug("Setting saved '" + name + "=" + val + "'"); |
da6dd893 JM |
231 | return val; |
232 | }, | |
233 | ||
234 | // Initial page load read/initialization of settings | |
235 | initSetting: function(name, defVal) { | |
a8edf9d8 | 236 | var val; |
da6dd893 JM |
237 | |
238 | // Check Query string followed by cookie | |
8d5d2c82 | 239 | val = WebUtil.getQueryVar(name); |
da6dd893 | 240 | if (val === null) { |
8d5d2c82 | 241 | val = WebUtil.readCookie(name, defVal); |
da6dd893 | 242 | } |
f7ec5b2c | 243 | UI.updateSetting(name, val); |
8db09746 | 244 | //Util.Debug("Setting '" + name + "' initialized to '" + val + "'"); |
da6dd893 JM |
245 | return val; |
246 | }, | |
247 | ||
248 | ||
249 | // Toggle the settings menu: | |
250 | // On open, settings are refreshed from saved cookies. | |
251 | // On close, settings are applied | |
252 | clickSettingsMenu: function() { | |
f7ec5b2c JM |
253 | if (UI.settingsOpen) { |
254 | UI.settingsApply(); | |
da6dd893 | 255 | |
f7ec5b2c | 256 | UI.closeSettingsMenu(); |
da6dd893 | 257 | } else { |
f7ec5b2c JM |
258 | UI.updateSetting('encrypt'); |
259 | UI.updateSetting('true_color'); | |
d890e864 | 260 | if (UI.rfb.get_display().get_cursor_uri()) { |
f7ec5b2c | 261 | UI.updateSetting('cursor'); |
da6dd893 | 262 | } else { |
f7ec5b2c | 263 | UI.updateSetting('cursor', false); |
e4671910 | 264 | $D('VNC_cursor').disabled = true; |
da6dd893 | 265 | } |
f7ec5b2c JM |
266 | UI.updateSetting('shared'); |
267 | UI.updateSetting('connectTimeout'); | |
268 | UI.updateSetting('stylesheet'); | |
269 | UI.updateSetting('logging'); | |
da6dd893 | 270 | |
f7ec5b2c | 271 | UI.openSettingsMenu(); |
da6dd893 JM |
272 | } |
273 | }, | |
274 | ||
275 | // Open menu | |
276 | openSettingsMenu: function() { | |
e4671910 | 277 | $D('VNC_settings_menu').style.display = "block"; |
f7ec5b2c | 278 | UI.settingsOpen = true; |
da6dd893 JM |
279 | }, |
280 | ||
281 | // Close menu (without applying settings) | |
282 | closeSettingsMenu: function() { | |
e4671910 | 283 | $D('VNC_settings_menu').style.display = "none"; |
f7ec5b2c | 284 | UI.settingsOpen = false; |
da6dd893 JM |
285 | }, |
286 | ||
287 | // Disable/enable controls depending on connection state | |
b5087acc JM |
288 | settingsDisabled: function(disabled, rfb) { |
289 | //Util.Debug(">> settingsDisabled"); | |
e4671910 JM |
290 | $D('VNC_encrypt').disabled = disabled; |
291 | $D('VNC_true_color').disabled = disabled; | |
d890e864 | 292 | if (rfb && rfb.get_display() && rfb.get_display().get_cursor_uri()) { |
e4671910 | 293 | $D('VNC_cursor').disabled = disabled; |
da6dd893 | 294 | } else { |
f7ec5b2c | 295 | UI.updateSetting('cursor', false); |
e4671910 | 296 | $D('VNC_cursor').disabled = true; |
da6dd893 | 297 | } |
e4671910 JM |
298 | $D('VNC_shared').disabled = disabled; |
299 | $D('VNC_connectTimeout').disabled = disabled; | |
b5087acc | 300 | //Util.Debug("<< settingsDisabled"); |
da6dd893 JM |
301 | }, |
302 | ||
303 | // Save/apply settings when 'Apply' button is pressed | |
304 | settingsApply: function() { | |
8db09746 | 305 | //Util.Debug(">> settingsApply"); |
f7ec5b2c JM |
306 | UI.saveSetting('encrypt'); |
307 | UI.saveSetting('true_color'); | |
d890e864 | 308 | if (UI.rfb.get_display().get_cursor_uri()) { |
f7ec5b2c | 309 | UI.saveSetting('cursor'); |
da6dd893 | 310 | } |
f7ec5b2c JM |
311 | UI.saveSetting('shared'); |
312 | UI.saveSetting('connectTimeout'); | |
313 | UI.saveSetting('stylesheet'); | |
314 | UI.saveSetting('logging'); | |
da6dd893 JM |
315 | |
316 | // Settings with immediate (non-connected related) effect | |
f7ec5b2c JM |
317 | WebUtil.selectStylesheet(UI.getSetting('stylesheet')); |
318 | WebUtil.init_logging(UI.getSetting('logging')); | |
da6dd893 | 319 | |
8db09746 | 320 | //Util.Debug("<< settingsApply"); |
da6dd893 JM |
321 | }, |
322 | ||
323 | ||
324 | ||
f00b1e37 | 325 | setPassword: function() { |
e4671910 | 326 | UI.rfb.sendPassword($D('VNC_password').value); |
f00b1e37 JM |
327 | return false; |
328 | }, | |
329 | ||
63708ff5 | 330 | sendCtrlAltDel: function() { |
f7ec5b2c | 331 | UI.rfb.sendCtrlAltDel(); |
63708ff5 JM |
332 | }, |
333 | ||
ad3f7624 JM |
334 | setMouseButton: function(num) { |
335 | var b, blist = [1,2,4], button, | |
336 | mouse = UI.rfb.get_mouse(); | |
337 | ||
338 | if (typeof num === 'undefined') { | |
339 | // Show the default | |
340 | num = mouse.get_touchButton(); | |
341 | } else if (num === mouse.get_touchButton()) { | |
342 | // Set all buttons off (no clicks) | |
343 | mouse.set_touchButton(0); | |
344 | num = 0; | |
345 | } else { | |
346 | // Turn on one button | |
347 | mouse.set_touchButton(num); | |
348 | } | |
349 | ||
350 | for (b = 0; b < blist.length; b++) { | |
351 | button = $D('VNC_mouse_button' + blist[b]); | |
352 | if (blist[b] === num) { | |
353 | button.style.backgroundColor = "black"; | |
354 | button.style.color = "lightgray"; | |
355 | } else { | |
356 | button.style.backgroundColor = ""; | |
357 | button.style.color = ""; | |
358 | } | |
359 | } | |
360 | ||
361 | }, | |
362 | ||
8db09746 | 363 | updateState: function(rfb, state, oldstate, msg) { |
a7a89626 | 364 | var s, sb, c, cad, klass; |
e4671910 JM |
365 | s = $D('VNC_status'); |
366 | sb = $D('VNC_status_bar'); | |
367 | c = $D('VNC_connect_button'); | |
368 | cad = $D('sendCtrlAltDelButton'); | |
91308399 JM |
369 | switch (state) { |
370 | case 'failed': | |
f00b1e37 | 371 | case 'fatal': |
91308399 | 372 | c.disabled = true; |
160fabf6 | 373 | cad.disabled = true; |
f7ec5b2c | 374 | UI.settingsDisabled(true, rfb); |
91308399 JM |
375 | klass = "VNC_status_error"; |
376 | break; | |
377 | case 'normal': | |
378 | c.value = "Disconnect"; | |
f7ec5b2c | 379 | c.onclick = UI.disconnect; |
91308399 | 380 | c.disabled = false; |
160fabf6 | 381 | cad.disabled = false; |
f7ec5b2c | 382 | UI.settingsDisabled(true, rfb); |
91308399 JM |
383 | klass = "VNC_status_normal"; |
384 | break; | |
385 | case 'disconnected': | |
f00b1e37 | 386 | case 'loaded': |
91308399 | 387 | c.value = "Connect"; |
f7ec5b2c | 388 | c.onclick = UI.connect; |
91308399 JM |
389 | |
390 | c.disabled = false; | |
160fabf6 | 391 | cad.disabled = true; |
f7ec5b2c | 392 | UI.settingsDisabled(false, rfb); |
91308399 JM |
393 | klass = "VNC_status_normal"; |
394 | break; | |
f00b1e37 JM |
395 | case 'password': |
396 | c.value = "Send Password"; | |
f7ec5b2c | 397 | c.onclick = UI.setPassword; |
f00b1e37 JM |
398 | |
399 | c.disabled = false; | |
400 | cad.disabled = true; | |
f7ec5b2c | 401 | UI.settingsDisabled(true, rfb); |
f00b1e37 JM |
402 | klass = "VNC_status_warn"; |
403 | break; | |
91308399 JM |
404 | default: |
405 | c.disabled = true; | |
160fabf6 | 406 | cad.disabled = true; |
f7ec5b2c | 407 | UI.settingsDisabled(true, rfb); |
91308399 JM |
408 | klass = "VNC_status_warn"; |
409 | break; | |
410 | } | |
411 | ||
412 | if (typeof(msg) !== 'undefined') { | |
413 | s.setAttribute("class", klass); | |
63708ff5 | 414 | sb.setAttribute("class", klass); |
91308399 JM |
415 | s.innerHTML = msg; |
416 | } | |
417 | ||
418 | }, | |
419 | ||
8db09746 | 420 | clipReceive: function(rfb, text) { |
f7ec5b2c | 421 | Util.Debug(">> UI.clipReceive: " + text.substr(0,40) + "..."); |
e4671910 | 422 | $D('VNC_clipboard_text').value = text; |
f7ec5b2c | 423 | Util.Debug("<< UI.clipReceive"); |
8db09746 JM |
424 | }, |
425 | ||
426 | ||
91308399 | 427 | connect: function() { |
f7ec5b2c | 428 | var host, port, password; |
da6dd893 | 429 | |
f7ec5b2c | 430 | UI.closeSettingsMenu(); |
da6dd893 | 431 | |
e4671910 JM |
432 | host = $D('VNC_host').value; |
433 | port = $D('VNC_port').value; | |
434 | password = $D('VNC_password').value; | |
91308399 | 435 | if ((!host) || (!port)) { |
63708ff5 | 436 | throw("Must set host and port"); |
91308399 JM |
437 | } |
438 | ||
f7ec5b2c JM |
439 | UI.rfb.set_encrypt(UI.getSetting('encrypt')); |
440 | UI.rfb.set_true_color(UI.getSetting('true_color')); | |
441 | UI.rfb.set_local_cursor(UI.getSetting('cursor')); | |
442 | UI.rfb.set_shared(UI.getSetting('shared')); | |
443 | UI.rfb.set_connectTimeout(UI.getSetting('connectTimeout')); | |
da6dd893 | 444 | |
f7ec5b2c | 445 | UI.rfb.connect(host, port, password); |
91308399 JM |
446 | }, |
447 | ||
448 | disconnect: function() { | |
f7ec5b2c | 449 | UI.closeSettingsMenu(); |
da6dd893 | 450 | |
f7ec5b2c | 451 | UI.rfb.disconnect(); |
91308399 JM |
452 | }, |
453 | ||
d890e864 | 454 | displayBlur: function() { |
d1bd5ec7 JM |
455 | UI.rfb.get_keyboard().set_focused(false); |
456 | UI.rfb.get_mouse().set_focused(false); | |
91308399 JM |
457 | }, |
458 | ||
d890e864 | 459 | displayFocus: function() { |
d1bd5ec7 JM |
460 | UI.rfb.get_keyboard().set_focused(true); |
461 | UI.rfb.get_mouse().set_focused(true); | |
91308399 JM |
462 | }, |
463 | ||
464 | clipClear: function() { | |
e4671910 | 465 | $D('VNC_clipboard_text').value = ""; |
f7ec5b2c | 466 | UI.rfb.clipboardPasteFrom(""); |
91308399 JM |
467 | }, |
468 | ||
469 | clipSend: function() { | |
e4671910 | 470 | var text = $D('VNC_clipboard_text').value; |
f7ec5b2c JM |
471 | Util.Debug(">> UI.clipSend: " + text.substr(0,40) + "..."); |
472 | UI.rfb.clipboardPasteFrom(text); | |
473 | Util.Debug("<< UI.clipSend"); | |
91308399 JM |
474 | } |
475 | ||
63708ff5 | 476 | }; |
7825b9ee CG |
477 | |
478 | /* | |
479 | Functions for use of mobile devices native keyboards | |
480 | Added by Chris Gordon | |
481 | http://www.chrisgordon.com.au | |
482 | Date: 23/08/2011 | |
483 | */ | |
484 | ||
485 | function showkeyboard(){ | |
486 | //Get Current Scroll Position of Browser | |
487 | var scrollx = (document.all)?document.body.scrollLeft:window.pageXOffset; | |
488 | var scrolly = (document.all)?document.body.scrollTop:window.pageYOffset; | |
489 | ||
490 | //Stop browser zooming on textbox when focus is set. | |
491 | zoomDisable(); | |
492 | ||
493 | //Focus on hidden textbox to bring up native keyboard. | |
494 | document.getElementById('keyboardinput').focus(); | |
495 | ||
496 | //Set scroll position of browser to the same position it was prior to focus. | |
497 | scroll(scrollx,scrolly); | |
498 | ||
499 | //Renable user zooming. | |
500 | zoomEnable(); | |
501 | } | |
502 | ||
503 | function zoomDisable(){ | |
504 | //Change viewport meta data to disable zooming. | |
1734b5e4 | 505 | changeViewportMeta("user-scalable=0"); |
7825b9ee CG |
506 | } |
507 | ||
508 | function zoomEnable(){ | |
509 | //Change viewport meta data to enable user zooming. | |
1734b5e4 CG |
510 | changeViewportMeta("user-scalable=1"); |
511 | } | |
512 | ||
513 | function changeViewportMeta(newattributes) { | |
514 | ||
515 | // First, get the array of meta-tag elements | |
516 | var metatags = document.getElementsByTagName("meta"); | |
517 | ||
518 | // Update only the Viewport meta tag | |
519 | for (var cnt = 0; cnt < metatags.length; cnt++) | |
520 | { | |
521 | ||
522 | var name = metatags[cnt].getAttribute("name"); | |
523 | var content = metatags[cnt].getAttribute("content"); | |
524 | ||
525 | // Update the Viewport meta tag | |
526 | if (metatags[cnt].getAttribute("name") == "viewport") | |
527 | metatags[cnt].setAttribute("content", newattributes); | |
528 | } | |
7825b9ee | 529 | } |