shithub: rd

ref: 2d8cd749501b9a51a8dd8904e30b6e61e4ce4c6d
dir: /cap.c/

View raw version
#include <u.h>
#include <libc.h>
#include "dat.h"
#include "fns.h"

enum /* 2.2.7 Capability Sets; T.128 */
{
	CapGeneral=	1,
	CapBitmap=	2,
	CapOrder=	3,
	CapPointer=	8,
	CapBitcache2=	19,
	CapInput=	13,
	CapSound=	12,
	CapGlyph=	16,

	/* 2.2.7.1.1 General Capability Set (TS_GENERAL_CAPABILITYSET) */
	CanFastpath=	0x0001,
	NoBitcomphdr=	0x0400,
	CanLongcred=	0x0004,
};

static int	putncap(uchar*,uint,Caps*);
static int	putbitcaps(uchar*,uint,Caps*);
static int	putgencaps(uchar*,uint,Caps*);
static int	putordcaps(uchar*,uint,Caps*);
static int	putbc2caps(uchar*,uint,Caps*);
static int	putptrcaps(uchar*,uint,Caps*);
static int	putinpcaps(uchar*,uint,Caps*);
static int	putsndcaps(uchar*,uint,Caps*);
static int	putglycaps(uchar*,uint,Caps*);

static
struct {
	int	size;
	int	(*putcap)(uchar*,uint,Caps*);
} ctab[]=
{
	{ 4,	putncap },
	{ 24,	putgencaps },
	{ 30,	putbitcaps },
	{ 88,	putordcaps },
	{ 40,	putbc2caps },
	{ 8,	putptrcaps },
	{ 88,	putinpcaps },
	{ 8,	putsndcaps },
	{ 52,	putglycaps },
};

int
getcaps(Caps* caps, uchar* a, uint nb)
{
	int ncap, type, len;
	uchar *p, *ep;
	int extraFlags;

	p = a;
	ep = p+nb;
	memset(caps, sizeof(*caps), 0);

	ncap = GSHORT(p);
	p += 4;
	for(; ncap>0 && p+4<ep; ncap--){
		type = GSHORT(p+0);
		len = GSHORT(p+2);
		if(p+len > ep){
			werrstr("bad length in server's capability set");
			return -1;
		}
		switch(type){
		case CapGeneral:
			/* 2.2.7.1.1 General Capability Set (TS_GENERAL_CAPABILITYSET) */
			if(len < 24){
				werrstr(Eshort);
				return -1;
			}
			caps->general = 1;
			extraFlags  = GSHORT(p+14);
			caps->canrefresh = p[22];
			caps->cansupress = p[23];
			USED(extraFlags);
			break;
		case CapBitmap:
			/* 2.2.7.1.2 Bitmap Capability Set (TS_BITMAP_CAPABILITYSET) */
			if(len < 16){
				werrstr(Eshort);
				return -1;
			}
			caps->bitmap = 1;
			caps->depth = GSHORT(p+4);
			caps->xsz = GSHORT(p+12);
			caps->ysz = GSHORT(p+14);
			break;
		}
		p += len;
	}
	return p-a;
}

int
sizecaps(Caps* caps)
{
	int i, n;

	USED(caps);
	n = 0;
	for(i = 0; i < nelem(ctab); i++)
		n += ctab[i].size;
	return n;
}

int
putcaps(uchar* a, uint nb, Caps* caps)
{
	uchar *p, *ep;
	int i, n;

	p = a;
	ep = a+nb;

	for(i = 0; i < nelem(ctab); i++){
		n = ctab[i].putcap(p, ep-p, caps);
		if(n < 0)
			return -1;
		p += n;
	}
	return p-a;
}

static int
putncap(uchar *p, uint nb, Caps* caps)
{
	int ncap;

	USED(caps);
	ncap = 8;
	
	if(nb<4){
		werrstr(Eshort);
		return -1;
	}
	PSHORT(p, ncap);
	PSHORT(p+2, 0);
	return 4;
}

