315 lines
10 KiB
Java
315 lines
10 KiB
Java
package tdm.xserver;
|
|
|
|
import android.util.Log;
|
|
|
|
import android.graphics.Bitmap;
|
|
import android.graphics.Canvas;
|
|
import android.graphics.Path;
|
|
import android.graphics.Paint;
|
|
|
|
import java.util.ArrayList;
|
|
|
|
abstract class X11Drawable extends X11Resource
|
|
{
|
|
byte mDepth;
|
|
byte mBPP;
|
|
X11Rect mRect;
|
|
short mBorderWidth; // This is here for GetGeometry
|
|
X11Visual mVisual; // This is here for GetImage
|
|
|
|
Bitmap mBitmap;
|
|
Canvas mCanvas;
|
|
|
|
X11Drawable(int type, int id) {
|
|
super(type, id);
|
|
}
|
|
|
|
void destroy() {
|
|
mCanvas = null;
|
|
mBitmap = null;
|
|
mVisual = null;
|
|
mRect = null;
|
|
super.destroy();
|
|
}
|
|
|
|
void handleGetGeometry(X11Client c, X11RequestMessage msg) {
|
|
X11ReplyMessage reply = new X11ReplyMessage(msg);
|
|
reply.headerData(mDepth);
|
|
reply.mData.enqInt(c.mServer.mDefaultScreen.mRoot.mId);
|
|
reply.mData.enqShort(mRect.x);
|
|
reply.mData.enqShort(mRect.y);
|
|
reply.mData.enqShort(mRect.w);
|
|
reply.mData.enqShort(mRect.h);
|
|
reply.mData.enqShort(mBorderWidth);
|
|
c.send(reply);
|
|
}
|
|
|
|
void handleCopyArea(X11Client c, X11RequestMessage msg) throws X11Error {
|
|
X11Drawable dst = c.getDrawable(msg.mData.deqInt());
|
|
X11GContext gc = c.getGContext(msg.mData.deqInt());
|
|
short src_x = msg.mData.deqShort();
|
|
short src_y = msg.mData.deqShort();
|
|
short dst_x = msg.mData.deqShort();
|
|
short dst_y = msg.mData.deqShort();
|
|
short w = msg.mData.deqShort();
|
|
short h = msg.mData.deqShort();
|
|
|
|
//XXX: Use Canvas.drawBitmap with a clip mask?
|
|
//XXX: handle window with tiled background
|
|
short x, y;
|
|
for (y = 0; y < h; ++y) {
|
|
for (x = 0; x < w; ++x) {
|
|
int pixel = mBitmap.getPixel(src_x + x, src_y + y);
|
|
dst.mBitmap.setPixel(dst_x + x, dst_y + y, pixel);
|
|
}
|
|
}
|
|
}
|
|
|
|
void handlePolyPoint(X11Client c, X11RequestMessage msg) throws X11Error {
|
|
X11GContext gc = c.getGContext(msg.mData.deqInt());
|
|
int count = msg.mData.remain()/4;
|
|
float[] points = new float[count*2];
|
|
for (int n = 0; n < count; ++n) {
|
|
points[n*2+0] = (float)msg.mData.deqShort();
|
|
points[n*2+1] = (float)msg.mData.deqShort();
|
|
}
|
|
mCanvas.drawPoints(points, gc.mPaint);
|
|
postRender();
|
|
}
|
|
|
|
void handlePolyLine(X11Client c, X11RequestMessage msg) throws X11Error {
|
|
byte coord_mode = msg.headerData();
|
|
X11GContext gc = c.getGContext(msg.mData.deqInt());
|
|
int count = msg.mData.remain()/4 - 1;
|
|
float[] points = new float[count*4];
|
|
float lastx = (float)msg.mData.deqShort();
|
|
float lasty = (float)msg.mData.deqShort();
|
|
for (int n = 0; n < count; ++n) {
|
|
points[n*4+0] = lastx;
|
|
points[n*4+1] = lasty;
|
|
points[n*4+2] = (float)msg.mData.deqShort();
|
|
points[n*4+3] = (float)msg.mData.deqShort();
|
|
if (coord_mode == 0 /* Origin */) {
|
|
lastx = points[n*4+2];
|
|
lasty = points[n*4+3];
|
|
}
|
|
else {
|
|
lastx += points[n*4+2];
|
|
lasty += points[n*4+3];
|
|
}
|
|
}
|
|
mCanvas.drawLines(points, gc.mPaint);
|
|
postRender();
|
|
}
|
|
|
|
void handlePolySegment(X11Client c, X11RequestMessage msg) throws X11Error {
|
|
X11GContext gc = c.getGContext(msg.mData.deqInt());
|
|
int count = msg.mData.remain()/8;
|
|
float[] points = new float[count*4];
|
|
for (int n = 0; n < count; ++n) {
|
|
points[n*4+0] = (float)msg.mData.deqShort();
|
|
points[n*4+1] = (float)msg.mData.deqShort();
|
|
points[n*4+2] = (float)msg.mData.deqShort();
|
|
points[n*4+3] = (float)msg.mData.deqShort();
|
|
}
|
|
mCanvas.drawLines(points, gc.mPaint);
|
|
postRender();
|
|
}
|
|
|
|
void handlePolyRectangle(X11Client c, X11RequestMessage msg) throws X11Error {
|
|
X11GContext gc = c.getGContext(msg.mData.deqInt());
|
|
while (msg.mData.remain() > 0) {
|
|
short x = msg.mData.deqShort();
|
|
short y = msg.mData.deqShort();
|
|
short w = msg.mData.deqShort();
|
|
short h = msg.mData.deqShort();
|
|
mCanvas.drawRect(x, y, x+w, y+h, gc.mPaint);
|
|
}
|
|
postRender();
|
|
}
|
|
|
|
void handlePolyArc(X11Client c, X11RequestMessage msg) throws X11Error {
|
|
X11GContext gc = c.getGContext(msg.mData.deqInt());
|
|
int count = msg.mData.remain()/12;
|
|
float[] points = new float[count*6];
|
|
for (int n = 0; n < count; ++n) {
|
|
points[n*4+0] = (float)msg.mData.deqShort();
|
|
points[n*4+1] = (float)msg.mData.deqShort();
|
|
points[n*4+2] = (float)msg.mData.deqShort();
|
|
points[n*4+3] = (float)msg.mData.deqShort();
|
|
points[n*4+4] = (float)msg.mData.deqShort();
|
|
points[n*4+5] = (float)msg.mData.deqShort();
|
|
}
|
|
throw new X11Error(X11Error.IMPLEMENTATION, 0);
|
|
}
|
|
|
|
void handleFillPoly(X11Client c, X11RequestMessage msg) throws X11Error {
|
|
X11GContext gc = c.getGContext(msg.mData.deqInt());
|
|
byte shape = msg.mData.deqByte();
|
|
byte coord_mode = msg.mData.deqByte();
|
|
msg.mData.deqSkip(2);
|
|
|
|
Path path = new Path();
|
|
path.setFillType(Path.FillType.WINDING); //XXX: ???
|
|
|
|
float x, y;
|
|
x = (float)msg.mData.deqShort();
|
|
y = (float)msg.mData.deqShort();
|
|
path.moveTo(x, y);
|
|
while (msg.mData.remain() > 0) {
|
|
x = (float)msg.mData.deqShort();
|
|
y = (float)msg.mData.deqShort();
|
|
path.lineTo(x, y);
|
|
}
|
|
mCanvas.drawPath(path, gc.mPaint);
|
|
postRender();
|
|
}
|
|
|
|
void handlePolyFillRectangle(X11Client c, X11RequestMessage msg) throws X11Error {
|
|
X11GContext gc = c.getGContext(msg.mData.deqInt());
|
|
|
|
Paint.Style oldstyle = gc.mPaint.getStyle();
|
|
gc.mPaint.setStyle(Paint.Style.FILL);
|
|
|
|
while (msg.mData.remain() > 0) {
|
|
short x = msg.mData.deqShort();
|
|
short y = msg.mData.deqShort();
|
|
short w = msg.mData.deqShort();
|
|
short h = msg.mData.deqShort();
|
|
mCanvas.drawRect(x, y, x+w, y+h, gc.mPaint);
|
|
}
|
|
gc.mPaint.setStyle(oldstyle);
|
|
postRender();
|
|
}
|
|
|
|
void handlePolyFillArc(X11Client c, X11RequestMessage msg) throws X11Error {
|
|
throw new X11Error(X11Error.IMPLEMENTATION, msg.requestType());
|
|
}
|
|
|
|
void handlePutImage(X11Client c, X11RequestMessage msg) throws X11Error {
|
|
byte fmt = msg.headerData();
|
|
X11GContext gc = c.getGContext(msg.mData.deqInt());
|
|
X11Rect rect = new X11Rect();
|
|
rect.w = msg.mData.deqShort();
|
|
rect.h = msg.mData.deqShort();
|
|
rect.x = msg.mData.deqShort();
|
|
rect.y = msg.mData.deqShort();
|
|
byte left_pad = msg.mData.deqByte();
|
|
byte depth = msg.mData.deqByte();
|
|
msg.mData.deqSkip(2);
|
|
|
|
if (fmt == 0 /* Bitmap */) {
|
|
if (depth != (byte)1) {
|
|
throw new X11Error(X11Error.VALUE, depth);
|
|
}
|
|
fmt = (byte)1 /* XYPixmap */;
|
|
}
|
|
|
|
ArrayList<X11Format> formats = c.mServer.getPixmapFormats();
|
|
X11Format f = null;
|
|
for (X11Format cur : formats) {
|
|
if (cur.mDepth == depth) {
|
|
f = cur;
|
|
break;
|
|
}
|
|
}
|
|
//XXX: handle not found
|
|
|
|
Bitmap bmp;
|
|
|
|
switch (fmt) {
|
|
case 1 /* XYPixmap */:
|
|
bmp = f.decodeImageXY(rect.w, rect.h, msg.mData);
|
|
break;
|
|
case 2 /* ZPixmap */ :
|
|
bmp = f.decodeImageZ(rect.w, rect.h, msg.mData);
|
|
break;
|
|
default:
|
|
throw new X11Error(X11Error.VALUE, fmt);
|
|
}
|
|
|
|
mCanvas.drawBitmap(bmp, rect.x, rect.y, null);
|
|
postRender(rect);
|
|
}
|
|
|
|
void handleGetImage(X11Client c, X11RequestMessage msg) throws X11Error {
|
|
byte fmt = msg.headerData();
|
|
X11Rect rect = new X11Rect();
|
|
rect.x = msg.mData.deqShort();
|
|
rect.y = msg.mData.deqShort();
|
|
rect.w = msg.mData.deqShort();
|
|
rect.h = msg.mData.deqShort();
|
|
int plane_mask = msg.mData.deqInt();
|
|
|
|
ArrayList<X11Format> formats = c.mServer.getPixmapFormats();
|
|
X11Format f = null;
|
|
for (X11Format cur : formats) {
|
|
if (cur.mDepth == mDepth) {
|
|
f = cur;
|
|
break;
|
|
}
|
|
}
|
|
//XXX: handle not found
|
|
|
|
byte[] data;
|
|
|
|
switch (fmt) {
|
|
case 1 /* XYPixmap */:
|
|
data = f.encodeImageXY(rect, plane_mask, mBitmap);
|
|
break;
|
|
case 2 /* ZPixmap */ :
|
|
data = f.encodeImageZ(rect, plane_mask, mBitmap);
|
|
break;
|
|
default:
|
|
throw new X11Error(X11Error.VALUE, fmt);
|
|
}
|
|
|
|
X11ReplyMessage reply = new X11ReplyMessage(msg);
|
|
reply.headerData(mDepth);
|
|
//XXX: This looks ugly, is it the best way?
|
|
reply.mData.enqInt( (mVisual == null ? 0 : mVisual.mId) );
|
|
reply.mData.enqSkip(20);
|
|
reply.mData.enqArray(data);
|
|
c.send(reply);
|
|
}
|
|
|
|
void handleImageText8(X11Client c, X11RequestMessage msg) throws X11Error {
|
|
byte len = msg.headerData();
|
|
X11GContext gc = c.getGContext(msg.mData.deqInt());
|
|
short x = msg.mData.deqShort();
|
|
short y = msg.mData.deqShort();
|
|
String text = msg.mData.deqString(len);
|
|
|
|
short x_min, x_max, y_min, y_max;
|
|
x_min = x;
|
|
x_max = x;
|
|
y_min = y;
|
|
y_max = y;
|
|
for (int idx = 0; idx < text.length(); ++idx) {
|
|
char ch = text.charAt(idx);
|
|
X11CharInfo info = gc.mFont.getCharInfo(ch);
|
|
Bitmap bmp = gc.mFont.getCharImage(ch, gc.mForePixel, gc.mBackPixel);
|
|
if (bmp != null) {
|
|
//XXX: This is probably not correct
|
|
mCanvas.drawBitmap(bmp, x, y-bmp.getHeight(), null);
|
|
}
|
|
x += info.character_width;
|
|
|
|
x_max += info.character_width;
|
|
y_min = (short)Math.min(y_min, y-bmp.getHeight());
|
|
//y_max = (short)Math.max(y_max, y+info.descent);
|
|
}
|
|
|
|
X11Rect r = new X11Rect();
|
|
r.x = x_min;
|
|
r.w = (short)(x_max - x_min);
|
|
r.y = y_min;
|
|
r.h = (short)(y_max - y_min);
|
|
|
|
postRender(r);
|
|
}
|
|
|
|
void postRender(X11Rect r) {}
|
|
void postRender() {}
|
|
}
|