summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorVincent Sanders <vince@netsurf-browser.org>2009-06-02 13:01:45 +0000
committerVincent Sanders <vince@netsurf-browser.org>2009-06-02 13:01:45 +0000
commit30edb722902dff842b5b9544f9b43846b93adc92 (patch)
treeade17d9dc0ec2985a82a767134d2f22c354d181b /src
parent3d5b21e1473dbdee6c3df66d9ba2a9d657f1b486 (diff)
downloadlibnsfb-30edb722902dff842b5b9544f9b43846b93adc92.tar.gz
libnsfb-30edb722902dff842b5b9544f9b43846b93adc92.tar.bz2
add cursor support
svn path=/trunk/libnsfb/; revision=7687
Diffstat (limited to 'src')
-rw-r--r--src/16bpp_plotters.c2
-rw-r--r--src/32bpp_plotters.c28
-rw-r--r--src/8bpp_plotters.c2
-rw-r--r--src/Makefile2
-rw-r--r--src/cursor.c94
-rw-r--r--src/frontend.c10
-rw-r--r--src/frontend_sdl.c69
-rw-r--r--src/plot.c8
-rw-r--r--src/plot_util.c46
9 files changed, 254 insertions, 7 deletions
diff --git a/src/16bpp_plotters.c b/src/16bpp_plotters.c
index 035a9a6..6497f91 100644
--- a/src/16bpp_plotters.c
+++ b/src/16bpp_plotters.c
@@ -325,7 +325,7 @@ glyph8(nsfb_t *nsfb,
static bool
bitmap(nsfb_t *nsfb,
- nsfb_bbox_t *loc,
+ const nsfb_bbox_t *loc,
const nsfb_colour_t *pixel,
int bmp_width,
int bmp_height,
diff --git a/src/32bpp_plotters.c b/src/32bpp_plotters.c
index 2456f58..232a000 100644
--- a/src/32bpp_plotters.c
+++ b/src/32bpp_plotters.c
@@ -322,7 +322,7 @@ glyph8(nsfb_t *nsfb,
static bool
bitmap(nsfb_t *nsfb,
- nsfb_bbox_t *loc,
+ const nsfb_bbox_t *loc,
const nsfb_colour_t *pixel,
int bmp_width,
int bmp_height,
@@ -356,8 +356,9 @@ bitmap(nsfb_t *nsfb,
clipped.x1 = x + width;
clipped.y1 = y + height;
- if (!nsfb_plot_clip_ctx(nsfb, &clipped))
+ if (!nsfb_plot_clip_ctx(nsfb, &clipped)) {
return true;
+ }
if (height > (clipped.y1 - clipped.y0))
height = (clipped.y1 - clipped.y0);
@@ -399,7 +400,29 @@ bitmap(nsfb_t *nsfb,
return true;
}
+static bool readrect(nsfb_t *nsfb, nsfb_bbox_t *rect, nsfb_colour_t *buffer)
+{
+ uint32_t *pvideo;
+ int xloop, yloop;
+ int width;
+
+ if (!nsfb_plot_clip_ctx(nsfb, rect)) {
+ return true;
+ }
+
+ width = rect->x1 - rect->x0;
+
+ pvideo = get_xy_loc(nsfb, rect->x0, rect->y0);
+ for (yloop = rect->y0; yloop < rect->y1; yloop += 1) {
+ for (xloop = 0; xloop < width; xloop++) {
+ *buffer = pixel_to_colour(*(pvideo + xloop));
+ buffer++;
+ }
+ pvideo += (nsfb->linelen >> 2);
+ }
+ return true;
+}
const nsfb_plotter_fns_t _nsfb_32bpp_plotters = {
.line = line,
@@ -408,6 +431,7 @@ const nsfb_plotter_fns_t _nsfb_32bpp_plotters = {
.bitmap = bitmap,
.glyph8 = glyph8,
.glyph1 = glyph1,
+ .readrect = readrect,
};
/*
diff --git a/src/8bpp_plotters.c b/src/8bpp_plotters.c
index 40a06f9..307e4a7 100644
--- a/src/8bpp_plotters.c
+++ b/src/8bpp_plotters.c
@@ -300,7 +300,7 @@ glyph8(nsfb_t *nsfb,
static bool
bitmap(nsfb_t *nsfb,
- nsfb_bbox_t *loc,
+ const nsfb_bbox_t *loc,
const nsfb_colour_t *pixel,
int bmp_width,
int bmp_height,
diff --git a/src/Makefile b/src/Makefile
index 431abd9..af1c780 100644
--- a/src/Makefile
+++ b/src/Makefile
@@ -1,5 +1,5 @@
# Sources
-DIR_SOURCES := libnsfb.c frontend.c frontend_sdl.c frontend_linux.c frontend_vnc.c frontend_able.c frontend_ram.c plot.c legacy_plot.c plot_util.c plotters.c 32bpp_plotters.c 16bpp_plotters.c 8bpp_plotters.c
+DIR_SOURCES := libnsfb.c frontend.c frontend_sdl.c frontend_linux.c frontend_vnc.c frontend_able.c frontend_ram.c cursor.c plot.c legacy_plot.c plot_util.c plotters.c 32bpp_plotters.c 16bpp_plotters.c 8bpp_plotters.c
include build/makefiles/Makefile.subdir
diff --git a/src/cursor.c b/src/cursor.c
new file mode 100644
index 0000000..faa96b1
--- /dev/null
+++ b/src/cursor.c
@@ -0,0 +1,94 @@
+#include <stdbool.h>
+#include <stdlib.h>
+
+#include "libnsfb.h"
+#include "libnsfb_plot.h"
+#include "libnsfb_cursor.h"
+
+#include "nsfb.h"
+#include "cursor.h"
+#include "nsfb_plot.h"
+#include "frontend.h"
+
+
+bool nsfb_cursor_init(nsfb_t *nsfb)
+{
+ if (nsfb->cursor != NULL)
+ return false;
+
+ nsfb->cursor = calloc(1, sizeof(struct nsfb_cursor_s));
+ if (nsfb->cursor == NULL)
+ return false;
+
+ nsfb->cursor->loc.x0 = nsfb->width / 2;
+ nsfb->cursor->loc.y0 = nsfb->height / 2;
+ return true;
+}
+
+bool nsfb_cursor_set(nsfb_t *nsfb, const nsfb_colour_t *pixel, int bmp_width, int bmp_height, int bmp_stride)
+{
+ if (nsfb->cursor == NULL)
+ return false;
+
+ nsfb->cursor->pixel = pixel;
+ nsfb->cursor->bmp_width = bmp_width;
+ nsfb->cursor->bmp_height = bmp_height;
+ nsfb->cursor->bmp_stride = bmp_stride;
+ nsfb->cursor->loc.x1 = nsfb->cursor->loc.x0 + nsfb->cursor->bmp_width;
+ nsfb->cursor->loc.y1 = nsfb->cursor->loc.y0 + nsfb->cursor->bmp_height;
+
+ return nsfb->frontend_rtns->cursor(nsfb, nsfb->cursor);
+}
+
+bool nsfb_cursor_loc_set(nsfb_t *nsfb, const nsfb_bbox_t *loc)
+{
+ if (nsfb->cursor == NULL)
+ return false;
+
+ nsfb->cursor->loc = *loc;
+ nsfb->cursor->loc.x1 = nsfb->cursor->loc.x0 + nsfb->cursor->bmp_width;
+ nsfb->cursor->loc.y1 = nsfb->cursor->loc.y0 + nsfb->cursor->bmp_height;
+
+ return nsfb->frontend_rtns->cursor(nsfb, nsfb->cursor);
+}
+
+bool nsfb_cursor_loc_get(nsfb_t *nsfb, nsfb_bbox_t *loc)
+{
+ if (nsfb->cursor == NULL)
+ return false;
+
+ *loc = nsfb->cursor->loc;
+ return true;
+}
+
+/* documented in cursor.h */
+bool nsfb_cursor_plot(nsfb_t *nsfb, struct nsfb_cursor_s *cursor)
+{
+ int sav_size;
+
+ cursor->savloc = cursor->loc;
+
+ cursor->sav_width = cursor->savloc.x1 - cursor->savloc.x0;
+ cursor->sav_height = cursor->savloc.y1 - cursor->savloc.y0;
+
+ sav_size = cursor->sav_width * cursor->sav_height * sizeof(nsfb_colour_t);
+ if (cursor->sav_size < sav_size) {
+ cursor->sav = realloc(cursor->sav, sav_size);
+ cursor->sav_size = sav_size;
+ }
+
+ nsfb->plotter_fns->readrect(nsfb, &cursor->savloc, cursor->sav );
+ cursor->sav_width = cursor->savloc.x1 - cursor->savloc.x0;
+ cursor->sav_height = cursor->savloc.y1 - cursor->savloc.y0;
+
+ nsfb->plotter_fns->bitmap(nsfb,
+ &cursor->loc,
+ cursor->pixel,
+ cursor->bmp_width,
+ cursor->bmp_height,
+ cursor->bmp_stride,
+ true);
+ cursor->plotted = true;
+
+ return true;
+}
diff --git a/src/frontend.c b/src/frontend.c
index c53ba66..a071719 100644
--- a/src/frontend.c
+++ b/src/frontend.c
@@ -67,6 +67,13 @@ static int frontend_release(nsfb_t *nsfb, nsfb_bbox_t *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;
@@ -99,6 +106,9 @@ nsfb_frontend_rtns_t *nsfb_frontend_get_rtns(enum nsfb_frontend_e type)
if (rtns->release == NULL)
rtns->release = frontend_release;
+ if (rtns->cursor == NULL)
+ rtns->cursor = frontend_cursor;
+
break;
}
}
diff --git a/src/frontend_sdl.c b/src/frontend_sdl.c
index ca98199..f8837b5 100644
--- a/src/frontend_sdl.c
+++ b/src/frontend_sdl.c
@@ -11,9 +11,13 @@
#include "libnsfb.h"
#include "libnsfb_event.h"
+#include "libnsfb_plot_util.h"
+
#include "nsfb.h"
#include "frontend.h"
#include "plotters.h"
+#include "nsfb_plot.h"
+#include "cursor.h"
enum nsfb_key_code_e sdl_nsfb_map[] = {
NSFB_KEY_UNKNOWN,
@@ -437,7 +441,7 @@ static bool sdl_input(nsfb_t *nsfb, nsfb_event_t *event, int timeout)
int got_event;
SDL_Event sdlevent;
- nsfb=nsfb; /* unused */
+ nsfb = nsfb; /* unused */
if (timeout < 0)
got_event = SDL_WaitEvent(&sdlevent);
@@ -532,9 +536,70 @@ static bool sdl_input(nsfb_t *nsfb, nsfb_event_t *event, int timeout)
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->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 sdl_cursor(nsfb_t *nsfb, struct nsfb_cursor_s *cursor)
+{
+ SDL_Surface *sdl_screen = nsfb->frontend_priv;
+ nsfb_bbox_t sclip;
+ nsfb_bbox_t redraw;
+
+ if ((cursor != NULL) && (cursor->plotted == true)) {
+ sclip = nsfb->clip;
+
+ nsfb_plot_add_rect(&cursor->savloc, &cursor->loc, &redraw);
+
+ nsfb->plotter_fns->set_clip(nsfb, &redraw);
+
+ nsfb->plotter_fns->bitmap(nsfb,
+ &cursor->savloc,
+ cursor->sav,
+ cursor->sav_width,
+ cursor->sav_height,
+ cursor->sav_width,
+ false);
+
+ nsfb_cursor_plot(nsfb, cursor);
+
+ SDL_UpdateRect(sdl_screen,
+ redraw.x0,
+ redraw.y0,
+ redraw.x1 - redraw.x0,
+ redraw.y1 - redraw.y0);
+
+
+ nsfb->clip = sclip;
+ }
+ return true;
+}
+
+
static int sdl_release(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,
@@ -549,7 +614,9 @@ const nsfb_frontend_rtns_t sdl_rtns = {
.initialise = sdl_initialise,
.finalise = sdl_finalise,
.input = sdl_input,
+ .claim = sdl_claim,
.release = sdl_release,
+ .cursor = sdl_cursor,
.geometry = sdl_set_geometry,
};
diff --git a/src/plot.c b/src/plot.c
index 440a445..b79267a 100644
--- a/src/plot.c
+++ b/src/plot.c
@@ -115,7 +115,7 @@ bool nsfb_plot_copy(nsfb_t *nsfb, int srcx, int srcy, int width, int height, int
return nsfb->plotter_fns->copy(nsfb, srcx, srcy, width, height, dstx, dsty);
}
-bool nsfb_plot_bitmap(nsfb_t *nsfb, nsfb_bbox_t *loc, const nsfb_colour_t *pixel, int bmp_width, int bmp_height, int bmp_stride, bool alpha)
+bool nsfb_plot_bitmap(nsfb_t *nsfb, const nsfb_bbox_t *loc, const nsfb_colour_t *pixel, int bmp_width, int bmp_height, int bmp_stride, bool alpha)
{
return nsfb->plotter_fns->bitmap(nsfb, loc, pixel, bmp_width, bmp_height, bmp_stride, alpha);
}
@@ -134,3 +134,9 @@ bool nsfb_plot_glyph1(nsfb_t *nsfb, nsfb_bbox_t *loc, const uint8_t *pixel, int
{
return nsfb->plotter_fns->glyph1(nsfb, loc, pixel, pitch, c);
}
+
+/* read a rectangle from screen into buffer */
+bool nsfb_plot_readrect(nsfb_t *nsfb, nsfb_bbox_t *rect, nsfb_colour_t *buffer)
+{
+ return nsfb->plotter_fns->readrect(nsfb, rect, buffer);
+}
diff --git a/src/plot_util.c b/src/plot_util.c
index ae1f548..a126021 100644
--- a/src/plot_util.c
+++ b/src/plot_util.c
@@ -149,3 +149,49 @@ bool nsfb_plot_clip_line_ctx(nsfb_t *nsfb, nsfb_bbox_t * restrict line)
return nsfb_plot_clip_line(&nsfb->clip, line);
}
+/* documented in libnsfb_plot_util.h */
+bool nsfb_plot_add_rect(const nsfb_bbox_t *box1, const nsfb_bbox_t *box2, nsfb_bbox_t *result)
+{
+ /* lower x coordinate */
+ if (box1->x0 < box2->x0)
+ result->x0 = box1->x0;
+ else
+ result->x0 = box2->x0;
+
+ /* lower y coordinate */
+ if (box1->y0 < box2->y0)
+ result->y0 = box1->y0;
+ else
+ result->y0 = box2->y0;
+
+ /* upper x coordinate */
+ if (box1->x1 > box2->x1)
+ result->x1 = box1->x1;
+ else
+ result->x1 = box2->x1;
+
+ /* upper y coordinate */
+ if (box1->y1 > box2->y1)
+ result->y1 = box1->y1;
+ else
+ result->y1 = box2->y1;
+
+ return true;
+}
+
+bool nsfb_plot_bbox_intersect(const nsfb_bbox_t *box1, const nsfb_bbox_t *box2)
+{
+ if (box2->x1 < box1->x0)
+ return false;
+
+ if (box2->y1 < box1->y0)
+ return false;
+
+ if (box2->x0 > box1->x1)
+ return false;
+
+ if (box2->y0 > box1->y1)
+ return false;
+
+ return true;
+}