mirror of
https://github.com/gyurix1968/guacamole-client.git
synced 2025-09-07 05:31:22 +00:00
Adding files from old SVN repo, as of 0.2.6 trunk.
This commit is contained in:
35
guacamole/src/net/sourceforge/guacamole/Client.java
Normal file
35
guacamole/src/net/sourceforge/guacamole/Client.java
Normal file
@@ -0,0 +1,35 @@
|
||||
|
||||
package net.sourceforge.guacamole;
|
||||
|
||||
/*
|
||||
* Guacamole - Pure JavaScript/HTML VNC Client
|
||||
* Copyright (C) 2010 Michael Jumper
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import net.sourceforge.guacamole.instruction.Instruction;
|
||||
import net.sourceforge.guacamole.net.GuacamoleException;
|
||||
import net.sourceforge.guacamole.vnc.event.KeyEvent;
|
||||
import net.sourceforge.guacamole.vnc.event.PointerEvent;
|
||||
|
||||
public abstract class Client {
|
||||
|
||||
public abstract void send(KeyEvent event) throws GuacamoleException;
|
||||
public abstract void send(PointerEvent event) throws GuacamoleException;
|
||||
public abstract void setClipboard(String clipboard) throws GuacamoleException;
|
||||
public abstract void disconnect() throws GuacamoleException;
|
||||
public abstract Instruction nextInstruction(boolean blocking) throws GuacamoleException;
|
||||
|
||||
}
|
@@ -0,0 +1,39 @@
|
||||
|
||||
package net.sourceforge.guacamole.instruction;
|
||||
|
||||
/*
|
||||
* Guacamole - Pure JavaScript/HTML VNC Client
|
||||
* Copyright (C) 2010 Michael Jumper
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
public class ClipboardInstruction extends Instruction {
|
||||
|
||||
private String data;
|
||||
|
||||
public ClipboardInstruction(String data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public String getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "clipboard:" + escape(getData()) + ";";
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,39 @@
|
||||
|
||||
package net.sourceforge.guacamole.instruction;
|
||||
|
||||
/*
|
||||
* Guacamole - Pure JavaScript/HTML VNC Client
|
||||
* Copyright (C) 2010 Michael Jumper
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
public class ErrorInstruction extends Instruction {
|
||||
|
||||
private String error;
|
||||
|
||||
public ErrorInstruction(String error) {
|
||||
this.error = error;
|
||||
}
|
||||
|
||||
public String getError() {
|
||||
return error;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "error:" + escape(getError()) + ";";
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,63 @@
|
||||
|
||||
package net.sourceforge.guacamole.instruction;
|
||||
|
||||
/*
|
||||
* Guacamole - Pure JavaScript/HTML VNC Client
|
||||
* Copyright (C) 2010 Michael Jumper
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
public abstract class Instruction {
|
||||
|
||||
|
||||
// All Instructions must provide a toString() implementation
|
||||
// which returns the properly formatted instruction:
|
||||
// OPCODE:parm1,parm2,...,parmN;
|
||||
|
||||
@Override
|
||||
public abstract String toString();
|
||||
|
||||
public String escape(String str) {
|
||||
|
||||
StringBuffer sb = new StringBuffer();
|
||||
|
||||
for (int i=0; i<str.length(); i++) {
|
||||
|
||||
char c = str.charAt(i);
|
||||
|
||||
switch (c) {
|
||||
case ',':
|
||||
sb.append("\\c");
|
||||
break;
|
||||
|
||||
case ';':
|
||||
sb.append("\\s");
|
||||
break;
|
||||
|
||||
case '\\':
|
||||
sb.append("\\\\");
|
||||
break;
|
||||
|
||||
default:
|
||||
sb.append(c);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
return sb.toString();
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,39 @@
|
||||
|
||||
package net.sourceforge.guacamole.instruction;
|
||||
|
||||
/*
|
||||
* Guacamole - Pure JavaScript/HTML VNC Client
|
||||
* Copyright (C) 2010 Michael Jumper
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
public class NameInstruction extends Instruction {
|
||||
|
||||
private String name;
|
||||
|
||||
public NameInstruction(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "name:" + escape(getName()) + ";";
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,47 @@
|
||||
|
||||
package net.sourceforge.guacamole.instruction;
|
||||
|
||||
/*
|
||||
* Guacamole - Pure JavaScript/HTML VNC Client
|
||||
* Copyright (C) 2010 Michael Jumper
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
public class SizeInstruction extends Instruction {
|
||||
|
||||
private int width;
|
||||
private int height;
|
||||
|
||||
public SizeInstruction(int width, int height) {
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "size:"
|
||||
+ getWidth() + ","
|
||||
+ getHeight() + ";";
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,78 @@
|
||||
|
||||
package net.sourceforge.guacamole.instruction.framebuffer;
|
||||
|
||||
/*
|
||||
* Guacamole - Pure JavaScript/HTML VNC Client
|
||||
* Copyright (C) 2010 Michael Jumper
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import net.sourceforge.guacamole.instruction.Instruction;
|
||||
|
||||
public class CopyRectInstruction extends Instruction {
|
||||
|
||||
private final int x;
|
||||
private final int y;
|
||||
private final int width;
|
||||
private final int height;
|
||||
|
||||
private final int srcX;
|
||||
private final int srcY;
|
||||
|
||||
public CopyRectInstruction(int x, int y, int width, int height, int srcX, int srcY) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.srcX = srcX;
|
||||
this.srcY = srcY;
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public int getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public int getSrcX() {
|
||||
return srcX;
|
||||
}
|
||||
|
||||
public int getSrcY() {
|
||||
return srcY;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "copy:"
|
||||
+ getSrcX() + ","
|
||||
+ getSrcY() + ","
|
||||
+ getWidth() + ","
|
||||
+ getHeight() + ","
|
||||
+ getX() + ","
|
||||
+ getY() + ";";
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,66 @@
|
||||
package net.sourceforge.guacamole.instruction.framebuffer;
|
||||
|
||||
import net.sourceforge.guacamole.net.Base64;
|
||||
|
||||
/*
|
||||
* Guacamole - Pure JavaScript/HTML VNC Client
|
||||
* Copyright (C) 2010 Michael Jumper
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import net.sourceforge.guacamole.instruction.Instruction;
|
||||
|
||||
public class CursorInstruction extends Instruction {
|
||||
|
||||
private int x;
|
||||
private int y;
|
||||
private PNGImage image;
|
||||
|
||||
public CursorInstruction(int x, int y, PNGImage image) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.image = image;
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public int getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public PNGImage getImage() {
|
||||
return image;
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return getImage().getWidth();
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return getImage().getHeight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "cursor:"
|
||||
+ getX() + ","
|
||||
+ getY() + ","
|
||||
+ Base64.toString(getImage().getData()) + ";";
|
||||
}
|
||||
|
||||
|
||||
}
|
@@ -0,0 +1,72 @@
|
||||
|
||||
package net.sourceforge.guacamole.instruction.framebuffer;
|
||||
|
||||
/*
|
||||
* Guacamole - Pure JavaScript/HTML VNC Client
|
||||
* Copyright (C) 2010 Michael Jumper
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import net.sourceforge.guacamole.instruction.Instruction;
|
||||
|
||||
public class DrawRectInstruction extends Instruction {
|
||||
|
||||
private final int x;
|
||||
private final int y;
|
||||
private final int width;
|
||||
private final int height;
|
||||
private final int color;
|
||||
|
||||
public DrawRectInstruction(int x, int y, int width, int height, int color) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.width = width;
|
||||
this.height = height;
|
||||
this.color = color;
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public int getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public int getColor() {
|
||||
return color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
|
||||
return "rect:"
|
||||
+ getX() + ","
|
||||
+ getY() + ","
|
||||
+ getWidth() + ","
|
||||
+ getHeight() + ","
|
||||
+ String.format("#%06X", getColor()) + ";";
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,96 @@
|
||||
package net.sourceforge.guacamole.instruction.framebuffer;
|
||||
|
||||
/*
|
||||
* Guacamole - Pure JavaScript/HTML VNC Client
|
||||
* Copyright (C) 2010 Michael Jumper
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import java.util.Iterator;
|
||||
import javax.imageio.IIOImage;
|
||||
import javax.imageio.ImageIO;
|
||||
import javax.imageio.ImageWriter;
|
||||
import javax.imageio.stream.ImageOutputStream;
|
||||
import net.sourceforge.guacamole.vnc.VNCException;
|
||||
|
||||
|
||||
public class PNGImage {
|
||||
|
||||
private int width;
|
||||
private int height;
|
||||
private byte[] data;
|
||||
|
||||
public PNGImage(BufferedImage image) throws VNCException {
|
||||
|
||||
width = image.getWidth();
|
||||
height = image.getHeight();
|
||||
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
|
||||
try {
|
||||
writeImage(image, bos);
|
||||
bos.flush();
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new VNCException("I/O Error while creating PNG.", e);
|
||||
}
|
||||
|
||||
data = bos.toByteArray();
|
||||
}
|
||||
|
||||
public byte[] getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return height;
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return width;
|
||||
}
|
||||
|
||||
private static void writeImage(BufferedImage image, OutputStream outputStream) throws VNCException, IOException {
|
||||
|
||||
// Obtain list of image writers
|
||||
// If no such writers exist, fail with error, exit.
|
||||
Iterator<ImageWriter> writers = ImageIO.getImageWritersByMIMEType("image/png");
|
||||
if (!writers.hasNext())
|
||||
throw new VNCException("No useful image writers found.");
|
||||
|
||||
// Obtain JPEG writer
|
||||
ImageWriter imageWriter = writers.next();
|
||||
|
||||
// Setup image parameters (including compression quality)
|
||||
/*ImageWriteParam imageParameters = new JPEGImageWriteParam(Locale.ENGLISH);
|
||||
imageParameters.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
|
||||
imageParameters.setCompressionQuality(0.6f); // 60% quality, currently...
|
||||
imageParameters.setProgressiveMode(ImageWriteParam.MODE_DEFAULT);*/
|
||||
|
||||
ImageOutputStream out = ImageIO.createImageOutputStream(outputStream);
|
||||
|
||||
// Write image
|
||||
imageWriter.setOutput(out);
|
||||
imageWriter.write(null, new IIOImage(image, null, null), null/*imageParameters*/);
|
||||
imageWriter.dispose();
|
||||
|
||||
out.flush();
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,65 @@
|
||||
package net.sourceforge.guacamole.instruction.framebuffer;
|
||||
|
||||
/*
|
||||
* Guacamole - Pure JavaScript/HTML VNC Client
|
||||
* Copyright (C) 2010 Michael Jumper
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import net.sourceforge.guacamole.instruction.Instruction;
|
||||
import net.sourceforge.guacamole.net.Base64;
|
||||
|
||||
public class PNGInstruction extends Instruction {
|
||||
|
||||
private int x;
|
||||
private int y;
|
||||
private PNGImage image;
|
||||
|
||||
public PNGInstruction(int x, int y, PNGImage image) {
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
this.image = image;
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public int getY() {
|
||||
return y;
|
||||
}
|
||||
|
||||
public PNGImage getImage() {
|
||||
return image;
|
||||
}
|
||||
|
||||
public int getWidth() {
|
||||
return getImage().getWidth();
|
||||
}
|
||||
|
||||
public int getHeight() {
|
||||
return getImage().getHeight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "png:"
|
||||
+ getX() + ","
|
||||
+ getY() + ","
|
||||
+ Base64.toString(getImage().getData()) + ";";
|
||||
}
|
||||
|
||||
|
||||
}
|
66
guacamole/src/net/sourceforge/guacamole/net/Base64.java
Normal file
66
guacamole/src/net/sourceforge/guacamole/net/Base64.java
Normal file
@@ -0,0 +1,66 @@
|
||||
package net.sourceforge.guacamole.net;
|
||||
|
||||
/*
|
||||
* Guacamole - Pure JavaScript/HTML VNC Client
|
||||
* Copyright (C) 2010 Michael Jumper
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
public class Base64 {
|
||||
|
||||
private static String characters =
|
||||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/";
|
||||
|
||||
|
||||
public static String toString(byte[] data) {
|
||||
|
||||
StringBuffer buff = new StringBuffer();
|
||||
for (int i=0; i<data.length; i+=3) {
|
||||
|
||||
int a = data[i];
|
||||
int b = 0; if (i+1 < data.length) b = data[i+1];
|
||||
int c = 0; if (i+2 < data.length) c = data[i+2];
|
||||
|
||||
buff.append(characters.charAt(
|
||||
(a & 0xFC) >> 2
|
||||
));
|
||||
|
||||
buff.append(characters.charAt(
|
||||
((a & 0x03) << 4) |
|
||||
((b & 0xF0) >> 4)
|
||||
));
|
||||
|
||||
if (i+1 < data.length)
|
||||
buff.append(characters.charAt(
|
||||
((b & 0x0F) << 2) |
|
||||
((c & 0xC0) >> 6)
|
||||
));
|
||||
else
|
||||
buff.append('=');
|
||||
|
||||
if (i+2 < data.length)
|
||||
buff.append(characters.charAt(
|
||||
(c & 0x3F)
|
||||
));
|
||||
else
|
||||
buff.append('=');
|
||||
|
||||
}
|
||||
|
||||
return buff.toString();
|
||||
|
||||
}
|
||||
|
||||
}
|
129
guacamole/src/net/sourceforge/guacamole/net/Configuration.java
Normal file
129
guacamole/src/net/sourceforge/guacamole/net/Configuration.java
Normal file
@@ -0,0 +1,129 @@
|
||||
|
||||
package net.sourceforge.guacamole.net;
|
||||
|
||||
/*
|
||||
* Guacamole - Pure JavaScript/HTML VNC Client
|
||||
* Copyright (C) 2010 Michael Jumper
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
public abstract class Configuration {
|
||||
|
||||
private ServletContext context;
|
||||
|
||||
protected String humanReadableList(Object... values) {
|
||||
|
||||
String list = "";
|
||||
for (int i=0; i<values.length; i++) {
|
||||
|
||||
if (i >= 1)
|
||||
list += ", ";
|
||||
|
||||
if (i == values.length -1)
|
||||
list += " or ";
|
||||
|
||||
list += "\"" + values[i] + "\"";
|
||||
}
|
||||
|
||||
return list;
|
||||
|
||||
}
|
||||
|
||||
protected String readParameter(String name, String defaultValue, String... allowedValues) throws GuacamoleException {
|
||||
|
||||
String value = context.getInitParameter(name);
|
||||
|
||||
// Use default if not specified
|
||||
if (value == null) {
|
||||
if (defaultValue == null)
|
||||
throw new GuacamoleException("Parameter \"" + name + "\" is required.");
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
// If not restricted to certain values, just return whatever is given.
|
||||
if (allowedValues.length == 0)
|
||||
return value;
|
||||
|
||||
// If restricted, only return value within given list
|
||||
for (String allowedValue : allowedValues)
|
||||
if (value.equals(allowedValue))
|
||||
return value;
|
||||
|
||||
throw new GuacamoleException("Parameter \"" + name + "\" must be " + humanReadableList((Object) allowedValues));
|
||||
}
|
||||
|
||||
protected boolean readBooleanParameter(String name, Boolean defaultValue) throws GuacamoleException {
|
||||
|
||||
String value = context.getInitParameter(name);
|
||||
|
||||
// Use default if not specified
|
||||
if (value == null) {
|
||||
if (defaultValue == null)
|
||||
throw new GuacamoleException("Parameter \"" + name + "\" is required.");
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
value = value.trim();
|
||||
if (value.equals("true"))
|
||||
return true;
|
||||
|
||||
if (value.equals("false"))
|
||||
return false;
|
||||
|
||||
throw new GuacamoleException("Parameter \"" + name + "\" must be \"true\" or \"false\".");
|
||||
|
||||
}
|
||||
|
||||
protected int readIntParameter(String name, Integer defaultValue, Integer... allowedValues) throws GuacamoleException {
|
||||
|
||||
String parmString = context.getInitParameter(name);
|
||||
|
||||
// Use default if not specified
|
||||
if (parmString== null) {
|
||||
if (defaultValue == null)
|
||||
throw new GuacamoleException("Parameter \"" + name + "\" is required.");
|
||||
|
||||
return defaultValue;
|
||||
}
|
||||
|
||||
try {
|
||||
int value = Integer.parseInt(parmString);
|
||||
|
||||
// If not restricted to certain values, just return whatever is given.
|
||||
if (allowedValues.length == 0)
|
||||
return value;
|
||||
|
||||
// If restricted, only return value within given list
|
||||
for (int allowedValue : allowedValues)
|
||||
if (value == allowedValue)
|
||||
return value;
|
||||
|
||||
throw new GuacamoleException("Parameter \"" + name + "\" must be " + humanReadableList((Object) allowedValues));
|
||||
}
|
||||
catch (NumberFormatException e) {
|
||||
throw new GuacamoleException("Parameter \"" + name + "\" must be an integer.", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public Configuration(ServletContext context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,64 @@
|
||||
|
||||
package net.sourceforge.guacamole.net;
|
||||
|
||||
/*
|
||||
* Guacamole - Pure JavaScript/HTML VNC Client
|
||||
* Copyright (C) 2010 Michael Jumper
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
public class GuacamoleConfiguration extends Configuration {
|
||||
|
||||
private String hostname;
|
||||
private int port;
|
||||
private String password;
|
||||
private int outputBPP;
|
||||
private boolean compressStream;
|
||||
|
||||
public GuacamoleConfiguration(ServletContext context) throws GuacamoleException {
|
||||
|
||||
super(context);
|
||||
|
||||
hostname = readParameter("host", null);
|
||||
port = readIntParameter("port", null);
|
||||
password = context.getInitParameter("password");
|
||||
outputBPP = readIntParameter("output-bpp", 8, 8, 24);
|
||||
compressStream = readBooleanParameter("compress-stream", false);
|
||||
|
||||
}
|
||||
|
||||
public String getHostname() {
|
||||
return hostname;
|
||||
}
|
||||
|
||||
public int getOutputBPP() {
|
||||
return outputBPP;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
public int getPort() {
|
||||
return port;
|
||||
}
|
||||
|
||||
public boolean getCompressStream() {
|
||||
return compressStream;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,36 @@
|
||||
|
||||
package net.sourceforge.guacamole.net;
|
||||
|
||||
/*
|
||||
* Guacamole - Pure JavaScript/HTML VNC Client
|
||||
* Copyright (C) 2010 Michael Jumper
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
public class GuacamoleException extends Exception {
|
||||
|
||||
public GuacamoleException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public GuacamoleException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
public GuacamoleException(Throwable cause) {
|
||||
super(cause);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,62 @@
|
||||
|
||||
package net.sourceforge.guacamole.net;
|
||||
|
||||
/*
|
||||
* Guacamole - Pure JavaScript/HTML VNC Client
|
||||
* Copyright (C) 2010 Michael Jumper
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import javax.servlet.ServletException;
|
||||
import javax.servlet.http.HttpServlet;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import net.sourceforge.guacamole.vnc.VNCException;
|
||||
|
||||
public abstract class GuacamoleServlet extends HttpServlet {
|
||||
|
||||
@Override
|
||||
protected final void doGet(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||
try {
|
||||
handleRequest(req, resp);
|
||||
}
|
||||
catch (GuacamoleException e) {
|
||||
throw new ServletException(e);
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected final void doPost(HttpServletRequest req, HttpServletResponse resp) throws ServletException, IOException {
|
||||
try {
|
||||
handleRequest(req, resp);
|
||||
}
|
||||
catch (GuacamoleException e) {
|
||||
throw new ServletException(e);
|
||||
}
|
||||
}
|
||||
|
||||
private final void handleRequest(HttpServletRequest request, HttpServletResponse response) throws GuacamoleException {
|
||||
GuacamoleSession session = new GuacamoleSession(request.getSession(shouldCreateSession()));
|
||||
handleRequest(session, request, response);
|
||||
}
|
||||
|
||||
protected abstract void handleRequest(GuacamoleSession session, HttpServletRequest request, HttpServletResponse response) throws GuacamoleException;
|
||||
|
||||
protected boolean shouldCreateSession() {
|
||||
return false;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,123 @@
|
||||
|
||||
package net.sourceforge.guacamole.net;
|
||||
|
||||
/*
|
||||
* Guacamole - Pure JavaScript/HTML VNC Client
|
||||
* Copyright (C) 2010 Michael Jumper
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import javax.servlet.ServletContext;
|
||||
import javax.servlet.http.HttpSession;
|
||||
import javax.servlet.http.HttpSessionBindingEvent;
|
||||
import javax.servlet.http.HttpSessionBindingListener;
|
||||
import net.sourceforge.guacamole.Client;
|
||||
import net.sourceforge.guacamole.vnc.VNCClient;
|
||||
import net.sourceforge.guacamole.vnc.VNCConfiguration;
|
||||
import net.sourceforge.guacamole.vnc.VNCException;
|
||||
|
||||
public class GuacamoleSession {
|
||||
|
||||
private GuacamoleConfiguration config;
|
||||
private final HttpSession session;
|
||||
private Client client;
|
||||
|
||||
private class SessionVNCClient extends VNCClient implements HttpSessionBindingListener {
|
||||
|
||||
public SessionVNCClient(String host, int port, String password, int colorBits, int outputBPP) throws VNCException {
|
||||
super(host, port, password, colorBits, outputBPP);
|
||||
}
|
||||
|
||||
public void valueBound(HttpSessionBindingEvent event) {
|
||||
// Do nothing
|
||||
}
|
||||
|
||||
public void valueUnbound(HttpSessionBindingEvent event) {
|
||||
try {
|
||||
disconnect();
|
||||
}
|
||||
catch (GuacamoleException e) {
|
||||
// Ignore
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public GuacamoleSession(HttpSession session) throws GuacamoleException {
|
||||
|
||||
if (session == null)
|
||||
throw new GuacamoleException("User has no session.");
|
||||
|
||||
this.session = session;
|
||||
synchronized (session) {
|
||||
|
||||
// Read configuration parameters
|
||||
ServletContext context = session.getServletContext();
|
||||
config = new GuacamoleConfiguration(context);
|
||||
|
||||
client = (Client) session.getAttribute("CLIENT");
|
||||
}
|
||||
}
|
||||
|
||||
public void connect() throws GuacamoleException {
|
||||
synchronized (session) {
|
||||
|
||||
if (client != null)
|
||||
client.disconnect();
|
||||
|
||||
// Connect to VNC server
|
||||
try {
|
||||
|
||||
// Read VNC-specific parameters
|
||||
ServletContext context = session.getServletContext();
|
||||
VNCConfiguration vncconfig = new VNCConfiguration(context);
|
||||
|
||||
client = new SessionVNCClient(
|
||||
config.getHostname(),
|
||||
config.getPort(),
|
||||
vncconfig.getPassword(),
|
||||
vncconfig.getBPP(),
|
||||
config.getOutputBPP()
|
||||
);
|
||||
}
|
||||
catch (VNCException e) {
|
||||
throw new GuacamoleException(e);
|
||||
}
|
||||
|
||||
session.setAttribute("CLIENT", client);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public GuacamoleConfiguration getConfiguration() {
|
||||
return config;
|
||||
}
|
||||
|
||||
public Client getClient() {
|
||||
synchronized (session) {
|
||||
return client;
|
||||
}
|
||||
}
|
||||
|
||||
public void invalidate() {
|
||||
session.invalidate();
|
||||
}
|
||||
|
||||
public void disconnect() throws GuacamoleException {
|
||||
if (client != null)
|
||||
client.disconnect();
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,131 @@
|
||||
|
||||
package net.sourceforge.guacamole.net;
|
||||
|
||||
/*
|
||||
* Guacamole - Pure JavaScript/HTML VNC Client
|
||||
* Copyright (C) 2010 Michael Jumper
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.OutputStream;
|
||||
import javax.servlet.ServletRequest;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import javax.xml.parsers.DocumentBuilder;
|
||||
import javax.xml.parsers.DocumentBuilderFactory;
|
||||
import javax.xml.parsers.ParserConfigurationException;
|
||||
import javax.xml.transform.OutputKeys;
|
||||
import javax.xml.transform.Transformer;
|
||||
import javax.xml.transform.TransformerConfigurationException;
|
||||
import javax.xml.transform.TransformerException;
|
||||
import javax.xml.transform.TransformerFactory;
|
||||
import javax.xml.transform.dom.DOMSource;
|
||||
import javax.xml.transform.stream.StreamResult;
|
||||
import net.sourceforge.guacamole.Client;
|
||||
import org.w3c.dom.Document;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
public abstract class XMLGuacamoleServlet extends GuacamoleServlet {
|
||||
|
||||
@Override
|
||||
protected final void handleRequest(GuacamoleSession session, HttpServletRequest request, HttpServletResponse response) throws GuacamoleException {
|
||||
|
||||
response.setContentType("text/xml");
|
||||
response.setHeader("Cache-Control", "no-store");
|
||||
response.setHeader("Pragma", "no-cache");
|
||||
response.setDateHeader("Expires", 0);
|
||||
|
||||
try {
|
||||
|
||||
// Create document
|
||||
DocumentBuilderFactory documentBuilderFactory = DocumentBuilderFactory.newInstance();
|
||||
DocumentBuilder documentBuilder = documentBuilderFactory.newDocumentBuilder();
|
||||
Document document = documentBuilder.newDocument();
|
||||
|
||||
// Root element
|
||||
Element root = document.createElement("guacamole");
|
||||
document.appendChild(root);
|
||||
|
||||
try {
|
||||
handleRequest(session, request, root);
|
||||
}
|
||||
catch (Throwable t) {
|
||||
addFatalError(root, t.getMessage());
|
||||
|
||||
// FATAL error ... try to disconnect
|
||||
if (session != null) {
|
||||
Client client = session.getClient();
|
||||
try {
|
||||
if (client != null)
|
||||
client.disconnect();
|
||||
}
|
||||
catch (GuacamoleException e) {
|
||||
addFatalError(root, e.getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Set up transformer
|
||||
TransformerFactory transformerFactory = TransformerFactory.newInstance();
|
||||
Transformer transformer = transformerFactory.newTransformer();
|
||||
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
|
||||
//transformer.setOutputProperty(OutputKeys.OMIT_XML_DECLARATION, "yes");
|
||||
transformer.setOutputProperty(OutputKeys.ENCODING, "UTF-8");
|
||||
|
||||
// Write XML using transformer
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
StreamResult result = new StreamResult(bos);
|
||||
DOMSource source = new DOMSource(document);
|
||||
transformer.transform(source, result);
|
||||
|
||||
|
||||
bos.flush();
|
||||
|
||||
byte[] xmlData = bos.toByteArray();
|
||||
response.setContentLength(xmlData.length);
|
||||
OutputStream outputStream = response.getOutputStream();
|
||||
outputStream.write(xmlData);
|
||||
|
||||
// Close stream
|
||||
outputStream.close();
|
||||
}
|
||||
catch (ParserConfigurationException e) {
|
||||
throw new GuacamoleException(e);
|
||||
}
|
||||
catch (TransformerConfigurationException e) {
|
||||
throw new GuacamoleException(e);
|
||||
}
|
||||
catch (TransformerException e) {
|
||||
throw new GuacamoleException(e);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new GuacamoleException(e);
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
private void addFatalError(Element root, String message) {
|
||||
Element error = root.getOwnerDocument().createElement("error");
|
||||
error.setAttribute("type", "fatal");
|
||||
error.setTextContent(message);
|
||||
root.appendChild(error);
|
||||
}
|
||||
|
||||
protected abstract void handleRequest(GuacamoleSession session, ServletRequest request, Element root) throws GuacamoleException;
|
||||
|
||||
}
|
@@ -0,0 +1,47 @@
|
||||
package net.sourceforge.guacamole.net.control;
|
||||
|
||||
/*
|
||||
* Guacamole - Pure JavaScript/HTML VNC Client
|
||||
* Copyright (C) 2010 Michael Jumper
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import javax.servlet.ServletRequest;
|
||||
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import net.sourceforge.guacamole.net.XMLGuacamoleServlet;
|
||||
import net.sourceforge.guacamole.net.GuacamoleException;
|
||||
import net.sourceforge.guacamole.net.GuacamoleSession;
|
||||
|
||||
public class Connect extends XMLGuacamoleServlet {
|
||||
|
||||
protected boolean shouldCreateSession() {
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void handleRequest(GuacamoleSession session, ServletRequest request, Element root) throws GuacamoleException {
|
||||
|
||||
try {
|
||||
session.connect();
|
||||
}
|
||||
catch (GuacamoleException e) {
|
||||
throw new GuacamoleException("Error connecting to server: " + e.getMessage(), e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,43 @@
|
||||
package net.sourceforge.guacamole.net.control;
|
||||
|
||||
/*
|
||||
* Guacamole - Pure JavaScript/HTML VNC Client
|
||||
* Copyright (C) 2010 Michael Jumper
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import javax.servlet.ServletRequest;
|
||||
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import net.sourceforge.guacamole.net.XMLGuacamoleServlet;
|
||||
import net.sourceforge.guacamole.net.GuacamoleException;
|
||||
import net.sourceforge.guacamole.net.GuacamoleSession;
|
||||
|
||||
public class Disconnect extends XMLGuacamoleServlet {
|
||||
|
||||
@Override
|
||||
protected void handleRequest(GuacamoleSession session, ServletRequest request, Element root) throws GuacamoleException {
|
||||
|
||||
try {
|
||||
session.disconnect(); // Disconnect client.
|
||||
}
|
||||
catch (GuacamoleException e) {
|
||||
throw new GuacamoleException("Error disconnecting from VNC server: " + e.getMessage(), e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,69 @@
|
||||
|
||||
package net.sourceforge.guacamole.net.input;
|
||||
|
||||
/*
|
||||
* Guacamole - Pure JavaScript/HTML VNC Client
|
||||
* Copyright (C) 2010 Michael Jumper
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import javax.servlet.ServletRequest;
|
||||
import net.sourceforge.guacamole.net.GuacamoleException;
|
||||
import org.w3c.dom.Element;
|
||||
|
||||
import net.sourceforge.guacamole.net.GuacamoleSession;
|
||||
import net.sourceforge.guacamole.net.XMLGuacamoleServlet;
|
||||
import net.sourceforge.guacamole.vnc.VNCException;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.Reader;
|
||||
|
||||
/**
|
||||
* Servlet which sets the VNC clipboard data.
|
||||
*
|
||||
* This servlet takes one parameter:
|
||||
* data: The data to set the clipboard to.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
|
||||
public class Clipboard extends XMLGuacamoleServlet {
|
||||
|
||||
@Override
|
||||
protected void handleRequest(GuacamoleSession session, ServletRequest request, Element root) throws GuacamoleException {
|
||||
|
||||
try {
|
||||
|
||||
// Read data from request body
|
||||
Reader reader = request.getReader();
|
||||
StringBuilder data = new StringBuilder();
|
||||
|
||||
int codepoint;
|
||||
while ((codepoint = reader.read()) != -1)
|
||||
data.appendCodePoint(codepoint);
|
||||
|
||||
// Set clipboard
|
||||
session.getClient().setClipboard(data.toString());
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new GuacamoleException("I/O error sending clipboard to server: " + e.getMessage(), e);
|
||||
}
|
||||
catch (GuacamoleException e) {
|
||||
throw new GuacamoleException("Error sending clipboard to server: " + e.getMessage(), e);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
67
guacamole/src/net/sourceforge/guacamole/net/input/Key.java
Normal file
67
guacamole/src/net/sourceforge/guacamole/net/input/Key.java
Normal file
@@ -0,0 +1,67 @@
|
||||
|
||||
package net.sourceforge.guacamole.net.input;
|
||||
|
||||
/*
|
||||
* Guacamole - Pure JavaScript/HTML VNC Client
|
||||
* Copyright (C) 2010 Michael Jumper
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import javax.servlet.ServletRequest;
|
||||
import net.sourceforge.guacamole.net.GuacamoleException;
|
||||
import org.w3c.dom.Element;
|
||||
import net.sourceforge.guacamole.vnc.event.KeyEvent;
|
||||
|
||||
import net.sourceforge.guacamole.net.GuacamoleSession;
|
||||
import net.sourceforge.guacamole.net.XMLGuacamoleServlet;
|
||||
import net.sourceforge.guacamole.vnc.VNCException;
|
||||
|
||||
/**
|
||||
* Servlet which accepts keyboard input events, forwards these events to the
|
||||
* VNC client associated with the session, and returns the result (if any)
|
||||
* to the HTTP client via XML.
|
||||
*
|
||||
* This servlet takes three parameters:
|
||||
* index: The event index. As HTTP requests may arrive out of order,
|
||||
* this index provides the event queue with a means of sorting
|
||||
* events, and determining if events are missing. The first
|
||||
* event has index 0.
|
||||
* pressed: Whether the key was pressed (1) or released (0).
|
||||
* keysym: The integer representing the corresponding X11 keysym.
|
||||
*
|
||||
* @author Michael Jumper
|
||||
*/
|
||||
|
||||
public class Key extends XMLGuacamoleServlet {
|
||||
|
||||
@Override
|
||||
protected void handleRequest(GuacamoleSession session, ServletRequest request, Element root) throws GuacamoleException {
|
||||
|
||||
// Event parameters
|
||||
int index = Integer.parseInt(request.getParameter("index"));
|
||||
boolean pressed = request.getParameter("pressed").equals("1");
|
||||
int keysym = Integer.parseInt(request.getParameter("keysym"));
|
||||
|
||||
// Send/queue event
|
||||
try {
|
||||
session.getClient().send(new KeyEvent(index, keysym, pressed));
|
||||
}
|
||||
catch (GuacamoleException e) {
|
||||
throw new GuacamoleException("Error sending key event to server: " + e.getMessage(), e);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
@@ -0,0 +1,64 @@
|
||||
package net.sourceforge.guacamole.net.input;
|
||||
|
||||
/*
|
||||
* Guacamole - Pure JavaScript/HTML VNC Client
|
||||
* Copyright (C) 2010 Michael Jumper
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import javax.servlet.ServletRequest;
|
||||
import net.sourceforge.guacamole.net.GuacamoleException;
|
||||
import org.w3c.dom.Element;
|
||||
import net.sourceforge.guacamole.vnc.event.PointerEvent;
|
||||
|
||||
import net.sourceforge.guacamole.net.GuacamoleSession;
|
||||
import net.sourceforge.guacamole.net.XMLGuacamoleServlet;
|
||||
import net.sourceforge.guacamole.vnc.VNCException;
|
||||
|
||||
public class Pointer extends XMLGuacamoleServlet {
|
||||
|
||||
|
||||
@Override
|
||||
protected void handleRequest(GuacamoleSession session, ServletRequest request, Element root) throws GuacamoleException {
|
||||
// Event parameters
|
||||
String[] events = request.getParameterValues("event");
|
||||
|
||||
for (String event : events) {
|
||||
|
||||
String[] parameters = event.split(",");
|
||||
|
||||
int index = Integer.parseInt(parameters[0]);
|
||||
|
||||
int x = Integer.parseInt(parameters[1]);
|
||||
int y = Integer.parseInt(parameters[2]);
|
||||
|
||||
boolean left = parameters[3].equals("1");
|
||||
boolean middle = parameters[4].equals("1");
|
||||
boolean right = parameters[5].equals("1");
|
||||
boolean up = parameters[6].equals("1");
|
||||
boolean down = parameters[7].equals("1");
|
||||
|
||||
// Store event
|
||||
try {
|
||||
session.getClient().send(new PointerEvent(index, left, middle, right, up, down, x, y));
|
||||
}
|
||||
catch (GuacamoleException e) {
|
||||
throw new GuacamoleException("Error sending pointer event to server: " + e.getMessage(), e);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -0,0 +1,130 @@
|
||||
package net.sourceforge.guacamole.net.output;
|
||||
|
||||
/*
|
||||
* Guacamole - Pure JavaScript/HTML VNC Client
|
||||
* Copyright (C) 2010 Michael Jumper
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import java.io.OutputStream;
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.UnsupportedEncodingException;
|
||||
import java.util.zip.DeflaterOutputStream;
|
||||
import java.util.zip.GZIPOutputStream;
|
||||
import javax.servlet.http.HttpServletRequest;
|
||||
import javax.servlet.http.HttpServletResponse;
|
||||
import net.sourceforge.guacamole.Client;
|
||||
import net.sourceforge.guacamole.net.GuacamoleServlet;
|
||||
import net.sourceforge.guacamole.net.GuacamoleException;
|
||||
import net.sourceforge.guacamole.net.GuacamoleSession;
|
||||
import net.sourceforge.guacamole.instruction.Instruction;
|
||||
import net.sourceforge.guacamole.instruction.ErrorInstruction;
|
||||
|
||||
|
||||
public class InstructionStream extends GuacamoleServlet {
|
||||
|
||||
@Override
|
||||
protected void handleRequest(GuacamoleSession session, HttpServletRequest request, HttpServletResponse response) throws GuacamoleException {
|
||||
|
||||
// Instruction buffer
|
||||
StringBuilder instructions = new StringBuilder();
|
||||
|
||||
try {
|
||||
|
||||
// Query new update from VNC server
|
||||
Client client = session.getClient();
|
||||
|
||||
int messageLimit = Integer.parseInt(request.getParameter("messageLimit"));
|
||||
|
||||
// For all messages, up to given message limit.
|
||||
Instruction message = client.nextInstruction(true); // Block until first message is read
|
||||
while (message != null) {
|
||||
|
||||
// Add message
|
||||
instructions.append(message.toString());
|
||||
|
||||
// No more messages if we're exceeding our limit
|
||||
if (instructions.length() >= messageLimit) break;
|
||||
|
||||
message = client.nextInstruction(false); // Read remaining messages, do not block.
|
||||
}
|
||||
|
||||
}
|
||||
catch (GuacamoleException e) {
|
||||
instructions.append(new ErrorInstruction(e.getMessage()).toString());
|
||||
}
|
||||
|
||||
try {
|
||||
|
||||
// Get output bytes
|
||||
byte[] outputBytes = instructions.toString().getBytes("UTF-8");
|
||||
|
||||
// Compress if enabled and supported by browser
|
||||
if (session.getConfiguration().getCompressStream()) {
|
||||
|
||||
String encodingHeader = request.getHeader("Accept-Encoding");
|
||||
if (encodingHeader != null) {
|
||||
|
||||
String[] encodings = encodingHeader.split(",");
|
||||
for (String encoding : encodings) {
|
||||
|
||||
// Use gzip if supported
|
||||
if (encoding.equals("gzip")) {
|
||||
response.setHeader("Content-Encoding", "gzip");
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
OutputStream zout = new GZIPOutputStream(bos);
|
||||
zout.write(outputBytes);
|
||||
zout.close();
|
||||
outputBytes = bos.toByteArray();
|
||||
break;
|
||||
}
|
||||
|
||||
// Use deflate if supported
|
||||
if (encoding.equals("deflate")) {
|
||||
response.setHeader("Content-Encoding", "deflate");
|
||||
ByteArrayOutputStream bos = new ByteArrayOutputStream();
|
||||
OutputStream zout = new DeflaterOutputStream(bos);
|
||||
zout.write(outputBytes);
|
||||
zout.close();
|
||||
outputBytes = bos.toByteArray();
|
||||
break;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
response.setContentType("text/plain");
|
||||
response.setContentLength(outputBytes.length);
|
||||
|
||||
// Use default output stream if no compression.
|
||||
OutputStream out = response.getOutputStream();
|
||||
out.write(outputBytes);
|
||||
out.flush();
|
||||
}
|
||||
catch (UnsupportedEncodingException e) {
|
||||
throw new GuacamoleException("UTF-8 not supported by Java.", e);
|
||||
}
|
||||
catch (IOException e) {
|
||||
throw new GuacamoleException("I/O error writing to servlet output stream.", e);
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
BIN
guacamole/src/net/sourceforge/guacamole/vnc/.VNCClient.java.swp
Normal file
BIN
guacamole/src/net/sourceforge/guacamole/vnc/.VNCClient.java.swp
Normal file
Binary file not shown.
@@ -0,0 +1,63 @@
|
||||
|
||||
package net.sourceforge.guacamole.vnc;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.io.InputStream;
|
||||
import java.util.LinkedList;
|
||||
|
||||
public class InputOutputStream extends InputStream {
|
||||
|
||||
private int pos = 0;
|
||||
private byte[] current = null;
|
||||
private LinkedList<byte[]> buffer = new LinkedList<byte[]>();
|
||||
|
||||
public void write(byte[] data) {
|
||||
|
||||
if (data.length == 0)
|
||||
return;
|
||||
|
||||
if (current == null)
|
||||
current = data;
|
||||
else
|
||||
buffer.addLast(data);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read() throws IOException {
|
||||
|
||||
if (pos >= current.length) {
|
||||
if (buffer.size() == 0)
|
||||
throw new IOException("Buffer underrun.");
|
||||
|
||||
current = buffer.removeFirst();
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
return 0xFF & current[pos++];
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte[] data) throws IOException {
|
||||
return read(data, 0, data.length);
|
||||
}
|
||||
|
||||
@Override
|
||||
public int read(byte[] data, int off, int len) throws IOException {
|
||||
|
||||
if (pos >= current.length) {
|
||||
if (buffer.size() == 0)
|
||||
throw new IOException("Buffer underrun.");
|
||||
|
||||
current = buffer.removeFirst();
|
||||
pos = 0;
|
||||
}
|
||||
|
||||
int amountRead = Math.min(current.length - pos, len);
|
||||
System.arraycopy(current, pos, data, off, amountRead);
|
||||
pos += amountRead;
|
||||
|
||||
return amountRead;
|
||||
}
|
||||
|
||||
}
|
1098
guacamole/src/net/sourceforge/guacamole/vnc/VNCClient.java
Normal file
1098
guacamole/src/net/sourceforge/guacamole/vnc/VNCClient.java
Normal file
File diff suppressed because it is too large
Load Diff
@@ -0,0 +1,47 @@
|
||||
|
||||
package net.sourceforge.guacamole.vnc;
|
||||
|
||||
/*
|
||||
* Guacamole - Pure JavaScript/HTML VNC Client
|
||||
* Copyright (C) 2010 Michael Jumper
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import net.sourceforge.guacamole.net.*;
|
||||
import javax.servlet.ServletContext;
|
||||
|
||||
public class VNCConfiguration extends Configuration {
|
||||
|
||||
private String password;
|
||||
private int bpp;
|
||||
|
||||
public VNCConfiguration(ServletContext context) throws GuacamoleException {
|
||||
|
||||
super(context);
|
||||
|
||||
password = context.getInitParameter("password");
|
||||
bpp = readIntParameter("bpp", 24, 8, 16, 24);
|
||||
|
||||
}
|
||||
|
||||
public int getBPP() {
|
||||
return bpp;
|
||||
}
|
||||
|
||||
public String getPassword() {
|
||||
return password;
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,32 @@
|
||||
|
||||
package net.sourceforge.guacamole.vnc;
|
||||
|
||||
/*
|
||||
* Guacamole - Pure JavaScript/HTML VNC Client
|
||||
* Copyright (C) 2010 Michael Jumper
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
public class VNCException extends Exception {
|
||||
|
||||
public VNCException(String message, Throwable cause) {
|
||||
super(message, cause);
|
||||
}
|
||||
|
||||
public VNCException(String message) {
|
||||
super(message);
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,211 @@
|
||||
package net.sourceforge.guacamole.vnc;
|
||||
|
||||
/*
|
||||
* Guacamole - Pure JavaScript/HTML VNC Client
|
||||
* Copyright (C) 2010 Michael Jumper
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.IndexColorModel;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
|
||||
public class VNCFullColorImageReader extends VNCImageReader {
|
||||
|
||||
private int bpp;
|
||||
private int depth;
|
||||
|
||||
private int redBits;
|
||||
private int greenBits;
|
||||
private int blueBits;
|
||||
|
||||
private int redMax;
|
||||
private int greenMax;
|
||||
private int blueMax;
|
||||
|
||||
private int redShift;
|
||||
private int greenShift;
|
||||
private int blueShift;
|
||||
|
||||
private boolean readAsIndexed;
|
||||
|
||||
public boolean isBigEndian() {
|
||||
return true;
|
||||
}
|
||||
|
||||
public int getBitsPerPixel() {
|
||||
return bpp;
|
||||
}
|
||||
|
||||
public int getDepth() {
|
||||
return depth;
|
||||
}
|
||||
|
||||
public int getRedMax() {
|
||||
return redMax;
|
||||
}
|
||||
|
||||
public int getGreenMax() {
|
||||
return greenMax;
|
||||
}
|
||||
|
||||
public int getBlueMax() {
|
||||
return blueMax;
|
||||
}
|
||||
|
||||
public int getRedShift() {
|
||||
return redShift;
|
||||
}
|
||||
|
||||
public int getGreenShift() {
|
||||
return greenShift;
|
||||
}
|
||||
|
||||
public int getBlueShift() {
|
||||
return blueShift;
|
||||
}
|
||||
|
||||
// Set up BGR reader
|
||||
public VNCFullColorImageReader(int redBits, int greenBits, int blueBits, int outputBPP) throws VNCException {
|
||||
|
||||
depth = redBits + greenBits + blueBits;
|
||||
|
||||
if (depth > 0 && depth <= 8)
|
||||
bpp = 8;
|
||||
else if (depth <= 16)
|
||||
bpp = 16;
|
||||
else if (depth <= 32)
|
||||
bpp = 32;
|
||||
else
|
||||
throw new VNCException("Illegal bit depth for VNC images: " + bpp);
|
||||
|
||||
this.redBits = redBits;
|
||||
this.greenBits = greenBits;
|
||||
this.blueBits = blueBits;
|
||||
|
||||
redMax = (1 << redBits) - 1;
|
||||
greenMax = (1 << greenBits) - 1;
|
||||
blueMax = (1 << blueBits) - 1;
|
||||
|
||||
redShift = greenBits + blueBits;
|
||||
greenShift = blueBits;
|
||||
blueShift = 0;
|
||||
|
||||
if (outputBPP == 8)
|
||||
this.readAsIndexed = true;
|
||||
else if (outputBPP == 24)
|
||||
this.readAsIndexed = false;
|
||||
else
|
||||
throw new VNCException("Only 8-bit or 24-bit output is supported.");
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readCPixel(DataInputStream input) throws IOException {
|
||||
|
||||
if (redBits != 8 || greenBits != 8 || blueBits != 8)
|
||||
return readPixel(input);
|
||||
|
||||
int red = input.read();
|
||||
int green = input.read();
|
||||
int blue = input.read();
|
||||
|
||||
int color = (red << 16) | (green << 8) | blue;
|
||||
return color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readPixel(DataInputStream input) throws IOException {
|
||||
int value;
|
||||
switch (bpp) {
|
||||
case 8:
|
||||
value = input.read();
|
||||
break;
|
||||
case 16:
|
||||
value = input.readShort();
|
||||
break;
|
||||
case 32:
|
||||
value = input.readInt();
|
||||
break;
|
||||
default:
|
||||
throw new IOException("Invalid BPP.");
|
||||
}
|
||||
|
||||
int red = (value >> redShift) & redMax;
|
||||
int green = (value >> greenShift) & greenMax;
|
||||
int blue = (value >> blueShift) & blueMax;
|
||||
|
||||
red <<= 8 - redBits;
|
||||
green <<= 8 - greenBits;
|
||||
blue <<= 8 - blueBits;
|
||||
|
||||
int color = (red << 16) | (green << 8) | blue;
|
||||
return color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BufferedImage generateBlankImage(int width, int height) {
|
||||
if (readAsIndexed)
|
||||
return new BufferedImage(width, height, BufferedImage.TYPE_BYTE_INDEXED, COLOR_MODEL);
|
||||
return new BufferedImage(width, height, BufferedImage.TYPE_INT_ARGB);
|
||||
}
|
||||
|
||||
// Load color model
|
||||
public static final IndexColorModel COLOR_MODEL;
|
||||
static {
|
||||
// Construct color model
|
||||
byte[] colorShade = {0, (byte) 51, (byte) 104, (byte) 153, (byte) 204, (byte) 255};
|
||||
byte[] greyShade = new byte[39];
|
||||
for (int i=1; i<40; i++)
|
||||
greyShade[i-1] = (byte) (6*i);
|
||||
|
||||
byte[] red = new byte[colorShade.length*colorShade.length*colorShade.length+greyShade.length+1];
|
||||
byte[] green = new byte[colorShade.length*colorShade.length*colorShade.length+greyShade.length+1];
|
||||
byte[] blue = new byte[colorShade.length*colorShade.length*colorShade.length+greyShade.length+1];
|
||||
byte[] alpha = new byte[colorShade.length*colorShade.length*colorShade.length+greyShade.length+1];
|
||||
|
||||
int color = 0;
|
||||
for (int r=0; r<colorShade.length; r++) {
|
||||
for (int g=0; g<colorShade.length; g++) {
|
||||
for (int b=0; b<colorShade.length; b++) {
|
||||
red[color] = colorShade[r];
|
||||
green[color] = colorShade[g];
|
||||
blue[color] = colorShade[b];
|
||||
alpha[color] = (byte) 255;
|
||||
color++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int grey=0; grey<greyShade.length; grey++) {
|
||||
red[color] = greyShade[grey];
|
||||
green[color] = greyShade[grey];
|
||||
blue[color] = greyShade[grey];
|
||||
alpha[color] = (byte) 255;
|
||||
color++;
|
||||
}
|
||||
|
||||
red[color] = 0;
|
||||
green[color] = 0;
|
||||
blue[color] = 0;
|
||||
alpha[color] = (byte) 0;
|
||||
|
||||
COLOR_MODEL = new IndexColorModel(8, 256, red, green, blue, alpha);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -0,0 +1,64 @@
|
||||
package net.sourceforge.guacamole.vnc;
|
||||
|
||||
/*
|
||||
* Guacamole - Pure JavaScript/HTML VNC Client
|
||||
* Copyright (C) 2010 Michael Jumper
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
public abstract class VNCImageReader {
|
||||
|
||||
public BufferedImage readCImage(DataInputStream input, int width, int height) throws IOException {
|
||||
|
||||
BufferedImage image = generateBlankImage(width, height);
|
||||
// Read image
|
||||
|
||||
for (int pixelY=0; pixelY<height; pixelY++) {
|
||||
for (int pixelX=0; pixelX<width; pixelX++) {
|
||||
int color = 0xFF000000 | readCPixel(input);
|
||||
image.setRGB(pixelX, pixelY, color);
|
||||
}
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
public BufferedImage readImage(DataInputStream input, int width, int height) throws IOException {
|
||||
|
||||
BufferedImage image = generateBlankImage(width, height);
|
||||
// Read image
|
||||
|
||||
for (int pixelY=0; pixelY<height; pixelY++) {
|
||||
for (int pixelX=0; pixelX<width; pixelX++) {
|
||||
int color = 0xFF000000 | readPixel(input);
|
||||
image.setRGB(pixelX, pixelY, color);
|
||||
}
|
||||
}
|
||||
|
||||
return image;
|
||||
}
|
||||
|
||||
public abstract BufferedImage generateBlankImage(int width, int height);
|
||||
public abstract int readPixel(DataInputStream input) throws IOException;
|
||||
public int readCPixel(DataInputStream input) throws IOException {
|
||||
return readPixel(input);
|
||||
}
|
||||
|
||||
}
|
||||
|
@@ -0,0 +1,104 @@
|
||||
package net.sourceforge.guacamole.vnc;
|
||||
|
||||
/*
|
||||
* Guacamole - Pure JavaScript/HTML VNC Client
|
||||
* Copyright (C) 2010 Michael Jumper
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
import java.awt.image.IndexColorModel;
|
||||
import java.io.DataInputStream;
|
||||
import java.io.IOException;
|
||||
|
||||
|
||||
public class VNCIndexedImageReader extends VNCImageReader {
|
||||
|
||||
private IndexColorModel palette;
|
||||
private byte[] red;
|
||||
private byte[] green;
|
||||
private byte[] blue;
|
||||
|
||||
// Set up BGR reader
|
||||
public VNCIndexedImageReader(byte[] red, byte[] green, byte[] blue) throws VNCException {
|
||||
|
||||
this.red = red;
|
||||
this.green = green;
|
||||
this.blue = blue;
|
||||
|
||||
palette = new IndexColorModel(8, 256, red, green, blue);
|
||||
if (palette.getMapSize() != 256)
|
||||
throw new VNCException("Currently, only 256-color maps are supported.");
|
||||
|
||||
}
|
||||
|
||||
@Override
|
||||
public int readPixel(DataInputStream input) throws IOException {
|
||||
int value = input.read();
|
||||
int color = (red[value] << 16) | (green[value] << 8) | blue[value];
|
||||
return color;
|
||||
}
|
||||
|
||||
@Override
|
||||
public BufferedImage generateBlankImage(int width, int height) {
|
||||
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_BYTE_INDEXED, palette);
|
||||
return image;
|
||||
}
|
||||
|
||||
// Load color model
|
||||
public static final IndexColorModel COLOR_MODEL;
|
||||
static {
|
||||
// Construct color model
|
||||
byte[] colorShade = {0, (byte) 51, (byte) 104, (byte) 153, (byte) 204, (byte) 255};
|
||||
byte[] greyShade = new byte[39];
|
||||
for (int i=1; i<40; i++)
|
||||
greyShade[i-1] = (byte) (6*i);
|
||||
|
||||
byte[] red = new byte[colorShade.length*colorShade.length*colorShade.length+greyShade.length+1];
|
||||
byte[] green = new byte[colorShade.length*colorShade.length*colorShade.length+greyShade.length+1];
|
||||
byte[] blue = new byte[colorShade.length*colorShade.length*colorShade.length+greyShade.length+1];
|
||||
byte[] alpha = new byte[colorShade.length*colorShade.length*colorShade.length+greyShade.length+1];
|
||||
|
||||
int color = 0;
|
||||
for (int r=0; r<colorShade.length; r++) {
|
||||
for (int g=0; g<colorShade.length; g++) {
|
||||
for (int b=0; b<colorShade.length; b++) {
|
||||
red[color] = colorShade[r];
|
||||
green[color] = colorShade[g];
|
||||
blue[color] = colorShade[b];
|
||||
alpha[color] = (byte) 255;
|
||||
color++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (int grey=0; grey<greyShade.length; grey++) {
|
||||
red[color] = greyShade[grey];
|
||||
green[color] = greyShade[grey];
|
||||
blue[color] = greyShade[grey];
|
||||
alpha[color] = (byte) 255;
|
||||
color++;
|
||||
}
|
||||
|
||||
red[color] = 0;
|
||||
green[color] = 0;
|
||||
blue[color] = 0;
|
||||
alpha[color] = (byte) 0;
|
||||
|
||||
COLOR_MODEL = new IndexColorModel(8, 256, red, green, blue, alpha);
|
||||
}
|
||||
|
||||
}
|
||||
|
55
guacamole/src/net/sourceforge/guacamole/vnc/event/Event.java
Normal file
55
guacamole/src/net/sourceforge/guacamole/vnc/event/Event.java
Normal file
@@ -0,0 +1,55 @@
|
||||
|
||||
package net.sourceforge.guacamole.vnc.event;
|
||||
|
||||
/*
|
||||
* Guacamole - Pure JavaScript/HTML VNC Client
|
||||
* Copyright (C) 2010 Michael Jumper
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
public abstract class Event implements Comparable<Event> {
|
||||
|
||||
private long time;
|
||||
private int index;
|
||||
|
||||
public Event(int index) {
|
||||
this.time = System.currentTimeMillis();
|
||||
this.index = index;
|
||||
}
|
||||
|
||||
public int getIndex() {
|
||||
return index;
|
||||
}
|
||||
|
||||
public long getTime() {
|
||||
return time;
|
||||
}
|
||||
|
||||
public int hashCode() {
|
||||
return index;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean equals(Object o) {
|
||||
if (o == null) return false;
|
||||
if (getClass() != o.getClass()) return false;
|
||||
return getIndex() == ((Event) o).getIndex();
|
||||
}
|
||||
|
||||
public int compareTo(Event e) {
|
||||
return getIndex() - e.getIndex();
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,28 @@
|
||||
|
||||
package net.sourceforge.guacamole.vnc.event;
|
||||
|
||||
/*
|
||||
* Guacamole - Pure JavaScript/HTML VNC Client
|
||||
* Copyright (C) 2010 Michael Jumper
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
|
||||
public interface EventHandler<E extends Event> {
|
||||
|
||||
public void handle(E e) throws IOException;
|
||||
|
||||
}
|
@@ -0,0 +1,191 @@
|
||||
|
||||
package net.sourceforge.guacamole.vnc.event;
|
||||
|
||||
/*
|
||||
* Guacamole - Pure JavaScript/HTML VNC Client
|
||||
* Copyright (C) 2010 Michael Jumper
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.PriorityQueue;
|
||||
|
||||
public class EventQueue<E extends Event> {
|
||||
|
||||
private int nextIndex = 0;
|
||||
private final PriorityQueue<E> queue = new PriorityQueue<E>();
|
||||
private EventHandler<E> handler;
|
||||
|
||||
private final int deadline;
|
||||
|
||||
private AutoflushThread autoflush = new AutoflushThread();
|
||||
|
||||
private class AutoflushThread extends Thread {
|
||||
|
||||
private IOException error;
|
||||
private long deadline;
|
||||
private static final long ONE_YEAR = 31536000;
|
||||
|
||||
private boolean killed = false;
|
||||
|
||||
public AutoflushThread() {
|
||||
this.deadline = ONE_YEAR;
|
||||
start();
|
||||
}
|
||||
|
||||
public void run() {
|
||||
while (!killed) {
|
||||
try {
|
||||
if (deadline > 0) sleep(deadline);
|
||||
dropPendingEvents();
|
||||
flush();
|
||||
}
|
||||
catch (InterruptedException e) {
|
||||
// Interrupt indicates event handled, or thread killed
|
||||
if (killed) return;
|
||||
}
|
||||
catch (IOException e) {
|
||||
error = e;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void setDeadline(long deadline) {
|
||||
this.deadline = deadline;
|
||||
interrupt();
|
||||
}
|
||||
|
||||
public void checkError() throws IOException {
|
||||
if (error != null) throw error;
|
||||
}
|
||||
|
||||
public void kill() {
|
||||
killed = true;
|
||||
interrupt();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
public void close() {
|
||||
autoflush.kill();
|
||||
}
|
||||
|
||||
// Starts autoflush wait thread for any waiting events on the queue
|
||||
private void startDeadlineAutoflush() {
|
||||
synchronized (queue) {
|
||||
|
||||
// No need to autoflush if nothing waiting
|
||||
if (queue.size() == 0) return;
|
||||
|
||||
// Get waiting event
|
||||
E waiting = queue.peek();
|
||||
|
||||
if (waiting != null) {
|
||||
long untilDeadline = deadline + waiting.getTime() - System.currentTimeMillis();
|
||||
|
||||
// Start autoflush thread which waits for time remaining until next
|
||||
// event's deadline.
|
||||
autoflush.setDeadline(untilDeadline);
|
||||
}
|
||||
else
|
||||
autoflush.setDeadline(AutoflushThread.ONE_YEAR);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
public EventQueue(EventHandler<E> handler, int deadline) {
|
||||
this.handler = handler;
|
||||
this.deadline = deadline;
|
||||
}
|
||||
|
||||
public void add(E event) throws IOException {
|
||||
synchronized (queue) {
|
||||
|
||||
autoflush.checkError();
|
||||
|
||||
if (event.getIndex() < nextIndex) {
|
||||
//System.err.println("Past event dropped.");
|
||||
return;
|
||||
}
|
||||
|
||||
if (event == null)
|
||||
throw new Error("Cannot add null event.");
|
||||
|
||||
queue.add(event);
|
||||
}
|
||||
|
||||
flush();
|
||||
}
|
||||
|
||||
private E next() {
|
||||
synchronized (queue) {
|
||||
// If no events, return nothing.
|
||||
if (queue.size() == 0) return null;
|
||||
|
||||
// If still waiting for true next event, return nothing.
|
||||
E event = queue.peek();
|
||||
if (event.getIndex() != nextIndex)
|
||||
return null;
|
||||
|
||||
// If event found, expect next event, remove and return current.
|
||||
queue.remove();
|
||||
nextIndex++;
|
||||
return event;
|
||||
}
|
||||
}
|
||||
|
||||
// Return number of waiting events
|
||||
public int getWaiting() {
|
||||
synchronized (queue) {
|
||||
// If no events, then none waiting.
|
||||
if (queue.size() == 0) return 0;
|
||||
|
||||
// If we have the next event, then none waiting.
|
||||
E event = queue.peek();
|
||||
if (event.getIndex() == nextIndex)
|
||||
return 0;
|
||||
|
||||
// Otherwise, all events are waiting.
|
||||
return queue.size();
|
||||
}
|
||||
}
|
||||
|
||||
// Stop waiting for any unreceived events
|
||||
private void dropPendingEvents() {
|
||||
synchronized (queue) {
|
||||
// If no events, nothing needs to be changed;
|
||||
if (queue.size() == 0) return;
|
||||
|
||||
// Otherwise, update nextIndex to index of next event
|
||||
E event = queue.peek();
|
||||
nextIndex = event.getIndex();
|
||||
}
|
||||
}
|
||||
|
||||
// Attempts to flush queue
|
||||
// If any events remain, an autoflush thread is started.
|
||||
private void flush() throws IOException {
|
||||
synchronized (queue) {
|
||||
E nextEvent;
|
||||
while ((nextEvent = next()) != null)
|
||||
handler.handle(nextEvent);
|
||||
}
|
||||
|
||||
// Start autoflush thread for any remaining events.
|
||||
startDeadlineAutoflush();
|
||||
}
|
||||
|
||||
}
|
@@ -0,0 +1,39 @@
|
||||
package net.sourceforge.guacamole.vnc.event;
|
||||
|
||||
/*
|
||||
* Guacamole - Pure JavaScript/HTML VNC Client
|
||||
* Copyright (C) 2010 Michael Jumper
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
public class KeyEvent extends Event {
|
||||
|
||||
private int keysym;
|
||||
private boolean pressed;
|
||||
|
||||
public KeyEvent(int index, int keysym, boolean pressed) {
|
||||
super(index);
|
||||
this.keysym = keysym;
|
||||
this.pressed = pressed;
|
||||
}
|
||||
|
||||
public int getKeySym() {
|
||||
return keysym;
|
||||
}
|
||||
|
||||
public boolean getPressed() {
|
||||
return pressed;
|
||||
}
|
||||
}
|
@@ -0,0 +1,69 @@
|
||||
package net.sourceforge.guacamole.vnc.event;
|
||||
|
||||
/*
|
||||
* Guacamole - Pure JavaScript/HTML VNC Client
|
||||
* Copyright (C) 2010 Michael Jumper
|
||||
*
|
||||
* This program is free software: you can redistribute it and/or modify
|
||||
* it under the terms of the GNU Affero General Public License as published by
|
||||
* the Free Software Foundation, either version 3 of the License, or
|
||||
* (at your option) any later version.
|
||||
*
|
||||
* 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
|
||||
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
||||
*/
|
||||
|
||||
public class PointerEvent extends Event {
|
||||
|
||||
private boolean leftButtonPressed;
|
||||
private boolean middleButtonPressed;
|
||||
private boolean rightButtonPressed;
|
||||
private boolean upButtonPressed;
|
||||
private boolean downButtonPressed;
|
||||
private int x;
|
||||
private int y;
|
||||
|
||||
public PointerEvent(int index, boolean leftButtonPressed, boolean middleButtonPressed, boolean rightButtonPressed, boolean upButtonPressed, boolean downButtonPressed, int x, int y) {
|
||||
super(index);
|
||||
this.leftButtonPressed = leftButtonPressed;
|
||||
this.middleButtonPressed = middleButtonPressed;
|
||||
this.rightButtonPressed = rightButtonPressed;
|
||||
this.upButtonPressed = upButtonPressed;
|
||||
this.downButtonPressed = downButtonPressed;
|
||||
this.x = x;
|
||||
this.y = y;
|
||||
}
|
||||
|
||||
public boolean isLeftButtonPressed() {
|
||||
return leftButtonPressed;
|
||||
}
|
||||
|
||||
public boolean isMiddleButtonPressed() {
|
||||
return middleButtonPressed;
|
||||
}
|
||||
|
||||
public boolean isRightButtonPressed() {
|
||||
return rightButtonPressed;
|
||||
}
|
||||
|
||||
public boolean isUpButtonPressed() {
|
||||
return upButtonPressed;
|
||||
}
|
||||
|
||||
public boolean isDownButtonPressed() {
|
||||
return downButtonPressed;
|
||||
}
|
||||
|
||||
public int getX() {
|
||||
return x;
|
||||
}
|
||||
|
||||
public int getY() {
|
||||
return y;
|
||||
}
|
||||
}
|
Reference in New Issue
Block a user