/* 2.2.7.1.1 General Capability Set (TS_GENERAL_CAPABILITYSET) */
static int
putgencaps(uchar *p, uint nb, Caps* caps)
{
	int extraFlags;

	USED(caps);
	extraFlags = 0
		| CanFastpath
		| NoBitcomphdr
		| CanLongcred
		;
	if(nb<24){
		werrstr(Eshort);
		return -1;
	}
	PSHORT(p+0, CapGeneral);
	PSHORT(p+2, 24);	// size
	PSHORT(p+4, 0);	// OSMAJORTYPE_UNSPECIFIED
	PSHORT(p+6, 0);	// OSMINORTYPE_UNSPECIFIED
	PSHORT(p+8, 0x200);	// TS_CAPS_PROTOCOLVERSION
	PSHORT(p+12, 0);	// generalCompressionTypes
	PSHORT(p+14, extraFlags);
	PSHORT(p+16, 0);	// updateCapabilityFlag
	PSHORT(p+18, 0);	// remoteUnshareFlag 
	PSHORT(p+20, 0);	// generalCompressionLevel
	p[22] = 0;  	// refreshRectSupport - server only
	p[23] = 0;  	// suppressOutputSupport - server only
	return 24;
}


/* 2.2.7.1.2 Bitmap Capability Set (TS_BITMAP_CAPABILITYSET) */
static int
putbitcaps(uchar *p, uint nb, Caps* caps)
{
	if(nb < 30){
		werrstr(Eshort);
		return -1;
	}
	PSHORT(p+0, CapBitmap);
	PSHORT(p+2, 30);	// size
	PSHORT(p+4, caps->depth);	// preferredBitsPerPixel
	PSHORT(p+6, 1);	// receive1BitPerPixel
	PSHORT(p+8, 1);	// receive4BitsPerPixel
	PSHORT(p+10, 1);	// receive8BitsPerPixel
	PSHORT(p+12, caps->xsz);	// desktopWidth
	PSHORT(p+14, caps->ysz);	// desktopHeight
	PSHORT(p+16, 0);	// pad2octets 
	PSHORT(p+18, 1);	// desktopResizeFlag 
	PSHORT(p+20, 1);	// bitmapCompressionFlag 
	PSHORT(p+22, 0);	// highColorFlags 
	PSHORT(p+24, 1);	// drawingFlags 
	PSHORT(p+26, 1);	// multipleRectangleSupport
	PSHORT(p+26, 0);	// pad2octetsB
	return 30;
}

/* 2.2.7.1.3 Order Capability Set (TS_ORDER_CAPABILITYSET) */
static int
putordcaps(uchar *p, uint nb, Caps* caps)
{
	ushort orderFlags;
	enum
	{
		NEGOTIATEORDERSUPPORT=		0x02,
		ZEROBOUNDSDELTASSUPPORT=	0x08,
		COLORINDEXSUPPORT=			0x20,
		SOLIDPATTERNBRUSHONLY=		0x40,
	};

	USED(caps);
	orderFlags = 0
		| NEGOTIATEORDERSUPPORT
		| ZEROBOUNDSDELTASSUPPORT
		| COLORINDEXSUPPORT
		| SOLIDPATTERNBRUSHONLY
		;
	if(nb<88){
		werrstr(Eshort);
		return -1;
	}
	PSHORT(p+0, CapOrder);
	PSHORT(p+2, 88);	// size
	memset(p+4, 16, 0);	// terminalDescriptor
	PLONG(p+20, 0);	// pad4octetsA 
	PSHORT(p+24, 1);	// desktopSaveXGranularity 
	PSHORT(p+26, 20);	// desktopSaveYGranularity 
	PSHORT(p+28, 0);	// pad2octetsA
	PSHORT(p+30, 1);	// maximumOrderLevel 
	PSHORT(p+32, 0);	// numberFonts 
	PSHORT(p+34, orderFlags);
	memcpy(p+36, orderSupport, 32);
	PSHORT(p+68, 0x6a1);	// textFlags
	PSHORT(p+70, 0);	// orderSupportExFlags
	PLONG(p+72, 0);	// pad4octetsB
	PLONG(p+76, 480*480);	// desktopSaveSize
	PSHORT(p+80, 0);	// pad2octetsC
	PSHORT(p+82, 0);	// pad2octetsD
	PSHORT(p+84, 0xe4);	// textANSICodePage
	PSHORT(p+86, 0x04);	// pad2octetsE
	return 88;
}

