3 * Guacamole - Clientless Remote Desktop
4 * Copyright (C) 2010 Michael Jumper
6 * This program is free software: you can redistribute it and/or modify
7 * it under the terms of the GNU Affero General Public License as published by
8 * the Free Software Foundation, either version 3 of the License, or
9 * (at your option) any later version.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU Affero General Public License for more details.
16 * You should have received a copy of the GNU Affero General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
20 function Layer(width, height) {
23 var display = document.createElement("canvas");
24 var displayContext = display.getContext("2d");
26 function resize(newWidth, newHeight) {
27 display.style.position = "absolute";
28 display.style.left = "0px";
29 display.style.right = "0px";
31 display.width = newWidth;
32 display.height = newHeight;
38 display.resize = function(newWidth, newHeight) {
39 if (newWidth != width || newHeight != height)
40 resize(newWidth, newHeight);
43 function fitRect(x, y, w, h) {
49 // Determine max width
52 resizeWidth = opBoundX;
56 // Determine max height
58 if (opBoundY > height)
59 resizeHeight = opBoundY;
61 resizeHeight = height;
63 // Resize if necessary
64 if (resizeWidth != width || resizeHeight != height)
65 resize(resizeWidth, resizeHeight);
69 resize(width, height);
71 var readyHandler = null;
72 var nextUpdateToDraw = 0;
73 var currentUpdate = 0;
74 var updates = new Array();
77 display.setAutosize = function(flag) {
81 // Given an update ID, either call the provided update callback, or
82 // schedule the update for later.
83 function setUpdate(updateId, update) {
85 // If this update is the next to draw...
86 if (updateId == nextUpdateToDraw) {
88 // Call provided update handler.
91 // Draw all pending updates.
93 while ((updateCallback = updates[++nextUpdateToDraw])) {
95 delete updates[nextUpdateToDraw];
98 // If done with updates, call ready handler
99 if (display.isReady() && readyHandler != null)
104 // If not next to draw, set callback and wait.
106 updates[updateId] = update;
110 display.isReady = function() {
111 return currentUpdate == nextUpdateToDraw;
114 display.setReadyHandler = function(handler) {
115 readyHandler = handler;
119 display.drawImage = function(x, y, image) {
120 var updateId = currentUpdate++;
122 setUpdate(updateId, function() {
123 if (autosize != 0) fitRect(x, y, image.width, image.height);
124 displayContext.drawImage(image, x, y);
130 display.draw = function(x, y, url) {
131 var updateId = currentUpdate++;
133 var image = new Image();
134 image.onload = function() {
135 setUpdate(updateId, function() {
136 if (autosize != 0) fitRect(x, y, image.width, image.height);
137 displayContext.drawImage(image, x, y);
144 display.copyRect = function(srcLayer, srcx, srcy, w, h, x, y) {
145 var updateId = currentUpdate++;
147 setUpdate(updateId, function() {
148 if (autosize != 0) fitRect(x, y, w, h);
149 displayContext.drawImage(srcLayer, srcx, srcy, w, h, x, y, w, h);
154 display.clearRect = function(x, y, w, h) {
155 var updateId = currentUpdate++;
157 setUpdate(updateId, function() {
158 if (autosize != 0) fitRect(x, y, w, h);
159 displayContext.clearRect(x, y, w, h);
164 display.filter = function(filter) {
165 var updateId = currentUpdate++;
167 setUpdate(updateId, function() {
168 var imageData = displayContext.getImageData(0, 0, width, height);
169 filter(imageData.data, width, height);
170 displayContext.putImageData(imageData, 0, 0);