diff --git a/guacamole-common/src/main/java/org/glyptodon/guacamole/protocol/ConfiguredGuacamoleSocket.java b/guacamole-common/src/main/java/org/glyptodon/guacamole/protocol/ConfiguredGuacamoleSocket.java index 5856b6cd3..ab5bffe88 100644 --- a/guacamole-common/src/main/java/org/glyptodon/guacamole/protocol/ConfiguredGuacamoleSocket.java +++ b/guacamole-common/src/main/java/org/glyptodon/guacamole/protocol/ConfiguredGuacamoleSocket.java @@ -183,6 +183,13 @@ public class ConfiguredGuacamoleSocket implements GuacamoleSocket { info.getVideoMimetypes().toArray(new String[0]) )); + // Send supported image formats + writer.writeInstruction( + new GuacamoleInstruction( + "image", + info.getImageMimetypes().toArray(new String[0]) + )); + // Send args writer.writeInstruction(new GuacamoleInstruction("connect", arg_values)); diff --git a/guacamole-common/src/main/java/org/glyptodon/guacamole/protocol/GuacamoleClientInformation.java b/guacamole-common/src/main/java/org/glyptodon/guacamole/protocol/GuacamoleClientInformation.java index 2974c94d4..5a1e5043a 100644 --- a/guacamole-common/src/main/java/org/glyptodon/guacamole/protocol/GuacamoleClientInformation.java +++ b/guacamole-common/src/main/java/org/glyptodon/guacamole/protocol/GuacamoleClientInformation.java @@ -55,10 +55,15 @@ public class GuacamoleClientInformation { private final List audioMimetypes = new ArrayList(); /** - * The list of audio mimetypes reported by the client to be supported. + * The list of video mimetypes reported by the client to be supported. */ private final List videoMimetypes = new ArrayList(); + /** + * The list of image mimetypes reported by the client to be supported. + */ + private final List imageMimetypes = new ArrayList(); + /** * Returns the optimal screen width requested by the client, in pixels. * @return The optimal screen width requested by the client, in pixels. @@ -133,4 +138,15 @@ public class GuacamoleClientInformation { return videoMimetypes; } + /** + * Returns the list of image mimetypes supported by the client. To add or + * removed supported mimetypes, the list returned by this function can be + * modified. + * + * @return The set of video mimetypes supported by the client. + */ + public List getImageMimetypes() { + return imageMimetypes; + } + } diff --git a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/TunnelRequestService.java b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/TunnelRequestService.java index 974ed4a7e..1e3eea992 100644 --- a/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/TunnelRequestService.java +++ b/guacamole/src/main/java/org/glyptodon/guacamole/net/basic/TunnelRequestService.java @@ -112,6 +112,11 @@ public class TunnelRequestService { if (video_mimetypes != null) info.getVideoMimetypes().addAll(video_mimetypes); + // Add image mimetypes + List image_mimetypes = request.getParameterValues("image"); + if (image_mimetypes != null) + info.getImageMimetypes().addAll(image_mimetypes); + return info; } diff --git a/guacamole/src/main/webapp/app/client/services/guacImage.js b/guacamole/src/main/webapp/app/client/services/guacImage.js new file mode 100644 index 000000000..ff70688f3 --- /dev/null +++ b/guacamole/src/main/webapp/app/client/services/guacImage.js @@ -0,0 +1,63 @@ +/* + * Copyright (C) 2015 Glyptodon LLC + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ + +/** + * A service for checking browser non-standard image format support for + * formats such as Google's WebP. + */ + +angular.module('client').factory('guacImage', [function guacImage() { + + /** + * Object describing the UI's level of non-standard image format support. + */ + return new (function () { + + /** + * All non-standard image formats to test along with a 1x1 sized + * base64 encoded test image. + */ + var formats = { + 'image/webp': 'data:image/webp;base64,UklGRhoAAABXRUJQVlA4TA0AAAAvAAAAEAcQERGIiP4HAA==', + }; + + /** + * Array of supported (non-standard) image mimetypes. + */ + this.supported = []; + + // Build array of supported image formats + angular.forEach(formats, function(testImgUri, format) { + var image = document.createElement("img"); + image.src = testImgUri; + image.onload = image.onerror = (function (_this) { + return function() { + if (image.width === 1) { + _this.supported.push(format); + } + }; + })(this); + }, this); + + })(); + +}]); diff --git a/guacamole/src/main/webapp/app/client/types/ManagedClient.js b/guacamole/src/main/webapp/app/client/types/ManagedClient.js index 822a80870..5e1de8a4e 100644 --- a/guacamole/src/main/webapp/app/client/types/ManagedClient.js +++ b/guacamole/src/main/webapp/app/client/types/ManagedClient.js @@ -42,6 +42,7 @@ angular.module('client').factory('ManagedClient', ['$rootScope', '$injector', var connectionService = $injector.get('connectionService'); var guacAudio = $injector.get('guacAudio'); var guacHistory = $injector.get('guacHistory'); + var guacImage = $injector.get('guacImage'); var guacVideo = $injector.get('guacVideo'); /** @@ -190,6 +191,11 @@ angular.module('client').factory('ManagedClient', ['$rootScope', '$injector', connectString += "&video=" + encodeURIComponent(mimetype); }); + // Add non-standard image mimetypes to connect_string + guacImage.supported.forEach(function(mimetype) { + connectString += "&image=" + encodeURIComponent(mimetype); + }); + return connectString; }; diff --git a/guacamole/src/main/webapp/app/index/controllers/indexController.js b/guacamole/src/main/webapp/app/index/controllers/indexController.js index 3980568d1..0ee39a06a 100644 --- a/guacamole/src/main/webapp/app/index/controllers/indexController.js +++ b/guacamole/src/main/webapp/app/index/controllers/indexController.js @@ -31,6 +31,9 @@ angular.module('index').controller('indexController', ['$scope', '$injector', var $window = $injector.get('$window'); var guacNotification = $injector.get('guacNotification'); + // Request guacImage service early as it needs time to load images + var guacImage = $injector.get('guacImage'); + /** * The notification service. */