Module Name:    src
Committed By:   jmcneill
Date:           Thu Aug 25 11:45:26 UTC 2011

Added Files:
        src/sys/arch/usermode/dev: genfb_thunkbus.c
        src/sys/arch/usermode/usermode: thunk_sdl.c

Log Message:
- build thunk code with warnings
- add option SDL which pulls in thunk_sdl code and links the kernel to libSDL
- add an experimental framebuffer driver based on thunk_sdl, enable with:
    options SDL
    genfb* at mainbus?
    wsdisplay* at genfb?
    options WS_KERNEL_FG=WSCOL_GREEN
    options WSEMUL_VT100
- reserve a major # for wsdisplay
- add thunk_getenv()


To generate a diff of this commit:
cvs rdiff -u -r0 -r1.1 src/sys/arch/usermode/dev/genfb_thunkbus.c
cvs rdiff -u -r0 -r1.1 src/sys/arch/usermode/usermode/thunk_sdl.c

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Added files:

Index: src/sys/arch/usermode/dev/genfb_thunkbus.c
diff -u /dev/null src/sys/arch/usermode/dev/genfb_thunkbus.c:1.1
--- /dev/null	Thu Aug 25 11:45:26 2011
+++ src/sys/arch/usermode/dev/genfb_thunkbus.c	Thu Aug 25 11:45:25 2011
@@ -0,0 +1,156 @@
+/* $NetBSD: genfb_thunkbus.c,v 1.1 2011/08/25 11:45:25 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2011 Jared D. McNeill <jmcne...@invisible.ca>
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
+ */
+
+#include <sys/cdefs.h>
+__KERNEL_RCSID(0, "$NetBSD: genfb_thunkbus.c,v 1.1 2011/08/25 11:45:25 jmcneill Exp $");
+
+#include <sys/param.h>
+#include <sys/proc.h>
+#include <sys/systm.h>
+#include <sys/device.h>
+
+#include <dev/wsfb/genfbvar.h>
+
+#include <machine/mainbus.h>
+#include <machine/thunk.h>
+
+#ifdef _KERNEL_OPT
+#include "opt_sdl.h"
+#endif
+
+#if !defined(SDL)
+#error genfb_thunkbus requires options SDL
+#endif
+
+#define GENFB_THUNKBUS_WIDTH	640
+#define	GENFB_THUNKBUS_HEIGHT	480
+#define	GENFB_THUNKBUS_DEPTH	32
+#define	GENFB_THUNKBUS_FBSIZE	\
+	(GENFB_THUNKBUS_WIDTH * GENFB_THUNKBUS_HEIGHT * (GENFB_THUNKBUS_DEPTH / 8))
+
+static int	genfb_thunkbus_match(device_t, cfdata_t, void *);
+static void	genfb_thunkbus_attach(device_t, device_t, void *);
+static int	genfb_thunkbus_ioctl(void *, void *, u_long, void *, int, lwp_t *);
+static paddr_t	genfb_thunkbus_mmap(void *, void *, off_t, int);
+
+int		genfb_thunkbus_cnattach(void);
+
+struct genfb_thunkbus_softc {
+	struct genfb_softc	sc_gen;
+};
+
+static void *	genfb_thunkbus_fbaddr;
+
+CFATTACH_DECL_NEW(genfb_thunkbus, sizeof(struct genfb_thunkbus_softc),
+    genfb_thunkbus_match, genfb_thunkbus_attach, NULL, NULL);
+
+static int
+genfb_thunkbus_match(device_t parent, cfdata_t match, void *opaque)
+{
+	struct thunkbus_attach_args *taa = opaque;
+
+	if (taa->taa_type != THUNKBUS_TYPE_GENFB)
+		return 0;
+
+	if (thunk_getenv("DISPLAY") == NULL)
+		return 0;
+
+	return 1;
+}
+
+static void
+genfb_thunkbus_attach(device_t parent, device_t self, void *opaque)
+{
+	struct genfb_thunkbus_softc *sc = device_private(self);
+	struct genfb_ops ops;
+	prop_dictionary_t dict = device_properties(self);
+
+	aprint_naive("\n");
+	aprint_normal("\n");
+
+	sc->sc_gen.sc_dev = self;
+	sc->sc_gen.sc_fbaddr = genfb_thunkbus_fbaddr;
+
+	prop_dictionary_set_bool(dict, "is_console", true);
+	prop_dictionary_set_uint32(dict, "width", GENFB_THUNKBUS_WIDTH);
+	prop_dictionary_set_uint32(dict, "height", GENFB_THUNKBUS_HEIGHT);
+	prop_dictionary_set_uint8(dict, "depth", GENFB_THUNKBUS_DEPTH);
+	prop_dictionary_set_uint16(dict, "linebytes",
+	    GENFB_THUNKBUS_WIDTH * (GENFB_THUNKBUS_DEPTH / 8));
+	prop_dictionary_set_uint64(dict, "address", 0);
+	prop_dictionary_set_uint64(dict, "virtual_address",
+	    (vaddr_t)sc->sc_gen.sc_fbaddr);
+
+	genfb_init(&sc->sc_gen);
+
+	memset(&ops, 0, sizeof(ops));
+	ops.genfb_ioctl = genfb_thunkbus_ioctl;
+	ops.genfb_mmap = genfb_thunkbus_mmap;
+
+	if (genfb_attach(&sc->sc_gen, &ops) != 0)
+		panic("%s: couldn't attach genfb", __func__);
+
+}
+
+static int
+genfb_thunkbus_ioctl(void *v, void *vs, u_long cmd, void *data, int flag, lwp_t *l)
+{
+	switch (cmd) {
+	case WSDISPLAYIO_GTYPE:
+		*(unsigned int *)data = WSDISPLAY_TYPE_UNKNOWN;
+		return 0;
+	}
+
+	return EPASSTHROUGH;
+}
+
+static paddr_t
+genfb_thunkbus_mmap(void *v, void *vs, off_t off, int prot)
+{
+	return -1;
+}
+
+int
+genfb_thunkbus_cnattach(void)
+{
+	int error;
+
+	if (thunk_getenv("DISPLAY") == NULL)
+		return 0;
+
+	genfb_thunkbus_fbaddr = thunk_sdl_getfb(GENFB_THUNKBUS_FBSIZE);
+	if (genfb_thunkbus_fbaddr == NULL)
+		return 0;
+
+	error = thunk_sdl_init(GENFB_THUNKBUS_WIDTH,
+	    GENFB_THUNKBUS_HEIGHT, GENFB_THUNKBUS_DEPTH);
+	if (error)
+		return 0;
+
+	return 1;
+}

