Hi all,
DirectFB may belong to the past, but here is a patch for people still
interested in using it.
A screenshot with NetSurf running directly on top of DirectFB is available on
the HiGFXback (History of graphics backends) project.
Nicolas Caramelli
diff --git a/Makefile b/Makefile
index dd6bbac..9c4d73b 100644
--- a/Makefile
+++ b/Makefile
@@ -44,11 +44,19 @@ NSFB_XCB_PKG_NAMES := xcb xcb-icccm xcb-image
xcb-keysyms xcb-atom
# determine which surface handlers can be compiled based upon avalable library
$(eval $(call pkg_config_package_available,NSFB_VNC_AVAILABLE,libvncserver))
+$(eval $(call pkg_config_package_available,NSFB_DIRECTFB_AVAILABLE,directfb))
$(eval $(call pkg_config_package_available,NSFB_SDL_AVAILABLE,sdl))
$(eval $(call pkg_config_package_available,NSFB_XCB_AVAILABLE,$(NSFB_XCB_PKG_NAMES)))
$(eval $(call pkg_config_package_available,NSFB_WLD_AVAILABLE,wayland-client))
# Flags and setup for each support library
+ifeq ($(NSFB_DIRECTFB_AVAILABLE),yes)
+ $(eval $(call pkg_config_package_add_flags,directfb,CFLAGS,LDFLAGS))
+ $(eval $(call pkg_config_package_add_flags,directfb,TESTCFLAGS,TESTLDFLAGS))
+
+ REQUIRED_PKGS := $(REQUIRED_PKGS) directfb
+endif
+
ifeq ($(NSFB_SDL_AVAILABLE),yes)
$(eval $(call pkg_config_package_add_flags,sdl,CFLAGS))
$(eval $(call pkg_config_package_add_flags,sdl,TESTCFLAGS,TESTLDFLAGS))
diff --git a/README b/README
index b4a1685..d4a3820 100644
--- a/README
+++ b/README
@@ -18,6 +18,7 @@ Requirements
The following libraries may also be installed:
+ + DirectFB (for the DirectFB surface)
+ SDL 1.2 (for the SDL surface)
+ libxcb* (for the X11 surface)
* wayland-client (for wayland surface)
diff --git a/include/libnsfb.h b/include/libnsfb.h
index dfb720c..9aec3dd 100644
--- a/include/libnsfb.h
+++ b/include/libnsfb.h
@@ -36,6 +36,7 @@ typedef struct nsfb_bbox_s {
enum nsfb_type_e {
NSFB_SURFACE_NONE = 0, /**< No surface */
NSFB_SURFACE_RAM, /**< RAM surface */
+ NSFB_SURFACE_DIRECTFB, /**< DirectFB surface */
NSFB_SURFACE_SDL, /**< SDL surface */
NSFB_SURFACE_LINUX, /**< Linux framebuffer surface */
NSFB_SURFACE_VNC, /**< VNC surface */
diff --git a/src/surface/Makefile b/src/surface/Makefile
index 848c3d4..d35d1cc 100644
--- a/src/surface/Makefile
+++ b/src/surface/Makefile
@@ -4,6 +4,7 @@
SURFACE_HANDLER_yes := surface.c ram.c
# optional surface handlers
+SURFACE_HANDLER_$(NSFB_DIRECTFB_AVAILABLE) += directfb.c
SURFACE_HANDLER_$(NSFB_SDL_AVAILABLE) += sdl.c
SURFACE_HANDLER_$(NSFB_XCB_AVAILABLE) += x.c
SURFACE_HANDLER_$(NSFB_VNC_AVAILABLE) += vnc.c
diff --git a/src/surface/directfb.c b/src/surface/directfb.c
new file mode 100644
index 0000000..4a108a0
--- /dev/null
+++ b/src/surface/directfb.c
@@ -0,0 +1,259 @@
+/*
+ * Copyright 2019 Nicolas Caramelli
+ *
+ * This file is part of libnsfb, http://www.netsurf-browser.org/
+ * Licenced under the MIT License,
+ * http://www.opensource.org/licenses/mit-license.php
+ */
+
+#include <directfb.h>
+
+#include "libnsfb.h"
+#include "libnsfb_event.h"
+
+#include "surface.h"
+#include "plot.h"
+
+typedef struct directfb_priv_s {
+ IDirectFB *dfb;
+ IDirectFBDisplayLayer *layer;
+ IDirectFBWindow *window;
+ IDirectFBSurface *surface;
+ IDirectFBEventBuffer *buffer;
+} directfb_priv_t;
+
+static int directfb_set_geometry(nsfb_t *nsfb, int width, int height,
+ enum nsfb_format_e format)
+{
+ if (nsfb->surface_priv != NULL) {
+ return -1;
+ }
+
+ nsfb->width = width;
+ nsfb->height = height;
+ if (format != NSFB_FMT_XRGB8888) {
+ return -1;
+ }
+
+ select_plotters(nsfb);
+
+ return 0;
+}
+
+static int directfb_initialise(nsfb_t *nsfb)
+{
+ directfb_priv_t *directfb_priv;
+ int ret = DFB_OK;
+ DFBWindowDescription desc;
+
+ if (nsfb->surface_priv != NULL) {
+ return -1;
+ }
+
+ directfb_priv = calloc(1, sizeof(directfb_priv_t));
+ if (directfb_priv == NULL) {
+ fprintf(stderr, "DirectFB private data allocation failed\n");
+ return -1;
+ }
+
+ ret = DirectFBInit(NULL, NULL);
+ if (ret) {
+ fprintf(stderr, "DirectFBInit failed: %s\n", DirectFBErrorString(ret));
+ goto fail;
+ }
+
+ ret = DirectFBCreate(&directfb_priv->dfb);
+ if (ret) {
+ fprintf(stderr, "DirectFBCreate failed: %s\n",
+ DirectFBErrorString(ret));
+ goto fail;
+ }
+
+ ret = directfb_priv->dfb->GetDisplayLayer(directfb_priv->dfb, DLID_PRIMARY,
+ &directfb_priv->layer);
+ if (ret) {
+ fprintf(stderr, "GetDisplayLayer failed: %s\n",
+ DirectFBErrorString(ret));
+ goto fail;
+ }
+
+ desc.flags = DWDESC_WIDTH | DWDESC_HEIGHT | DSDESC_PIXELFORMAT;
+ desc.width = nsfb->width;
+ desc.height = nsfb->height;
+ desc.pixelformat = DSPF_ARGB;
+ ret = directfb_priv->layer->CreateWindow(directfb_priv->layer, &desc,
+ &directfb_priv->window);
+ if (ret) {
+ fprintf(stderr, "CreateWindow failed: %s\n", DirectFBErrorString(ret));
+ goto fail;
+ }
+
+ ret = directfb_priv->window->GetSurface(directfb_priv->window,
+ &directfb_priv->surface);
+ if (ret) {
+ fprintf(stderr, "GetSurface failed: %s\n", DirectFBErrorString(ret));
+ goto fail;
+ }
+
+ ret = directfb_priv->surface->Lock(directfb_priv->surface, DSLF_WRITE,
+ (void **)&nsfb->ptr, &nsfb->linelen);
+ if (ret) {
+ fprintf(stderr, "Lock failed: %s\n", DirectFBErrorString(ret));
+ goto fail;
+ }
+
+ ret = directfb_priv->surface->Unlock(directfb_priv->surface);
+ if (ret) {
+ fprintf(stderr, "Unlock failed: %s\n", DirectFBErrorString(ret));
+ goto fail;
+ }
+
+ ret = directfb_priv->window->CreateEventBuffer(directfb_priv->window,
+ &directfb_priv->buffer);
+ if (ret) {
+ fprintf(stderr, "CreateEventBuffer failed: %s\n",
+ DirectFBErrorString(ret));
+ goto fail;
+ }
+
+ ret = directfb_priv->window->SetOpacity(directfb_priv->window, 0xff);
+ if (ret) {
+ fprintf(stderr, "SetOpacity failed: %s\n", DirectFBErrorString(ret));
+ goto fail;
+ }
+
+ nsfb->surface_priv = directfb_priv;
+
+ return 0;
+
+fail:
+ if (directfb_priv->buffer)
+ directfb_priv->buffer->Release(directfb_priv->buffer);
+ if (directfb_priv->surface)
+ directfb_priv->surface->Release(directfb_priv->surface);
+ if (directfb_priv->window)
+ directfb_priv->window->Release(directfb_priv->window);
+ if (directfb_priv->layer)
+ directfb_priv->layer->Release(directfb_priv->layer);
+ if (directfb_priv->dfb)
+ directfb_priv->dfb->Release(directfb_priv->dfb);
+ free(directfb_priv);
+ return -1;
+}
+
+static int directfb_finalise(nsfb_t *nsfb)
+{
+ directfb_priv_t *directfb_priv = nsfb->surface_priv;
+
+ if (directfb_priv == NULL) {
+ return 0;
+ }
+
+ directfb_priv->buffer->Release(directfb_priv->buffer);
+ directfb_priv->surface->Release(directfb_priv->surface);
+ directfb_priv->window->Release(directfb_priv->window);
+ directfb_priv->layer->Release(directfb_priv->layer);
+ directfb_priv->dfb->Release(directfb_priv->dfb);
+ free(directfb_priv);
+
+ return 0;
+}
+
+static bool directfb_input(nsfb_t *nsfb, nsfb_event_t *event, int timeout)
+{
+ directfb_priv_t *directfb_priv = nsfb->surface_priv;
+ int ret = DFB_OK;
+ DFBWindowEvent dfb_event;
+
+ if (directfb_priv == NULL) {
+ return false;
+ }
+
+ ret = directfb_priv->buffer->WaitForEventWithTimeout(directfb_priv->buffer,
+ timeout / 1000,
+ timeout % 1000);
+ if (ret == DFB_TIMEOUT) {
+ event->type = NSFB_EVENT_CONTROL;
+ event->value.controlcode = NSFB_CONTROL_TIMEOUT;
+ return true;
+ }
+
+ directfb_priv->buffer->GetEvent(directfb_priv->buffer,
+ (DFBEvent *)&dfb_event);
+
+ if (dfb_event.type == DWET_KEYDOWN) {
+ event->type = NSFB_EVENT_KEY_DOWN;
+ event->value.keycode = dfb_event.key_symbol;
+ } else if (dfb_event.type == DWET_KEYUP) {
+ event->type = NSFB_EVENT_KEY_UP;
+ event->value.keycode = dfb_event.key_symbol;
+ } else if (dfb_event.type == DWET_BUTTONDOWN) {
+ event->type = NSFB_EVENT_KEY_DOWN;
+ switch (dfb_event.button) {
+ case DIBI_LEFT:
+ event->value.keycode = NSFB_KEY_MOUSE_1;
+ break;
+ case DIBI_MIDDLE:
+ event->value.keycode = NSFB_KEY_MOUSE_2;
+ break;
+ case DIBI_RIGHT:
+ event->value.keycode = NSFB_KEY_MOUSE_3;
+ break;
+ default:
+ break;
+ }
+ } else if (dfb_event.type == DWET_BUTTONUP) {
+ event->type = NSFB_EVENT_KEY_UP;
+ switch (dfb_event.button) {
+ case DIBI_LEFT:
+ event->value.keycode = NSFB_KEY_MOUSE_1;
+ break;
+ case DIBI_MIDDLE:
+ event->value.keycode = NSFB_KEY_MOUSE_2;
+ break;
+ case DIBI_RIGHT:
+ event->value.keycode = NSFB_KEY_MOUSE_3;
+ break;
+ default:
+ break;
+ }
+ } else if (dfb_event.type == DWET_MOTION) {
+ event->type = NSFB_EVENT_MOVE_ABSOLUTE;
+ event->value.vector.x = dfb_event.x;
+ event->value.vector.y = dfb_event.y;
+ event->value.vector.z = 0;
+ } else {
+ event->type = NSFB_EVENT_NONE;
+ }
+
+ return true;
+}
+
+static int directfb_update(nsfb_t *nsfb, nsfb_bbox_t *box)
+{
+ directfb_priv_t *directfb_priv = nsfb->surface_priv;
+
+ if (directfb_priv != NULL) {
+ directfb_priv->surface->Flip(directfb_priv->surface,
+ (DFBRegion *)box, DSFLIP_WAITFORSYNC);
+ }
+
+ return 0;
+}
+
+const nsfb_surface_rtns_t directfb_rtns = {
+ .geometry = directfb_set_geometry,
+ .initialise = directfb_initialise,
+ .finalise = directfb_finalise,
+ .input = directfb_input,
+ .update = directfb_update,
+};
+
+NSFB_SURFACE_DEF(directfb, NSFB_SURFACE_DIRECTFB, &directfb_rtns)
+
+/*
+ * Local variables:
+ * c-basic-offset: 4
+ * tab-width: 8
+ * End:
+ */
No comments:
Post a Comment