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 -Naur libnsfb.orig/Makefile libnsfb/Makefile --- libnsfb.orig/Makefile 2019-09-05 15:05:20.000000000 +0000 +++ libnsfb/Makefile 2019-09-05 15:05:32.000000000 +0000 @@ -44,11 +44,19 @@ # 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 -Naur libnsfb.orig/README libnsfb/README --- libnsfb.orig/README 2019-09-05 15:05:20.000000000 +0000 +++ libnsfb/README 2019-09-05 15:05:32.000000000 +0000 @@ -18,6 +18,7 @@ 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 -Naur libnsfb.orig/include/libnsfb.h libnsfb/include/libnsfb.h --- libnsfb.orig/include/libnsfb.h 2019-09-05 15:05:20.000000000 +0000 +++ libnsfb/include/libnsfb.h 2019-09-05 15:05:32.000000000 +0000 @@ -36,6 +36,7 @@ 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 -Naur libnsfb.orig/src/surface/Makefile libnsfb/src/surface/Makefile --- libnsfb.orig/src/surface/Makefile 2019-09-05 15:05:20.000000000 +0000 +++ libnsfb/src/surface/Makefile 2019-09-05 15:05:32.000000000 +0000 @@ -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 -Naur libnsfb.orig/src/surface/directfb.c libnsfb/src/surface/directfb.c --- libnsfb.orig/src/surface/directfb.c 1970-01-01 00:00:00.000000000 +0000 +++ libnsfb/src/surface/directfb.c 2019-09-05 15:05:32.000000000 +0000 @@ -0,0 +1,271 @@ +/* + * 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)); + free(directfb_priv); + return -1; + } + + ret = DirectFBCreate(&directfb_priv->dfb); + if (ret) { + fprintf(stderr, "DirectFBCreate failed: %s\n", + DirectFBErrorString(ret)); + free(directfb_priv); + return -1; + } + + ret = directfb_priv->dfb->GetDisplayLayer(directfb_priv->dfb, DLID_PRIMARY, + &directfb_priv->layer); + if (ret) { + fprintf(stderr, "GetDisplayLayer failed: %s\n", + DirectFBErrorString(ret)); + directfb_priv->dfb->Release(directfb_priv->dfb); + free(directfb_priv); + return -1; + } + + 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)); + directfb_priv->layer->Release(directfb_priv->layer); + directfb_priv->dfb->Release(directfb_priv->dfb); + free(directfb_priv); + return -1; + } + + ret = directfb_priv->window->GetSurface(directfb_priv->window, + &directfb_priv->surface); + if (ret) { + fprintf(stderr, "GetSurface failed: %s\n", DirectFBErrorString(ret)); + 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 -1; + } + + directfb_priv->surface->Lock(directfb_priv->surface, DSLF_WRITE, + (void **)&nsfb->ptr, &nsfb->linelen); + directfb_priv->surface->Unlock(directfb_priv->surface); + + ret = directfb_priv->window->SetOpacity(directfb_priv->window, 0xff); + if (ret) { + fprintf(stderr, "SetOpacity failed: %s\n", DirectFBErrorString(ret)); + 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 -1; + } + + ret = directfb_priv->dfb->CreateEventBuffer(directfb_priv->dfb, + &directfb_priv->buffer); + if (ret) { + fprintf(stderr, "CreateEventBuffer failed: %s\n", + DirectFBErrorString(ret)); + 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 -1; + } + + ret = directfb_priv->window->AttachEventBuffer(directfb_priv->window, + directfb_priv->buffer); + if (ret) { + fprintf(stderr, "AttachEventBuffer failed: %s\n", + DirectFBErrorString(ret)); + 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 -1; + } + + nsfb->surface_priv = directfb_priv; + + return 0; +} + +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: + */