Index: src/sys/arch/usermode/usermode/thunk_sdl.c
diff -u /dev/null src/sys/arch/usermode/usermode/thunk_sdl.c:1.1
--- /dev/null	Thu Aug 25 11:45:26 2011
+++ src/sys/arch/usermode/usermode/thunk_sdl.c	Thu Aug 25 11:45:26 2011
@@ -0,0 +1,239 @@
+/* $NetBSD: thunk_sdl.c,v 1.1 2011/08/25 11:45:26 jmcneill Exp $ */
+
+/*-
+ * Copyright (c) 2011 Jared D. McNeill <jmcne...@invisible.ca>
+ * All rights reserved.
+ *
+ * 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.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. 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 FOUNDATION 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.
+ */
+
+#include <sys/cdefs.h>
+__RCSID("$NetBSD: thunk_sdl.c,v 1.1 2011/08/25 11:45:26 jmcneill Exp $");
+
+#include <sys/types.h>
+#include <sys/signal.h>
+#include <sys/reboot.h>
+#include <sys/shm.h>
+
+#include <errno.h>
+#include <fcntl.h>
+#include <unistd.h>
+
+#include <SDL.h>
+
+#include "../include/thunk.h"
+
+extern const char ostype[];
+extern const char osrelease[];
+extern const char kernel_ident[];
+
+#define THUNK_SDL_REDRAW_INTERVAL	100	/* 10 Hz */
+
+#define THUNK_SDL_EV_REDRAW		1
+
+static int thunk_sdl_running = 0;	/* SDL event loop run status */
+static void *thunk_sdl_fbaddr = NULL;	/* framebuffer va */
+static int thunk_sdl_shmid;
+
+/* Framebuffer parameters */
+static unsigned int thunk_sdl_width;
+static unsigned int thunk_sdl_height;
+static unsigned short thunk_sdl_depth;
+
+/*
+ * Create an SDL surface from the framebuffer memory, then blit
+ * it to the screen.
+ */
+static void
+thunk_sdl_redraw(SDL_Surface *screen)
+{
+	SDL_Surface *wsfb;
+	Uint32 rmask, gmask, bmask, amask;
+
+	if (thunk_sdl_fbaddr == NULL)
+		return;
+
+	rmask = 0x000000ff;
+	gmask = 0x0000ff00;
+	bmask = 0x00ff0000;
+	amask = 0x00000000;
+
+	wsfb = SDL_CreateRGBSurfaceFrom(thunk_sdl_fbaddr,
+	    thunk_sdl_width, thunk_sdl_height, thunk_sdl_depth,
+	    thunk_sdl_width * (thunk_sdl_depth / 8),
+	    rmask, gmask, bmask, amask);
+	if (wsfb == NULL)
+		abort();
+	if (SDL_BlitSurface(wsfb, NULL, screen, NULL) == -1)
+		abort();
+	SDL_Flip(screen);
+	SDL_FreeSurface(wsfb);
+}
+
+/*
+ * Timer callback used to inject a redraw event into the SDL event loop
+ */
+static Uint32
+thunk_sdl_tick(Uint32 interval, void *param)
+{
+	SDL_Event ev;
+
+	if (!thunk_sdl_running)
+		return 0;
+
+	ev.type = SDL_USEREVENT;
+	ev.user.code = THUNK_SDL_EV_REDRAW;
+	ev.user.data1 = ev.user.data2 = NULL;
+	SDL_PushEvent(&ev);
+
+	return interval;
+}
+
+/*
+ * SDL event loop
+ */
+static int
+thunk_sdl_eventloop(void *priv)
+{
+	SDL_Surface *screen;
+	char caption[81];
+	//int stdin_fd;
+	SDL_Event ev;
+	key_t k;
+
+	thunk_sdl_running = 1;
+
+	k = ftok("/dev/null", 1);
+	if (k == (key_t)-1)
+		return errno;
+	thunk_sdl_shmid = shmget(k,
+	    thunk_sdl_width * thunk_sdl_height * (thunk_sdl_depth / 8), 0600);
+	thunk_sdl_fbaddr = shmat(thunk_sdl_shmid, NULL, 0);
+	if (thunk_sdl_fbaddr == NULL)
+		abort();
+
+	/* SDL_Init closes stdin, so we need to restore it after it returns */
+	//stdin_fd = dup(0);
+	if (SDL_Init(SDL_INIT_VIDEO|SDL_INIT_TIMER) < 0)
+		abort();
+	atexit(SDL_Quit);
+	//close(0);
+	//dup2(stdin_fd, 0);
+
+	/* Clear SDL signal handler so ^C will work */
+	//signal(SIGINT, SIG_DFL);
+
+	/* Configure key repeat */
+	SDL_EnableKeyRepeat(SDL_DEFAULT_REPEAT_DELAY, SDL_DEFAULT_REPEAT_DELAY);
+
+	/* Set the window title */
+	memset(caption, 0, sizeof(caption));
+	snprintf(caption, sizeof(caption), "%s %s (%s)",
+	    ostype, osrelease, kernel_ident); 
+	SDL_WM_SetCaption(caption, NULL);
+
+	/* Try to configure the requested video mode */
+	screen = SDL_SetVideoMode(thunk_sdl_width, thunk_sdl_height,
+	    thunk_sdl_depth, 0);
+	if (screen == NULL)
+		abort();
+
+	/* Hide the mouse cursor */
+	SDL_ShowCursor(SDL_DISABLE);
+
+	SDL_AddTimer(THUNK_SDL_REDRAW_INTERVAL, thunk_sdl_tick, NULL);
+
+	while (thunk_sdl_running) {
+		if (!SDL_WaitEvent(&ev))
+			abort();
+		printf("ev.type = %d\n", ev.type);
+		switch (ev.type) {
+		case SDL_QUIT:
+			thunk_sdl_running = 0;
+			break;
+		case SDL_KEYDOWN:
+			printf("key %X scancode %X\n", ev.key.keysym.sym,
+			    ev.key.keysym.scancode);
+			break;
+		case SDL_USEREVENT:
+			switch (ev.user.code) {
+			case THUNK_SDL_EV_REDRAW:
+				thunk_sdl_redraw(screen);
+				break;
+			}
+		}
+
+		thunk_sdl_redraw(screen);
+	}
+
+	printf("shutting down...\n");
+	abort();
+	return 0;
+}
+
+int
+thunk_sdl_init(unsigned int width, unsigned int height, unsigned short depth)
+{
+	static int thunk_sdl_inited = 0;
+	static int thunk_sdl_init_status = -1;
+
+	if (thunk_sdl_inited)
+		goto done;
+	thunk_sdl_inited = 1;
+
+	/* Save a copy of the video mode parameters for later */
+	thunk_sdl_width = width;
+	thunk_sdl_height = height;
+	thunk_sdl_depth = depth;
+
+	/* run event loop */
+	switch (fork()) {
+	case 0:
+		thunk_sdl_eventloop(NULL);
+		break;
+	case -1:
+		abort();
+	default:
+		break;
+	}
+
+	thunk_sdl_init_status = 0;
+
+done:
+	return thunk_sdl_init_status;
+}
+
+/*
+ * Get the framebuffer virtual address
+ */
+void *
+thunk_sdl_getfb(size_t fbsize)
+{
+	key_t k;
+
+	k = ftok("/dev/null", 1);
+	if (k == (key_t)-1)
+		return NULL;
+
+	thunk_sdl_shmid = shmget(k, fbsize, IPC_CREAT | 0600);
+	return shmat(thunk_sdl_shmid, NULL, 0);
+}

Reply via email to