浏览代码

- Determine pixel layout at runtime instead of relying on compile-time flags
- Fix some potential null dereference bugs

0x0203 6 年之前
父节点
当前提交
4de6d284a3
共有 4 个文件被更改,包括 108 次插入55 次删除
  1. 1 1
      demo/x11_rawfb/Makefile
  2. 3 3
      demo/x11_rawfb/main.c
  3. 81 47
      demo/x11_rawfb/nuklear_rawfb.h
  4. 23 4
      demo/x11_rawfb/nuklear_xlib.h

+ 1 - 1
demo/x11_rawfb/Makefile

@@ -2,7 +2,7 @@
 BIN = zahnrad
 BIN = zahnrad
 
 
 # Flags
 # Flags
-CFLAGS += -std=c89 -pedantic -O2 -Wunused -DRAWFB_XRGB_8888
+CFLAGS += -std=c89 -pedantic -O2 -Wunused
 
 
 SRC = main.c
 SRC = main.c
 OBJ = $(SRC:.c=.o)
 OBJ = $(SRC:.c=.o)

+ 3 - 3
demo/x11_rawfb/main.c

@@ -35,7 +35,6 @@
 #include <unistd.h>
 #include <unistd.h>
 #include <time.h>
 #include <time.h>
 
 
-#define RAWFB_XRGB_8888
 #define NK_INCLUDE_FIXED_TYPES
 #define NK_INCLUDE_FIXED_TYPES
 #define NK_INCLUDE_STANDARD_IO
 #define NK_INCLUDE_STANDARD_IO
 #define NK_INCLUDE_STANDARD_VARARGS
 #define NK_INCLUDE_STANDARD_VARARGS
@@ -152,6 +151,7 @@ main(void)
     XWindow xw;
     XWindow xw;
     struct rawfb_context *rawfb;
     struct rawfb_context *rawfb;
     void *fb = NULL;
     void *fb = NULL;
+    rawfb_pl pl;
     unsigned char tex_scratch[512 * 512];
     unsigned char tex_scratch[512 * 512];
 
 
     /* X11 */
     /* X11 */
@@ -180,12 +180,12 @@ main(void)
     xw.height = (unsigned int)xw.attr.height;
     xw.height = (unsigned int)xw.attr.height;
 
 
     /* Framebuffer emulator */
     /* 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)
     if (!status || !fb)
         return 0;
         return 0;
 
 
     /* GUI */
     /* 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;
     if (!rawfb) running = 0;
 
 
     #ifdef INCLUDE_STYLE
     #ifdef INCLUDE_STYLE

+ 81 - 47
demo/x11_rawfb/nuklear_rawfb.h

@@ -33,11 +33,18 @@
 
 
 struct rawfb_context;
 struct rawfb_context;
 
 
+typedef enum rawfb_pixel_layout {
+    PIXEL_LAYOUT_XRGB_8888,
+    PIXEL_LAYOUT_RGBX_8888,
+}
+rawfb_pl;
+
+
 /* All functions are thread-safe */
 /* 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_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_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
 #endif
 /*
 /*
@@ -48,10 +55,10 @@ NK_API void                  nk_rawfb_resize_fb(struct rawfb_context *rawfb, voi
  * ===============================================================
  * ===============================================================
  */
  */
 #ifdef NK_RAWFB_IMPLEMENTATION
 #ifdef NK_RAWFB_IMPLEMENTATION
-
 struct rawfb_image {
 struct rawfb_image {
     void *pixels;
     void *pixels;
     int w, h, pitch;
     int w, h, pitch;
+    rawfb_pl pl;
     enum nk_font_atlas_format format;
     enum nk_font_atlas_format format;
 };
 };
 struct rawfb_context {
 struct rawfb_context {
@@ -70,42 +77,54 @@ struct rawfb_context {
 #endif
 #endif
 
 
 static unsigned int
 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;
     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);
     return (res);
 }
 }
 
 
 static struct nk_color
 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;
     return col;
 }
 }
 
 
