added depth reduction and startup for true color visuals

16bpp should now work
This commit is contained in:
Derek Foreman 2003-03-19 23:26:54 +00:00
parent c1e6991224
commit de307661b6
4 changed files with 123 additions and 34 deletions

View file

@ -58,3 +58,48 @@ void color_free(color_rgb *c)
XFreeGC(ob_display, c->gc); XFreeGC(ob_display, c->gc);
free(c); free(c);
} }
void reduce_depth(pixel32 *data, XImage *im)
{
// since pixel32 is the largest possible pixel size, we can share the array
int r, g, b;
int x,y;
pixel16 *p = (pixel16*) data;
switch (im->bits_per_pixel) {
case 32:
if ((render_red_offset != default_red_shift) ||
(render_blue_offset != default_blue_shift) ||
(render_green_offset != default_green_shift)) {
for (y = 0; y < im->height; y++) {
for (x = 0; x < im->width; x++) {
r = (data[x] >> default_red_shift) & 0xFF;
g = (data[x] >> default_green_shift) & 0xFF;
b = (data[x] >> default_blue_shift) & 0xFF;
data[x] = (r << render_red_offset) + (g << render_green_offset) +
(b << render_blue_offset);
}
data += im->width;
}
}
break;
case 16:
for (y = 0; y < im->height; y++) {
for (x = 0; x < im->width; x++) {
r = (data[x] >> default_red_shift) & 0xFF;
r = r >> render_red_shift;
g = (data[x] >> default_green_shift) & 0xFF;
g = g >> render_green_shift;
b = (data[x] >> default_blue_shift) & 0xFF;
b = b >> render_blue_shift;
p[x] = (r << render_red_offset)
+ (g << render_green_offset)
+ (b << render_blue_offset);
}
data += im->width;
p += im->bytes_per_line/2;
}
break;
default:
g_message("your bit depth is currently unhandled\n");
}
}

View file

