#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;
}
|