Subversion Repositories planix.SVN

Rev

Details | Last modification | View Log | RSS feed

Rev Author Line No. Line
2 - 1
#include "vnc.h"
2
#include "vncv.h"
3
 
4
enum {
5
	RGB12 = CHAN4(CIgnore, 4, CRed, 4, CGreen, 4, CBlue, 4),
6
	BGR12 = CHAN4(CIgnore, 4, CBlue, 4, CGreen, 4, CRed, 4),
7
	BGR8 = CHAN3(CBlue, 2, CGreen, 3, CRed, 3),
8
};
9
 
10
void (*cvtpixels)(uchar*, uchar*, int);
11
 
12
static void
13
chan2fmt(Pixfmt *fmt, ulong chan)
14
{
15
	ulong c, rc, shift;
16
 
17
	shift = 0;
18
	for(rc = chan; rc; rc >>=8){
19
		c = rc & 0xFF;
20
		switch(TYPE(c)){
21
		case CRed:
22
			fmt->red = (Colorfmt){(1<<NBITS(c))-1, shift};
23
			break;
24
		case CBlue:
25
			fmt->blue = (Colorfmt){(1<<NBITS(c))-1, shift};
26
			break;
27
		case CGreen:
28
			fmt->green = (Colorfmt){(1<<NBITS(c))-1, shift};
29
			break;
30
		}
31
		shift += NBITS(c);
32
	}
33
}
34
 
35
/*
36
 * convert 32-bit data to 24-bit data by skipping
37
 * the last of every four bytes.  we skip the last
38
 * because we keep the server in little endian mode.
39
 */
40
static void
41
cvt32to24(uchar *dst, uchar *src, int npixel)
42
{
43
	int i;
44
 
45
	for(i=0; i<npixel; i++){
46
		*dst++ = *src++;
47
		*dst++ = *src++;
48
		*dst++ = *src++;
49
		src++;
50
	}
51
}
52
 
53
/*
54
 * convert RGB12 (x4r4g4b4) into CMAP8
55
 */
56
static uchar rgb12[16*16*16];
57
static void
58
mkrgbtab(void)
59
{
60
	int r, g, b;
61
 
62
	for(r=0; r<16; r++)
63
	for(g=0; g<16; g++)
64
	for(b=0; b<16; b++)
65
		rgb12[r*256+g*16+b] = rgb2cmap(r*0x11, g*0x11, b*0x11);
66
}
67
 
68
static void
69
cvtrgb12tocmap8(uchar *dst, uchar *src, int npixel)
70
{
71
	int i, s;
72
 
73
	for(i=0; i<npixel; i++){
74
		s = (src[0] | (src[1]<<8)) & 0xFFF;
75
		*dst++ = rgb12[s];
76
		src += 2;
77
	}
78
}
79
 
80
/*
81
 * convert BGR8 (b2g3r3, default VNC format) to CMAP8 
82
 * some bits are lost.
83
 */
84
static uchar bgr8[256];
85
static void
86
mkbgrtab(void)
87
{
88
	int i, r, g, b;
89
 
90
	for(i=0; i<256; i++){
91
		b = i>>6;
92
		b = (b<<6)|(b<<4)|(b<<2)|b;
93
		g = (i>>3) & 7;
94
		g = (g<<5)|(g<<2)|(g>>1);
95
		r = i & 7;
96
		r = (r<<5)|(r<<2)|(r>>1);
97
		bgr8[i] = rgb2cmap(r, g, b);
98
	}
99
}
100
 
101
static void
102
cvtbgr332tocmap8(uchar *dst, uchar *src, int npixel)
103
{
104
	uchar *ed;
105
 
106
	ed = dst+npixel;
107
	while(dst < ed)
108
		*dst++ = bgr8[*src++];
109
}
110
 
111
void
112
choosecolor(Vnc *v)
113
{
114
	int bpp, depth;
115
	ulong chan;
116
 
117
	bpp = screen->depth;
118
	if((bpp / 8) * 8 != bpp)
119
		sysfatal("screen not supported");
120
 
121
	depth = screen->depth;
122
	chan = screen->chan;
123
 
124
	if(bpp == 24){
125
		if(verbose)
126
			fprint(2, "24bit emulation using 32bpp\n");
127
		bpp = 32;
128
		cvtpixels = cvt32to24;
129
	}
130
 
131
	if(chan == CMAP8){
132
		if(bpp12){
133
			if(verbose)
134
				fprint(2, "8bit emulation using 12bpp\n");
135
			bpp = 16;
136
			depth = 12;
137
			chan = RGB12;
138
			cvtpixels = cvtrgb12tocmap8;
139
			mkrgbtab();
140
		}else{
141
			if(verbose)
142
				fprint(2, "8bit emulation using 6bpp\n");	/* 6: we throw away 1 r, g bit */
143
			bpp = 8;
144
			depth = 8;
145
			chan = BGR8;
146
			cvtpixels = cvtbgr332tocmap8;
147
			mkbgrtab();
148
		}
149
	}
150
 
151
	v->bpp = bpp;
152
	v->depth = depth;
153
	v->truecolor = 1;
154
	v->bigendian = 0;
155
	chan2fmt(v, chan);
156
	if(v->red.max == 0 || v->green.max == 0 || v->blue.max == 0)
157
		sysfatal("screen not supported");
158
 
159
	if(verbose)
160
		fprint(2, "%d bpp, %d depth, 0x%lx chan, %d truecolor, %d bigendian\n",
161
			v->bpp, v->depth, screen->chan, v->truecolor, v->bigendian);
162
 
163
	/* send information to server */
164
	vncwrchar(v, MPixFmt);
165
	vncwrchar(v, 0);	/* padding */
166
	vncwrshort(v, 0);
167
	vncwrpixfmt(v, &v->Pixfmt);
168
	vncflush(v);
169
}