]> git.lizzy.rs Git - plan9front.git/blob - sys/src/cmd/vnc/color.c
vnc: don't prompt for password on auth_respond() failure
[plan9front.git] / sys / src / cmd / vnc / color.c
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 }