diff options
author | Vincent Sanders <vince@netsurf-browser.org> | 2009-06-02 13:01:45 +0000 |
---|---|---|
committer | Vincent Sanders <vince@netsurf-browser.org> | 2009-06-02 13:01:45 +0000 |
commit | 30edb722902dff842b5b9544f9b43846b93adc92 (patch) | |
tree | ade17d9dc0ec2985a82a767134d2f22c354d181b /src | |
parent | 3d5b21e1473dbdee6c3df66d9ba2a9d657f1b486 (diff) | |
download | libnsfb-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.c | 2 | ||||
-rw-r--r-- | src/32bpp_plotters.c | 28 | ||||
-rw-r--r-- | src/8bpp_plotters.c | 2 | ||||
-rw-r--r-- | src/Makefile | 2 | ||||
-rw-r--r-- | src/cursor.c | 94 | ||||
-rw-r--r-- | src/frontend.c | 10 | ||||
-rw-r--r-- | src/frontend_sdl.c | 69 | ||||
-rw-r--r-- | src/plot.c | 8 | ||||
-rw-r--r-- | src/plot_util.c | 46 |
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, }; @@ -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; +} |