/* * Copyright 2010 jOpenRay, ILM Informatique * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 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 * General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/> */ package org.jopenray.server.thinclient; import java.io.IOException; import java.util.ArrayList; import java.util.List; import org.jopenray.operation.Operation; import org.jopenray.operation.SleepOperation; import org.jopenray.util.ByteArrayList; public class DisplayMessage { private ByteArrayList operationBuffer; private DisplayWriterThread displayWriterThread; private List<Operation> operations = new ArrayList<Operation>(4); private int l; private boolean resending; public DisplayMessage(DisplayWriterThread displayWriterThread) { this.displayWriterThread = displayWriterThread; resending = false; } public DisplayMessage(DisplayWriterThread displayWriterThread, boolean resending) { this.displayWriterThread = displayWriterThread; this.resending = resending; // operationBuffer = new ByteArrayList(1448, HEADER_SIZE); } public boolean isEmpty() { return operations.isEmpty(); } public void addOperation(Operation o) { this.operations.add(o); l += o.getLength(); } public void send(final ThinClient client) throws IOException { // System.out.println("\n=====Sending Message..."); int maxSize = client.getMTU() - 10 - 42; byte[] buffer = new byte[maxSize]; int type = 1; int bufferLength = 16; int nextPacketStartAt = 0; int size = this.operations.size(); for (int i = 0; i < size; i++) { Operation o = this.operations.get(i); if (o instanceof SleepOperation) { try { Thread.sleep(((SleepOperation) o).getSleepTime(), 0); } catch (InterruptedException e) { // TODO Auto-generated catch block e.printStackTrace(); } continue; } try { if (!resending) { o.setSequence(displayWriterThread.getNextOpcodeSeq(o .getSequenceIncrement())); client.addToHistory(o); } int nbCopiedBytes = o.copyStart(buffer, bufferLength); int nbBytesMissing = o.getLength() - nbCopiedBytes; bufferLength += nbCopiedBytes; if (nbBytesMissing > 0) { // Sending the packet split type = 6; // add header ByteArrayList.setInt16(buffer, 0, displayWriterThread .getNextSeq()); ByteArrayList.setInt16(buffer, 2, nextPacketStartAt); ByteArrayList.setInt16(buffer, 4, type); // next 12 bytes are 0 client.sendBytes(buffer, bufferLength); o.copyEnd(buffer, nbBytesMissing, 16); bufferLength = nbBytesMissing + 16; if (nbBytesMissing == o.getLength()) { nextPacketStartAt = 0; } else { nextPacketStartAt = nbBytesMissing; } } } catch (Throwable t) { t.printStackTrace(); new IllegalStateException("Failed to process operation:" + o); } } if (bufferLength > 0) { // add header ByteArrayList.setInt16(buffer, 0, displayWriterThread.getNextSeq()); ByteArrayList.setInt16(buffer, 2, nextPacketStartAt); ByteArrayList.setInt16(buffer, 4, type); // next 12 bytes are 0 client.sendBytes(buffer, bufferLength); } // System.out.println("=====Sending Message done..."); } /* * public void readFromRawFile(String string) { File b = new File(string); * if (!b.exists()) { System.err.println("Not found:" + * b.getAbsolutePath()); } try { FileInputStream fIn = new * FileInputStream(b); byte[] fileContent = new byte[(int) b.length()]; int * r = fIn.read(fileContent); ByteBuffer newBuffer = * ByteBuffer.wrap(fileContent, 0, r); newBuffer.putInt(0, * buffer.getInt(0)); buffer = newBuffer; * * System.out.println("Read:" + r + " bytes"); } catch (Exception e) { // * TODO Auto-generated catch block e.printStackTrace(); } } */ /* * public void addFillRect(int x, int y, int width, int height, Color color) * { int nextOpcodeSeq = this.displayWriterThread.getNextOpcodeSeq(); * System. * out.println("DisplayMessage.addFillRect() at: "+x+" , "+y+" "+width * +" x "+height +" opseq:"+nextOpcodeSeq); operationBuffer.addInt8(0xA2); * // fillrect // hflags operationBuffer.addInt8(0x00); // seq * * operationBuffer.addInt16(nextOpcodeSeq); // x y * operationBuffer.addInt16(x); operationBuffer.addInt16(y); // w h * operationBuffer.addInt16(width); operationBuffer.addInt16(height); // * fillrect * * operationBuffer.addInt8(0xFF); operationBuffer.addInt8(color.getBlue()); * operationBuffer.addInt8(color.getGreen()); * operationBuffer.addInt8(color.getRed()); * * } */ /* * public void addAC() { operationBuffer.addInt8(0xAC); // hflags * operationBuffer.addInt8(0x00); // seq * operationBuffer.addInt16(this.displayWriterThread.getNextOpcodeSeq()); // * x y operationBuffer.addInt16(0); operationBuffer.addInt16(0); // w h * operationBuffer.addInt16(0); operationBuffer.addInt16(0); * * operationBuffer.addInt16(0); operationBuffer.addInt16(1); * operationBuffer.addInt16(0); operationBuffer.addInt16(4); } */ /* * public void addD1(int x, int y, int width, int height) { * operationBuffer.addInt8(0xD1); // hflags operationBuffer.addInt8(0x00); * // seq * operationBuffer.addInt16(this.displayWriterThread.getNextOpcodeSeq()); // * x y operationBuffer.addInt16(x); operationBuffer.addInt16(y); // w h * operationBuffer.addInt16(width); operationBuffer.addInt16(height); * * } */ /* * public void addD8(int x, int y, int width, int height) { * operationBuffer.addInt8(0xD8); // hflags operationBuffer.addInt8(0x00); * // seq * operationBuffer.addInt16(this.displayWriterThread.getNextOpcodeSeq()); // * x y operationBuffer.addInt16(x); operationBuffer.addInt16(y); // w h * operationBuffer.addInt16(width); operationBuffer.addInt16(height); * * } */ /* * public void addPad() { operationBuffer.addInt8(0xAF); // hflags * operationBuffer.addInt8(0x00); // seq operationBuffer * .addInt16(this.displayWriterThread.getCurrentOpcodeSeq()); // x y * operationBuffer.addInt16(0); operationBuffer.addInt16(1); // w h * operationBuffer.addInt16(0xFFFF); operationBuffer.addInt16(0xFFFF); * * operationBuffer.addInt8(0xFF); operationBuffer.addInt8(0xFF); * operationBuffer.addInt8(0xFF); operationBuffer.addInt8(0xFF); for (int i * = 0; i < 8; i++) { operationBuffer.addInt8(0xFF); } } */ /* * public void addA1() { operationBuffer.addInt8(0xA1); // hflags * operationBuffer.addInt8(0x00); // seq * operationBuffer.addInt16(this.displayWriterThread.getNextOpcodeSeq()); // * x y operationBuffer.addInt16(0); operationBuffer.addInt16(0); // w h * operationBuffer.addInt16(0x0001); operationBuffer.addInt16(0x0001); * * operationBuffer.addInt8(0x00); operationBuffer.addInt8(0x00); * operationBuffer.addInt8(0x00); operationBuffer.addInt8(0x00); * * } */ /* * public void addSetMouseBound(int x, int y, int width, int height) { * operationBuffer.addInt8(0xA8); // hflags operationBuffer.addInt8(0x00); * // seq * operationBuffer.addInt16(this.displayWriterThread.getNextOpcodeSeq()); // * x y operationBuffer.addInt16(x); operationBuffer.addInt16(y); // w h * operationBuffer.addInt16(width); operationBuffer.addInt16(height); * * // Bounds operationBuffer.addInt16(x); operationBuffer.addInt16(y); * operationBuffer.addInt16(width); operationBuffer.addInt16(height); * * } */ public void addSetMouseCursor(int x, int y, int width, int height) { operationBuffer.addInt8(0xA9); // hflags operationBuffer.addInt8(0x00); // seq operationBuffer.addInt16(this.displayWriterThread.getNextOpcodeSeq(0)); // x y operationBuffer.addInt16(x); operationBuffer.addInt16(y); // w h operationBuffer.addInt16(width); operationBuffer.addInt16(height); // C1 operationBuffer.addInt8(0x0); operationBuffer.addInt8(0x255); operationBuffer.addInt8(0x255); operationBuffer.addInt8(0x255); // C2 operationBuffer.addInt8(0x0); operationBuffer.addInt8(0x0); operationBuffer.addInt8(0x0); operationBuffer.addInt8(0x0); // Bitmap byte[] bitmap = new byte[] { 0x00, 0x00, 0x70, 0x0E, 0x78, 0x1E, 0x7C, 0x3E, 0x3E, 0x7C, 0x1F, (byte) 0xF8, 0x0F, (byte) 0xF0, 0x07, (byte) 0xE0, 0x07, (byte) 0xE0, 0x0F, (byte) 0xF0, 0x1F, (byte) 0xF8, 0x3E, 0x7C, 0x7C, 0x3E, 0x78, 0x1E, 0x70, 0x0E, 0x00, 0x00 }; operationBuffer.addBytes(bitmap); // Bitmap byte[] mask = new byte[] { (byte) 0xF0, 0x0F, (byte) 0xF8, 0x1F, (byte) 0xFC, 0x3F, (byte) 0xFE, 0x7F, 0x7F, (byte) 0xFE, 0x3F, (byte) 0xFC, (byte) 0x1F, (byte) 0xF8, 0x0F, (byte) 0xF0, 0x0F, (byte) 0xF0, 0x1F, (byte) 0xF8, 0x3F, (byte) 0xFC, 0x7F, (byte) 0xFE, (byte) 0xFE, 0x7F, (byte) 0xFC, 0x3F, (byte) 0xF8, 0x1F, (byte) 0xF0, 0x0F }; operationBuffer.addBytes(mask); } /* * public void addSetRectBitmap(int x, int y, int width, int height, Color * c0, Color c1, BitArray b) { int nextOpcodeSeq = * this.displayWriterThread.getNextOpcodeSeq(); * System.out.println("DisplayMessage.addSetRectBitmap() at: " * +x+" , "+y+" "+width+" x "+height +" opcodeseq:"+nextOpcodeSeq); * * operationBuffer.addInt8(0xA5); // hflags operationBuffer.addInt8(0x00); * // seq operationBuffer.addInt16(nextOpcodeSeq); // x y * operationBuffer.addInt16(x); operationBuffer.addInt16(y); // w h * operationBuffer.addInt16(width); operationBuffer.addInt16(height); // C1 * operationBuffer.addInt8(0x00); operationBuffer.addInt8(c0.getBlue()); * operationBuffer.addInt8(c0.getGreen()); * operationBuffer.addInt8(c0.getRed()); // C2 * operationBuffer.addInt8(0x00); operationBuffer.addInt8(c1.getBlue()); * operationBuffer.addInt8(c1.getGreen()); * operationBuffer.addInt8(c1.getRed()); * * * operationBuffer.addBytes(b.toByteArray()); * * } */ public int getLength() { return l; } public void dump() { final int size = this.operations.size(); for (int i = 0; i < size; i++) { System.out.println("Operation " + i); this.operations.get(i).dump(); } } }