@ -2,6 +2,37 @@
#define __color_h #define __color_h
#include <X11/Xlib.h> #include <X11/Xlib.h>
#include <X11/Xutil.h>
#ifdef HAVE_STDINT_H
# include <stdint.h>
#else
# ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
# endif
#endif
#ifdef HAVE_STDINT_H
typedef uint32_t pixel32;
typedef uint16_t pixel16;
#else
typedef u_int32_t pixel32;
typedef u_int16_t pixel16;
#endif /* HAVE_STDINT_H */
#if (G_ENDIAN == G_BIG_ENDIAN)
#define default_red_shift 0
#define default_green_shift 8
#define default_blue_shift 16
#define endian MSBFirst
#else
#define default_red_shift 16
#define default_green_shift 8
#define default_blue_shift 0
#define endian LSBFirst
#endif /* G_ENDIAN == G_BIG_ENDIAN */
typedef struct color_rgb { typedef struct color_rgb {
int r; int r;
@ -15,5 +46,14 @@ void color_allocate_gc(color_rgb *in);
color_rgb *color_parse(char *colorname); color_rgb *color_parse(char *colorname);
color_rgb *color_new(int r, int g, int b); color_rgb *color_new(int r, int g, int b);
void color_free(color_rgb *in); void color_free(color_rgb *in);
void reduce_depth(pixel32 *data, XImage *im);
extern int render_red_offset;
extern int render_green_offset;
extern int render_blue_offset;
extern int render_red_shift;
extern int render_green_shift;
extern int render_blue_shift;
#endif /* __color_h */ #endif /* __color_h */

View file

@ -5,11 +5,14 @@
#include "gradient.h" #include "gradient.h"
#include "font.h" #include "font.h"
#include "mask.h" #include "mask.h"
#include "color.h"
#include "../kernel/openbox.h" #include "../kernel/openbox.h"
int render_depth; int render_depth;
Visual *render_visual; Visual *render_visual;
Colormap render_colormap; Colormap render_colormap;
int render_red_offset = 0, render_green_offset = 0, render_blue_offset = 0;
int render_red_shift, render_green_shift, render_blue_shift;
void render_startup(void) void render_startup(void)
{ {
@ -52,18 +55,46 @@ void render_startup(void)
} }
XFree(vinfo_return); XFree(vinfo_return);
} }
truecolor_startup();
}
void truecolor_startup(void)
{
unsigned long red_mask, green_mask, blue_mask;
XImage *timage = NULL;
timage = XCreateImage(ob_display, render_visual, render_depth,
ZPixmap, 0, NULL, 1, 1, 32, 0);
g_assert(timage != NULL);
// find the offsets for each color in the visual's masks
red_mask = timage->red_mask;
green_mask = timage->green_mask;
blue_mask = timage->blue_mask;
render_red_offset = 0;
render_green_offset = 0;
render_blue_offset = 0;
while (! (red_mask & 1)) { render_red_offset++; red_mask >>= 1; }
while (! (green_mask & 1)) { render_green_offset++; green_mask >>= 1; }
while (! (blue_mask & 1)) { render_blue_offset++; blue_mask >>= 1; }
render_red_shift = render_green_shift = render_blue_shift = 8;
while (red_mask) { red_mask >>= 1; render_red_shift--; }
while (green_mask) { green_mask >>= 1; render_green_shift--; }
while (blue_mask) { blue_mask >>= 1; render_blue_shift--; }
XFree(timage);
} }
void x_paint(Window win, Appearance *l, int x, int y, int w, int h) void x_paint(Window win, Appearance *l, int x, int y, int w, int h)
{ {
int i; int i;
XImage *im; XImage *im = NULL;
Pixmap oldp; Pixmap oldp;
if (w <= 0 || h <= 0) return; if (w <= 0 || h <= 0) return;
g_assert(l->surface.type == Surface_Planar); g_assert(l->surface.type == Surface_Planar);
// printf("painting window %ld\n", win);
oldp = l->pixmap; /* save to free after changing the visible pixmap */ oldp = l->pixmap; /* save to free after changing the visible pixmap */
l->pixmap = XCreatePixmap(ob_display, ob_root, x+w, y+h, render_depth); l->pixmap = XCreatePixmap(ob_display, ob_root, x+w, y+h, render_depth);
@ -83,16 +114,16 @@ void x_paint(Window win, Appearance *l, int x, int y, int w, int h)
gradient_solid(l, x, y, w, h); gradient_solid(l, x, y, w, h);
else gradient_render(&l->surface, w, h); else gradient_render(&l->surface, w, h);
/*reduce depth here... /*this is not the right place for this code, it's only here so
also, this is not the right place for this code, it's only here so
text rendering shows up for now. text rendering shows up for now.
*/ */
if (l->surface.data.planar.grad != Background_Solid) { if (l->surface.data.planar.grad != Background_Solid) {
im = XCreateImage(ob_display, render_visual, render_depth, im = XCreateImage(ob_display, render_visual, render_depth,
ZPixmap, 0, NULL, w, h, 32, 0); ZPixmap, 0, NULL, w, h, 32, 0);
g_assert(im != None); g_assert(im != NULL);
im->byte_order = endian; im->byte_order = endian;
im->data = l->surface.data.planar.pixel_data; im->data = (unsigned char *)l->surface.data.planar.pixel_data;
reduce_depth(im->data, im);
XPutImage(ob_display, l->pixmap, DefaultGC(ob_display, ob_screen), XPutImage(ob_display, l->pixmap, DefaultGC(ob_display, ob_screen),
im, 0, 0, x, y, w, h); im, 0, 0, x, y, w, h);
im->data = NULL; im->data = NULL;

View file

@ -7,34 +7,6 @@
#include <glib.h> #include <glib.h>
#include "color.h" #include "color.h"
#ifdef HAVE_STDINT_H
# include <stdint.h>
#else
# ifdef HAVE_SYS_TYPES_H
# include <sys/types.h>
# endif
#endif
#ifdef HAVE_STDINT_H
typedef uint32_t pixel32;
typedef uint16_t pixel16;
#else
typedef u_int32_t pixel32;
typedef u_int16_t pixel16;
#endif /* HAVE_STDINT_H */
#if (G_ENDIAN == G_BIG_ENDIAN)
#define default_red_shift 0
#define default_green_shift 8
#define default_blue_shift 16
#define endian MSBFirst
#else
#define default_red_shift 16
#define default_green_shift 8
#define default_blue_shift 0
#define endian LSBFirst
#endif /* G_ENDIAN == G_BIG_ENDIAN */
typedef enum { typedef enum {
Surface_Planar, Surface_Planar,
Surface_Nonplanar Surface_Nonplanar
@ -164,4 +136,5 @@ void render_shutdown(void);
Appearance *appearance_new(SurfaceType type, int numtex); Appearance *appearance_new(SurfaceType type, int numtex);
Appearance *appearance_copy(Appearance *a); Appearance *appearance_copy(Appearance *a);
void appearance_free(Appearance *a); void appearance_free(Appearance *a);
void truecolor_startup(void);
#endif /*__render_h*/ #endif /*__render_h*/