diff options
author | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2008-11-30 16:46:21 +0000 |
---|---|---|
committer | patacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3> | 2008-11-30 16:46:21 +0000 |
commit | 9560a9c61336f114585563c55bf5fc64522710ef (patch) | |
tree | 201af1bfe304382a915caeb43e732051d4246552 /nuttx/arch/sim/src | |
parent | dfe8da156b2a2e0da650805c425af00ec4ed1d55 (diff) | |
download | px4-nuttx-9560a9c61336f114585563c55bf5fc64522710ef.tar.gz px4-nuttx-9560a9c61336f114585563c55bf5fc64522710ef.tar.bz2 px4-nuttx-9560a9c61336f114585563c55bf5fc64522710ef.zip |
Add X11 simulated framebuffer
git-svn-id: svn://svn.code.sf.net/p/nuttx/code/trunk@1359 42af7a65-404d-4744-a932-0658087f49c3
Diffstat (limited to 'nuttx/arch/sim/src')
-rw-r--r-- | nuttx/arch/sim/src/Makefile | 4 | ||||
-rw-r--r-- | nuttx/arch/sim/src/up_framebuffer.c | 31 | ||||
-rw-r--r-- | nuttx/arch/sim/src/up_x11framebuffer.c | 413 |
3 files changed, 446 insertions, 2 deletions
diff --git a/nuttx/arch/sim/src/Makefile b/nuttx/arch/sim/src/Makefile index 765a92aa1..6897f2f63 100644 --- a/nuttx/arch/sim/src/Makefile +++ b/nuttx/arch/sim/src/Makefile @@ -45,7 +45,7 @@ CSRCS = up_initialize.c up_idle.c up_interruptcontext.c \ up_releasepending.c up_reprioritizertr.c \ up_exit.c up_schedulesigaction.c up_allocateheap.c \ up_devconsole.c up_framebuffer.c -HOSTSRCS = up_stdio.c +HOSTSRCS = up_stdio.c up_x11framebuffer.c ifeq ($(CONFIG_FS_FAT),y) CSRCS += up_blockdevice.c up_deviceimage.c endif @@ -63,7 +63,7 @@ SRCS = $(ASRCS) $(CSRCS) $(HOSTSRCS) OBJS = $(AOBJS) $(COBJS) $(HOSTOBJS) LDFLAGS = $(ARCHSCRIPT) -STDLIBS = -lc +STDLIBS = -lX11 -lXext -lc ifeq ($(CONFIG_FS_FAT),y) STDLIBS += -lz endif diff --git a/nuttx/arch/sim/src/up_framebuffer.c b/nuttx/arch/sim/src/up_framebuffer.c index 31bb1d459..f81a5512b 100644 --- a/nuttx/arch/sim/src/up_framebuffer.c +++ b/nuttx/arch/sim/src/up_framebuffer.c @@ -114,6 +114,21 @@ static int up_setcursor(FAR struct fb_vtable_s *vtable, FAR struct fb_setcursor_ #endif /**************************************************************************** + * Public Function Prototypes + ****************************************************************************/ + +#ifdef CONFIG_SIM_X11FB +extern int up_x11initialize(unsigned short width, unsigned short height, + void **fbmem, unsigned int *fblen, unsigned char *bpp, + unsigned short *stride); +#ifdef CONFIG_FB_CMAP +extern int up_x11cmap(unsigned short first, unsigned short len, + unsigned char *red, unsigned char *green, + unsigned char *blue, unsigned char *transp) +#endif +#endif + +/**************************************************************************** * Private Data ****************************************************************************/ @@ -129,6 +144,7 @@ static const struct fb_videoinfo_s g_videoinfo = .nplanes = 1, }; +#ifndef CONFIG_SIM_X11FB /* This structure describes the single, simulated color plane */ static const struct fb_planeinfo_s g_planeinfo = @@ -138,6 +154,11 @@ static const struct fb_planeinfo_s g_planeinfo = .stride = FB_WIDTH, .bpp = CONFIG_SIM_FBBPP, }; +#else +/* This structure describes the single, X11 color plane */ + +static struct fb_planeinfo_s g_planeinfo; +#endif /* Simulated RGB mapping */ @@ -224,6 +245,9 @@ static int up_getplaneinfo(FAR struct fb_vtable_s *vtable, int planeno, #ifdef CONFIG_FB_CMAP static int up_getcmap(FAR struct fb_vtable_s *vtable, FAR struct fb_cmap_s *cmap) { +#ifdef CONFIG_SIM_X11FB + return up_x11cmap(cmap->start, cmap->len, cmap->red, cmap->green, cmap->blue, cmap->transp); +#else int len int i; @@ -244,6 +268,7 @@ static int up_getcmap(FAR struct fb_vtable_s *vtable, FAR struct fb_cmap_s *cmap } dbg("Returning EINVAL\n"); return -EINVAL; +#endif } #endif @@ -345,7 +370,13 @@ static int up_setcursor(FAR struct fb_vtable_s *vtable, int up_fbinitialize(void) { +#ifdef CONFIG_SIM_X11FB + return up_x11initialize(CONFIG_SIM_FBWIDTH, CONFIG_SIM_FBHEIGHT, + &g_planeinfo.fbmem, &g_planeinfo.fblen, + &g_planeinfo.bpp, &g_planeinfo.stride); +#else return OK; +#endif } /**************************************************************************** diff --git a/nuttx/arch/sim/src/up_x11framebuffer.c b/nuttx/arch/sim/src/up_x11framebuffer.c new file mode 100644 index 000000000..d19a56f80 --- /dev/null +++ b/nuttx/arch/sim/src/up_x11framebuffer.c @@ -0,0 +1,413 @@ +/**************************************************************************** + * arch/sim/src/up_framebuffer.c + * + * Copyright (C) 2008 Gregory Nutt. All rights reserved. + * Author: Gregory Nutt <spudmonkey@racsa.co.cr> + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions + * are met: + * + * 1. Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * 2. Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in + * the documentation and/or other materials provided with the + * distribution. + * 3. Neither the name NuttX nor the names of its contributors may be + * used to endorse or promote products derived from this software + * without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS + * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE + * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, + * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, + * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS + * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED + * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT + * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN + * ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE + * POSSIBILITY OF SUCH DAMAGE. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#define CONFIG_SIM_X11NOSHM 1 + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <X11/Xlib.h> +#include <X11/Xutil.h> +#include <sys/ipc.h> + +#ifndef CONFIG_SIM_X11NOSHM +# include <sys/shm.h> +# include <X11/extensions/XShm.h> +#endif + +/**************************************************************************** + * Definitions + ****************************************************************************/ + +/**************************************************************************** + * Private Type Declarations + ***************************************************************************/ + +/**************************************************************************** + * Private Function Prototypes + ****************************************************************************/ + +/**************************************************************************** + * Global Variables + ****************************************************************************/ + +/**************************************************************************** + * Private Variables + ****************************************************************************/ + +static Display *g_display; +static int g_screen; +static Window g_window; +static GC g_gc; +#ifndef CONFIG_SIM_X11NOSHM +static XShmSegmentInfo g_xshminfo; +static int g_xerror; +#endif +static XImage *g_image; +static unsigned char *g_framebuffer; +static unsigned short g_fbpixelwidth; +static unsigned short g_fbpixelheight; +static int g_shmcheckpoint = 0; +static int b_useshm; + +/**************************************************************************** + * Name: up_x11createframe + ***************************************************************************/ + +static inline int up_x11createframe(void) +{ + XGCValues gcval; + char *argv[2] = { "nuttx", NULL }; + char *winName = "NuttX"; + char *iconName = "NX"; + XTextProperty winprop; + XTextProperty iconprop; + XSizeHints hints; + + g_display = XOpenDisplay(NULL); + if (g_display == NULL) + { + printf("Unable to open display.\n"); + return -1; + } + + g_screen = DefaultScreen(g_display); + g_window = XCreateSimpleWindow(g_display, DefaultRootWindow(g_display), + 0, 0, g_fbpixelwidth, g_fbpixelheight, 2, + BlackPixel(g_display, g_screen), + BlackPixel(g_display, g_screen)); + + XStringListToTextProperty(&winName, 1, &winprop); + XStringListToTextProperty(&iconName, 1, &iconprop); + + hints.flags = PSize | PMinSize | PMaxSize; + hints.width = hints.min_width = hints.max_width = g_fbpixelwidth; + hints.height= hints.min_height = hints.max_height = g_fbpixelheight; + + XSetWMProperties(g_display, g_window, &winprop, &iconprop, argv, 1, + &hints, NULL, NULL); + + XMapWindow(g_display, g_window); + XSelectInput(g_display, g_window, + ButtonPressMask | ButtonReleaseMask | + ButtonMotionMask | KeyPressMask | ExposureMask); + gcval.graphics_exposures = 0; + g_gc = XCreateGC(g_display, g_window, GCGraphicsExposures, &gcval); + return 0; +} + +/**************************************************************************** + * Name: up_x11errorhandler + ***************************************************************************/ + +#ifndef CONFIG_SIM_X11NOSHM +static int up_x11errorhandler(Display *display, XErrorEvent *event) +{ + g_xerror = 1; + return 0; +} +#endif + +/**************************************************************************** + * Name: up_x11traperrors + ***************************************************************************/ + +#ifndef CONFIG_SIM_X11NOSHM +static void up_x11traperrors(void) +{ + g_xerror = 0; + XSetErrorHandler(up_x11errorhandler); +} +#endif + +/**************************************************************************** + * Name: up_x11untraperrors + ***************************************************************************/ + +#ifndef CONFIG_SIM_X11NOSHM +static int up_x11untraperrors(void) +{ + XSync(g_display,0); + XSetErrorHandler(NULL); + return g_xerror; +} +#endif + +/**************************************************************************** + * Name: up_x11uninitialize + ***************************************************************************/ + +void up_x11uninitialize(void) +{ + fprintf(stderr, "Uninitalizing\n"); +#ifndef CONFIG_SIM_X11NOSHM + if (g_shmcheckpoint > 4) + { + XShmDetach(g_display, &g_xshminfo); + } + + if (g_shmcheckpoint > 3) + { + shmdt(g_xshminfo.shmaddr); + } + + if (g_shmcheckpoint > 2) + { + shmctl(g_xshminfo.shmid, IPC_RMID, 0); + } +#endif + + if (g_shmcheckpoint > 1) + { + XDestroyImage(g_image); + if (!b_useshm) + { + free(g_framebuffer); + } + } + + if (g_shmcheckpoint > 0) + { + g_shmcheckpoint = 1; + } + XCloseDisplay(g_display); +} + +/**************************************************************************** + * Name: up_x11mapsharedmem + ***************************************************************************/ + +static inline int up_x11mapsharedmem(int bpp, unsigned int fblen) +{ +#ifndef CONFIG_SIM_X11NOSHM + Status result; +#endif + + atexit(up_x11uninitialize); + g_shmcheckpoint = 1; + b_useshm = 0; + +#ifndef CONFIG_SIM_X11NOSHM + if (XShmQueryExtension(g_display)) + { + b_useshm = 1; + printf("Using shared memory.\n"); + + up_x11traperrors(); + g_image = XShmCreateImage(g_display, DefaultVisual(g_display, g_screen), + bpp, ZPixmap, NULL, &g_xshminfo, + g_fbpixelwidth, g_fbpixelheight); + if (up_x11untraperrors()) + { + up_x11uninitialize(); + goto shmerror; + } + if (!g_image) + { + fprintf(stderr,"Unable to create g_image."); + return -1; + } + g_shmcheckpoint++; + + g_xshminfo.shmid = shmget(IPC_PRIVATE, + g_image->bytes_per_line * g_image->height, + IPC_CREAT | 0777); + if (g_xshminfo.shmid < 0) + { + up_x11uninitialize(); + goto shmerror; + } + g_shmcheckpoint++; + + g_image->data = (char *) shmat(g_xshminfo.shmid, 0, 0); + if (g_image->data == ((char *) -1)) + { + up_x11uninitialize(); + goto shmerror; + } + g_shmcheckpoint++; + + g_xshminfo.shmaddr = g_image->data; + g_xshminfo.readOnly = 0; + + up_x11traperrors(); + result = XShmAttach(g_display, &g_xshminfo); + if (up_x11untraperrors() || !result) + { + up_x11uninitialize(); + goto shmerror; + } + + g_shmcheckpoint++; + + } + else +#endif + if (!b_useshm) + { +#ifndef CONFIG_SIM_X11NOSHM +shmerror: +#endif + b_useshm = 0; + + g_framebuffer = (unsigned char*)malloc(fblen); + + g_image = XCreateImage(g_display, DefaultVisual(g_display,g_screen), bpp, + ZPixmap, 0, (char *) g_framebuffer, g_fbpixelwidth, g_fbpixelheight, + 8, 0); + + if (g_image == NULL) + { + fprintf(stderr, "Unable to create g_image\n"); + return -1; + } + + g_shmcheckpoint++; + } + return 0; +} + +/**************************************************************************** + * Name: up_x11update + ***************************************************************************/ + +static void up_x11update(void) +{ +#ifndef CONFIG_SIM_X11NOSHM + if (b_useshm) + { + XShmPutImage(g_display, g_window, g_gc, g_image, 0, 0, 0, 0, + g_fbpixelwidth, g_fbpixelheight, 0); + } + else +#endif + { + XPutImage(g_display, g_window, g_gc, g_image, 0, 0, 0, 0, + g_fbpixelwidth, g_fbpixelheight); + } + XSync(g_display, 0); +} + +/**************************************************************************** + * Public Functions + ***************************************************************************/ + +/**************************************************************************** + * Name: up_x11initialize + * + * Description: + * Make an X11 window look like a frame buffer. + * + ***************************************************************************/ + +int up_x11initialize(unsigned short width, unsigned short height, + void **fbmem, unsigned int *fblen, unsigned char *bpp, + unsigned short *stride) +{ + XWindowAttributes windowAttributes; + int ret; + + /* Save inputs */ + + g_fbpixelwidth = width; + g_fbpixelheight = height; + + /* Create the X11 window */ + + ret = up_x11createframe(); + if (ret < 0) + { + return ret; + } + + /* Determine the supported pixel bpp of the current window */ + + XGetWindowAttributes(g_display, DefaultRootWindow(g_display), &windowAttributes); + printf("Pixel bpp is %d bits\n", windowAttributes.depth); + + *bpp = windowAttributes.depth; + *stride = (windowAttributes.depth * width / 8); + *fbmem = (void*)g_framebuffer; + *fblen = (*stride * height); + + /* Map the window to shared memory */ + + up_x11mapsharedmem(windowAttributes.depth, *fblen); + return 0; +} + +/**************************************************************************** + * Name: up_x11cmap + ***************************************************************************/ + +int up_x11cmap(unsigned short first, unsigned short len, + unsigned char *red, unsigned char *green, + unsigned char *blue, unsigned char *transp) +{ + Colormap cMap; + int ndx; + + printf("Creating Colormap\n"); + + /* Convert each color to X11 scaling */ + + cMap = DefaultColormap(g_display, g_screen); + for (ndx = first; ndx < first + len; ndx++) + { + XColor color; + + /* Convert to RGB. In the NuttX cmap, each component + * ranges from 0-255; for X11 the range is 0-65536 */ + + color.red = (short)(*red++) << 8; + color.green = (short)(*green++) << 8; + color.blue = (short)(*blue++) << 8; + color.flags = DoRed | DoGreen | DoBlue; + + /* Then allocate a color for this selection */ + + if (!XAllocColor(g_display, cMap, &color)) + { + fprintf(stderr, "Failed to allocate color%d\n", ndx); + return -1; + } + } + + return 0; +} |