]>
Dogcows Code - chaz/openbox/blob - pseudorendercontrol.cc
89e95ab6eec20b327ba4841b66f39eb59d576da4
1 // -*- mode: C++; indent-tabs-mode: nil; c-basic-offset: 2; -*-
5 #include "pseudorendercontrol.hh"
7 #include "screeninfo.hh"
9 #include "rendertexture.hh"
14 #endif // HAVE_STDLIB_H
16 #include "../src/gettext.h"
17 #define _(str) gettext(str)
22 PseudoRenderControl::PseudoRenderControl(int screen
)
23 : RenderControl(screen
)
25 printf("Initializing PseudoColor RenderControl\n");
26 const ScreenInfo
*info
= display
->screenInfo(_screen
);
27 int depth
= info
->depth();
29 // determine the number of colors and the bits-per-color
30 _bpc
= 2; // XXX THIS SHOULD BE A USER OPTION
32 _ncolors
= 1 << (_bpc
* 3);
34 if (_ncolors
> 1 << depth
) {
36 _("PseudoRenderControl: Invalid colormap size. Resizing.\n"));
37 _bpc
= 1 << (depth
/3) >> 3;
38 _ncolors
= 1 << (_bpc
* 3);
42 _colors
= new XColor
[_ncolors
];
44 int cpc
= 1 << _bpc
; // colors per channel
47 for (int g
= 0; g
< cpc
; g
++)
48 for (int b
= 0; b
< cpc
; b
++, n
++) {
49 tr
= (int)(((float)(r
)/(float)(cpc
-1)) * 0xFF);
50 tg
= (int)(((float)(g
)/(float)(cpc
-1)) * 0xFF);
51 tb
= (int)(((float)(b
)/(float)(cpc
-1)) * 0xFF);
52 _colors
[n
].red
= tr
| tr
<< 8;
53 _colors
[n
].green
= tg
| tg
<< 8;
54 _colors
[n
].blue
= tb
| tb
<< 8;
55 _colors
[n
].flags
= DoRed
|DoGreen
|DoBlue
; // used to track allocation
58 // allocate the colors
59 for (int i
= 0; i
< _ncolors
; i
++)
60 if (!XAllocColor(**display
, info
->colormap(), &_colors
[i
]))
61 _colors
[i
].flags
= 0; // mark it as unallocated
63 // try allocate any colors that failed allocation above
65 // get the allocated values from the X server (only the first 256 XXX why!?)
67 int incolors
= (((1 << depth
) > 256) ? 256 : (1 << depth
));
68 for (int i
= 0; i
< incolors
; i
++)
70 XQueryColors(**display
, info
->colormap(), icolors
, incolors
);
72 // try match unallocated ones
73 for (int i
= 0; i
< _ncolors
; i
++) {
74 if (!_colors
[i
].flags
) { // if it wasn't allocated...
75 unsigned long closest
= 0xffffffff, close
= 0;
76 for (int ii
= 0; ii
< incolors
; ii
++) {
78 int r
= (_colors
[i
].red
- icolors
[ii
].red
) & 0xff;
79 int g
= (_colors
[i
].green
- icolors
[ii
].green
) & 0xff;
80 int b
= (_colors
[i
].blue
- icolors
[ii
].blue
) & 0xff;
81 // find a weighted absolute deviation
82 unsigned long dev
= (r
* r
) + (g
* g
) + (b
* b
);
90 _colors
[i
].red
= icolors
[close
].red
;
91 _colors
[i
].green
= icolors
[close
].green
;
92 _colors
[i
].blue
= icolors
[close
].blue
;
93 _colors
[i
].pixel
= icolors
[close
].pixel
;
95 // try alloc this closest color, it had better succeed!
96 if (XAllocColor(**display
, info
->colormap(), &_colors
[i
])) {
97 _colors
[i
].flags
= DoRed
|DoGreen
|DoBlue
; // mark as alloced
100 assert(false); // wtf has gone wrong, its already alloced for chissake!
105 PseudoRenderControl::~PseudoRenderControl()
107 printf("Destroying PseudoColor RenderControl\n");
109 unsigned long *pixels
= new unsigned long [_ncolors
], *p
= pixels
;
110 for (int i
= 0; i
< _ncolors
; ++i
, ++p
)
111 *p
= _colors
[i
].pixel
;
112 XFreeColors(**display
, display
->screenInfo(_screen
)->colormap(), pixels
,
117 void PseudoRenderControl::reduceDepth(Surface
&sf
, XImage
*im
) const
119 pixel32
*data
= sf
.pixelData();
120 char *p
= (char *)data
;
122 for (y
= 0; y
< im
->height
; y
++) {
123 for (x
= 0; x
< im
->width
; x
++) {
124 r
= (data
[x
] >> default_red_shift
) & 0xFF;
126 g
= (data
[x
] >> default_green_shift
) & 0xFF;
128 b
= (data
[x
] >> default_blue_shift
) & 0xFF;
130 p
[x
] = _colors
[(r
<< (2*_bpc
)) + (g
<< (1*_bpc
)) + b
].pixel
;
133 p
+= im
->bytes_per_line
;
This page took 0.037112 seconds and 3 git commands to generate.