/*
* 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.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.List;
import javax.imageio.ImageIO;
import org.jopenray.operation.FillOperation;
import org.jopenray.operation.SetBoundsOperation;
import org.jopenray.operation.SetMouseCursorOperation;
import org.jopenray.operation.SleepOperation;
public class DisplayWriterThread extends Thread {
private static final int WIDTH = 4;
private static final int MAX_SIZE = 320;
private static final boolean DEBUG = false;
private static final int NO_COLOR = 888;
private ThinClient client;
List<DisplayMessage> toSend = new LinkedList<DisplayMessage>();
public BitmapEncoder encoder;
public DisplayWriterThread(ThinClient client) {
this.client = client;
setDaemon(true);
encoder = new BitmapEncoder(this);
setName("Display connection" + client.getServer().getHostAddress());
this.setPriority(MIN_PRIORITY);
}
private int seq = 0;
private int opSeq = 0;
private long totalBytesToSend = 0;
public void addMessage(DisplayMessage m) {
synchronized (toSend) {
totalBytesToSend += m.getLength();
// System.out.println("Total bytes to send:" + totalBytesToSend);
toSend.add(m);
if (toSend.size() == 1) {
toSend.notify();
}
}
}
public void addHighPriorityMessage(DisplayMessage m) {
synchronized (toSend) {
totalBytesToSend += m.getLength();
System.out.println("Total bytes to send:" + totalBytesToSend);
toSend.add(0, m);
if (toSend.size() == 1) {
toSend.notify();
}
}
}
long counter = 0;
@Override
public void run() {
sendInit();
while (!this.isInterrupted()) {
DisplayMessage m = null;
synchronized (toSend) {
if (!toSend.isEmpty()) {
m = toSend.remove(0);
} else {
try {
toSend.wait();
} catch (InterruptedException e) {
e.printStackTrace();
}
}
}
if (m != null) {
try {
m.send(client);
counter += m.getLength();
} catch (Exception e) {
e.printStackTrace();
}
}
}
}
void sendInit() {
final int screenWidth = client.getScreenWidth();
final int screenHeight = client.getScreenHeight();
synchronized (toSend) {
{
DisplayMessage mBound = new DisplayMessage(this);
mBound.addOperation(new SetBoundsOperation(0, 0, screenWidth,
screenHeight));
addMessage(mBound);
}
{
DisplayMessage mCursor = new DisplayMessage(this);
mCursor.addOperation(new SetMouseCursorOperation(
SetMouseCursorOperation.INVISIBLE_CURSOR));
addMessage(mCursor);
}
final int stop = 2 * screenWidth / 3;
for (int i = 0; i < stop; i += WIDTH) {
DisplayMessage mClear = new DisplayMessage(this);
mClear.addOperation(new FillOperation(screenWidth - WIDTH - i,
0, WIDTH, screenHeight, Color.BLACK));
mClear.addOperation(new FillOperation(i, 0, WIDTH,
screenHeight, Color.BLACK));
mClear.addOperation(new SleepOperation(4));
addMessage(mClear);
}
}
}
private void test() {
{
DisplayMessage mBound = new DisplayMessage(this);
mBound.addOperation(new SetBoundsOperation(0, 0, 1280, 1024));
addMessage(mBound);
}
{
DisplayMessage mCursor = new DisplayMessage(this);
mCursor.addOperation(new SetMouseCursorOperation(
SetMouseCursorOperation.UNIX_CURSOR));
addMessage(mCursor);
}
DisplayMessage mClear = new DisplayMessage(this);
mClear.addOperation(new FillOperation(0, 0, 1280, 1024, Color.RED));
addMessage(mClear);
try {
Thread.sleep(1000);
} catch (InterruptedException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
System.out
.println("===================== init done ==========================");
sendImage("test.png", 0, 0);
sendImage("console.png", 212, 23);
System.out
.println("===================== bitmap sent ========================");
}
public void sendImage(String fileName, int toX, int toY) {
try {
BufferedImage image = ImageIO.read(new File(fileName));
encoder.encode(image, toX, toY);
} catch (IOException e1) {
// TODO Auto-generated catch block
e1.printStackTrace();
}
}
public void sendImage(BufferedImage image, int toX, int toY) {
try {
encoder.encode(image, toX, toY);
} catch (Exception e) {
// TODO: handle exception
System.err.println("sendImage:" + image.getWidth() + "x"
+ image.getHeight() + " to:" + toX + "," + toY);
e.printStackTrace();
}
}
public static Color getColorFrom(int c1) {
if (c1 == NO_COLOR) {
throw new IllegalArgumentException("Bad color");
}
int red1 = (c1 & 0x00ff0000) >> 16;
int green1 = (c1 & 0x0000ff00) >> 8;
int blue1 = c1 & 0x000000ff;
return new Color(red1, green1, blue1);
}
public synchronized int getNextSeq() {
seq++;
return seq;
}
public synchronized int getNextOpcodeSeq(int i) {
opSeq += i;
return opSeq;
}
public synchronized int getCurrentOpcodeSeq() {
return opSeq;
}
public int getMessageToSendCount() {
return this.toSend.size();
}
public String getStats() {
return encoder.getStats();
}
public void dumpOperationsToSend() {
synchronized (toSend) {
System.out.println(encoder.getStats());
for (Iterator iterator = toSend.iterator(); iterator.hasNext();) {
DisplayMessage type = (DisplayMessage) iterator.next();
type.dump();
// System.out.println(encoder.getStats());
}
}
}
}