@@ -113,7 +132,7 @@ static void
 nk_rawfb_ctx_setpixel(const struct rawfb_context *rawfb,
 nk_rawfb_ctx_setpixel(const struct rawfb_context *rawfb,
     const short x0, const short y0, const struct nk_color col)
     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 char *pixels = rawfb->fb.pixels;
     unsigned int *ptr;
     unsigned int *ptr;
 
 
@@ -144,7 +163,7 @@ nk_rawfb_line_horizontal(const struct rawfb_context *rawfb,
 
 
     n = x1 - x0;
     n = x1 - x0;
     for (i = 0; i < sizeof(c) / sizeof(c[0]); i++)
     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) {
     while (n > 16) {
         memcpy((void *)ptr, c, sizeof(c));
         memcpy((void *)ptr, c, sizeof(c));
@@ -157,7 +176,7 @@ static void
 nk_rawfb_img_setpixel(const struct rawfb_image *img,
 nk_rawfb_img_setpixel(const struct rawfb_image *img,
     const int x0, const int y0, const struct nk_color col)
     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 char *ptr;
     unsigned int *pixel;
     unsigned int *pixel;
     NK_ASSERT(img);
     NK_ASSERT(img);
@@ -191,7 +210,7 @@ nk_rawfb_img_getpixel(const struct rawfb_image *img, const int x0, const int y0)
         } else {
         } else {
 	    pixel = ptr;
 	    pixel = ptr;
 	    pixel += x0;
 	    pixel += x0;
-	    col = nk_rawfb_int2color(*pixel);
+	    col = nk_rawfb_int2color(*pixel, img->pl);
         }
         }
     } return col;
     } 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_API struct rawfb_context*
 nk_rawfb_init(void *fb, void *tex_mem, const unsigned int w, const unsigned int h,
 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;
     const void *tex;
     struct rawfb_context *rawfb;
     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.pixels = fb;
     rawfb->fb.w= w;
     rawfb->fb.w= w;
     rawfb->fb.h = h;
     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.format = NK_FONT_ATLAS_RGBA32;
     rawfb->fb.pitch = pitch;
     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_init_default(&rawfb->atlas);
     nk_font_atlas_begin(&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);
     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) {
     switch(rawfb->font_tex.format) {
     case NK_FONT_ATLAS_ALPHA8:
     case NK_FONT_ATLAS_ALPHA8:
@@ -988,9 +1018,11 @@ nk_rawfb_drawimage(const struct rawfb_context *rawfb,
 NK_API void
 NK_API void
 nk_rawfb_shutdown(struct rawfb_context *rawfb)
 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
 NK_API void
@@ -998,12 +1030,14 @@ nk_rawfb_resize_fb(struct rawfb_context *rawfb,
                    void *fb,
                    void *fb,
                    const unsigned int w,
                    const unsigned int w,
                    const unsigned int h,
                    const unsigned int h,
-                   const unsigned int pitch)
+                   const unsigned int pitch,
+		   const rawfb_pl pl)
 {
 {
     rawfb->fb.w = w;
     rawfb->fb.w = w;
     rawfb->fb.h = h;
     rawfb->fb.h = h;
     rawfb->fb.pixels = fb;
     rawfb->fb.pixels = fb;
     rawfb->fb.pitch = pitch;
     rawfb->fb.pitch = pitch;
+    rawfb->fb.pl = pl;
 }
 }
 
 
 NK_API void
 NK_API void

+ 23 - 4
demo/x11_rawfb/nuklear_xlib.h

@@ -35,7 +35,7 @@
 
 
 #include <X11/Xlib.h>
 #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 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_render(Drawable screen);
 NK_API void nk_xlib_shutdown(void);
 NK_API void nk_xlib_shutdown(void);
@@ -71,7 +71,7 @@ static struct  {
 
 
 NK_API int
 NK_API int
 nk_xlib_init(Display *dpy, Visual *vis, int screen, Window root,
 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);
     unsigned int depth = XDefaultDepth(dpy, screen);
     xlib.dpy = dpy;
     xlib.dpy = dpy;
@@ -134,6 +134,24 @@ nk_xlib_init(Display *dpy, Visual *vis, int screen, Window root,
     }
     }
     xlib.gc = XDefaultGC(dpy, screen);
     xlib.gc = XDefaultGC(dpy, screen);
     *fb = xlib.ximg->data;
     *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;
     return 1;
 }
 }
 
 
@@ -238,13 +256,14 @@ nk_xlib_handle_event(Display *dpy, int screen, Window win, XEvent *evt, struct r
         unsigned int width, height;
         unsigned int width, height;
         XWindowAttributes attr;
         XWindowAttributes attr;
         XGetWindowAttributes(dpy, win, &attr);
         XGetWindowAttributes(dpy, win, &attr);
+	rawfb_pl pl;
 
 
         width = (unsigned int)attr.width;
         width = (unsigned int)attr.width;
         height = (unsigned int)attr.height;
         height = (unsigned int)attr.height;
 
 
         nk_xlib_shutdown();
         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) {
     } else if (evt->type == KeymapNotify) {
         XRefreshKeyboardMapping(&evt->xmapping);
         XRefreshKeyboardMapping(&evt->xmapping);
         return 1;
         return 1;