- Determine pixel layout at runtime instead of relying on compile-time flags
- Fix some potential null dereference bugs
This commit is contained in:
parent
1dfe4ebc19
commit
4de6d284a3
|
@ -2,7 +2,7 @@
|
|||
BIN = zahnrad
|
||||
|
||||
# Flags
|
||||
CFLAGS += -std=c89 -pedantic -O2 -Wunused -DRAWFB_XRGB_8888
|
||||
CFLAGS += -std=c89 -pedantic -O2 -Wunused
|
||||
|
||||
SRC = main.c
|
||||
OBJ = $(SRC:.c=.o)
|
||||
|
|
|
@ -35,7 +35,6 @@
|
|||
#include <unistd.h>
|
||||
#include <time.h>
|
||||
|
||||
#define RAWFB_XRGB_8888
|
||||
#define NK_INCLUDE_FIXED_TYPES
|
||||
#define NK_INCLUDE_STANDARD_IO
|
||||
#define NK_INCLUDE_STANDARD_VARARGS
|
||||
|
@ -152,6 +151,7 @@ main(void)
|
|||
XWindow xw;
|
||||
struct rawfb_context *rawfb;
|
||||
void *fb = NULL;
|
||||
rawfb_pl pl;
|
||||
unsigned char tex_scratch[512 * 512];
|
||||
|
||||
/* X11 */
|
||||
|
@ -180,12 +180,12 @@ main(void)
|
|||
xw.height = (unsigned int)xw.attr.height;
|
||||
|
||||
/* Framebuffer emulator */
|
||||
status = nk_xlib_init(xw.dpy, xw.vis, xw.screen, xw.win, xw.width, xw.height, &fb);
|
||||
status = nk_xlib_init(xw.dpy, xw.vis, xw.screen, xw.win, xw.width, xw.height, &fb, &pl);
|
||||
if (!status || !fb)
|
||||
return 0;
|
||||
|
||||
/* GUI */
|
||||
rawfb = nk_rawfb_init(fb, tex_scratch, xw.width, xw.height, xw.width * 4);
|
||||
rawfb = nk_rawfb_init(fb, tex_scratch, xw.width, xw.height, xw.width * 4, pl);
|
||||
if (!rawfb) running = 0;
|
||||
|
||||
#ifdef INCLUDE_STYLE
|
||||
|
|
|
@ -33,11 +33,18 @@
|
|||
|
||||
struct rawfb_context;
|
||||
|
||||
typedef enum rawfb_pixel_layout {
|
||||
PIXEL_LAYOUT_XRGB_8888,
|
||||
PIXEL_LAYOUT_RGBX_8888,
|
||||
}
|
||||
rawfb_pl;
|
||||
|
||||
|
||||
/* All functions are thread-safe */
|
||||
NK_API struct rawfb_context *nk_rawfb_init(void *fb, void *tex_mem, const unsigned int w, const unsigned int h, const unsigned int pitch);
|
||||
NK_API struct rawfb_context *nk_rawfb_init(void *fb, void *tex_mem, const unsigned int w, const unsigned int h, const unsigned int pitch, const rawfb_pl pl);
|
||||
NK_API void nk_rawfb_render(const struct rawfb_context *rawfb, const struct nk_color clear, const unsigned char enable_clear);
|
||||
NK_API void nk_rawfb_shutdown(struct rawfb_context *rawfb);
|
||||
NK_API void nk_rawfb_resize_fb(struct rawfb_context *rawfb, void *fb, const unsigned int w, const unsigned int h, const unsigned int pitch);
|
||||
NK_API void nk_rawfb_resize_fb(struct rawfb_context *rawfb, void *fb, const unsigned int w, const unsigned int h, const unsigned int pitch, const rawfb_pl pl);
|
||||
|
||||
#endif
|
||||
/*
|
||||
|
@ -48,10 +55,10 @@ NK_API void nk_rawfb_resize_fb(struct rawfb_context *rawfb, voi
|
|||
* ===============================================================
|
||||
*/
|
||||
#ifdef NK_RAWFB_IMPLEMENTATION
|
||||
|
||||
struct rawfb_image {
|
||||
void *pixels;
|
||||
int w, h, pitch;
|
||||
rawfb_pl pl;
|
||||
enum nk_font_atlas_format format;
|
||||
};
|
||||
struct rawfb_context {
|
||||
|
@ -70,42 +77,54 @@ struct rawfb_context {
|
|||
#endif
|
||||
|
||||
static unsigned int
|
||||
nk_rawfb_color2int(const struct nk_color c)
|
||||
nk_rawfb_color2int(const struct nk_color c, rawfb_pl pl)
|
||||
{
|
||||
unsigned int res = 0;
|
||||
#if defined(RAWFB_RGBX_8888) && !defined(RAWFB_XRGB_8888)
|
||||
res |= c.r << 24;
|
||||
res |= c.g << 16;
|
||||
res |= c.b << 8;
|
||||
res |= c.a;
|
||||
#elif defined(RAWFB_XRGB_8888) && !defined(RAWFB_RGBX_8888)
|
||||
res |= c.a << 24;
|
||||
res |= c.r << 16;
|
||||
res |= c.g << 8;
|
||||
res |= c.b << 0;
|
||||
#else
|
||||
#error Define one of RAWFB_RGBX_8888 , RAWFB_XRGB_8888
|
||||
#endif
|
||||
|
||||
switch (pl) {
|
||||
case PIXEL_LAYOUT_RGBX_8888:
|
||||
res |= c.r << 24;
|
||||
res |= c.g << 16;
|
||||
res |= c.b << 8;
|
||||
res |= c.a;
|
||||
break;
|
||||
case PIXEL_LAYOUT_XRGB_8888:
|
||||
res |= c.a << 24;
|
||||
res |= c.r << 16;
|
||||
res |= c.g << 8;
|
||||
res |= c.b << 0;
|
||||
break;
|
||||
|
||||
default:
|
||||
perror("Unsupported pixel layout.\n");
|
||||
break;
|
||||
}
|
||||
return (res);
|
||||
}
|
||||
|
||||
static struct nk_color
|
||||
nk_rawfb_int2color(const unsigned int i)
|
||||
nk_rawfb_int2color(const unsigned int i, rawfb_pl pl)
|
||||
{
|
||||
struct nk_color col;
|
||||
#if defined(RAWFB_RGBX_8888) && !defined(RAWFB_XRGB_8888)
|
||||
col.r = (i >> 24) & 0xff;
|
||||
col.g = (i >> 16) & 0xff;
|
||||
col.b = (i >> 8) & 0xff;
|
||||
col.a = (i >> 0) & 0xff;
|
||||
#elif defined(RAWFB_XRGB_8888) && !defined(RAWFB_RGBX_8888)
|
||||
col.a = (i >> 24) & 0xff;
|
||||
col.r = (i >> 16) & 0xff;
|
||||
col.g = (i >> 8) & 0xff;
|
||||
col.b = (i >> 0) & 0xff;
|
||||
#else
|
||||
#error Define one of RAWFB_RGBX_8888 , RAWFB_XRGB_8888
|
||||
#endif
|
||||
struct nk_color col = {0,0,0,0};
|
||||
|
||||
switch (pl) {
|
||||
case PIXEL_LAYOUT_RGBX_8888:
|
||||
col.r = (i >> 24) & 0xff;
|
||||
col.g = (i >> 16) & 0xff;
|
||||
col.b = (i >> 8) & 0xff;
|
||||
col.a = (i >> 0) & 0xff;
|
||||
break;
|
||||
case PIXEL_LAYOUT_XRGB_8888:
|
||||
col.a = (i >> 24) & 0xff;
|
||||
col.r = (i >> 16) & 0xff;
|
||||
col.g = (i >> 8) & 0xff;
|
||||
col.b = (i >> 0) & 0xff;
|
||||
break;
|
||||
|
||||
default:
|
||||
perror("Unsupported pixel layout.\n");
|
||||
break;
|
||||
}
|
||||
return col;
|
||||
}
|
||||
|
||||
|
@ -113,7 +132,7 @@ static void
|
|||
nk_rawfb_ctx_setpixel(const struct rawfb_context *rawfb,
|
||||
const short x0, const short y0, const struct nk_color col)
|
||||
{
|
||||
unsigned int c = nk_rawfb_color2int(col);
|
||||
unsigned int c = nk_rawfb_color2int(col, rawfb->fb.pl);
|
||||
unsigned char *pixels = rawfb->fb.pixels;
|
||||
unsigned int *ptr;
|
||||
|
||||
|
@ -144,7 +163,7 @@ nk_rawfb_line_horizontal(const struct rawfb_context *rawfb,
|
|||
|
||||
n = x1 - x0;
|
||||
for (i = 0; i < sizeof(c) / sizeof(c[0]); i++)
|
||||
c[i] = nk_rawfb_color2int(col);
|
||||
c[i] = nk_rawfb_color2int(col, rawfb->fb.pl);
|
||||
|
||||
while (n > 16) {
|
||||
memcpy((void *)ptr, c, sizeof(c));
|
||||
|
@ -157,7 +176,7 @@ static void
|
|||
nk_rawfb_img_setpixel(const struct rawfb_image *img,
|
||||
const int x0, const int y0, const struct nk_color col)
|
||||
{
|
||||
unsigned int c = nk_rawfb_color2int(col);
|
||||
unsigned int c = nk_rawfb_color2int(col, img->pl);
|
||||
unsigned char *ptr;
|
||||
unsigned int *pixel;
|
||||
NK_ASSERT(img);
|
||||
|
@ -191,7 +210,7 @@ nk_rawfb_img_getpixel(const struct rawfb_image *img, const int x0, const int y0)
|
|||
} else {
|
||||
pixel = ptr;
|
||||
pixel += x0;
|
||||
col = nk_rawfb_int2color(*pixel);
|
||||
col = nk_rawfb_int2color(*pixel, img->pl);
|
||||
}
|
||||
} return col;
|
||||
}
|
||||
|
@ -799,7 +818,7 @@ nk_rawfb_clear(const struct rawfb_context *rawfb, const struct nk_color col)
|
|||
|
||||
NK_API struct rawfb_context*
|
||||
nk_rawfb_init(void *fb, void *tex_mem, const unsigned int w, const unsigned int h,
|
||||
const unsigned int pitch)
|
||||
const unsigned int pitch, const rawfb_pl pl)
|
||||
{
|
||||
const void *tex;
|
||||
struct rawfb_context *rawfb;
|
||||
|
@ -815,19 +834,30 @@ nk_rawfb_init(void *fb, void *tex_mem, const unsigned int w, const unsigned int
|
|||
rawfb->fb.pixels = fb;
|
||||
rawfb->fb.w= w;
|
||||
rawfb->fb.h = h;
|
||||
rawfb->fb.pl = pl;
|
||||
|
||||
#if defined(RAWFB_XRGB_8888) || defined(RAWFB_RGBX_8888)
|
||||
if (pl == PIXEL_LAYOUT_RGBX_8888 || pl == PIXEL_LAYOUT_XRGB_8888) {
|
||||
rawfb->fb.format = NK_FONT_ATLAS_RGBA32;
|
||||
rawfb->fb.pitch = pitch;
|
||||
#else
|
||||
#error Fixme
|
||||
#endif
|
||||
}
|
||||
else {
|
||||
perror("Unsupported pixel layout.\n");
|
||||
free(rawfb);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
if (0 == nk_init_default(&rawfb->ctx, 0)) {
|
||||
free(rawfb);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
nk_init_default(&rawfb->ctx, 0);
|
||||
nk_font_atlas_init_default(&rawfb->atlas);
|
||||
nk_font_atlas_begin(&rawfb->atlas);
|
||||
tex = nk_font_atlas_bake(&rawfb->atlas, &rawfb->font_tex.w, &rawfb->font_tex.h, rawfb->font_tex.format);
|
||||
if (!tex) return 0;
|
||||
if (!tex) {
|
||||
free(rawfb);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
switch(rawfb->font_tex.format) {
|
||||
case NK_FONT_ATLAS_ALPHA8:
|
||||
|
@ -988,9 +1018,11 @@ nk_rawfb_drawimage(const struct rawfb_context *rawfb,
|
|||
NK_API void
|
||||
nk_rawfb_shutdown(struct rawfb_context *rawfb)
|
||||
{
|
||||
nk_free(&rawfb->ctx);
|
||||
nk_memset(rawfb, 0, sizeof(struct rawfb_context));
|
||||
free(rawfb);
|
||||
if (rawfb) {
|
||||
nk_free(&rawfb->ctx);
|
||||
nk_memset(rawfb, 0, sizeof(struct rawfb_context));
|
||||
free(rawfb);
|
||||
}
|
||||
}
|
||||
|
||||
NK_API void
|
||||
|
@ -998,12 +1030,14 @@ nk_rawfb_resize_fb(struct rawfb_context *rawfb,
|
|||
void *fb,
|
||||
const unsigned int w,
|
||||
const unsigned int h,
|
||||
const unsigned int pitch)
|
||||
const unsigned int pitch,
|
||||
const rawfb_pl pl)
|
||||
{
|
||||
rawfb->fb.w = w;
|
||||
rawfb->fb.h = h;
|
||||
rawfb->fb.pixels = fb;
|
||||
rawfb->fb.pitch = pitch;
|
||||
rawfb->fb.pl = pl;
|
||||
}
|
||||
|
||||
NK_API void
|
||||
|
|
|
@ -35,7 +35,7 @@
|
|||
|
||||
#include <X11/Xlib.h>
|
||||
|
||||
NK_API int nk_xlib_init(Display *dpy, Visual *vis, int screen, Window root, unsigned int w, unsigned int h, void **fb);
|
||||
NK_API int nk_xlib_init(Display *dpy, Visual *vis, int screen, Window root, unsigned int w, unsigned int h, void **fb, rawfb_pl *pl);
|
||||
NK_API int nk_xlib_handle_event(Display *dpy, int screen, Window win, XEvent *evt, struct rawfb_context *rawfb);
|
||||
NK_API void nk_xlib_render(Drawable screen);
|
||||
NK_API void nk_xlib_shutdown(void);
|
||||
|
@ -71,7 +71,7 @@ static struct {
|
|||
|
||||
NK_API int
|
||||
nk_xlib_init(Display *dpy, Visual *vis, int screen, Window root,
|
||||
unsigned int w, unsigned int h, void **fb)
|
||||
unsigned int w, unsigned int h, void **fb, rawfb_pl *pl)
|
||||
{
|
||||
unsigned int depth = XDefaultDepth(dpy, screen);
|
||||
xlib.dpy = dpy;
|
||||
|
@ -134,6 +134,24 @@ nk_xlib_init(Display *dpy, Visual *vis, int screen, Window root,
|
|||
}
|
||||
xlib.gc = XDefaultGC(dpy, screen);
|
||||
*fb = xlib.ximg->data;
|
||||
|
||||
if (xlib.ximg->red_mask == 0xff0000 &&
|
||||
xlib.ximg->green_mask == 0xff00 &&
|
||||
xlib.ximg->blue_mask == 0xff &&
|
||||
xlib.ximg->bits_per_pixel == 32) {
|
||||
*pl = PIXEL_LAYOUT_XRGB_8888;
|
||||
}
|
||||
else if (xlib.ximg->red_mask == 0xff000000 &&
|
||||
xlib.ximg->green_mask == 0xff0000 &&
|
||||
xlib.ximg->blue_mask == 0xff00 &&
|
||||
xlib.ximg->bits_per_pixel == 32) {
|
||||
*pl = PIXEL_LAYOUT_RGBX_8888;
|
||||
}
|
||||
else {
|
||||
printf("Unrecognized pixel layout.\n");
|
||||
return 0;
|
||||
}
|
||||
|
||||
return 1;
|
||||
}
|
||||
|
||||
|
@ -238,13 +256,14 @@ nk_xlib_handle_event(Display *dpy, int screen, Window win, XEvent *evt, struct r
|
|||
unsigned int width, height;
|
||||
XWindowAttributes attr;
|
||||
XGetWindowAttributes(dpy, win, &attr);
|
||||
rawfb_pl pl;
|
||||
|
||||
width = (unsigned int)attr.width;
|
||||
height = (unsigned int)attr.height;
|
||||
|
||||
nk_xlib_shutdown();
|
||||
nk_xlib_init(dpy, XDefaultVisual(dpy, screen), screen, win, width, height, &fb);
|
||||
nk_rawfb_resize_fb(rawfb, fb, width, height, width * 4);
|
||||
nk_xlib_init(dpy, XDefaultVisual(dpy, screen), screen, win, width, height, &fb, &pl);
|
||||
nk_rawfb_resize_fb(rawfb, fb, width, height, width * 4, pl);
|
||||
} else if (evt->type == KeymapNotify) {
|
||||
XRefreshKeyboardMapping(&evt->xmapping);
|
||||
return 1;
|
||||
|
|
Loading…
Reference in New Issue