/* 2.2.7.1.4 Bitmap Cache Capability Set (TS_BITMAPCACHE_CAPABILITYSET) */
/* 2.2.7.1.4.2 Revision 2 (TS_BITMAPCACHE_CAPABILITYSET_REV2) */
static int
putbc2caps(uchar *p, uint nb, Caps* caps)
{
	USED(caps);
	if(nb<40){
		werrstr(Eshort);
		return -1;
	}
	PSHORT(p+0, CapBitcache2);
	PSHORT(p+2, 40);	// size
	PSHORT(p+4, 0);	// CacheFlags (2 bytes):  
	p[6] = 0;	// pad2
	p[7] = 3;	// NumCellCaches
	PLONG(p+8, 120);	// BitmapCache0CellInfo
	PLONG(p+12, 120);	// BitmapCache1CellInfo
	PLONG(p+16, 336);	// BitmapCache2CellInfo
	PLONG(p+20, 0);	// BitmapCache3CellInfo
	PLONG(p+24, 0);	// BitmapCache4CellInfo
	memset(p+28, 12, 0); // Pad3
	return 40;
}

/* 2.2.7.1.5 Pointer Capability Set (TS_POINTER_CAPABILITYSET) */
static int
putptrcaps(uchar *p, uint nb, Caps* caps)
{
	USED(caps);
	if(nb<8){
		werrstr(Eshort);
		return -1;
	}
	PSHORT(p+0, CapPointer);
	PSHORT(p+2, 8);	// size
	PSHORT(p+4, 0);	// colorPointerFlag  
	PSHORT(p+6, 20);	// colorPointerCacheSize 
	return 8;
}

/* 2.2.7.1.6 Input Capability Set (TS_INPUT_CAPABILITYSET) */
static int
putinpcaps(uchar *p, uint nb, Caps* caps)
{
	long inputFlags;
	USED(caps);
	enum
	{
		INPUT_FLAG_SCANCODES=		0x0001,
		INPUT_FLAG_MOUSEX=			0x0004,
		INPUT_FLAG_FASTPATH_INPUT=	0x0008,
		INPUT_FLAG_UNICODE=			0x0010,
		INPUT_FLAG_FASTPATH_INPUT2=	0x0020,
	};

	inputFlags = 0
		| INPUT_FLAG_SCANCODES
		| INPUT_FLAG_UNICODE
		;
	if(nb<88){
		werrstr(Eshort);
		return -1;
	}
	PSHORT(p+0, CapInput);
	PSHORT(p+2, 88);	// size
	PSHORT(p+4, inputFlags);	// inputFlags
	PSHORT(p+6, 0);	// pad2octetsA

	// the below SHOULD be the same as in the Client Core Data (section 2.2.1.3.2).
	PLONG(p+8, 0x409);	// keyboardLayout
	PLONG(p+12, 4);	// keyboardType: IBM enhanced (101- or 102-key)
	PLONG(p+16, 0);	// keyboardSubType
	PLONG(p+20, 12);	// keyboardFunctionKey
	memset(p+24, 64, 0);	// imeFileName
	return 88;
}

/* 2.2.7.1.8 Glyph Cache Capability Set (TS_GLYPHCACHE_CAPABILITYSET) */
static int
putglycaps(uchar *p, uint nb, Caps* caps)
{
	enum {
		GLYPH_SUPPORT_NONE= 0,
	};
	USED(caps);

	if(nb<52){
		werrstr(Eshort);
		return -1;
	}
	PSHORT(p+0, CapGlyph);
	PSHORT(p+2, 52);	// size
	PLONG(p+4, 0x0400fe);	// GlyphCache 0
	PLONG(p+8, 0x0400fe);	// GlyphCache 1
	PLONG(p+12, 0x0800fe);	// GlyphCache 2
	PLONG(p+16, 0x0800fe);	// GlyphCache 3
	PLONG(p+20, 0x1000fe);	// GlyphCache 4
	PLONG(p+24, 0x2000fe);	// GlyphCache 5
	PLONG(p+28, 0x4000fe);	// GlyphCache 6
	PLONG(p+32, 0x8000fe);	// GlyphCache 7
	PLONG(p+36, 0x10000fe);	// GlyphCache 8
	PLONG(p+40, 0x8000040);	// GlyphCache 9
	PLONG(p+44, 0x01000100);	// FragCache 
	PSHORT(p+48, GLYPH_SUPPORT_NONE);	// GlyphSupportLevel
	PSHORT(p+50, 0);	// pad2octets 
	return 52;
}

/* 2.2.7.1.11 Sound Capability Set (TS_SOUND_CAPABILITYSET) */
static int
putsndcaps(uchar *p, uint nb, Caps* caps)
{
	USED(caps);
	if(nb<8){
		werrstr(Eshort);
		return -1;
	}
	PSHORT(p+0, CapSound);
	PSHORT(p+2, 8);	// size
	PSHORT(p+4, 0);	// soundFlags
	PSHORT(p+6, 0);	// pad2octetsA
	return 8;
}