[Spice-devel] [PATCH spice-html5 v2 1/3] cursor: Add support for mono cursor type
Tomáš Bohdálek
tom.bohdalek at gmail.com
Thu Sep 14 10:06:55 UTC 2017
---
cursor.js | 18 +++++++--
png.js | 2 +-
spice.html | 1 +
spice_auto.html | 1 +
thirdparty/monocursor.js | 100 +++++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 117 insertions(+), 5 deletions(-)
create mode 100644 thirdparty/monocursor.js
diff --git a/cursor.js b/cursor.js
index d3f4d55..1fb1ede 100644
--- a/cursor.js
+++ b/cursor.js
@@ -62,7 +62,8 @@ SpiceCursorConn.prototype.process_channel_message = function(msg)
if (cursor_set.flags > 0)
this.log_warn("FIXME: No support for cursor flags " + cursor_set.flags);
- if (cursor_set.cursor.header.type != SPICE_CURSOR_TYPE_ALPHA)
+ if (cursor_set.cursor.header.type != SPICE_CURSOR_TYPE_ALPHA &&
+ cursor_set.cursor.header.type != SPICE_CURSOR_TYPE_MONO)
{
this.log_warn("FIXME: No support for cursor type " + cursor_set.cursor.header.type);
return false;
@@ -117,9 +118,18 @@ SpiceCursorConn.prototype.process_channel_message = function(msg)
SpiceCursorConn.prototype.set_cursor = function(cursor)
{
- var pngstr = create_rgba_png(cursor.header.height, cursor.header.width, cursor.data);
- var curstr = 'url(data:image/png,' + pngstr + ') ' +
- cursor.header.hot_spot_x + ' ' + cursor.header.hot_spot_y + ", default";
+ var pngstr = null;
+ if (cursor.header.type == SPICE_CURSOR_TYPE_ALPHA)
+ {
+ pngstr = create_rgba_png(cursor.header.height, cursor.header.width, cursor.data);
+ }
+ if (cursor.header.type == SPICE_CURSOR_TYPE_MONO)
+ {
+ pngstr = mono_cursor(cursor.header.height, cursor.header.width, cursor.data);
+ }
+
+ var curstr = 'url(' + pngstr + ') ' +
+ cursor.header.hot_spot_x + ' ' + cursor.header.hot_spot_y + ", default";
var screen = document.getElementById(this.parent.screen_id);
screen.style.cursor = 'auto';
screen.style.cursor = curstr;
diff --git a/png.js b/png.js
index 6a26151..5b52ed5 100644
--- a/png.js
+++ b/png.js
@@ -252,5 +252,5 @@ function create_rgba_png(width, height, bytes)
}
- return "%89PNG%0D%0A%1A%0A" + str;
+ return "data:image/png,%89PNG%0D%0A%1A%0A" + str;
}
diff --git a/spice.html b/spice.html
index 7abfcff..3a74e21 100644
--- a/spice.html
+++ b/spice.html
@@ -54,6 +54,7 @@
<script src="thirdparty/prng4.js"></script>
<script src="thirdparty/rng.js"></script>
<script src="thirdparty/sha1.js"></script>
+ <script src="thirdparty/monocursor.js"></script>
<script src="ticket.js"></script>
<script src="resize.js"></script>
<script src="filexfer.js"></script>
diff --git a/spice_auto.html b/spice_auto.html
index 2f04fc9..10f5508 100644
--- a/spice_auto.html
+++ b/spice_auto.html
@@ -54,6 +54,7 @@
<script src="thirdparty/prng4.js"></script>
<script src="thirdparty/rng.js"></script>
<script src="thirdparty/sha1.js"></script>
+ <script src="thirdparty/monocursor.js"></script>
<script src="ticket.js"></script>
<script src="resize.js"></script>
<script src="filexfer.js"></script>
diff --git a/thirdparty/monocursor.js b/thirdparty/monocursor.js
new file mode 100644
index 0000000..36ebd88
--- /dev/null
+++ b/thirdparty/monocursor.js
@@ -0,0 +1,100 @@
+/* Downloaded 1/6/2017 from https://github.com/eyeos/spice-web-client/blob/master/lib/graphic.js by Tomáš Bohdálek.
+
+License reproduce here for completeness:
+
+ eyeOS Spice Web Client
+Copyright (c) 2015 eyeOS S.L.
+
+Contact Jose Carlos Norte (jose at eyeos.com) for more information about this software.
+
+This program is free software; you can redistribute it and/or modify it under
+the terms of the GNU Affero General Public License version 3 as published by the
+Free Software Foundation.
+
+This program 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 Affero General Public License for more
+details.
+
+You should have received a copy of the GNU Affero General Public License
+version 3 along with this program in the file "LICENSE". If not, see
+<http://www.gnu.org/licenses/agpl-3.0.txt>.
+
+See www.eyeos.org for more details. All requests should be sent to licensing at eyeos.org
+
+The interactive user interfaces in modified source and object code versions
+of this program must display Appropriate Legal Notices, as required under
+Section 5 of the GNU Affero General Public License version 3.
+
+In accordance with Section 7(b) of the GNU Affero General Public License version 3,
+these Appropriate Legal Notices must retain the display of the "Powered by
+eyeos" logo and retain the original copyright notice. If the display of the
+logo is not reasonably feasible for technical reasons, the Appropriate Legal Notices
+must display the words "Powered by eyeos" and retain the original copyright notice.
+*/
+
+function mono_cursor(height, width, data)
+{
+ var monoMask = [1, 2, 4, 8, 16, 32, 64, 128];
+ var bytes = new Uint8Array(data);
+ var length = bytes.length;
+ var half = length / 2;
+
+ var canvas = document.createElement("canvas");
+ canvas.setAttribute('width', width);
+ canvas.setAttribute('height', height);
+ var context = canvas.getContext("2d");
+ var result = context.createImageData(width, height);
+
+ var andMask = [];
+ var xorMask = [];
+
+ for (var i = 0; i < length; i++) {
+ var currentByte = bytes[i];
+ var bitsLeft = 8;
+
+ if (i >= half) {
+ while (bitsLeft--) {
+ var bit = (currentByte & monoMask[bitsLeft]) && true;
+ andMask.push(bit);
+ }
+ } else if (i < half) {
+ while (bitsLeft--) {
+ var bit = (currentByte & monoMask[bitsLeft]) && true;
+ xorMask.push(bit);
+ }
+ }
+ }
+
+ var pos = 0;
+ half = xorMask.length;
+
+ for (i = 0; i < half; i++) {
+ pos = i * 4;
+ if (!andMask[i] && !xorMask[i]) {
+ result.data[pos] = 0;
+ result.data[pos + 1] = 0;
+ result.data[pos + 2] = 0;
+ result.data[pos + 3] = 255;
+ } else if (!andMask[i] && xorMask[i]) {
+ result.data[pos] = 255;
+ result.data[pos + 1] = 255;
+ result.data[pos + 2] = 255;
+ result.data[pos + 3] = 0;
+ } else if (andMask[i] && !xorMask[i]) {
+ result.data[pos] = 255;
+ result.data[pos + 1] = 255;
+ result.data[pos + 2] = 255;
+ result.data[pos + 3] = 255;
+ } else if (andMask[i] && xorMask[i]) {
+ result.data[pos] = 0;
+ result.data[pos + 1] = 0;
+ result.data[pos + 2] = 0;
+ result.data[pos + 3] = 255;
+ }
+ }
+
+ context.putImageData(result, 0, 0);
+
+ return canvas.toDataURL("image/png");
+}
--
2.9.5
More information about the Spice-devel
mailing list