return null;
}
-/* This resizes the window so the *inner* size is the specified size */
-function resizeBrowserWindow(window, w, h) {
- var innerW = window.innerWidth;
- var innerH = window.innerHeight;
-
- var outerW = window.outerWidth;
- var outerH = window.outerHeight;
-
- window.resizeTo(w + outerW - innerW,
- h + outerH - innerH);
-}
-
function resizeCanvas(canvas, w, h)
{
/* Canvas resize clears the data, so we need to save it first */
context.drawImage(tmpCanvas, 0, 0, tmpCanvas.width, tmpCanvas.height);
}
-var useToplevelWindows = false;
-var toplevelWindows = [];
var grab = new Object();
grab.window = null;
grab.ownerEvents = false;
}
}
-function ensureSurfaceInDocument(surface, doc)
-{
- if (surface.document != doc) {
- var oldCanvas = surface.canvas;
- var canvas = doc.importNode(oldCanvas, false);
- doc.body.appendChild(canvas);
- canvas.surface = surface;
- oldCanvas.parentNode.removeChild(oldCanvas);
-
- surface.canvas = canvas;
- if (surface.toplevelElement == oldCanvas)
- surface.toplevelElement = canvas;
- surface.document = doc;
- }
-}
-
function sendConfigureNotify(surface)
{
sendInput("w", [surface.id, surface.x, surface.y, surface.width, surface.height]);
}
-var windowGeometryTimeout = null;
-
-function updateBrowserWindowGeometry(win, alwaysSendConfigure) {
- if (win.closed)
- return;
-
- var surface = win.surface;
-
- var innerW = win.innerWidth;
- var innerH = win.innerHeight;
-
- var x = surface.x;
- var y = surface.y;
-
- if (win.mozInnerScreenX != undefined) {
- x = win.mozInnerScreenX;
- y = win.mozInnerScreenY;
- } else if (win.screenTop != undefined) {
- x = win.screenTop;
- y = win.screenLeft;
- } else {
- alert("No implementation to get window position");
- }
-
- if (alwaysSendConfigure || x != surface.x || y != surface.y ||
- innerW != surface.width || innerH != surface.height) {
- var oldX = surface.x;
- var oldY = surface.y;
- surface.x = x;
- surface.y = y;
- if (surface.width != innerW || surface.height != innerH)
- resizeCanvas(surface.canvas, innerW, innerH);
- surface.width = innerW;
- surface.height = innerH;
- sendConfigureNotify(surface);
- for (id in surfaces) {
- var childSurface = surfaces[id];
- var transientToplevel = getTransientToplevel(childSurface);
- if (transientToplevel != null && transientToplevel == surface) {
- childSurface.x += surface.x - oldX;
- childSurface.y += surface.y - oldY;
- sendConfigureNotify(childSurface);
- }
- }
- }
-}
-
-function browserWindowClosed(win) {
- var surface = win.surface;
-
- sendInput ("W", [surface.id]);
- for (id in surfaces) {
- var childSurface = surfaces[id];
- var transientToplevel = getTransientToplevel(childSurface);
- if (transientToplevel != null && transientToplevel == surface) {
- sendInput ("W", [childSurface.id]);
- }
- }
-}
-
-function registerWindow(win)
-{
- toplevelWindows.push(win);
- win.onresize = function(ev) { updateBrowserWindowGeometry(ev.target, false); };
- if (!windowGeometryTimeout)
- windowGeometryTimeout = setInterval(function () {
- for (var i = 0; i < toplevelWindows.length; i++)
- updateBrowserWindowGeometry(toplevelWindows[i], false);
- }, 2000);
- win.onunload = function(ev) { browserWindowClosed(ev.target.defaultView); };
-}
-
-function unregisterWindow(win)
-{
- var i = toplevelWindows.indexOf(win);
- if (i >= 0)
- toplevelWindows.splice(i, 1);
-
- if (windowGeometryTimeout && toplevelWindows.length == 0) {
- clearInterval(windowGeometryTimeout);
- windowGeometryTimeout = null;
- }
-}
-
-function getTransientToplevel(surface)
-{
- while (surface && surface.transientParent != 0) {
- surface = surfaces[surface.transientParent];
- if (surface && surface.window)
- return surface;
- }
- return null;
-}
-
function getStyle(el, styleProp)
{
if (el.currentStyle) {
surface.drawQueue = [];
surface.transientParent = 0;
surface.visible = false;
- surface.window = null;
- surface.document = document;
surface.frame = null;
var canvas = document.createElement("canvas");
surface.canvas = canvas;
var toplevelElement;
- if (useToplevelWindows || isTemp) {
+ if (isTemp) {
toplevelElement = canvas;
document.body.appendChild(canvas);
} else {
toplevelElement = frame;
document.body.appendChild(frame);
-
- surface.x = 100 + positionIndex * 10;
- surface.y = 100 + positionIndex * 10;
- positionIndex = (positionIndex + 1) % 20;
}
surface.toplevelElement = toplevelElement;
var xOffset = surface.x;
var yOffset = surface.y;
- if (useToplevelWindows) {
- var doc = document;
- if (!surface.isTemp) {
- var options =
- 'width='+surface.width+',height='+surface.height+
- ',location=no,menubar=no,scrollbars=no,toolbar=no';
- if (surface.positioned)
- options = options +
- ',left='+surface.x+',top='+surface.y+',screenX='+surface.x+',screenY='+surface.y;
- var win = window.open('','_blank', options);
- win.surface = surface;
- registerWindow(win);
- doc = win.document;
- doc.open();
- doc.write("<body></body>");
- setupDocument(doc);
-
- surface.window = win;
- xOffset = 0;
- yOffset = 0;
- } else {
- var transientToplevel = getTransientToplevel(surface);
- if (transientToplevel) {
- doc = transientToplevel.window.document;
- xOffset = surface.x - transientToplevel.x;
- yOffset = surface.y - transientToplevel.y;
- }
- }
-
- ensureSurfaceInDocument(surface, doc);
- } else {
- if (surface.frame) {
- var offset = getFrameOffset(surface);
- xOffset -= offset.x;
- yOffset -= offset.y;
- }
+ if (surface.frame) {
+ var offset = getFrameOffset(surface);
+ xOffset -= offset.x;
+ yOffset -= offset.y;
}
surface.toplevelElement.style["left"] = xOffset + "px";
surface.toplevelElement.style["visibility"] = "visible";
restackWindows();
-
- if (surface.window)
- updateBrowserWindowGeometry(surface.window, false);
}
function cmdHideSurface(id)
var element = surface.toplevelElement;
element.style["visibility"] = "hidden";
-
- // Import the canvas into the main document
- ensureSurfaceInDocument(surface, document);
-
- if (surface.window) {
- unregisterWindow(surface.window);
- surface.window.close();
- surface.window = null;
- }
}
function cmdSetTransientFor(id, parentId)
resizeCanvas(surface.canvas, w, h);
if (surface.visible) {
- if (surface.window) {
- /* TODO: This moves the outer frame position, we really want the inner position.
- * However this isn't *strictly* invalid, as any WM could have done whatever it
- * wanted with the positioning of the window.
- */
- if (has_pos)
- surface.window.moveTo(surface.x, surface.y);
- if (has_size)
- resizeBrowserWindow(surface.window, w, h);
- } else {
- if (has_pos) {
- var xOffset = surface.x;
- var yOffset = surface.y;
+ if (has_pos) {
+ var xOffset = surface.x;
+ var yOffset = surface.y;
- var transientToplevel = getTransientToplevel(surface);
- if (transientToplevel) {
- xOffset = surface.x - transientToplevel.x;
- yOffset = surface.y - transientToplevel.y;
- }
-
- var element = surface.canvas;
- if (surface.frame) {
- element = surface.frame;
- var offset = getFrameOffset(surface);
- xOffset -= offset.x;
- yOffset -= offset.y;
- }
+ var transientToplevel = getTransientToplevel(surface);
+ if (transientToplevel) {
+ xOffset = surface.x - transientToplevel.x;
+ yOffset = surface.y - transientToplevel.y;
+ }
- element.style["left"] = xOffset + "px";
- element.style["top"] = yOffset + "px";
+ var element = surface.canvas;
+ if (surface.frame) {
+ element = surface.frame;
+ var offset = getFrameOffset(surface);
+ xOffset -= offset.x;
+ yOffset -= offset.y;
}
+
+ element.style["left"] = xOffset + "px";
+ element.style["top"] = yOffset + "px";
}
}
- if (surface.window) {
- updateBrowserWindowGeometry(surface.window, true);
- } else {
- sendConfigureNotify(surface);
- }
+ sendConfigureNotify(surface);
}
function cmdFlushSurface(id)
q.img.src = url;
surfaces[q.id].drawQueue.push(q);
if (!q.img.complete) {
- q.img.onload = function() { handleOutstanding(); };
+ q.img.onload = function() { cmd.free_image_url (url); handleOutstanding(); };
return false;
}
+ cmd.free_image_url (url);
break;
case 'b': // Copy rects
this.pos = this.pos + size;
return url;
};
+TextCommands.prototype.free_image_url = function(url) {
+};
+
+function BinCommands(message) {
+ this.arraybuffer = message;
+ this.u8 = new Uint8Array(message);
+ this.length = this.u8.length;
+ this.pos = 0;
+}
+
+BinCommands.prototype.get_char = function() {
+ return String.fromCharCode(this.u8[this.pos++]);
+};
+BinCommands.prototype.get_bool = function() {
+ return this.u8[this.pos++] != 0;
+};
+BinCommands.prototype.get_flags = function() {
+ return this.u8[this.pos++];
+}
+BinCommands.prototype.get_16 = function() {
+ var v =
+ this.u8[this.pos] +
+ (this.u8[this.pos+1] << 8);
+ this.pos = this.pos + 2;
+ return v;
+};
+BinCommands.prototype.get_16s = function() {
+ var v = this.get_16 ();
+ if (v > 32767)
+ return v - 65536;
+ else
+ return v;
+};
+BinCommands.prototype.get_32 = function() {
+ var v =
+ this.u8[this.pos] +
+ (this.u8[this.pos+1] << 8) +
+ (this.u8[this.pos+2] << 16) +
+ (this.u8[this.pos+3] << 24);
+ this.pos = this.pos + 4;
+ return v;
+};
+BinCommands.prototype.get_image_url = function() {
+ var size = this.get_32();
+ var png_blob = new Blob ([this.arraybuffer.slice (this.pos, this.pos + size)], {type:"image/png"});
+ var url = URL.createObjectURL(png_blob, {oneTimeOnly: true});
+ this.pos = this.pos + size;
+ return url;
+};
+BinCommands.prototype.free_image_url = function(url) {
+ URL.revokeObjectURL(url);
+};
function handleMessage(message)
{
- var cmd = new TextCommands(message);
+ var cmd;
+ if (message instanceof ArrayBuffer)
+ cmd = new BinCommands(message);
+ else
+ cmd = new TextCommands(message);
outstandingCommands.push(cmd);
if (outstandingCommands.length == 1) {
handleOutstanding();
function getPositionsFromEvent(ev, relativeId) {
var absX, absY;
- if (useToplevelWindows) {
- absX = ev.screenX;
- absY = ev.screenY;
- } else {
- absX = ev.pageX;
- absY = ev.pageY;
- }
+ absX = ev.pageX;
+ absY = ev.pageY;
var res = getPositionsFromAbsCoord(absX, absY, relativeId);
lastX = res.rootX;
lastState |= GDK_MOD1_MASK;
lastTimeStamp = ev.timeStamp;
- if (ev.target.surface && ev.target.surface.window) {
- var win = ev.target.surface.window;
- updateBrowserWindowGeometry(win, false);
- }
}
function onMouseMove (ev) {
surface.x += dx;
surface.y += dy;
var offset = getFrameOffset(surface);
+ if (surface.y < offset.y)
+ surface.y = offset.y;
localGrab.frame.style["left"] = (surface.x - offset.x) + "px";
localGrab.frame.style["top"] = (surface.y - offset.y) + "px";
sendConfigureNotify(surface);
localGrab.lastX = ev.pageX;
localGrab.lastY = ev.pageY;
moveToTop(localGrab.frame.frameFor);
- return;
+ return false;
}
if (id == 0 && ev.target.closeFor) { /* mouse click on frame */
localGrab.button = ev.target;
localGrab.lastX = ev.pageX;
localGrab.lastY = ev.pageY;
- return;
+ return false;
}
var pos = getPositionsFromEvent(ev, id);
if (grab.window == null)
doGrab (id, false, true);
sendInput ("b", [realWindowWithMouse, id, pos.rootX, pos.rootY, pos.winX, pos.winY, lastState, button]);
+ return false;
}
function onMouseUp (ev) {
sendInput ("W", [localGrab.surface.id]);
}
localGrab = null;
- return;
+ return false;
}
sendInput ("B", [realWindowWithMouse, id, pos.rootX, pos.rootY, pos.winX, pos.winY, lastState, button]);
if (grab.window != null && grab.implicit)
doUngrab();
+
+ return false;
}
/* Some of the keyboard handling code is from noVNC and
// browser behaviors or it has no corresponding keyPress
// event, then send it immediately
if (!ignoreKeyEvent(ev))
- sendInput("k", [keysym, lastState]);
+ sendInput("k", [realWindowWithMouse, keysym, lastState]);
suppress = true;
}
// Send the translated keysym
if (keysym > 0)
- sendInput ("k", [keysym, lastState]);
+ sendInput ("k", [realWindowWithMouse, keysym, lastState]);
// Stop keypress events just in case
return cancelEvent(ev);
}
if (keysym > 0)
- sendInput ("K", [keysym, lastState]);
+ sendInput ("K", [realWindowWithMouse, keysym, lastState]);
return cancelEvent(ev);
}
var query_string = url.split("?");
if (query_string.length > 1) {
var params = query_string[1].split("&");
- if (params[0].indexOf("toplevel") != -1)
- useToplevelWindows = true;
}
var loc = window.location.toString().replace("http:", "ws:");
ws.onopen = function() {
inputSocket = ws;
var w, h;
- if (useToplevelWindows) {
- w = window.screen.width;
- h = window.screen.height;
- } else {
+ w = window.innerWidth;
+ h = window.innerHeight;
+ window.onresize = function(ev) {
+ var w, h;
w = window.innerWidth;
h = window.innerHeight;
- window.onresize = function(ev) {
- var w, h;
- w = window.innerWidth;
- h = window.innerHeight;
- sendInput ("d", [w, h]);
- };
- }
+ sendInput ("d", [w, h]);
+ };
sendInput ("d", [w, h]);
};
ws.onclose = function() {
};
setupDocument(document);
- window.onunload = function (ev) {
- for (var i = 0; i < toplevelWindows.length; i++)
- toplevelWindows[i].close();
- };
}