summaryrefslogtreecommitdiff
path: root/nuttx/arch/sim
diff options
context:
space:
mode:
authorpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2008-11-30 16:46:21 +0000
committerpatacongo <patacongo@42af7a65-404d-4744-a932-0658087f49c3>2008-11-30 16:46:21 +0000
commit9560a9c61336f114585563c55bf5fc64522710ef (patch)
tree201af1bfe304382a915caeb43e732051d4246552 /nuttx/arch/sim
parentdfe8da156b2a2e0da650805c425af00ec4ed1d55 (diff)
downloadpx4-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')
-rw-r--r--nuttx/arch/sim/src/Makefile4
-rw-r--r--nuttx/arch/sim/src/up_framebuffer.c31
-rw-r--r--nuttx/arch/sim/src/up_x11framebuffer.c413
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;
+}