summaryrefslogtreecommitdiff
path: root/src/surface
diff options
context:
space:
mode:
Diffstat (limited to 'src/surface')
-rw-r--r--src/surface/Makefile4
-rw-r--r--src/surface/able.c59
-rw-r--r--src/surface/linux.c135
-rw-r--r--src/surface/ram.c59
-rw-r--r--src/surface/sdl.c660
-rw-r--r--src/surface/surface.c127
-rw-r--r--src/surface/vnc.c59
-rw-r--r--src/surface/x.c786
8 files changed, 1889 insertions, 0 deletions
diff --git a/src/surface/Makefile b/src/surface/Makefile
new file mode 100644
index 0000000..3abbfb6
--- /dev/null
+++ b/src/surface/Makefile
@@ -0,0 +1,4 @@
+# Sources
+DIR_SOURCES := surface.c sdl.c vnc.c able.c ram.c linux.c x.c
+
+include build/makefiles/Makefile.subdir
diff --git a/src/surface/able.c b/src/surface/able.c
new file mode 100644
index 0000000..d7b9226
--- /dev/null
+++ b/src/surface/able.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2009 Vincent Sanders <vince@simtec.co.uk>
+ *
+ * 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 <stdbool.h>
+#include <stdio.h>
+
+#include "libnsfb.h"
+#include "libnsfb_plot.h"
+#include "libnsfb_event.h"
+#include "nsfb.h"
+#include "frontend.h"
+
+#define UNUSED(x) ((x) = (x))
+
+static int able_set_geometry(nsfb_t *nsfb, int width, int height, int bpp)
+{
+ if (nsfb->frontend_priv != NULL)
+ return -1; /* if were already initialised fail */
+
+ nsfb->width = width;
+ nsfb->height = height;
+ nsfb->bpp = bpp;
+
+ return 0;
+}
+
+static int able_initialise(nsfb_t *nsfb)
+{
+ UNUSED(nsfb);
+ return 0;
+}
+
+static int able_finalise(nsfb_t *nsfb)
+{
+ UNUSED(nsfb);
+ return 0;
+}
+
+static bool able_input(nsfb_t *nsfb, nsfb_event_t *event, int timeout)
+{
+ UNUSED(nsfb);
+ UNUSED(event);
+ UNUSED(timeout);
+ return false;
+}
+
+const nsfb_frontend_rtns_t able_rtns = {
+ .initialise = able_initialise,
+ .finalise = able_finalise,
+ .input = able_input,
+ .geometry = able_set_geometry,
+};
+
+NSFB_FRONTEND_DEF(able, NSFB_FRONTEND_ABLE, &able_rtns)
diff --git a/src/surface/linux.c b/src/surface/linux.c
new file mode 100644
index 0000000..3394f85
--- /dev/null
+++ b/src/surface/linux.c
@@ -0,0 +1,135 @@
+/*
+ * Copyright 2009 Vincent Sanders <vince@simtec.co.uk>
+ *
+ * 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 <stdbool.h>
+#include <stdio.h>
+
+#include "libnsfb.h"
+#include "libnsfb_event.h"
+#include "libnsfb_plot.h"
+#include "libnsfb_plot_util.h"
+
+#include "nsfb.h"
+#include "plot.h"
+#include "frontend.h"
+#include "cursor.h"
+
+
+#define UNUSED(x) ((x) = (x))
+
+static int linux_set_geometry(nsfb_t *nsfb, int width, int height, int bpp)
+{
+ if (nsfb->frontend_priv != NULL)
+ return -1; /* if we are already initialised fail */
+
+ nsfb->width = width;
+ nsfb->height = height;
+ nsfb->bpp = bpp;
+
+ /* select default sw plotters for bpp */
+ select_plotters(nsfb);
+
+ return 0;
+}
+
+static int linux_initialise(nsfb_t *nsfb)
+{
+ if (nsfb->frontend_priv != NULL)
+ return -1;
+
+ /* sanity checked depth. */
+ if ((nsfb->bpp != 32) && (nsfb->bpp != 16) && (nsfb->bpp != 8))
+ return -1;
+
+
+ return 0;
+}
+
+static int linux_finalise(nsfb_t *nsfb)
+{
+ UNUSED(nsfb);
+ return 0;
+}
+
+static bool linux_input(nsfb_t *nsfb, nsfb_event_t *event, int timeout)
+{
+ UNUSED(nsfb);
+ UNUSED(event);
+ UNUSED(timeout);
+ return false;
+}
+
+static int linux_claim(nsfb_t *nsfb, nsfb_bbox_t *box)
+{
+ struct nsfb_cursor_s *cursor = nsfb->cursor;
+
+ if ((cursor != NULL) &&
+ (cursor->plotted == true) &&
+ (nsfb_plot_bbox_intersect(box, &cursor->loc))) {
+
+ nsfb->plotter_fns->bitmap(nsfb,
+ &cursor->savloc,
+ cursor->sav,
+ cursor->sav_width,
+ cursor->sav_height,
+ cursor->sav_width,
+ false);
+ cursor->plotted = false;
+ }
+ return 0;
+}
+
+static int linux_cursor(nsfb_t *nsfb, struct nsfb_cursor_s *cursor)
+{
+ nsfb_bbox_t sclip;
+
+ if ((cursor != NULL) && (cursor->plotted == true)) {
+ sclip = nsfb->clip;
+
+ nsfb->plotter_fns->set_clip(nsfb, NULL);
+
+ nsfb->plotter_fns->bitmap(nsfb,
+ &cursor->savloc,
+ cursor->sav,
+ cursor->sav_width,
+ cursor->sav_height,
+ cursor->sav_width,
+ false);
+
+ nsfb_cursor_plot(nsfb, cursor);
+
+ nsfb->clip = sclip;
+ }
+ return true;
+}
+
+
+static int linux_update(nsfb_t *nsfb, nsfb_bbox_t *box)
+{
+ struct nsfb_cursor_s *cursor = nsfb->cursor;
+
+ UNUSED(box);
+
+ if ((cursor != NULL) && (cursor->plotted == false)) {
+ nsfb_cursor_plot(nsfb, cursor);
+ }
+
+ return 0;
+}
+
+const nsfb_frontend_rtns_t linux_rtns = {
+ .initialise = linux_initialise,
+ .finalise = linux_finalise,
+ .input = linux_input,
+ .claim = linux_claim,
+ .update = linux_update,
+ .cursor = linux_cursor,
+ .geometry = linux_set_geometry,
+};
+
+NSFB_FRONTEND_DEF(linux, NSFB_FRONTEND_LINUX, &linux_rtns)
diff --git a/src/surface/ram.c b/src/surface/ram.c
new file mode 100644
index 0000000..0948a5d
--- /dev/null
+++ b/src/surface/ram.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2009 Vincent Sanders <vince@simtec.co.uk>
+ *
+ * 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 <stdbool.h>
+#include <stdio.h>
+
+#include "libnsfb.h"
+#include "libnsfb_plot.h"
+#include "libnsfb_event.h"
+#include "nsfb.h"
+#include "frontend.h"
+
+#define UNUSED(x) ((x) = (x))
+
+static int ram_set_geometry(nsfb_t *nsfb, int width, int height, int bpp)
+{
+ if (nsfb->frontend_priv != NULL)
+ return -1; /* if were already initialised fail */
+
+ nsfb->width = width;
+ nsfb->height = height;
+ nsfb->bpp = bpp;
+
+ return 0;
+}
+
+static int ram_initialise(nsfb_t *nsfb)
+{
+ UNUSED(nsfb);
+ return 0;
+}
+
+static int ram_finalise(nsfb_t *nsfb)
+{
+ UNUSED(nsfb);
+ return 0;
+}
+
+static bool ram_input(nsfb_t *nsfb, nsfb_event_t *event, int timeout)
+{
+ UNUSED(nsfb);
+ UNUSED(event);
+ UNUSED(timeout);
+ return false;
+}
+
+const nsfb_frontend_rtns_t ram_rtns = {
+ .initialise = ram_initialise,
+ .finalise = ram_finalise,
+ .input = ram_input,
+ .geometry = ram_set_geometry,
+};
+
+NSFB_FRONTEND_DEF(ram, NSFB_FRONTEND_RAM, &ram_rtns)
diff --git a/src/surface/sdl.c b/src/surface/sdl.c
new file mode 100644
index 0000000..cc83a4e
--- /dev/null
+++ b/src/surface/sdl.c
@@ -0,0 +1,660 @@
+/*
+ * Copyright 2009 Vincent Sanders <vince@simtec.co.uk>
+ *
+ * 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 <stdbool.h>
+#include <stdlib.h>
+#include <SDL/SDL.h>
+
+#include "libnsfb.h"
+#include "libnsfb_event.h"
+#include "libnsfb_plot.h"
+#include "libnsfb_plot_util.h"
+
+#include "nsfb.h"
+#include "frontend.h"
+#include "plot.h"
+#include "cursor.h"
+
+enum nsfb_key_code_e sdl_nsfb_map[] = {
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_BACKSPACE,
+ NSFB_KEY_TAB,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_CLEAR,
+ NSFB_KEY_RETURN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_PAUSE,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_ESCAPE,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_SPACE,
+ NSFB_KEY_EXCLAIM,
+ NSFB_KEY_QUOTEDBL,
+ NSFB_KEY_HASH,
+ NSFB_KEY_DOLLAR,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_AMPERSAND,
+ NSFB_KEY_QUOTE,
+ NSFB_KEY_LEFTPAREN,
+ NSFB_KEY_RIGHTPAREN,
+ NSFB_KEY_ASTERISK,
+ NSFB_KEY_PLUS,
+ NSFB_KEY_COMMA,
+ NSFB_KEY_MINUS,
+ NSFB_KEY_PERIOD,
+ NSFB_KEY_SLASH,
+ NSFB_KEY_0,
+ NSFB_KEY_1,
+ NSFB_KEY_2,
+ NSFB_KEY_3,
+ NSFB_KEY_4,
+ NSFB_KEY_5,
+ NSFB_KEY_6,
+ NSFB_KEY_7,
+ NSFB_KEY_8,
+ NSFB_KEY_9,
+ NSFB_KEY_COLON,
+ NSFB_KEY_SEMICOLON,
+ NSFB_KEY_LESS,
+ NSFB_KEY_EQUALS,
+ NSFB_KEY_GREATER,
+ NSFB_KEY_QUESTION,
+ NSFB_KEY_AT,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_LEFTBRACKET,
+ NSFB_KEY_BACKSLASH,
+ NSFB_KEY_RIGHTBRACKET,
+ NSFB_KEY_CARET,
+ NSFB_KEY_UNDERSCORE,
+ NSFB_KEY_BACKQUOTE,
+ NSFB_KEY_a,
+ NSFB_KEY_b,
+ NSFB_KEY_c,
+ NSFB_KEY_d,
+ NSFB_KEY_e,
+ NSFB_KEY_f,
+ NSFB_KEY_g,
+ NSFB_KEY_h,
+ NSFB_KEY_i,
+ NSFB_KEY_j,
+ NSFB_KEY_k,
+ NSFB_KEY_l,
+ NSFB_KEY_m,
+ NSFB_KEY_n,
+ NSFB_KEY_o,
+ NSFB_KEY_p,
+ NSFB_KEY_q,
+ NSFB_KEY_r,
+ NSFB_KEY_s,
+ NSFB_KEY_t,
+ NSFB_KEY_u,
+ NSFB_KEY_v,
+ NSFB_KEY_w,
+ NSFB_KEY_x,
+ NSFB_KEY_y,
+ NSFB_KEY_z,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_DELETE,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_KP0,
+ NSFB_KEY_KP1,
+ NSFB_KEY_KP2,
+ NSFB_KEY_KP3,
+ NSFB_KEY_KP4,
+ NSFB_KEY_KP5,
+ NSFB_KEY_KP6,
+ NSFB_KEY_KP7,
+ NSFB_KEY_KP8,
+ NSFB_KEY_KP9,
+ NSFB_KEY_KP_PERIOD,
+ NSFB_KEY_KP_DIVIDE,
+ NSFB_KEY_KP_MULTIPLY,
+ NSFB_KEY_KP_MINUS,
+ NSFB_KEY_KP_PLUS,
+ NSFB_KEY_KP_ENTER,
+ NSFB_KEY_KP_EQUALS,
+ NSFB_KEY_UP,
+ NSFB_KEY_DOWN,
+ NSFB_KEY_RIGHT,
+ NSFB_KEY_LEFT,
+ NSFB_KEY_INSERT,
+ NSFB_KEY_HOME,
+ NSFB_KEY_END,
+ NSFB_KEY_PAGEUP,
+ NSFB_KEY_PAGEDOWN,
+ NSFB_KEY_F1,
+ NSFB_KEY_F2,
+ NSFB_KEY_F3,
+ NSFB_KEY_F4,
+ NSFB_KEY_F5,
+ NSFB_KEY_F6,
+ NSFB_KEY_F7,
+ NSFB_KEY_F8,
+ NSFB_KEY_F9,
+ NSFB_KEY_F10,
+ NSFB_KEY_F11,
+ NSFB_KEY_F12,
+ NSFB_KEY_F13,
+ NSFB_KEY_F14,
+ NSFB_KEY_F15,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_NUMLOCK,
+ NSFB_KEY_CAPSLOCK,
+ NSFB_KEY_SCROLLOCK,
+ NSFB_KEY_RSHIFT,
+ NSFB_KEY_LSHIFT,
+ NSFB_KEY_RCTRL,
+ NSFB_KEY_LCTRL,
+ NSFB_KEY_RALT,
+ NSFB_KEY_LALT,
+ NSFB_KEY_RMETA,
+ NSFB_KEY_LMETA,
+ NSFB_KEY_LSUPER,
+ NSFB_KEY_RSUPER,
+ NSFB_KEY_MODE,
+ NSFB_KEY_COMPOSE,
+ NSFB_KEY_HELP,
+ NSFB_KEY_PRINT,
+ NSFB_KEY_SYSREQ,
+ NSFB_KEY_BREAK,
+ NSFB_KEY_MENU,
+ NSFB_KEY_POWER,
+ NSFB_KEY_EURO,
+ NSFB_KEY_UNDO,
+};
+
+
+static void
+set_palette(nsfb_t *nsfb)
+{
+ SDL_Surface *sdl_screen = nsfb->frontend_priv;
+ SDL_Color palette[256];
+ int rloop, gloop, bloop;
+ int loop = 0;
+
+ /* build a linear R:3 G:3 B:2 colour cube palette. */
+ for (rloop = 0; rloop < 8; rloop++) {
+ for (gloop = 0; gloop < 8; gloop++) {
+ for (bloop = 0; bloop < 4; bloop++) {
+ palette[loop].r = (rloop << 5) | (rloop << 2) | (rloop >> 1);
+ palette[loop].g = (gloop << 5) | (gloop << 2) | (gloop >> 1);
+ palette[loop].b = (bloop << 6) | (bloop << 4) | (bloop << 2) | (bloop);
+ nsfb->palette[loop] = palette[loop].r |
+ palette[loop].g << 8 |
+ palette[loop].b << 16;
+ loop++;
+ }
+ }
+ }
+
+ /* Set palette */
+ SDL_SetColors(sdl_screen, palette, 0, 256);
+
+}
+
+static bool
+sdlcopy(nsfb_t *nsfb, nsfb_bbox_t *srcbox, nsfb_bbox_t *dstbox)
+{
+ SDL_Rect src;
+ SDL_Rect dst;
+ SDL_Surface *sdl_screen = nsfb->frontend_priv;
+ nsfb_bbox_t allbox;
+ struct nsfb_cursor_s *cursor = nsfb->cursor;
+
+ nsfb_plot_add_rect(srcbox, dstbox, &allbox);
+
+ /* clear the cursor if its within the region to be altered */
+ if ((cursor != NULL) &&
+ (cursor->plotted == true) &&
+ (nsfb_plot_bbox_intersect(&allbox, &cursor->loc))) {
+ nsfb_cursor_clear(nsfb, cursor);
+ }
+
+ src.x = srcbox->x0;
+ src.y = srcbox->y0;
+ src.w = srcbox->x1 - srcbox->x0;
+ src.h = srcbox->y1 - srcbox->y0;
+
+ dst.x = dstbox->x0;
+ dst.y = dstbox->y0;
+ dst.w = dstbox->x1 - dstbox->x0;
+ dst.h = dstbox->y1 - dstbox->y0;
+
+ SDL_BlitSurface(sdl_screen, &src, sdl_screen , &dst);
+
+ if ((cursor != NULL) &&
+ (cursor->plotted == false)) {
+ nsfb_cursor_plot(nsfb, cursor);
+ }
+
+ SDL_UpdateRect(sdl_screen, dst.x, dst.y, dst.w, dst.h);
+
+ return true;
+
+}
+
+static int sdl_set_geometry(nsfb_t *nsfb, int width, int height, int bpp)
+{
+ if (nsfb->frontend_priv != NULL)
+ return -1; /* if were already initialised fail */
+
+ nsfb->width = width;
+ nsfb->height = height;
+ nsfb->bpp = bpp;
+
+ /* select default sw plotters for bpp */
+ select_plotters(nsfb);
+
+ nsfb->plotter_fns->copy = sdlcopy;
+
+ return 0;
+}
+
+static int sdl_initialise(nsfb_t *nsfb)
+{
+ SDL_Surface *sdl_screen;
+
+ if (nsfb->frontend_priv != NULL)
+ return -1;
+
+ /* sanity checked depth. */
+ if ((nsfb->bpp != 32) && (nsfb->bpp != 16) && (nsfb->bpp != 8))
+ return -1;
+
+ /* initialise SDL library */
+ if (SDL_Init(SDL_INIT_VIDEO) < 0 ) {
+ fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError());
+ return -1;
+ }
+ atexit(SDL_Quit);
+
+ sdl_screen = SDL_SetVideoMode(nsfb->width,
+ nsfb->height,
+ nsfb->bpp,
+ SDL_SWSURFACE);
+
+ if (sdl_screen == NULL ) {
+ fprintf(stderr, "Unable to set video: %s\n", SDL_GetError());
+ return -1;
+ }
+
+ nsfb->frontend_priv = sdl_screen;
+
+ if (nsfb->bpp == 8)
+ set_palette(nsfb);
+
+ nsfb->ptr = sdl_screen->pixels;
+ nsfb->linelen = sdl_screen->pitch;
+
+ SDL_ShowCursor(SDL_DISABLE);
+ SDL_EnableKeyRepeat(300, 50);
+
+ return 0;
+}
+
+static int sdl_finalise(nsfb_t *nsfb)
+{
+ nsfb=nsfb;
+ return 0;
+}
+
+static bool sdl_input(nsfb_t *nsfb, nsfb_event_t *event, int timeout)
+{
+ int got_event;
+ SDL_Event sdlevent;
+
+ nsfb = nsfb; /* unused */
+
+ if (timeout < 0)
+ got_event = SDL_WaitEvent(&sdlevent);
+ else
+ got_event = SDL_PollEvent(&sdlevent);
+
+ /* Do nothing if there was no event */
+ if (got_event == 0)
+ return false;
+
+ event->type = NSFB_EVENT_NONE;
+
+ switch (sdlevent.type) {
+ case SDL_KEYDOWN:
+ event->type = NSFB_EVENT_KEY_DOWN;
+ event->value.keycode = sdl_nsfb_map[sdlevent.key.keysym.sym];
+ break;
+
+ case SDL_KEYUP:
+ event->type = NSFB_EVENT_KEY_UP;
+ event->value.keycode = sdl_nsfb_map[sdlevent.key.keysym.sym];
+ break;
+
+ case SDL_MOUSEBUTTONDOWN:
+ event->type = NSFB_EVENT_KEY_DOWN;
+
+ switch (sdlevent.button.button) {
+
+ case SDL_BUTTON_LEFT:
+ event->value.keycode = NSFB_KEY_MOUSE_1;
+ break;
+
+ case SDL_BUTTON_MIDDLE:
+ event->value.keycode = NSFB_KEY_MOUSE_2;
+ break;
+
+ case SDL_BUTTON_RIGHT:
+ event->value.keycode = NSFB_KEY_MOUSE_3;
+ break;
+
+ case SDL_BUTTON_WHEELUP:
+ event->value.keycode = NSFB_KEY_MOUSE_4;
+ break;
+
+ case SDL_BUTTON_WHEELDOWN:
+ event->value.keycode = NSFB_KEY_MOUSE_5;
+ break;
+ }
+ break;
+
+ case SDL_MOUSEBUTTONUP:
+ event->type = NSFB_EVENT_KEY_UP;
+
+ switch (sdlevent.button.button) {
+
+ case SDL_BUTTON_LEFT:
+ event->value.keycode = NSFB_KEY_MOUSE_1;
+ break;
+
+ case SDL_BUTTON_MIDDLE:
+ event->value.keycode = NSFB_KEY_MOUSE_2;
+ break;
+
+ case SDL_BUTTON_RIGHT:
+ event->value.keycode = NSFB_KEY_MOUSE_3;
+ break;
+
+ case SDL_BUTTON_WHEELUP:
+ event->value.keycode = NSFB_KEY_MOUSE_4;
+ break;
+
+ case SDL_BUTTON_WHEELDOWN:
+ event->value.keycode = NSFB_KEY_MOUSE_5;
+ break;
+ }
+ break;
+
+ case SDL_MOUSEMOTION:
+ event->type = NSFB_EVENT_MOVE_ABSOLUTE;
+ event->value.vector.x = sdlevent.motion.x;
+ event->value.vector.y = sdlevent.motion.y;
+ event->value.vector.z = 0;
+ break;
+
+ case SDL_QUIT:
+ event->type = NSFB_EVENT_CONTROL;
+ event->value.controlcode = NSFB_CONTROL_QUIT;
+ break;
+
+ }
+
+ return true;
+}
+
+static int sdl_claim(nsfb_t *nsfb, nsfb_bbox_t *box)
+{
+ struct nsfb_cursor_s *cursor = nsfb->cursor;
+
+ if ((cursor != NULL) &&
+ (cursor->plotted == true) &&
+ (nsfb_plot_bbox_intersect(box, &cursor->loc))) {
+ nsfb_cursor_clear(nsfb, cursor);
+ }
+ return 0;
+}
+
+static int
+sdl_cursor(nsfb_t *nsfb, struct nsfb_cursor_s *cursor)
+{
+ SDL_Surface *sdl_screen = nsfb->frontend_priv;
+ nsfb_bbox_t redraw;
+ nsfb_bbox_t fbarea;
+
+ if ((cursor != NULL) && (cursor->plotted == true)) {
+
+ nsfb_plot_add_rect(&cursor->savloc, &cursor->loc, &redraw);
+
+ /* screen area */
+ fbarea.x0 = 0;
+ fbarea.y0 = 0;
+ fbarea.x1 = nsfb->width;
+ fbarea.y1 = nsfb->height;
+
+ nsfb_plot_clip(&fbarea, &redraw);
+
+ nsfb_cursor_clear(nsfb, cursor);
+
+ nsfb_cursor_plot(nsfb, cursor);
+
+ SDL_UpdateRect(sdl_screen,
+ redraw.x0,
+ redraw.y0,
+ redraw.x1 - redraw.x0,
+ redraw.y1 - redraw.y0);
+
+
+ }
+ return true;
+}
+
+
+static int sdl_update(nsfb_t *nsfb, nsfb_bbox_t *box)
+{
+ SDL_Surface *sdl_screen = nsfb->frontend_priv;
+ struct nsfb_cursor_s *cursor = nsfb->cursor;
+
+ if ((cursor != NULL) &&
+ (cursor->plotted == false)) {
+ nsfb_cursor_plot(nsfb, cursor);
+ }
+
+ SDL_UpdateRect(sdl_screen,
+ box->x0,
+ box->y0,
+ box->x1 - box->x0,
+ box->y1 - box->y0);
+
+ return 0;
+}
+
+const nsfb_frontend_rtns_t sdl_rtns = {
+ .initialise = sdl_initialise,
+ .finalise = sdl_finalise,
+ .input = sdl_input,
+ .claim = sdl_claim,
+ .update = sdl_update,
+ .cursor = sdl_cursor,
+ .geometry = sdl_set_geometry,
+};
+
+NSFB_FRONTEND_DEF(sdl, NSFB_FRONTEND_SDL, &sdl_rtns)
diff --git a/src/surface/surface.c b/src/surface/surface.c
new file mode 100644
index 0000000..17d6113
--- /dev/null
+++ b/src/surface/surface.c
@@ -0,0 +1,127 @@
+/*
+ * Copyright 2009 Vincent Sanders <vince@simtec.co.uk>
+ *
+ * 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 <stdbool.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <malloc.h>
+#include <string.h>
+
+#include "frontend.h"
+#include "plot.h"
+
+#define MAX_FRONTENDS 16
+
+struct nsfb_frontend_s {
+ enum nsfb_frontend_e type;
+ const nsfb_frontend_rtns_t *rtns;
+ const char *name;
+};
+
+static struct nsfb_frontend_s frontends[MAX_FRONTENDS];
+static int frontend_count = 0;
+
+/* internal routine which lets frontends register their presence at runtime */
+void _nsfb_register_frontend(const enum nsfb_frontend_e type,
+ const nsfb_frontend_rtns_t *rtns,
+ const char *name)
+{
+ if (frontend_count >= MAX_FRONTENDS)
+ return; /* no space for additional frontends */
+
+ frontends[frontend_count].type = type;
+ frontends[frontend_count].rtns = rtns;
+ frontends[frontend_count].name = name;
+ frontend_count++;
+}
+
+/* default frontend implementations */
+static int frontend_defaults(nsfb_t *nsfb)
+{
+ nsfb->width = 800;
+ nsfb->height = 600;
+ nsfb->bpp = 32;
+
+ /* select default sw plotters for bpp */
+ select_plotters(nsfb);
+
+ return 0;
+}
+
+static int frontend_claim(nsfb_t *nsfb, nsfb_bbox_t *box)
+{
+ nsfb=nsfb;
+ box=box;
+ return 0;
+}
+
+static int frontend_update(nsfb_t *nsfb, nsfb_bbox_t *box)
+{
+ nsfb=nsfb;
+ box=box;
+ return 0;
+}
+
+static int frontend_cursor(nsfb_t *nsfb, struct nsfb_cursor_s *cursor)
+{
+ nsfb=nsfb;
+ cursor=cursor;
+ return 0;
+}
+
+nsfb_frontend_rtns_t *nsfb_frontend_get_rtns(enum nsfb_frontend_e type)
+{
+ int fend_loop;
+ nsfb_frontend_rtns_t *rtns = NULL;
+
+ for (fend_loop = 0; fend_loop < frontend_count; fend_loop++) {
+ if (frontends[fend_loop].type == type) {
+ rtns = malloc(sizeof(nsfb_frontend_rtns_t));
+ memcpy(rtns,
+ frontends[fend_loop].rtns,
+ sizeof(nsfb_frontend_rtns_t));
+
+ /* frontend must have an initialisor, finaliser and input method */
+ if ((rtns->initialise == NULL) ||
+ (rtns->finalise == NULL) ||
+ (rtns->input == NULL) ) {
+ free(rtns);
+ rtns = NULL;
+ } else {
+ /* The rest may be empty but to avoid the null check every time
+ * provide default implementations.
+ */
+ if (rtns->defaults == NULL)
+ rtns->defaults = frontend_defaults;
+
+ if (rtns->claim == NULL)
+ rtns->claim = frontend_claim;
+
+ if (rtns->update == NULL)
+ rtns->update = frontend_update;
+
+ if (rtns->cursor == NULL)
+ rtns->cursor = frontend_cursor;
+ }
+
+ break;
+ }
+ }
+ return rtns;
+}
+
+enum nsfb_frontend_e nsfb_frontend_from_name(const char *name)
+{
+ int fend_loop;
+
+ for (fend_loop = 0; fend_loop < frontend_count; fend_loop++) {
+ if (strcmp(frontends[fend_loop].name, name) == 0)
+ return frontends[fend_loop].type;
+ }
+ return NSFB_FRONTEND_NONE;
+}
diff --git a/src/surface/vnc.c b/src/surface/vnc.c
new file mode 100644
index 0000000..eb6d6ff
--- /dev/null
+++ b/src/surface/vnc.c
@@ -0,0 +1,59 @@
+/*
+ * Copyright 2009 Vincent Sanders <vince@simtec.co.uk>
+ *
+ * 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 <stdbool.h>
+#include <stdio.h>
+
+#include "libnsfb.h"
+#include "libnsfb_event.h"
+#include "libnsfb_plot.h"
+#include "nsfb.h"
+#include "frontend.h"
+
+#define UNUSED(x) ((x) = (x))
+
+static int vnc_set_geometry(nsfb_t *nsfb, int width, int height, int bpp)
+{
+ if (nsfb->frontend_priv != NULL)
+ return -1; /* if were already initialised fail */
+
+ nsfb->width = width;
+ nsfb->height = height;
+ nsfb->bpp = bpp;
+
+ return 0;
+}
+
+static int vnc_initialise(nsfb_t *nsfb)
+{
+ UNUSED(nsfb);
+ return 0;
+}
+
+static int vnc_finalise(nsfb_t *nsfb)
+{
+ UNUSED(nsfb);
+ return 0;
+}
+
+static bool vnc_input(nsfb_t *nsfb, nsfb_event_t *event, int timeout)
+{
+ UNUSED(nsfb);
+ UNUSED(event);
+ UNUSED(timeout);
+ return false;
+}
+
+const nsfb_frontend_rtns_t vnc_rtns = {
+ .initialise = vnc_initialise,
+ .finalise = vnc_finalise,
+ .input = vnc_input,
+ .geometry = vnc_set_geometry,
+};
+
+NSFB_FRONTEND_DEF(vnc, NSFB_FRONTEND_VNC, &vnc_rtns)
diff --git a/src/surface/x.c b/src/surface/x.c
new file mode 100644
index 0000000..6c45074
--- /dev/null
+++ b/src/surface/x.c
@@ -0,0 +1,786 @@
+/*
+ * Copyright 2009 Vincent Sanders <vince@simtec.co.uk>
+ *
+ * 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 <stdbool.h>
+#include <stdlib.h>
+#include <stdio.h>
+
+#include <xcb/xcb.h>
+#include <xcb/xcb_image.h>
+#include <xcb/xcb_atom.h>
+#include <xcb/xcb_icccm.h>
+
+#include "libnsfb.h"
+#include "libnsfb_event.h"
+#include "libnsfb_plot.h"
+#include "libnsfb_plot_util.h"
+
+#include "nsfb.h"
+#include "frontend.h"
+#include "plot.h"
+#include "cursor.h"
+
+enum nsfb_key_code_e x_nsfb_map[] = {
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_BACKSPACE,
+ NSFB_KEY_TAB,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_CLEAR,
+ NSFB_KEY_RETURN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_PAUSE,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_ESCAPE,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_SPACE,
+ NSFB_KEY_EXCLAIM,
+ NSFB_KEY_QUOTEDBL,
+ NSFB_KEY_HASH,
+ NSFB_KEY_DOLLAR,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_AMPERSAND,
+ NSFB_KEY_QUOTE,
+ NSFB_KEY_LEFTPAREN,
+ NSFB_KEY_RIGHTPAREN,
+ NSFB_KEY_ASTERISK,
+ NSFB_KEY_PLUS,
+ NSFB_KEY_COMMA,
+ NSFB_KEY_MINUS,
+ NSFB_KEY_PERIOD,
+ NSFB_KEY_SLASH,
+ NSFB_KEY_0,
+ NSFB_KEY_1,
+ NSFB_KEY_2,
+ NSFB_KEY_3,
+ NSFB_KEY_4,
+ NSFB_KEY_5,
+ NSFB_KEY_6,
+ NSFB_KEY_7,
+ NSFB_KEY_8,
+ NSFB_KEY_9,
+ NSFB_KEY_COLON,
+ NSFB_KEY_SEMICOLON,
+ NSFB_KEY_LESS,
+ NSFB_KEY_EQUALS,
+ NSFB_KEY_GREATER,
+ NSFB_KEY_QUESTION,
+ NSFB_KEY_AT,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_LEFTBRACKET,
+ NSFB_KEY_BACKSLASH,
+ NSFB_KEY_RIGHTBRACKET,
+ NSFB_KEY_CARET,
+ NSFB_KEY_UNDERSCORE,
+ NSFB_KEY_BACKQUOTE,
+ NSFB_KEY_a,
+ NSFB_KEY_b,
+ NSFB_KEY_c,
+ NSFB_KEY_d,
+ NSFB_KEY_e,
+ NSFB_KEY_f,
+ NSFB_KEY_g,
+ NSFB_KEY_h,
+ NSFB_KEY_i,
+ NSFB_KEY_j,
+ NSFB_KEY_k,
+ NSFB_KEY_l,
+ NSFB_KEY_m,
+ NSFB_KEY_n,
+ NSFB_KEY_o,
+ NSFB_KEY_p,
+ NSFB_KEY_q,
+ NSFB_KEY_r,
+ NSFB_KEY_s,
+ NSFB_KEY_t,
+ NSFB_KEY_u,
+ NSFB_KEY_v,
+ NSFB_KEY_w,
+ NSFB_KEY_x,
+ NSFB_KEY_y,
+ NSFB_KEY_z,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_DELETE,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_KP0,
+ NSFB_KEY_KP1,
+ NSFB_KEY_KP2,
+ NSFB_KEY_KP3,
+ NSFB_KEY_KP4,
+ NSFB_KEY_KP5,
+ NSFB_KEY_KP6,
+ NSFB_KEY_KP7,
+ NSFB_KEY_KP8,
+ NSFB_KEY_KP9,
+ NSFB_KEY_KP_PERIOD,
+ NSFB_KEY_KP_DIVIDE,
+ NSFB_KEY_KP_MULTIPLY,
+ NSFB_KEY_KP_MINUS,
+ NSFB_KEY_KP_PLUS,
+ NSFB_KEY_KP_ENTER,
+ NSFB_KEY_KP_EQUALS,
+ NSFB_KEY_UP,
+ NSFB_KEY_DOWN,
+ NSFB_KEY_RIGHT,
+ NSFB_KEY_LEFT,
+ NSFB_KEY_INSERT,
+ NSFB_KEY_HOME,
+ NSFB_KEY_END,
+ NSFB_KEY_PAGEUP,
+ NSFB_KEY_PAGEDOWN,
+ NSFB_KEY_F1,
+ NSFB_KEY_F2,
+ NSFB_KEY_F3,
+ NSFB_KEY_F4,
+ NSFB_KEY_F5,
+ NSFB_KEY_F6,
+ NSFB_KEY_F7,
+ NSFB_KEY_F8,
+ NSFB_KEY_F9,
+ NSFB_KEY_F10,
+ NSFB_KEY_F11,
+ NSFB_KEY_F12,
+ NSFB_KEY_F13,
+ NSFB_KEY_F14,
+ NSFB_KEY_F15,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_UNKNOWN,
+ NSFB_KEY_NUMLOCK,
+ NSFB_KEY_CAPSLOCK,
+ NSFB_KEY_SCROLLOCK,
+ NSFB_KEY_RSHIFT,
+ NSFB_KEY_LSHIFT,
+ NSFB_KEY_RCTRL,
+ NSFB_KEY_LCTRL,
+ NSFB_KEY_RALT,
+ NSFB_KEY_LALT,
+ NSFB_KEY_RMETA,
+ NSFB_KEY_LMETA,
+ NSFB_KEY_LSUPER,
+ NSFB_KEY_RSUPER,
+ NSFB_KEY_MODE,
+ NSFB_KEY_COMPOSE,
+ NSFB_KEY_HELP,
+ NSFB_KEY_PRINT,
+ NSFB_KEY_SYSREQ,
+ NSFB_KEY_BREAK,
+ NSFB_KEY_MENU,
+ NSFB_KEY_POWER,
+ NSFB_KEY_EURO,
+ NSFB_KEY_UNDO,
+};
+
+/*
+ static void
+ set_palette(nsfb_t *nsfb)
+ {
+ X_Surface *x_screen = nsfb->frontend_priv;
+ X_Color palette[256];
+ int rloop, gloop, bloop;
+ int loop = 0;
+
+ // build a linear R:3 G:3 B:2 colour cube palette.
+ for (rloop = 0; rloop < 8; rloop++) {
+ for (gloop = 0; gloop < 8; gloop++) {
+ for (bloop = 0; bloop < 4; bloop++) {
+ palette[loop].r = (rloop << 5) | (rloop << 2) | (rloop >> 1);
+ palette[loop].g = (gloop << 5) | (gloop << 2) | (gloop >> 1);
+ palette[loop].b = (bloop << 6) | (bloop << 4) | (bloop << 2) | (bloop);
+ nsfb->palette[loop] = palette[loop].r |
+ palette[loop].g << 8 |
+ palette[loop].b << 16;
+ loop++;
+ }
+ }
+ }
+
+ // Set palette
+ //X_SetColors(x_screen, palette, 0, 256);
+
+ }
+*/
+
+static int x_set_geometry(nsfb_t *nsfb, int width, int height, int bpp)
+{
+ if (nsfb->frontend_priv != NULL)
+ return -1; /* if were already initialised fail */
+
+ nsfb->width = width;
+ nsfb->height = height;
+ nsfb->bpp = bpp;
+
+ /* select default sw plotters for bpp */
+ select_plotters(nsfb);
+
+ return 0;
+}
+
+typedef struct xstate_s {
+ xcb_connection_t *connection; /* The x server connection */
+ xcb_screen_t *screen; /* The screen to put the window on */
+
+ xcb_image_t *image; /* The X image buffer */
+
+ xcb_window_t window; /* The handle to the window */
+ xcb_pixmap_t pmap; /* The handle to the backing pixmap */
+ xcb_gcontext_t gc; /* The handle to the pixmap plotting graphics context */
+} xstate_t;
+
+static xcb_format_t *
+find_format(xcb_connection_t * c, uint8_t depth, uint8_t bpp)
+{
+ const xcb_setup_t *setup = xcb_get_setup(c);
+ xcb_format_t *fmt = xcb_setup_pixmap_formats(setup);
+ xcb_format_t *fmtend = fmt + xcb_setup_pixmap_formats_length(setup);
+ for(; fmt != fmtend; ++fmt)
+ if((fmt->depth == depth) && (fmt->bits_per_pixel == bpp)) {
+ return fmt;
+ }
+ return 0;
+}
+
+static xcb_image_t *
+create_image(xcb_connection_t *c, int width, int height, int bpp)
+{
+ const xcb_setup_t *setup = xcb_get_setup(c);
+ unsigned char *image_data;
+ xcb_format_t *fmt;
+ int depth = bpp;
+ uint32_t image_size;
+
+ if (bpp == 32)
+ depth = 24;
+
+ fmt = find_format(c, depth, bpp);
+ if (fmt == NULL)
+ return NULL;
+
+ /* doing it this way ensures we deal with bpp smaller than 8 */
+ image_size = (bpp * width * height) >> 3;
+
+ image_data = calloc(1, image_size);
+ if (image_data == NULL)
+ return NULL;
+
+ return xcb_image_create(width,
+ height,
+ XCB_IMAGE_FORMAT_Z_PIXMAP,
+ fmt->scanline_pad,
+ fmt->depth,
+ fmt->bits_per_pixel,
+ 0,
+ setup->image_byte_order,
+ XCB_IMAGE_ORDER_LSB_FIRST,
+ image_data,
+ image_size,
+ image_data);
+}
+
+static int x_initialise(nsfb_t *nsfb)
+{
+ uint32_t mask;
+ uint32_t values[2];
+ xcb_size_hints_t *hints;
+ xstate_t *xstate = nsfb->frontend_priv;
+
+ if (xstate != NULL)
+ return -1; /* already initialised */
+
+ /* sanity check bpp. */
+ if ((nsfb->bpp != 32) && (nsfb->bpp != 16) && (nsfb->bpp != 8))
+ return -1;
+
+ xstate = calloc(1, sizeof(xstate_t));
+ if (xstate == NULL)
+ return -1; /* no memory */
+
+ /* open connection with the server */
+ xstate->connection = xcb_connect (NULL, NULL);
+ if (xstate->connection == NULL) {
+ fprintf(stderr, "Unable to open display\n");
+ free(xstate);
+ }
+
+ /* get screen */
+ xstate->screen = xcb_setup_roots_iterator(xcb_get_setup(xstate->connection)).data;
+
+ /* create image */
+ xstate->image = create_image(xstate->connection, nsfb->width, nsfb->height, nsfb->bpp);
+ if (xstate->image == NULL) {
+ fprintf(stderr, "Unable to create image\n");
+ free(xstate);
+ xcb_disconnect(xstate->connection);
+ return -1;
+ }
+
+ /* ensure plotting information is stored */
+ nsfb->frontend_priv = xstate;
+ nsfb->ptr = xstate->image->data;
+ nsfb->linelen = xstate->image->stride;
+
+ /* create window */
+ mask = XCB_CW_BACK_PIXEL | XCB_CW_EVENT_MASK;
+ values[0] = xstate->screen->white_pixel;
+ values[1] = XCB_EVENT_MASK_EXPOSURE |
+ XCB_EVENT_MASK_KEY_PRESS |
+ XCB_EVENT_MASK_BUTTON_PRESS |
+ XCB_EVENT_MASK_POINTER_MOTION;
+
+ xstate->window = xcb_generate_id(xstate->connection);
+ xcb_create_window (xstate->connection,
+ XCB_COPY_FROM_PARENT,
+ xstate->window,
+ xstate->screen->root,
+ 10, 10, xstate->image->width, xstate->image->height, 1,
+ XCB_WINDOW_CLASS_INPUT_OUTPUT,
+ xstate->screen->root_visual,
+ mask, values);
+ /* set size hits on window */
+ hints = xcb_alloc_size_hints();
+ xcb_size_hints_set_max_size(hints, xstate->image->width, xstate->image->height);
+ xcb_size_hints_set_min_size(hints, xstate->image->width, xstate->image->height);
+ xcb_set_wm_size_hints(xstate->connection, xstate->window, WM_NORMAL_HINTS, hints);
+ xcb_free_size_hints(hints);
+
+ /* create backing pixmap */
+ xstate->pmap = xcb_generate_id(xstate->connection);
+ xcb_create_pixmap(xstate->connection, 24, xstate->pmap, xstate->window, xstate->image->width, xstate->image->height);
+
+ /* create pixmap plot gc */
+ mask = XCB_GC_FOREGROUND | XCB_GC_BACKGROUND;
+ values[0] = xstate->screen->black_pixel;
+ values[1] = 0xffffff;
+
+ xstate->gc = xcb_generate_id (xstate->connection);
+ xcb_create_gc(xstate->connection, xstate->gc, xstate->pmap, mask, values);
+
+ /* put the image into the pixmap */
+ xcb_image_put(xstate->connection, xstate->pmap, xstate->gc, xstate->image, 0, 0, 0);
+
+ /* if (nsfb->bpp == 8)
+ set_palette(nsfb);
+ */
+
+ /* show the window */
+ xcb_map_window (xstate->connection, xstate->window);
+ xcb_flush(xstate->connection);
+
+ return 0;
+}
+
+static int x_finalise(nsfb_t *nsfb)
+{
+ xstate_t *xstate = nsfb->frontend_priv;
+ if (xstate == NULL)
+ return 0;
+
+ /* free pixmap */
+ xcb_free_pixmap(xstate->connection, xstate->pmap);
+
+ /* close connection to server */
+ xcb_disconnect(xstate->connection);
+
+ return 0;
+}
+
+static bool x_input(nsfb_t *nsfb, nsfb_event_t *event, int timeout)
+{
+ xcb_generic_event_t *e;
+ xcb_expose_event_t *ee;
+ xcb_motion_notify_event_t *emn;
+ xstate_t *xstate = nsfb->frontend_priv;
+
+ if (xstate == NULL)
+ return false;
+
+ if (timeout < 0)
+ e = xcb_wait_for_event(xstate->connection);
+ else
+ e = xcb_poll_for_event(xstate->connection);
+
+ /* Do nothing if there was no event */
+ if (e == NULL)
+ return false;
+
+ /* expose event is special and is not handled with the other events */
+ if (e->response_type == XCB_EXPOSE) {
+ ee = (xcb_expose_event_t *)e;
+ xcb_copy_area(xstate->connection,
+ xstate->pmap,
+ xstate->window,
+ xstate->gc,
+ ee->x, ee->y,
+ ee->x, ee->y,
+ ee->width, ee->height);
+ xcb_flush (xstate->connection);
+ return false;
+ }
+
+ event->type = NSFB_EVENT_NONE;
+
+
+ switch (e->response_type) {
+ case XCB_MOTION_NOTIFY:
+ emn = (xcb_motion_notify_event_t *)e;
+ event->type = NSFB_EVENT_MOVE_ABSOLUTE;
+ event->value.vector.x = emn->event_x;
+ event->value.vector.y = emn->event_y;
+ event->value.vector.z = 0;
+ break;
+ }
+ /*
+ switch (sdlevent.type) {
+ case X_KEYDOWN:
+ event->type = NSFB_EVENT_KEY_DOWN;
+ event->value.keycode = x_nsfb_map[sdlevent.key.keysym.sym];
+ break;
+
+ case X_KEYUP:
+ event->type = NSFB_EVENT_KEY_UP;
+ event->value.keycode = x_nsfb_map[sdlevent.key.keysym.sym];
+ break;
+
+ case X_MOUSEBUTTONDOWN:
+ event->type = NSFB_EVENT_KEY_DOWN;
+
+ switch (sdlevent.button.button) {
+
+ case X_BUTTON_LEFT:
+ event->value.keycode = NSFB_KEY_MOUSE_1;
+ break;
+
+ case X_BUTTON_MIDDLE:
+ event->value.keycode = NSFB_KEY_MOUSE_2;
+ break;
+
+ case X_BUTTON_RIGHT:
+ event->value.keycode = NSFB_KEY_MOUSE_3;
+ break;
+
+ case X_BUTTON_WHEELUP:
+ event->value.keycode = NSFB_KEY_MOUSE_4;
+ break;
+
+ case X_BUTTON_WHEELDOWN:
+ event->value.keycode = NSFB_KEY_MOUSE_5;
+ break;
+ }
+ break;
+
+ case X_MOUSEBUTTONUP:
+ event->type = NSFB_EVENT_KEY_UP;
+
+ switch (sdlevent.button.button) {
+
+ case X_BUTTON_LEFT:
+ event->value.keycode = NSFB_KEY_MOUSE_1;
+ break;
+
+ case X_BUTTON_MIDDLE:
+ event->value.keycode = NSFB_KEY_MOUSE_2;
+ break;
+
+ case X_BUTTON_RIGHT:
+ event->value.keycode = NSFB_KEY_MOUSE_3;
+ break;
+
+ case X_BUTTON_WHEELUP:
+ event->value.keycode = NSFB_KEY_MOUSE_4;
+ break;
+
+ case X_BUTTON_WHEELDOWN:
+ event->value.keycode = NSFB_KEY_MOUSE_5;
+ break;
+ }
+ break;
+
+ case X_MOUSEMOTION:
+ event->type = NSFB_EVENT_MOVE_ABSOLUTE;
+ event->value.vector.x = sdlevent.motion.x;
+ event->value.vector.y = sdlevent.motion.y;
+ event->value.vector.z = 0;
+ break;
+
+ case X_QUIT:
+ event->type = NSFB_EVENT_CONTROL;
+ event->value.controlcode = NSFB_CONTROL_QUIT;
+ break;
+
+ }
+ */
+ return true;
+}
+
+static int x_claim(nsfb_t *nsfb, nsfb_bbox_t *box)
+{
+ struct nsfb_cursor_s *cursor = nsfb->cursor;
+
+ if ((cursor != NULL) &&
+ (cursor->plotted == true) &&
+ (nsfb_plot_bbox_intersect(box, &cursor->loc))) {
+ nsfb_cursor_clear(nsfb, cursor);
+ }
+ return 0;
+}
+
+static int
+x_cursor(nsfb_t *nsfb, struct nsfb_cursor_s *cursor)
+{
+ xstate_t *xstate = nsfb->frontend_priv;
+ nsfb_bbox_t redraw;
+ nsfb_bbox_t fbarea;
+
+ if ((cursor != NULL) && (cursor->plotted == true)) {
+
+ nsfb_plot_add_rect(&cursor->savloc, &cursor->loc, &redraw);
+
+ /* screen area */
+ fbarea.x0 = 0;
+ fbarea.y0 = 0;
+ fbarea.x1 = nsfb->width;
+ fbarea.y1 = nsfb->height;
+
+ nsfb_plot_clip(&fbarea, &redraw);
+
+ nsfb_cursor_clear(nsfb, cursor);
+
+ nsfb_cursor_plot(nsfb, cursor);
+
+ /* TODO: This is hediously ineficient - should keep the pointer image
+ * as a pixmap and plot server side
+ */
+ xcb_image_put(xstate->connection, xstate->pmap, xstate->gc, xstate->image, 0, 0, 0);
+ xcb_copy_area(xstate->connection,
+ xstate->pmap,
+ xstate->window,
+ xstate->gc,
+ redraw.x0,
+ redraw.y0,
+ redraw.x0,
+ redraw.y0,
+ redraw.x1 - redraw.x0,
+ redraw.y1 - redraw.y0);
+
+
+ }
+ return true;
+}
+
+
+static int x_update(nsfb_t *nsfb, nsfb_bbox_t *box)
+{
+ xstate_t *xstate = nsfb->frontend_priv;
+ struct nsfb_cursor_s *cursor = nsfb->cursor;
+
+ if ((cursor != NULL) &&
+ (cursor->plotted == false)) {
+ nsfb_cursor_plot(nsfb, cursor);
+ }
+
+ xcb_image_put(xstate->connection, xstate->pmap, xstate->gc, xstate->image, 0, 0, 0);
+ xcb_copy_area(xstate->connection,
+ xstate->pmap,
+ xstate->window,
+ xstate->gc,
+ box->x0,
+ box->y0,
+ box->x0,
+ box->y0,
+ box->x1 - box->x0,
+ box->y1 - box->y0);
+
+ return 0;
+}
+
+const nsfb_frontend_rtns_t x_rtns = {
+ .initialise = x_initialise,
+ .finalise = x_finalise,
+ .input = x_input,
+ .claim = x_claim,
+ .update = x_update,
+ .cursor = x_cursor,
+ .geometry = x_set_geometry,
+};
+
+NSFB_FRONTEND_DEF(x, NSFB_FRONTEND_X, &x_rtns)