]>
Dogcows Code - chaz/openbox/blob - otk/pseudorendercontrol.cc
1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
5 #include "pseudorendercontrol.hh"
7 #include "screeninfo.hh"
9 #include "rendertexture.hh"
12 #include "../src/gettext.h"
13 #define _(str) gettext(str)
20 PseudoRenderControl::PseudoRenderControl(int screen
)
21 : RenderControl(screen
)
23 printf("Initializing PseudoColor RenderControl\n");
24 const ScreenInfo
*info
= display
->screenInfo(_screen
);
25 int depth
= info
->depth();
27 // determine the number of colors and the bits-per-color
28 _bpc
= 2; // XXX THIS SHOULD BE A USER OPTION
30 _ncolors
= 1 << (_bpc
* 3);
32 if (_ncolors
> 1 << depth
) {
34 _("PseudoRenderControl: Invalid colormap size. Resizing.\n"));
35 _bpc
= 1 << (depth
/3) >> 3;
36 _ncolors
= 1 << (_bpc
* 3);
40 _colors
= new XColor
[_ncolors
];
42 int cpc
= 1 << _bpc
; // colors per channel
45 for (int g
= 0; g
< cpc
; g
++)
46 for (int b
= 0; b
< cpc
; b
++, n
++) {
47 tr
= (int)(((float)(r
)/(float)(cpc
-1)) * 0xFF);
48 tg
= (int)(((float)(g
)/(float)(cpc
-1)) * 0xFF);
49 tb
= (int)(((float)(b
)/(float)(cpc
-1)) * 0xFF);
50 _colors
[n
].red
= tr
| tr
<< 8;
51 _colors
[n
].green
= tg
| tg
<< 8;
52 _colors
[n
].blue
= tb
| tb
<< 8;
53 _colors
[n
].flags
= DoRed
|DoGreen
|DoBlue
; // used to track allocation
56 // allocate the colors
57 for (int i
= 0; i
< _ncolors
; i
++)
58 if (!XAllocColor(**display
, info
->colormap(), &_colors
[i
]))
59 _colors
[i
].flags
= 0; // mark it as unallocated
61 // try allocate any colors that failed allocation above
63 // get the allocated values from the X server (only the first 256 XXX why!?)
65 int incolors
= (((1 << depth
) > 256) ? 256 : (1 << depth
));
66 for (int i
= 0; i
< incolors
; i
++)
68 XQueryColors(**display
, info
->colormap(), icolors
, incolors
);
70 // try match unallocated ones
71 for (int i
= 0; i
< _ncolors
; i
++) {
72 if (!_colors
[i
].flags
) { // if it wasn't allocated...
73 unsigned long closest
= 0xffffffff, close
= 0;
74 for (int ii
= 0; ii
< incolors
; ii
++) {
76 int r
= (_colors
[i
].red
- icolors
[ii
].red
) & 0xff;
77 int g
= (_colors
[i
].green
- icolors
[ii
].green
) & 0xff;
78 int b
= (_colors
[i
].blue
- icolors
[ii
].blue
) & 0xff;
79 // find a weighted absolute deviation
80 unsigned long dev
= (r
* r
) + (g
* g
) + (b
* b
);
88 _colors
[i
].red
= icolors
[close
].red
;
89 _colors
[i
].green
= icolors
[close
].green
;
90 _colors
[i
].blue
= icolors
[close
].blue
;
91 _colors
[i
].pixel
= icolors
[close
].pixel
;
93 // try alloc this closest color, it had better succeed!
94 if (XAllocColor(**display
, info
->colormap(), &_colors
[i
]))
95 _colors
[i
].flags
= DoRed
|DoGreen
|DoBlue
; // mark as alloced
97 assert(false); // wtf has gone wrong, its already alloced for chissake!
102 PseudoRenderControl::~PseudoRenderControl()
104 printf("Destroying PseudoColor RenderControl\n");
106 unsigned long *pixels
= new unsigned long [_ncolors
], *p
= pixels
;
107 for (int i
= 0; i
< _ncolors
; ++i
, ++p
)
108 *p
= _colors
[i
].pixel
;
109 XFreeColors(**display
, display
->screenInfo(_screen
)->colormap(), pixels
,
114 inline const XColor
*PseudoRenderControl::pickColor(int r
, int g
, int b
) const
116 r
= (r
& 0xff) >> (8-_bpc
);
117 g
= (g
& 0xff) >> (8-_bpc
);
118 b
= (b
& 0xff) >> (8-_bpc
);
119 return &_colors
[(r
<< (2*_bpc
)) + (g
<< (1*_bpc
)) + b
];
122 void PseudoRenderControl::reduceDepth(Surface
&sf
, XImage
*im
) const
124 pixel32
*data
= sf
.pixelData();
125 pixel32
*ret
= (pixel32
*)malloc(im
->width
* im
->height
* 4);
126 char *p
= (char *)ret
;
128 for (y
= 0; y
< im
->height
; y
++) {
129 for (x
= 0; x
< im
->width
; x
++) {
130 p
[x
] = pickColor(data
[x
] >> default_red_shift
,
131 data
[x
] >> default_green_shift
,
132 data
[x
] >> default_blue_shift
)->pixel
;
135 p
+= im
->bytes_per_line
;
137 im
->data
= (char*)ret
;
140 void PseudoRenderControl::allocateColor(XColor
*color
) const
142 const XColor
*c
= pickColor(color
->red
, color
->blue
, color
->green
);
145 color
->green
= c
->green
;
146 color
->blue
= c
->blue
;
147 color
->pixel
= c
->pixel
;
149 if (XAllocColor(**display
, display
->screenInfo(_screen
)->colormap(), color
))
150 color
->flags
= DoRed
|DoGreen
|DoBlue
; // mark as alloced
152 assert(false); // wtf has gone wrong, its already alloced for chissake!
This page took 0.041454 seconds and 4 git commands to generate.