From de307661b6ce96e61e20a123b00297dbc57d5d85 Mon Sep 17 00:00:00 2001 From: Derek Foreman Date: Wed, 19 Mar 2003 23:26:54 +0000 Subject: [PATCH] added depth reduction and startup for true color visuals 16bpp should now work --- render/color.c | 45 +++++++++++++++++++++++++++++++++++++++++++++ render/color.h | 40 ++++++++++++++++++++++++++++++++++++++++ render/render.c | 43 +++++++++++++++++++++++++++++++++++++------ render/render.h | 29 +---------------------------- 4 files changed, 123 insertions(+), 34 deletions(-) diff --git a/render/color.c b/render/color.c index 0cf7b226..10ad5e3b 100644 --- a/render/color.c +++ b/render/color.c @@ -58,3 +58,48 @@ void color_free(color_rgb *c) XFreeGC(ob_display, c->gc); 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"); + } +} diff --git a/render/color.h b/render/color.h index 1e0cc57a..202817d3 100644 --- a/render/color.h +++ b/render/color.h @@ -2,6 +2,37 @@ #define __color_h #include +#include + +#ifdef HAVE_STDINT_H +# include +#else +# ifdef HAVE_SYS_TYPES_H +# include +# 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 { int r; @@ -15,5 +46,14 @@ void color_allocate_gc(color_rgb *in); color_rgb *color_parse(char *colorname); color_rgb *color_new(int r, int g, int b); 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 */ diff --git a/render/render.c b/render/render.c index 13257910..df0ed282 100644 --- a/render/render.c +++ b/render/render.c @@ -5,11 +5,14 @@ #include "gradient.h" #include "font.h" #include "mask.h" +#include "color.h" #include "../kernel/openbox.h" int render_depth; Visual *render_visual; 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) { @@ -52,18 +55,46 @@ void render_startup(void) } 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) { int i; - XImage *im; + XImage *im = NULL; Pixmap oldp; if (w <= 0 || h <= 0) return; g_assert(l->surface.type == Surface_Planar); -// printf("painting window %ld\n", win); oldp = l->pixmap; /* save to free after changing the visible pixmap */ 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); else gradient_render(&l->surface, w, h); -/*reduce depth here... - also, this is not the right place for this code, it's only here so +/*this is not the right place for this code, it's only here so text rendering shows up for now. */ if (l->surface.data.planar.grad != Background_Solid) { im = XCreateImage(ob_display, render_visual, render_depth, ZPixmap, 0, NULL, w, h, 32, 0); - g_assert(im != None); + g_assert(im != NULL); 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), im, 0, 0, x, y, w, h); im->data = NULL; diff --git a/render/render.h b/render/render.h index dfbf4f12..8363dd90 100644 --- a/render/render.h +++ b/render/render.h @@ -7,34 +7,6 @@ #include #include "color.h" -#ifdef HAVE_STDINT_H -# include -#else -# ifdef HAVE_SYS_TYPES_H -# include -# 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 { Surface_Planar, Surface_Nonplanar @@ -164,4 +136,5 @@ void render_shutdown(void); Appearance *appearance_new(SurfaceType type, int numtex); Appearance *appearance_copy(Appearance *a); void appearance_free(Appearance *a); +void truecolor_startup(void); #endif /*__render_h*/ -- 2.39.2