From 36b5deef09d0390e6d1a7bac9362bb8bc0008b0b Mon Sep 17 00:00:00 2001 From: Vincent Sanders Date: Sun, 28 Jun 2009 18:32:47 +0000 Subject: Make framebuffer port use libnsfb svn path=/trunk/netsurf/; revision=8122 --- Docs/BUILDING-Framebuffer | 105 ++- Makefile | 111 +-- Makefile.resources | 10 +- Makefile.sources | 26 +- desktop/options.c | 4 +- framebuffer/bitmap.c | 259 +++++++ framebuffer/bitmap.h | 33 + framebuffer/convert_image.c | 307 +++++++++ framebuffer/fb_16bpp_plotters.c | 569 ---------------- framebuffer/fb_1bpp_plotters.c | 266 -------- framebuffer/fb_32bpp_plotters.c | 613 ----------------- framebuffer/fb_8bpp_plotters.c | 463 ------------- framebuffer/fb_bitmap.c | 259 ------- framebuffer/fb_bitmap.h | 33 - framebuffer/fb_convert_image.c | 307 --------- framebuffer/fb_cursor.c | 236 ------- framebuffer/fb_cursor.h | 38 -- framebuffer/fb_filetype.c | 55 -- framebuffer/fb_findfile.c | 106 --- framebuffer/fb_findfile.h | 26 - framebuffer/fb_font.h | 57 -- framebuffer/fb_font_freetype.c | 476 ------------- framebuffer/fb_font_internal.c | 141 ---- framebuffer/fb_font_internal.h | 39 -- framebuffer/fb_frontend.h | 28 - framebuffer/fb_frontend_ablefb.c | 310 --------- framebuffer/fb_frontend_dummy.c | 84 --- framebuffer/fb_frontend_linuxfb.c | 775 --------------------- framebuffer/fb_frontend_sdl.c | 252 ------- framebuffer/fb_frontend_vnc.c | 231 ------- framebuffer/fb_gui.c | 1126 ------------------------------- framebuffer/fb_gui.h | 72 -- framebuffer/fb_image_data.h | 52 -- framebuffer/fb_options.h | 68 -- framebuffer/fb_plotters.c | 495 -------------- framebuffer/fb_plotters.h | 88 --- framebuffer/fb_schedule.c | 202 ------ framebuffer/fb_schedule.h | 24 - framebuffer/fb_tk.c | 1180 -------------------------------- framebuffer/fb_tk.h | 212 ------ framebuffer/fbtk.c | 1337 +++++++++++++++++++++++++++++++++++++ framebuffer/fbtk.h | 216 ++++++ framebuffer/filetype.c | 55 ++ framebuffer/findfile.c | 106 +++ framebuffer/findfile.h | 26 + framebuffer/font.h | 34 + framebuffer/font_8x16.c | 2 +- framebuffer/font_freetype.c | 477 +++++++++++++ framebuffer/font_freetype.h | 30 + framebuffer/font_internal.c | 141 ++++ framebuffer/font_internal.h | 39 ++ framebuffer/framebuffer.c | 299 +++++++++ framebuffer/framebuffer.h | 5 + framebuffer/gui.c | 1274 +++++++++++++++++++++++++++++++++++ framebuffer/gui.h | 67 ++ framebuffer/image_data.h | 52 ++ framebuffer/options.h | 68 ++ framebuffer/schedule.c | 202 ++++++ framebuffer/schedule.h | 24 + nsfb | 25 - 60 files changed, 5131 insertions(+), 9086 deletions(-) create mode 100644 framebuffer/bitmap.c create mode 100644 framebuffer/bitmap.h create mode 100644 framebuffer/convert_image.c delete mode 100644 framebuffer/fb_16bpp_plotters.c delete mode 100644 framebuffer/fb_1bpp_plotters.c delete mode 100644 framebuffer/fb_32bpp_plotters.c delete mode 100644 framebuffer/fb_8bpp_plotters.c delete mode 100644 framebuffer/fb_bitmap.c delete mode 100644 framebuffer/fb_bitmap.h delete mode 100644 framebuffer/fb_convert_image.c delete mode 100644 framebuffer/fb_cursor.c delete mode 100644 framebuffer/fb_cursor.h delete mode 100644 framebuffer/fb_filetype.c delete mode 100644 framebuffer/fb_findfile.c delete mode 100644 framebuffer/fb_findfile.h delete mode 100644 framebuffer/fb_font.h delete mode 100644 framebuffer/fb_font_freetype.c delete mode 100644 framebuffer/fb_font_internal.c delete mode 100644 framebuffer/fb_font_internal.h delete mode 100644 framebuffer/fb_frontend.h delete mode 100644 framebuffer/fb_frontend_ablefb.c delete mode 100644 framebuffer/fb_frontend_dummy.c delete mode 100644 framebuffer/fb_frontend_linuxfb.c delete mode 100644 framebuffer/fb_frontend_sdl.c delete mode 100644 framebuffer/fb_frontend_vnc.c delete mode 100644 framebuffer/fb_gui.c delete mode 100644 framebuffer/fb_gui.h delete mode 100644 framebuffer/fb_image_data.h delete mode 100644 framebuffer/fb_options.h delete mode 100644 framebuffer/fb_plotters.c delete mode 100644 framebuffer/fb_plotters.h delete mode 100644 framebuffer/fb_schedule.c delete mode 100644 framebuffer/fb_schedule.h delete mode 100644 framebuffer/fb_tk.c delete mode 100644 framebuffer/fb_tk.h create mode 100644 framebuffer/fbtk.c create mode 100644 framebuffer/fbtk.h create mode 100644 framebuffer/filetype.c create mode 100644 framebuffer/findfile.c create mode 100644 framebuffer/findfile.h create mode 100644 framebuffer/font.h create mode 100644 framebuffer/font_freetype.c create mode 100644 framebuffer/font_freetype.h create mode 100644 framebuffer/font_internal.c create mode 100644 framebuffer/font_internal.h create mode 100644 framebuffer/framebuffer.c create mode 100644 framebuffer/framebuffer.h create mode 100644 framebuffer/gui.c create mode 100644 framebuffer/gui.h create mode 100644 framebuffer/image_data.h create mode 100644 framebuffer/options.h create mode 100644 framebuffer/schedule.c create mode 100644 framebuffer/schedule.h delete mode 100755 nsfb diff --git a/Docs/BUILDING-Framebuffer b/Docs/BUILDING-Framebuffer index 540dff9da..8dd0b0007 100644 --- a/Docs/BUILDING-Framebuffer +++ b/Docs/BUILDING-Framebuffer @@ -17,11 +17,6 @@ Others cannot be automatically detected from the Makefile, so you will either need to install the dependencies, or set them to NO. - One option it is vitally important to set is the Framebuffer ports - frontend type by setting the NETSURF_FB_FRONTEND variable. The port - can run on a number of simple framebuffer implementations including - the linux framebuffer and an SDL surface. - You should then obtain NetSurf's dependencies, keeping in mind which options you have enabled in the configuration file. See the next section for specifics. @@ -30,58 +25,19 @@ $ make TARGET=framebuffer - If that produces errors, you probably don't have some of NetSurf's build - dependencies installed. See "Obtaining NetSurf's dependencies" below. Or turn - off the complaining features in your Makefile.config. You may need to "make clean" - before attempting to build after installing the dependencies. + If that produces errors, you probably don't have some of NetSurf's + build dependencies installed. See "Obtaining NetSurf's dependencies" + below. Or turn off the complaining features in your + Makefile.config. You may need to "make clean" before attempting to + build after installing the dependencies. - Run NetSurf by executing the "nsfb" shell script: + Run NetSurf by executing the "nsfb" program: $ ./nsfb - This script makes it easy to run the nsfb binary from the build tree. It - sets up some environment variables which enable NetSurf to find its - resources. - - Selecting a frontend and appropriate options -============================================== + The NETSURFRES environment variable may require setting to enable + NetSurf to find its resources. - The framebuffer port can operate on a number of frontends. A - frontend in this context is simply the combination of input and - output devices. A frontend output device may be any linearly mapped - area of memory. The framebuffer may be treated as values at 32, 16 - or 8 bits per pixel. The input device is typically selected to - complement the output device and is completely specific to the - frontend. - - There are several configuration options which may influence the - framebuffer frontends. These are: - - fb_refresh - The refresh rate (for physical displays) - fb_depth - The depth (in bits per pixel) of the framebuffer - window_width - The width of the framebuffer - window_height - The height of the framebuffer - - The defaults are for 800 by 600 pixels at 16bpp and 70Hz refresh rate. - - There are currently four frontends: - - linux Output to a Linux framebuffer and input from linux input - event device nodes. The output device is specified with - the fb_device option which defaults to /dev/fb0 . The - input nodes are searched for in the path specified by the - fb_input_devpath option which defaults to /dev/input/ - - sdl The SDL frontend is a straightforward port to the SDL library - which abstracts the input and output from the application and has - been targeted to several operating systems. - - vnc The VNC server frontend uses the libvncserver library to - provide a straightforward unsecured VNC server, multiple - clients may connect. - - able Output to the Simtec ABLE bootloader framebuffer and input - from its input device node. Fonts @@ -138,10 +94,10 @@ and prior the following patch is necessary. -Index: framebuffer/fb_font_freetype.c +Index: framebuffer/font_freetype.c =================================================================== ---- framebuffer/fb_font_freetype.c (revision 6750) -+++ framebuffer/fb_font_freetype.c (working copy) +--- framebuffer/font_freetype.c (revision 6750) ++++ framebuffer/font_freetype.c (working copy) @@ -311,6 +311,7 @@ FT_Glyph glyph; FT_Error error; @@ -184,6 +140,34 @@ Index: framebuffer/fb_font_freetype.c } + Selecting a frontend and appropriate options +============================================== + + The framebuffer port interfaces to its input and output devices + using the NetSurf Framebuffer library (libnsfb). This library + provides an abstraction layer to input and output devices. + + The frontend used by libnsfb is selected by using the -fe switch to + netsurf when executed. A frontend in this context is simply the + combination of input and output devices. + + A frontend output device may be any linearly mapped area of + memory. The framebuffer may be treated as values at 32, 16 or 8 bits + per pixel. The input device is typically selected to complement the + output device and is completely specific to the frontend. + + There are several configuration options which may influence the + framebuffer frontends. These are: + + fb_refresh - The refresh rate (for physical displays) + fb_depth - The depth (in bits per pixel) of the framebuffer + window_width - The width of the framebuffer + window_height - The height of the framebuffer + + The defaults are for 800 by 600 pixels at 16bpp and 70Hz refresh rate. + + The documentation of libnsfb should be consulted for futher + information about supported frontends and their configuration. Obtaining NetSurf's build dependencies ======================================== @@ -223,6 +207,17 @@ Index: framebuffer/fb_font_freetype.c configured to use libpng instead of libmng. If you wish to do this, install the libpng development package instead. + Libnsfb +--------- + + The NetSurf framebuffer library provides the underlying interface to + the underlying input and output devices. + You can check it out from svn://svn.netsurf-browser.org/trunk/libnsfb + + To build and install it: + + $ sudo make install + Libnsbmp ---------- diff --git a/Makefile b/Makefile index 6d214ce1b..200c1ae3b 100644 --- a/Makefile +++ b/Makefile @@ -473,115 +473,40 @@ endif # ---------------------------------------------------------------------------- ifeq ($(TARGET),framebuffer) + $(eval $(call feature_enabled,MNG,-DWITH_MNG,-lmng,PNG support)) $(eval $(call feature_enabled,PNG,-DWITH_PNG,-lpng,PNG support)) + ifeq ($(NETSURF_FB_FONTLIB),freetype) - CFLAGS += -DFB_USE_FREETYPE $(shell freetype-config --cflags) - LDFLAGS += $(shell freetype-config --libs) + CFLAGS += -DFB_USE_FREETYPE $(shell freetype-config --cflags) + LDFLAGS += $(shell freetype-config --libs) endif # define additional CFLAGS and LDFLAGS requirements for pkg-configed libs here NETSURF_FEATURE_RSVG_CFLAGS := -DWITH_RSVG NETSURF_FEATURE_ROSPRITE_CFLAGS := -DWITH_NSSPRITE + NETSURF_FEATURE_HUBBUB_CFLAGS := -DWITH_HUBBUB NETSURF_FEATURE_BMP_CFLAGS := -DWITH_BMP NETSURF_FEATURE_GIF_CFLAGS := -DWITH_GIF - CFLAGS += '-DNETSURF_FB_RESPATH="$(NETSURF_FB_RESPATH_$(NETSURF_FB_FRONTEND))"' - CFLAGS += -Dnsfb - - ifeq ($(NETSURF_FB_FRONTEND),linux) - $(eval $(call pkg_config_find_and_add,RSVG,librsvg-2.0,SVG rendering)) - $(eval $(call pkg_config_find_and_add,ROSPRITE,librosprite,RISC OS sprite rendering)) - $(eval $(call pkg_config_find_and_add,BMP,libnsbmp,NetSurf BMP decoder)) - $(eval $(call pkg_config_find_and_add,GIF,libnsgif,NetSurf GIF decoder)) - - - CFLAGS += -std=c99 -g -I. -Dsmall $(WARNFLAGS) \ - $(shell $(PKG_CONFIG) --cflags libhubbub libcurl openssl) \ - $(shell xml2-config --cflags) \ - -D_BSD_SOURCE \ - -D_XOPEN_SOURCE=600 \ - -D_POSIX_C_SOURCE=200112L - - LDFLAGS += -lxml2 -lz -ljpeg -lcurl -lm - LDFLAGS += $(shell $(PKG_CONFIG) --libs libxml-2.0 libcurl libhubbub openssl) - SUBTARGET := -linux - endif - - ifeq ($(NETSURF_FB_FRONTEND),able) - $(eval $(call feature_enabled,GIF,-DWITH_GIF,-lnsgif,NetSurf GIF decoder)) - CC=arm-able-gcc - CFLAGS += -std=c99 -I. -I/usr/lib/able/include -Dsmall $(WARNFLAGS) - LDFLAGS += -lxml2 -lz -ljpeg -lcurl -lm -lhubbub -lparserutils - SUBTARGET := -able - endif - - ifeq ($(NETSURF_FB_FRONTEND),dummy) - $(eval $(call pkg_config_find_and_add,RSVG,librsvg-2.0,SVG rendering)) - $(eval $(call pkg_config_find_and_add,ROSPRITE,librosprite,RISC OS sprite rendering)) - $(eval $(call pkg_config_find_and_add,BMP,libnsbmp,NetSurf BMP decoder)) - $(eval $(call pkg_config_find_and_add,GIF,libnsgif,NetSurf GIF decoder)) - - - CFLAGS += -std=c99 -g -I. $(WARNFLAGS) \ - $(shell $(PKG_CONFIG) --cflags libhubbub libcurl openssl) \ - $(shell xml2-config --cflags) \ - -D_BSD_SOURCE \ - -D_XOPEN_SOURCE=600 \ - -D_POSIX_C_SOURCE=200112L - - LDFLAGS += -lxml2 -lz -ljpeg -lcurl -lm - LDFLAGS += $(shell $(PKG_CONFIG) --libs libxml-2.0 libcurl openssl) - LDFLAGS += $(shell $(PKG_CONFIG) --libs libhubbub) - SUBTARGET := -dummy - endif - - ifeq ($(NETSURF_FB_FRONTEND),sdl) - $(eval $(call pkg_config_find_and_add,RSVG,librsvg-2.0,SVG rendering)) - $(eval $(call pkg_config_find_and_add,ROSPRITE,librosprite,RISC OS sprite rendering)) - $(eval $(call pkg_config_find_and_add,BMP,libnsbmp,NetSurf BMP decoder)) - $(eval $(call pkg_config_find_and_add,GIF,libnsgif,NetSurf GIF decoder)) -# $(eval $(call pkg_config_find_and_add,SDL,libSDL,SDL Library)) - - - CFLAGS += -std=c99 -g -I. $(WARNFLAGS) \ - $(shell $(PKG_CONFIG) --cflags libhubbub libcurl openssl) \ - $(shell xml2-config --cflags) \ - -D_BSD_SOURCE \ - -D_XOPEN_SOURCE=600 \ - -D_POSIX_C_SOURCE=200112L - - LDFLAGS += -lxml2 -lz -ljpeg -lcurl -lm -lSDL - LDFLAGS += $(shell $(PKG_CONFIG) --libs libxml-2.0 libcurl openssl) - LDFLAGS += $(shell $(PKG_CONFIG) --libs libhubbub) - SUBTARGET := -sdl - endif - - ifeq ($(NETSURF_FB_FRONTEND),vnc) - $(eval $(call pkg_config_find_and_add,RSVG,librsvg-2.0,SVG rendering)) - $(eval $(call pkg_config_find_and_add,ROSPRITE,librosprite,RISC OS sprite rendering)) - $(eval $(call pkg_config_find_and_add,BMP,libnsbmp,NetSurf BMP decoder)) - $(eval $(call pkg_config_find_and_add,GIF,libnsgif,NetSurf GIF decoder)) -# $(eval $(call pkg_config_find_and_add,VNCSERVER,libvncserver,VNC server)) + CFLAGS += -Dnsframebuffer '-DNETSURF_FB_RESPATH="$(NETSURF_FB_RESPATH_$(NETSURF_FB_FRONTEND))"' + $(eval $(call pkg_config_find_and_add,ROSPRITE,librosprite,RISC OS sprite rendering)) + $(eval $(call pkg_config_find_and_add,BMP,libnsbmp,NetSurf BMP decoder)) + $(eval $(call pkg_config_find_and_add,GIF,libnsgif,NetSurf GIF decoder)) - CFLAGS += -std=c99 -g -I. $(WARNFLAGS) \ - $(shell $(PKG_CONFIG) --cflags libhubbub libcurl openssl) \ - $(shell xml2-config --cflags) \ - -D_BSD_SOURCE \ - -D_XOPEN_SOURCE=600 \ - -D_POSIX_C_SOURCE=200112L - LDFLAGS += -lxml2 -lz -ljpeg -lcurl -lm -lvncserver - LDFLAGS += $(shell $(PKG_CONFIG) --libs libxml-2.0 libcurl openssl) - LDFLAGS += $(shell $(PKG_CONFIG) --libs libhubbub) - SUBTARGET := -vnc - endif + CFLAGS += -std=c99 -g -I. -Dsmall $(WARNFLAGS) \ + -D_BSD_SOURCE \ + -D_XOPEN_SOURCE=600 \ + -D_POSIX_C_SOURCE=200112L \ + $(shell $(PKG_CONFIG) --cflags libnsfb-0) \ + $(shell $(PKG_CONFIG) --cflags libhubbub libcurl openssl) \ + $(shell xml2-config --cflags) - ifeq ($(SUBTARGET),) - $(error Unable to proceed, no FB subtarget chosen.) - endif + LDFLAGS += -Wl,--whole-archive $(shell $(PKG_CONFIG) --libs libnsfb) -Wl,--no-whole-archive + LDFLAGS += $(shell $(PKG_CONFIG) --libs libxml-2.0 libcurl libhubbub openssl) endif diff --git a/Makefile.resources b/Makefile.resources index f5bfde9bf..fec2c73f3 100644 --- a/Makefile.resources +++ b/Makefile.resources @@ -8,11 +8,11 @@ ifeq ($(TARGET),framebuffer) -# We make fb_convert_image depend on fb_bitmap.h so that if we change +# We make convert_image depend on fb_bitmap.h so that if we change # that header, we get new images built just in case. -$(TOOLROOT)/fb_convert_image: $(TOOLROOT)/created framebuffer/fb_convert_image.c framebuffer/fb_bitmap.h +$(TOOLROOT)/convert_image: $(TOOLROOT)/created framebuffer/convert_image.c framebuffer/bitmap.h $(VQ)echo " HOST CC: $@" - $(Q)$(HOST_CC) -o $@ framebuffer/fb_convert_image.c -lpng + $(Q)$(HOST_CC) -o $@ framebuffer/convert_image.c -lpng FB_IMAGE_left_arrow := framebuffer/res/icons/back.png FB_IMAGE_right_arrow := framebuffer/res/icons/forward.png @@ -51,8 +51,8 @@ define convert_image S_IMAGES += $(2) -$(2): $(1) $(TOOLROOT)/fb_convert_image - $(Q)$(TOOLROOT)/fb_convert_image $(1) $(2) $(3) +$(2): $(1) $(TOOLROOT)/convert_image + $(Q)$(TOOLROOT)/convert_image $(1) $(2) $(3) endef diff --git a/Makefile.sources b/Makefile.sources index 886b6e176..458eb8b87 100644 --- a/Makefile.sources +++ b/Makefile.sources @@ -87,34 +87,16 @@ S_AMIGA := compat.c gui.c tree.c history.c hotlist.c schedule.c \ S_AMIGA := $(addprefix amiga/,$(S_AMIGA)) # S_FRAMEBUFFER are sources purely for the framebuffer build -S_FRAMEBUFFER := fb_gui.c tree.c history.c hotlist.c fb_schedule.c \ - thumbnail.c misc.c fb_bitmap.c fb_filetype.c login.c \ - fb_cursor.c fb_plotters.c fb_8bpp_plotters.c \ - fb_16bpp_plotters.c fb_32bpp_plotters.c fb_findfile.c \ - fb_tk.c -# fb_1bpp_plotters.c +S_FRAMEBUFFER := gui.c framebuffer.c tree.c history.c hotlist.c \ + schedule.c thumbnail.c misc.c bitmap.c filetype.c login.c \ + findfile.c fbtk.c -S_FRAMEBUFFER += fb_font_$(NETSURF_FB_FONTLIB).c +S_FRAMEBUFFER += font_$(NETSURF_FB_FONTLIB).c ifeq ($(NETSURF_FB_FONTLIB),internal) S_FRAMEBUFFER += font_8x16.c endif -ifeq ($(NETSURF_FB_FRONTEND),linux) -S_FRAMEBUFFER += fb_frontend_linuxfb.c -endif -ifeq ($(NETSURF_FB_FRONTEND),able) -S_FRAMEBUFFER += fb_frontend_ablefb.c -endif -ifeq ($(NETSURF_FB_FRONTEND),dummy) -S_FRAMEBUFFER += fb_frontend_dummy.c -endif -ifeq ($(NETSURF_FB_FRONTEND),sdl) -S_FRAMEBUFFER += fb_frontend_sdl.c -endif -ifeq ($(NETSURF_FB_FRONTEND),vnc) -S_FRAMEBUFFER += fb_frontend_vnc.c -endif S_FRAMEBUFFER := $(addprefix framebuffer/,$(S_FRAMEBUFFER)) diff --git a/desktop/options.c b/desktop/options.c index a871214bf..28cdecf3c 100644 --- a/desktop/options.c +++ b/desktop/options.c @@ -50,8 +50,8 @@ #include "beos/options.h" #elif defined(nsamiga) #include "amiga/options.h" -#elif defined(nsfb) -#include "framebuffer/fb_options.h" +#elif defined(nsframebuffer) +#include "framebuffer/options.h" #else #define EXTRA_OPTION_DEFINE #define EXTRA_OPTION_TABLE diff --git a/framebuffer/bitmap.c b/framebuffer/bitmap.c new file mode 100644 index 000000000..4f9e90647 --- /dev/null +++ b/framebuffer/bitmap.c @@ -0,0 +1,259 @@ +/* + * Copyright 2008 Vincent Sanders + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include + +#include "assert.h" +#include "image/bitmap.h" +#include "framebuffer/bitmap.h" + +#include "utils/log.h" + +/** + * Create a bitmap. + * + * \param width width of image in pixels + * \param height width of image in pixels + * \param state a flag word indicating the initial state + * \return an opaque struct bitmap, or NULL on memory exhaustion + */ + +void *bitmap_create(int width, int height, unsigned int state) +{ + struct bitmap *bitmap; + + LOG(("width %d, height %d, state %u",width,height,state)); + + bitmap = calloc(1 , sizeof(struct bitmap)); + if (bitmap) { + bitmap->pixdata = calloc(4, width * height); + if (bitmap->pixdata != NULL) { + bitmap->width = width; + bitmap->height = height; + bitmap->opaque = false; + } else { + free(bitmap); + bitmap=NULL; + } + } + + LOG(("bitmap %p", bitmap)); + + return bitmap; +} + + +/** + * Return a pointer to the pixel data in a bitmap. + * + * \param bitmap a bitmap, as returned by bitmap_create() + * \return pointer to the pixel buffer + * + * The pixel data is packed as BITMAP_FORMAT, possibly with padding at the end + * of rows. The width of a row in bytes is given by bitmap_get_rowstride(). + */ + +unsigned char *bitmap_get_buffer(void *bitmap) +{ + struct bitmap *bm = bitmap; + + if (bitmap == NULL) { + LOG(("NULL bitmap!")); + return NULL; + } + + return bm->pixdata; +} + + +/** + * Find the width of a pixel row in bytes. + * + * \param bitmap a bitmap, as returned by bitmap_create() + * \return width of a pixel row in the bitmap + */ + +size_t bitmap_get_rowstride(void *bitmap) +{ + struct bitmap *bm = bitmap; + + if (bitmap == NULL) { + LOG(("NULL bitmap!")); + return 0; + } + + return (bm->width) * 4; +} + + +/** + * Free a bitmap. + * + * \param bitmap a bitmap, as returned by bitmap_create() + */ + +void bitmap_destroy(void *bitmap) +{ + struct bitmap *bm = bitmap; + + if (bitmap == NULL) { + LOG(("NULL bitmap!")); + return; + } + + free(bm->pixdata); + free(bm); +} + + +/** + * Save a bitmap in the platform's native format. + * + * \param bitmap a bitmap, as returned by bitmap_create() + * \param path pathname for file + * \return true on success, false on error and error reported + */ + +bool bitmap_save(void *bitmap, const char *path, unsigned flags) +{ + return true; +} + + +/** + * The bitmap image has changed, so flush any persistant cache. + * + * \param bitmap a bitmap, as returned by bitmap_create() + */ +void bitmap_modified(void *bitmap) { +} + + +/** + * The bitmap image can be suspended. + * + * \param bitmap a bitmap, as returned by bitmap_create() + * \param private_word a private word to be returned later + * \param suspend the function to be called upon suspension + * \param resume the function to be called when resuming + */ +void bitmap_set_suspendable(void *bitmap, void *private_word, + void (*invalidate)(void *bitmap, void *private_word)) { +} + +/** + * Sets whether a bitmap should be plotted opaque + * + * \param bitmap a bitmap, as returned by bitmap_create() + * \param opaque whether the bitmap should be plotted opaque + */ +void bitmap_set_opaque(void *bitmap, bool opaque) +{ + struct bitmap *bm = bitmap; + + if (bitmap == NULL) { + LOG(("NULL bitmap!")); + return; + } + + LOG(("setting bitmap %p to %s", bm, opaque?"opaque":"transparent")); + bm->opaque = opaque; +} + + +/** + * Tests whether a bitmap has an opaque alpha channel + * + * \param bitmap a bitmap, as returned by bitmap_create() + * \return whether the bitmap is opaque + */ +bool bitmap_test_opaque(void *bitmap) +{ + int tst; + struct bitmap *bm = bitmap; + + if (bitmap == NULL) { + LOG(("NULL bitmap!")); + return false; + } + + tst = bm->width * bm->height; + + while (tst-- > 0) { + if (bm->pixdata[(tst << 2) + 3] != 0xff) { + LOG(("bitmap %p has transparency",bm)); + return false; + } + } + LOG(("bitmap %p is opaque", bm)); + return true; +} + + +/** + * Gets whether a bitmap should be plotted opaque + * + * \param bitmap a bitmap, as returned by bitmap_create() + */ +bool bitmap_get_opaque(void *bitmap) +{ + struct bitmap *bm = bitmap; + + if (bitmap == NULL) { + LOG(("NULL bitmap!")); + return false; + } + + return bm->opaque; +} + +int bitmap_get_width(void *bitmap) +{ + struct bitmap *bm = bitmap; + + if (bitmap == NULL) { + LOG(("NULL bitmap!")); + return 0; + } + + return(bm->width); +} + +int bitmap_get_height(void *bitmap) +{ + struct bitmap *bm = bitmap; + + if (bitmap == NULL) { + LOG(("NULL bitmap!")); + return 0; + } + + return(bm->height); +} + +size_t bitmap_get_bpp(void *bitmap) +{ + return 4; +} + +/* + * Local Variables: + * c-basic-offset:8 + * End: + */ diff --git a/framebuffer/bitmap.h b/framebuffer/bitmap.h new file mode 100644 index 000000000..9a75b0b13 --- /dev/null +++ b/framebuffer/bitmap.h @@ -0,0 +1,33 @@ +/* + * Copyright 2008 Vincent Sanders + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef FRAMEBUFFER_BITMAP_H +#define FRAMEBUFFER_BITMAP_H + +struct bitmap { + int width; + int height; + uint8_t *pixdata; + bool opaque; + + /* The following two are only used for cursors */ + int hot_x; + int hot_y; +}; + +#endif diff --git a/framebuffer/convert_image.c b/framebuffer/convert_image.c new file mode 100644 index 000000000..6b16c26dc --- /dev/null +++ b/framebuffer/convert_image.c @@ -0,0 +1,307 @@ +/* + * Copyright 2009 Daniel Silverstone + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include + +static png_structp png; +static png_infop info; +static int interlace; +static size_t rowbytes; +static int raw_width, raw_height; +static int rowstride; +static unsigned char *bitmap_data; +static bool is_cursor = true; +static int raw_hot_x, raw_hot_y; + +#define WIDTH (is_cursor?raw_width-1:raw_width) +#define HEIGHT (is_cursor?raw_height-1:raw_height) + +#define HOT_X (is_cursor?raw_hot_x-1:0) +#define HOT_Y (is_cursor?raw_hot_y-1:0) + +#define REAL(v) (is_cursor?v+1:v) + +#define PPIX_AT(x,y) ((bitmap_data + (rowstride * y)) + (x * 4)) + +#define R_OFF 2 +#define G_OFF 1 +#define B_OFF 0 +#define A_OFF 3 + +#define R_AT(x,y) *(PPIX_AT(x,y) + R_OFF) +#define G_AT(x,y) *(PPIX_AT(x,y) + G_OFF) +#define B_AT(x,y) *(PPIX_AT(x,y) + B_OFF) +#define A_AT(x,y) *(PPIX_AT(x,y) + A_OFF) + +static void info_callback(png_structp png, png_infop info); +static void row_callback(png_structp png, png_bytep new_row, + png_uint_32 row_num, int pass); +static void end_callback(png_structp png, png_infop info); + + + +static void +usage(void) +{ + fprintf(stderr, "usage: fb_convert_image input.png output.inc varname\n"); +} + +static void info_callback(png_structp png, png_infop info); +static void row_callback(png_structp png, png_bytep new_row, + png_uint_32 row_num, int pass); +static void end_callback(png_structp png, png_infop info); + + +static void +detect_hotspot(void) +{ + int i; + int greenpixels = 0; + + for (i = 0; i < raw_width; ++i) { + if (A_AT(i, 0) == 255) { + if (G_AT(i, 0) == 255) { + greenpixels++; + raw_hot_x = i; + } + if ((B_AT(i, 0) != 0) || (R_AT(i, 0) != 0)) { + is_cursor = false; + return; + } + } else if (A_AT(i, 0) != 0) { + is_cursor = false; + return; + } + } + if (greenpixels != 1) { + is_cursor = false; + return; + } + + for (i = 0; i < raw_height; ++i) { + if (A_AT(0, i) == 255) { + if (G_AT(0, i) == 255) { + greenpixels++; + raw_hot_y = i; + } + if ((B_AT(0, i) != 0) || (R_AT(0, i) != 0)) { + is_cursor = false; + return; + } + } else if (A_AT(0, i) != 0) { + is_cursor = false; + return; + } + } + if (greenpixels != 2) { + is_cursor = false; + return; + } + printf(" Pointer detected. Adjusted hotspot at %d, %d (0-based)\n", + raw_hot_x - 1, raw_hot_y - 1); +} + +int +main(int argc, char **argv) +{ + FILE *f; + unsigned char buffer[1024]; + int br; + int x, y, c; + + if (argc != 4) { + usage(); + return 1; + } + + printf(" CONVERT: %s (%s)\n", argv[1], argv[3]); + + png = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); + info = png_create_info_struct(png); + + png_set_progressive_read_fn(png, NULL, info_callback, row_callback, end_callback); + + f = fopen(argv[1], "rb"); + if (f == NULL) { + printf(" Unable to open %s\n", argv[1]); + return 1; + } + + do { + br = fread(buffer, 1, 1024, f); + if (br > 0) { + png_process_data(png, info, buffer, br); + } + } while (br > 0); + + if (br < 0) { + printf("Error reading input: %s\n", strerror(errno)); + return 1; + } + + fclose(f); + + detect_hotspot(); + + f = fopen(argv[2], "w"); + if (f == NULL) { + printf(" Unable to open %s\n", argv[2]); + return 2; + } + + fprintf(f, "/* This file is auto-generated from %s\n", argv[1]); + fprintf(f, " *\n * Do not edit this file directly.\n */\n\n"); + fprintf(f, "#include \n\n"); + fprintf(f, "#include \n\n"); + fprintf(f, "#include \n\n"); + fprintf(f, "#include \"framebuffer/bitmap.h\"\n\n"); + + fprintf(f, "static uint8_t %s_pixdata[] = {\n", argv[3]); + for (y = 0; y < HEIGHT; ++y) { + unsigned char *rowptr = bitmap_data + (rowstride * y); + if (is_cursor) { + /* If it's a cursor, skip one row and one column */ + rowptr += rowstride + 4; + } + fprintf(f, "\t"); + for (x = 0; x < WIDTH; ++x) { + for (c = 0; c < 4; ++c) { + unsigned char b = *rowptr++; + fprintf(f, "0x%02x, ", b); + } + } + fprintf(f, "\n"); + } + fprintf(f, "};\n\n"); + + fprintf(f, "struct bitmap %s = {\n", argv[3]); + fprintf(f, "\t.width\t\t= %d,\n", WIDTH); + fprintf(f, "\t.height\t\t= %d,\n", HEIGHT); + fprintf(f, "\t.hot_x\t\t= %d,\n", HOT_X); + fprintf(f, "\t.hot_y\t\t= %d,\n", HOT_Y); + fprintf(f, "\t.pixdata\t= %s_pixdata,\n", argv[3]); + + fprintf(f, "};\n\n"); + fclose(f); + + return 0; +} + +static void +info_callback(png_structp png, png_infop info) +{ + int bit_depth, color_type, interlace, intent; + double gamma; + unsigned long width, height; + + /* Read the PNG details */ + png_get_IHDR(png, info, &width, &height, &bit_depth, + &color_type, &interlace, 0, 0); + + /* Set up our transformations */ + if (color_type == PNG_COLOR_TYPE_PALETTE) + png_set_palette_to_rgb(png); + if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) + png_set_gray_1_2_4_to_8(png); + if (png_get_valid(png, info, PNG_INFO_tRNS)) + png_set_tRNS_to_alpha(png); + if (bit_depth == 16) + png_set_strip_16(png); + if (color_type == PNG_COLOR_TYPE_GRAY || + color_type == PNG_COLOR_TYPE_GRAY_ALPHA) + png_set_gray_to_rgb(png); + if (!(color_type & PNG_COLOR_MASK_ALPHA)) + png_set_filler(png, 0xff, PNG_FILLER_AFTER); + /* gamma correction - we use 2.2 as our screen gamma + * this appears to be correct (at least in respect to !Browse) + * see http://www.w3.org/Graphics/PNG/all_seven.html for a test case + */ + if (png_get_sRGB(png, info, &intent)) + png_set_gamma(png, 2.2, 0.45455); + else { + if (png_get_gAMA(png, info, &gamma)) + png_set_gamma(png, 2.2, gamma); + else + png_set_gamma(png, 2.2, 0.45455); + } + + + png_read_update_info(png, info); + + rowbytes = png_get_rowbytes(png, info); + interlace = (interlace == PNG_INTERLACE_ADAM7); + raw_width = width; + raw_height = height; + + rowstride = raw_width * 4; + bitmap_data = malloc(rowstride * raw_height); +} + +static unsigned int interlace_start[8] = {0, 16, 0, 8, 0, 4, 0}; +static unsigned int interlace_step[8] = {28, 28, 12, 12, 4, 4, 0}; +static unsigned int interlace_row_start[8] = {0, 0, 4, 0, 2, 0, 1}; +static unsigned int interlace_row_step[8] = {8, 8, 8, 4, 4, 2, 2}; + +static void +row_callback(png_structp png, png_bytep new_row, + png_uint_32 row_num, int pass) +{ + unsigned long i, j; + unsigned int start, step; + unsigned char *row = bitmap_data + (rowstride * row_num); + + if (new_row == 0) + return; + + if (interlace) { + start = interlace_start[pass]; + step = interlace_step[pass]; + row_num = interlace_row_start[pass] + + interlace_row_step[pass] * row_num; + + /* Copy the data to our current row taking interlacing + * into consideration */ + row = bitmap_data + (rowstride * row_num); + for (j = 0, i = start; i < rowbytes; i += step) { + row[i++] = new_row[j++]; + row[i++] = new_row[j++]; + row[i++] = new_row[j++]; + row[i++] = new_row[j++]; + } + } else { + memcpy(row, new_row, rowbytes); + } +} + +static void +end_callback(png_structp png, png_infop info) +{ +} + + + +/* + * Local Variables: + * c-basic-offset:8 + * End: + */ + diff --git a/framebuffer/fb_16bpp_plotters.c b/framebuffer/fb_16bpp_plotters.c deleted file mode 100644 index b97c42da5..000000000 --- a/framebuffer/fb_16bpp_plotters.c +++ /dev/null @@ -1,569 +0,0 @@ -/* - * Copyright 2008 Vincent Sanders - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include - -#include "utils/log.h" -#include "utils/utf8.h" -#include "desktop/plotters.h" - -#include "framebuffer/fb_gui.h" -#include "framebuffer/fb_plotters.h" -#include "framebuffer/fb_bitmap.h" -#include "framebuffer/fb_font.h" - -static inline uint16_t * -fb_16bpp_get_xy_loc(int x, int y) -{ - return (void *)(framebuffer->ptr + - (y * framebuffer->linelen) + - (x << 1)); -} - -static inline colour fb_16bpp_to_colour(uint16_t pixel) -{ - return ((pixel & 0x1F) << 19) | - ((pixel & 0x7E0) << 5) | - ((pixel & 0xF800) >> 8); -} - -/* convert a colour value to a 16bpp pixel value ready for screen output */ -static inline uint16_t fb_colour_to_pixel(colour c) -{ - return ((c & 0xF8) << 8) | ((c & 0xFC00 ) >> 5) | ((c & 0xF80000) >> 19); -} - -#define SIGN(x) ((x<0) ? -1 : ((x>0) ? 1 : 0)) - -static bool fb_16bpp_line(int x0, int y0, int x1, int y1, int width, - colour c, bool dotted, bool dashed) -{ - int w; - uint16_t ent; - uint16_t *pvideo; - - int x, y, i; - int dx, dy, sdy; - int dxabs, dyabs; - - /*LOG(("%d, %d, %d, %d, %d, 0x%lx, %d, %d", - x0,y0,x1,y1,width,c,dotted,dashed));*/ - - if (y1 > fb_plot_ctx.y1) - return true; - if (y0 < fb_plot_ctx.y0) - return true; - - ent = fb_colour_to_pixel(c); - - if (y0 == y1) { - /* horizontal line special cased */ - if (!fb_plotters_clip_rect_ctx(&x0, &y0, &x1, &y1)) - return true; /* line outside clipping */ - - /*LOG(("horiz: %d, %d, %d, %d, %d, 0x%lx, %d, %d", - x0,y0,x1,y1,width,c,dotted,dashed));*/ - - pvideo = fb_16bpp_get_xy_loc(x0, y0); - - w = x1 - x0; - while (w-- > 0) { - *(pvideo + w) = ent; - } - return true; - } else { - /* standard bresenham line */ - if (!fb_plotters_clip_line_ctx(&x0, &y0, &x1, &y1)) - return true; /* line outside clipping */ - - //LOG(("%d, %d, %d, %d", x0,y0,x1,y1)); - - /* the horizontal distance of the line */ - dx = x1 - x0; - dxabs = abs (dx); - - /* the vertical distance of the line */ - dy = y1 - y0; - dyabs = abs (dy); - - sdy = dx ? SIGN(dy) * SIGN(dx) : SIGN(dy); - - if (dx >= 0) - pvideo = fb_16bpp_get_xy_loc(x0, y0); - else - pvideo = fb_16bpp_get_xy_loc(x1, y1); - - x = dyabs >> 1; - y = dxabs >> 1; - - if (dxabs >= dyabs) { - /* the line is more horizontal than vertical */ - for (i = 0; i <= dxabs; i++) { - *pvideo = ent; - - pvideo++; - y += dyabs; - if (y > dxabs) { - y -= dxabs; - pvideo += sdy * (framebuffer->linelen>>1); - } - } - } else { - /* the line is more vertical than horizontal */ - for (i = 0; i <= dyabs; i++) { - *pvideo = ent; - pvideo += sdy * (framebuffer->linelen >> 1); - - x += dxabs; - if (x > dyabs) { - x -= dyabs; - pvideo++; - } - } - } - - } - - - - return true; -} - -static bool fb_16bpp_rectangle(int x0, int y0, int width, int height, - int line_width, colour c, bool dotted, bool dashed) -{ - fb_16bpp_line(x0, y0, x0 + width, y0, line_width, c, dotted, dashed); - fb_16bpp_line(x0, y0 + height, x0 + width, y0 + height, line_width, c, dotted, dashed); - fb_16bpp_line(x0, y0, x0, y0 + height, line_width, c, dotted, dashed); - fb_16bpp_line(x0 + width, y0, x0 + width, y0 + height, line_width, c, dotted, dashed); - return true; -} - -static bool fb_16bpp_polygon(const int *p, unsigned int n, colour fill) -{ - return fb_plotters_polygon(p, n, fill, fb_16bpp_line); -} - - -static bool fb_16bpp_fill(int x0, int y0, int x1, int y1, colour c) -{ - int w; - uint16_t *pvid16; - uint16_t ent16; - uint32_t *pvid32; - uint32_t ent32; - uint32_t llen; - uint32_t width; - uint32_t height; - - if (!fb_plotters_clip_rect_ctx(&x0, &y0, &x1, &y1)) - return true; /* fill lies outside current clipping region */ - - ent16 = fb_colour_to_pixel(c); - width = x1 - x0; - height = y1 - y0; - - pvid16 = fb_16bpp_get_xy_loc(x0, y0); - - if (((x0 & 1) == 0) && ((width & 1) == 0)) { - /* aligned to 32bit value and width is even */ - width = width >> 1; - llen = (framebuffer->linelen >> 2) - width; - ent32 = ent16 | (ent16 << 16); - pvid32 = (uint32_t *)pvid16; - - while (height-- > 0) { - w = width; - while (w >= 16) { - *pvid32++ = ent32; *pvid32++ = ent32; - *pvid32++ = ent32; *pvid32++ = ent32; - *pvid32++ = ent32; *pvid32++ = ent32; - *pvid32++ = ent32; *pvid32++ = ent32; - *pvid32++ = ent32; *pvid32++ = ent32; - *pvid32++ = ent32; *pvid32++ = ent32; - *pvid32++ = ent32; *pvid32++ = ent32; - *pvid32++ = ent32; *pvid32++ = ent32; - w-=16; - } - while (w >= 4) { - *pvid32++ = ent32; *pvid32++ = ent32; - *pvid32++ = ent32; *pvid32++ = ent32; - w-=4; - } - while (w > 0) { - *pvid32++ = ent32; - w--; - } - // for (w = width; w > 0; w--) *pvid32++ = ent32; - pvid32 += llen; - } - - } else { - llen = (framebuffer->linelen >> 1) - width; - - - while (height-- > 0) { - for (w = width; w > 0; w--) *pvid16++ = ent16; - pvid16 += llen; - } - } - return true; -} - -static bool fb_16bpp_clg(colour c) -{ - /* LOG(("c %lx", c)); */ - fb_16bpp_fill(fb_plot_ctx.x0, - fb_plot_ctx.y0, - fb_plot_ctx.x1, - fb_plot_ctx.y1, - c); - return true; -} - -#ifdef FB_USE_FREETYPE - -static bool -fb_16bpp_draw_ft_monobitmap(FT_Bitmap *bp, int x, int y, colour c) -{ - return false; -} - -static bool -fb_16bpp_draw_ft_bitmap(FT_Bitmap *bp, int x, int y, colour c) -{ - uint16_t *pvideo; - uint8_t *pixel = (uint8_t *)bp->buffer; - colour abpixel; /* alphablended pixel */ - int xloop, yloop; - int x0,y0,x1,y1; - int xoff, yoff; /* x and y offset into image */ - int height = bp->rows; - int width = bp->width; - uint32_t fgcol; - - /* The part of the scaled image actually displayed is cropped to the - * current context. - */ - x0 = x; - y0 = y; - x1 = x + width; - y1 = y + height; - - if (!fb_plotters_clip_rect_ctx(&x0, &y0, &x1, &y1)) - return true; - - if (height > (y1 - y0)) - height = (y1 - y0); - - if (width > (x1 - x0)) - width = (x1 - x0); - - xoff = x0 - x; - yoff = y0 - y; - - /* plot the image */ - pvideo = fb_16bpp_get_xy_loc(x0, y0); - - fgcol = c & 0xFFFFFF; - - for (yloop = 0; yloop < height; yloop++) { - for (xloop = 0; xloop < width; xloop++) { - abpixel = (pixel[((yoff + yloop) * bp->pitch) + xloop + xoff] << 24) | fgcol; - if ((abpixel & 0xFF000000) != 0) { - if ((abpixel & 0xFF000000) != 0xFF000000) { - abpixel = fb_plotters_ablend(abpixel, - fb_16bpp_to_colour(*(pvideo + xloop))); - } - - *(pvideo + xloop) = fb_colour_to_pixel(abpixel); - - } - } - pvideo += (framebuffer->linelen >> 1); - } - - return true; -} - -static bool fb_16bpp_text(int x, int y, const struct css_style *style, - const char *text, size_t length, colour bg, colour c) -{ - uint32_t ucs4; - size_t nxtchr = 0; - FT_Glyph glyph; - FT_BitmapGlyph bglyph; - - while (nxtchr < length) { - ucs4 = utf8_to_ucs4(text + nxtchr, length - nxtchr); - nxtchr = utf8_next(text, length, nxtchr); - - glyph = fb_getglyph(style, ucs4); - if (glyph == NULL) - continue; - if (glyph->format == FT_GLYPH_FORMAT_BITMAP) { - bglyph = (FT_BitmapGlyph)glyph; - - /* now, draw to our target surface */ - if (bglyph->bitmap.pixel_mode == FT_PIXEL_MODE_MONO) { - fb_16bpp_draw_ft_monobitmap(&bglyph->bitmap, - x + bglyph->left, - y - bglyph->top, - c); - } else { - fb_16bpp_draw_ft_bitmap(&bglyph->bitmap, - x + bglyph->left, - y - bglyph->top, - c); - } - } - x += glyph->advance.x >> 16; - - } - return true; -} - -#else -static bool fb_16bpp_text(int x, int y, const struct css_style *style, - const char *text, size_t length, colour bg, colour c) -{ - const struct fb_font_desc* fb_font = fb_get_font(style); - const uint32_t *font_data; - int xloop, yloop; - uint32_t row; - size_t chr; - - uint16_t *pvideo; - uint16_t fgcol; - uint16_t bgcol; - - unsigned char *buffer = NULL; - int x0,y0,x1,y1; - int xoff, yoff; /* x and y offset into image */ - int height = fb_font->height; - - /* aquire thge text in local font encoding */ - utf8_to_font_encoding(fb_font, text, length, (char **)&buffer); - if (!buffer) - return true; - length = strlen((char *)buffer); - - - /* y is given to the fonts baseline we need it to the fonts top */ - y-=((fb_font->height * 75)/100); - - y+=1; /* the coord is the bottom-left of the pixels offset by 1 to make - * it work since fb coords are the top-left of pixels - */ - - /* The part of the text displayed is cropped to the current context. */ - x0 = x; - y0 = y; - x1 = x + (fb_font->width * length); - y1 = y + fb_font->height; - - if (!fb_plotters_clip_rect_ctx(&x0, &y0, &x1, &y1)) - return true; /* text lies outside current clipping region */ - - /* find width and height to plot */ - if (height > (y1 - y0)) - height = (y1 - y0); - - xoff = x0 - x; - yoff = y0 - y; - - fgcol = fb_colour_to_pixel(c); - - bgcol = fb_colour_to_pixel(bg); - - /*LOG(("x %d, y %d, style %p, txt %.*s , len %d, bg 0x%lx, fg 0x%lx", - x,y,style,length,text,length,bg,c));*/ - - for (chr = 0; chr < length; chr++, x += fb_font->width) { - if ((x + fb_font->width) > x1) - break; - - if (x < x0) - continue; - - pvideo = fb_16bpp_get_xy_loc(x, y0); - - /* move our font-data to the correct position */ - font_data = fb_font->data + (buffer[chr] * fb_font->height); - - for (yloop = 0; yloop < height; yloop++) { - row = font_data[yoff + yloop]; - for (xloop = fb_font->width; xloop > 0 ; xloop--) { - if ((row & 1) != 0) - *(pvideo + xloop) = fgcol; - row = row >> 1; - } - pvideo += (framebuffer->linelen >> 1); - } - } - - free(buffer); - return true; -} -#endif - -static bool fb_16bpp_disc(int x, int y, int radius, colour c, bool filled) -{ - LOG(("x %d, y %d, r %d, c 0x%lx, fill %d", - x, y, radius, (unsigned long)c, filled)); - - return true; -} - -static bool fb_16bpp_arc(int x, int y, int radius, int angle1, int angle2, - colour c) -{ - LOG(("x %d, y %d, r %d, a1 %d, a2 %d, c 0x%lx", - x, y, radius, angle1, angle2, (unsigned long)c)); - return true; -} - - -static bool fb_16bpp_bitmap(int x, int y, int width, int height, - struct bitmap *bitmap, colour bg, - struct content *content) -{ - uint16_t *pvideo; - colour *pixel = (colour *)bitmap->pixdata; - colour abpixel; /* alphablended pixel */ - int xloop, yloop; - int x0,y0,x1,y1; - int xoff, yoff; /* x and y offset into image */ - - - /* TODO here we should scale the image from bitmap->width to width, for - * now simply crop. - */ - if (width > bitmap->width) - width = bitmap->width; - - if (height > bitmap->height) - height = bitmap->height; - - /* The part of the scaled image actually displayed is cropped to the - * current context. - */ - x0 = x; - y0 = y; - x1 = x + width; - y1 = y + height; - - if (!fb_plotters_clip_rect_ctx(&x0, &y0, &x1, &y1)) - return true; - - - LOG(("%d, %d %d, %d bitmap %p, content %p", - x0,y0,x1,y1,bitmap,content)); - - if (height > (y1 - y0)) - height = (y1 - y0); - - if (width > (x1 - x0)) - width = (x1 - x0); - - - xoff = x0 - x; - yoff = (y0 - y) * bitmap->width; - height = height * bitmap->width + yoff; - - /* plot the image */ - pvideo = fb_16bpp_get_xy_loc(x0, y0); - - if (bitmap->opaque) { - for (yloop = yoff; yloop < height; yloop += bitmap->width) { - for (xloop = 0; xloop < width; xloop++) { - abpixel = pixel[yloop + xloop + xoff]; - *(pvideo + xloop) = fb_colour_to_pixel(abpixel); - } - pvideo += (framebuffer->linelen >> 1); - } - } else { - for (yloop = yoff; yloop < height; yloop += bitmap->width) { - for (xloop = 0; xloop < width; xloop++) { - abpixel = pixel[yloop + xloop + xoff]; - if ((abpixel & 0xFF000000) != 0) { - if ((abpixel & 0xFF000000) != 0xFF000000) { - abpixel = fb_plotters_ablend(abpixel, - fb_16bpp_to_colour(*(pvideo + xloop))); - } - - *(pvideo + xloop) = fb_colour_to_pixel(abpixel); - } - } - pvideo += (framebuffer->linelen >> 1); - } - } - - return true; -} - -static bool fb_16bpp_bitmap_tile(int x, int y, int width, int height, - struct bitmap *bitmap, colour bg, - bool repeat_x, bool repeat_y, - struct content *content) -{ - return fb_plotters_bitmap_tile(x, y, width, height, - bitmap, bg, repeat_x, repeat_y, - content, fb_16bpp_bitmap); -} - -static bool fb_16bpp_flush(void) -{ - LOG(("optional")); - return true; -} - -static bool fb_16bpp_path(const float *p, unsigned int n, colour fill, float width, - colour c, const float transform[6]) -{ - LOG(("%f, %d, 0x%lx, %f, 0x%lx, %f", - *p, n, (unsigned long)fill, width, (unsigned long)c, *transform)); - return true; -} - - -const struct plotter_table framebuffer_16bpp_plot = { - .clg = fb_16bpp_clg, - .rectangle = fb_16bpp_rectangle, - .line = fb_16bpp_line, - .polygon = fb_16bpp_polygon, - .fill = fb_16bpp_fill, - .clip = fb_clip, - .text = fb_16bpp_text, - .disc = fb_16bpp_disc, - .arc = fb_16bpp_arc, - .bitmap = fb_16bpp_bitmap, - .bitmap_tile = fb_16bpp_bitmap_tile, - .flush = fb_16bpp_flush, - .path = fb_16bpp_path, - .option_knockout = true, -}; - -/* - * Local Variables: - * c-basic-offset:8 - * End: - */ diff --git a/framebuffer/fb_1bpp_plotters.c b/framebuffer/fb_1bpp_plotters.c deleted file mode 100644 index bd511e7ff..000000000 --- a/framebuffer/fb_1bpp_plotters.c +++ /dev/null @@ -1,266 +0,0 @@ -/* - * Copyright 2008 Vincent Sanders - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include - -#include "utils/log.h" -#include "utils/utf8.h" -#include "desktop/plotters.h" - -#include "framebuffer/fb_gui.h" -#include "framebuffer/fb_plotters.h" -#include "framebuffer/fb_bitmap.h" -#include "framebuffer/fb_font.h" - -extern struct fb_info_s *fbinfo; - - -static bool fb_1bpp_rectangle(int x0, int y0, int width, int height, - int line_width, colour c, bool dotted, bool dashed) -{ - LOG(("%s(%d, %d, %d, %d, %d, 0x%lx, %d, %d)\n", __func__, - x0,y0,width,height,line_width,c,dotted,dashed)); - return true; -} - -static bool fb_1bpp_line(int x0, int y0, int x1, int y1, int width, - colour c, bool dotted, bool dashed) -{ - LOG(("%s(%d, %d, %d, %d, %d, 0x%lx, %d, %d)\n", __func__, - x0,y0,x1,y1,width,c,dotted,dashed)); - - return true; -} - -static bool fb_1bpp_polygon(const int *p, unsigned int n, colour fill) -{ - LOG(("%s(%p, %d, 0x%lx)\n", __func__, p,n,fill)); - return true; -} - - -static bool fb_1bpp_fill(int x0, int y0, int x1, int y1, colour c) -{ - int x; - int y; - int pent; - - LOG(("%s(%d, %d, %d, %d, 0x%lx)\n", __func__, - x0,y0,x1,y1,c)); - - if (c != 0) - pent = 0xff; - else - pent = 0; - - fb_plotters_clip_rect_ctx(&x0, &y0, &x1, &y1); - - x = x1 - x0; - for (y = y0; y < y1; y++) { - memset(fb_plotters_get_xy_loc(x0, y, fbinfo), pent, x); - } - return true; -} - -static bool fb_1bpp_clg(colour c) -{ - LOG(("%s(%lx)\n", __func__, c)); - fb_1bpp_fill(fb_plot_ctx.x0, - fb_plot_ctx.y0, - fb_plot_ctx.x1, - fb_plot_ctx.y1, - c); - return true; -} - - -static bool fb_1bpp_text(int x, int y, const struct css_style *style, - const char *text, size_t length, colour bg, colour c) -{ - const struct fb_font_desc* fb_font = fb_get_font(style); - u8_t *video_char_start; - const u8_t *font_data; - int yloop; - unsigned char row; - int chr; - - LOG(("%s(%d, %d, %p, %.*s , %d, 0x%lx, 0x%lx)\n", __func__, - x,y,style,length,text,length,bg,c)); - - for (chr=0; chr < length; chr++) { - video_char_start = fb_plotters_get_xy_loc(x + (chr * (fb_font->width)), y, fbinfo); - - /* move our font-data to the correct position */ - font_data = fb_font->data + (text[chr] * fb_font->height); - - for (yloop = 0; yloop < fb_font->height; yloop++) { - row = font_data[yloop]; - *video_char_start = row; - video_char_start += fbinfo->line_len; - } - } - return true; - - - /* copied from css/css.h - need to open the correct font here - * font properties * - css_font_family font_family; - struct { - css_font_size_type size; - union { - struct css_length length; - float absolute; - float percent; - } value; - } font_size; - css_font_style font_style; - css_font_variant font_variant; - css_font_weight font_weight; - */ - return true; -} - -static bool fb_1bpp_disc(int x, int y, int radius, colour c, bool filled) -{ - LOG(("%s(%d, %d, %d, 0x%lx, %d)\n", __func__, - x, y, radius, c, filled)); - return true; -} - -static bool fb_1bpp_arc(int x, int y, int radius, int angle1, int angle2, - colour c) -{ - LOG(("x %d, y %d, radius %d, angle1 %d, angle2 %d, c 0x%lx", - x, y, radius, angle1, angle2, c)); - return true; -} - -static inline colour ablend(colour pixel) -{ - return pixel; -} - - -static bool fb_1bpp_bitmap(int x, int y, int width, int height, - struct bitmap *bitmap, colour bg, - struct content *content) -{ - u8_t *video_char_start; - colour *pixel = (colour *)bitmap->pixdata; - colour abpixel; /* alphablended pixel */ - int xloop,yloop; - - video_char_start = fb_plotters_get_xy_loc(x, y, fbinfo); - - for (yloop = 0; yloop < height; yloop++) { - for (xloop = 0; xloop < width; xloop++) { - abpixel = pixel[(yloop * bitmap->width) + xloop]; - if ((abpixel & 0xFF000000) != 0) { - if ((abpixel & 0xFF000000) != 0xFF) - abpixel = ablend(abpixel); - if (abpixel == 0) - video_char_start[xloop] |= (1 << (xloop % 8)); - else - video_char_start[xloop] &= ~(1 << (xloop % 8)); - - } - } - video_char_start += fbinfo->line_len; - } - - return true; -} - -static bool fb_1bpp_bitmap_tile(int x, int y, int width, int height, - struct bitmap *bitmap, colour bg, - bool repeat_x, bool repeat_y, - struct content *content) -{ - unsigned long xf,yf,wf,hf; - - if (!(repeat_x || repeat_y)) { - /* Not repeating at all, so just pass it on */ - return fb_1bpp_bitmap(x,y,width,height,bitmap,bg,content); - } - - for (xf = 0; xf < width; xf += bitmap->width) { - for(yf = 0;yf < height; yf += bitmap->height) { - if(width > xf+bitmap->width) - { - wf = width-(xf+bitmap->width); - } - else - { - wf=bitmap->width; - } - - if(height > yf+bitmap->height) - { - hf = height-(yf+bitmap->height); - } - else - { - hf=bitmap->height; - } - - fb_1bpp_bitmap(x+xf, y+yf, wf, hf, bitmap, bg, content); - - } - } - - return true; -} - -static bool fb_1bpp_flush(void) -{ - LOG(("%s()\n", __func__)); - return true; -} - -static bool fb_1bpp_path(const float *p, unsigned int n, colour fill, float width, - colour c, const float transform[6]) -{ - LOG(("%s(%f, %d, 0x%lx, %f, 0x%lx, %f)\n", __func__, - *p, n, fill, width, c, *transform)); - return true; -} - -const struct plotter_table framebuffer_1bpp_plot = { - .clg = fb_1bpp_clg, - .rectangle = fb_1bpp_rectangle, - .line = fb_1bpp_line, - .polygon = fb_1bpp_polygon, - .fill = fb_1bpp_fill, - .clip = fb_clip, - .text = fb_1bpp_text, - .disc = fb_1bpp_disc, - .arc = fb_1bpp_arc, - .bitmap = fb_1bpp_bitmap, - .bitmap_tile = fb_1bpp_bitmap_tile, - .flush = fb_1bpp_flush, - .path = fb_1bpp_path -}; - -/* - * Local Variables: - * c-basic-offset:8 - * End: - */ diff --git a/framebuffer/fb_32bpp_plotters.c b/framebuffer/fb_32bpp_plotters.c deleted file mode 100644 index 5b02bd26f..000000000 --- a/framebuffer/fb_32bpp_plotters.c +++ /dev/null @@ -1,613 +0,0 @@ -/* - * Copyright 2008 Vincent Sanders - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include - -#include "utils/log.h" -#include "utils/utf8.h" -#include "desktop/plotters.h" - -#include "framebuffer/fb_gui.h" -#include "framebuffer/fb_plotters.h" -#include "framebuffer/fb_bitmap.h" -#include "framebuffer/fb_font.h" - -static inline uint32_t * -fb_32bpp_get_xy_loc(int x, int y) -{ - return (uint32_t *)(framebuffer->ptr + - (y * framebuffer->linelen) + - (x << 2)); -} - -#if __BYTE_ORDER == __BIG_ENDIAN -static inline colour fb_32bpp_to_colour(uint32_t pixel) -{ - return (pixel >> 8) & ~0xFF000000U; -} - -/* convert a colour value to a 32bpp pixel value ready for screen output */ -static inline uint32_t fb_colour_to_pixel(colour c) -{ - return (c << 8); -} -#else -static inline colour fb_32bpp_to_colour(uint32_t pixel) -{ - return ((pixel & 0xFF) << 16) | - ((pixel & 0xFF00)) | - ((pixel & 0xFF0000) >> 16); -} - -/* convert a colour value to a 32bpp pixel value ready for screen output */ -static inline uint32_t fb_colour_to_pixel(colour c) -{ - return ((c & 0xff0000) >> 16) | (c & 0xff00) | ((c & 0xff) << 16); -} -#endif - -#define SIGN(x) ((x<0) ? -1 : ((x>0) ? 1 : 0)) - -static bool fb_32bpp_line(int x0, int y0, int x1, int y1, int width, - colour c, bool dotted, bool dashed) -{ - int w; - uint32_t ent; - uint32_t *pvideo; - - int x, y, i; - int dx, dy, sdy; - int dxabs, dyabs; - - if (y1 > fb_plot_ctx.y1) - return true; - if (y0 < fb_plot_ctx.y0) - return true; - - ent = fb_colour_to_pixel(c); - - if (y0 == y1) { - /* horizontal line special cased */ - if (!fb_plotters_clip_rect_ctx(&x0, &y0, &x1, &y1)) - return true; /* line outside clipping */ - - pvideo = fb_32bpp_get_xy_loc(x0, y0); - - w = x1 - x0; - while (w-- > 0) { - *(pvideo + w) = ent; - } - return true; - } else { - /* standard bresenham line */ - if (!fb_plotters_clip_line_ctx(&x0, &y0, &x1, &y1)) - return true; /* line outside clipping */ - - /* the horizontal distance of the line */ - dx = x1 - x0; - dxabs = abs (dx); - - /* the vertical distance of the line */ - dy = y1 - y0; - dyabs = abs (dy); - - sdy = dx ? SIGN(dy) * SIGN(dx) : SIGN(dy); - - if (dx >= 0) - pvideo = fb_32bpp_get_xy_loc(x0, y0); - else - pvideo = fb_32bpp_get_xy_loc(x1, y1); - - x = dyabs >> 1; - y = dxabs >> 1; - - if (dxabs >= dyabs) { - /* the line is more horizontal than vertical */ - for (i = 0; i < dxabs; i++) { - *pvideo = ent; - - pvideo++; - y += dyabs; - if (y >= dxabs) { - y -= dxabs; - pvideo += sdy * (framebuffer->linelen>>2); - } - } - } else { - /* the line is more vertical than horizontal */ - for (i = 0; i < dyabs; i++) { - *pvideo = ent; - pvideo += sdy * (framebuffer->linelen >> 2); - - x += dxabs; - if (x >= dyabs) { - x -= dyabs; - pvideo++; - } - } - } - - } - - return true; -} - -static bool fb_32bpp_rectangle(int x0, int y0, int width, int height, - int line_width, colour c, bool dotted, bool dashed) -{ - fb_32bpp_line(x0, y0, x0 + width, y0, line_width, c, dotted, dashed); - fb_32bpp_line(x0, y0 + height, x0 + width, y0 + height, line_width, c, dotted, dashed); - fb_32bpp_line(x0, y0, x0, y0 + height, line_width, c, dotted, dashed); - fb_32bpp_line(x0 + width, y0, x0 + width, y0 + height, line_width, c, dotted, dashed); - return true; -} - - -static bool fb_32bpp_polygon(const int *p, unsigned int n, colour fill) -{ - return fb_plotters_polygon(p, n, fill, fb_32bpp_line); -} - - - - -static bool fb_32bpp_fill(int x0, int y0, int x1, int y1, colour c) -{ - int w; - uint32_t *pvid; - uint32_t ent; - uint32_t llen; - uint32_t width; - uint32_t height; - - if (!fb_plotters_clip_rect_ctx(&x0, &y0, &x1, &y1)) - return true; /* fill lies outside current clipping region */ - - ent = fb_colour_to_pixel(c); - width = x1 - x0; - height = y1 - y0; - llen = (framebuffer->linelen >> 2) - width; - - pvid = fb_32bpp_get_xy_loc(x0, y0); - - while (height-- > 0) { - w = width; - while (w >= 16) { - *pvid++ = ent; *pvid++ = ent; - *pvid++ = ent; *pvid++ = ent; - *pvid++ = ent; *pvid++ = ent; - *pvid++ = ent; *pvid++ = ent; - *pvid++ = ent; *pvid++ = ent; - *pvid++ = ent; *pvid++ = ent; - *pvid++ = ent; *pvid++ = ent; - *pvid++ = ent; *pvid++ = ent; - w-=16; - } - while (w >= 4) { - *pvid++ = ent; *pvid++ = ent; - *pvid++ = ent; *pvid++ = ent; - w-=4; - } - while (w > 0) { - *pvid++ = ent; - w--; - } - pvid += llen; - } - - return true; -} - -static bool fb_32bpp_clg(colour c) -{ - fb_32bpp_fill(fb_plot_ctx.x0, - fb_plot_ctx.y0, - fb_plot_ctx.x1, - fb_plot_ctx.y1, - c); - return true; -} - -#ifdef FB_USE_FREETYPE - - -static bool -fb_32bpp_draw_ft_monobitmap(FT_Bitmap *bp, int x, int y, colour c) -{ - int height = bp->rows; - int width = bp->width; - uint32_t row = 0; - int xloop, yloop; - - uint32_t *pvideo; - uint32_t fgcol; - - int x0,y0,x1,y1; - int xoff, yoff; /* x and y offset into image */ - - unsigned char *fntd; - - if (width == 0) { - LOG(("null width char!")); - return false; - } - - - y+=1; /* the coord is the bottom-left of the pixels offset by 1 to make - * it work since fb coords are the top-left of pixels - */ - - /* The part of the text displayed is cropped to the current context. */ - x0 = x; - y0 = y; - x1 = x + width; - y1 = y + height; - - if (!fb_plotters_clip_rect_ctx(&x0, &y0, &x1, &y1)) { - return true; /* text lies outside current clipping region */ - } - - /* find width and height to plot */ - if (height > (y1 - y0)) - height = (y1 - y0); - - if (width > (x1 - x0)) - width = (x1 - x0); - - xoff = x0 - x; - yoff = y0 - y; - - fgcol = fb_colour_to_pixel(c); - - pvideo = fb_32bpp_get_xy_loc(x, y0); - - for (yloop = yoff; yloop < height; yloop++) { - fntd = bp->buffer + (yloop * bp->pitch); - for (xloop = 0; xloop < width ; xloop++) { - if ((xloop % 8) == 0) { - row = *fntd++; - } - - if ((row & 0x80) != 0) { - *(pvideo + xloop) = fgcol; - } - row = row << 1; - } - - pvideo += (framebuffer->linelen >> 2); - } - - - return true; -} - -static bool -fb_32bpp_draw_ft_bitmap(FT_Bitmap *bp, int x, int y, colour c) -{ - uint32_t *pvideo; - uint8_t *pixel = (uint8_t *)bp->buffer; - colour abpixel; /* alphablended pixel */ - int xloop, yloop; - int x0,y0,x1,y1; - int xoff, yoff; /* x and y offset into image */ - int height = bp->rows; - int width = bp->width; - uint32_t fgcol; - - /* The part of the scaled image actually displayed is cropped to the - * current context. - */ - x0 = x; - y0 = y; - x1 = x + width; - y1 = y + height; - - if (!fb_plotters_clip_rect_ctx(&x0, &y0, &x1, &y1)) - return true; - - if (height > (y1 - y0)) - height = (y1 - y0); - - if (width > (x1 - x0)) - width = (x1 - x0); - - xoff = x0 - x; - yoff = y0 - y; - - /* plot the image */ - pvideo = fb_32bpp_get_xy_loc(x0, y0); - - fgcol = c & 0xFFFFFF; - - for (yloop = 0; yloop < height; yloop++) { - for (xloop = 0; xloop < width; xloop++) { - abpixel = (pixel[((yoff + yloop) * bp->pitch) + xloop + xoff] << 24) | fgcol; - if ((abpixel & 0xFF000000) != 0) { - /* pixel is not transparent */ - if ((abpixel & 0xFF000000) != 0xFF000000) { - abpixel = fb_plotters_ablend(abpixel, - fb_32bpp_to_colour(*(pvideo + xloop))); - } - - *(pvideo + xloop) = fb_colour_to_pixel(abpixel); - } - } - pvideo += (framebuffer->linelen >> 2); - } - - return true; -} - -static bool fb_32bpp_text(int x, int y, const struct css_style *style, - const char *text, size_t length, colour bg, colour c) -{ - uint32_t ucs4; - size_t nxtchr = 0; - FT_Glyph glyph; - FT_BitmapGlyph bglyph; - - while (nxtchr < length) { - ucs4 = utf8_to_ucs4(text + nxtchr, length - nxtchr); - nxtchr = utf8_next(text, length, nxtchr); - - glyph = fb_getglyph(style, ucs4); - if (glyph == NULL) - continue; - - if (glyph->format == FT_GLYPH_FORMAT_BITMAP) { - bglyph = (FT_BitmapGlyph)glyph; - - /* now, draw to our target surface */ - if (bglyph->bitmap.pixel_mode == FT_PIXEL_MODE_MONO) { - fb_32bpp_draw_ft_monobitmap(&bglyph->bitmap, - x + bglyph->left, - y - bglyph->top, - c); - } else { - fb_32bpp_draw_ft_bitmap(&bglyph->bitmap, - x + bglyph->left, - y - bglyph->top, - c); - } - } - x += glyph->advance.x >> 16; - - } - return true; -} -#else -static bool fb_32bpp_text(int x, int y, const struct css_style *style, - const char *text, size_t length, colour bg, colour c) -{ - const struct fb_font_desc* fb_font = fb_get_font(style); - const uint32_t *font_data; - uint32_t row; - int xloop, yloop; - size_t chr; - - uint32_t *pvideo; - uint32_t fgcol; - - unsigned char *buffer = NULL; - int x0,y0,x1,y1; - int xoff, yoff; /* x and y offset into image */ - int height = fb_font->height; - - /* aquire thge text in local font encoding */ - utf8_to_font_encoding(fb_font, text, length, (char**)&buffer); - if (!buffer) - return true; - length = strlen((char *)buffer); - - - /* y is given to the fonts baseline we need it to the fonts top */ - y-=((fb_font->height * 75)/100); - - y+=1; /* the coord is the bottom-left of the pixels offset by 1 to make - * it work since fb coords are the top-left of pixels - */ - - /* The part of the text displayed is cropped to the current context. */ - x0 = x; - y0 = y; - x1 = x + (fb_font->width * length); - y1 = y + fb_font->height; - - if (!fb_plotters_clip_rect_ctx(&x0, &y0, &x1, &y1)) { - free(buffer); - return true; /* text lies outside current clipping region */ - } - - /* find width and height to plot */ - if (height > (y1 - y0)) - height = (y1 - y0); - - xoff = x0 - x; - yoff = y0 - y; - - fgcol = fb_colour_to_pixel(c); - - /*LOG(("x %d, y %d, style %p, txt %.*s , len %d, bg 0x%lx, fg 0x%lx", - x,y,style,length,text,length,bg,c));*/ - - for (chr = 0; chr < length; chr++, x += fb_font->width) { - if ((x + fb_font->width) > x1) - break; - - if (x < x0) - continue; - - pvideo = fb_32bpp_get_xy_loc(x, y0); - - /* move our font-data to the correct position */ - font_data = fb_font->data + (buffer[chr] * fb_font->height); - - for (yloop = 0; yloop < height; yloop++) { - row = font_data[yoff + yloop]; - for (xloop = fb_font->width; xloop > 0 ; xloop--) { - if ((row & 1) != 0) - *(pvideo + xloop) = fgcol; - row = row >> 1; - } - pvideo += (framebuffer->linelen >> 2); - } - } - - free(buffer); - return true; -} -#endif - -static bool fb_32bpp_disc(int x, int y, int radius, colour c, bool filled) -{ - LOG(("disc unimplemented")); - return true; -} - -static bool fb_32bpp_arc(int x, int y, int radius, int angle1, int angle2, - colour c) -{ - LOG(("arc unimplemented")); - return true; -} - - -static bool fb_32bpp_bitmap(int x, int y, int width, int height, - struct bitmap *bitmap, colour bg, - struct content *content) -{ - uint32_t *pvideo; - colour *pixel = (colour *)bitmap->pixdata; - colour abpixel = 0; /* alphablended pixel */ - int xloop, yloop; - int x0,y0,x1,y1; - int xoff, yoff; /* x and y offset into image */ - - /* LOG(("x %d, y %d, width %d, height %d, bitmap %p, content %p", - x,y,width,height,bitmap,content));*/ - - /* TODO here we should scale the image from bitmap->width to width, for - * now simply crop. - */ - if (width > bitmap->width) - width = bitmap->width; - - if (height > bitmap->height) - height = bitmap->height; - - /* The part of the scaled image actually displayed is cropped to the - * current context. - */ - x0 = x; - y0 = y; - x1 = x + width; - y1 = y + height; - - if (!fb_plotters_clip_rect_ctx(&x0, &y0, &x1, &y1)) - return true; - - if (height > (y1 - y0)) - height = (y1 - y0); - - if (width > (x1 - x0)) - width = (x1 - x0); - - xoff = x0 - x; - yoff = (y0 - y) * bitmap->width; - height = height * bitmap->width + yoff; - - /* plot the image */ - pvideo = fb_32bpp_get_xy_loc(x0, y0); - - if (bitmap->opaque) { - for (yloop = yoff; yloop < height; yloop += bitmap->width) { - for (xloop = 0; xloop < width; xloop++) { - abpixel = pixel[yloop + xloop + xoff]; - *(pvideo + xloop) = fb_colour_to_pixel(abpixel); - } - pvideo += (framebuffer->linelen >> 2); - } - } else { - for (yloop = yoff; yloop < height; yloop += bitmap->width) { - for (xloop = 0; xloop < width; xloop++) { - abpixel = pixel[yloop + xloop + xoff]; - if ((abpixel & 0xFF000000) != 0) { - if ((abpixel & 0xFF000000) != 0xFF000000) { - abpixel = fb_plotters_ablend(abpixel, - fb_32bpp_to_colour(*(pvideo + xloop))); - } - - *(pvideo + xloop) = fb_colour_to_pixel(abpixel); - } - } - pvideo += (framebuffer->linelen >> 2); - } - } - return true; -} - - -static bool fb_32bpp_bitmap_tile(int x, int y, int width, int height, - struct bitmap *bitmap, colour bg, - bool repeat_x, bool repeat_y, - struct content *content) -{ - return fb_plotters_bitmap_tile(x, y, width, height, - bitmap, bg, repeat_x, repeat_y, - content, fb_32bpp_bitmap); -} - -static bool fb_32bpp_flush(void) -{ - LOG(("flush unimplemnted")); - return true; -} - -static bool fb_32bpp_path(const float *p, unsigned int n, colour fill, float width, - colour c, const float transform[6]) -{ - LOG(("path unimplemented")); - return true; -} - - -const struct plotter_table framebuffer_32bpp_plot = { - .clg = fb_32bpp_clg, - .rectangle = fb_32bpp_rectangle, - .line = fb_32bpp_line, - .polygon = fb_32bpp_polygon, - .fill = fb_32bpp_fill, - .clip = fb_clip, - .text = fb_32bpp_text, - .disc = fb_32bpp_disc, - .arc = fb_32bpp_arc, - .bitmap = fb_32bpp_bitmap, - .bitmap_tile = fb_32bpp_bitmap_tile, - .flush = fb_32bpp_flush, - .path = fb_32bpp_path, - .option_knockout = true, -}; - -/* - * Local Variables: - * c-basic-offset:8 - * End: - */ diff --git a/framebuffer/fb_8bpp_plotters.c b/framebuffer/fb_8bpp_plotters.c deleted file mode 100644 index 7616f4f07..000000000 --- a/framebuffer/fb_8bpp_plotters.c +++ /dev/null @@ -1,463 +0,0 @@ -/* - * Copyright 2008 Vincent Sanders - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include - -#include "utils/log.h" -#include "utils/utf8.h" -#include "desktop/plotters.h" - -#include "framebuffer/fb_gui.h" -#include "framebuffer/fb_plotters.h" -#include "framebuffer/fb_bitmap.h" -#include "framebuffer/fb_font.h" - -static inline uint8_t * -fb_8bpp_get_xy_loc(int x, int y) -{ - return (uint8_t *)(framebuffer->ptr + - (y * framebuffer->linelen) + - (x)); -} - - -static bool fb_8bpp_line(int x0, int y0, int x1, int y1, int width, - colour c, bool dotted, bool dashed) -{ - LOG(("%d, %d, %d, %d, %d, 0x%lx, %d, %d", - x0, y0, x1, y1, width, (unsigned long)c, dotted, dashed)); - - return true; -} - -static bool fb_8bpp_rectangle(int x0, int y0, int width, int height, - int line_width, colour c, bool dotted, bool dashed) -{ - fb_8bpp_line(x0, y0, x0 + width, y0, line_width, c, dotted, dashed); - fb_8bpp_line(x0, y0 + height, x0 + width, y0 + height, line_width, c, dotted, dashed); - fb_8bpp_line(x0, y0, x0, y0 + height, line_width, c, dotted, dashed); - fb_8bpp_line(x0 + width, y0, x0 + width, y0 + height, line_width, c, dotted, dashed); - return true; -} - -static bool fb_8bpp_polygon(const int *p, unsigned int n, colour fill) -{ - /*LOG(("%p, %d, 0x%lx", p,n,fill));*/ - return fb_plotters_polygon(p, n, fill, fb_8bpp_line); -} - -static int -find_closest_palette_entry(colour c) -{ - colour palent; - int col; - - int dr, dg, db; /* delta red, green blue values */ - - int cur_distance; - int best_distance = INT_MAX; - int best_col = 0; - - for (col = 0; col < 256; col++) { - palent = framebuffer->palette[col]; - - dr = (c & 0xFF) - (palent & 0xFF); - dg = ((c >> 8) & 0xFF) - ((palent >> 8) & 0xFF); - db = ((c >> 16) & 0xFF) - ((palent >> 16) & 0xFF); - cur_distance = ((dr * dr) + (dg * dg) + (db *db)); - if (cur_distance < best_distance) { - best_distance = cur_distance; - best_col = col; - } - } - - return best_col; -} - -static inline uint8_t fb_colour_to_pixel(colour c) -{ - return find_closest_palette_entry(c); -} - -static inline colour fb_8bpp_to_colour(uint8_t pixel) -{ - return framebuffer->palette[pixel]; -} - -static bool fb_8bpp_fill(int x0, int y0, int x1, int y1, colour c) -{ - int y; - uint8_t ent; - uint8_t *pvideo; - - if (!fb_plotters_clip_rect_ctx(&x0, &y0, &x1, &y1)) - return true; /* fill lies outside current clipping region */ - - pvideo = fb_8bpp_get_xy_loc(x0, y0); - - ent = find_closest_palette_entry(c); - - for (y = y0; y < y1; y++) { - memset(pvideo, ent, x1 - x0); - pvideo += framebuffer->linelen; - } - - return true; -} - -static bool fb_8bpp_clg(colour c) -{ - LOG(("colour %lx", (unsigned long)c)); - fb_8bpp_fill(fb_plot_ctx.x0, - fb_plot_ctx.y0, - fb_plot_ctx.x1, - fb_plot_ctx.y1, - c); - return true; -} - -#ifdef FB_USE_FREETYPE - -static bool -fb_8bpp_draw_ft_monobitmap(FT_Bitmap *bp, int x, int y, colour c) -{ - return false; -} - -static bool -fb_8bpp_draw_ft_bitmap(FT_Bitmap *bp, int x, int y, colour c) -{ - uint8_t *pvideo; - uint8_t *pixel = (uint8_t *)bp->buffer; - colour abpixel; /* alphablended pixel */ - int xloop, yloop; - int x0,y0,x1,y1; - int xoff, yoff; /* x and y offset into image */ - int height = bp->rows; - int width = bp->width; - uint32_t fgcol; - - /* The part of the scaled image actually displayed is cropped to the - * current context. - */ - x0 = x; - y0 = y; - x1 = x + width; - y1 = y + height; - - if (!fb_plotters_clip_rect_ctx(&x0, &y0, &x1, &y1)) - return true; - - if (height > (y1 - y0)) - height = (y1 - y0); - - if (width > (x1 - x0)) - width = (x1 - x0); - - xoff = x0 - x; - yoff = y0 - y; - - /* plot the image */ - pvideo = fb_8bpp_get_xy_loc(x0, y0); - - fgcol = c & 0xFFFFFF; - - for (yloop = 0; yloop < height; yloop++) { - for (xloop = 0; xloop < width; xloop++) { - abpixel = (pixel[((yoff + yloop) * bp->pitch) + xloop + xoff] << 24) | fgcol; - if ((abpixel & 0xFF000000) != 0) { - if ((abpixel & 0xFF000000) != 0xFF000000) { - abpixel = fb_plotters_ablend(abpixel, - fb_8bpp_to_colour(*(pvideo + xloop))); - } - - *(pvideo + xloop) = fb_colour_to_pixel(abpixel); - - } - } - pvideo += framebuffer->linelen; - } - - return true; -} - -static bool fb_8bpp_text(int x, int y, const struct css_style *style, - const char *text, size_t length, colour bg, colour c) -{ - uint32_t ucs4; - size_t nxtchr = 0; - FT_Glyph glyph; - FT_BitmapGlyph bglyph; - - while (nxtchr < length) { - ucs4 = utf8_to_ucs4(text + nxtchr, length - nxtchr); - nxtchr = utf8_next(text, length, nxtchr); - - glyph = fb_getglyph(style, ucs4); - if (glyph == NULL) - continue; - if (glyph->format == FT_GLYPH_FORMAT_BITMAP) { - bglyph = (FT_BitmapGlyph)glyph; - - /* now, draw to our target surface */ - if (bglyph->bitmap.pixel_mode == FT_PIXEL_MODE_MONO) { - fb_8bpp_draw_ft_monobitmap(&bglyph->bitmap, - x + bglyph->left, - y - bglyph->top, - c); - } else { - fb_8bpp_draw_ft_bitmap(&bglyph->bitmap, - x + bglyph->left, - y - bglyph->top, - c); - } - } - x += glyph->advance.x >> 16; - - } - return true; - -} -#else -static bool fb_8bpp_text(int x, int y, const struct css_style *style, - const char *text, size_t length, colour bg, colour c) -{ - const struct fb_font_desc* fb_font = fb_get_font(style); - const uint32_t *font_data; - uint32_t row; - - int xloop, yloop; - size_t chr; - - uint8_t *pvideo; - uint8_t fgcol; - - unsigned char *buffer = NULL; - int x0,y0,x1,y1; - int xoff, yoff; /* x and y offset into image */ - int height = fb_font->height; - - /* aquire thge text in local font encoding */ - utf8_to_font_encoding(fb_font, text, length, (char **)&buffer); - if (!buffer) - return true; - length = strlen((char *)buffer); - - - /* y is given to the fonts baseline we need it to the fonts top */ - y-=((fb_font->height * 75)/100); - - y+=1; /* the coord is the bottom-left of the pixels offset by 1 to make - * it work since fb coords are the top-left of pixels - */ - - /* The part of the text displayed is cropped to the current context. */ - x0 = x; - y0 = y; - x1 = x + (fb_font->width * length); - y1 = y + fb_font->height; - - if (!fb_plotters_clip_rect_ctx(&x0, &y0, &x1, &y1)) - return true; /* text lies outside current clipping region */ - - /* find width and height to plot */ - if (height > (y1 - y0)) - height = (y1 - y0); - - xoff = x0 - x; - yoff = y0 - y; - - fgcol = find_closest_palette_entry(c); - - /*LOG(("x %d, y %d, style %p, txt %.*s , len %d, bg 0x%lx, fg 0x%lx", - x,y,style,length,text,length,bg,c));*/ - - for (chr = 0; chr < length; chr++, x += fb_font->width) { - if ((x + fb_font->width) > x1) - break; - - if (x < x0) - continue; - - pvideo = fb_8bpp_get_xy_loc(x, y0); - - /* move our font-data to the correct position */ - font_data = fb_font->data + (buffer[chr] * fb_font->height); - - for (yloop = 0; yloop < height; yloop++) { - row = font_data[yoff + yloop]; - for (xloop = fb_font->width; xloop > 0 ; xloop--) { - if ((row & 1) != 0) - *(pvideo + xloop) = fgcol; - row = row >> 1; - } - pvideo += framebuffer->linelen; - } - } - - free(buffer); - return true; -} -#endif - -static bool fb_8bpp_disc(int x, int y, int radius, colour c, bool filled) -{ - LOG(("x %d, y %d, rad %d, c 0x%lx, fill %d", x, y, radius, (unsigned long)c, filled)); - return true; -} - -static bool fb_8bpp_arc(int x, int y, int radius, int angle1, int angle2, - colour c) -{ - LOG(("x %d, y %d, radius %d, angle1 %d, angle2 %d, c 0x%lx", - x, y, radius, angle1, angle2, (unsigned long)c)); - return true; -} - - - -static bool fb_8bpp_bitmap(int x, int y, int width, int height, - struct bitmap *bitmap, colour bg, - struct content *content) -{ - uint8_t *pvideo; - colour *pixel = (colour *)bitmap->pixdata; - colour abpixel; /* alphablended pixel */ - int xloop, yloop; - int x0,y0,x1,y1; - int xoff, yoff; /* x and y offset into image */ - - /* LOG(("x %d, y %d, width %d, height %d, bitmap %p, content %p", - x,y,width,height,bitmap,content));*/ - - /* TODO here we should scale the image from bitmap->width to width, for - * now simply crop. - */ - if (width > bitmap->width) - width = bitmap->width; - - if (height > bitmap->height) - height = bitmap->height; - - /* The part of the scaled image actually displayed is cropped to the - * current context. - */ - x0 = x; - y0 = y; - x1 = x + width; - y1 = y + height; - - if (!fb_plotters_clip_rect_ctx(&x0, &y0, &x1, &y1)) - return true; - - if (height > (y1 - y0)) - height = (y1 - y0); - - if (width > (x1 - x0)) - width = (x1 - x0); - - xoff = x0 - x; - yoff = (y0 - y) * bitmap->width; - height = height * bitmap->width + yoff; - - /* plot the image */ - pvideo = fb_8bpp_get_xy_loc(x0, y0); - - if (bitmap->opaque) { - for (yloop = yoff; yloop < height; yloop += bitmap->width) { - for (xloop = 0; xloop < width; xloop++) { - abpixel = pixel[yloop + xloop + xoff]; - *(pvideo + xloop) = fb_colour_to_pixel(abpixel); - } - pvideo += framebuffer->linelen; - } - } else { - for (yloop = yoff; yloop < height; yloop += bitmap->width) { - for (xloop = 0; xloop < width; xloop++) { - abpixel = pixel[yloop + xloop + xoff]; - if ((abpixel & 0xFF000000) != 0) { - if ((abpixel & 0xFF000000) != 0xFF000000) { - abpixel = fb_plotters_ablend(abpixel, - fb_8bpp_to_colour(*(pvideo + xloop))); - } - - *(pvideo + xloop) = fb_colour_to_pixel(abpixel); - } - } - pvideo += framebuffer->linelen; - } - } - - return true; -} - -static bool fb_8bpp_bitmap_tile(int x, int y, int width, int height, - struct bitmap *bitmap, colour bg, - bool repeat_x, bool repeat_y, - struct content *content) -{ - return fb_plotters_bitmap_tile(x, y, width, height, - bitmap, bg, repeat_x, repeat_y, - content, fb_8bpp_bitmap); -} - -static bool fb_8bpp_flush(void) -{ - LOG(("%s()\n", __func__)); - return true; -} - -static bool fb_8bpp_path(const float *p, - unsigned int n, - colour fill, - float width, - colour c, - const float transform[6]) -{ - LOG(("%f, %d, 0x%lx, %f, 0x%lx, %f", - *p, n, (unsigned long)fill, width, (unsigned long)c, *transform)); - - return true; -} - -const struct plotter_table framebuffer_8bpp_plot = { - .clg = fb_8bpp_clg, - .rectangle = fb_8bpp_rectangle, - .line = fb_8bpp_line, - .polygon = fb_8bpp_polygon, - .fill = fb_8bpp_fill, - .clip = fb_clip, - .text = fb_8bpp_text, - .disc = fb_8bpp_disc, - .arc = fb_8bpp_arc, - .bitmap = fb_8bpp_bitmap, - .bitmap_tile = fb_8bpp_bitmap_tile, - .flush = fb_8bpp_flush, - .path = fb_8bpp_path, - .option_knockout = true, -}; - - -/* - * Local Variables: - * c-basic-offset:8 - * End: - */ diff --git a/framebuffer/fb_bitmap.c b/framebuffer/fb_bitmap.c deleted file mode 100644 index 1c62898a3..000000000 --- a/framebuffer/fb_bitmap.c +++ /dev/null @@ -1,259 +0,0 @@ -/* - * Copyright 2008 Vincent Sanders - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include - -#include "assert.h" -#include "image/bitmap.h" -#include "framebuffer/fb_bitmap.h" - -#include "utils/log.h" - -/** - * Create a bitmap. - * - * \param width width of image in pixels - * \param height width of image in pixels - * \param state a flag word indicating the initial state - * \return an opaque struct bitmap, or NULL on memory exhaustion - */ - -void *bitmap_create(int width, int height, unsigned int state) -{ - struct bitmap *bitmap; - - LOG(("width %d, height %d, state %u",width,height,state)); - - bitmap = calloc(1 , sizeof(struct bitmap)); - if (bitmap) { - bitmap->pixdata = calloc(4, width * height); - if (bitmap->pixdata != NULL) { - bitmap->width = width; - bitmap->height = height; - bitmap->opaque = false; - } else { - free(bitmap); - bitmap=NULL; - } - } - - LOG(("bitmap %p", bitmap)); - - return bitmap; -} - - -/** - * Return a pointer to the pixel data in a bitmap. - * - * \param bitmap a bitmap, as returned by bitmap_create() - * \return pointer to the pixel buffer - * - * The pixel data is packed as BITMAP_FORMAT, possibly with padding at the end - * of rows. The width of a row in bytes is given by bitmap_get_rowstride(). - */ - -unsigned char *bitmap_get_buffer(void *bitmap) -{ - struct bitmap *bm = bitmap; - - if (bitmap == NULL) { - LOG(("NULL bitmap!")); - return NULL; - } - - return bm->pixdata; -} - - -/** - * Find the width of a pixel row in bytes. - * - * \param bitmap a bitmap, as returned by bitmap_create() - * \return width of a pixel row in the bitmap - */ - -size_t bitmap_get_rowstride(void *bitmap) -{ - struct bitmap *bm = bitmap; - - if (bitmap == NULL) { - LOG(("NULL bitmap!")); - return 0; - } - - return (bm->width) * 4; -} - - -/** - * Free a bitmap. - * - * \param bitmap a bitmap, as returned by bitmap_create() - */ - -void bitmap_destroy(void *bitmap) -{ - struct bitmap *bm = bitmap; - - if (bitmap == NULL) { - LOG(("NULL bitmap!")); - return; - } - - free(bm->pixdata); - free(bm); -} - - -/** - * Save a bitmap in the platform's native format. - * - * \param bitmap a bitmap, as returned by bitmap_create() - * \param path pathname for file - * \return true on success, false on error and error reported - */ - -bool bitmap_save(void *bitmap, const char *path, unsigned flags) -{ - return true; -} - - -/** - * The bitmap image has changed, so flush any persistant cache. - * - * \param bitmap a bitmap, as returned by bitmap_create() - */ -void bitmap_modified(void *bitmap) { -} - - -/** - * The bitmap image can be suspended. - * - * \param bitmap a bitmap, as returned by bitmap_create() - * \param private_word a private word to be returned later - * \param suspend the function to be called upon suspension - * \param resume the function to be called when resuming - */ -void bitmap_set_suspendable(void *bitmap, void *private_word, - void (*invalidate)(void *bitmap, void *private_word)) { -} - -/** - * Sets whether a bitmap should be plotted opaque - * - * \param bitmap a bitmap, as returned by bitmap_create() - * \param opaque whether the bitmap should be plotted opaque - */ -void bitmap_set_opaque(void *bitmap, bool opaque) -{ - struct bitmap *bm = bitmap; - - if (bitmap == NULL) { - LOG(("NULL bitmap!")); - return; - } - - LOG(("setting bitmap %p to %s", bm, opaque?"opaque":"transparent")); - bm->opaque = opaque; -} - - -/** - * Tests whether a bitmap has an opaque alpha channel - * - * \param bitmap a bitmap, as returned by bitmap_create() - * \return whether the bitmap is opaque - */ -bool bitmap_test_opaque(void *bitmap) -{ - int tst; - struct bitmap *bm = bitmap; - - if (bitmap == NULL) { - LOG(("NULL bitmap!")); - return false; - } - - tst = bm->width * bm->height; - - while (tst-- > 0) { - if (bm->pixdata[(tst << 2) + 3] != 0xff) { - LOG(("bitmap %p has transparency",bm)); - return false; - } - } - LOG(("bitmap %p is opaque", bm)); - return true; -} - - -/** - * Gets whether a bitmap should be plotted opaque - * - * \param bitmap a bitmap, as returned by bitmap_create() - */ -bool bitmap_get_opaque(void *bitmap) -{ - struct bitmap *bm = bitmap; - - if (bitmap == NULL) { - LOG(("NULL bitmap!")); - return false; - } - - return bm->opaque; -} - -int bitmap_get_width(void *bitmap) -{ - struct bitmap *bm = bitmap; - - if (bitmap == NULL) { - LOG(("NULL bitmap!")); - return 0; - } - - return(bm->width); -} - -int bitmap_get_height(void *bitmap) -{ - struct bitmap *bm = bitmap; - - if (bitmap == NULL) { - LOG(("NULL bitmap!")); - return 0; - } - - return(bm->height); -} - -size_t bitmap_get_bpp(void *bitmap) -{ - return 4; -} - -/* - * Local Variables: - * c-basic-offset:8 - * End: - */ diff --git a/framebuffer/fb_bitmap.h b/framebuffer/fb_bitmap.h deleted file mode 100644 index 9a75b0b13..000000000 --- a/framebuffer/fb_bitmap.h +++ /dev/null @@ -1,33 +0,0 @@ -/* - * Copyright 2008 Vincent Sanders - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef FRAMEBUFFER_BITMAP_H -#define FRAMEBUFFER_BITMAP_H - -struct bitmap { - int width; - int height; - uint8_t *pixdata; - bool opaque; - - /* The following two are only used for cursors */ - int hot_x; - int hot_y; -}; - -#endif diff --git a/framebuffer/fb_convert_image.c b/framebuffer/fb_convert_image.c deleted file mode 100644 index 4fb40a933..000000000 --- a/framebuffer/fb_convert_image.c +++ /dev/null @@ -1,307 +0,0 @@ -/* - * Copyright 2009 Daniel Silverstone - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include -#include - -static png_structp png; -static png_infop info; -static int interlace; -static size_t rowbytes; -static int raw_width, raw_height; -static int rowstride; -static unsigned char *bitmap_data; -static bool is_cursor = true; -static int raw_hot_x, raw_hot_y; - -#define WIDTH (is_cursor?raw_width-1:raw_width) -#define HEIGHT (is_cursor?raw_height-1:raw_height) - -#define HOT_X (is_cursor?raw_hot_x-1:0) -#define HOT_Y (is_cursor?raw_hot_y-1:0) - -#define REAL(v) (is_cursor?v+1:v) - -#define PPIX_AT(x,y) ((bitmap_data + (rowstride * y)) + (x * 4)) - -#define R_OFF 2 -#define G_OFF 1 -#define B_OFF 0 -#define A_OFF 3 - -#define R_AT(x,y) *(PPIX_AT(x,y) + R_OFF) -#define G_AT(x,y) *(PPIX_AT(x,y) + G_OFF) -#define B_AT(x,y) *(PPIX_AT(x,y) + B_OFF) -#define A_AT(x,y) *(PPIX_AT(x,y) + A_OFF) - -static void info_callback(png_structp png, png_infop info); -static void row_callback(png_structp png, png_bytep new_row, - png_uint_32 row_num, int pass); -static void end_callback(png_structp png, png_infop info); - - - -static void -usage(void) -{ - fprintf(stderr, "usage: fb_convert_image input.png output.inc varname\n"); -} - -static void info_callback(png_structp png, png_infop info); -static void row_callback(png_structp png, png_bytep new_row, - png_uint_32 row_num, int pass); -static void end_callback(png_structp png, png_infop info); - - -static void -detect_hotspot(void) -{ - int i; - int greenpixels = 0; - - for (i = 0; i < raw_width; ++i) { - if (A_AT(i, 0) == 255) { - if (G_AT(i, 0) == 255) { - greenpixels++; - raw_hot_x = i; - } - if ((B_AT(i, 0) != 0) || (R_AT(i, 0) != 0)) { - is_cursor = false; - return; - } - } else if (A_AT(i, 0) != 0) { - is_cursor = false; - return; - } - } - if (greenpixels != 1) { - is_cursor = false; - return; - } - - for (i = 0; i < raw_height; ++i) { - if (A_AT(0, i) == 255) { - if (G_AT(0, i) == 255) { - greenpixels++; - raw_hot_y = i; - } - if ((B_AT(0, i) != 0) || (R_AT(0, i) != 0)) { - is_cursor = false; - return; - } - } else if (A_AT(0, i) != 0) { - is_cursor = false; - return; - } - } - if (greenpixels != 2) { - is_cursor = false; - return; - } - printf(" Pointer detected. Adjusted hotspot at %d, %d (0-based)\n", - raw_hot_x - 1, raw_hot_y - 1); -} - -int -main(int argc, char **argv) -{ - FILE *f; - unsigned char buffer[1024]; - int br; - int x, y, c; - - if (argc != 4) { - usage(); - return 1; - } - - printf(" CONVERT: %s (%s)\n", argv[1], argv[3]); - - png = png_create_read_struct(PNG_LIBPNG_VER_STRING, 0, 0, 0); - info = png_create_info_struct(png); - - png_set_progressive_read_fn(png, NULL, info_callback, row_callback, end_callback); - - f = fopen(argv[1], "rb"); - if (f == NULL) { - printf(" Unable to open %s\n", argv[1]); - return 1; - } - - do { - br = fread(buffer, 1, 1024, f); - if (br > 0) { - png_process_data(png, info, buffer, br); - } - } while (br > 0); - - if (br < 0) { - printf("Error reading input: %s\n", strerror(errno)); - return 1; - } - - fclose(f); - - detect_hotspot(); - - f = fopen(argv[2], "w"); - if (f == NULL) { - printf(" Unable to open %s\n", argv[2]); - return 2; - } - - fprintf(f, "/* This file is auto-generated from %s\n", argv[1]); - fprintf(f, " *\n * Do not edit this file directly.\n */\n\n"); - fprintf(f, "#include \n\n"); - fprintf(f, "#include \n\n"); - fprintf(f, "#include \n\n"); - fprintf(f, "#include \"framebuffer/fb_bitmap.h\"\n\n"); - - fprintf(f, "static uint8_t %s_pixdata[] = {\n", argv[3]); - for (y = 0; y < HEIGHT; ++y) { - unsigned char *rowptr = bitmap_data + (rowstride * y); - if (is_cursor) { - /* If it's a cursor, skip one row and one column */ - rowptr += rowstride + 4; - } - fprintf(f, "\t"); - for (x = 0; x < WIDTH; ++x) { - for (c = 0; c < 4; ++c) { - unsigned char b = *rowptr++; - fprintf(f, "0x%02x, ", b); - } - } - fprintf(f, "\n"); - } - fprintf(f, "};\n\n"); - - fprintf(f, "struct bitmap %s = {\n", argv[3]); - fprintf(f, "\t.width\t\t= %d,\n", WIDTH); - fprintf(f, "\t.height\t\t= %d,\n", HEIGHT); - fprintf(f, "\t.hot_x\t\t= %d,\n", HOT_X); - fprintf(f, "\t.hot_y\t\t= %d,\n", HOT_Y); - fprintf(f, "\t.pixdata\t= %s_pixdata,\n", argv[3]); - - fprintf(f, "};\n\n"); - fclose(f); - - return 0; -} - -static void -info_callback(png_structp png, png_infop info) -{ - int bit_depth, color_type, interlace, intent; - double gamma; - unsigned long width, height; - - /* Read the PNG details */ - png_get_IHDR(png, info, &width, &height, &bit_depth, - &color_type, &interlace, 0, 0); - - /* Set up our transformations */ - if (color_type == PNG_COLOR_TYPE_PALETTE) - png_set_palette_to_rgb(png); - if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) - png_set_gray_1_2_4_to_8(png); - if (png_get_valid(png, info, PNG_INFO_tRNS)) - png_set_tRNS_to_alpha(png); - if (bit_depth == 16) - png_set_strip_16(png); - if (color_type == PNG_COLOR_TYPE_GRAY || - color_type == PNG_COLOR_TYPE_GRAY_ALPHA) - png_set_gray_to_rgb(png); - if (!(color_type & PNG_COLOR_MASK_ALPHA)) - png_set_filler(png, 0xff, PNG_FILLER_AFTER); - /* gamma correction - we use 2.2 as our screen gamma - * this appears to be correct (at least in respect to !Browse) - * see http://www.w3.org/Graphics/PNG/all_seven.html for a test case - */ - if (png_get_sRGB(png, info, &intent)) - png_set_gamma(png, 2.2, 0.45455); - else { - if (png_get_gAMA(png, info, &gamma)) - png_set_gamma(png, 2.2, gamma); - else - png_set_gamma(png, 2.2, 0.45455); - } - - - png_read_update_info(png, info); - - rowbytes = png_get_rowbytes(png, info); - interlace = (interlace == PNG_INTERLACE_ADAM7); - raw_width = width; - raw_height = height; - - rowstride = raw_width * 4; - bitmap_data = malloc(rowstride * raw_height); -} - -static unsigned int interlace_start[8] = {0, 16, 0, 8, 0, 4, 0}; -static unsigned int interlace_step[8] = {28, 28, 12, 12, 4, 4, 0}; -static unsigned int interlace_row_start[8] = {0, 0, 4, 0, 2, 0, 1}; -static unsigned int interlace_row_step[8] = {8, 8, 8, 4, 4, 2, 2}; - -static void -row_callback(png_structp png, png_bytep new_row, - png_uint_32 row_num, int pass) -{ - unsigned long i, j; - unsigned int start, step; - unsigned char *row = bitmap_data + (rowstride * row_num); - - if (new_row == 0) - return; - - if (interlace) { - start = interlace_start[pass]; - step = interlace_step[pass]; - row_num = interlace_row_start[pass] + - interlace_row_step[pass] * row_num; - - /* Copy the data to our current row taking interlacing - * into consideration */ - row = bitmap_data + (rowstride * row_num); - for (j = 0, i = start; i < rowbytes; i += step) { - row[i++] = new_row[j++]; - row[i++] = new_row[j++]; - row[i++] = new_row[j++]; - row[i++] = new_row[j++]; - } - } else { - memcpy(row, new_row, rowbytes); - } -} - -static void -end_callback(png_structp png, png_infop info) -{ -} - - - -/* - * Local Variables: - * c-basic-offset:8 - * End: - */ - diff --git a/framebuffer/fb_cursor.c b/framebuffer/fb_cursor.c deleted file mode 100644 index a5e77e543..000000000 --- a/framebuffer/fb_cursor.c +++ /dev/null @@ -1,236 +0,0 @@ -/* - * Copyright 2008 Vincent Sanders - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include - -#include "utils/log.h" -#include "utils/utf8.h" -#include "desktop/plotters.h" -#include "desktop/browser.h" -#include "image/bitmap.h" - -#include "framebuffer/fb_gui.h" -#include "framebuffer/fb_tk.h" -#include "framebuffer/fb_plotters.h" -#include "framebuffer/fb_bitmap.h" -#include "framebuffer/fb_cursor.h" -#include "framebuffer/fb_frontend.h" -#include "framebuffer/fb_image_data.h" - -struct fb_cursor_s { - int x; - int y; - int width; /**< width */ - int height; /**< height */ - - bool plotted; - - struct bitmap *bitmap; /* pointer bitmap */ - - uint8_t *savedata; /* save under area */ -}; - - -static void fb_cursor_save(framebuffer_t *fb) -{ - uint8_t *savebuf; - int savelen; - uint8_t *pvid; - int yloop; - int height = fb->cursor->height; - - if ((fb->height - fb->cursor->y) < height) - height = fb->height - fb->cursor->y; - - if (height == 0) { - if (fb->cursor->savedata != NULL) - free(fb->cursor->savedata); - fb->cursor->savedata = NULL; - return; - } - - savelen = ((fb->cursor->width * fb->bpp) / 8); - savebuf = malloc(savelen * height); - if (savebuf == NULL) - return; - - if (fb->cursor->savedata != NULL) - free(fb->cursor->savedata); - - fb->cursor->savedata = savebuf; - - pvid = fb->ptr + - (fb->cursor->y * fb->linelen) + - ((fb->cursor->x * fb->bpp) / 8); - - for (yloop=0; yloop < height; yloop++) { - memcpy(savebuf, pvid, savelen); - savebuf += savelen; - pvid += fb->linelen; - } -} - -void fb_cursor_clear(framebuffer_t *fb) -{ - uint8_t *savebuf; - int savelen; - uint8_t *pvid; - int yloop; - int height = fb->cursor->height; - bbox_t cursorbox; - - if ((fb->height - fb->cursor->y) < height) - height = fb->height - fb->cursor->y ; - - if (height == 0) - return; - - if (fb->cursor->plotted == false) - return; - fb->cursor->plotted = false; - - savebuf = fb->cursor->savedata; - if (savebuf == NULL) - return; - - savelen = ((fb->cursor->width * fb->bpp) / 8); - - pvid = fb->ptr + - (fb->cursor->y * fb->linelen) + - ((fb->cursor->x * fb->bpp) / 8); - - for (yloop=0; yloop < height; yloop++) { - memcpy(pvid, savebuf, savelen); - savebuf += savelen; - pvid += fb->linelen; - } - - /* callback to the os specific routine in case it needs to do something - * explicit to redraw - */ - cursorbox.x0 = fb->cursor->x; - cursorbox.y0 = fb->cursor->y; - cursorbox.x1 = fb->cursor->x + fb->cursor->width; - cursorbox.y1 = fb->cursor->y + fb->cursor->height; - fb_os_redraw(&cursorbox); - -} - -/* move cursor to absolute position */ -void -fb_cursor_move(framebuffer_t *fb, int x, int y) -{ - fb_cursor_clear(fb); - - fb->cursor->x = x; - fb->cursor->y = y; - if (fb->cursor->x < 0) - fb->cursor->x = 0; - if (fb->cursor->y < 0) - fb->cursor->y = 0; - if (fb->cursor->x > fb->width) - fb->cursor->x = fb->width; - if (fb->cursor->y > fb->height) - fb->cursor->y = fb->height; -} - -void -fb_cursor_plot(framebuffer_t *fb) -{ - bbox_t saved_plot_ctx; - bbox_t cursorbox; - - /* if cursor is not currently plotted give up early */ - if (fb->cursor->plotted) - return; - - /* enlarge the clipping rectangle to the whole screen for plotting the - * cursor - */ - saved_plot_ctx = fb_plot_ctx; - - fb_plot_ctx.x0 = 0; - fb_plot_ctx.y0 = 0; - fb_plot_ctx.x1 = fb->width; - fb_plot_ctx.y1 = fb->height; - - /* save under the cursor */ - fb_cursor_save(fb); - - /* plot the cursor image */ - plot.bitmap(fb->cursor->x, fb->cursor->y, - fb->cursor->width, fb->cursor->height, - fb->cursor->bitmap, 0, NULL); - - /* callback to the os specific routine in case it needs to do something - * explicit to redraw - */ - cursorbox.x0 = fb->cursor->x; - cursorbox.y0 = fb->cursor->y; - cursorbox.x1 = fb->cursor->x + fb->cursor->width; - cursorbox.y1 = fb->cursor->y + fb->cursor->height; - fb_os_redraw(&cursorbox); - - fb->cursor->plotted = true; - - /* restore clipping rectangle */ - fb_plot_ctx = saved_plot_ctx; -} - -void -fb_cursor_set(fb_cursor_t *cursor, struct bitmap *bmp) -{ - cursor->width = bmp->width; - cursor->height = bmp->height; - cursor->bitmap = bmp; -} - -fb_cursor_t * -fb_cursor_init(framebuffer_t *fb, struct bitmap *bmp) -{ - fb_cursor_t *cursor; - cursor = calloc(1, sizeof(fb_cursor_t)); - - cursor->x = fb->width / 2; - cursor->y = fb->height / 2; - cursor->plotted = false; - - fb_cursor_set(cursor, bmp); - - return cursor; -} - -int fb_cursor_x(framebuffer_t *fb) -{ - return fb->cursor->x; -} - -int fb_cursor_y(framebuffer_t *fb) -{ - return fb->cursor->y; -} - - -/* - * Local Variables: - * c-basic-offset:8 - * End: - */ diff --git a/framebuffer/fb_cursor.h b/framebuffer/fb_cursor.h deleted file mode 100644 index b875cea4e..000000000 --- a/framebuffer/fb_cursor.h +++ /dev/null @@ -1,38 +0,0 @@ -/* - * Copyright 2008 Vincent Sanders - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef FRAMEBUFFER_FB_CURSOR -#define FRAMEBUFFER_FB_CURSOR - -int fb_cursor_x(framebuffer_t *fb); - -int fb_cursor_y(framebuffer_t *fb); - -void fb_cursor_move(struct framebuffer_s *fb, int x, int y); - -void fb_cursor_plot(struct framebuffer_s *fb); - -void fb_cursor_clear(struct framebuffer_s *fb); - -void fb_cursor_set(fb_cursor_t *cursor, struct bitmap *bmp); - -fb_cursor_t *fb_cursor_init(struct framebuffer_s *fb, struct bitmap *bmp); - -void fb_cursor_click(framebuffer_t *fb, struct gui_window *g, browser_mouse_state st); - -#endif diff --git a/framebuffer/fb_filetype.c b/framebuffer/fb_filetype.c deleted file mode 100644 index d15890ce4..000000000 --- a/framebuffer/fb_filetype.c +++ /dev/null @@ -1,55 +0,0 @@ -/* - * Copyright 2003 James Bursa - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include "content/fetch.h" -#include "utils/log.h" -#include "utils/utils.h" - -/** - * filetype -- determine the MIME type of a local file - */ - -const char *fetch_filetype(const char *unix_path) -{ - int l; - LOG(("unix path %s", unix_path)); - l = strlen(unix_path); - if (2 < l && strcasecmp(unix_path + l - 3, "css") == 0) - return "text/css"; - if (2 < l && strcasecmp(unix_path + l - 3, "jpg") == 0) - return "image/jpeg"; - if (3 < l && strcasecmp(unix_path + l - 4, "jpeg") == 0) - return "image/jpeg"; - if (2 < l && strcasecmp(unix_path + l - 3, "gif") == 0) - return "image/gif"; - if (2 < l && strcasecmp(unix_path + l - 3, "png") == 0) - return "image/png"; - if (2 < l && strcasecmp(unix_path + l - 3, "jng") == 0) - return "image/jng"; - if (2 < l && strcasecmp(unix_path + l - 3, "svg") == 0) - return "image/svg"; - return "text/html"; -} - - -char *fetch_mimetype(const char *ro_path) -{ - return strdup("text/plain"); -} diff --git a/framebuffer/fb_findfile.c b/framebuffer/fb_findfile.c deleted file mode 100644 index acfed41ca..000000000 --- a/framebuffer/fb_findfile.c +++ /dev/null @@ -1,106 +0,0 @@ -/* - * Copyright 2008 Daniel Silverstone - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include -#include -#include - -#include "utils/log.h" - -#include "fb_findfile.h" - -char *path_to_url(const char *path) -{ - char *r = malloc(strlen(path) + 7 + 1); - - strcpy(r, "file://"); - strcat(r, path); - - return r; -} - -/** - * Locate a shared resource file by searching known places in order. - * - * \param buf buffer to write to. must be at least PATH_MAX chars - * \param filename file to look for - * \param def default to return if file not found - * \return buf - * - * Search order is: ~/.netsurf/, $NETSURFRES/ (where NETSURFRES is an - * environment variable), and finally the path specified by NETSURF_FB_RESPATH - * from the Makefile - */ - -char *fb_find_resource(char *buf, const char *filename, const char *def) -{ - char *cdir = getenv("HOME"); - char t[PATH_MAX]; - - if (cdir != NULL) { - strcpy(t, cdir); - strcat(t, "/.netsurf/"); - strcat(t, filename); - if (realpath(t, buf) != NULL) { - if (access(buf, R_OK) == 0) - return buf; - } - } - - cdir = getenv("NETSURFRES"); - - if (cdir != NULL) { - if (realpath(cdir, buf) != NULL) { - strcat(buf, "/"); - strcat(buf, filename); - if (access(buf, R_OK) == 0) - return buf; - } - } - - strcpy(t, NETSURF_FB_RESPATH); - strcat(t, filename); - if (realpath(t, buf) != NULL) { - if (access(buf, R_OK) == 0) - return buf; - } - - if (def[0] == '~') { - snprintf(t, PATH_MAX, "%s%s", getenv("HOME"), def + 1); - if (realpath(t, buf) == NULL) { - strcpy(buf, t); - } - } else { - if (realpath(def, buf) == NULL) { - strcpy(buf, def); - } - } - - return buf; -} - - -/* - * Local Variables: - * c-basic-offset: 8 - * End: - */ - diff --git a/framebuffer/fb_findfile.h b/framebuffer/fb_findfile.h deleted file mode 100644 index 87b9a95e4..000000000 --- a/framebuffer/fb_findfile.h +++ /dev/null @@ -1,26 +0,0 @@ -/* - * Copyright 2008 Daniel Silverstone - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef NETSURF_FB_FINDFILE_H -#define NETSURF_FB_FINDFILE_H - -char *path_to_url(const char *path); - -extern char *fb_find_resource(char *buf, const char *filename, const char *def); - -#endif /* NETSURF_FB_FINDFILE_H */ diff --git a/framebuffer/fb_font.h b/framebuffer/fb_font.h deleted file mode 100644 index df29db2c1..000000000 --- a/framebuffer/fb_font.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * Copyright 2008 Vincent Sanders - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef NETSURF_FB_FONT_H -#define NETSURF_FB_FONT_H - -bool fb_font_init(void); -bool fb_font_finalise(void); - -#ifdef FB_USE_FREETYPE - -#include -#include FT_FREETYPE_H -#include - -FT_Glyph fb_getglyph(const struct css_style *style, uint32_t ucs4); - -extern int ft_load_type; - -#else - -#include "utils/utf8.h" - -struct fb_font_desc { - const char *name; - int width, height; - const char *encoding; - const uint32_t *data; -}; - -extern const struct fb_font_desc font_vga_8x16; - -extern const struct fb_font_desc* fb_get_font(const struct css_style *style); - -extern utf8_convert_ret utf8_to_font_encoding(const struct fb_font_desc* font, - const char *string, - size_t len, - char **result); -#endif - -#endif /* NETSURF_FB_FONT_H */ - diff --git a/framebuffer/fb_font_freetype.c b/framebuffer/fb_font_freetype.c deleted file mode 100644 index f88769f48..000000000 --- a/framebuffer/fb_font_freetype.c +++ /dev/null @@ -1,476 +0,0 @@ -/* - * Copyright 2005 James Bursa - * 2008 Vincent Sanders - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include - -#include - -#include "css/css.h" -#include "render/font.h" -#include "utils/utf8.h" -#include "utils/log.h" - -#include "framebuffer/fb_gui.h" -#include "framebuffer/fb_font.h" -#include "framebuffer/fb_options.h" -#include "framebuffer/fb_findfile.h" - -#define VERA_PATH "/usr/share/fonts/truetype/ttf-bitstream-vera/" - -static FT_Library library; -static FTC_Manager ft_cmanager; -static FTC_CMapCache ft_cmap_cache ; -static FTC_ImageCache ft_image_cache; - -int ft_load_type; - -/* cache manager faceID data to create freetype faceid on demand */ -typedef struct fb_faceid_s { - char *fontfile; /* path to font */ - int index; /* index of font */ - int cidx; /* character map index for unicode */ -} fb_faceid_t; - -/* defines for accesing the faces */ -#define FB_FACE_DEFAULT 0 - -#define FB_FACE_SANS_SERIF 0 -#define FB_FACE_SANS_SERIF_BOLD 1 -#define FB_FACE_SANS_SERIF_ITALIC 2 -#define FB_FACE_SANS_SERIF_ITALIC_BOLD 3 -#define FB_FACE_MONOSPACE 4 -#define FB_FACE_SERIF 5 -#define FB_FACE_SERIF_BOLD 6 - -#define FB_FACE_COUNT 7 - -static fb_faceid_t *fb_faces[FB_FACE_COUNT]; - - -utf8_convert_ret utf8_to_local_encoding(const char *string, - size_t len, - char **result) -{ - return utf8_to_enc(string, "UTF-8", len, result); -} - -/* map cache manager handle to face id */ -static FT_Error ft_face_requester(FTC_FaceID face_id, FT_Library library, FT_Pointer request_data, FT_Face *face ) -{ - FT_Error error; - fb_faceid_t *fb_face = (fb_faceid_t *)face_id; - int cidx; - - error = FT_New_Face(library, fb_face->fontfile, fb_face->index, face); - if (error) { - LOG(("Could not find font (code %d)\n", error)); - } else { - - error = FT_Select_Charmap(*face, FT_ENCODING_UNICODE); - if (error) { - LOG(("Could not select charmap (code %d)\n", error)); - } else { - for (cidx = 0; cidx < (*face)->num_charmaps; cidx++) { - if ((*face)->charmap == (*face)->charmaps[cidx]) { - fb_face->cidx = cidx; - break; - } - } - } - } - LOG(("Loaded face from %s\n", fb_face->fontfile)); - - return error; -} - -/* create new framebuffer face and cause it to be loaded to check its ok */ -static fb_faceid_t * -fb_new_face(const char *option, const char *resname, const char *fontfile) -{ - fb_faceid_t *newf; - FT_Error error; - FT_Face aface; - char buf[PATH_MAX]; - - newf = calloc(1, sizeof(fb_faceid_t)); - - if (option != NULL) { - newf->fontfile = strdup(option); - } else { - fb_find_resource(buf, resname, fontfile); - newf->fontfile = strdup(buf); - } - - error = FTC_Manager_LookupFace(ft_cmanager, (FTC_FaceID)newf, &aface); - if (error) { - LOG(("Could not find font face %s (code %d)\n", fontfile, error)); - free(newf); - newf = fb_faces[FB_FACE_DEFAULT]; /* use default */ - } - - return newf; -} - -/* initialise font handling */ -bool fb_font_init(void) -{ - FT_Error error; - FT_ULong max_cache_size; - FT_UInt max_faces = 6; - - /* freetype library initialise */ - error = FT_Init_FreeType( &library ); - if (error) { - LOG(("Freetype could not initialised (code %d)\n", error)); - return false; - } - - max_cache_size = 2 * 1024 *1024; /* 2MB should be enough */ - - /* cache manager initialise */ - error = FTC_Manager_New(library, - max_faces, - 0, - max_cache_size, - ft_face_requester, - NULL, - &ft_cmanager); - if (error) { - LOG(("Freetype could not initialise cache manager (code %d)\n", error)); - FT_Done_FreeType(library); - return false; - } - - error = FTC_CMapCache_New(ft_cmanager, &ft_cmap_cache); - - error = FTC_ImageCache_New(ft_cmanager, &ft_image_cache); - - fb_faces[FB_FACE_SANS_SERIF] = NULL; - fb_faces[FB_FACE_SANS_SERIF] = - fb_new_face(option_fb_face_sans_serif, - "sans_serif.ttf", - VERA_PATH"Vera.ttf"); - if (fb_faces[FB_FACE_SANS_SERIF] == NULL) { - LOG(("Could not find default font (code %d)\n", error)); - FTC_Manager_Done(ft_cmanager ); - FT_Done_FreeType(library); - return false; - } - - fb_faces[FB_FACE_SANS_SERIF_BOLD] = - fb_new_face(option_fb_face_sans_serif_bold, - "sans_serif_bold.ttf", - VERA_PATH"VeraBd.ttf"); - - fb_faces[FB_FACE_SANS_SERIF_ITALIC] = - fb_new_face(option_fb_face_sans_serif_italic, - "sans_serif_italic.ttf", - VERA_PATH"VeraIt.ttf"); - - fb_faces[FB_FACE_SANS_SERIF_ITALIC_BOLD] = - fb_new_face(option_fb_face_sans_serif_italic_bold, - "sans_serif_italic_bold.ttf", - VERA_PATH"VeraBI.ttf"); - - fb_faces[FB_FACE_MONOSPACE] = - fb_new_face(option_fb_face_monospace, - "monospace.ttf", - VERA_PATH"VeraMono.ttf"); - - fb_faces[FB_FACE_SERIF] = - fb_new_face(option_fb_face_serif, - "serif.ttf", - VERA_PATH"VeraSe.ttf"); - - fb_faces[FB_FACE_SERIF_BOLD] = - fb_new_face(option_fb_face_serif_bold, - "serif_bold.ttf", - VERA_PATH"VeraSeBd.ttf"); - - /* set the default render mode */ - if (option_fb_font_monochrome == true) - ft_load_type = FT_LOAD_MONOCHROME; /* faster but less pretty */ - else - ft_load_type = 0; - - return true; -} - -bool fb_font_finalise(void) -{ - FTC_Manager_Done(ft_cmanager ); - FT_Done_FreeType(library); - return true; -} - -static void fb_fill_scalar(const struct css_style *style, FTC_Scaler srec) -{ - int selected_face = FB_FACE_DEFAULT; - - switch (style->font_family) { - /* - case CSS_FONT_FAMILY_CURSIVE: - break; - case CSS_FONT_FAMILY_FANTASY: - break; - */ - case CSS_FONT_FAMILY_SERIF: - switch (style->font_weight) { - case CSS_FONT_WEIGHT_700: - case CSS_FONT_WEIGHT_800: - case CSS_FONT_WEIGHT_900: - case CSS_FONT_WEIGHT_BOLD: - selected_face = FB_FACE_SERIF_BOLD; - break; - - case CSS_FONT_WEIGHT_NORMAL: - default: - selected_face = FB_FACE_SERIF; - break; - } - - break; - - case CSS_FONT_FAMILY_MONOSPACE: - selected_face = FB_FACE_MONOSPACE; - break; - - case CSS_FONT_FAMILY_SANS_SERIF: - default: - switch (style->font_style) { - case CSS_FONT_STYLE_ITALIC: - switch (style->font_weight) { - case CSS_FONT_WEIGHT_700: - case CSS_FONT_WEIGHT_800: - case CSS_FONT_WEIGHT_900: - case CSS_FONT_WEIGHT_BOLD: - selected_face = FB_FACE_SANS_SERIF_ITALIC_BOLD; - break; - - case CSS_FONT_WEIGHT_NORMAL: - default: - selected_face = FB_FACE_SANS_SERIF_ITALIC; - break; - } - break; - - default: - switch (style->font_weight) { - case CSS_FONT_WEIGHT_700: - case CSS_FONT_WEIGHT_800: - case CSS_FONT_WEIGHT_900: - case CSS_FONT_WEIGHT_BOLD: - selected_face = FB_FACE_SANS_SERIF_BOLD; - break; - - case CSS_FONT_WEIGHT_NORMAL: - default: - selected_face = FB_FACE_SANS_SERIF; - break; - } - break; - } - } - - srec->face_id = (FTC_FaceID)fb_faces[selected_face]; - - if (style->font_size.value.length.unit == CSS_UNIT_PX) { - srec->width = srec->height = style->font_size.value.length.value; - srec->pixel = 1; - } else { - srec->width = srec->height = - css_len2pt(&style->font_size.value.length, style) * 64; - srec->pixel = 0; - - srec->x_res = srec->y_res = 72; - } - -} - -FT_Glyph fb_getglyph(const struct css_style *style, uint32_t ucs4) -{ - FT_UInt glyph_index; - FTC_ScalerRec srec; - FT_Glyph glyph; - FT_Error error; - fb_faceid_t *fb_face; - - fb_fill_scalar(style, &srec); - - fb_face = (fb_faceid_t *)srec.face_id; - - glyph_index = FTC_CMapCache_Lookup(ft_cmap_cache, srec.face_id, fb_face->cidx, ucs4); - - error = FTC_ImageCache_LookupScaler(ft_image_cache, - &srec, - FT_LOAD_RENDER | - FT_LOAD_FORCE_AUTOHINT | - ft_load_type, - glyph_index, - &glyph, - NULL); - - return glyph; -} - - -/** - * Measure the width of a string. - * - * \param style css_style for this text, with style->font_size.size == - * CSS_FONT_SIZE_LENGTH - * \param string UTF-8 string to measure - * \param length length of string - * \param width updated to width of string[0..length) - * \return true on success, false on error and error reported - */ -static bool nsfont_width(const struct css_style *style, - const char *string, size_t length, - int *width) -{ - uint32_t ucs4; - size_t nxtchr = 0; - FT_Glyph glyph; - - *width = 0; - while (nxtchr < length) { - ucs4 = utf8_to_ucs4(string + nxtchr, length - nxtchr); - nxtchr = utf8_next(string, length, nxtchr); - - glyph = fb_getglyph(style, ucs4); - if (glyph == NULL) - continue; - - *width += glyph->advance.x >> 16; - } - - return true; -} - -/** - * Find the position in a string where an x coordinate falls. - * - * \param style css_style for this text, with style->font_size.size == - * CSS_FONT_SIZE_LENGTH - * \param string UTF-8 string to measure - * \param length length of string - * \param x x coordinate to search for - * \param char_offset updated to offset in string of actual_x, [0..length] - * \param actual_x updated to x coordinate of character closest to x - * \return true on success, false on error and error reported - */ - -static bool nsfont_position_in_string(const struct css_style *style, - const char *string, size_t length, - int x, size_t *char_offset, int *actual_x) -{ - uint32_t ucs4; - size_t nxtchr = 0; - FT_Glyph glyph; - - *actual_x = 0; - while (nxtchr < length) { - ucs4 = utf8_to_ucs4(string + nxtchr, length - nxtchr); - - glyph = fb_getglyph(style, ucs4); - if (glyph == NULL) - continue; - - *actual_x += glyph->advance.x >> 16; - if (*actual_x > x) - break; - - nxtchr = utf8_next(string, length, nxtchr); - } - - *char_offset = nxtchr; - return true; -} - - -/** - * Find where to split a string to make it fit a width. - * - * \param style css_style for this text, with style->font_size.size == - * CSS_FONT_SIZE_LENGTH - * \param string UTF-8 string to measure - * \param length length of string - * \param x width available - * \param char_offset updated to offset in string of actual_x, [0..length] - * \param actual_x updated to x coordinate of character closest to x - * \return true on success, false on error and error reported - * - * On exit, [char_offset == 0 || - * string[char_offset] == ' ' || - * char_offset == length] - */ - -static bool nsfont_split(const struct css_style *style, - const char *string, size_t length, - int x, size_t *char_offset, int *actual_x) -{ - uint32_t ucs4; - size_t nxtchr = 0; - int last_space_x = 0; - int last_space_idx = 0; - FT_Glyph glyph; - - *actual_x = 0; - while (nxtchr < length) { - ucs4 = utf8_to_ucs4(string + nxtchr, length - nxtchr); - - glyph = fb_getglyph(style, ucs4); - if (glyph == NULL) - continue; - - if (ucs4 == 0x20) { - last_space_x = *actual_x; - last_space_idx = nxtchr; - } - - *actual_x += glyph->advance.x >> 16; - if (*actual_x > x) { - /* string has exceeded available width return previous - * space - */ - *actual_x = last_space_x; - *char_offset = last_space_idx; - return true; - } - - nxtchr = utf8_next(string, length, nxtchr); - } - - *char_offset = nxtchr; - - return true; -} - -const struct font_functions nsfont = { - nsfont_width, - nsfont_position_in_string, - nsfont_split -}; - -/* - * Local Variables: - * c-basic-offset:8 - * End: - */ diff --git a/framebuffer/fb_font_internal.c b/framebuffer/fb_font_internal.c deleted file mode 100644 index 9d7c9a76b..000000000 --- a/framebuffer/fb_font_internal.c +++ /dev/null @@ -1,141 +0,0 @@ -/* - * Copyright 2005 James Bursa - * 2008 Vincent Sanders - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include - -#include -#include "css/css.h" -#include "render/font.h" -#include "desktop/options.h" -#include "utils/utf8.h" - -#include "framebuffer/fb_gui.h" -#include "framebuffer/fb_font.h" - -bool fb_font_init(void) -{ - return true; -} - -const struct fb_font_desc* -fb_get_font(const struct css_style *style) -{ - return &font_vga_8x16; -} - -utf8_convert_ret utf8_to_font_encoding(const struct fb_font_desc* font, - const char *string, - size_t len, - char **result) -{ - return utf8_to_enc(string, font->encoding, len, result); - -} - -utf8_convert_ret utf8_to_local_encoding(const char *string, - size_t len, - char **result) -{ - return utf8_to_enc(string, "CP437", len, result); - -} - -static bool nsfont_width(const struct css_style *style, - const char *string, size_t length, - int *width) -{ - const struct fb_font_desc* fb_font = fb_get_font(style); - *width = fb_font->width * utf8_bounded_length(string, length); - return true; -} - -/** - * Find the position in a string where an x coordinate falls. - * - * \param style css_style for this text, with style->font_size.size == - * CSS_FONT_SIZE_LENGTH - * \param string UTF-8 string to measure - * \param length length of string - * \param x x coordinate to search for - * \param char_offset updated to offset in string of actual_x, [0..length] - * \param actual_x updated to x coordinate of character closest to x - * \return true on success, false on error and error reported - */ - -static bool nsfont_position_in_string(const struct css_style *style, - const char *string, size_t length, - int x, size_t *char_offset, int *actual_x) -{ - const struct fb_font_desc* fb_font = fb_get_font(style); - *char_offset = x / fb_font->width; - if (*char_offset > length) - *char_offset = length; - *actual_x = *char_offset * fb_font->width; - return true; -} - - -/** - * Find where to split a string to make it fit a width. - * - * \param style css_style for this text, with style->font_size.size == - * CSS_FONT_SIZE_LENGTH - * \param string UTF-8 string to measure - * \param length length of string - * \param x width available - * \param char_offset updated to offset in string of actual_x, [0..length] - * \param actual_x updated to x coordinate of character closest to x - * \return true on success, false on error and error reported - * - * On exit, [char_offset == 0 || - * string[char_offset] == ' ' || - * char_offset == length] - */ - -static bool nsfont_split(const struct css_style *style, - const char *string, size_t length, - int x, size_t *char_offset, int *actual_x) -{ - - const struct fb_font_desc* fb_font = fb_get_font(style); - *char_offset = x / fb_font->width; - if (*char_offset > length) { - *char_offset = length; - } else { - while (*char_offset > 0) { - if (string[*char_offset] == ' ') - break; - (*char_offset)--; - } - } - *actual_x = *char_offset * fb_font->width; - return true; -} - -const struct font_functions nsfont = { - nsfont_width, - nsfont_position_in_string, - nsfont_split -}; - -/* - * Local Variables: - * c-basic-offset:8 - * End: - */ diff --git a/framebuffer/fb_font_internal.h b/framebuffer/fb_font_internal.h deleted file mode 100644 index 502cf2e83..000000000 --- a/framebuffer/fb_font_internal.h +++ /dev/null @@ -1,39 +0,0 @@ -/* - * Copyright 2008 Vincent Sanders - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef NETSURF_FB_FONT_H -#define NETSURF_FB_FONT_H - -struct fb_font_desc { - const char *name; - int width, height; - const char *encoding; - const uint32_t *data; -}; - -extern const struct fb_font_desc font_vga_8x16; - -extern const struct fb_font_desc* fb_get_font(const struct css_style *style); - -extern utf8_convert_ret utf8_to_font_encoding(const struct fb_font_desc* font, - const char *string, - size_t len, - char **result); - -#endif /* NETSURF_FB_FONT_H */ - diff --git a/framebuffer/fb_frontend.h b/framebuffer/fb_frontend.h deleted file mode 100644 index 57f3c4a3f..000000000 --- a/framebuffer/fb_frontend.h +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright 2008 Vincent Sanders - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef NETSURF_FB_FRONTEND_H -#define NETSURF_FB_FRONTEND_H - -extern framebuffer_t *fb_os_init(int argc, char** argv); -extern void fb_os_quit(framebuffer_t *fb); -extern void fb_os_input(fbtk_widget_t *root, bool active); -extern void fb_os_option_override(void); -extern void fb_os_redraw(struct bbox_s *box); - -#endif /* NETSURF_FB_FRONTEND_H */ diff --git a/framebuffer/fb_frontend_ablefb.c b/framebuffer/fb_frontend_ablefb.c deleted file mode 100644 index a92bb260c..000000000 --- a/framebuffer/fb_frontend_ablefb.c +++ /dev/null @@ -1,310 +0,0 @@ -/* - * Copyright 2008 Vincent Sanders - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include - -#include "css/css.h" -#include "desktop/options.h" -#include "desktop/gui.h" -#include "desktop/options.h" -#include "utils/messages.h" -/* #include "desktop/textinput.h" cannot include this because it conflicts with the able defines */ -#define NSKEY_PAGE_DOWN 135 -#define NSKEY_PAGE_UP 134 -#define NSKEY_DOWN 31 -#define NSKEY_UP 30 -#define NSKEY_LEFT 28 -#define NSKEY_RIGHT 29 -#define NSKEY_ESCAPE 27 - -#define KEY_LEFTSHIFT 1 -#define KEY_RIGHTSHIFT 2 -#define KEY_PAGEDOWN 3 -#define KEY_PAGEUP 4 -#define KEY_DOWN 5 -#define KEY_UP 6 -#define KEY_LEFT 7 -#define KEY_RIGHT 8 -#define KEY_ESC 9 - -#include "framebuffer/fb_gui.h" -#include "framebuffer/fb_tk.h" -#include "framebuffer/fb_plotters.h" -#include "framebuffer/fb_frontend.h" -#include "framebuffer/fb_options.h" - -#include "utils/log.h" - -int devfd; -int eventfd; -static const char *fbdevname = "(fb0)"; -static const char *inputdevname = "(inputevent)"; - -framebuffer_t *fb_os_init(int argc, char** argv) -{ - framebuffer_t *newfb; - struct fb_info_s *fbinfo; - argb_t palent; - int ploop; - int res; - - /* open display device */ - devfd = open(option_fb_device ? option_fb_device : fbdevname, O_RDWR); - if (devfd < 0) { - LOG(("Error opening output device %s", fbdevname)); - return NULL; - } - - LOG(("Opened %s fd is %d",fbdevname, devfd)); - - res = ioctl(devfd, IOCTL_FB_GETINFO, &fbinfo); - - if (res < 0) { - LOG(("Output device error")); - close(devfd); - return NULL; - } - - LOG(("Framebuffer device name %s bpp %d\n", - fbinfo->name, - fbinfo->screeninfo->bits_per_pixel)); - - newfb = calloc(1, sizeof(framebuffer_t)); - - newfb->width = fbinfo->screeninfo->xres; - newfb->height = fbinfo->screeninfo->yres; - newfb->ptr = fbinfo->video_start + fbinfo->video_scroll; - newfb->linelen = fbinfo->line_len; - newfb->bpp = fbinfo->screeninfo->bits_per_pixel; - - if (newfb->bpp <= 8) { - for(ploop=0; ploop<256; ploop++) { - palent = fbinfo->cur_palette[ploop]; - - newfb->palette[ploop] = 0xFF000000 | - palent.b << 16 | - palent.g << 8 | - palent.r ; - } - } - - - /* set stdin to nonblocking */ - fcntl(0, F_SETFL, O_NONBLOCK); - - eventfd = open(inputdevname, O_RDONLY | O_NONBLOCK ); - - return newfb; -} - -void fb_os_quit(framebuffer_t *fb) -{ -} - -static int keymap[] = { - -1, -1, '1', '2', '3', '4', '5', '6', '7', '8', /* 0 - 9 */ - '9', '0', '-', '=', 8, 9, 'q', 'w', 'e', 'r', /* 10 - 19 */ - 't', 'y', 'u', 'i', 'o', 'p', '[', ']', 13, -1, /* 20 - 29 */ - 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', /* 30 - 39 */ - '\'', '#', -1, '\\', 'z', 'x', 'c', 'v', 'b', 'n', /* 40 - 49 */ - 'm', ',', '.', '/', -1, -1, -1, ' ', -1, -1, /* 50 - 59 */ -}; - -static int sh_keymap[] = { - -1, -1, '!', '"', 0xa3, '$', '%', '^', '&', '*', /* 0 - 9 */ - '(', ')', '_', '+', 8, 9, 'Q', 'W', 'E', 'R', /* 10 - 19 */ - 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', 13, -1, /* 20 - 29 */ - 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', /* 30 - 39 */ - '@', '~', -1, '|', 'Z', 'X', 'C', 'V', 'B', 'N', /* 40 - 49 */ - 'M', '<', '>', '?', -1, -1, -1, ' ', -1, -1, /* 50 - 59 */ -}; - -/* performs character mapping */ -static int keycode_to_ucs4(int code, bool shift) -{ - int ucs4 = -1; - - if (shift) { - if ((code >= 0) && (code < sizeof(sh_keymap))) - ucs4 = sh_keymap[code]; - } else { - if ((code >= 0) && (code < sizeof(keymap))) - ucs4 = keymap[code]; - } - return ucs4; -} - -void fb_os_input(fbtk_widget_t *root, bool active) -{ - ssize_t amt; - char key; - struct input_event event; - int ucs4 = -1; - static bool shift = false; - - amt = read(0, &key, 1); - - if (amt > 0) { - if (key == 'j') { - fbtk_input(root, NSKEY_UP); - } - if (key == 'k') { - fbtk_input(root, NSKEY_DOWN); - } - if (key == 'q') { - netsurf_quit = true; - } - if (key == 'd') { - list_schedule(); - } - } - - amt = read(eventfd, &event, sizeof(struct input_event)); - if (amt == sizeof(struct input_event)) { - if (event.type == EV_KEY) { - if (event.value == 0) { - /* key up */ - switch (event.code) { - case KEY_LEFTSHIFT: - case KEY_RIGHTSHIFT: - shift = false; - break; - - case BTN_LEFT: - fbtk_click(root, BROWSER_MOUSE_CLICK_1); - break; - } - return; - } - - switch (event.code) { - case KEY_PAGEDOWN: - ucs4 = NSKEY_PAGE_DOWN; - break; - - case KEY_PAGEUP: - ucs4 = NSKEY_PAGE_UP; - break; - - case KEY_DOWN: - ucs4 = NSKEY_DOWN; - break; - - case KEY_UP: - ucs4 = NSKEY_UP; - break; - - case KEY_LEFT: - ucs4 = NSKEY_LEFT; - break; - - case KEY_RIGHT: - ucs4 = NSKEY_RIGHT; - break; - - case KEY_ESC: - ucs4 = NSKEY_ESCAPE; - break; - - case BTN_LEFT: - fbtk_click(root, BROWSER_MOUSE_PRESS_1); - break; - - case KEY_LEFTSHIFT: - case KEY_RIGHTSHIFT: - shift = true; - break; - - default: - ucs4 = keycode_to_ucs4(event.code, shift); - - } - } else if (event.type == EV_REL) { - switch (event.code) { - case REL_X: - fbtk_move_pointer(root, event.value, 0, true); - break; - - case REL_Y: - fbtk_move_pointer(root, 0, event.value, true); - break; - - case REL_WHEEL: - if (event.value > 0) - fbtk_input(root, NSKEY_UP); - else - fbtk_input(root, NSKEY_DOWN); - break; - } - } else if (event.type == EV_ABS) { - switch (event.code) { - case ABS_X: - fbtk_move_pointer(root, event.value, -1, false); - break; - - case ABS_Y: - fbtk_move_pointer(root, -1, event.value, false); - break; - - } - } - - if (ucs4 != -1) { - fbtk_input(root, ucs4); - ucs4 = -1; - } - - - } - - - -} - -void -fb_os_option_override(void) -{ - /* override some options */ - option_max_cached_fetch_handles = 1; - option_max_fetchers = option_max_fetchers_per_host = 1; -} - -/* called by generic code to inform os code of screen update */ -void -fb_os_redraw(struct bbox_s *box) -{ -} - -char *realpath(const char *path, char *resolved_path) -{ - strcpy(resolved_path, path); -} - -/* - * Local Variables: - * c-basic-offset:8 - * End: - */ - diff --git a/framebuffer/fb_frontend_dummy.c b/framebuffer/fb_frontend_dummy.c deleted file mode 100644 index 5e9040779..000000000 --- a/framebuffer/fb_frontend_dummy.c +++ /dev/null @@ -1,84 +0,0 @@ -/* - * Copyright 2008 Vincent Sanders - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include -#include -#include - -#include "css/css.h" -#include "desktop/options.h" -#include "desktop/gui.h" -#include "desktop/options.h" -#include "utils/messages.h" - -#include "framebuffer/fb_gui.h" -#include "framebuffer/fb_plotters.h" -#include "framebuffer/fb_frontend.h" - -#include "utils/log.h" - -#define FILE_PFX "/home/vince/netsurf/netsurf-fb/framebuffer/res/" - -framebuffer_t *fb_os_init(int argc, char** argv) -{ - framebuffer_t *newfb; - - newfb = calloc(1, sizeof(framebuffer_t)); - - newfb->width = 800; - newfb->height = 600; - newfb->bpp = 16; - newfb->ptr = malloc((newfb->width * newfb->height * newfb->bpp) / 8); - newfb->linelen = (newfb->width * newfb->bpp) / 8; - - - /* load browser messages */ - messages_load(FILE_PFX "messages"); - - /* load browser options */ - options_read(FILE_PFX "Options"); - - - default_stylesheet_url = strdup("file://" FILE_PFX "default.css"); - - return newfb; -} - -void fb_os_quit(framebuffer_t *fb) -{ -} - -void fb_os_input(struct gui_window *g) -{ -} - -/* called by generic code to inform os code of screen update */ -void -fb_os_redraw(struct bbox_s *box) -{ -} - -/* - * Local Variables: - * c-basic-offset:8 - * End: - */ - diff --git a/framebuffer/fb_frontend_linuxfb.c b/framebuffer/fb_frontend_linuxfb.c deleted file mode 100644 index ea767295c..000000000 --- a/framebuffer/fb_frontend_linuxfb.c +++ /dev/null @@ -1,775 +0,0 @@ -/* - * Copyright 2008 Vincent Sanders - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include - -#include -#include -#include - -#include - -#include "css/css.h" -#include "utils/messages.h" -#include "desktop/gui.h" -/* #include "desktop/textinput.h" cannot include this because it conflicts with - the linux defines */ -#define NSKEY_PAGE_DOWN 135 -#define NSKEY_PAGE_UP 134 -#define NSKEY_DOWN 31 -#define NSKEY_UP 30 -#define NSKEY_LEFT 28 -#define NSKEY_RIGHT 29 -#define NSKEY_ESCAPE 27 - -#include "framebuffer/fb_gui.h" -#include "framebuffer/fb_tk.h" -#include "framebuffer/fb_plotters.h" -#include "framebuffer/fb_schedule.h" -#include "framebuffer/fb_cursor.h" -#include "framebuffer/fb_frontend.h" -#include "framebuffer/fb_options.h" - -#include "utils/log.h" -#include "utils/messages.h" - -#define FB_ACTIVE 0 -#define FB_REL_REQ 1 -#define FB_INACTIVE 2 -#define FB_ACQ_REQ 3 - - -struct fb_fix_screeninfo fb_fix; -struct fb_var_screeninfo fb_var; -unsigned char *fb_mem; -int fb_mem_offset = 0; -int fb_switch_state = FB_ACTIVE; - -static int fb,tty; -static int orig_vt_no = 0; -static struct vt_mode vt_mode; - -static int kd_mode; -static struct vt_mode vt_omode; -static struct termios term; -static struct fb_var_screeninfo fb_ovar; -static unsigned short ored[256], ogreen[256], oblue[256], otransp[256]; -static struct fb_cmap ocmap = { 0, 256, ored, ogreen, oblue, otransp }; - -typedef struct _input_dev { - struct _input_dev *next; - int fd; -} fb_input_dev; - -static fb_input_dev *inputdevs = 0; - -/* -------------------------------------------------------------------- */ -/* devices */ - -struct DEVS { - const char *fb0; - const char *fbnr; - const char *ttynr; -}; - -struct DEVS devs_default = { - .fb0 = "/dev/fb0", - .fbnr = "/dev/fb%d", - .ttynr = "/dev/tty%d", -}; - -struct DEVS *devices; - - -static char * -fconcat(const char *base, const char *leaf) -{ - static char buffer[PATH_MAX]; - snprintf(buffer, PATH_MAX, "%s/%s", base, leaf); - return buffer; -} - -/* Input device opening */ -static void -fb_open_input_devices(void) -{ - DIR *dir; - fb_input_dev *d; - struct dirent *de; - const char *basepath = option_fb_input_devpath ? option_fb_input_devpath : "/dev/input"; - - dir = opendir(basepath); - - if (dir == NULL) - return; - - while ((de = readdir(dir)) != NULL) { - if (fnmatch(option_fb_input_glob ? - option_fb_input_glob : "event*", - de->d_name, 0) == 0) { - char *cc = fconcat(basepath, de->d_name); - int fd = open(cc, O_RDONLY | O_NONBLOCK); - if (fd >= 0) { - d = calloc(1, sizeof(fb_input_dev)); - d->next = inputdevs; - inputdevs = d; - d->fd = fd; - } - } - } - - closedir(dir); -} - -/* -------------------------------------------------------------------- */ -/* console switching */ - - -static void -fb_switch_signal(int signal) -{ - if (signal == SIGUSR1) { - /* release */ - fb_switch_state = FB_REL_REQ; - } - if (signal == SIGUSR2) { - /* acquisition */ - fb_switch_state = FB_ACQ_REQ; - } -} - -static int -fb_switch_init(void) -{ - struct sigaction act,old; - - memset(&act, 0, sizeof(act)); - act.sa_handler = fb_switch_signal; - sigemptyset(&act.sa_mask); - sigaction(SIGUSR1, &act, &old); - sigaction(SIGUSR2, &act, &old); - - if (ioctl(tty,VT_GETMODE, &vt_mode) == -1) { - perror("ioctl VT_GETMODE"); - exit(1); - } - vt_mode.mode = VT_PROCESS; - vt_mode.waitv = 0; - vt_mode.relsig = SIGUSR1; - vt_mode.acqsig = SIGUSR2; - - if (ioctl(tty,VT_SETMODE, &vt_mode) == -1) { - perror("ioctl VT_SETMODE"); - exit(1); - } - return 0; -} - -/* -------------------------------------------------------------------- */ -/* initialisation & cleanup */ - -static int -fb_setmode(const char *name, int bpp) -{ - FILE *fp; - char line[80], label[32], value[16]; - int geometry = 0; - int timings = 0; - - /* load current values */ - if (ioctl(fb, FBIOGET_VSCREENINFO, &fb_var) == -1) { - perror("ioctl FBIOGET_VSCREENINFO"); - exit(1); - } - - if (name == NULL) - return -1; - - if ((fp = fopen("/etc/fb.modes","r")) == NULL) - return -1; - - while (NULL != fgets(line,79,fp)) { - if ((sscanf(line, "mode \"%31[^\"]\"", label) == 1) && - (strcmp(label,name) == 0)) { - /* fill in new values */ - fb_var.sync = 0; - fb_var.vmode = 0; - while ((fgets(line,79,fp) != NULL) && - (strstr(line,"endmode") == NULL)) { - if (5 == sscanf(line," geometry %d %d %d %d %d", - &fb_var.xres,&fb_var.yres, - &fb_var.xres_virtual,&fb_var.yres_virtual, - &fb_var.bits_per_pixel)) - geometry = 1; - - if (7 == sscanf(line," timings %d %d %d %d %d %d %d", - &fb_var.pixclock, - &fb_var.left_margin, &fb_var.right_margin, - &fb_var.upper_margin, &fb_var.lower_margin, - &fb_var.hsync_len, &fb_var.vsync_len)) - timings = 1; - - if (1 == sscanf(line, " hsync %15s",value) && - 0 == strcasecmp(value,"high")) - fb_var.sync |= FB_SYNC_HOR_HIGH_ACT; - - if (1 == sscanf(line, " vsync %15s",value) && - 0 == strcasecmp(value,"high")) - fb_var.sync |= FB_SYNC_VERT_HIGH_ACT; - - if (1 == sscanf(line, " csync %15s",value) && - 0 == strcasecmp(value,"high")) - fb_var.sync |= FB_SYNC_COMP_HIGH_ACT; - - if (1 == sscanf(line, " extsync %15s",value) && - 0 == strcasecmp(value,"true")) - fb_var.sync |= FB_SYNC_EXT; - - if (1 == sscanf(line, " laced %15s",value) && - 0 == strcasecmp(value,"true")) - fb_var.vmode |= FB_VMODE_INTERLACED; - - if (1 == sscanf(line, " double %15s",value) && - 0 == strcasecmp(value,"true")) - fb_var.vmode |= FB_VMODE_DOUBLE; - } - /* ok ? */ - if (!geometry || !timings) - return -1; - - if (bpp != 0) - fb_var.bits_per_pixel = bpp; - - /* set */ - fb_var.xoffset = 0; - fb_var.yoffset = 0; - if (ioctl(fb, FBIOPUT_VSCREENINFO, &fb_var) == -1) - perror("ioctl FBIOPUT_VSCREENINFO"); - - /* look what we have now ... */ - if (ioctl(fb, FBIOGET_VSCREENINFO, &fb_var) == -1) { - perror("ioctl FBIOGET_VSCREENINFO"); - exit(1); - } - return 0; - } - } - return -1; -} - -static void -fb_setvt(int vtno) -{ - struct vt_stat vts; - char vtname[12]; - - if (vtno < 0) { - if ((ioctl(tty, VT_OPENQRY, &vtno) == -1) || (vtno == -1)) { - perror("ioctl VT_OPENQRY"); - exit(1); - } - } - - vtno &= 0xff; - sprintf(vtname, devices->ttynr, vtno); - chown(vtname, getuid(), getgid()); - if (-1 == access(vtname, R_OK | W_OK)) { - fprintf(stderr,"access %s: %s\n",vtname,strerror(errno)); - exit(1); - } - - tty = open(vtname,O_RDWR); - if (ioctl(tty,VT_GETSTATE, &vts) == -1) { - perror("ioctl VT_GETSTATE"); - exit(1); - } - - orig_vt_no = vts.v_active; - if (ioctl(tty,VT_ACTIVATE, vtno) == -1) { - perror("ioctl VT_ACTIVATE"); - exit(1); - } - if (ioctl(tty,VT_WAITACTIVE, vtno) == -1) { - perror("ioctl VT_WAITACTIVE"); - exit(1); - } -} - -/* Hmm. radeonfb needs this. matroxfb doesn't. */ -static int -fb_activate_current(int tty) -{ - struct vt_stat vts; - - if (ioctl(tty,VT_GETSTATE, &vts) == -1) { - perror("ioctl VT_GETSTATE"); - return -1; - } - if (ioctl(tty,VT_ACTIVATE, vts.v_active) == -1) { - perror("ioctl VT_ACTIVATE"); - return -1; - } - if (ioctl(tty,VT_WAITACTIVE, vts.v_active) == -1) { - perror("ioctl VT_WAITACTIVE"); - return -1; - } - return 0; -} - -static void -fb_cleanup(void) -{ - /* restore console */ - if (ioctl(fb,FBIOPUT_VSCREENINFO,&fb_ovar) == -1) - perror("ioctl FBIOPUT_VSCREENINFO"); - - if (ioctl(fb,FBIOGET_FSCREENINFO,&fb_fix) == -1) - perror("ioctl FBIOGET_FSCREENINFO"); - - if ((fb_ovar.bits_per_pixel == 8) || - (fb_fix.visual == FB_VISUAL_DIRECTCOLOR)) { - if (ioctl(fb,FBIOPUTCMAP,&ocmap) == -1) - perror("ioctl FBIOPUTCMAP"); - } - close(fb); - - if (ioctl(tty,KDSETMODE, kd_mode) == -1) - perror("ioctl KDSETMODE"); - - if (ioctl(tty,VT_SETMODE, &vt_omode) == -1) - perror("ioctl VT_SETMODE"); - - if (orig_vt_no && (ioctl(tty, VT_ACTIVATE, orig_vt_no) == -1)) - perror("ioctl VT_ACTIVATE"); - - if (orig_vt_no && (ioctl(tty, VT_WAITACTIVE, orig_vt_no) == -1)) - perror("ioctl VT_WAITACTIVE"); - - tcsetattr(tty, TCSANOW, &term); - close(tty); -} - -static int -framebuffer_init(const char *device, int width, int height, int refresh, int bpp, int vt) -{ - char fbdev[16]; - struct vt_stat vts; - long pm = ~(sysconf(_SC_PAGESIZE) - 1); - char mode[32]; - - snprintf(mode, 32, "%dx%d-%d", width, height, refresh); - - devices = &devs_default; - - tty = 0; - if (vt != 0) - fb_setvt(vt); - - if (ioctl(tty,VT_GETSTATE, &vts) == -1) { - fprintf(stderr, - "ioctl VT_GETSTATE: %s (not a linux console?)\n", - strerror(errno)); - exit(1); - } - - if (device == NULL) { - device = getenv("FRAMEBUFFER"); - if (device == NULL) { - struct fb_con2fbmap c2m; - if ((fb = open(devices->fb0, O_RDWR, 0)) == -1) { - fprintf(stderr, - "open %s: %s\n", - devices->fb0, - strerror(errno)); - exit(1); - } - c2m.console = vts.v_active; - if (ioctl(fb, FBIOGET_CON2FBMAP, &c2m) == -1) { - perror("ioctl FBIOGET_CON2FBMAP"); - exit(1); - } - close(fb); - fprintf(stderr,"map: vt%02d => fb%d\n", - c2m.console, c2m.framebuffer); - sprintf(fbdev, devices->fbnr, c2m.framebuffer); - device = fbdev; - } - } - - /* get current settings (which we have to restore) */ - if ((fb = open(device, O_RDWR)) == -1) { - fprintf(stderr, "open %s: %s\n", device, strerror(errno)); - exit(1); - } - - if (ioctl(fb, FBIOGET_VSCREENINFO, &fb_ovar) == -1) { - perror("ioctl FBIOGET_VSCREENINFO"); - exit(1); - } - - if (ioctl(fb, FBIOGET_FSCREENINFO, &fb_fix) == -1) { - perror("ioctl FBIOGET_FSCREENINFO"); - exit(1); - } - - if ((fb_ovar.bits_per_pixel == 8) || - (fb_fix.visual == FB_VISUAL_DIRECTCOLOR)) { - if (ioctl(fb, FBIOGETCMAP, &ocmap) == -1) { - perror("ioctl FBIOGETCMAP"); - exit(1); - } - } - - if (ioctl(tty, KDGETMODE, &kd_mode) == -1) { - perror("ioctl KDGETMODE"); - exit(1); - } - - if (ioctl(tty,VT_GETMODE, &vt_omode) == -1) { - perror("ioctl VT_GETMODE"); - exit(1); - } - tcgetattr(tty, &term); - - /* switch mode */ - fb_setmode(mode, bpp); - - /* checks & initialisation */ - if (ioctl(fb, FBIOGET_FSCREENINFO, &fb_fix) == -1) { - perror("ioctl FBIOGET_FSCREENINFO"); - exit(1); - } - if (fb_fix.type != FB_TYPE_PACKED_PIXELS) { - fprintf(stderr,"can handle only packed pixel frame buffers\n"); - goto err; - } - - fb_mem_offset = (unsigned long)(fb_fix.smem_start) & (~pm); - fb_mem = mmap(NULL, fb_fix.smem_len + fb_mem_offset, - PROT_READ | PROT_WRITE, MAP_SHARED, fb, 0); - - if (-1L == (long)fb_mem) { - perror("mmap"); - goto err; - } - - /* move viewport to upper left corner */ - if ((fb_var.xoffset != 0) || - (fb_var.yoffset != 0)) { - fb_var.xoffset = 0; - fb_var.yoffset = 0; - if (ioctl(fb, FBIOPAN_DISPLAY, &fb_var) == -1) { - perror("ioctl FBIOPAN_DISPLAY"); - goto err; - } - } - - if (ioctl(tty, KDSETMODE, KD_GRAPHICS) == -1) { - perror("ioctl KDSETMODE"); - goto err; - } - fb_activate_current(tty); - - /* cls */ - memset(fb_mem + fb_mem_offset, 0, fb_fix.smem_len); - return fb; - -err: - fb_cleanup(); - exit(1); -} - - -/* -------------------------------------------------------------------- */ -/* handle fatal errors */ - -static jmp_buf fb_fatal_cleanup; - -static void -fb_catch_exit_signal(int signal) -{ - siglongjmp(fb_fatal_cleanup,signal); -} - -static void -fb_catch_exit_signals(void) -{ - struct sigaction act,old; - int termsig; - - memset(&act,0,sizeof(act)); - act.sa_handler = fb_catch_exit_signal; - sigemptyset(&act.sa_mask); - sigaction(SIGINT, &act, &old); - sigaction(SIGQUIT, &act, &old); - sigaction(SIGTERM, &act, &old); - - sigaction(SIGABRT, &act, &old); - sigaction(SIGTSTP, &act, &old); - - sigaction(SIGBUS, &act, &old); - sigaction(SIGILL, &act, &old); - sigaction(SIGSEGV, &act, &old); - - if ((termsig = sigsetjmp(fb_fatal_cleanup,0)) == 0) - return; - - /* cleanup */ - fb_cleanup(); - fprintf(stderr, "Oops: %s\n", sys_siglist[termsig]); - exit(42); -} - -framebuffer_t *fb_os_init(int argc, char** argv) -{ - framebuffer_t *newfb; - int ploop; - int fb_width; - int fb_height; - int fb_refresh; - int fb_depth; - - if ((option_window_width != 0) && - (option_window_height != 0)) { - fb_width = option_window_width; - fb_height = option_window_height; - } else { - fb_width = 800; - fb_height = 600; - } - - if (option_fb_refresh != 0) { - fb_refresh = option_fb_refresh; - } else { - fb_refresh = 60; - } - - fb_depth = option_fb_depth; - if ((fb_depth != 32) && - (fb_depth != 16) && - (fb_depth != 8)) - fb_depth = 16; /* sanity checked depth in bpp */ - - framebuffer_init(option_fb_device, fb_width, fb_height, fb_refresh, fb_depth, 1); - fb_switch_init(); - fb_catch_exit_signals(); - - newfb = calloc(1, sizeof(framebuffer_t)); - - newfb->width = fb_var.xres; - newfb->height = fb_var.yres; - newfb->ptr = fb_mem; - newfb->linelen = fb_fix.line_length; - newfb->bpp = fb_var.bits_per_pixel; - - if (newfb->bpp <= 8) { - for(ploop=0; ploop < 256; ploop++) { - newfb->palette[ploop] = 0xFF000000 | - ocmap.blue[ploop] << 16 | - ocmap.green[ploop] << 8 | - ocmap.red[ploop] ; - } - } - - - fb_open_input_devices(); - - return newfb; -} - -void fb_os_quit(framebuffer_t *fb) -{ - fb_cleanup(); -} - - -static int keymap[] = { - -1, -1, '1', '2', '3', '4', '5', '6', '7', '8', /* 0 - 9 */ - '9', '0', '-', '=', 8, 9, 'q', 'w', 'e', 'r', /* 10 - 19 */ - 't', 'y', 'u', 'i', 'o', 'p', '[', ']', 13, -1, /* 20 - 29 */ - 'a', 's', 'd', 'f', 'g', 'h', 'j', 'k', 'l', ';', /* 30 - 39 */ - '\'', '#', -1, '\\', 'z', 'x', 'c', 'v', 'b', 'n', /* 40 - 49 */ - 'm', ',', '.', '/', -1, -1, -1, ' ', -1, -1, /* 50 - 59 */ -}; - -static int sh_keymap[] = { - -1, -1, '!', '"', 0xa3, '$', '%', '^', '&', '*', /* 0 - 9 */ - '(', ')', '_', '+', 8, 9, 'Q', 'W', 'E', 'R', /* 10 - 19 */ - 'T', 'Y', 'U', 'I', 'O', 'P', '{', '}', 13, -1, /* 20 - 29 */ - 'A', 'S', 'D', 'F', 'G', 'H', 'J', 'K', 'L', ':', /* 30 - 39 */ - '@', '~', -1, '|', 'Z', 'X', 'C', 'V', 'B', 'N', /* 40 - 49 */ - 'M', '<', '>', '?', -1, -1, -1, ' ', -1, -1, /* 50 - 59 */ -}; - - -/* performs character mapping */ -static int keycode_to_ucs4(int code, bool shift) -{ - int ucs4 = -1; - - if (shift) { - if ((code >= 0) && (code < sizeof(sh_keymap))) - ucs4 = sh_keymap[code]; - } else { - if ((code >= 0) && (code < sizeof(keymap))) - ucs4 = keymap[code]; - } - return ucs4; -} - -void fb_os_input(fbtk_widget_t *root, bool active) -{ - ssize_t amt; - struct input_event event; - fb_input_dev *d; - int ucs4 = -1; - static bool shift = false; - - for (d = inputdevs; d != NULL; d = d->next) { - amt = read(d->fd, &event, sizeof(struct input_event)); - - if (amt > 0) { - if (event.type == EV_KEY) { - if (event.value == 0) { - /* key up */ - switch (event.code) { - case KEY_LEFTSHIFT: - case KEY_RIGHTSHIFT: - shift = false; - break; - - case BTN_LEFT: - fbtk_click(root, BROWSER_MOUSE_CLICK_1); - break; - } - return; - } - - switch (event.code) { - case KEY_PAGEDOWN: - ucs4 = NSKEY_PAGE_DOWN; - break; - - case KEY_PAGEUP: - ucs4 = NSKEY_PAGE_UP; - break; - - case KEY_DOWN: - ucs4 = NSKEY_DOWN; - break; - - case KEY_UP: - ucs4 = NSKEY_UP; - break; - - case KEY_LEFT: - ucs4 = NSKEY_LEFT; - break; - - case KEY_RIGHT: - ucs4 = NSKEY_RIGHT; - break; - - case KEY_ESC: - ucs4 = NSKEY_ESCAPE; - break; - - case BTN_LEFT: - fbtk_click(root, BROWSER_MOUSE_PRESS_1); - break; - - case KEY_LEFTSHIFT: - case KEY_RIGHTSHIFT: - shift = true; - break; - - default: - ucs4 = keycode_to_ucs4(event.code, shift); - - } - } else if (event.type == EV_REL) { - switch (event.code) { - case REL_X: - fbtk_move_pointer(root, event.value, 0, true); - break; - - case REL_Y: - fbtk_move_pointer(root, 0, event.value, true); - break; - - case REL_WHEEL: - if (event.value > 0) - fbtk_input(root, NSKEY_UP); - else - fbtk_input(root, NSKEY_DOWN); - break; - } - } else if (event.type == EV_ABS) { - switch (event.code) { - case ABS_X: - fbtk_move_pointer(root, event.value, -1, false); - break; - - case ABS_Y: - fbtk_move_pointer(root, -1, event.value, false); - break; - - } - } - - if (ucs4 != -1) { - fbtk_input(root, ucs4); - ucs4 = -1; - } - - - } - } -} - -void -fb_os_option_override(void) -{ -} - -/* called by generic code to inform os code of screen update */ -void -fb_os_redraw(struct bbox_s *box) -{ -} - -/* - * Local Variables: - * c-basic-offset:8 - * End: - */ diff --git a/framebuffer/fb_frontend_sdl.c b/framebuffer/fb_frontend_sdl.c deleted file mode 100644 index fc7ff3add..000000000 --- a/framebuffer/fb_frontend_sdl.c +++ /dev/null @@ -1,252 +0,0 @@ -/* - * Copyright 2008 Vincent Sanders - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include -#include -#include - -#include - -#include "css/css.h" -#include "desktop/gui.h" -#include "desktop/options.h" -#include "utils/messages.h" -#include "desktop/history_core.h" -#include "desktop/textinput.h" - -#include "framebuffer/fb_gui.h" -#include "framebuffer/fb_tk.h" -#include "framebuffer/fb_plotters.h" -#include "framebuffer/fb_frontend.h" -#include "framebuffer/fb_cursor.h" -#include "framebuffer/fb_options.h" - -#include "utils/log.h" - -static SDL_Surface *sdl_screen; - -static void -set_palette(framebuffer_t *fb) -{ - SDL_Color colors[256]; - int loop; - for(loop=0; loop < 256; loop++){ - colors[loop].r = loop; - colors[loop].g = loop; - colors[loop].b = loop; - fb->palette[loop] = loop << 16 | loop << 8 | loop; - } - - /* Set palette */ - SDL_SetColors(sdl_screen, colors, 0, 256); - -} - -framebuffer_t *fb_os_init(int argc, char** argv) -{ - framebuffer_t *newfb; - int fb_width; - int fb_height; - int fb_depth; - - - if ((option_window_width != 0) && (option_window_height != 0)) { - fb_width = option_window_width; - fb_height = option_window_height; - } else { - fb_width = 800; - fb_height = 600; - } - - fb_depth = option_fb_depth; - if ((fb_depth != 32) && (fb_depth != 16) && (fb_depth != 8)) - fb_depth = 16; /* sanity checked depth in bpp */ - - newfb = calloc(1, sizeof(framebuffer_t)); - if (newfb == NULL) - return NULL; - - if ( SDL_Init(SDL_INIT_VIDEO) < 0 ) { - fprintf(stderr, "Unable to init SDL: %s\n", SDL_GetError()); - return NULL; - } - atexit(SDL_Quit); - - newfb->width = fb_width; - newfb->height = fb_height; - newfb->bpp = fb_depth; - - sdl_screen = SDL_SetVideoMode(newfb->width, - newfb->height, - newfb->bpp, - SDL_SWSURFACE); - - if ( sdl_screen == NULL ) { - fprintf(stderr, - "Unable to set video: %s\n", SDL_GetError()); - free(newfb); - return NULL; - } - - if (newfb->bpp == 8) - set_palette(newfb); - - newfb->ptr = sdl_screen->pixels; - newfb->linelen = sdl_screen->pitch; - - SDL_ShowCursor(SDL_DISABLE); - - return newfb; -} - -void fb_os_quit(framebuffer_t *fb) -{ -} - -void fb_os_input(fbtk_widget_t *root, bool active) -{ - int got_event; - SDL_Event event; - int nskey; - - if (active) - got_event = SDL_PollEvent(&event); - else - got_event = SDL_WaitEvent(&event); - - /* Do nothing if there was no event */ - if (got_event == 0) - return; - - switch (event.type) { - case SDL_KEYDOWN: - - switch (event.key.keysym.sym) { - case SDLK_PAGEDOWN: - nskey = KEY_PAGE_DOWN; - break; - - case SDLK_PAGEUP: - nskey = KEY_PAGE_UP; - break; - - case SDLK_LEFT: - nskey = KEY_LEFT; - break; - - case SDLK_RIGHT: - nskey = KEY_RIGHT; - break; - - case SDLK_DOWN: - nskey = KEY_DOWN; - break; - - case SDLK_UP: - nskey = KEY_UP; - break; - - default: - nskey = event.key.keysym.sym; - break; - } - fbtk_input(root, nskey); - - break; - - case SDL_MOUSEMOTION: - fbtk_move_pointer(root, event.motion.x, event.motion.y, false); - break; - - case SDL_MOUSEBUTTONDOWN: - switch (event.button.button) { - - case SDL_BUTTON_LEFT: - fbtk_click(root, BROWSER_MOUSE_PRESS_1); - break; - - case SDL_BUTTON_RIGHT: - fbtk_click(root, BROWSER_MOUSE_PRESS_2); - break; - - case SDL_BUTTON_WHEELUP: - fbtk_input(root, KEY_UP); - break; - - case SDL_BUTTON_WHEELDOWN: - fbtk_input(root, KEY_DOWN); - break; - - } - break; - - case SDL_MOUSEBUTTONUP: - switch (event.button.button) { - - case SDL_BUTTON_LEFT: - fbtk_click(root, BROWSER_MOUSE_CLICK_1); - break; - - case SDL_BUTTON_RIGHT: - fbtk_click(root, BROWSER_MOUSE_CLICK_2); - break; - - } - break; - - case SDL_QUIT: - netsurf_quit = true; - break; - } - -} - -void -fb_os_option_override(void) -{ -} - -/* called by generic code to inform os code of screen update */ -void -fb_os_redraw(struct bbox_s *box) -{ - /*LOG(("%d,%d-%d,%d %d,%d", box->x0, box->y0, - box->x1, box->y1 , - box->x1 - box->x0, box->y1 - box->y0));*/ - /* - if ((box->y1 - box->y0) < 0) { - LOG(("WTF happened")); - return; - } - */ - SDL_UpdateRect(sdl_screen, - box->x0, - box->y0, - box->x1 - box->x0, - box->y1 - box->y0); -} - -/* - * Local Variables: - * c-basic-offset:8 - * End: - */ - diff --git a/framebuffer/fb_frontend_vnc.c b/framebuffer/fb_frontend_vnc.c deleted file mode 100644 index 837cddaaf..000000000 --- a/framebuffer/fb_frontend_vnc.c +++ /dev/null @@ -1,231 +0,0 @@ -/* - * Copyright 2008 Vincent Sanders - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include -#include -#include - -#include -#include - -#include "css/css.h" -#include "desktop/options.h" -#include "desktop/gui.h" -#include "desktop/options.h" -#include "utils/messages.h" -#include "desktop/history_core.h" -#include "desktop/textinput.h" - -#include "framebuffer/fb_gui.h" -#include "framebuffer/fb_tk.h" -#include "framebuffer/fb_plotters.h" -#include "framebuffer/fb_frontend.h" -#include "framebuffer/fb_cursor.h" -#include "framebuffer/fb_options.h" - -#include "utils/log.h" - -static rfbScreenInfoPtr vnc_screen; -static fbtk_widget_t *vncroot; - -static void fb_vnc_doptr(int buttonMask,int x,int y,rfbClientPtr cl) -{ - if (buttonMask == 0) { - fbtk_move_pointer(vncroot, x, y, false); - } else { - - /* left button */ - if (buttonMask && 0x1) { - fbtk_click(vncroot, BROWSER_MOUSE_CLICK_1); - } - - /* right button */ - if (buttonMask && 0x4) { - fbtk_click(vncroot, BROWSER_MOUSE_CLICK_2); - } - - if (buttonMask && 0x8) { - /* wheelup */ - fbtk_input(vncroot, KEY_UP); - } - - if (buttonMask && 0x10) { - /* wheeldown */ - fbtk_input(vncroot, KEY_DOWN); - } - } -} - - -static void fb_vnc_dokey(rfbBool down, rfbKeySym key, rfbClientPtr cl) -{ - int nskey; - - LOG(("Processing keycode %d",key)); - if (down) { - switch (key) { - - case XK_Page_Down: - nskey = KEY_PAGE_DOWN; - break; - - case XK_Page_Up: - nskey = KEY_PAGE_UP; - break; - - case XK_Down: - nskey = KEY_DOWN; - break; - - case XK_Up: - nskey = KEY_UP; - break; - - case XK_Escape: - nskey = 27; - break; - - case XK_Left: - nskey = KEY_LEFT; - break; - - case XK_Right: - nskey = KEY_RIGHT; - break; - - case XK_BackSpace: - nskey = 8; - break; - - case XK_Return: - nskey = 13; - break; - - default: - nskey = key; - break; - } - - fbtk_input(vncroot, nskey); - - } -} - -framebuffer_t *fb_os_init(int argc, char** argv) -{ - framebuffer_t *newfb; - int fb_width; - int fb_height; - int fb_depth; - - if ((option_window_width != 0) && (option_window_height != 0)) { - fb_width = option_window_width; - fb_height = option_window_height; - } else { - fb_width = 800; - fb_height = 600; - } - - fb_depth = option_fb_depth; - if ((fb_depth != 32) && (fb_depth != 16) && (fb_depth != 8)) - fb_depth = 16; /* sanity checked depth in bpp */ - - newfb = calloc(1, sizeof(framebuffer_t)); - if (newfb == NULL) - return NULL; - - newfb->width = fb_width; - newfb->height = fb_height; - newfb->bpp = fb_depth; - - vnc_screen = rfbGetScreen(&argc, argv, - newfb->width, newfb->height, - 8, 3, (fb_depth / 8)); - - vnc_screen->frameBuffer = malloc(newfb->width * newfb->height * (fb_depth / 8)); - - switch (fb_depth) { - case 8: - break; - - case 16: - vnc_screen->serverFormat.trueColour=TRUE; - vnc_screen->serverFormat.redShift = 11; - vnc_screen->serverFormat.greenShift = 5; - vnc_screen->serverFormat.blueShift = 0; - vnc_screen->serverFormat.redMax = 31; - vnc_screen->serverFormat.greenMax = 63; - vnc_screen->serverFormat.blueMax = 31; - break; - - case 32: - vnc_screen->serverFormat.trueColour=TRUE; - vnc_screen->serverFormat.redShift = 16; - vnc_screen->serverFormat.greenShift = 8; - vnc_screen->serverFormat.blueShift = 0; - break; - } - - vnc_screen->alwaysShared = TRUE; - vnc_screen->ptrAddEvent = fb_vnc_doptr; - vnc_screen->kbdAddEvent = fb_vnc_dokey; - - rfbInitServer(vnc_screen); - - newfb->ptr = vnc_screen->frameBuffer; - newfb->linelen = newfb->width * (fb_depth / 8); - - //rfbUndrawCursor(vnc_screen); - - return newfb; -} - -void fb_os_quit(framebuffer_t *fb) -{ -} - -void fb_os_input(fbtk_widget_t *root, bool active) -{ - vncroot = root; - - if (active) - rfbProcessEvents(vnc_screen, 10000); - else - rfbProcessEvents(vnc_screen, 100000); -} - -void -fb_os_option_override(void) -{ -} - -/* called by generic code to inform os code of screen update */ -void -fb_os_redraw(struct bbox_s *box) -{ - rfbMarkRectAsModified(vnc_screen, box->x0, box->y0, box->x1, box->y1); -} - -/* - * Local Variables: - * c-basic-offset:8 - * End: - */ diff --git a/framebuffer/fb_gui.c b/framebuffer/fb_gui.c deleted file mode 100644 index c7809dd39..000000000 --- a/framebuffer/fb_gui.c +++ /dev/null @@ -1,1126 +0,0 @@ -/* - * Copyright 2008 Vincent Sanders - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include -#include -#include -#include - -#include - -#include "desktop/gui.h" -#include "desktop/plotters.h" -#include "desktop/netsurf.h" -#include "desktop/options.h" -#include "utils/log.h" -#include "utils/messages.h" -#include "utils/utils.h" -#include "desktop/textinput.h" - -#include "framebuffer/fb_gui.h" -#include "framebuffer/fb_tk.h" -#include "framebuffer/fb_bitmap.h" -#include "framebuffer/fb_frontend.h" -#include "framebuffer/fb_plotters.h" -#include "framebuffer/fb_schedule.h" -#include "framebuffer/fb_cursor.h" -#include "framebuffer/fb_findfile.h" -#include "framebuffer/fb_image_data.h" -#include "framebuffer/fb_font.h" - -#include "content/urldb.h" -#include "desktop/history_core.h" -#include "content/fetch.h" - -char *default_stylesheet_url; -char *adblock_stylesheet_url; -char *options_file_location; - -fbtk_widget_t *fbtk; - -struct gui_window *input_window = NULL; -struct gui_window *search_current_window; -struct gui_window *window_list = NULL; - -bool redraws_pending = false; - -framebuffer_t *framebuffer; - -#ifndef MIN -#define MIN(a,b) (((a) < (b)) ? (a) : (b)) -#endif - -#ifndef MAX -#define MAX(a,b) (((a) > (b)) ? (a) : (b)) -#endif - -/* private data for browser user widget */ -struct browser_widget_s { - struct browser_window *bw; /**< The browser window connected to this gui window */ - int scrollx, scrolly; /**< scroll offsets. */ - - /* Pending window redraw state. */ - bool redraw_required; /**< flag indicating the foreground loop - * needs to redraw the browser widget. - */ - bbox_t redraw_box; /**< Area requiring redraw. */ - bool pan_required; /**< flag indicating the foreground loop - * needs to pan the window. - */ - int panx, pany; /**< Panning required. */ -}; - - -/* queue a redraw operation, co-ordinates are relative to the window */ -static void -fb_queue_redraw(struct fbtk_widget_s *widget, int x0, int y0, int x1, int y1) -{ - struct browser_widget_s *bwidget = fbtk_get_userpw(widget); - - bwidget->redraw_box.x0 = MIN(bwidget->redraw_box.x0, x0); - bwidget->redraw_box.y0 = MIN(bwidget->redraw_box.y0, y0); - bwidget->redraw_box.x1 = MAX(bwidget->redraw_box.x1, x1); - bwidget->redraw_box.y1 = MAX(bwidget->redraw_box.y1, y1); - - bwidget->redraw_required = true; - - fbtk_request_redraw(widget); -} - -static void fb_pan(fbtk_widget_t *widget, - struct browser_widget_s *bwidget, - struct browser_window *bw) -{ - struct content *c; - int x; - int y; - int width; - int height; - - c = bw->current_content; - - if ((!c) || (c->locked)) - return; - - height = fbtk_get_height(widget); - width = fbtk_get_width(widget); - x = fbtk_get_x(widget); - y = fbtk_get_y(widget); - - /* dont pan off the top */ - if ((bwidget->scrolly + bwidget->pany) < 0) - bwidget->pany = - bwidget->scrolly; - - /* do not pan off the bottom of the content */ - if ((bwidget->scrolly + bwidget->pany) > (c->height - height)) - bwidget->pany = (c->height - height) - bwidget->scrolly; - - /* dont pan off the left */ - if ((bwidget->scrollx + bwidget->panx) < 0) - bwidget->panx = - bwidget->scrollx; - - /* do not pan off the right of the content */ - if ((bwidget->scrollx + bwidget->panx) > (c->width - width)) - bwidget->panx = (c->width - width) - bwidget->scrollx; - - LOG(("panning %d, %d",bwidget->panx, bwidget->pany)); - - /* pump up the volume. dance, dance! lets do it */ - if (bwidget->pany < 0) { - /* we cannot pan more than a window height at a time */ - if (bwidget->pany < -height) - bwidget->pany = -height; - - LOG(("panning up %d", bwidget->pany)); - - fb_plotters_move_block(x, y, - width, height + bwidget->pany, - x, y - bwidget->pany); - bwidget->scrolly += bwidget->pany; - fb_queue_redraw(widget, 0, 0, width, - bwidget->pany); - } - - if (bwidget->pany > 0) { - /* we cannot pan more than a window height at a time */ - if (bwidget->pany > height) - bwidget->pany = height; - - LOG(("panning down %d", bwidget->pany)); - - fb_plotters_move_block(x, y + bwidget->pany, - width, height - bwidget->pany, - x, y); - bwidget->scrolly += bwidget->pany; - fb_queue_redraw(widget, 0, height - bwidget->pany, width, height); - } - - if (bwidget->panx < 0) { - /* we cannot pan more than a window width at a time */ - if (bwidget->panx < -width) - bwidget->panx = -width; - - LOG(("panning left %d", bwidget->panx)); - - fb_plotters_move_block(x, y, - width + bwidget->panx, height , - x - bwidget->panx, y ); - bwidget->scrollx += bwidget->panx; - fb_queue_redraw(widget, 0, 0, -bwidget->panx, height); - } - - if (bwidget->panx > 0) { - /* we cannot pan more than a window width at a time */ - if (bwidget->panx > width) - bwidget->panx = width; - - LOG(("panning right %d", bwidget->panx)); - - fb_plotters_move_block(x + bwidget->panx, y, - width - bwidget->panx, height, - x, y); - - bwidget->scrollx += bwidget->panx; - fb_queue_redraw(widget, width - bwidget->panx, 0, width, height); - } - - - bwidget->pan_required = false; - bwidget->panx = 0; - bwidget->pany = 0; -} - -static void fb_redraw(fbtk_widget_t *widget, - struct browser_widget_s *bwidget, - struct browser_window *bw) -{ - struct content *c; - int x; - int y; - int width; - int height; - - c = bw->current_content; - - if ((!c) || (c->locked)) - return; - - height = fbtk_get_height(widget); - width = fbtk_get_width(widget); - x = fbtk_get_x(widget); - y = fbtk_get_y(widget); - - /* adjust clipping co-ordinates according to window location */ - bwidget->redraw_box.y0 += y; - bwidget->redraw_box.y1 += y; - bwidget->redraw_box.x0 += x; - bwidget->redraw_box.x1 += x; - - - /* redraw bounding box is relative to window */ - content_redraw(c, - x - bwidget->scrollx, y - bwidget->scrolly, - width, height, - bwidget->redraw_box.x0, bwidget->redraw_box.y0, - bwidget->redraw_box.x1, bwidget->redraw_box.y1, - bw->scale, 0xFFFFFF); - - - fb_os_redraw(&bwidget->redraw_box); - - bwidget->redraw_box.y0 = bwidget->redraw_box.x0 = INT_MAX; - bwidget->redraw_box.y1 = bwidget->redraw_box.x1 = -(INT_MAX); - bwidget->redraw_required = false; -} - -static int -fb_browser_window_redraw(fbtk_widget_t *widget, void *pw) -{ - struct gui_window *gw = pw; - struct browser_widget_s *bwidget; - - bwidget = fbtk_get_userpw(widget); - - if (bwidget->pan_required) { - int pos; - fb_pan(widget, bwidget, gw->bw); - pos = (bwidget->scrollx * 100) / gw->bw->current_content->width;; - fbtk_set_scroll_pos(gw->hscroll, pos); - pos = (bwidget->scrolly * 100) / gw->bw->current_content->height; - fbtk_set_scroll_pos(gw->vscroll, pos); - - } - - if (bwidget->redraw_required) { - fb_redraw(widget, bwidget, gw->bw); - } - return 0; -} - -static void *myrealloc(void *ptr, size_t len, void *pw) -{ - return realloc(ptr, len); -} - -void gui_init(int argc, char** argv) -{ - char buf[PATH_MAX]; - - LOG(("argc %d, argv %p", argc, argv)); - - fb_find_resource(buf, "Aliases", "./framebuffer/res/Aliases"); - LOG(("Using '%s' as Aliases file", buf)); - if (hubbub_initialise(buf, myrealloc, NULL) != - HUBBUB_OK) - die("Unable to initialise HTML parsing library.\n"); - - /* load browser messages */ - fb_find_resource(buf, "messages", "./framebuffer/res/messages"); - LOG(("Using '%s' as Messages file", buf)); - messages_load(buf); - - /* load browser options */ - fb_find_resource(buf, "Options", "~/.netsurf/Options"); - LOG(("Using '%s' as Preferences file", buf)); - options_file_location = strdup(buf); - options_read(buf); - - /* set up stylesheet urls */ - fb_find_resource(buf, "default.css", "./framebuffer/res/default.css"); - default_stylesheet_url = path_to_url(buf); - LOG(("Using '%s' as Default CSS URL", default_stylesheet_url)); - - framebuffer = fb_os_init(argc, argv); - - fb_os_option_override(); - - option_target_blank = false; - - switch (framebuffer->bpp) { - /* case 1: - plot = framebuffer_1bpp_plot; - break; - */ - case 8: - plot = framebuffer_8bpp_plot; - break; - - case 16: - plot = framebuffer_16bpp_plot; - break; - - case 32: - plot = framebuffer_32bpp_plot; - break; - - default: - LOG(("Unsupported bit depth (%d)", framebuffer->bpp)); - die("Unsupported bit depth"); - } - - framebuffer->cursor = fb_cursor_init(framebuffer, &pointer_image); - - if (fb_font_init() == false) - die("Unable to initialise the font system"); - - fbtk = fbtk_init(framebuffer); -} - -void gui_init2(int argc, char** argv) -{ - struct browser_window *bw; - const char *addr = NETSURF_HOMEPAGE; - - LOG(("argc %d, argv %p", argc, argv)); - - if (option_homepage_url != NULL && option_homepage_url[0] != '\0') - addr = option_homepage_url; - - if (argc > 1) addr = argv[1]; - - LOG(("calling browser_window_create")); - bw = browser_window_create(addr, 0, 0, true, false); -} - - -void gui_multitask(void) -{ - // LOG(("gui_multitask")); -} - - -void gui_poll(bool active) -{ - // LOG(("enter fetch_poll")); - if (active) - fetch_poll(); - - active = schedule_run() | active | redraws_pending; - - fb_os_input(fbtk, active); - - fbtk_redraw(fbtk); - -} - -void gui_quit(void) -{ - LOG(("gui_quit")); - fb_os_quit(framebuffer); - /* We don't care if this fails as we're about to die, anyway */ - hubbub_finalise(myrealloc, NULL); -} - -/* called back when click in browser window */ -static int -fb_browser_window_click(fbtk_widget_t *widget, - browser_mouse_state st, - int x, int y, - void *pw) -{ - struct browser_window *bw = pw; - struct browser_widget_s *bwidget = fbtk_get_userpw(widget); - - LOG(("browser window clicked at %d,%d",x,y)); - browser_window_mouse_click(bw, - st, - x + bwidget->scrollx, - y + bwidget->scrolly); - return 0; -} - -/* called back when movement in browser window */ -static int -fb_browser_window_move(fbtk_widget_t *widget, - int x, int y, - void *pw) -{ - struct browser_window *bw = pw; - struct browser_widget_s *bwidget = fbtk_get_userpw(widget); - - browser_window_mouse_track(bw, - 0, - x + bwidget->scrollx, - y + bwidget->scrolly); - - return 0; -} - -static int -fb_browser_window_input(fbtk_widget_t *widget, int value, void *pw) -{ - struct gui_window *gw = pw; - int res = 0; - LOG(("got value %d",value)); - switch (value) { - - case KEY_PAGE_UP: - fb_window_scroll(gw, 0, -fbtk_get_height(gw->browser)); - break; - - case KEY_PAGE_DOWN: - fb_window_scroll(gw, 0, fbtk_get_height(gw->browser)); - break; - - case KEY_RIGHT: - fb_window_scroll(gw, 100, 0); - break; - - case KEY_LEFT: - fb_window_scroll(gw, -100, 0); - break; - - case KEY_UP: - fb_window_scroll(gw, 0, -100); - break; - - case KEY_DOWN: - fb_window_scroll(gw, 0, 100); - break; - - default: - res = browser_window_key_press(gw->bw, value); - break; - } - - return 0; -} - -static void -fb_update_back_forward(struct gui_window *gw) -{ - struct browser_window *bw = gw->bw; - - fbtk_set_bitmap(gw->back, - (browser_window_back_available(bw)) ? - &left_arrow : &left_arrow_g); - fbtk_set_bitmap(gw->forward, - (browser_window_forward_available(bw)) ? - &right_arrow : &right_arrow_g); -} - -/* left icon click routine */ -static int -fb_leftarrow_click(fbtk_widget_t *widget, - browser_mouse_state st, - int x, int y, void *pw) -{ - struct gui_window *gw =pw; - struct browser_window *bw = gw->bw; - - if (st == BROWSER_MOUSE_CLICK_1) { - if (history_back_available(bw->history)) - history_back(bw, bw->history); - } - fb_update_back_forward(gw); - return 0; - -} - -/* right arrow icon click routine */ -static int -fb_rightarrow_click(fbtk_widget_t *widget, browser_mouse_state st, int x, int y, void *pw) -{ - struct gui_window *gw =pw; - struct browser_window *bw = gw->bw; - - if (st == BROWSER_MOUSE_CLICK_1) { - if (history_forward_available(bw->history)) - history_forward(bw, bw->history); - } - fb_update_back_forward(gw); - return 0; - -} - -/* reload icon click routine */ -static int -fb_reload_click(fbtk_widget_t *widget, browser_mouse_state st, int x, int y, void *pw) -{ - struct browser_window *bw = pw; - browser_window_reload(bw, true); - return 0; -} - -/* stop icon click routine */ -static int -fb_stop_click(fbtk_widget_t *widget, browser_mouse_state st, int x, int y, void *pw) -{ - struct browser_window *bw = pw; - browser_window_stop(bw); - return 0; -} - -/* left scroll icon click routine */ -static int -fb_scrolll_click(fbtk_widget_t *widget, browser_mouse_state st, int x, int y, void *pw) -{ - fbtk_input(widget, KEY_LEFT); - return 0; -} - -static int -fb_scrollr_click(fbtk_widget_t *widget, browser_mouse_state st, int x, int y, void *pw) -{ - fbtk_input(widget, KEY_RIGHT); - return 0; -} - -static int -fb_scrollu_click(fbtk_widget_t *widget, browser_mouse_state st, int x, int y, void *pw) -{ - fbtk_input(widget, KEY_UP); - return 0; -} - -static int -fb_scrolld_click(fbtk_widget_t *widget, browser_mouse_state st, int x, int y, void *pw) -{ - fbtk_input(widget, KEY_DOWN); - return 0; -} - -static int -fb_url_enter(void *pw, char *text) -{ - struct browser_window *bw = pw; - browser_window_go(bw, text, 0, true); - return 0; -} - -static int -fb_url_move(fbtk_widget_t *widget, - int x, int y, - void *pw) -{ - fb_cursor_set(framebuffer->cursor, &caret_image); - return 0; -} - -static int -set_ptr_default_move(fbtk_widget_t *widget, - int x, int y, - void *pw) -{ - fb_cursor_set(framebuffer->cursor, &pointer_image); - return 0; -} - -static int -set_ptr_hand_move(fbtk_widget_t *widget, - int x, int y, - void *pw) -{ - fb_cursor_set(framebuffer->cursor, &hand_image); - return 0; -} - -struct gui_window * -gui_create_browser_window(struct browser_window *bw, - struct browser_window *clone, - bool new_tab) -{ - struct gui_window *gw; - struct browser_widget_s *browser_widget; - fbtk_widget_t *widget; - int top = 0; - int bot = 0; - int right = 0; - - gw = calloc(1, sizeof(struct gui_window)); - - if (gw == NULL) - return NULL; - - /* seems we need to associate the gui window with the underlying - * browser window - */ - gw->bw = bw; - - - switch(bw->browser_window_type) { - case BROWSER_WINDOW_NORMAL: - gw->window = fbtk_create_window(fbtk, 0, 0, 0, 0); - - top = 30; - bot = 20; - right = 18; - LOG(("Normal window")); - - /* fill toolbar background */ - widget = fbtk_create_fill(gw->window, - 0, 0, 0, 30, - FB_FRAME_COLOUR); - fbtk_set_handler_move(widget, set_ptr_default_move, bw); - - /* back button */ - gw->back = fbtk_create_button(gw->window, - 5, 2, - FB_FRAME_COLOUR, - &left_arrow_g, - fb_leftarrow_click, - gw); - fbtk_set_handler_move(gw->back, set_ptr_hand_move, bw); - - /* forward button */ - gw->forward = fbtk_create_button(gw->window, - 35, 2, - FB_FRAME_COLOUR, - &right_arrow_g, - fb_rightarrow_click, - gw); - fbtk_set_handler_move(gw->forward, set_ptr_hand_move, bw); - - /* reload button */ - widget = fbtk_create_button(gw->window, - 65, 2, - FB_FRAME_COLOUR, - &stop_image, - fb_stop_click, - bw); - fbtk_set_handler_move(widget, set_ptr_hand_move, bw); - - /* reload button */ - widget = fbtk_create_button(gw->window, - 95, 2, - FB_FRAME_COLOUR, - &reload, - fb_reload_click, - bw); - fbtk_set_handler_move(widget, set_ptr_hand_move, bw); - - /* url widget */ - gw->url = fbtk_create_writable_text(gw->window, - 125 , 3, - fbtk_get_width(gw->window) - 160, 24, - FB_COLOUR_WHITE, - FB_COLOUR_BLACK, - true, - fb_url_enter, - bw); - fbtk_set_handler_move(gw->url, fb_url_move, bw); - - gw->throbber = fbtk_create_bitmap(gw->window, - 130 + fbtk_get_width(gw->url), - 3, - FB_FRAME_COLOUR, - &throbber0); - - - - /* add status area widget, width of framebuffer less some for - * scrollbar - */ - gw->status = fbtk_create_text(gw->window, - 0 , - fbtk_get_height(gw->window) - bot, - fbtk_get_width(gw->window) - 200 - right, - bot, - FB_FRAME_COLOUR, FB_COLOUR_BLACK, - false); - - fbtk_set_handler_move(gw->status, set_ptr_default_move, bw); - - /* horizontal scrollbar */ - fbtk_create_button(gw->window, - fbtk_get_width(gw->window) - 200 - right, - fbtk_get_height(gw->window) - bot, - FB_FRAME_COLOUR, - &scrolll, - fb_scrolll_click, - bw); - - fbtk_create_button(gw->window, - fbtk_get_width(gw->window) - 20 - right, - fbtk_get_height(gw->window) - bot, - FB_FRAME_COLOUR, - &scrollr, - fb_scrollr_click, - bw); - - gw->hscroll = fbtk_create_hscroll(gw->window, - fbtk_get_width(gw->window) - 160 - 20 - right, - fbtk_get_height(gw->window) - bot, - 160, - bot, - FB_SCROLL_COLOUR, - FB_FRAME_COLOUR); - /* create vertical */ - fbtk_create_button(gw->window, - fbtk_get_width(gw->window) - right, - top, - FB_FRAME_COLOUR, - &scrollu, - fb_scrollu_click, - bw); - - fbtk_create_button(gw->window, - fbtk_get_width(gw->window) - right, - fbtk_get_height(gw->window) - bot - 20, - FB_FRAME_COLOUR, - &scrolld, - fb_scrolld_click, - bw); - - gw->vscroll = fbtk_create_vscroll(gw->window, - fbtk_get_width(gw->window) - right, - top + 20, - right, - fbtk_get_height(gw->window) - top - bot - 40 , - FB_SCROLL_COLOUR, - FB_FRAME_COLOUR); - - break; - - case BROWSER_WINDOW_FRAME: - gw->window = fbtk_create_window(bw->parent->window->window, 0, 0, 0, 0); - LOG(("create frame")); - break; - - default: - gw->window = fbtk_create_window(bw->parent->window->window, 0, 0, 0, 0); - LOG(("unhandled type")); - - } - - browser_widget = calloc(1, sizeof(struct browser_widget_s)); - - gw->browser = fbtk_create_user(gw->window, 0, top, -right, - (bot + top), browser_widget); - - fbtk_set_handler_click(gw->browser, fb_browser_window_click, bw); - fbtk_set_handler_input(gw->browser, fb_browser_window_input, gw); - fbtk_set_handler_redraw(gw->browser, fb_browser_window_redraw, gw); - fbtk_set_handler_move(gw->browser, fb_browser_window_move, bw); - - return gw; -} - -void gui_window_destroy(struct gui_window *gw) -{ - fbtk_destroy_widget(gw->window); - - free(gw); - - -} - -void gui_window_set_title(struct gui_window *g, const char *title) -{ - LOG(("%p, %s", g, title)); -} - - - -void fb_window_scroll(struct gui_window *g, int x, int y) -{ - struct browser_widget_s *bwidget = fbtk_get_userpw(g->browser); - - bwidget->panx += x; - bwidget->pany += y; - bwidget->pan_required = true; - - fbtk_request_redraw(g->browser); -} - -void gui_window_redraw(struct gui_window *g, int x0, int y0, int x1, int y1) -{ - fb_queue_redraw(g->browser, x0, y0, x1, y1); -} - -void gui_window_redraw_window(struct gui_window *g) -{ - fb_queue_redraw(g->browser, 0, 0, fbtk_get_width(g->browser),fbtk_get_height(g->browser) ); -} - -void gui_window_update_box(struct gui_window *g, - const union content_msg_data *data) -{ - fb_queue_redraw(g->browser, - data->redraw.x, - data->redraw.y, - data->redraw.x + data->redraw.width, - data->redraw.y + data->redraw.height); -} - -bool gui_window_get_scroll(struct gui_window *g, int *sx, int *sy) -{ - struct browser_widget_s *bwidget = fbtk_get_userpw(g->browser); - - *sx = bwidget->scrollx; - *sy = bwidget->scrolly; - - return true; -} - -void gui_window_set_scroll(struct gui_window *g, int sx, int sy) -{ - struct browser_widget_s *bwidget = fbtk_get_userpw(g->browser); - LOG(("scroll %d",sx)); - bwidget->panx = sx; - bwidget->pany = sy; - bwidget->pan_required = true; - - fbtk_request_redraw(g->browser); -} - -void gui_window_scroll_visible(struct gui_window *g, int x0, int y0, - int x1, int y1) -{ - LOG(("%s:(%p, %d, %d, %d, %d)", __func__, g, x0, y0, x1, y1)); -} - -void gui_window_position_frame(struct gui_window *g, int x0, int y0, - int x1, int y1) -{ - struct gui_window *parent; - int px, py; - int w, h; - LOG(("%s: %d, %d, %d, %d", g->bw->name, x0, y0, x1, y1)); - parent = g->bw->parent->window; - - if (parent->window == NULL) - return; /* doesnt have an fbtk widget */ - - px = fbtk_get_x(parent->browser) + x0; - py = fbtk_get_y(parent->browser) + y0; - w = x1 - x0; - h = y1 - y0; - if (w > (fbtk_get_width(parent->browser) - px)) - w = fbtk_get_width(parent->browser) - px; - - if (h > (fbtk_get_height(parent->browser) - py)) - h = fbtk_get_height(parent->browser) - py; - - fbtk_set_pos_and_size(g->window, px, py , w , h); - - fbtk_request_redraw(parent->browser); - -} - -void gui_window_get_dimensions(struct gui_window *g, int *width, int *height, - bool scaled) -{ - *width = fbtk_get_width(g->browser); - *height = fbtk_get_height(g->browser); -} - -void gui_window_update_extent(struct gui_window *g) -{ - int pct; - - pct = (fbtk_get_width(g->browser) * 100) / g->bw->current_content->width; - fbtk_set_scroll(g->hscroll, pct); - - pct = (fbtk_get_height(g->browser) * 100) / g->bw->current_content->height; - fbtk_set_scroll(g->vscroll, pct); - -} - -void gui_window_set_status(struct gui_window *g, const char *text) -{ - fbtk_set_text(g->status, text); -} - -void gui_window_set_pointer(struct gui_window *g, gui_pointer_shape shape) -{ - switch (shape) { - case GUI_POINTER_POINT: - fb_cursor_set(framebuffer->cursor, &hand_image); - break; - - case GUI_POINTER_CARET: - fb_cursor_set(framebuffer->cursor, &caret_image); - break; - - default: - fb_cursor_set(framebuffer->cursor, &pointer_image); - } -} - -void gui_window_hide_pointer(struct gui_window *g) -{ -} - -void gui_window_set_url(struct gui_window *g, const char *url) -{ - fbtk_set_text(g->url, url); -} - -static void -throbber_advance(void *pw) -{ - struct gui_window *g = pw; - struct bitmap *image; - - switch (g->throbber_index) { - case 0: - image = &throbber1; - g->throbber_index = 1; - break; - - case 1: - image = &throbber2; - g->throbber_index = 2; - break; - - case 2: - image = &throbber3; - g->throbber_index = 3; - break; - - case 3: - image = &throbber4; - g->throbber_index = 4; - break; - - case 4: - image = &throbber5; - g->throbber_index = 5; - break; - - case 5: - image = &throbber6; - g->throbber_index = 6; - break; - - case 6: - image = &throbber7; - g->throbber_index = 7; - break; - - case 7: - image = &throbber8; - g->throbber_index = 8; - break; - - case 8: - image = &throbber0; - g->throbber_index = 0; - break; - - default: - return; - } - - if (g->throbber_index >= 0) { - fbtk_set_bitmap(g->throbber, image); - schedule(10, throbber_advance, g); - } -} - -void gui_window_start_throbber(struct gui_window *g) -{ - g->throbber_index = 0; - schedule(10, throbber_advance, g); -} - -void gui_window_stop_throbber(struct gui_window *gw) -{ - gw->throbber_index = -1; - fbtk_set_bitmap(gw->throbber, &throbber0); - - fb_update_back_forward(gw); - -} - -void gui_window_place_caret(struct gui_window *g, int x, int y, int height) -{ -} - -void gui_window_remove_caret(struct gui_window *g) -{ -} - -void gui_window_new_content(struct gui_window *g) -{ -} - -bool gui_window_scroll_start(struct gui_window *g) -{ - return true; -} - -bool gui_window_box_scroll_start(struct gui_window *g, - int x0, int y0, int x1, int y1) -{ - return true; -} - -bool gui_window_frame_resize_start(struct gui_window *g) -{ - LOG(("resize frame\n")); - return true; -} - -void gui_window_save_as_link(struct gui_window *g, struct content *c) -{ -} - -void gui_window_set_scale(struct gui_window *g, float scale) -{ - LOG(("set scale\n")); -} - -struct gui_download_window *gui_download_window_create(const char *url, - const char *mime_type, struct fetch *fetch, - unsigned int total_size, struct gui_window *gui) -{ - return NULL; -} - -void gui_download_window_data(struct gui_download_window *dw, const char *data, - unsigned int size) -{ -} - -void gui_download_window_error(struct gui_download_window *dw, - const char *error_msg) -{ -} - -void gui_download_window_done(struct gui_download_window *dw) -{ -} - -void gui_drag_save_object(gui_save_type type, struct content *c, - struct gui_window *g) -{ -} - -void gui_drag_save_selection(struct selection *s, struct gui_window *g) -{ -} - -void gui_start_selection(struct gui_window *g) -{ -} - -void gui_paste_from_clipboard(struct gui_window *g, int x, int y) -{ -} - -bool gui_empty_clipboard(void) -{ - return false; -} - -bool gui_add_to_clipboard(const char *text, size_t length, bool space) -{ - return false; -} - -bool gui_commit_clipboard(void) -{ - return false; -} - -bool gui_copy_to_clipboard(struct selection *s) -{ - return false; -} - -void gui_create_form_select_menu(struct browser_window *bw, - struct form_control *control) -{ -} - -void gui_launch_url(const char *url) -{ -} - -bool gui_search_term_highlighted(struct gui_window *g, - unsigned start_offset, unsigned end_offset, - unsigned *start_idx, unsigned *end_idx) -{ - return false; -} - - - -void gui_cert_verify(struct browser_window *bw, struct content *c, - const struct ssl_cert_info *certs, unsigned long num) -{ -} - -/* - * Local Variables: - * c-basic-offset:8 - * End: - */ diff --git a/framebuffer/fb_gui.h b/framebuffer/fb_gui.h deleted file mode 100644 index 2d828133e..000000000 --- a/framebuffer/fb_gui.h +++ /dev/null @@ -1,72 +0,0 @@ -/* - * Copyright 2008 Vincent Sanders - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef NETSURF_FB_GUI_H -#define NETSURF_FB_GUI_H - -typedef struct fb_cursor_s fb_cursor_t; - -/* bounding box */ -typedef struct bbox_s { - int x0; - int y0; - int x1; - int y1; -} bbox_t; - -typedef struct framebuffer_s { - int width; - int height; - uint8_t *ptr; /**< Base of video memory. */ - int linelen; /**< length of a video line. */ - int bpp; - colour palette[256]; /* palette for index modes */ - fb_cursor_t *cursor; -} framebuffer_t; - -struct gui_window { - struct browser_window *bw; - - struct fbtk_widget_s *window; - struct fbtk_widget_s *back; - struct fbtk_widget_s *forward; - struct fbtk_widget_s *url; - struct fbtk_widget_s *status; - struct fbtk_widget_s *throbber; - struct fbtk_widget_s *hscroll; - struct fbtk_widget_s *vscroll; - struct fbtk_widget_s *browser; - int throbber_index; -}; - - -extern framebuffer_t *framebuffer; -extern struct gui_window *window_list; - -/* scroll a window */ -void fb_window_scroll(struct gui_window *g, int x, int y); - -#endif /* NETSURF_FB_GUI_H */ - -/* - * Local Variables: - * c-basic-offset:8 - * End: - */ - - diff --git a/framebuffer/fb_image_data.h b/framebuffer/fb_image_data.h deleted file mode 100644 index d94f14b51..000000000 --- a/framebuffer/fb_image_data.h +++ /dev/null @@ -1,52 +0,0 @@ -/* - * Copyright 2008 Vincent Sanders - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef FB_IMAGE_DATA -#define FB_IMAGE_DATA - -#include "framebuffer/fb_bitmap.h" - -extern struct bitmap left_arrow; -extern struct bitmap right_arrow; -extern struct bitmap reload; -extern struct bitmap stop_image; -extern struct bitmap left_arrow_g; -extern struct bitmap right_arrow_g; -extern struct bitmap reload_g; -extern struct bitmap stop_image_g; - -extern struct bitmap scrolll; -extern struct bitmap scrollr; -extern struct bitmap scrollu; -extern struct bitmap scrolld; - -extern struct bitmap pointer_image; -extern struct bitmap hand_image; -extern struct bitmap caret_image; - -extern struct bitmap throbber0; -extern struct bitmap throbber1; -extern struct bitmap throbber2; -extern struct bitmap throbber3; -extern struct bitmap throbber4; -extern struct bitmap throbber5; -extern struct bitmap throbber6; -extern struct bitmap throbber7; -extern struct bitmap throbber8; - -#endif /* FB_IMAGE_DATA */ diff --git a/framebuffer/fb_options.h b/framebuffer/fb_options.h deleted file mode 100644 index f2f52ae49..000000000 --- a/framebuffer/fb_options.h +++ /dev/null @@ -1,68 +0,0 @@ -/* - * Copyright 2008 Daniel Silverstone - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef _NETSURF_FRAMEBUFFER_OPTIONS_H_ -#define _NETSURF_FRAMEBUFFER_OPTIONS_H_ - -#include "desktop/options.h" - -extern int option_fb_depth; -extern int option_fb_refresh; -extern bool option_fb_font_monochrome; /* render font monochrome */ -extern char *option_fb_device; -extern char *option_fb_input_devpath; -extern char *option_fb_input_glob; -extern char *option_fb_face_sans_serif; /* default sans face */ -extern char *option_fb_face_sans_serif_bold; /* bold sans face */ -extern char *option_fb_face_sans_serif_italic; /* bold sans face */ -extern char *option_fb_face_sans_serif_italic_bold; /* bold sans face */ -extern char *option_fb_face_monospace; /* monospace face */ -extern char *option_fb_face_serif; /* serif face */ -extern char *option_fb_face_serif_bold; /* bold serif face */ - -#define EXTRA_OPTION_DEFINE \ - int option_fb_depth = 32; \ - int option_fb_refresh = 70; \ - bool option_fb_font_monochrome = false; \ - char *option_fb_device = 0; \ - char *option_fb_input_devpath = 0; \ - char *option_fb_input_glob = 0; \ - char *option_fb_face_sans_serif; \ - char *option_fb_face_sans_serif_bold; \ - char *option_fb_face_sans_serif_italic; \ - char *option_fb_face_sans_serif_italic_bold; \ - char *option_fb_face_monospace; \ - char *option_fb_face_serif; \ - char *option_fb_face_serif_bold; - -#define EXTRA_OPTION_TABLE \ - { "fb_depth", OPTION_INTEGER, &option_fb_depth }, \ - { "fb_refresh", OPTION_INTEGER, &option_fb_refresh }, \ - { "fb_device", OPTION_STRING, &option_fb_device }, \ - { "fb_input_devpath", OPTION_STRING, &option_fb_input_devpath }, \ - { "fb_input_glob", OPTION_STRING, &option_fb_input_glob }, \ - { "fb_font_monochrome", OPTION_BOOL, &option_fb_font_monochrome }, \ - { "fb_face_sans_serif", OPTION_STRING, &option_fb_face_sans_serif }, \ - { "fb_face_sans_serif_bold", OPTION_STRING, &option_fb_face_sans_serif_bold }, \ - { "fb_face_sans_serif_italic", OPTION_STRING, &option_fb_face_sans_serif_italic }, \ - { "fb_face_sans_serif_italic_bold", OPTION_STRING, &option_fb_face_sans_serif_italic_bold }, \ - { "fb_face_monospace", OPTION_STRING, &option_fb_face_monospace }, \ - { "fb_face_serif", OPTION_STRING, &option_fb_face_serif }, \ - { "fb_serif_bold", OPTION_STRING, &option_fb_face_serif_bold } - -#endif diff --git a/framebuffer/fb_plotters.c b/framebuffer/fb_plotters.c deleted file mode 100644 index 46ef82a95..000000000 --- a/framebuffer/fb_plotters.c +++ /dev/null @@ -1,495 +0,0 @@ -/* - * Copyright 2008 Vincent Sanders - * Copyright 2009 Michael Drake - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include -#include - -#include "utils/log.h" -#include "utils/utf8.h" -#include "desktop/browser.h" -#include "desktop/plotters.h" - -#include "framebuffer/fb_gui.h" -#include "framebuffer/fb_tk.h" -#include "framebuffer/fb_plotters.h" -#include "framebuffer/fb_bitmap.h" -#include "framebuffer/fb_font.h" -#include "framebuffer/fb_frontend.h" - -extern fbtk_widget_t *fbtk; - -/* max height the poly plotter can cope with */ -#define WINDOW_HEIGHT (2048) - -/* Currently selected ploting routines. */ -struct plotter_table plot; - -/* Current plotting context */ -bbox_t fb_plot_ctx; - -enum { - POINT_LEFTOF_REGION = 1, - POINT_RIGHTOF_REGION = 2, - POINT_ABOVE_REGION = 4, - POINT_BELOW_REGION = 8, -}; - -#define REGION(x,y,cx1,cx2,cy1,cy2) ( ( (y) > (cy2) ? POINT_BELOW_REGION : 0) | \ - ( (y) < (cy1) ? POINT_ABOVE_REGION : 0) | \ - ( (x) > (cx2) ? POINT_RIGHTOF_REGION : 0) | \ - ( (x) < (cx1) ? POINT_LEFTOF_REGION : 0) ) - -#define SWAP(a, b) do { int t; t=(a); (a)=(b); (b)=t; } while(0) - -/* clip a rectangle to another rectangle */ -bool fb_plotters_clip_rect(const bbox_t * restrict clip, - int * restrict x0, int * restrict y0, - int * restrict x1, int * restrict y1) -{ - char region1; - char region2; - - if (*x1 < *x0) SWAP(*x0, *x1); - - if (*y1 < *y0) SWAP(*y0, *y1); - - region1 = REGION(*x0, *y0, clip->x0, clip->x1 - 1, clip->y0, clip->y1 - 1); - region2 = REGION(*x1, *y1, clip->x0, clip->x1 - 1, clip->y0, clip->y1 - 1); - - /* area lies entirely outside the clipping rectangle */ - if ((region1 | region2) && (region1 & region2)) - return false; - - if (*x0 < clip->x0) - *x0 = clip->x0; - if (*x0 > clip->x1) - *x0 = clip->x1; - - if (*x1 < clip->x0) - *x1 = clip->x0; - if (*x1 > clip->x1) - *x1 = clip->x1; - - if (*y0 < clip->y0) - *y0 = clip->y0; - if (*y0 > clip->y1) - *y0 = clip->y1; - - if (*y1 < clip->y0) - *y1 = clip->y0; - if (*y1 > clip->y1) - *y1 = clip->y1; - - return true; -} - -bool fb_plotters_clip_rect_ctx(int *x0, int *y0, int *x1, int *y1) -{ - return fb_plotters_clip_rect(&fb_plot_ctx, x0, y0, x1, y1); -} - -/** Clip a line to a bounding box. - */ -bool fb_plotters_clip_line(const bbox_t *clip, - int *x0, int *y0, int *x1, int *y1) -{ - char region1; - char region2; - region1 = REGION(*x0, *y0, clip->x0, clip->x1 - 1, clip->y0, clip->y1 - 1); - region2 = REGION(*x1, *y1, clip->x0, clip->x1 - 1, clip->y0, clip->y1 - 1); - - while (region1 | region2) { - if (region1 & region2) { - /* line lies entirely outside the clipping rectangle */ - return false; - } - - if (region1) { - /* first point */ - if (region1 & POINT_BELOW_REGION) { - /* divide line at bottom */ - *x0 = (*x0 + (*x1 - *x0) * - (clip->y1 - 1 - *y0) / (*y1-*y0)); - *y0 = clip->y1 - 1; - } else if (region1 & POINT_ABOVE_REGION) { - /* divide line at top */ - *x0 = (*x0 + (*x1 - *x0) * - (clip->y0 - *y0) / (*y1-*y0)); - *y0 = clip->y0; - } else if (region1 & POINT_RIGHTOF_REGION) { - /* divide line at right */ - *y0 = (*y0 + (*y1 - *y0) * - (clip->x1 - 1 - *x0) / (*x1-*x0)); - *x0 = clip->x1 - 1; - } else if (region1 & POINT_LEFTOF_REGION) { - /* divide line at right */ - *y0 = (*y0 + (*y1 - *y0) * - (clip->x0 - *x0) / (*x1-*x0)); - *x0 = clip->x0; - } - - region1 = REGION(*x0, *y0, - clip->x0, clip->x1 - 1, clip->y0, clip->y1 - 1); - } else { - /* second point */ - if (region2 & POINT_BELOW_REGION) { - /* divide line at bottom*/ - *x1 = (*x0 + (*x1 - *x0) * - (clip->y1 - 1 - *y0) / (*y1-*y0)); - *y1 = clip->y1 - 1; - } else if (region2 & POINT_ABOVE_REGION) { - /* divide line at top*/ - *x1 = (*x0 + (*x1 - *x0) * - (clip->y0 - *y0) / (*y1-*y0)); - *y1 = clip->y0; - } else if (region2 & POINT_RIGHTOF_REGION) { - /* divide line at right*/ - *y1 = (*y0 + (*y1 - *y0) * - (clip->x1 - 1 - *x0) / (*x1 - *x0)); - *x1 = clip->x1 - 1; - } else if (region2 & POINT_LEFTOF_REGION) { - /* divide line at right*/ - *y1 = (*y0 + (*y1 - *y0) * - (clip->x0 - *x0) / (*x1 - *x0)); - *x1 = clip->x0; - } - - region2 = REGION(*x1, *y1, - clip->x0, clip->x1 - 1, clip->y0, clip->y1 - 1); - } - } - - return true; -} - -bool fb_plotters_clip_line_ctx(int *x0, int *y0, int *x1, int *y1) -{ - return fb_plotters_clip_line(&fb_plot_ctx, x0, y0, x1, y1); -} - -/* generic setting of clipping rectangle */ -bool fb_clip(int x0, int y0, int x1, int y1) -{ - bbox_t clip; - - if (x1 < x0) SWAP(x0, x1); - if (y1 < y0) SWAP(y0, y1); - - clip.x0 = fbtk_get_x(fbtk); - clip.y0 = fbtk_get_y(fbtk); - clip.x1 = fbtk_get_width(fbtk); - clip.y1 = fbtk_get_height(fbtk); - - if (fb_plotters_clip_rect(&clip, &x0, &y0, &x1, &y1)) { - /* new clipping region is inside the root window */ - fb_plot_ctx.x0 = x0; - fb_plot_ctx.y0 = y0; - fb_plot_ctx.x1 = x1; - fb_plot_ctx.y1 = y1; - } - - /*LOG(("%d, %d - %d, %d clipped to %d, %d - %d, %d", - x0,y0,x1,y1, - fb_plot_ctx.x0, fb_plot_ctx.y0, fb_plot_ctx.x1, fb_plot_ctx.y1)); */ - - return true; -} - -typedef bool (linefn_t)(int x0, int y0, int x1, int y1, int width, colour c, - bool dotted, bool dashed); - - -/** - * Find find first filled span along horizontal line at given coordinate - * - * \param p array of polygon vertices (x1, y1, x2, y2, ... , xN, yN) - * \param n number of polygon vertex values (N * 2) - * \param x current position along current scan line - * \param y position of current scan line - * \param x0 updated to start of filled area - * \param x1 updated to end of filled area - * \return true if an intersection was found - */ - -static bool fb_plotters_find_span(const int *p, int n, int x, int y, - int *x0, int *x1) -{ - int i; - int p_x0, p_y0; - int p_x1, p_y1; - int x_new; - bool direction = false; - - *x0 = *x1 = INT_MAX; - - for (i = 0; i < n; i = i + 2) { - /* get line endpoints */ - if (i != n - 2) { - /* not the last line */ - p_x0 = p[i]; p_y0 = p[i + 1]; - p_x1 = p[i + 2]; p_y1 = p[i + 3]; - } else { - /* last line; 2nd endpoint is first vertex */ - p_x0 = p[i]; p_y0 = p[i + 1]; - p_x1 = p[0]; p_y1 = p[1]; - } - /* ignore horizontal lines */ - if (p_y0 == p_y1) - continue; - - /* ignore lines that don't cross this y level */ - if ((y < p_y0 && y < p_y1) || (y > p_y0 && y > p_y1)) - continue; - - if (p_x0 == p_x1) { - /* vertical line, x is constant */ - x_new = p_x0; - } else { - /* find intersect */ - x_new = p_x0 + ((long long)(y - p_y0) * (p_x1 - p_x0)) / - (p_y1 - p_y0); - } - - /* ignore intersections before current x */ - if (x_new < x) - continue; - - /* set nearest intersections as filled area endpoints */ - if (x_new < *x0) { - /* nearer than first endpoint */ - *x1 = *x0; - *x0 = x_new; - direction = (p_y0 > p_y1); - } else if (x_new == *x0) { - /* same as first endpoint */ - if ((p_y0 > p_y1) != direction) - *x1 = x_new; - } else if (x_new < *x1) { - /* nearer than second endpoint */ - *x1 = x_new; - } - - } - if (*x0 == INT_MAX) - /* no span found */ - return false; - - /* span found */ - if (*x1 == INT_MAX) { - *x1 = *x0; - *x0 = x; - return true; - } - - return true; -} - - -/** - * Plot a polygon - * - * \param p array of polygon vertices (x1, y1, x2, y2, ... , xN, yN) - * \param n number of polygon vertices (N) - * \param c fill colour - * \param linefn function to call to plot a horizontal line - * \return true if no errors - */ - -bool fb_plotters_polygon(const int *p, unsigned int n, colour c, - linefn_t linefn) -{ - int poly_x0, poly_y0; /* Bounding box top left corner */ - int poly_x1, poly_y1; /* Bounding box bottom right corner */ - int i, j; /* indexes */ - int x0, x1; /* filled span extents */ - int y; /* current y coordinate */ - int y_max; /* bottom of plot area */ - - /* find no. of vertex values */ - int v = n * 2; - - /* Can't plot polygons with 2 or fewer vertices */ - if (n <= 2) - return true; - - /* Find polygon bounding box */ - poly_x0 = poly_x1 = *p; - poly_y0 = poly_y1 = p[1]; - for (i = 2; i < v; i = i + 2) { - j = i + 1; - if (p[i] < poly_x0) - poly_x0 = p[i]; - else if (p[i] > poly_x1) - poly_x1 = p[i]; - if (p[j] < poly_y0) - poly_y0 = p[j]; - else if (p[j] > poly_y1) - poly_y1 = p[j]; - } - - /* Don't try to plot it if it's outside the clip rectangle */ - if (fb_plot_ctx.y1 < poly_y0 || fb_plot_ctx.y0 > poly_y1 || - fb_plot_ctx.x1 < poly_x0 || fb_plot_ctx.x0 > poly_x1) - return true; - - /* Find the top of the important area */ - if (poly_y0 > fb_plot_ctx.y0) - y = poly_y0; - else - y = fb_plot_ctx.y0; - - /* Find the bottom of the important area */ - if (poly_y1 < fb_plot_ctx.y1) - y_max = poly_y1; - else - y_max = fb_plot_ctx.y1; - - for (; y < y_max; y++) { - x1 = poly_x0; - /* For each row */ - while (fb_plotters_find_span(p, v, x1, y, &x0, &x1)) { - /* don't draw anything outside clip region */ - if (x1 < fb_plot_ctx.x0) - continue; - else if (x0 < fb_plot_ctx.x0) - x0 = fb_plot_ctx.x0; - if (x0 > fb_plot_ctx.x1) - break; - else if (x1 > fb_plot_ctx.x1) - x1 = fb_plot_ctx.x1; - - /* draw this filled span on current row */ - linefn(x0, y, x1, y, 1, c, false, false); - - /* don't look for more spans if already at end of clip - * region or polygon */ - if (x1 == fb_plot_ctx.x1 || x1 == poly_x1) - break; - - if (x0 == x1) - x1++; - } - } - return true; -} - -bool fb_plotters_bitmap_tile(int x, int y, - int width, int height, - struct bitmap *bitmap, colour bg, - bool repeat_x, bool repeat_y, - struct content *content, - bool (bitmapfn)(int x, int y, - int width, int height, - struct bitmap *bitmap, - colour bg, - struct content *content)) -{ - int xf,yf; - - /* x and y define coordinate of top left of of the initial explicitly - * placed tile. The width and height are the image scaling and the - * bounding box defines the extent of the repeat (which may go in all - * four directions from the initial tile). - */ - - LOG(("x %d, y %d, width %d, height %d, bitmap %p, repx %d repy %d content %p", x,y,width,height,bitmap,repeat_x, repeat_y, content)); - - if (!(repeat_x || repeat_y)) { - /* Not repeating at all, so just pass it on */ - LOG(("Not repeating")); - return bitmapfn(x, y, width, height, bitmap, bg,content); - } - - /* get left most tile position */ - if (repeat_x) - for (; x > fb_plot_ctx.x0; x -= width) - ; - - /* get top most tile position */ - if (repeat_y) - for (; y > fb_plot_ctx.y0; y -= height) - ; - - /* tile down and across to extents */ - for (xf = x; xf < fb_plot_ctx.x1; xf += width) { - for (yf = y; yf < fb_plot_ctx.y1; yf += height) { - bitmapfn(xf, yf, width, height, bitmap, bg, content); - if (!repeat_y) - break; - } - if (!repeat_x) - break; - } - return true; -} - -bool fb_plotters_move_block(int srcx, int srcy, int width, int height, int dstx, int dsty) -{ - uint8_t *srcptr = (framebuffer->ptr + - (srcy * framebuffer->linelen) + - ((srcx * framebuffer->bpp) / 8)); - - uint8_t *dstptr = (framebuffer->ptr + - (dsty * framebuffer->linelen) + - ((dstx * framebuffer->bpp) / 8)); - - bbox_t redrawbox; - int hloop; - - LOG(("from (%d,%d) w %d h %d to (%d,%d)",srcx,srcy,width,height,dstx,dsty)); - - if (width == framebuffer->width) { - /* take shortcut and use memmove */ - memmove(dstptr, srcptr, (width * height * framebuffer->bpp) / 8); - } else { - if (srcy > dsty) { - for (hloop = height; hloop > 0; hloop--) { - memmove(dstptr, srcptr, (width * framebuffer->bpp) / 8); - srcptr += framebuffer->linelen; - dstptr += framebuffer->linelen; - } - } else { - srcptr += height * framebuffer->linelen; - dstptr += height * framebuffer->linelen; - for (hloop = height; hloop > 0; hloop--) { - srcptr -= framebuffer->linelen; - dstptr -= framebuffer->linelen; - memmove(dstptr, srcptr, (width * framebuffer->bpp) / 8); - } - } - } - /* callback to the os specific routine in case it needs to do something - * explicit to redraw - */ - redrawbox.x0 = dstx; - redrawbox.y0 = dsty; - redrawbox.x1 = dstx + width; - redrawbox.y1 = dsty + height; - fb_os_redraw(&redrawbox); - - return true; -} - -/* - * Local Variables: - * c-basic-offset:8 - * End: - */ diff --git a/framebuffer/fb_plotters.h b/framebuffer/fb_plotters.h deleted file mode 100644 index 8e2d1fe3f..000000000 --- a/framebuffer/fb_plotters.h +++ /dev/null @@ -1,88 +0,0 @@ -/* - * Copyright 2008 Vincent Sanders - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef FRAMEBUFFER_PLOTTERS_H -#define FRAMEBUFFER_PLOTTERS_H - -extern const struct plotter_table framebuffer_1bpp_plot; -extern const struct plotter_table framebuffer_8bpp_plot; -extern const struct plotter_table framebuffer_16bpp_plot; -extern const struct plotter_table framebuffer_32bpp_plot; - -/* plotting context */ -extern bbox_t fb_plot_ctx; - -/* plotter support functions */ -bool fb_plotters_clip_rect_ctx(int *x0, int *y0, int *x1, int *y1); -bool fb_plotters_clip_rect(const bbox_t *clip, int *x0, int *y0, int *x1, int *y1); - -bool fb_plotters_clip_line_ctx(int *x0, int *y0, int *x1, int *y1); -bool fb_plotters_clip_line(const bbox_t *clip, int *x0, int *y0, int *x1, int *y1); - -bool fb_plotters_polygon(const int *p, unsigned int n, colour fill, bool (linefn)(int x0, int y0, int x1, int y1, int width, colour c, bool dotted, bool dashed)); - -bool fb_plotters_bitmap_tile(int x, int y, - int width, int height, - struct bitmap *bitmap, colour bg, - bool repeat_x, bool repeat_y, - struct content *content, - bool (bitmapfn)(int x, int y, - int width, int height, - struct bitmap *bitmap, - colour bg, - struct content *content)); - -/* alpha blend two pixels together */ -static inline colour fb_plotters_ablend(colour pixel, colour scrpixel) -{ -#if 0 - int opacity = (pixel >> 24) & 0xFF; - int r,g,b; - - r = (((pixel & 0xFF) * opacity) >> 8) + - (((scrpixel & 0xFF) * (0xFF - opacity)) >> 8); - - g = ((((pixel & 0xFF00) >> 8) * opacity) >> 8) + - ((((scrpixel & 0xFF00) >> 8) * (0xFF - opacity)) >> 8); - - b = ((((pixel & 0xFF0000) >> 16) * opacity) >> 8) + - ((((scrpixel & 0xFF0000) >> 16) * (0xFF - opacity)) >> 8); - - return r | (g << 8) | (b << 16); -#else - int opacity = pixel >> 24; - int transp = 0x100 - opacity; - uint32_t rb, g; - - rb = ((pixel & 0xFF00FF) * opacity + - (scrpixel & 0xFF00FF) * transp) >> 8; - g = ((pixel & 0x00FF00) * opacity + - (scrpixel & 0x00FF00) * transp) >> 8; - - return (rb & 0xFF00FF) | (g & 0xFF00); -#endif -} - - -bool fb_plotters_move_block(int srcx, int srcy, int width, int height, int dstx, int dsty); - -/* generic plotter entry points */ -bool fb_clip(int x0, int y0, int x1, int y1); - - -#endif diff --git a/framebuffer/fb_schedule.c b/framebuffer/fb_schedule.c deleted file mode 100644 index 782210202..000000000 --- a/framebuffer/fb_schedule.c +++ /dev/null @@ -1,202 +0,0 @@ -/* - * Copyright 2008 Vincent Sanders - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include - -#include "desktop/browser.h" -#include "framebuffer/fb_schedule.h" - -#include "utils/log.h" - -/* linked list of scheduled callbacks */ -static struct nscallback *schedule_list = NULL; - -/** - * scheduled callback. - */ -struct nscallback -{ - struct nscallback *next; - struct timeval tv; - void (*callback)(void *p); - void *p; -}; - - -/** - * Schedule a callback. - * - * \param tival interval before the callback should be made / cs - * \param callback callback function - * \param p user parameter, passed to callback function - * - * The callback function will be called as soon as possible after t cs have - * passed. - */ - -void schedule(int cs_ival, void (*callback)(void *p), void *p) -{ - struct nscallback *nscb; - struct timeval tv; - - tv.tv_sec = 0; - tv.tv_usec = cs_ival * 10000; - - nscb = calloc(1, sizeof(struct nscallback)); - - LOG(("adding callback %p for %p(%p) at %d cs", nscb, callback, p, cs_ival)); - - gettimeofday(&nscb->tv, NULL); - timeradd(&nscb->tv, &tv, &nscb->tv); - - nscb->callback = callback; - nscb->p = p; - - /* add to list front */ - nscb->next = schedule_list; - schedule_list = nscb; -} - -/** - * Unschedule a callback. - * - * \param callback callback function - * \param p user parameter, passed to callback function - * - * All scheduled callbacks matching both callback and p are removed. - */ - -void schedule_remove(void (*callback)(void *p), void *p) -{ - struct nscallback *cur_nscb; - struct nscallback *prev_nscb; - struct nscallback *unlnk_nscb; - - if (schedule_list == NULL) - return; - - LOG(("removing %p, %p", callback, p)); - - cur_nscb = schedule_list; - prev_nscb = NULL; - - while (cur_nscb != NULL) { - if ((cur_nscb->callback == callback) && - (cur_nscb->p == p)) { - /* item to remove */ - - LOG(("callback entry %p removing %p(%p)", - cur_nscb, cur_nscb->callback, cur_nscb->p)); - - /* remove callback */ - unlnk_nscb = cur_nscb; - cur_nscb = unlnk_nscb->next; - - if (prev_nscb == NULL) { - schedule_list = cur_nscb; - } else { - prev_nscb->next = cur_nscb; - } - free (unlnk_nscb); - } else { - /* move to next element */ - prev_nscb = cur_nscb; - cur_nscb = prev_nscb->next; - } - } -} - -/** - * Process events up to current time. - */ - -bool schedule_run(void) -{ - struct timeval tv; - struct nscallback *cur_nscb; - struct nscallback *prev_nscb; - struct nscallback *unlnk_nscb; - - if (schedule_list == NULL) - return false; - - cur_nscb = schedule_list; - prev_nscb = NULL; - - gettimeofday(&tv, NULL); - - while (cur_nscb != NULL) { - if (timercmp(&tv, &cur_nscb->tv, >)) { - /* scheduled time */ - - /* remove callback */ - unlnk_nscb = cur_nscb; - - if (prev_nscb == NULL) { - schedule_list = unlnk_nscb->next; - } else { - prev_nscb->next = unlnk_nscb->next; - } - - LOG(("callback entry %p running %p(%p)", - unlnk_nscb, unlnk_nscb->callback, unlnk_nscb->p)); - /* call callback */ - unlnk_nscb->callback(unlnk_nscb->p); - - free (unlnk_nscb); - - /* the callback might have modded the list, so start - * again - */ - cur_nscb = schedule_list; - prev_nscb = NULL; - - } else { - /* move to next element */ - prev_nscb = cur_nscb; - cur_nscb = prev_nscb->next; - } - } - return true; -} - -void list_schedule(void) -{ - struct timeval tv; - struct nscallback *cur_nscb; - - gettimeofday(&tv, NULL); - - LOG(("schedule list at %ld:%ld", tv.tv_sec, tv.tv_usec)); - - cur_nscb = schedule_list; - - while (cur_nscb != NULL) { - LOG(("Schedule %p at %ld:%ld", - cur_nscb, cur_nscb->tv.tv_sec, cur_nscb->tv.tv_usec)); - cur_nscb = cur_nscb->next; - } -} - - -/* - * Local Variables: - * c-basic-offset:8 - * End: - */ diff --git a/framebuffer/fb_schedule.h b/framebuffer/fb_schedule.h deleted file mode 100644 index f735a06df..000000000 --- a/framebuffer/fb_schedule.h +++ /dev/null @@ -1,24 +0,0 @@ -/* - * Copyright 2008 Vincent Sanders - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#ifndef FRAMEBUFFER_SCHEDULE_H -#define FRAMEBUFFER_SCHEDULE_H - -void list_schedule(void); - -#endif diff --git a/framebuffer/fb_tk.c b/framebuffer/fb_tk.c deleted file mode 100644 index 4076e5306..000000000 --- a/framebuffer/fb_tk.c +++ /dev/null @@ -1,1180 +0,0 @@ -/* - * Copyright 2008 Vincent Sanders - * - * Framebuffer windowing toolkit - * - * This file is part of NetSurf, http://www.netsurf-browser.org/ - * - * NetSurf is free software; you can redistribute it and/or modify - * it under the terms of the GNU General Public License as published by - * the Free Software Foundation; version 2 of the License. - * - * NetSurf is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - * GNU General Public License for more details. - * - * You should have received a copy of the GNU General Public License - * along with this program. If not, see . - */ - -#include -#include -#include - -#include "utils/log.h" -#include "css/css.h" -#include "desktop/browser.h" -#include "desktop/plotters.h" - -#include "framebuffer/fb_gui.h" -#include "framebuffer/fb_tk.h" -#include "framebuffer/fb_plotters.h" -#include "framebuffer/fb_bitmap.h" -#include "framebuffer/fb_cursor.h" -#include "framebuffer/fb_image_data.h" -#include "framebuffer/fb_frontend.h" - -static struct css_style root_style; - -enum fbtk_widgettype_e { - FB_WIDGET_TYPE_ROOT = 0, - FB_WIDGET_TYPE_WINDOW, - FB_WIDGET_TYPE_BITMAP, - FB_WIDGET_TYPE_FILL, - FB_WIDGET_TYPE_TEXT, - FB_WIDGET_TYPE_HSCROLL, - FB_WIDGET_TYPE_VSCROLL, - FB_WIDGET_TYPE_USER, -}; - -typedef struct fbtk_widget_list_s fbtk_widget_list_t; - -/* wrapper struct for all widget types */ -struct fbtk_widget_s { - /* Generic properties */ - int x; - int y; - int width; - int height; - colour bg; - colour fg; - - /* handlers */ - fbtk_mouseclick_t click; - void *clickpw; /* private data for callback */ - - fbtk_input_t input; - void *inputpw; /* private data for callback */ - - fbtk_move_t move; - void *movepw; /* private data for callback */ - - fbtk_redraw_t redraw; - void *redrawpw; /* private data for callback */ - - bool redraw_required; - - fbtk_widget_t *parent; /* parent widget */ - - /* Widget specific */ - enum fbtk_widgettype_e type; - - union { - /* toolkit base handle */ - struct { - framebuffer_t *fb; - fbtk_widget_t *rootw; - fbtk_widget_t *input; - } root; - - /* window */ - struct { - /* widgets associated with this window */ - fbtk_widget_list_t *widgets; /* begining of list */ - fbtk_widget_list_t *widgets_end; /* end of list */ - } window; - - /* bitmap */ - struct { - struct bitmap *bitmap; - } bitmap; - - /* text */ - struct { - char* text; - bool outline; - fbtk_enter_t enter; - void *pw; - int idx; - } text; - - /* application driven widget */ - struct { - void *pw; /* private data for user widget */ - } user; - - struct { - int pos; - int pct; - } scroll; - - } u; -}; - -/* widget list */ -struct fbtk_widget_list_s { - struct fbtk_widget_list_s *next; - struct fbtk_widget_list_s *prev; - fbtk_widget_t *widget; -} ; - -enum { - POINT_LEFTOF_REGION = 1, - POINT_RIGHTOF_REGION = 2, - POINT_ABOVE_REGION = 4, - POINT_BELOW_REGION = 8, -}; - -#define REGION(x,y,cx1,cx2,cy1,cy2) \ - (( (y) > (cy2) ? POINT_BELOW_REGION : 0) | \ - ( (y) < (cy1) ? POINT_ABOVE_REGION : 0) | \ - ( (x) > (cx2) ? POINT_RIGHTOF_REGION : 0) | \ - ( (x) < (cx1) ? POINT_LEFTOF_REGION : 0) ) - -#define SWAP(a, b) do { int t; t=(a); (a)=(b); (b)=t; } while(0) - -/* clip a rectangle to another rectangle */ -bool fbtk_clip_rect(const bbox_t * restrict clip, bbox_t * restrict box) -{ - uint8_t region1; - uint8_t region2; - - if (box->x1 < box->x0) SWAP(box->x0, box->x1); - if (box->y1 < box->y0) SWAP(box->y0, box->y1); - - region1 = REGION(box->x0, box->y0, clip->x0, clip->x1 - 1, clip->y0, clip->y1 - 1); - region2 = REGION(box->x1, box->y1, clip->x0, clip->x1 - 1, clip->y0, clip->y1 - 1); - - /* area lies entirely outside the clipping rectangle */ - if ((region1 | region2) && (region1 & region2)) - return false; - - if (box->x0 < clip->x0) - box->x0 = clip->x0; - if (box->x0 > clip->x1) - box->x0 = clip->x1; - - if (box->x1 < clip->x0) - box->x1 = clip->x0; - if (box->x1 > clip->x1) - box->x1 = clip->x1; - - if (box->y0 < clip->y0) - box->y0 = clip->y0; - if (box->y0 > clip->y1) - box->y0 = clip->y1; - - if (box->y1 < clip->y0) - box->y1 = clip->y0; - if (box->y1 > clip->y1) - box->y1 = clip->y1; - - return true; -} - - -/* creates a new widget of a given type */ -static fbtk_widget_t * -new_widget(enum fbtk_widgettype_e type) -{ - fbtk_widget_t *neww; - neww = calloc(1, sizeof(fbtk_widget_t)); - neww->type = type; - return neww; -} - - -/* find the root widget from any widget in the toolkits hierarchy */ -static fbtk_widget_t * -get_root_widget(fbtk_widget_t *widget) -{ - while (widget->parent != NULL) - widget = widget->parent; - - /* check root widget was found */ - if (widget->type != FB_WIDGET_TYPE_ROOT) { - LOG(("Widget with null parent that is not the root widget!")); - return NULL; - } - - return widget; -} - - -/* set widget to be redrawn */ -void -fbtk_request_redraw(fbtk_widget_t *widget) -{ - widget->redraw_required = 1; - - if (widget->type == FB_WIDGET_TYPE_WINDOW) { - fbtk_widget_list_t *lent = widget->u.window.widgets; - - while (lent != NULL) { - lent->widget->redraw_required = 1; - lent = lent->next; - } - } - - while (widget->parent != NULL) { - widget = widget->parent; - widget->redraw_required = 1; - } -} - -static fbtk_widget_t * -add_widget_to_window(fbtk_widget_t *window, fbtk_widget_t *widget) -{ - fbtk_widget_list_t *newent; - fbtk_widget_list_t **nextent; - fbtk_widget_list_t *prevent; /* previous entry pointer */ - - if (window->type == FB_WIDGET_TYPE_WINDOW) { - /* caller attached widget to a window */ - - nextent = &window->u.window.widgets; - prevent = NULL; - while (*nextent != NULL) { - prevent = (*nextent); - nextent = &(prevent->next); - } - - newent = calloc(1, sizeof(struct fbtk_widget_list_s)); - - newent->widget = widget; - newent->next = NULL; - newent->prev = prevent; - - *nextent = newent; - - window->u.window.widgets_end = newent; - } - widget->parent = window; - - fbtk_request_redraw(widget); - - return widget; -} - -static void -remove_widget_from_window(fbtk_widget_t *window, fbtk_widget_t *widget) -{ - fbtk_widget_list_t *lent = window->u.window.widgets; - - while ((lent != NULL) && (lent->widget != widget)) { - lent = lent->next; - } - - if (lent != NULL) { - if (lent->prev == NULL) { - window->u.window.widgets = lent->next; - } else { - lent->prev->next = lent->next; - } - if (lent->next == NULL) { - window->u.window.widgets_end = lent->prev; - } else { - lent->next->prev = lent->prev; - } - free(lent); - } -} - -static void -fbtk_redraw_widget(fbtk_widget_t *widget) -{ - bbox_t saved_plot_ctx; - - //LOG(("widget %p type %d", widget, widget->type)); - - /* set the clipping rectangle to the widget area */ - saved_plot_ctx = fb_plot_ctx; - - fb_plot_ctx.x0 = fbtk_get_x(widget); - fb_plot_ctx.y0 = fbtk_get_y(widget); - fb_plot_ctx.x1 = fb_plot_ctx.x0 + widget->width; - fb_plot_ctx.y1 = fb_plot_ctx.y0 + widget->height; - - if (fbtk_clip_rect(&saved_plot_ctx, &fb_plot_ctx )) { - /* do our drawing according to type */ - widget->redraw(widget, widget->redrawpw); - - widget->redraw_required = false; - //LOG(("OS redrawing %d,%d %d,%d", fb_plot_ctx.x0, fb_plot_ctx.y0, fb_plot_ctx.x1, fb_plot_ctx.y1)); - } - - /* restore clipping rectangle */ - fb_plot_ctx = saved_plot_ctx; - //LOG(("Redraw Complete")); -} - -/*************** redraw widgets **************/ - -static int -fb_redraw_fill(fbtk_widget_t *widget, void *pw) -{ - /* clear background */ - if ((widget->bg & 0xFF000000) != 0) { - /* transparent polygon filling isnt working so fake it */ - plot.fill(fb_plot_ctx.x0, fb_plot_ctx.y0, - fb_plot_ctx.x1, fb_plot_ctx.y1, - widget->bg); - } - - fb_os_redraw(&fb_plot_ctx); - return 0; -} - -static int -fb_redraw_hscroll(fbtk_widget_t *widget, void *pw) -{ - int hscroll; - int hpos; - - plot.fill(fb_plot_ctx.x0, fb_plot_ctx.y0, - fb_plot_ctx.x1, fb_plot_ctx.y1, - widget->bg); - - plot.fill(fb_plot_ctx.x0 + 1, - fb_plot_ctx.y0 + 3, - fb_plot_ctx.x1 - 1, - fb_plot_ctx.y1 - 3, - widget->fg); - - plot.rectangle(fb_plot_ctx.x0, - fb_plot_ctx.y0 + 2, - fb_plot_ctx.x1 - fb_plot_ctx.x0 - 1, - fb_plot_ctx.y1 - fb_plot_ctx.y0 - 5, - 1, 0xFF000000, false, false); - - hscroll = ((widget->width - 4) * widget->u.scroll.pct) / 100 ; - hpos = ((widget->width - 4) * widget->u.scroll.pos) / 100 ; - - LOG(("hscroll %d",hscroll)); - - plot.fill(fb_plot_ctx.x0 + 3 + hpos, - fb_plot_ctx.y0 + 5, - fb_plot_ctx.x0 + hscroll + hpos, - fb_plot_ctx.y0 + widget->height - 5, - widget->bg); - - fb_os_redraw(&fb_plot_ctx); - - return 0; -} - -static int -fb_redraw_vscroll(fbtk_widget_t *widget, void *pw) -{ - int vscroll; - int vpos; - - plot.fill(fb_plot_ctx.x0, fb_plot_ctx.y0, - fb_plot_ctx.x1, fb_plot_ctx.y1, - widget->bg); - - plot.fill(fb_plot_ctx.x0 + 1, - fb_plot_ctx.y0 + 3, - fb_plot_ctx.x1 - 1, - fb_plot_ctx.y1 - 3, - widget->fg); - - plot.rectangle(fb_plot_ctx.x0, - fb_plot_ctx.y0 + 2, - fb_plot_ctx.x1 - fb_plot_ctx.x0 - 1, - fb_plot_ctx.y1 - fb_plot_ctx.y0 - 5, - 1, 0xFF000000, false, false); - - vscroll = ((widget->height - 4) * widget->u.scroll.pct) / 100 ; - vpos = ((widget->height - 4) * widget->u.scroll.pos) / 100 ; - - LOG(("scroll %d",vscroll)); - - plot.fill(fb_plot_ctx.x0 + 3, - fb_plot_ctx.y0 + 5 + vpos, - fb_plot_ctx.x0 + widget->width - 3, - fb_plot_ctx.y0 + vscroll + vpos - 5, - widget->bg); - - fb_os_redraw(&fb_plot_ctx); - - return 0; -} - -static int -fb_redraw_bitmap(fbtk_widget_t *widget, void *pw) -{ - /* clear background */ - if ((widget->bg & 0xFF000000) != 0) { - /* transparent polygon filling isnt working so fake it */ - plot.fill(fb_plot_ctx.x0, fb_plot_ctx.y0, - fb_plot_ctx.x1, fb_plot_ctx.y1, - widget->bg); - } - - /* plot the image */ - plot.bitmap(fb_plot_ctx.x0, fb_plot_ctx.y0, - widget->width, widget->height, - widget->u.bitmap.bitmap, 0, NULL); - - fb_os_redraw(&fb_plot_ctx); - - return 0; -} - -static int -fbtk_window_default_redraw(fbtk_widget_t *window, void *pw) -{ - fbtk_widget_list_t *lent; - fbtk_widget_t *widget; - int res = 0; - - if (!window->redraw) - return res; - - /* get the list of widgets */ - lent = window->u.window.widgets; - - while (lent != NULL) { - widget = lent->widget; - - if ((widget->redraw != NULL) && - (widget->redraw_required)) { - fbtk_redraw_widget(widget); - - } - lent = lent->next; - } - return res; -} - -static int -fbtk_window_default_move(fbtk_widget_t *window, int x, int y, void *pw) -{ - fbtk_widget_list_t *lent; - fbtk_widget_t *widget; - int res = 0; - - /* get the list of widgets */ - lent = window->u.window.widgets_end; - - while (lent != NULL) { - widget = lent->widget; - - if ((x > widget->x) && - (y > widget->y) && - (x < widget->x + widget->width) && - (y < widget->y + widget->height)) { - if (widget->move != NULL) { - res = widget->move(widget, - x - widget->x, - y - widget->y, - widget->movepw); - } - break; - } - lent = lent->prev; - } - return res; -} - -static int -fbtk_window_default_click(fbtk_widget_t *window, browser_mouse_state st, int x, int y, void *pw) -{ - fbtk_widget_list_t *lent; - fbtk_widget_t *widget; - int res = 0; - - /* get the list of widgets */ - lent = window->u.window.widgets; - - while (lent != NULL) { - widget = lent->widget; - - if ((x > widget->x) && - (y > widget->y) && - (x < widget->x + widget->width) && - (y < widget->y + widget->height)) { - if (widget->input != NULL) { - fbtk_widget_t *root = get_root_widget(widget); - root->u.root.input = widget; - } - - if (widget->click != NULL) { - res = widget->click(widget, - st, - x - widget->x, - y - widget->y, - widget->clickpw); - break; - } - - - - } - lent = lent->next; - } - return res; -} - -static int -fb_redraw_text(fbtk_widget_t *widget, void *pw) -{ - /* clear background */ - if ((widget->bg & 0xFF000000) != 0) { - /* transparent polygon filling isnt working so fake it */ - plot.fill(fb_plot_ctx.x0, fb_plot_ctx.y0, - fb_plot_ctx.x1, fb_plot_ctx.y1, - widget->bg); - } - - if (widget->u.text.outline) { - plot.rectangle(fb_plot_ctx.x0, fb_plot_ctx.y0, - fb_plot_ctx.x1 - fb_plot_ctx.x0 - 1, - fb_plot_ctx.y1 - fb_plot_ctx.y0 - 1, - 1, 0x00000000, false, false); - } - if (widget->u.text.text != NULL) { - plot.text(fb_plot_ctx.x0 + 3, - fb_plot_ctx.y0 + 17, - &root_style, - widget->u.text.text, - strlen(widget->u.text.text), - widget->bg, - widget->fg); - } - - fb_os_redraw(&fb_plot_ctx); - - return 0; -} - - - - -static int -text_input(fbtk_widget_t *widget, int value, void *pw) -{ - - switch (value) { - case -1: - /* gain focus */ - if (widget->u.text.text == NULL) - widget->u.text.text = calloc(1,1); - widget->u.text.idx = strlen(widget->u.text.text); - break; - - case '\b': - if (widget->u.text.idx <= 0) - break; - widget->u.text.idx--; - widget->u.text.text[widget->u.text.idx] = 0; - break; - - case '\r': - widget->u.text.enter(widget->u.text.pw, widget->u.text.text); - break; - - default: - /* allow for new character and null */ - widget->u.text.text = realloc(widget->u.text.text, widget->u.text.idx + 2); - widget->u.text.text[widget->u.text.idx] = value; - widget->u.text.text[widget->u.text.idx + 1] = '\0'; - widget->u.text.idx++; - break; - } - - fbtk_request_redraw(widget); - - return 0; -} - -/* sets the enter action on a writable icon */ -void -fbtk_writable_text(fbtk_widget_t *widget, fbtk_enter_t enter, void *pw) -{ - widget->u.text.enter = enter; - widget->u.text.pw = pw; - - widget->input = text_input; - widget->inputpw = widget; -} - - -/********** acessors ***********/ -int -fbtk_get_height(fbtk_widget_t *widget) -{ - return widget->height; -} - -int -fbtk_get_width(fbtk_widget_t *widget) -{ - return widget->width; -} - -int -fbtk_get_x(fbtk_widget_t *widget) -{ - int x = widget->x; - - while (widget->parent != NULL) { - widget = widget->parent; - x += widget->x; - } - - return x; -} - -int -fbtk_get_y(fbtk_widget_t *widget) -{ - int y = widget->y; - - while (widget->parent != NULL) { - widget = widget->parent; - y += widget->y; - } - - return y; -} - -void -fbtk_set_handler_click(fbtk_widget_t *widget, fbtk_mouseclick_t click, void *pw) -{ - widget->click = click; - widget->clickpw = pw; -} - -void -fbtk_set_handler_input(fbtk_widget_t *widget, fbtk_input_t input, void *pw) -{ - widget->input = input; - widget->inputpw = pw; -} - -void -fbtk_set_handler_redraw(fbtk_widget_t *widget, fbtk_redraw_t redraw, void *pw) -{ - widget->redraw = redraw; - widget->redrawpw = pw; -} - -void -fbtk_set_handler_move(fbtk_widget_t *widget, fbtk_move_t move, void *pw) -{ - widget->move = move; - widget->movepw = pw; -} - -void * -fbtk_get_userpw(fbtk_widget_t *widget) -{ - if ((widget == NULL) || (widget->type != FB_WIDGET_TYPE_USER)) - return NULL; - - return widget->u.user.pw; -} - -void -fbtk_set_text(fbtk_widget_t *widget, const char *text) -{ - if ((widget == NULL) || (widget->type != FB_WIDGET_TYPE_TEXT)) - return; - if (widget->u.text.text != NULL) { - if (strcmp(widget->u.text.text, text) == 0) - return; /* text is being set to the same thing */ - free(widget->u.text.text); - } - widget->u.text.text = strdup(text); - widget->u.text.idx = strlen(text); - - fbtk_request_redraw(widget); -} - -void -fbtk_set_scroll(fbtk_widget_t *widget, int pct) -{ - if (widget == NULL) - return; - - if ((widget->type == FB_WIDGET_TYPE_HSCROLL) || - (widget->type == FB_WIDGET_TYPE_VSCROLL)) { - - widget->u.scroll.pct = pct; - fbtk_request_redraw(widget); - } -} - -void -fbtk_set_scroll_pos(fbtk_widget_t *widget, int pos) -{ - if (widget == NULL) - return; - - if ((widget->type == FB_WIDGET_TYPE_HSCROLL) || - (widget->type == FB_WIDGET_TYPE_VSCROLL)) { - - widget->u.scroll.pos = pos; - - fbtk_request_redraw(widget); - } -} - -void -fbtk_set_bitmap(fbtk_widget_t *widget, struct bitmap *image) -{ - if ((widget == NULL) || (widget->type != FB_WIDGET_TYPE_BITMAP)) - return; - - widget->u.bitmap.bitmap = image; - - fbtk_request_redraw(widget); -} - -void -fbtk_set_pos_and_size(fbtk_widget_t *widget, int x, int y, int width, int height) -{ - if ((widget->x != x) || - (widget->y != y) || - (widget->width != width) || - (widget->height != height)) { - widget->x = x; - widget->y = y; - widget->width = width; - widget->height = height; - fbtk_request_redraw(widget); - LOG(("%d,%d %d,%d",x,y,width,height)); - } -} - -int -fbtk_count_children(fbtk_widget_t *widget) -{ - int count = 0; - fbtk_widget_list_t *lent; - - if (widget->type != FB_WIDGET_TYPE_WINDOW) { - if (widget->type != FB_WIDGET_TYPE_ROOT) - return -1; - widget = widget->u.root.rootw; - } - - lent = widget->u.window.widgets; - - while (lent != NULL) { - count++; - lent = lent->next; - } - - return count; -} - - -void -fbtk_input(fbtk_widget_t *widget, uint32_t ucs4) -{ - fbtk_widget_t *input; - - widget = get_root_widget(widget); - - /* obtain widget with input focus */ - input = widget->u.root.input; - if (input == NULL) - return; - - if (input->input == NULL) - return; - - input->input(input, ucs4, input->inputpw); -} - -void -fbtk_click(fbtk_widget_t *widget, browser_mouse_state st) -{ - fbtk_widget_t *root; - fbtk_widget_t *window; - int x; - int y; - - /* ensure we have the root widget */ - root = get_root_widget(widget); - - x = fb_cursor_x(root->u.root.fb); - y = fb_cursor_y(root->u.root.fb); - - /* get the root window */ - window = root->u.root.rootw; - - if (window->click != NULL) - window->click(window, st, x, y, window->clickpw); -} - - - -void -fbtk_move_pointer(fbtk_widget_t *widget, int x, int y, bool relative) -{ - fbtk_widget_t *root; - fbtk_widget_t *window; - - /* ensure we have the root widget */ - root = get_root_widget(widget); - - if (relative) { - x += fb_cursor_x(root->u.root.fb); - y += fb_cursor_y(root->u.root.fb); - } - - root->redraw_required = true; - - fb_cursor_move(root->u.root.fb, x, y); - - /* get the root window */ - window = root->u.root.rootw; - - if (window->move != NULL) - window->move(window, x, y,window->movepw); - -} - -int -fbtk_redraw(fbtk_widget_t *widget) -{ - fbtk_widget_t *root; - fbtk_widget_t *window; - bbox_t saved_plot_ctx; - - - /* ensure we have the root widget */ - root = get_root_widget(widget); - - if (!root->redraw_required) - return 0; - - /* set the clipping rectangle to the widget area */ - saved_plot_ctx = fb_plot_ctx; - - /* get the root window */ - window = root->u.root.rootw; - - fb_plot_ctx.x0 = window->x; - fb_plot_ctx.y0 = window->y; - fb_plot_ctx.x1 = window->x + window->width; - fb_plot_ctx.y1 = window->y + window->height; - - fb_cursor_clear(root->u.root.fb); - - if (window->redraw != NULL) - fbtk_redraw_widget(window); - - root->redraw_required = false; - - fb_plot_ctx = saved_plot_ctx; - - fb_cursor_plot(root->u.root.fb); - - return 1; - -} - -/****** widget destruction ********/ -int fbtk_destroy_widget(fbtk_widget_t *widget) -{ - if (widget->type == FB_WIDGET_TYPE_WINDOW) { - /* TODO: walk child widgets and destroy them */ - } - - remove_widget_from_window(widget->parent, widget); - free(widget); - - return 0; -} - - -/************** Widget creation *************/ -fbtk_widget_t * -fbtk_create_text(fbtk_widget_t *window, - int x, int y, - int width, int height, - colour bg, colour fg, - bool outline) -{ - fbtk_widget_t *newt = new_widget(FB_WIDGET_TYPE_TEXT); - - newt->x = x; - newt->y = y; - newt->width = width; - newt->height = height; - newt->u.text.outline = outline; - - newt->fg = fg; - newt->bg = bg; - - newt->redraw = fb_redraw_text; - - return add_widget_to_window(window, newt); -} - -fbtk_widget_t * -fbtk_create_bitmap(fbtk_widget_t *window, int x, int y, colour c, struct bitmap *image) -{ - fbtk_widget_t *newb = new_widget(FB_WIDGET_TYPE_BITMAP); - - newb->x = x; - newb->y = y; - newb->width = image->width; - newb->height = image->height; - newb->bg = c; - - newb->u.bitmap.bitmap = image; - - newb->redraw = fb_redraw_bitmap; - - return add_widget_to_window(window, newb); -} - -static void -fbtk_width_height(fbtk_widget_t *parent, int x, int y, int *width, int *height) -{ - /* make widget fit inside parent */ - if (*width == 0) { - *width = parent->width - x; - } else if (*width < 0) { - *width = parent->width + *width; - } - if ((*width + x) > parent->width) { - *width = parent->width - x; - } - - if (*height == 0) { - *height = parent->height - y; - } else if (*height < 0) { - *height = parent->height + *height; - } - if ((*height + y) > parent->height) { - *height = parent->height - y; - } -} - -fbtk_widget_t * -fbtk_create_fill(fbtk_widget_t *window, int x, int y, int width, int height, colour c) -{ - fbtk_widget_t *neww = new_widget(FB_WIDGET_TYPE_FILL); - - neww->x = x; - neww->y = y; - neww->width = width; - neww->height = height; - - fbtk_width_height(window, x, y, &neww->width, &neww->height); - - neww->bg = c; - - neww->redraw = fb_redraw_fill; - - return add_widget_to_window(window, neww); -} - -fbtk_widget_t * -fbtk_create_hscroll(fbtk_widget_t *window, int x, int y, int width, int height, colour fg, colour bg) -{ - fbtk_widget_t *neww = new_widget(FB_WIDGET_TYPE_HSCROLL); - - neww->x = x; - neww->y = y; - neww->width = width; - neww->height = height; - neww->fg = fg; - neww->bg = bg; - - neww->redraw = fb_redraw_hscroll; - - return add_widget_to_window(window, neww); -} - -fbtk_widget_t * -fbtk_create_vscroll(fbtk_widget_t *window, int x, int y, int width, int height, colour fg, colour bg) -{ - fbtk_widget_t *neww = new_widget(FB_WIDGET_TYPE_VSCROLL); - - neww->x = x; - neww->y = y; - neww->width = width; - neww->height = height; - neww->fg = fg; - neww->bg = bg; - - neww->redraw = fb_redraw_vscroll; - - return add_widget_to_window(window, neww); -} - -fbtk_widget_t * -fbtk_create_button(fbtk_widget_t *window, - int x, int y, - colour c, - struct bitmap *image, - fbtk_mouseclick_t click, - void *pw) -{ - fbtk_widget_t *newb = fbtk_create_bitmap(window, x, y, c, image); - - newb->click = click; - newb->clickpw = pw; - - return newb; -} - -fbtk_widget_t * -fbtk_create_writable_text(fbtk_widget_t *window, - int x, int y, - int width, int height, - colour bg, colour fg, - bool outline, - fbtk_enter_t enter, void *pw) -{ - fbtk_widget_t *newt = fbtk_create_text(window, x, y, width, height, bg,fg,outline); - newt->u.text.enter = enter; - newt->u.text.pw = pw; - - newt->input = text_input; - newt->inputpw = newt; - return newt; -} - -/* create user widget - * - * @param x coord relative to parent - */ -fbtk_widget_t * -fbtk_create_user(fbtk_widget_t *window, - int x, int y, - int width, int height, - void *pw) -{ - fbtk_widget_t *newu = new_widget(FB_WIDGET_TYPE_USER); - - - /* make new window fit inside parent */ - if (width == 0) { - width = window->width - x; - } else if (width < 0) { - width = window->width + width; - } - if ((width + x) > window->width) { - width = window->width - x; - } - - if (height == 0) { - height = window->height - y; - } else if (height < 0) { - height = window->height + height; - } - if ((height + y) > window->height) { - height = window->height - y; - } - - newu->x = x; - newu->y = y; - newu->width = width; - newu->height = height; - - newu->u.user.pw = pw; - - return add_widget_to_window(window, newu); -} - - -/* create new window - * - * @param x coord relative to parent - */ -fbtk_widget_t * -fbtk_create_window(fbtk_widget_t *parent, - int x, int y, int width, int height) -{ - fbtk_widget_t *newwin; - - LOG(("Creating window %p %d,%d %d,%d",parent,x,y,width,height)); - if (parent == NULL) - return NULL; - - if ((parent->type == FB_WIDGET_TYPE_ROOT) && - (parent->u.root.rootw != NULL)) { - LOG(("Using root window")); - parent = parent->u.root.rootw; - } - - newwin = new_widget(FB_WIDGET_TYPE_WINDOW); - - /* make new window fit inside parent */ - if (width == 0) { - width = parent->width - x; - } else if (width < 0) { - width = parent->width + width; - } - if ((width + x) > parent->width) { - width = parent->width - x; - } - - if (height == 0) { - height = parent->height - y; - } else if (height < 0) { - height = parent->height + height; - } - if ((height + y) > parent->height) { - height = parent->height - y; - } - - newwin->x = x; - newwin->y = y; - newwin->width = width; - newwin->height = height; - - newwin->redraw = fbtk_window_default_redraw; - newwin->move = fbtk_window_default_move; - newwin->click = fbtk_window_default_click; - - LOG(("Created window %p %d,%d %d,%d",newwin,x,y,width,height)); - - return add_widget_to_window(parent, newwin); -} - - -/* Initialise toolkit for use */ -fbtk_widget_t * -fbtk_init(framebuffer_t *fb) -{ - fbtk_widget_t *root = new_widget(FB_WIDGET_TYPE_ROOT); - - root->u.root.fb = fb; - root->x = 0; - root->y = 0; - root->width = framebuffer->width; - root->height = framebuffer->height; - root->u.root.rootw = fbtk_create_window(root, 0, 0, 0, 0); - - root_style.font_size.value.length.unit = CSS_UNIT_PX; - root_style.font_size.value.length.value = 14; - - return root; -} - -/* - * Local Variables: - * c-basic-offset:8 - * End: - */ diff --git a/framebuffer/fb_tk.h b/framebuffer/fb_tk.h deleted file mode 100644 index 8d51a4840..000000000 --- a/framebuffer/fb_tk.h +++ /dev/null @@ -1,212 +0,0 @@ - -#define FB_SCROLL_COLOUR 0xFF888888 -#define FB_FRAME_COLOUR 0xFFDDDDDD -#define FB_COLOUR_BLACK 0xFF000000 -#define FB_COLOUR_WHITE 0xFFFFFFFF - -typedef struct fbtk_widget_s fbtk_widget_t; - -/* user widget callback */ -typedef int (*fbtk_user_t)(fbtk_widget_t *widget, void *pw); - -/* input callback */ -typedef int (*fbtk_input_t)(fbtk_widget_t *widget, int value, void *pw); - -/* mouse click callback */ -typedef int (*fbtk_mouseclick_t)(fbtk_widget_t *widget, browser_mouse_state st, int x, int y, void *pw); - -/* mouse move callback */ -typedef int (*fbtk_move_t)(fbtk_widget_t *widget, int x, int y, void *pw); - -/* redraw function */ -typedef int (*fbtk_redraw_t)(fbtk_widget_t *widget, void *pw); - -/* enter pressed on writable icon */ -typedef int (*fbtk_enter_t)(void *pw, char *text); - - -/* Widget creation */ - -/** Initialise widget toolkit. - * - * Initialises widget toolkit and creates root window against a framebuffer. - * - * @param fb The underlying framebuffer. - * @return The root widget handle. - */ -fbtk_widget_t *fbtk_init(framebuffer_t *fb); - -/** Create a window widget. - * - * @param parent The parent window or the root widget for a top level window. - * @param x The x location relative to the parent window. - * @param y the y location relative to the parent window. - * @param width The width of the window. 0 indicates parents width should be - * used. Negative value indicates parents width less the value - * should be used. The width is limited to lie within the parent - * window. - * @param height The height of the window limited in a similar way to the - * /a width. - * @param c The background colour. - * @return new window widget handle or NULL on error. - */ -fbtk_widget_t *fbtk_create_window(fbtk_widget_t *parent, int x, int y, int width, int height); - -/** Create a text widget. - * - * @param window The window to add the text widget to. - * @return new widget handle or NULL on error. - */ -fbtk_widget_t *fbtk_create_text(fbtk_widget_t *window, int x, int y, int width, int height, colour bg, colour fg, bool outline); - -/** Create a bitmap widget. - * - * Create a widget which shows a bitmap. - * - * @param window The window to add the bitmap widget to. - * @return new widget handle or NULL on error. - */ -fbtk_widget_t *fbtk_create_bitmap(fbtk_widget_t *window, int x, int y, colour c,struct bitmap *image); - -/** Create a filled rectangle - * - * Create a widget which is a filled rectangle, usually used for backgrounds. - * - * @param window The window to add the filled area widget to. - * @return new widget handle or NULL on error. - */ -fbtk_widget_t * -fbtk_create_fill(fbtk_widget_t *window, int x, int y, int width, int height, colour c); - -/** Create a horizontal scroll widget - * - * Create a horizontal scroll widget. - * - * @param window The window to add the filled area widget to. - * @return new widget handle or NULL on error. - */ -fbtk_widget_t * -fbtk_create_hscroll(fbtk_widget_t *window, int x, int y, int width, int height, colour fg, colour bg); - -/** Create a vertical scroll widget - * - * Create a vertical scroll widget. - * - * @param window The window to add the filled area widget to. - * @return new widget handle or NULL on error. - */ -fbtk_widget_t * -fbtk_create_vscroll(fbtk_widget_t *window, int x, int y, int width, int height, colour fg, colour bg); - -/** Create a user widget. - * - * Create a widget which is to be handled entirely by the calling application. - * - * @param window The window to add the user widget to. - * @param pw The private pointer which can be read using ::fbtk_get_pw - * @return new widget handle or NULL on error. - */ -fbtk_widget_t *fbtk_create_user(fbtk_widget_t *window, int x, int y, int width, int height, void *pw); - - -/** Create a button widget. - * - * Helper function which creates a bitmap widget and associate a handler for - * when it is clicked. - * - * @param window The window to add the button widget to. - * @return new widget handle or NULL on error. - */ -fbtk_widget_t *fbtk_create_button(fbtk_widget_t *window, int x, int y, colour c, struct bitmap *image, fbtk_mouseclick_t click, void *pw); - -/** Create a writable text widget. - * - * Helper function which creates a text widget and configures an input handler - * to create a writable text field. This call is equivalent to calling - * ::fbtk_create_text followed by ::fbtk_writable_text - * - * @param window The window to add the text widget to. - * @return new widget handle or NULL on error. - */ -fbtk_widget_t *fbtk_create_writable_text(fbtk_widget_t *window, int x, int y, int width, int height, colour bg, colour fg, bool outline, fbtk_enter_t enter, void *pw); - - -/* Widget Destruction */ - -/** Destroy and free a widget and all its children. - * - * @param widget The widget to destroy. - * @return 0 on success or -1 on error. - */ -int fbtk_destroy_widget(fbtk_widget_t *widget); - -/* Widget information */ - -int fbtk_get_y(fbtk_widget_t *widget); -int fbtk_get_x(fbtk_widget_t *widget); -int fbtk_get_width(fbtk_widget_t *widget); -int fbtk_get_height(fbtk_widget_t *widget); -void *fbtk_get_userpw(fbtk_widget_t *widget); - -/* Set widget properties */ - -void fbtk_set_text(fbtk_widget_t *widget, const char *text); -void fbtk_set_bitmap(fbtk_widget_t *widget, struct bitmap *image); -void fbtk_set_scroll(fbtk_widget_t *widget, int pct); -void fbtk_set_scroll_pos(fbtk_widget_t *widget, int pos); -void fbtk_set_pos_and_size(fbtk_widget_t *widget, int x, int y, int width, int height); -void fbtk_set_handler_redraw(fbtk_widget_t *widget, fbtk_redraw_t input, void *pw); -void fbtk_set_handler_input(fbtk_widget_t *widget, fbtk_input_t input, void *pw); -void fbtk_set_handler_click(fbtk_widget_t *widget, fbtk_mouseclick_t click, void *pw); -void fbtk_set_handler_move(fbtk_widget_t *widget, fbtk_move_t move, void *pw); - -/** Alter a text widget to be writable. - */ -void fbtk_writable_text(fbtk_widget_t *widget, fbtk_enter_t enter, void *pw); - - -/* General routines */ - -bool fbtk_clip_rect(const bbox_t * restrict clip, bbox_t * restrict box); - -/** Pointer movement. - * - * Pointer has been moved. - * - * @param widget any tookit widget. - * @parm x movement in horizontal plane. - * @parm y movement in vertical plane. - * @parm relative Wether the /a x and /a y should be considered relative to - * current pointer position. - */ -void fbtk_move_pointer(fbtk_widget_t *widget, int x, int y, bool relative); - -/** Mouse has been clicked - */ -void fbtk_click(fbtk_widget_t *widget, browser_mouse_state st); - -/** Input has been recived - */ -void fbtk_input(fbtk_widget_t *widget, uint32_t ucs4); - -/** Indicate a widget has to be redrawn - */ -void fbtk_request_redraw(fbtk_widget_t *widget); - -/** Cause a redraw to happen. - */ -int fbtk_redraw(fbtk_widget_t *widget); - -int fbtk_count_children(fbtk_widget_t *widget); - - - - - - - - - - - - diff --git a/framebuffer/fbtk.c b/framebuffer/fbtk.c new file mode 100644 index 000000000..21e796eac --- /dev/null +++ b/framebuffer/fbtk.c @@ -0,0 +1,1337 @@ +/* + * Copyright 2008 Vincent Sanders + * + * Framebuffer windowing toolkit + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "utils/log.h" +#include "css/css.h" +#include "desktop/browser.h" +#include "desktop/plotters.h" + +#include "framebuffer/gui.h" +#include "framebuffer/fbtk.h" +#include "framebuffer/bitmap.h" +#include "framebuffer/image_data.h" + +static struct css_style root_style; + +enum fbtk_widgettype_e { + FB_WIDGET_TYPE_ROOT = 0, + FB_WIDGET_TYPE_WINDOW, + FB_WIDGET_TYPE_BITMAP, + FB_WIDGET_TYPE_FILL, + FB_WIDGET_TYPE_TEXT, + FB_WIDGET_TYPE_HSCROLL, + FB_WIDGET_TYPE_VSCROLL, + FB_WIDGET_TYPE_USER, +}; + +typedef struct fbtk_widget_list_s fbtk_widget_list_t; + +/* wrapper struct for all widget types */ +struct fbtk_widget_s { + /* Generic properties */ + int x; + int y; + int width; + int height; + colour bg; + colour fg; + + /* handlers */ + fbtk_mouseclick_t click; + void *clickpw; /* private data for callback */ + + fbtk_input_t input; + void *inputpw; /* private data for callback */ + + fbtk_move_t move; + void *movepw; /* private data for callback */ + + fbtk_redraw_t redraw; + void *redrawpw; /* private data for callback */ + + bool redraw_required; + + fbtk_widget_t *parent; /* parent widget */ + + /* Widget specific */ + enum fbtk_widgettype_e type; + + union { + /* toolkit base handle */ + struct { + nsfb_t *fb; + fbtk_widget_t *rootw; + fbtk_widget_t *input; + } root; + + /* window */ + struct { + /* widgets associated with this window */ + fbtk_widget_list_t *widgets; /* begining of list */ + fbtk_widget_list_t *widgets_end; /* end of list */ + } window; + + /* bitmap */ + struct { + struct bitmap *bitmap; + } bitmap; + + /* text */ + struct { + char* text; + bool outline; + fbtk_enter_t enter; + void *pw; + int idx; + } text; + + /* application driven widget */ + struct { + void *pw; /* private data for user widget */ + } user; + + struct { + int pos; + int pct; + } scroll; + + } u; +}; + +/* widget list */ +struct fbtk_widget_list_s { + struct fbtk_widget_list_s *next; + struct fbtk_widget_list_s *prev; + fbtk_widget_t *widget; +} ; + +enum { + POINT_LEFTOF_REGION = 1, + POINT_RIGHTOF_REGION = 2, + POINT_ABOVE_REGION = 4, + POINT_BELOW_REGION = 8, +}; + +#define REGION(x,y,cx1,cx2,cy1,cy2) \ + (( (y) > (cy2) ? POINT_BELOW_REGION : 0) | \ + ( (y) < (cy1) ? POINT_ABOVE_REGION : 0) | \ + ( (x) > (cx2) ? POINT_RIGHTOF_REGION : 0) | \ + ( (x) < (cx1) ? POINT_LEFTOF_REGION : 0) ) + +#define SWAP(a, b) do { int t; t=(a); (a)=(b); (b)=t; } while(0) + +/* clip a rectangle to another rectangle */ +bool fbtk_clip_rect(const bbox_t * restrict clip, bbox_t * restrict box) +{ + uint8_t region1; + uint8_t region2; + + if (box->x1 < box->x0) SWAP(box->x0, box->x1); + if (box->y1 < box->y0) SWAP(box->y0, box->y1); + + region1 = REGION(box->x0, box->y0, clip->x0, clip->x1 - 1, clip->y0, clip->y1 - 1); + region2 = REGION(box->x1, box->y1, clip->x0, clip->x1 - 1, clip->y0, clip->y1 - 1); + + /* area lies entirely outside the clipping rectangle */ + if ((region1 | region2) && (region1 & region2)) + return false; + + if (box->x0 < clip->x0) + box->x0 = clip->x0; + if (box->x0 > clip->x1) + box->x0 = clip->x1; + + if (box->x1 < clip->x0) + box->x1 = clip->x0; + if (box->x1 > clip->x1) + box->x1 = clip->x1; + + if (box->y0 < clip->y0) + box->y0 = clip->y0; + if (box->y0 > clip->y1) + box->y0 = clip->y1; + + if (box->y1 < clip->y0) + box->y1 = clip->y0; + if (box->y1 > clip->y1) + box->y1 = clip->y1; + + return true; +} + + +/* creates a new widget of a given type */ +static fbtk_widget_t * +new_widget(enum fbtk_widgettype_e type) +{ + fbtk_widget_t *neww; + neww = calloc(1, sizeof(fbtk_widget_t)); + neww->type = type; + return neww; +} + + +/* find the root widget from any widget in the toolkits hierarchy */ +static fbtk_widget_t * +get_root_widget(fbtk_widget_t *widget) +{ + while (widget->parent != NULL) + widget = widget->parent; + + /* check root widget was found */ + if (widget->type != FB_WIDGET_TYPE_ROOT) { + LOG(("Widget with null parent that is not the root widget!")); + return NULL; + } + + return widget; +} + + +/* set widget to be redrawn */ +void +fbtk_request_redraw(fbtk_widget_t *widget) +{ + widget->redraw_required = 1; + + if (widget->type == FB_WIDGET_TYPE_WINDOW) { + fbtk_widget_list_t *lent = widget->u.window.widgets; + + while (lent != NULL) { + lent->widget->redraw_required = 1; + lent = lent->next; + } + } + + while (widget->parent != NULL) { + widget = widget->parent; + widget->redraw_required = 1; + } +} + +static fbtk_widget_t * +add_widget_to_window(fbtk_widget_t *window, fbtk_widget_t *widget) +{ + fbtk_widget_list_t *newent; + fbtk_widget_list_t **nextent; + fbtk_widget_list_t *prevent; /* previous entry pointer */ + + if (window->type == FB_WIDGET_TYPE_WINDOW) { + /* caller attached widget to a window */ + + nextent = &window->u.window.widgets; + prevent = NULL; + while (*nextent != NULL) { + prevent = (*nextent); + nextent = &(prevent->next); + } + + newent = calloc(1, sizeof(struct fbtk_widget_list_s)); + + newent->widget = widget; + newent->next = NULL; + newent->prev = prevent; + + *nextent = newent; + + window->u.window.widgets_end = newent; + } + widget->parent = window; + + fbtk_request_redraw(widget); + + return widget; +} + +static void +remove_widget_from_window(fbtk_widget_t *window, fbtk_widget_t *widget) +{ + fbtk_widget_list_t *lent = window->u.window.widgets; + + while ((lent != NULL) && (lent->widget != widget)) { + lent = lent->next; + } + + if (lent != NULL) { + if (lent->prev == NULL) { + window->u.window.widgets = lent->next; + } else { + lent->prev->next = lent->next; + } + if (lent->next == NULL) { + window->u.window.widgets_end = lent->prev; + } else { + lent->next->prev = lent->prev; + } + free(lent); + } +} + +static void +fbtk_redraw_widget(fbtk_widget_t *root, fbtk_widget_t *widget) +{ + nsfb_bbox_t saved_plot_ctx; + nsfb_bbox_t plot_ctx; + + //LOG(("widget %p type %d", widget, widget->type)); + if (widget->redraw_required == false) + return; + + widget->redraw_required = false; + + /* ensure there is a redraw handler */ + if (widget->redraw == NULL) + return; + + /* get the current clipping rectangle */ + nsfb_plot_get_clip(root->u.root.fb, &saved_plot_ctx); + + plot_ctx.x0 = fbtk_get_x(widget); + plot_ctx.y0 = fbtk_get_y(widget); + plot_ctx.x1 = plot_ctx.x0 + widget->width; + plot_ctx.y1 = plot_ctx.y0 + widget->height; + + /* clip widget to the current area and redraw if its exposed */ + if (nsfb_plot_clip(&saved_plot_ctx, &plot_ctx )) { + + nsfb_plot_set_clip(root->u.root.fb, &plot_ctx); + + /* do our drawing according to type */ + widget->redraw(root, widget, widget->redrawpw); + + /* restore clipping rectangle */ + nsfb_plot_set_clip(root->u.root.fb, &saved_plot_ctx); + + //LOG(("OS redrawing %d,%d %d,%d", fb_plot_ctx.x0, fb_plot_ctx.y0, fb_plot_ctx.x1, fb_plot_ctx.y1)); + } + +} + +/*************** redraw widgets **************/ + +static int +fb_redraw_fill(fbtk_widget_t *root, fbtk_widget_t *widget, void *pw) +{ + nsfb_bbox_t bbox; + fbtk_get_bbox(widget, &bbox); + + nsfb_claim(root->u.root.fb, &bbox); + + /* clear background */ + if ((widget->bg & 0xFF000000) != 0) { + /* transparent polygon filling isnt working so fake it */ + nsfb_plot_rectangle_fill(root->u.root.fb, &bbox, widget->bg); + } + + nsfb_release(root->u.root.fb, &bbox); + return 0; +} + +static int +fb_redraw_hscroll(fbtk_widget_t *root, fbtk_widget_t *widget, void *pw) +{ + int hscroll; + int hpos; + nsfb_bbox_t bbox; + nsfb_bbox_t rect; + + fbtk_get_bbox(widget, &bbox); + + nsfb_claim(root->u.root.fb, &bbox); + + rect = bbox; + + nsfb_plot_rectangle_fill(root->u.root.fb, &rect, widget->bg); + + rect.x0 = bbox.x0 + 1; + rect.y0 = bbox.y0 + 3; + rect.x1 = bbox.x1 - 1; + rect.y1 = bbox.y1 - 3; + + nsfb_plot_rectangle_fill(root->u.root.fb, &rect, widget->fg); + + rect.x0 = bbox.x0; + rect.y0 = bbox.y0 + 2; + rect.x1 = bbox.x1 - 1; + rect.y1 = bbox.y1 - 5; + + nsfb_plot_rectangle(root->u.root.fb, &rect, 1, 0xFF000000, false, false); + + hscroll = ((widget->width - 4) * widget->u.scroll.pct) / 100 ; + hpos = ((widget->width - 4) * widget->u.scroll.pos) / 100 ; + + LOG(("hscroll %d",hscroll)); + + rect.x0 = bbox.x0 + 3 + hpos; + rect.y0 = bbox.y0 + 5; + rect.x1 = bbox.x0 + hscroll + hpos; + rect.y1 = bbox.y0 + widget->height - 5; + + nsfb_plot_rectangle_fill(root->u.root.fb, &rect, widget->bg); + + nsfb_release(root->u.root.fb, &bbox); + + return 0; +} + +static int +fb_redraw_vscroll(fbtk_widget_t *root, fbtk_widget_t *widget, void *pw) +{ + int vscroll; + int vpos; + + nsfb_bbox_t bbox; + nsfb_bbox_t rect; + + fbtk_get_bbox(widget, &bbox); + + nsfb_claim(root->u.root.fb, &bbox); + + rect = bbox; + + nsfb_plot_rectangle_fill(root->u.root.fb, &rect, widget->bg); + + rect.x0 = bbox.x0 + 1; + rect.y0 = bbox.y0 + 3; + rect.x1 = bbox.x1 - 1; + rect.y1 = bbox.y1 - 3; + + nsfb_plot_rectangle_fill(root->u.root.fb, &rect, widget->fg); + + rect.x0 = bbox.x0; + rect.y0 = bbox.y0 + 2; + rect.x1 = bbox.x1 - 1; + rect.y1 = bbox.y1 - 5; + + nsfb_plot_rectangle(root->u.root.fb, &rect, 1, 0xFF000000, false, false); + + vscroll = ((widget->height - 4) * widget->u.scroll.pct) / 100 ; + vpos = ((widget->height - 4) * widget->u.scroll.pos) / 100 ; + + LOG(("scroll %d",vscroll)); + + rect.x0 = bbox.x0 + 3 ; + rect.y0 = bbox.y0 + 5 + vpos; + rect.x1 = bbox.x0 + widget->width - 3; + rect.y1 = bbox.y0 + vscroll + vpos - 5; + + nsfb_plot_rectangle_fill(root->u.root.fb, &rect, widget->bg); + + nsfb_release(root->u.root.fb, &bbox); + + return 0; +} + +static int +fb_redraw_bitmap(fbtk_widget_t *root, fbtk_widget_t *widget, void *pw) +{ + nsfb_bbox_t bbox; + nsfb_bbox_t rect; + + fbtk_get_bbox(widget, &bbox); + + rect = bbox; + + nsfb_claim(root->u.root.fb, &bbox); + + /* clear background */ + if ((widget->bg & 0xFF000000) != 0) { + /* transparent polygon filling isnt working so fake it */ + nsfb_plot_rectangle_fill(root->u.root.fb, &bbox, widget->bg); + } + + /* plot the image */ + nsfb_plot_bitmap(root->u.root.fb, &rect, (nsfb_colour_t *)widget->u.bitmap.bitmap->pixdata, widget->u.bitmap.bitmap->width, widget->u.bitmap.bitmap->height, widget->u.bitmap.bitmap->width, !widget->u.bitmap.bitmap->opaque); + + nsfb_release(root->u.root.fb, &bbox); + + return 0; +} + +static int +fbtk_window_default_redraw(fbtk_widget_t *root, fbtk_widget_t *window, void *pw) +{ + fbtk_widget_list_t *lent; + int res = 0; + + if (!window->redraw) + return res; + + /* get the list of widgets */ + lent = window->u.window.widgets; + + while (lent != NULL) { + fbtk_redraw_widget(root, lent->widget); + lent = lent->next; + } + return res; +} + +static int +fbtk_window_default_move(fbtk_widget_t *window, int x, int y, void *pw) +{ + fbtk_widget_list_t *lent; + fbtk_widget_t *widget; + int res = 0; + + /* get the list of widgets */ + lent = window->u.window.widgets_end; + + while (lent != NULL) { + widget = lent->widget; + + if ((x > widget->x) && + (y > widget->y) && + (x < widget->x + widget->width) && + (y < widget->y + widget->height)) { + if (widget->move != NULL) { + res = widget->move(widget, + x - widget->x, + y - widget->y, + widget->movepw); + } + break; + } + lent = lent->prev; + } + return res; +} + +static int +fbtk_window_default_click(fbtk_widget_t *window, nsfb_event_t *event, int x, int y, void *pw) +{ + fbtk_widget_list_t *lent; + fbtk_widget_t *widget; + int res = 0; + + /* get the list of widgets */ + lent = window->u.window.widgets; + + while (lent != NULL) { + widget = lent->widget; + + if ((x > widget->x) && + (y > widget->y) && + (x < widget->x + widget->width) && + (y < widget->y + widget->height)) { + if (widget->input != NULL) { + fbtk_widget_t *root = get_root_widget(widget); + root->u.root.input = widget; + } + + if (widget->click != NULL) { + res = widget->click(widget, + event, + x - widget->x, + y - widget->y, + widget->clickpw); + break; + } + + + + } + lent = lent->next; + } + return res; +} + +static int +fb_redraw_text(fbtk_widget_t *root, fbtk_widget_t *widget, void *pw) +{ + nsfb_bbox_t bbox; + nsfb_bbox_t rect; + + fbtk_get_bbox(widget, &bbox); + + rect = bbox; + + nsfb_claim(root->u.root.fb, &bbox); + + /* clear background */ + if ((widget->bg & 0xFF000000) != 0) { + /* transparent polygon filling isnt working so fake it */ + nsfb_plot_rectangle_fill(root->u.root.fb, &bbox, widget->bg); + } + + + if (widget->u.text.outline) { + rect.x1--; + rect.y1--; + nsfb_plot_rectangle(root->u.root.fb, &rect, 1, 0x00000000, false, false); + } + + if (widget->u.text.text != NULL) { + plot.text(bbox.x0 + 3, + bbox.y0 + 17, + &root_style, + widget->u.text.text, + strlen(widget->u.text.text), + widget->bg, + widget->fg); + } + + nsfb_release(root->u.root.fb, &bbox); + + return 0; +} + + + + +static int +text_input(fbtk_widget_t *widget, nsfb_event_t *event, void *pw) +{ + int value; + if (event == NULL) { + /* gain focus */ + if (widget->u.text.text == NULL) + widget->u.text.text = calloc(1,1); + widget->u.text.idx = strlen(widget->u.text.text); + + fbtk_request_redraw(widget); + + return 0; + + } + + if (event->type != NSFB_EVENT_KEY_DOWN) + return 0; + + value = event->value.keycode; + switch (value) { + case NSFB_KEY_BACKSPACE: + if (widget->u.text.idx <= 0) + break; + widget->u.text.idx--; + widget->u.text.text[widget->u.text.idx] = 0; + break; + + case NSFB_KEY_RETURN: + widget->u.text.enter(widget->u.text.pw, widget->u.text.text); + break; + + default: + /* allow for new character and null */ + widget->u.text.text = realloc(widget->u.text.text, widget->u.text.idx + 2); + widget->u.text.text[widget->u.text.idx] = value; + widget->u.text.text[widget->u.text.idx + 1] = '\0'; + widget->u.text.idx++; + break; + } + + fbtk_request_redraw(widget); + + return 0; +} + +/* sets the enter action on a writable icon */ +void +fbtk_writable_text(fbtk_widget_t *widget, fbtk_enter_t enter, void *pw) +{ + widget->u.text.enter = enter; + widget->u.text.pw = pw; + + widget->input = text_input; + widget->inputpw = widget; +} + + +/********** acessors ***********/ +int +fbtk_get_height(fbtk_widget_t *widget) +{ + return widget->height; +} + +int +fbtk_get_width(fbtk_widget_t *widget) +{ + return widget->width; +} + +int +fbtk_get_x(fbtk_widget_t *widget) +{ + int x = widget->x; + + while (widget->parent != NULL) { + widget = widget->parent; + x += widget->x; + } + + return x; +} + +int +fbtk_get_y(fbtk_widget_t *widget) +{ + int y = widget->y; + + while (widget->parent != NULL) { + widget = widget->parent; + y += widget->y; + } + + return y; +} + +/* get widgets bounding box in screen co-ordinates */ +bool +fbtk_get_bbox(fbtk_widget_t *widget, nsfb_bbox_t *bbox) +{ + bbox->x0 = widget->x; + bbox->y0 = widget->y; + bbox->x1 = widget->x + widget->width; + bbox->y1 = widget->y + widget->height; + + while (widget->parent != NULL) { + widget = widget->parent; + bbox->x0 += widget->x; + bbox->y0 += widget->y; + bbox->x1 += widget->x; + bbox->y1 += widget->y; + } + + return true; +} + +void +fbtk_set_handler_click(fbtk_widget_t *widget, fbtk_mouseclick_t click, void *pw) +{ + widget->click = click; + widget->clickpw = pw; +} + +void +fbtk_set_handler_input(fbtk_widget_t *widget, fbtk_input_t input, void *pw) +{ + widget->input = input; + widget->inputpw = pw; +} + +void +fbtk_set_handler_redraw(fbtk_widget_t *widget, fbtk_redraw_t redraw, void *pw) +{ + widget->redraw = redraw; + widget->redrawpw = pw; +} + +void +fbtk_set_handler_move(fbtk_widget_t *widget, fbtk_move_t move, void *pw) +{ + widget->move = move; + widget->movepw = pw; +} + +void * +fbtk_get_userpw(fbtk_widget_t *widget) +{ + if ((widget == NULL) || (widget->type != FB_WIDGET_TYPE_USER)) + return NULL; + + return widget->u.user.pw; +} + +void +fbtk_set_text(fbtk_widget_t *widget, const char *text) +{ + if ((widget == NULL) || (widget->type != FB_WIDGET_TYPE_TEXT)) + return; + if (widget->u.text.text != NULL) { + if (strcmp(widget->u.text.text, text) == 0) + return; /* text is being set to the same thing */ + free(widget->u.text.text); + } + widget->u.text.text = strdup(text); + widget->u.text.idx = strlen(text); + + fbtk_request_redraw(widget); +} + +void +fbtk_set_scroll(fbtk_widget_t *widget, int pct) +{ + if (widget == NULL) + return; + + if ((widget->type == FB_WIDGET_TYPE_HSCROLL) || + (widget->type == FB_WIDGET_TYPE_VSCROLL)) { + + widget->u.scroll.pct = pct; + fbtk_request_redraw(widget); + } +} + +void +fbtk_set_scroll_pos(fbtk_widget_t *widget, int pos) +{ + if (widget == NULL) + return; + + if ((widget->type == FB_WIDGET_TYPE_HSCROLL) || + (widget->type == FB_WIDGET_TYPE_VSCROLL)) { + + widget->u.scroll.pos = pos; + + fbtk_request_redraw(widget); + } +} + +void +fbtk_set_bitmap(fbtk_widget_t *widget, struct bitmap *image) +{ + if ((widget == NULL) || (widget->type != FB_WIDGET_TYPE_BITMAP)) + return; + + widget->u.bitmap.bitmap = image; + + fbtk_request_redraw(widget); +} + +void +fbtk_set_pos_and_size(fbtk_widget_t *widget, int x, int y, int width, int height) +{ + if ((widget->x != x) || + (widget->y != y) || + (widget->width != width) || + (widget->height != height)) { + widget->x = x; + widget->y = y; + widget->width = width; + widget->height = height; + fbtk_request_redraw(widget); + LOG(("%d,%d %d,%d",x,y,width,height)); + } +} + +int +fbtk_count_children(fbtk_widget_t *widget) +{ + int count = 0; + fbtk_widget_list_t *lent; + + if (widget->type != FB_WIDGET_TYPE_WINDOW) { + if (widget->type != FB_WIDGET_TYPE_ROOT) + return -1; + widget = widget->u.root.rootw; + } + + lent = widget->u.window.widgets; + + while (lent != NULL) { + count++; + lent = lent->next; + } + + return count; +} + + +void +fbtk_input(fbtk_widget_t *root, nsfb_event_t *event) +{ + fbtk_widget_t *input; + + root = get_root_widget(root); + + /* obtain widget with input focus */ + input = root->u.root.input; + if (input == NULL) + return; /* no widget with input */ + + if (input->input == NULL) + return; + + /* call the widgets input method */ + input->input(input, event, input->inputpw); +} + +void +fbtk_click(fbtk_widget_t *widget, nsfb_event_t *event) +{ + fbtk_widget_t *root; + fbtk_widget_t *window; + nsfb_bbox_t cloc; + + /* ensure we have the root widget */ + root = get_root_widget(widget); + + nsfb_cursor_loc_get(root->u.root.fb, &cloc); + + /* get the root window */ + window = root->u.root.rootw; + LOG(("click %d, %d",cloc.x0,cloc.y0)); + if (window->click != NULL) + window->click(window, event, cloc.x0, cloc.y0, window->clickpw); +} + + + +void +fbtk_move_pointer(fbtk_widget_t *widget, int x, int y, bool relative) +{ + fbtk_widget_t *root; + fbtk_widget_t *window; + nsfb_bbox_t cloc; + + /* ensure we have the root widget */ + root = get_root_widget(widget); + + if (relative) { + nsfb_cursor_loc_get(root->u.root.fb, &cloc); + cloc.x0 += x; + cloc.y0 += y; + } else { + cloc.x0 = x; + cloc.y0 = y; + } + + root->redraw_required = true; + + nsfb_cursor_loc_set(root->u.root.fb, &cloc); + + /* get the root window */ + window = root->u.root.rootw; + + if (window->move != NULL) + window->move(window, cloc.x0, cloc.y0, window->movepw); + +} + +int +fbtk_redraw(fbtk_widget_t *widget) +{ + fbtk_widget_t *root; + + /* ensure we have the root widget */ + root = get_root_widget(widget); + + if (!root->redraw_required) + return 0; + + fbtk_redraw_widget(root, root->u.root.rootw); + + return 1; +} + +/****** widget destruction ********/ +int fbtk_destroy_widget(fbtk_widget_t *widget) +{ + if (widget->type == FB_WIDGET_TYPE_WINDOW) { + /* TODO: walk child widgets and destroy them */ + } + + remove_widget_from_window(widget->parent, widget); + free(widget); + + return 0; +} + + +/************** Widget creation *************/ +fbtk_widget_t * +fbtk_create_text(fbtk_widget_t *window, + int x, int y, + int width, int height, + colour bg, colour fg, + bool outline) +{ + fbtk_widget_t *newt = new_widget(FB_WIDGET_TYPE_TEXT); + + newt->x = x; + newt->y = y; + newt->width = width; + newt->height = height; + newt->u.text.outline = outline; + + newt->fg = fg; + newt->bg = bg; + + newt->redraw = fb_redraw_text; + + return add_widget_to_window(window, newt); +} + +fbtk_widget_t * +fbtk_create_bitmap(fbtk_widget_t *window, int x, int y, colour c, struct bitmap *image) +{ + fbtk_widget_t *newb = new_widget(FB_WIDGET_TYPE_BITMAP); + + newb->x = x; + newb->y = y; + newb->width = image->width; + newb->height = image->height; + newb->bg = c; + + newb->u.bitmap.bitmap = image; + + newb->redraw = fb_redraw_bitmap; + + return add_widget_to_window(window, newb); +} + +static void +fbtk_width_height(fbtk_widget_t *parent, int x, int y, int *width, int *height) +{ + /* make widget fit inside parent */ + if (*width == 0) { + *width = parent->width - x; + } else if (*width < 0) { + *width = parent->width + *width; + } + if ((*width + x) > parent->width) { + *width = parent->width - x; + } + + if (*height == 0) { + *height = parent->height - y; + } else if (*height < 0) { + *height = parent->height + *height; + } + if ((*height + y) > parent->height) { + *height = parent->height - y; + } +} + +fbtk_widget_t * +fbtk_create_fill(fbtk_widget_t *window, int x, int y, int width, int height, colour c) +{ + fbtk_widget_t *neww = new_widget(FB_WIDGET_TYPE_FILL); + + neww->x = x; + neww->y = y; + neww->width = width; + neww->height = height; + + fbtk_width_height(window, x, y, &neww->width, &neww->height); + + neww->bg = c; + + neww->redraw = fb_redraw_fill; + + return add_widget_to_window(window, neww); +} + +fbtk_widget_t * +fbtk_create_hscroll(fbtk_widget_t *window, int x, int y, int width, int height, colour fg, colour bg) +{ + fbtk_widget_t *neww = new_widget(FB_WIDGET_TYPE_HSCROLL); + + neww->x = x; + neww->y = y; + neww->width = width; + neww->height = height; + neww->fg = fg; + neww->bg = bg; + + neww->redraw = fb_redraw_hscroll; + + return add_widget_to_window(window, neww); +} + +fbtk_widget_t * +fbtk_create_vscroll(fbtk_widget_t *window, int x, int y, int width, int height, colour fg, colour bg) +{ + fbtk_widget_t *neww = new_widget(FB_WIDGET_TYPE_VSCROLL); + + neww->x = x; + neww->y = y; + neww->width = width; + neww->height = height; + neww->fg = fg; + neww->bg = bg; + + neww->redraw = fb_redraw_vscroll; + + return add_widget_to_window(window, neww); +} + +fbtk_widget_t * +fbtk_create_button(fbtk_widget_t *window, + int x, int y, + colour c, + struct bitmap *image, + fbtk_mouseclick_t click, + void *pw) +{ + fbtk_widget_t *newb = fbtk_create_bitmap(window, x, y, c, image); + + newb->click = click; + newb->clickpw = pw; + + return newb; +} + +fbtk_widget_t * +fbtk_create_writable_text(fbtk_widget_t *window, + int x, int y, + int width, int height, + colour bg, colour fg, + bool outline, + fbtk_enter_t enter, void *pw) +{ + fbtk_widget_t *newt = fbtk_create_text(window, x, y, width, height, bg,fg,outline); + newt->u.text.enter = enter; + newt->u.text.pw = pw; + + newt->input = text_input; + newt->inputpw = newt; + return newt; +} + +/* create user widget + * + * @param x coord relative to parent + */ +fbtk_widget_t * +fbtk_create_user(fbtk_widget_t *window, + int x, int y, + int width, int height, + void *pw) +{ + fbtk_widget_t *newu = new_widget(FB_WIDGET_TYPE_USER); + + + /* make new window fit inside parent */ + if (width == 0) { + width = window->width - x; + } else if (width < 0) { + width = window->width + width; + } + if ((width + x) > window->width) { + width = window->width - x; + } + + if (height == 0) { + height = window->height - y; + } else if (height < 0) { + height = window->height + height; + } + if ((height + y) > window->height) { + height = window->height - y; + } + + newu->x = x; + newu->y = y; + newu->width = width; + newu->height = height; + + newu->u.user.pw = pw; + + return add_widget_to_window(window, newu); +} + + +/* create new window + * + * @param x coord relative to parent + */ +fbtk_widget_t * +fbtk_create_window(fbtk_widget_t *parent, + int x, int y, int width, int height) +{ + fbtk_widget_t *newwin; + + LOG(("Creating window %p %d,%d %d,%d",parent,x,y,width,height)); + if (parent == NULL) + return NULL; + + if ((parent->type == FB_WIDGET_TYPE_ROOT) && + (parent->u.root.rootw != NULL)) { + LOG(("Using root window")); + parent = parent->u.root.rootw; + } + + newwin = new_widget(FB_WIDGET_TYPE_WINDOW); + + /* make new window fit inside parent */ + if (width == 0) { + width = parent->width - x; + } else if (width < 0) { + width = parent->width + width; + } + if ((width + x) > parent->width) { + width = parent->width - x; + } + + if (height == 0) { + height = parent->height - y; + } else if (height < 0) { + height = parent->height + height; + } + if ((height + y) > parent->height) { + height = parent->height - y; + } + + newwin->x = x; + newwin->y = y; + newwin->width = width; + newwin->height = height; + + newwin->redraw = fbtk_window_default_redraw; + newwin->move = fbtk_window_default_move; + newwin->click = fbtk_window_default_click; + + LOG(("Created window %p %d,%d %d,%d",newwin,x,y,width,height)); + + return add_widget_to_window(parent, newwin); +} + +bool fbtk_event(fbtk_widget_t *root, nsfb_event_t *event, int timeout) +{ + bool unused = false; /* is the event available */ + + /* ensure we have the root widget */ + root = get_root_widget(root); + + //LOG(("Reading event with timeout %d",timeout)); + + if (nsfb_event(root->u.root.fb, event, timeout) == false) + return false; + + switch (event->type) { + case NSFB_EVENT_KEY_DOWN: + case NSFB_EVENT_KEY_UP: + if ((event->value.controlcode >= NSFB_KEY_MOUSE_1) && + (event->value.controlcode <= NSFB_KEY_MOUSE_5)) { + fbtk_click(root, event); + } else { + fbtk_input(root, event); + } + break; + + case NSFB_EVENT_CONTROL: + unused = true; + break; + + case NSFB_EVENT_MOVE_RELATIVE: + fbtk_move_pointer(root, event->value.vector.x, event->value.vector.y, true); + break; + + case NSFB_EVENT_MOVE_ABSOLUTE: + fbtk_move_pointer(root, event->value.vector.x, event->value.vector.y, false); + break; + + default: + break; + + } + return unused; +} + + +nsfb_t * +fbtk_get_nsfb(fbtk_widget_t *widget) +{ + fbtk_widget_t *root; + + /* ensure we have the root widget */ + root = get_root_widget(widget); + + return root->u.root.fb; +} + +/* Initialise toolkit for use */ +fbtk_widget_t * +fbtk_init(nsfb_t *fb) +{ + fbtk_widget_t *root = new_widget(FB_WIDGET_TYPE_ROOT); + + nsfb_get_geometry(fb, &root->width, &root->height, NULL); + + LOG(("width %d height %d",root->width, root->height)); + root->u.root.fb = fb; + root->x = 0; + root->y = 0; + root->u.root.rootw = fbtk_create_window(root, 0, 0, 0, 0); + + root_style.font_size.value.length.unit = CSS_UNIT_PX; + root_style.font_size.value.length.value = 14; + + return root; +} + +static int keymap[] = { + /* 0 1 2 3 4 5 6 7 8 9 */ + -1, -1, -1, -1, -1, -1, -1, -1, 8, 9, /* 0 - 9 */ + -1, -1, -1, 13, -1, -1, -1, -1, -1, -1, /* 10 - 19 */ + -1, -1, -1, -1, -1, -1, -1, 27, -1, -1, /* 20 - 29 */ + -1, -1, ' ', '!', '"', '#', '$', -1, '&','\'', /* 30 - 39 */ + '(', ')', '*', '+', ',', '-', '.', '/', '0', '1', /* 40 - 49 */ + '2', '3', '4', '5', '6', '7', '8', '9', ':', ';', /* 50 - 59 */ + '<', '=', '>', '?', '@', -1, -1, -1, -1, -1, /* 60 - 69 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 70 - 79 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 80 - 89 */ + -1, '[','\\', ']', '~', '_', '`', 'a', 'b', 'c', /* 90 - 99 */ + 'd', 'e', 'f', 'g', 'h', 'i', 'j', 'k', 'l', 'm', /* 100 - 109 */ + 'n', 'o', 'p', 'q', 'r', 's', 't', 'u', 'v', 'w', /* 110 - 119 */ + 'x', 'y', 'z', -1, -1, -1, -1, -1, -1, -1, /* 120 - 129 */ +}; + +static int sh_keymap[] = { + /* 0 1 2 3 4 5 6 7 8 9 */ + -1, -1, -1, -1, -1, -1, -1, -1, 8, 9, /* 0 - 9 */ + -1, -1, -1, 13, -1, -1, -1, -1, -1, -1, /* 10 - 19 */ + -1, -1, -1, -1, -1, -1, -1, 27, -1, -1, /* 20 - 29 */ + -1, -1, ' ', '!', '"', '~', '$', -1, '&', '@', /* 30 - 39 */ + '(', ')', '*', '+', '<', '_', '>', '?', ')', '!', /* 40 - 49 */ + '"', 243, '&', '*', '(', ';', ':', /* 50 - 59 */ + '<', '+', '>', '?', '@', -1, -1, -1, -1, -1, /* 60 - 69 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 70 - 79 */ + -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, /* 80 - 89 */ + -1, '{', '|', '}', '~', '_', 254, 'A', 'B', 'C', /* 90 - 99 */ + 'D', 'E', 'F', 'G', 'H', 'I', 'J', 'K', 'L', 'M', /* 100 - 109 */ + 'N', 'O', 'P', 'Q', 'R', 'S', 'T', 'U', 'V', 'W', /* 110 - 119 */ + 'X', 'Y', 'Z', -1, -1, -1, -1, -1, -1, -1, /* 120 - 129 */ +}; + + +/* performs character mapping */ +int fbtk_keycode_to_ucs4(int code, uint8_t mods) +{ + int ucs4 = -1; + + if (mods) { + if ((code >= 0) && (code < sizeof(sh_keymap))) + ucs4 = sh_keymap[code]; + } else { + if ((code >= 0) && (code < sizeof(keymap))) + ucs4 = keymap[code]; + } + return ucs4; +} + +/* + * Local Variables: + * c-basic-offset:8 + * End: + */ diff --git a/framebuffer/fbtk.h b/framebuffer/fbtk.h new file mode 100644 index 000000000..95bd8b9a3 --- /dev/null +++ b/framebuffer/fbtk.h @@ -0,0 +1,216 @@ + +#define FB_SCROLL_COLOUR 0xFF888888 +#define FB_FRAME_COLOUR 0xFFDDDDDD +#define FB_COLOUR_BLACK 0xFF000000 +#define FB_COLOUR_WHITE 0xFFFFFFFF + +typedef struct fbtk_widget_s fbtk_widget_t; + +/* user widget callback */ +typedef int (*fbtk_user_t)(fbtk_widget_t *widget, void *pw); + +/* input callback */ +typedef int (*fbtk_input_t)(fbtk_widget_t *widget, nsfb_event_t *event, void *pw); + +/* mouse click callback */ +typedef int (*fbtk_mouseclick_t)(fbtk_widget_t *widget, nsfb_event_t *event, int x, int y, void *pw); + +/* mouse move callback */ +typedef int (*fbtk_move_t)(fbtk_widget_t *widget, int x, int y, void *pw); + +/* redraw function */ +typedef int (*fbtk_redraw_t)(fbtk_widget_t *root, fbtk_widget_t *widget, void *pw); + +/* enter pressed on writable icon */ +typedef int (*fbtk_enter_t)(void *pw, char *text); + + +/* Widget creation */ + +/** Initialise widget toolkit. + * + * Initialises widget toolkit and creates root window against a framebuffer. + * + * @param fb The underlying framebuffer. + * @return The root widget handle. + */ +fbtk_widget_t *fbtk_init(nsfb_t *fb); + +/** Create a window widget. + * + * @param parent The parent window or the root widget for a top level window. + * @param x The x location relative to the parent window. + * @param y the y location relative to the parent window. + * @param width The width of the window. 0 indicates parents width should be + * used. Negative value indicates parents width less the value + * should be used. The width is limited to lie within the parent + * window. + * @param height The height of the window limited in a similar way to the + * /a width. + * @param c The background colour. + * @return new window widget handle or NULL on error. + */ +fbtk_widget_t *fbtk_create_window(fbtk_widget_t *parent, int x, int y, int width, int height); + +/** Create a text widget. + * + * @param window The window to add the text widget to. + * @return new widget handle or NULL on error. + */ +fbtk_widget_t *fbtk_create_text(fbtk_widget_t *window, int x, int y, int width, int height, colour bg, colour fg, bool outline); + +/** Create a bitmap widget. + * + * Create a widget which shows a bitmap. + * + * @param window The window to add the bitmap widget to. + * @return new widget handle or NULL on error. + */ +fbtk_widget_t *fbtk_create_bitmap(fbtk_widget_t *window, int x, int y, colour c,struct bitmap *image); + +/** Create a filled rectangle + * + * Create a widget which is a filled rectangle, usually used for backgrounds. + * + * @param window The window to add the filled area widget to. + * @return new widget handle or NULL on error. + */ +fbtk_widget_t * +fbtk_create_fill(fbtk_widget_t *window, int x, int y, int width, int height, colour c); + +/** Create a horizontal scroll widget + * + * Create a horizontal scroll widget. + * + * @param window The window to add the filled area widget to. + * @return new widget handle or NULL on error. + */ +fbtk_widget_t * +fbtk_create_hscroll(fbtk_widget_t *window, int x, int y, int width, int height, colour fg, colour bg); + +/** Create a vertical scroll widget + * + * Create a vertical scroll widget. + * + * @param window The window to add the filled area widget to. + * @return new widget handle or NULL on error. + */ +fbtk_widget_t * +fbtk_create_vscroll(fbtk_widget_t *window, int x, int y, int width, int height, colour fg, colour bg); + +/** Create a user widget. + * + * Create a widget which is to be handled entirely by the calling application. + * + * @param window The window to add the user widget to. + * @param pw The private pointer which can be read using ::fbtk_get_pw + * @return new widget handle or NULL on error. + */ +fbtk_widget_t *fbtk_create_user(fbtk_widget_t *window, int x, int y, int width, int height, void *pw); + + +/** Create a button widget. + * + * Helper function which creates a bitmap widget and associate a handler for + * when it is clicked. + * + * @param window The window to add the button widget to. + * @return new widget handle or NULL on error. + */ +fbtk_widget_t *fbtk_create_button(fbtk_widget_t *window, int x, int y, colour c, struct bitmap *image, fbtk_mouseclick_t click, void *pw); + +/** Create a writable text widget. + * + * Helper function which creates a text widget and configures an input handler + * to create a writable text field. This call is equivalent to calling + * ::fbtk_create_text followed by ::fbtk_writable_text + * + * @param window The window to add the text widget to. + * @return new widget handle or NULL on error. + */ +fbtk_widget_t *fbtk_create_writable_text(fbtk_widget_t *window, int x, int y, int width, int height, colour bg, colour fg, bool outline, fbtk_enter_t enter, void *pw); + + +/* Widget Destruction */ + +/** Destroy and free a widget and all its children. + * + * @param widget The widget to destroy. + * @return 0 on success or -1 on error. + */ +int fbtk_destroy_widget(fbtk_widget_t *widget); + +/* Widget information */ + +int fbtk_get_y(fbtk_widget_t *widget); +int fbtk_get_x(fbtk_widget_t *widget); +int fbtk_get_width(fbtk_widget_t *widget); +int fbtk_get_height(fbtk_widget_t *widget); +void *fbtk_get_userpw(fbtk_widget_t *widget); +nsfb_t *fbtk_get_nsfb(fbtk_widget_t *widget); + +/* Set widget properties */ + +void fbtk_set_text(fbtk_widget_t *widget, const char *text); +void fbtk_set_bitmap(fbtk_widget_t *widget, struct bitmap *image); +void fbtk_set_scroll(fbtk_widget_t *widget, int pct); +void fbtk_set_scroll_pos(fbtk_widget_t *widget, int pos); +void fbtk_set_pos_and_size(fbtk_widget_t *widget, int x, int y, int width, int height); +void fbtk_set_handler_redraw(fbtk_widget_t *widget, fbtk_redraw_t input, void *pw); +void fbtk_set_handler_input(fbtk_widget_t *widget, fbtk_input_t input, void *pw); +void fbtk_set_handler_click(fbtk_widget_t *widget, fbtk_mouseclick_t click, void *pw); +void fbtk_set_handler_move(fbtk_widget_t *widget, fbtk_move_t move, void *pw); + +/** Alter a text widget to be writable. + */ +void fbtk_writable_text(fbtk_widget_t *widget, fbtk_enter_t enter, void *pw); + + +/* General routines */ + +bool fbtk_clip_rect(const bbox_t * restrict clip, bbox_t * restrict box); + +/** Pointer movement. + * + * Pointer has been moved. + * + * @param widget any tookit widget. + * @parm x movement in horizontal plane. + * @parm y movement in vertical plane. + * @parm relative Wether the /a x and /a y should be considered relative to + * current pointer position. + */ +void fbtk_move_pointer(fbtk_widget_t *widget, int x, int y, bool relative); + +/** Mouse has been clicked + */ +void fbtk_click(fbtk_widget_t *widget, nsfb_event_t *event); + +/** Input has been recived + */ +void fbtk_input(fbtk_widget_t *widget, nsfb_event_t *event); + +/** Indicate a widget has to be redrawn + */ +void fbtk_request_redraw(fbtk_widget_t *widget); + +/** Cause a redraw to happen. + */ +int fbtk_redraw(fbtk_widget_t *widget); + +int fbtk_count_children(fbtk_widget_t *widget); + +bool fbtk_get_bbox(fbtk_widget_t *widget, struct nsfb_bbox_s *bbox); + +bool fbtk_event(fbtk_widget_t *root, nsfb_event_t *event, int timeout); + +/* keycode to ucs4 */ +int fbtk_keycode_to_ucs4(int code, uint8_t mods); + + + + + + + + diff --git a/framebuffer/filetype.c b/framebuffer/filetype.c new file mode 100644 index 000000000..d15890ce4 --- /dev/null +++ b/framebuffer/filetype.c @@ -0,0 +1,55 @@ +/* + * Copyright 2003 James Bursa + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include "content/fetch.h" +#include "utils/log.h" +#include "utils/utils.h" + +/** + * filetype -- determine the MIME type of a local file + */ + +const char *fetch_filetype(const char *unix_path) +{ + int l; + LOG(("unix path %s", unix_path)); + l = strlen(unix_path); + if (2 < l && strcasecmp(unix_path + l - 3, "css") == 0) + return "text/css"; + if (2 < l && strcasecmp(unix_path + l - 3, "jpg") == 0) + return "image/jpeg"; + if (3 < l && strcasecmp(unix_path + l - 4, "jpeg") == 0) + return "image/jpeg"; + if (2 < l && strcasecmp(unix_path + l - 3, "gif") == 0) + return "image/gif"; + if (2 < l && strcasecmp(unix_path + l - 3, "png") == 0) + return "image/png"; + if (2 < l && strcasecmp(unix_path + l - 3, "jng") == 0) + return "image/jng"; + if (2 < l && strcasecmp(unix_path + l - 3, "svg") == 0) + return "image/svg"; + return "text/html"; +} + + +char *fetch_mimetype(const char *ro_path) +{ + return strdup("text/plain"); +} diff --git a/framebuffer/findfile.c b/framebuffer/findfile.c new file mode 100644 index 000000000..29b82588d --- /dev/null +++ b/framebuffer/findfile.c @@ -0,0 +1,106 @@ +/* + * Copyright 2008 Daniel Silverstone + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include + +#include "utils/log.h" + +#include "framebuffer/findfile.h" + +char *path_to_url(const char *path) +{ + char *r = malloc(strlen(path) + 7 + 1); + + strcpy(r, "file://"); + strcat(r, path); + + return r; +} + +/** + * Locate a shared resource file by searching known places in order. + * + * \param buf buffer to write to. must be at least PATH_MAX chars + * \param filename file to look for + * \param def default to return if file not found + * \return buf + * + * Search order is: ~/.netsurf/, $NETSURFRES/ (where NETSURFRES is an + * environment variable), and finally the path specified by NETSURF_FB_RESPATH + * from the Makefile + */ + +char *fb_find_resource(char *buf, const char *filename, const char *def) +{ + char *cdir = getenv("HOME"); + char t[PATH_MAX]; + + if (cdir != NULL) { + strcpy(t, cdir); + strcat(t, "/.netsurf/"); + strcat(t, filename); + if (realpath(t, buf) != NULL) { + if (access(buf, R_OK) == 0) + return buf; + } + } + + cdir = getenv("NETSURFRES"); + + if (cdir != NULL) { + if (realpath(cdir, buf) != NULL) { + strcat(buf, "/"); + strcat(buf, filename); + if (access(buf, R_OK) == 0) + return buf; + } + } + + strcpy(t, NETSURF_FB_RESPATH); + strcat(t, filename); + if (realpath(t, buf) != NULL) { + if (access(buf, R_OK) == 0) + return buf; + } + + if (def[0] == '~') { + snprintf(t, PATH_MAX, "%s%s", getenv("HOME"), def + 1); + if (realpath(t, buf) == NULL) { + strcpy(buf, t); + } + } else { + if (realpath(def, buf) == NULL) { + strcpy(buf, def); + } + } + + return buf; +} + + +/* + * Local Variables: + * c-basic-offset: 8 + * End: + */ + diff --git a/framebuffer/findfile.h b/framebuffer/findfile.h new file mode 100644 index 000000000..87b9a95e4 --- /dev/null +++ b/framebuffer/findfile.h @@ -0,0 +1,26 @@ +/* + * Copyright 2008 Daniel Silverstone + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef NETSURF_FB_FINDFILE_H +#define NETSURF_FB_FINDFILE_H + +char *path_to_url(const char *path); + +extern char *fb_find_resource(char *buf, const char *filename, const char *def); + +#endif /* NETSURF_FB_FINDFILE_H */ diff --git a/framebuffer/font.h b/framebuffer/font.h new file mode 100644 index 000000000..5ae5bb3ad --- /dev/null +++ b/framebuffer/font.h @@ -0,0 +1,34 @@ +/* + * Copyright 2008 Vincent Sanders + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef NETSURF_FB_FONT_H +#define NETSURF_FB_FONT_H + +#include "utils/utf8.h" + +bool fb_font_init(void); +bool fb_font_finalise(void); + +#ifdef FB_USE_FREETYPE +#include "framebuffer/font_freetype.h" +#else +#include "framebuffer/font_internal.h" +#endif + +#endif /* NETSURF_FB_FONT_H */ + diff --git a/framebuffer/font_8x16.c b/framebuffer/font_8x16.c index fd9399fbd..df0bb6ae0 100644 --- a/framebuffer/font_8x16.c +++ b/framebuffer/font_8x16.c @@ -19,7 +19,7 @@ #include "desktop/plotters.h" #include "utils/utf8.h" -#include "framebuffer/fb_font.h" +#include "framebuffer/font_internal.h" #define FONTDATAMAX 4096 diff --git a/framebuffer/font_freetype.c b/framebuffer/font_freetype.c new file mode 100644 index 000000000..a4bc7868b --- /dev/null +++ b/framebuffer/font_freetype.c @@ -0,0 +1,477 @@ +/* + * Copyright 2005 James Bursa + * 2008 Vincent Sanders + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include + +#include + +#include "css/css.h" +#include "render/font.h" +#include "utils/utf8.h" +#include "utils/log.h" +#include "desktop/options.h" + +#include "framebuffer/gui.h" +#include "framebuffer/font.h" +#include "framebuffer/options.h" +#include "framebuffer/findfile.h" + +#define VERA_PATH "/usr/share/fonts/truetype/ttf-bitstream-vera/" + +static FT_Library library; +static FTC_Manager ft_cmanager; +static FTC_CMapCache ft_cmap_cache ; +static FTC_ImageCache ft_image_cache; + +int ft_load_type; + +/* cache manager faceID data to create freetype faceid on demand */ +typedef struct fb_faceid_s { + char *fontfile; /* path to font */ + int index; /* index of font */ + int cidx; /* character map index for unicode */ +} fb_faceid_t; + +/* defines for accesing the faces */ +#define FB_FACE_DEFAULT 0 + +#define FB_FACE_SANS_SERIF 0 +#define FB_FACE_SANS_SERIF_BOLD 1 +#define FB_FACE_SANS_SERIF_ITALIC 2 +#define FB_FACE_SANS_SERIF_ITALIC_BOLD 3 +#define FB_FACE_MONOSPACE 4 +#define FB_FACE_SERIF 5 +#define FB_FACE_SERIF_BOLD 6 + +#define FB_FACE_COUNT 7 + +static fb_faceid_t *fb_faces[FB_FACE_COUNT]; + + +utf8_convert_ret utf8_to_local_encoding(const char *string, + size_t len, + char **result) +{ + return utf8_to_enc(string, "UTF-8", len, result); +} + +/* map cache manager handle to face id */ +static FT_Error ft_face_requester(FTC_FaceID face_id, FT_Library library, FT_Pointer request_data, FT_Face *face ) +{ + FT_Error error; + fb_faceid_t *fb_face = (fb_faceid_t *)face_id; + int cidx; + + error = FT_New_Face(library, fb_face->fontfile, fb_face->index, face); + if (error) { + LOG(("Could not find font (code %d)\n", error)); + } else { + + error = FT_Select_Charmap(*face, FT_ENCODING_UNICODE); + if (error) { + LOG(("Could not select charmap (code %d)\n", error)); + } else { + for (cidx = 0; cidx < (*face)->num_charmaps; cidx++) { + if ((*face)->charmap == (*face)->charmaps[cidx]) { + fb_face->cidx = cidx; + break; + } + } + } + } + LOG(("Loaded face from %s\n", fb_face->fontfile)); + + return error; +} + +/* create new framebuffer face and cause it to be loaded to check its ok */ +static fb_faceid_t * +fb_new_face(const char *option, const char *resname, const char *fontfile) +{ + fb_faceid_t *newf; + FT_Error error; + FT_Face aface; + char buf[PATH_MAX]; + + newf = calloc(1, sizeof(fb_faceid_t)); + + if (option != NULL) { + newf->fontfile = strdup(option); + } else { + fb_find_resource(buf, resname, fontfile); + newf->fontfile = strdup(buf); + } + + error = FTC_Manager_LookupFace(ft_cmanager, (FTC_FaceID)newf, &aface); + if (error) { + LOG(("Could not find font face %s (code %d)\n", fontfile, error)); + free(newf); + newf = fb_faces[FB_FACE_DEFAULT]; /* use default */ + } + + return newf; +} + +/* initialise font handling */ +bool fb_font_init(void) +{ + FT_Error error; + FT_ULong max_cache_size; + FT_UInt max_faces = 6; + + /* freetype library initialise */ + error = FT_Init_FreeType( &library ); + if (error) { + LOG(("Freetype could not initialised (code %d)\n", error)); + return false; + } + + max_cache_size = 2 * 1024 *1024; /* 2MB should be enough */ + + /* cache manager initialise */ + error = FTC_Manager_New(library, + max_faces, + 0, + max_cache_size, + ft_face_requester, + NULL, + &ft_cmanager); + if (error) { + LOG(("Freetype could not initialise cache manager (code %d)\n", error)); + FT_Done_FreeType(library); + return false; + } + + error = FTC_CMapCache_New(ft_cmanager, &ft_cmap_cache); + + error = FTC_ImageCache_New(ft_cmanager, &ft_image_cache); + + fb_faces[FB_FACE_SANS_SERIF] = NULL; + fb_faces[FB_FACE_SANS_SERIF] = + fb_new_face(option_fb_face_sans_serif, + "sans_serif.ttf", + VERA_PATH"Vera.ttf"); + if (fb_faces[FB_FACE_SANS_SERIF] == NULL) { + LOG(("Could not find default font (code %d)\n", error)); + FTC_Manager_Done(ft_cmanager ); + FT_Done_FreeType(library); + return false; + } + + fb_faces[FB_FACE_SANS_SERIF_BOLD] = + fb_new_face(option_fb_face_sans_serif_bold, + "sans_serif_bold.ttf", + VERA_PATH"VeraBd.ttf"); + + fb_faces[FB_FACE_SANS_SERIF_ITALIC] = + fb_new_face(option_fb_face_sans_serif_italic, + "sans_serif_italic.ttf", + VERA_PATH"VeraIt.ttf"); + + fb_faces[FB_FACE_SANS_SERIF_ITALIC_BOLD] = + fb_new_face(option_fb_face_sans_serif_italic_bold, + "sans_serif_italic_bold.ttf", + VERA_PATH"VeraBI.ttf"); + + fb_faces[FB_FACE_MONOSPACE] = + fb_new_face(option_fb_face_monospace, + "monospace.ttf", + VERA_PATH"VeraMono.ttf"); + + fb_faces[FB_FACE_SERIF] = + fb_new_face(option_fb_face_serif, + "serif.ttf", + VERA_PATH"VeraSe.ttf"); + + fb_faces[FB_FACE_SERIF_BOLD] = + fb_new_face(option_fb_face_serif_bold, + "serif_bold.ttf", + VERA_PATH"VeraSeBd.ttf"); + + /* set the default render mode */ + if (option_fb_font_monochrome == true) + ft_load_type = FT_LOAD_MONOCHROME; /* faster but less pretty */ + else + ft_load_type = 0; + + return true; +} + +bool fb_font_finalise(void) +{ + FTC_Manager_Done(ft_cmanager ); + FT_Done_FreeType(library); + return true; +} + +static void fb_fill_scalar(const struct css_style *style, FTC_Scaler srec) +{ + int selected_face = FB_FACE_DEFAULT; + + switch (style->font_family) { + /* + case CSS_FONT_FAMILY_CURSIVE: + break; + case CSS_FONT_FAMILY_FANTASY: + break; + */ + case CSS_FONT_FAMILY_SERIF: + switch (style->font_weight) { + case CSS_FONT_WEIGHT_700: + case CSS_FONT_WEIGHT_800: + case CSS_FONT_WEIGHT_900: + case CSS_FONT_WEIGHT_BOLD: + selected_face = FB_FACE_SERIF_BOLD; + break; + + case CSS_FONT_WEIGHT_NORMAL: + default: + selected_face = FB_FACE_SERIF; + break; + } + + break; + + case CSS_FONT_FAMILY_MONOSPACE: + selected_face = FB_FACE_MONOSPACE; + break; + + case CSS_FONT_FAMILY_SANS_SERIF: + default: + switch (style->font_style) { + case CSS_FONT_STYLE_ITALIC: + switch (style->font_weight) { + case CSS_FONT_WEIGHT_700: + case CSS_FONT_WEIGHT_800: + case CSS_FONT_WEIGHT_900: + case CSS_FONT_WEIGHT_BOLD: + selected_face = FB_FACE_SANS_SERIF_ITALIC_BOLD; + break; + + case CSS_FONT_WEIGHT_NORMAL: + default: + selected_face = FB_FACE_SANS_SERIF_ITALIC; + break; + } + break; + + default: + switch (style->font_weight) { + case CSS_FONT_WEIGHT_700: + case CSS_FONT_WEIGHT_800: + case CSS_FONT_WEIGHT_900: + case CSS_FONT_WEIGHT_BOLD: + selected_face = FB_FACE_SANS_SERIF_BOLD; + break; + + case CSS_FONT_WEIGHT_NORMAL: + default: + selected_face = FB_FACE_SANS_SERIF; + break; + } + break; + } + } + + srec->face_id = (FTC_FaceID)fb_faces[selected_face]; + + if (style->font_size.value.length.unit == CSS_UNIT_PX) { + srec->width = srec->height = style->font_size.value.length.value; + srec->pixel = 1; + } else { + srec->width = srec->height = + css_len2pt(&style->font_size.value.length, style) * 64; + srec->pixel = 0; + + srec->x_res = srec->y_res = 72; + } + +} + +FT_Glyph fb_getglyph(const struct css_style *style, uint32_t ucs4) +{ + FT_UInt glyph_index; + FTC_ScalerRec srec; + FT_Glyph glyph; + FT_Error error; + fb_faceid_t *fb_face; + + fb_fill_scalar(style, &srec); + + fb_face = (fb_faceid_t *)srec.face_id; + + glyph_index = FTC_CMapCache_Lookup(ft_cmap_cache, srec.face_id, fb_face->cidx, ucs4); + + error = FTC_ImageCache_LookupScaler(ft_image_cache, + &srec, + FT_LOAD_RENDER | + FT_LOAD_FORCE_AUTOHINT | + ft_load_type, + glyph_index, + &glyph, + NULL); + + return glyph; +} + + +/** + * Measure the width of a string. + * + * \param style css_style for this text, with style->font_size.size == + * CSS_FONT_SIZE_LENGTH + * \param string UTF-8 string to measure + * \param length length of string + * \param width updated to width of string[0..length) + * \return true on success, false on error and error reported + */ +static bool nsfont_width(const struct css_style *style, + const char *string, size_t length, + int *width) +{ + uint32_t ucs4; + size_t nxtchr = 0; + FT_Glyph glyph; + + *width = 0; + while (nxtchr < length) { + ucs4 = utf8_to_ucs4(string + nxtchr, length - nxtchr); + nxtchr = utf8_next(string, length, nxtchr); + + glyph = fb_getglyph(style, ucs4); + if (glyph == NULL) + continue; + + *width += glyph->advance.x >> 16; + } + + return true; +} + +/** + * Find the position in a string where an x coordinate falls. + * + * \param style css_style for this text, with style->font_size.size == + * CSS_FONT_SIZE_LENGTH + * \param string UTF-8 string to measure + * \param length length of string + * \param x x coordinate to search for + * \param char_offset updated to offset in string of actual_x, [0..length] + * \param actual_x updated to x coordinate of character closest to x + * \return true on success, false on error and error reported + */ + +static bool nsfont_position_in_string(const struct css_style *style, + const char *string, size_t length, + int x, size_t *char_offset, int *actual_x) +{ + uint32_t ucs4; + size_t nxtchr = 0; + FT_Glyph glyph; + + *actual_x = 0; + while (nxtchr < length) { + ucs4 = utf8_to_ucs4(string + nxtchr, length - nxtchr); + + glyph = fb_getglyph(style, ucs4); + if (glyph == NULL) + continue; + + *actual_x += glyph->advance.x >> 16; + if (*actual_x > x) + break; + + nxtchr = utf8_next(string, length, nxtchr); + } + + *char_offset = nxtchr; + return true; +} + + +/** + * Find where to split a string to make it fit a width. + * + * \param style css_style for this text, with style->font_size.size == + * CSS_FONT_SIZE_LENGTH + * \param string UTF-8 string to measure + * \param length length of string + * \param x width available + * \param char_offset updated to offset in string of actual_x, [0..length] + * \param actual_x updated to x coordinate of character closest to x + * \return true on success, false on error and error reported + * + * On exit, [char_offset == 0 || + * string[char_offset] == ' ' || + * char_offset == length] + */ + +static bool nsfont_split(const struct css_style *style, + const char *string, size_t length, + int x, size_t *char_offset, int *actual_x) +{ + uint32_t ucs4; + size_t nxtchr = 0; + int last_space_x = 0; + int last_space_idx = 0; + FT_Glyph glyph; + + *actual_x = 0; + while (nxtchr < length) { + ucs4 = utf8_to_ucs4(string + nxtchr, length - nxtchr); + + glyph = fb_getglyph(style, ucs4); + if (glyph == NULL) + continue; + + if (ucs4 == 0x20) { + last_space_x = *actual_x; + last_space_idx = nxtchr; + } + + *actual_x += glyph->advance.x >> 16; + if (*actual_x > x) { + /* string has exceeded available width return previous + * space + */ + *actual_x = last_space_x; + *char_offset = last_space_idx; + return true; + } + + nxtchr = utf8_next(string, length, nxtchr); + } + + *char_offset = nxtchr; + + return true; +} + +const struct font_functions nsfont = { + nsfont_width, + nsfont_position_in_string, + nsfont_split +}; + +/* + * Local Variables: + * c-basic-offset:8 + * End: + */ diff --git a/framebuffer/font_freetype.h b/framebuffer/font_freetype.h new file mode 100644 index 000000000..68d986b8c --- /dev/null +++ b/framebuffer/font_freetype.h @@ -0,0 +1,30 @@ +/* + * Copyright 2008 Vincent Sanders + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef NETSURF_FB_FONT_FREETYPE_H +#define NETSURF_FB_FONT_FREETYPE_H + +#include +#include FT_FREETYPE_H +#include + +extern int ft_load_type; + +FT_Glyph fb_getglyph(const struct css_style *style, uint32_t ucs4); + +#endif /* NETSURF_FB_FONT_FREETYPE_H */ diff --git a/framebuffer/font_internal.c b/framebuffer/font_internal.c new file mode 100644 index 000000000..ba03ecc08 --- /dev/null +++ b/framebuffer/font_internal.c @@ -0,0 +1,141 @@ +/* + * Copyright 2005 James Bursa + * 2008 Vincent Sanders + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include + +#include +#include "css/css.h" +#include "render/font.h" +#include "desktop/options.h" +#include "utils/utf8.h" + +#include "framebuffer/gui.h" +#include "framebuffer/font.h" + +bool fb_font_init(void) +{ + return true; +} + +const struct fb_font_desc* +fb_get_font(const struct css_style *style) +{ + return &font_vga_8x16; +} + +utf8_convert_ret utf8_to_font_encoding(const struct fb_font_desc* font, + const char *string, + size_t len, + char **result) +{ + return utf8_to_enc(string, font->encoding, len, result); + +} + +utf8_convert_ret utf8_to_local_encoding(const char *string, + size_t len, + char **result) +{ + return utf8_to_enc(string, "CP437", len, result); + +} + +static bool nsfont_width(const struct css_style *style, + const char *string, size_t length, + int *width) +{ + const struct fb_font_desc* fb_font = fb_get_font(style); + *width = fb_font->width * utf8_bounded_length(string, length); + return true; +} + +/** + * Find the position in a string where an x coordinate falls. + * + * \param style css_style for this text, with style->font_size.size == + * CSS_FONT_SIZE_LENGTH + * \param string UTF-8 string to measure + * \param length length of string + * \param x x coordinate to search for + * \param char_offset updated to offset in string of actual_x, [0..length] + * \param actual_x updated to x coordinate of character closest to x + * \return true on success, false on error and error reported + */ + +static bool nsfont_position_in_string(const struct css_style *style, + const char *string, size_t length, + int x, size_t *char_offset, int *actual_x) +{ + const struct fb_font_desc* fb_font = fb_get_font(style); + *char_offset = x / fb_font->width; + if (*char_offset > length) + *char_offset = length; + *actual_x = *char_offset * fb_font->width; + return true; +} + + +/** + * Find where to split a string to make it fit a width. + * + * \param style css_style for this text, with style->font_size.size == + * CSS_FONT_SIZE_LENGTH + * \param string UTF-8 string to measure + * \param length length of string + * \param x width available + * \param char_offset updated to offset in string of actual_x, [0..length] + * \param actual_x updated to x coordinate of character closest to x + * \return true on success, false on error and error reported + * + * On exit, [char_offset == 0 || + * string[char_offset] == ' ' || + * char_offset == length] + */ + +static bool nsfont_split(const struct css_style *style, + const char *string, size_t length, + int x, size_t *char_offset, int *actual_x) +{ + + const struct fb_font_desc* fb_font = fb_get_font(style); + *char_offset = x / fb_font->width; + if (*char_offset > length) { + *char_offset = length; + } else { + while (*char_offset > 0) { + if (string[*char_offset] == ' ') + break; + (*char_offset)--; + } + } + *actual_x = *char_offset * fb_font->width; + return true; +} + +const struct font_functions nsfont = { + nsfont_width, + nsfont_position_in_string, + nsfont_split +}; + +/* + * Local Variables: + * c-basic-offset:8 + * End: + */ diff --git a/framebuffer/font_internal.h b/framebuffer/font_internal.h new file mode 100644 index 000000000..eaa9dfba8 --- /dev/null +++ b/framebuffer/font_internal.h @@ -0,0 +1,39 @@ +/* + * Copyright 2008 Vincent Sanders + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef NETSURF_FB_FONT_INTERNAL_H +#define NETSURF_FB_FONT_INTERNAL_H + +struct fb_font_desc { + const char *name; + int width, height; + const char *encoding; + const uint32_t *data; +}; + +extern const struct fb_font_desc font_vga_8x16; + +extern const struct fb_font_desc* fb_get_font(const struct css_style *style); + +extern utf8_convert_ret utf8_to_font_encoding(const struct fb_font_desc* font, + const char *string, + size_t len, + char **result); + +#endif /* NETSURF_FB_FONT_INTERNAL_H */ + diff --git a/framebuffer/framebuffer.c b/framebuffer/framebuffer.c new file mode 100644 index 000000000..093dfedbe --- /dev/null +++ b/framebuffer/framebuffer.c @@ -0,0 +1,299 @@ +/* + * Copyright 2008 Vincent Sanders + * + * Framebuffer interface + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include + +#include +#include +#include +#include +#include + +#include "utils/log.h" +#include "desktop/browser.h" +#include "desktop/plotters.h" + +#include "framebuffer/gui.h" +#include "framebuffer/fbtk.h" +#include "framebuffer/framebuffer.h" +#include "framebuffer/bitmap.h" +#include "framebuffer/font.h" + +/* netsurf framebuffer library handle */ +static nsfb_t *nsfb; + +#ifdef FB_USE_FREETYPE + +static bool framebuffer_plot_text(int x, int y, const struct css_style *style, + const char *text, size_t length, colour bg, colour c) +{ + uint32_t ucs4; + size_t nxtchr = 0; + FT_Glyph glyph; + FT_BitmapGlyph bglyph; + nsfb_bbox_t loc; + + while (nxtchr < length) { + ucs4 = utf8_to_ucs4(text + nxtchr, length - nxtchr); + nxtchr = utf8_next(text, length, nxtchr); + + glyph = fb_getglyph(style, ucs4); + if (glyph == NULL) + continue; + + if (glyph->format == FT_GLYPH_FORMAT_BITMAP) { + bglyph = (FT_BitmapGlyph)glyph; + + loc.x0 = x + bglyph->left; + loc.y0 = y - bglyph->top; + loc.x1 = loc.x0 + bglyph->bitmap.width; + loc.y1 = loc.y0 + bglyph->bitmap.rows; + + /* now, draw to our target surface */ + if (bglyph->bitmap.pixel_mode == FT_PIXEL_MODE_MONO) { + nsfb_plot_glyph1(nsfb, + &loc, + bglyph->bitmap.buffer, + bglyph->bitmap.pitch, + c); + } else { + nsfb_plot_glyph8(nsfb, + &loc, + bglyph->bitmap.buffer, + bglyph->bitmap.pitch, + c); + } + } + x += glyph->advance.x >> 16; + + } + return true; + +} +#else +static bool framebuffer_plot_text(int x, int y, const struct css_style *style, + const char *text, size_t length, colour bg, colour c) +{ + const struct fb_font_desc* fb_font = fb_get_font(style); + const uint32_t *chrp; + char *buffer = NULL; + int chr; + int blen; + nsfb_bbox_t loc; + + utf8_to_font_encoding(fb_font, text, length, &buffer); + if (buffer == NULL) + return true; + + /* y is given to the fonts baseline we need it to the fonts top */ + y-=((fb_font->height * 75)/100); + + y+=1; /* the coord is the bottom-left of the pixels offset by 1 to make + * it work since fb coords are the top-left of pixels + */ + + blen = strlen(buffer); + + for (chr = 0; chr < blen; chr++) { + loc.x0 = x; + loc.y0 = y; + loc.x1 = loc.x0 + fb_font->width; + loc.y1 = loc.y0 + fb_font->height; + + chrp = fb_font->data + ((unsigned char)buffer[chr] * fb_font->height); + nsfb_plot_glyph1(nsfb, &loc, (uint8_t *)chrp, 32, c); + + x+=fb_font->width; + + } + + free(buffer); + return true; +} +#endif + +static bool framebuffer_plot_bitmap(int x, int y, int width, int height, + struct bitmap *bitmap, colour bg, + struct content *content) +{ + nsfb_bbox_t loc; + loc.x0 = x; + loc.y0 = y; + loc.x1 = loc.x0 + width; + loc.y1 = loc.y0 + height; + + return nsfb_plot_bitmap(nsfb, &loc, (nsfb_colour_t *)bitmap->pixdata, bitmap->width, bitmap->height, bitmap->width, !bitmap->opaque); + +} + +static bool +framebuffer_plot_bitmap_tile(int x, int y, + int width, int height, + struct bitmap *bitmap, colour bg, + bool repeat_x, bool repeat_y, + struct content *content) +{ + int xf,yf; + + nsfb_bbox_t clipbox; + + nsfb_plot_get_clip(nsfb, &clipbox); + + /* x and y define coordinate of top left of of the initial explicitly + * placed tile. The width and height are the image scaling and the + * bounding box defines the extent of the repeat (which may go in all + * four directions from the initial tile). + */ + + LOG(("x %d, y %d, width %d, height %d, bitmap %p, repx %d repy %d content %p", x,y,width,height,bitmap,repeat_x, repeat_y, content)); + + if (!(repeat_x || repeat_y)) { + /* Not repeating at all, so just pass it on */ + LOG(("Not repeating")); + return framebuffer_plot_bitmap(x, y, width, height, bitmap, bg,content); + } + + /* get left most tile position */ + if (repeat_x) + for (; x > clipbox.x0; x -= width); + + /* get top most tile position */ + if (repeat_y) + for (; y > clipbox.y0; y -= height) + ; + + /* tile down and across to extents */ + for (xf = x; xf < clipbox.x1; xf += width) { + for (yf = y; yf < clipbox.y1; yf += height) { + framebuffer_plot_bitmap(xf, yf, width, height, bitmap, bg, content); + if (!repeat_y) + break; + } + if (!repeat_x) + break; + } + return true; +} + + +static bool framebuffer_plot_flush(void) +{ + LOG(("flush unimplemnted")); + return true; +} + +static bool +framebuffer_plot_path(const float *p, + unsigned int n, + colour fill, + float width, + colour c, + const float transform[6]) +{ + LOG(("path unimplemented")); + return true; +} + +struct plotter_table plot = { + .clg = nsfb_lplot_clg, + .rectangle = nsfb_lplot_rectangle, + .line = nsfb_lplot_line, + .polygon = nsfb_lplot_polygon, + .fill = nsfb_lplot_fill, + .clip = nsfb_lplot_clip, + .text = framebuffer_plot_text, + .disc = nsfb_lplot_disc, + .arc = nsfb_lplot_arc, + .bitmap = framebuffer_plot_bitmap, + .bitmap_tile = framebuffer_plot_bitmap_tile, + .flush = framebuffer_plot_flush, + .path = framebuffer_plot_path, + .option_knockout = true, +}; + + + +nsfb_t * +framebuffer_initialise(int argc, char** argv) +{ + const char *fename; + enum nsfb_frontend_e fetype; + + /* select frontend from commandline */ + if ((argc > 2) && (argv[1][0] == '-') && + (argv[1][1] == 'f') && + (argv[1][2] == 'e') && + (argv[1][3] == 0)) { + int argcmv; + fename = (const char *)argv[2]; + for (argcmv = 3; argcmv < argc; argcmv++) { + argv[argcmv - 2] = argv[argcmv]; + } + argc-=2; + } else { + fename="sdl"; + } + + fetype = nsfb_frontend_from_name(fename); + if (fetype == NSFB_FRONTEND_NONE) { + LOG(("The %s frontend is not available from libnsfb\n", fename)); + return NULL; + } + + nsfb = nsfb_init(fetype); + if (nsfb == NULL) { + LOG(("Unable to initialise nsfb with %s frontend\n", fename)); + return NULL; + } + + if (nsfb_set_geometry(nsfb, 0, 0, 32) == -1) { + LOG(("Unable to set geometry\n")); + nsfb_finalise(nsfb); + return NULL; + } + + nsfb_cursor_init(nsfb); + + if (nsfb_init_frontend(nsfb) == -1) { + LOG(("Unable to initialise nsfb frontend\n")); + nsfb_finalise(nsfb); + return NULL; + } + + nsfb_lplot_ctx(nsfb); + + return nsfb; + +} + +void +framebuffer_finalise(void) +{ + nsfb_finalise(nsfb); +} + +bool +framebuffer_set_cursor(struct bitmap *bm) +{ + return nsfb_cursor_set(nsfb, (nsfb_colour_t *)bm->pixdata, bm->width, bm->height, bm->width); +} diff --git a/framebuffer/framebuffer.h b/framebuffer/framebuffer.h new file mode 100644 index 000000000..c6b37bcf2 --- /dev/null +++ b/framebuffer/framebuffer.h @@ -0,0 +1,5 @@ +nsfb_t *framebuffer_initialise(int argc, char** argv); +void framebuffer_finalise(void); +bool framebuffer_set_cursor(struct bitmap *bm); + + diff --git a/framebuffer/gui.c b/framebuffer/gui.c new file mode 100644 index 000000000..5671adc8a --- /dev/null +++ b/framebuffer/gui.c @@ -0,0 +1,1274 @@ +/* + * Copyright 2008 Vincent Sanders + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include + +#include +#include +#include + +#include "desktop/gui.h" +#include "desktop/plotters.h" +#include "desktop/netsurf.h" +#include "desktop/options.h" +#include "utils/log.h" +#include "utils/messages.h" +#include "utils/utils.h" +#include "desktop/textinput.h" + +#include "framebuffer/gui.h" +#include "framebuffer/fbtk.h" +#include "framebuffer/framebuffer.h" +#include "framebuffer/bitmap.h" +#include "framebuffer/schedule.h" +#include "framebuffer/findfile.h" +#include "framebuffer/image_data.h" +#include "framebuffer/font.h" + +#include "content/urldb.h" +#include "desktop/history_core.h" +#include "content/fetch.h" + +char *default_stylesheet_url; +char *adblock_stylesheet_url; +char *options_file_location; + + +fbtk_widget_t *fbtk; + +struct gui_window *input_window = NULL; +struct gui_window *search_current_window; +struct gui_window *window_list = NULL; + +bool redraws_pending = false; + + +#ifndef MIN +#define MIN(a,b) (((a) < (b)) ? (a) : (b)) +#endif + +#ifndef MAX +#define MAX(a,b) (((a) > (b)) ? (a) : (b)) +#endif + +/* private data for browser user widget */ +struct browser_widget_s { + struct browser_window *bw; /**< The browser window connected to this gui window */ + int scrollx, scrolly; /**< scroll offsets. */ + + /* Pending window redraw state. */ + bool redraw_required; /**< flag indicating the foreground loop + * needs to redraw the browser widget. + */ + bbox_t redraw_box; /**< Area requiring redraw. */ + bool pan_required; /**< flag indicating the foreground loop + * needs to pan the window. + */ + int panx, pany; /**< Panning required. */ +}; + + +/* queue a redraw operation, co-ordinates are relative to the window */ +static void +fb_queue_redraw(struct fbtk_widget_s *widget, int x0, int y0, int x1, int y1) +{ + struct browser_widget_s *bwidget = fbtk_get_userpw(widget); + + bwidget->redraw_box.x0 = MIN(bwidget->redraw_box.x0, x0); + bwidget->redraw_box.y0 = MIN(bwidget->redraw_box.y0, y0); + bwidget->redraw_box.x1 = MAX(bwidget->redraw_box.x1, x1); + bwidget->redraw_box.y1 = MAX(bwidget->redraw_box.y1, y1); + + bwidget->redraw_required = true; + + fbtk_request_redraw(widget); +} + +static void fb_pan(fbtk_widget_t *widget, + struct browser_widget_s *bwidget, + struct browser_window *bw) +{ + struct content *c; + int x; + int y; + int width; + int height; + nsfb_bbox_t redraw_box; + + c = bw->current_content; + + if ((!c) || (c->locked)) + return; + + nsfb_t *nsfb = fbtk_get_nsfb(widget); + + height = fbtk_get_height(widget); + width = fbtk_get_width(widget); + x = fbtk_get_x(widget); + y = fbtk_get_y(widget); + + /* dont pan off the top */ + if ((bwidget->scrolly + bwidget->pany) < 0) + bwidget->pany = - bwidget->scrolly; + + /* do not pan off the bottom of the content */ + if ((bwidget->scrolly + bwidget->pany) > (c->height - height)) + bwidget->pany = (c->height - height) - bwidget->scrolly; + + /* dont pan off the left */ + if ((bwidget->scrollx + bwidget->panx) < 0) + bwidget->panx = - bwidget->scrollx; + + /* do not pan off the right of the content */ + if ((bwidget->scrollx + bwidget->panx) > (c->width - width)) + bwidget->panx = (c->width - width) - bwidget->scrollx; + + LOG(("panning %d, %d",bwidget->panx, bwidget->pany)); + + /* pump up the volume. dance, dance! lets do it */ + if (bwidget->pany < 0) { + /* we cannot pan more than a window height at a time */ + if (bwidget->pany < -height) + bwidget->pany = -height; + + LOG(("panning up %d", bwidget->pany)); + + redraw_box.x0 = x; + redraw_box.y0 = y - bwidget->pany; + redraw_box.x1 = redraw_box.x0 + width; + redraw_box.y1 = redraw_box.y0 + height + bwidget->pany; + nsfb_claim(nsfb, &redraw_box); + nsfb_plot_copy(nsfb, x, y, width, height + bwidget->pany, x, y - bwidget->pany); + nsfb_release(nsfb, &redraw_box); + + bwidget->scrolly += bwidget->pany; + fb_queue_redraw(widget, 0, 0, width, - bwidget->pany); + } + + if (bwidget->pany > 0) { + /* we cannot pan more than a window height at a time */ + if (bwidget->pany > height) + bwidget->pany = height; + + LOG(("panning down %d", bwidget->pany)); + + redraw_box.x0 = x; + redraw_box.y0 = y; + redraw_box.x1 = redraw_box.x0 + width; + redraw_box.y1 = redraw_box.y0 + height - bwidget->pany; + nsfb_claim(nsfb, &redraw_box); + nsfb_plot_copy(nsfb, + x, y + bwidget->pany, + width, height - bwidget->pany, + x, y); + nsfb_release(nsfb, &redraw_box); + + bwidget->scrolly += bwidget->pany; + fb_queue_redraw(widget, 0, height - bwidget->pany, width, height); + } + + if (bwidget->panx < 0) { + /* we cannot pan more than a window width at a time */ + if (bwidget->panx < -width) + bwidget->panx = -width; + + LOG(("panning left %d", bwidget->panx)); + + redraw_box.x0 = x - bwidget->panx; + redraw_box.y0 = y; + redraw_box.x1 = redraw_box.x0 + width + bwidget->panx; + redraw_box.y1 = redraw_box.y0 + height; + nsfb_claim(nsfb, &redraw_box); + nsfb_plot_copy(nsfb, + x, y, + width + bwidget->panx, height, + x - bwidget->panx, y); + nsfb_release(nsfb, &redraw_box); + bwidget->scrollx += bwidget->panx; + fb_queue_redraw(widget, 0, 0, -bwidget->panx, height); + } + + if (bwidget->panx > 0) { + /* we cannot pan more than a window width at a time */ + if (bwidget->panx > width) + bwidget->panx = width; + + LOG(("panning right %d", bwidget->panx)); + + redraw_box.x0 = x; + redraw_box.y0 = y; + redraw_box.x1 = redraw_box.x0 + width - bwidget->panx; + redraw_box.y1 = redraw_box.y0 + height; + nsfb_claim(nsfb, &redraw_box); + nsfb_plot_copy(nsfb, + x + bwidget->panx, y, + width - bwidget->panx, height, + x, y); + nsfb_release(nsfb, &redraw_box); + + bwidget->scrollx += bwidget->panx; + fb_queue_redraw(widget, width - bwidget->panx, 0, width, height); + } + + + bwidget->pan_required = false; + bwidget->panx = 0; + bwidget->pany = 0; +} + +static void fb_redraw(fbtk_widget_t *widget, + struct browser_widget_s *bwidget, + struct browser_window *bw) +{ + struct content *c; + int x; + int y; + int width; + int height; + + c = bw->current_content; + + if ((!c) || (c->locked)) + return; + + height = fbtk_get_height(widget); + width = fbtk_get_width(widget); + x = fbtk_get_x(widget); + y = fbtk_get_y(widget); + + /* adjust clipping co-ordinates according to window location */ + bwidget->redraw_box.y0 += y; + bwidget->redraw_box.y1 += y; + bwidget->redraw_box.x0 += x; + bwidget->redraw_box.x1 += x; + + nsfb_claim(fbtk_get_nsfb(widget), &bwidget->redraw_box); + + /* redraw bounding box is relative to window */ + content_redraw(c, + x - bwidget->scrollx, y - bwidget->scrolly, + width, height, + bwidget->redraw_box.x0, bwidget->redraw_box.y0, + bwidget->redraw_box.x1, bwidget->redraw_box.y1, + bw->scale, 0xFFFFFF); + + + nsfb_release(fbtk_get_nsfb(widget), &bwidget->redraw_box); + + bwidget->redraw_box.y0 = bwidget->redraw_box.x0 = INT_MAX; + bwidget->redraw_box.y1 = bwidget->redraw_box.x1 = -(INT_MAX); + bwidget->redraw_required = false; +} + +static int +fb_browser_window_redraw(fbtk_widget_t *root, fbtk_widget_t *widget, void *pw) +{ + struct gui_window *gw = pw; + struct browser_widget_s *bwidget; + + bwidget = fbtk_get_userpw(widget); + if (bwidget == NULL) { + LOG(("browser widget from widget %p was null", widget)); + return -1; + } + + if (bwidget->pan_required) { + int pos; + fb_pan(widget, bwidget, gw->bw); + pos = (bwidget->scrollx * 100) / gw->bw->current_content->width;; + fbtk_set_scroll_pos(gw->hscroll, pos); + pos = (bwidget->scrolly * 100) / gw->bw->current_content->height; + fbtk_set_scroll_pos(gw->vscroll, pos); + + } + + if (bwidget->redraw_required) { + fb_redraw(widget, bwidget, gw->bw); + } + return 0; +} + +static void *myrealloc(void *ptr, size_t len, void *pw) +{ + return realloc(ptr, len); +} + +void gui_init(int argc, char** argv) +{ + char buf[PATH_MAX]; + nsfb_t *nsfb; + + LOG(("argc %d, argv %p", argc, argv)); + + fb_find_resource(buf, "Aliases", "./framebuffer/res/Aliases"); + LOG(("Using '%s' as Aliases file", buf)); + if (hubbub_initialise(buf, myrealloc, NULL) != HUBBUB_OK) + die("Unable to initialise HTML parsing library.\n"); + + /* load browser messages */ + fb_find_resource(buf, "messages", "./framebuffer/res/messages"); + LOG(("Using '%s' as Messages file", buf)); + messages_load(buf); + + /* load browser options */ + fb_find_resource(buf, "Options", "~/.netsurf/Options"); + LOG(("Using '%s' as Preferences file", buf)); + options_file_location = strdup(buf); + options_read(buf); + + /* set up stylesheet urls */ + fb_find_resource(buf, "default.css", "./framebuffer/res/default.css"); + default_stylesheet_url = path_to_url(buf); + LOG(("Using '%s' as Default CSS URL", default_stylesheet_url)); + + nsfb = framebuffer_initialise(argc, argv); + if (nsfb == NULL) + die("Unable to initialise framebuffer"); + + framebuffer_set_cursor(&pointer_image); + + if (fb_font_init() == false) + die("Unable to initialise the font system"); + + fbtk = fbtk_init(nsfb); + +} + +void gui_init2(int argc, char** argv) +{ + struct browser_window *bw; + const char *addr = NETSURF_HOMEPAGE; + + LOG(("argc %d, argv %p", argc, argv)); + + if (option_homepage_url != NULL && option_homepage_url[0] != '\0') + addr = option_homepage_url; + + if (argc > 1) addr = argv[1]; + + LOG(("calling browser_window_create")); + bw = browser_window_create(addr, 0, 0, true, false); +} + + +void gui_multitask(void) +{ + // LOG(("gui_multitask")); +} + + +void gui_poll(bool active) +{ + nsfb_event_t event; + int timeout = 0; + + active |= schedule_run() | redraws_pending; + + if (!active) + timeout = -1; + + fbtk_event(fbtk, &event, timeout); + + if ((event.type == NSFB_EVENT_CONTROL) && + (event.value.controlcode == NSFB_CONTROL_QUIT)) + netsurf_quit = true; + + fbtk_redraw(fbtk); + +} + +void gui_quit(void) +{ + LOG(("gui_quit")); + framebuffer_finalise(); + + /* We don't care if this fails as we're about to exit, anyway */ + hubbub_finalise(myrealloc, NULL); +} + +/* called back when click in browser window */ +static int +fb_browser_window_click(fbtk_widget_t *widget, + nsfb_event_t *event, + int x, int y, + void *pw) +{ + struct browser_window *bw = pw; + struct browser_widget_s *bwidget = fbtk_get_userpw(widget); + + if (event->type != NSFB_EVENT_KEY_DOWN) + return 0; + + LOG(("browser window clicked at %d,%d",x,y)); + + switch (event->type) { + case NSFB_EVENT_KEY_DOWN: + switch (event->value.keycode) { + case NSFB_KEY_MOUSE_1: + browser_window_mouse_click(bw, + BROWSER_MOUSE_PRESS_1, + x + bwidget->scrollx, + y + bwidget->scrolly); + break; + + case NSFB_KEY_MOUSE_3: + browser_window_mouse_click(bw, + BROWSER_MOUSE_PRESS_2, + x + bwidget->scrollx, + y + bwidget->scrolly); + break; + + case NSFB_KEY_MOUSE_4: + /* scroll up */ + fb_window_scroll(widget, 0, -100); + break; + + case NSFB_KEY_MOUSE_5: + /* scroll down */ + fb_window_scroll(widget, 0, 100); + break; + + default: + break; + + } + case NSFB_EVENT_KEY_UP: + + switch (event->value.keycode) { + case NSFB_KEY_MOUSE_1: + browser_window_mouse_click(bw, + BROWSER_MOUSE_CLICK_1, + x + bwidget->scrollx, + y + bwidget->scrolly); + break; + + case NSFB_KEY_MOUSE_3: + browser_window_mouse_click(bw, + BROWSER_MOUSE_CLICK_2, + x + bwidget->scrollx, + y + bwidget->scrolly); + break; + + default: + break; + + } + + default: + break; + + } + return 0; +} + +/* called back when movement in browser window */ +static int +fb_browser_window_move(fbtk_widget_t *widget, + int x, int y, + void *pw) +{ + struct browser_window *bw = pw; + struct browser_widget_s *bwidget = fbtk_get_userpw(widget); + + browser_window_mouse_track(bw, + 0, + x + bwidget->scrollx, + y + bwidget->scrolly); + + return 0; +} + + +static int +fb_browser_window_input(fbtk_widget_t *widget, + nsfb_event_t *event, + void *pw) +{ + struct gui_window *gw = pw; + int res = 0; + static uint8_t modifier = 0; + int ucs4 = -1; + + LOG(("got value %d", event->value.keycode)); + + switch (event->type) { + case NSFB_EVENT_KEY_DOWN: + switch (event->value.keycode) { + + case NSFB_KEY_PAGEUP: + if (browser_window_key_press(gw->bw, KEY_PAGE_UP) == false) + fb_window_scroll(gw->browser, 0, -fbtk_get_height(gw->browser)); + break; + + case NSFB_KEY_PAGEDOWN: + if (browser_window_key_press(gw->bw, KEY_PAGE_DOWN) == false) + fb_window_scroll(gw->browser, 0, fbtk_get_height(gw->browser)); + break; + + case NSFB_KEY_RIGHT: + if (browser_window_key_press(gw->bw, KEY_RIGHT) == false) + fb_window_scroll(gw->browser, 100, 0); + break; + + case NSFB_KEY_LEFT: + if (browser_window_key_press(gw->bw, KEY_LEFT) == false) + fb_window_scroll(gw->browser, -100, 0); + break; + + case NSFB_KEY_UP: + if (browser_window_key_press(gw->bw, KEY_UP) == false) + fb_window_scroll(gw->browser, 0, -100); + break; + + case NSFB_KEY_DOWN: + if (browser_window_key_press(gw->bw, KEY_DOWN) == false) + fb_window_scroll(gw->browser, 0, 100); + break; + + case NSFB_KEY_RSHIFT: + modifier |= 1; + break; + + case NSFB_KEY_LSHIFT: + modifier |= 1<<1; + break; + + default: + ucs4 = fbtk_keycode_to_ucs4(event->value.keycode, modifier); + if (ucs4 != -1) + res = browser_window_key_press(gw->bw, ucs4); + break; + } + break; + + case NSFB_EVENT_KEY_UP: + switch (event->value.keycode) { + case NSFB_KEY_RSHIFT: + modifier &= ~1; + break; + + case NSFB_KEY_LSHIFT: + modifier &= ~(1<<1); + break; + + default: + break; + } + break; + + default: + break; + } + + return 0; +} + +static void +fb_update_back_forward(struct gui_window *gw) +{ + struct browser_window *bw = gw->bw; + + fbtk_set_bitmap(gw->back, + (browser_window_back_available(bw)) ? + &left_arrow : &left_arrow_g); + fbtk_set_bitmap(gw->forward, + (browser_window_forward_available(bw)) ? + &right_arrow : &right_arrow_g); +} + +/* left icon click routine */ +static int +fb_leftarrow_click(fbtk_widget_t *widget, + nsfb_event_t *event, + int x, int y, void *pw) +{ + struct gui_window *gw = pw; + struct browser_window *bw = gw->bw; + + if (history_back_available(bw->history)) + history_back(bw, bw->history); + + fb_update_back_forward(gw); + return 0; + +} + +/* right arrow icon click routine */ +static int +fb_rightarrow_click(fbtk_widget_t *widget, + nsfb_event_t *event, + int x, int y, + void *pw) +{ + struct gui_window *gw =pw; + struct browser_window *bw = gw->bw; + + if (history_forward_available(bw->history)) + history_forward(bw, bw->history); + + fb_update_back_forward(gw); + return 0; + +} + +/* reload icon click routine */ +static int +fb_reload_click(fbtk_widget_t *widget, + nsfb_event_t *event, + int x, int y, + void *pw) +{ + struct browser_window *bw = pw; + browser_window_reload(bw, true); + return 0; +} + +/* stop icon click routine */ +static int +fb_stop_click(fbtk_widget_t *widget, + nsfb_event_t *event, + int x, int y, + void *pw) +{ + struct browser_window *bw = pw; + browser_window_stop(bw); + return 0; +} + +/* left scroll icon click routine */ +static int +fb_scrolll_click(fbtk_widget_t *widget, + nsfb_event_t *event, + int x, int y, void *pw) +{ + struct gui_window *gw = pw; + fb_window_scroll(gw->browser, -100, 0); + return 0; +} + +static int +fb_scrollr_click(fbtk_widget_t *widget, + nsfb_event_t *event, + int x, int y, void *pw) +{ + struct gui_window *gw = pw; + fb_window_scroll(gw->browser, 100, 0); + + return 0; +} + +static int +fb_scrollu_click(fbtk_widget_t *widget, + nsfb_event_t *event, + int x, int y, void *pw) +{ + struct gui_window *gw = pw; + fb_window_scroll(gw->browser, 0, -100); + + return 0; +} + +static int +fb_scrolld_click(fbtk_widget_t *widget, + nsfb_event_t *event, + int x, int y, void *pw) +{ + struct gui_window *gw = pw; + fb_window_scroll(gw->browser, 0, 100); + + return 0; +} + +static int +fb_url_enter(void *pw, char *text) +{ + struct browser_window *bw = pw; + browser_window_go(bw, text, 0, true); + return 0; +} + +static int +fb_url_move(fbtk_widget_t *widget, + int x, int y, + void *pw) +{ + framebuffer_set_cursor(&caret_image); + return 0; +} + +static int +set_ptr_default_move(fbtk_widget_t *widget, + int x, int y, + void *pw) +{ + framebuffer_set_cursor(&pointer_image); + return 0; +} + +static int +set_ptr_hand_move(fbtk_widget_t *widget, + int x, int y, + void *pw) +{ + framebuffer_set_cursor(&hand_image); + return 0; +} + +struct gui_window * +gui_create_browser_window(struct browser_window *bw, + struct browser_window *clone, + bool new_tab) +{ + struct gui_window *gw; + struct browser_widget_s *browser_widget; + fbtk_widget_t *widget; + int top = 0; + int bot = 0; + int right = 0; + + gw = calloc(1, sizeof(struct gui_window)); + + if (gw == NULL) + return NULL; + + /* seems we need to associate the gui window with the underlying + * browser window + */ + gw->bw = bw; + + + switch(bw->browser_window_type) { + case BROWSER_WINDOW_NORMAL: + gw->window = fbtk_create_window(fbtk, 0, 0, 0, 0); + + top = 30; + bot = 20; + right = 18; + LOG(("Normal window")); + + /* fill toolbar background */ + widget = fbtk_create_fill(gw->window, + 0, 0, 0, 30, + FB_FRAME_COLOUR); + fbtk_set_handler_move(widget, set_ptr_default_move, bw); + + /* back button */ + gw->back = fbtk_create_button(gw->window, + 5, 2, + FB_FRAME_COLOUR, + &left_arrow_g, + fb_leftarrow_click, + gw); + fbtk_set_handler_move(gw->back, set_ptr_hand_move, bw); + + /* forward button */ + gw->forward = fbtk_create_button(gw->window, + 35, 2, + FB_FRAME_COLOUR, + &right_arrow_g, + fb_rightarrow_click, + gw); + fbtk_set_handler_move(gw->forward, set_ptr_hand_move, bw); + + /* reload button */ + widget = fbtk_create_button(gw->window, + 65, 2, + FB_FRAME_COLOUR, + &stop_image, + fb_stop_click, + bw); + fbtk_set_handler_move(widget, set_ptr_hand_move, bw); + + /* reload button */ + widget = fbtk_create_button(gw->window, + 95, 2, + FB_FRAME_COLOUR, + &reload, + fb_reload_click, + bw); + fbtk_set_handler_move(widget, set_ptr_hand_move, bw); + + /* url widget */ + gw->url = fbtk_create_writable_text(gw->window, + 125 , 3, + fbtk_get_width(gw->window) - 160, 24, + FB_COLOUR_WHITE, + FB_COLOUR_BLACK, + true, + fb_url_enter, + bw); + fbtk_set_handler_move(gw->url, fb_url_move, bw); + + gw->throbber = fbtk_create_bitmap(gw->window, + 130 + fbtk_get_width(gw->url), + 3, + FB_FRAME_COLOUR, + &throbber0); + + + + /* add status area widget, width of framebuffer less some for + * scrollbar + */ + gw->status = fbtk_create_text(gw->window, + 0 , + fbtk_get_height(gw->window) - bot, + fbtk_get_width(gw->window) - 200 - right, + bot, + FB_FRAME_COLOUR, FB_COLOUR_BLACK, + false); + + fbtk_set_handler_move(gw->status, set_ptr_default_move, bw); + + /* horizontal scrollbar */ + fbtk_create_button(gw->window, + fbtk_get_width(gw->window) - 200 - right, + fbtk_get_height(gw->window) - bot, + FB_FRAME_COLOUR, + &scrolll, + fb_scrolll_click, + gw); + + fbtk_create_button(gw->window, + fbtk_get_width(gw->window) - 20 - right, + fbtk_get_height(gw->window) - bot, + FB_FRAME_COLOUR, + &scrollr, + fb_scrollr_click, + gw); + + gw->hscroll = fbtk_create_hscroll(gw->window, + fbtk_get_width(gw->window) - 160 - 20 - right, + fbtk_get_height(gw->window) - bot, + 160, + bot, + FB_SCROLL_COLOUR, + FB_FRAME_COLOUR); + /* create vertical */ + fbtk_create_button(gw->window, + fbtk_get_width(gw->window) - right, + top, + FB_FRAME_COLOUR, + &scrollu, + fb_scrollu_click, + gw); + + fbtk_create_button(gw->window, + fbtk_get_width(gw->window) - right, + fbtk_get_height(gw->window) - bot - 20, + FB_FRAME_COLOUR, + &scrolld, + fb_scrolld_click, + gw); + + gw->vscroll = fbtk_create_vscroll(gw->window, + fbtk_get_width(gw->window) - right, + top + 20, + right, + fbtk_get_height(gw->window) - top - bot - 40 , + FB_SCROLL_COLOUR, + FB_FRAME_COLOUR); + + break; + + case BROWSER_WINDOW_FRAME: + gw->window = fbtk_create_window(bw->parent->window->window, 0, 0, 0, 0); + LOG(("create frame")); + break; + + default: + gw->window = fbtk_create_window(bw->parent->window->window, 0, 0, 0, 0); + LOG(("unhandled type")); + + } + + browser_widget = calloc(1, sizeof(struct browser_widget_s)); + + gw->browser = fbtk_create_user(gw->window, 0, top, -right, - (bot + top), browser_widget); + + fbtk_set_handler_click(gw->browser, fb_browser_window_click, bw); + fbtk_set_handler_input(gw->browser, fb_browser_window_input, gw); + fbtk_set_handler_redraw(gw->browser, fb_browser_window_redraw, gw); + fbtk_set_handler_move(gw->browser, fb_browser_window_move, bw); + + return gw; +} + +void gui_window_destroy(struct gui_window *gw) +{ + fbtk_destroy_widget(gw->window); + + free(gw); + + +} + +void gui_window_set_title(struct gui_window *g, const char *title) +{ + LOG(("%p, %s", g, title)); +} + + + +void fb_window_scroll(struct fbtk_widget_s *browser, int x, int y) +{ + struct browser_widget_s *bwidget = fbtk_get_userpw(browser); + LOG(("window scroll")); + bwidget->panx += x; + bwidget->pany += y; + bwidget->pan_required = true; + + fbtk_request_redraw(browser); +} + +void gui_window_redraw(struct gui_window *g, int x0, int y0, int x1, int y1) +{ + fb_queue_redraw(g->browser, x0, y0, x1, y1); +} + +void gui_window_redraw_window(struct gui_window *g) +{ + fb_queue_redraw(g->browser, 0, 0, fbtk_get_width(g->browser),fbtk_get_height(g->browser) ); +} + +void gui_window_update_box(struct gui_window *g, + const union content_msg_data *data) +{ + fb_queue_redraw(g->browser, + data->redraw.x, + data->redraw.y, + data->redraw.x + data->redraw.width, + data->redraw.y + data->redraw.height); +} + +bool gui_window_get_scroll(struct gui_window *g, int *sx, int *sy) +{ + struct browser_widget_s *bwidget = fbtk_get_userpw(g->browser); + + *sx = bwidget->scrollx; + *sy = bwidget->scrolly; + + return true; +} + +void gui_window_set_scroll(struct gui_window *g, int sx, int sy) +{ + struct browser_widget_s *bwidget = fbtk_get_userpw(g->browser); + LOG(("scroll %d",sx)); + bwidget->panx = sx; + bwidget->pany = sy; + bwidget->pan_required = true; + + fbtk_request_redraw(g->browser); +} + +void gui_window_scroll_visible(struct gui_window *g, int x0, int y0, + int x1, int y1) +{ + LOG(("%s:(%p, %d, %d, %d, %d)", __func__, g, x0, y0, x1, y1)); +} + +void gui_window_position_frame(struct gui_window *g, int x0, int y0, + int x1, int y1) +{ + struct gui_window *parent; + int px, py; + int w, h; + LOG(("%s: %d, %d, %d, %d", g->bw->name, x0, y0, x1, y1)); + parent = g->bw->parent->window; + + if (parent->window == NULL) + return; /* doesnt have an fbtk widget */ + + px = fbtk_get_x(parent->browser) + x0; + py = fbtk_get_y(parent->browser) + y0; + w = x1 - x0; + h = y1 - y0; + if (w > (fbtk_get_width(parent->browser) - px)) + w = fbtk_get_width(parent->browser) - px; + + if (h > (fbtk_get_height(parent->browser) - py)) + h = fbtk_get_height(parent->browser) - py; + + fbtk_set_pos_and_size(g->window, px, py , w , h); + + fbtk_request_redraw(parent->browser); + +} + +void gui_window_get_dimensions(struct gui_window *g, int *width, int *height, + bool scaled) +{ + *width = fbtk_get_width(g->browser); + *height = fbtk_get_height(g->browser); +} + +void gui_window_update_extent(struct gui_window *g) +{ + int pct; + + pct = (fbtk_get_width(g->browser) * 100) / g->bw->current_content->width; + fbtk_set_scroll(g->hscroll, pct); + + pct = (fbtk_get_height(g->browser) * 100) / g->bw->current_content->height; + fbtk_set_scroll(g->vscroll, pct); + +} + +void gui_window_set_status(struct gui_window *g, const char *text) +{ + fbtk_set_text(g->status, text); +} + +void gui_window_set_pointer(struct gui_window *g, gui_pointer_shape shape) +{ + switch (shape) { + case GUI_POINTER_POINT: + framebuffer_set_cursor(&hand_image); + break; + + case GUI_POINTER_CARET: + framebuffer_set_cursor(&caret_image); + break; + + default: + framebuffer_set_cursor(&pointer_image); + break; + } +} + +void gui_window_hide_pointer(struct gui_window *g) +{ +} + +void gui_window_set_url(struct gui_window *g, const char *url) +{ + fbtk_set_text(g->url, url); +} + +static void +throbber_advance(void *pw) +{ + struct gui_window *g = pw; + struct bitmap *image; + + switch (g->throbber_index) { + case 0: + image = &throbber1; + g->throbber_index = 1; + break; + + case 1: + image = &throbber2; + g->throbber_index = 2; + break; + + case 2: + image = &throbber3; + g->throbber_index = 3; + break; + + case 3: + image = &throbber4; + g->throbber_index = 4; + break; + + case 4: + image = &throbber5; + g->throbber_index = 5; + break; + + case 5: + image = &throbber6; + g->throbber_index = 6; + break; + + case 6: + image = &throbber7; + g->throbber_index = 7; + break; + + case 7: + image = &throbber8; + g->throbber_index = 8; + break; + + case 8: + image = &throbber0; + g->throbber_index = 0; + break; + + default: + return; + } + + if (g->throbber_index >= 0) { + fbtk_set_bitmap(g->throbber, image); + schedule(10, throbber_advance, g); + } +} + +void gui_window_start_throbber(struct gui_window *g) +{ + g->throbber_index = 0; + schedule(10, throbber_advance, g); +} + +void gui_window_stop_throbber(struct gui_window *gw) +{ + gw->throbber_index = -1; + fbtk_set_bitmap(gw->throbber, &throbber0); + + fb_update_back_forward(gw); + +} + +void gui_window_place_caret(struct gui_window *g, int x, int y, int height) +{ +} + +void gui_window_remove_caret(struct gui_window *g) +{ +} + +void gui_window_new_content(struct gui_window *g) +{ +} + +bool gui_window_scroll_start(struct gui_window *g) +{ + return true; +} + +bool gui_window_box_scroll_start(struct gui_window *g, + int x0, int y0, int x1, int y1) +{ + return true; +} + +bool gui_window_frame_resize_start(struct gui_window *g) +{ + LOG(("resize frame\n")); + return true; +} + +void gui_window_save_as_link(struct gui_window *g, struct content *c) +{ +} + +void gui_window_set_scale(struct gui_window *g, float scale) +{ + LOG(("set scale\n")); +} + +struct gui_download_window *gui_download_window_create(const char *url, + const char *mime_type, struct fetch *fetch, + unsigned int total_size, struct gui_window *gui) +{ + return NULL; +} + +void gui_download_window_data(struct gui_download_window *dw, const char *data, + unsigned int size) +{ +} + +void gui_download_window_error(struct gui_download_window *dw, + const char *error_msg) +{ +} + +void gui_download_window_done(struct gui_download_window *dw) +{ +} + +void gui_drag_save_object(gui_save_type type, struct content *c, + struct gui_window *g) +{ +} + +void gui_drag_save_selection(struct selection *s, struct gui_window *g) +{ +} + +void gui_start_selection(struct gui_window *g) +{ +} + +void gui_paste_from_clipboard(struct gui_window *g, int x, int y) +{ +} + +bool gui_empty_clipboard(void) +{ + return false; +} + +bool gui_add_to_clipboard(const char *text, size_t length, bool space) +{ + return false; +} + +bool gui_commit_clipboard(void) +{ + return false; +} + +bool gui_copy_to_clipboard(struct selection *s) +{ + return false; +} + +void gui_create_form_select_menu(struct browser_window *bw, + struct form_control *control) +{ +} + +void gui_launch_url(const char *url) +{ +} + +bool gui_search_term_highlighted(struct gui_window *g, + unsigned start_offset, unsigned end_offset, + unsigned *start_idx, unsigned *end_idx) +{ + return false; +} + + + +void gui_cert_verify(struct browser_window *bw, struct content *c, + const struct ssl_cert_info *certs, unsigned long num) +{ +} + +/* + * Local Variables: + * c-basic-offset:8 + * End: + */ diff --git a/framebuffer/gui.h b/framebuffer/gui.h new file mode 100644 index 000000000..5600d44ba --- /dev/null +++ b/framebuffer/gui.h @@ -0,0 +1,67 @@ +/* + * Copyright 2008 Vincent Sanders + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef NETSURF_FB_GUI_H +#define NETSURF_FB_GUI_H + +typedef struct fb_cursor_s fb_cursor_t; + +/* bounding box */ +typedef struct nsfb_bbox_s bbox_t; + +typedef struct framebuffer_s { + int width; + int height; + uint8_t *ptr; /**< Base of video memory. */ + int linelen; /**< length of a video line. */ + int bpp; + colour palette[256]; /* palette for index modes */ + fb_cursor_t *cursor; +} framebuffer_t; + +struct gui_window { + struct browser_window *bw; + + struct fbtk_widget_s *window; + struct fbtk_widget_s *back; + struct fbtk_widget_s *forward; + struct fbtk_widget_s *url; + struct fbtk_widget_s *status; + struct fbtk_widget_s *throbber; + struct fbtk_widget_s *hscroll; + struct fbtk_widget_s *vscroll; + struct fbtk_widget_s *browser; + int throbber_index; +}; + + +extern framebuffer_t *framebuffer; +extern struct gui_window *window_list; + +/* scroll a window */ +void fb_window_scroll(struct fbtk_widget_s *browser, int x, int y); + +#endif /* NETSURF_FB_GUI_H */ + +/* + * Local Variables: + * c-basic-offset:8 + * End: + */ + + diff --git a/framebuffer/image_data.h b/framebuffer/image_data.h new file mode 100644 index 000000000..f7b65c812 --- /dev/null +++ b/framebuffer/image_data.h @@ -0,0 +1,52 @@ +/* + * Copyright 2008 Vincent Sanders + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef FB_IMAGE_DATA +#define FB_IMAGE_DATA + +#include "framebuffer/bitmap.h" + +extern struct bitmap left_arrow; +extern struct bitmap right_arrow; +extern struct bitmap reload; +extern struct bitmap stop_image; +extern struct bitmap left_arrow_g; +extern struct bitmap right_arrow_g; +extern struct bitmap reload_g; +extern struct bitmap stop_image_g; + +extern struct bitmap scrolll; +extern struct bitmap scrollr; +extern struct bitmap scrollu; +extern struct bitmap scrolld; + +extern struct bitmap pointer_image; +extern struct bitmap hand_image; +extern struct bitmap caret_image; + +extern struct bitmap throbber0; +extern struct bitmap throbber1; +extern struct bitmap throbber2; +extern struct bitmap throbber3; +extern struct bitmap throbber4; +extern struct bitmap throbber5; +extern struct bitmap throbber6; +extern struct bitmap throbber7; +extern struct bitmap throbber8; + +#endif /* FB_IMAGE_DATA */ diff --git a/framebuffer/options.h b/framebuffer/options.h new file mode 100644 index 000000000..f2f52ae49 --- /dev/null +++ b/framebuffer/options.h @@ -0,0 +1,68 @@ +/* + * Copyright 2008 Daniel Silverstone + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef _NETSURF_FRAMEBUFFER_OPTIONS_H_ +#define _NETSURF_FRAMEBUFFER_OPTIONS_H_ + +#include "desktop/options.h" + +extern int option_fb_depth; +extern int option_fb_refresh; +extern bool option_fb_font_monochrome; /* render font monochrome */ +extern char *option_fb_device; +extern char *option_fb_input_devpath; +extern char *option_fb_input_glob; +extern char *option_fb_face_sans_serif; /* default sans face */ +extern char *option_fb_face_sans_serif_bold; /* bold sans face */ +extern char *option_fb_face_sans_serif_italic; /* bold sans face */ +extern char *option_fb_face_sans_serif_italic_bold; /* bold sans face */ +extern char *option_fb_face_monospace; /* monospace face */ +extern char *option_fb_face_serif; /* serif face */ +extern char *option_fb_face_serif_bold; /* bold serif face */ + +#define EXTRA_OPTION_DEFINE \ + int option_fb_depth = 32; \ + int option_fb_refresh = 70; \ + bool option_fb_font_monochrome = false; \ + char *option_fb_device = 0; \ + char *option_fb_input_devpath = 0; \ + char *option_fb_input_glob = 0; \ + char *option_fb_face_sans_serif; \ + char *option_fb_face_sans_serif_bold; \ + char *option_fb_face_sans_serif_italic; \ + char *option_fb_face_sans_serif_italic_bold; \ + char *option_fb_face_monospace; \ + char *option_fb_face_serif; \ + char *option_fb_face_serif_bold; + +#define EXTRA_OPTION_TABLE \ + { "fb_depth", OPTION_INTEGER, &option_fb_depth }, \ + { "fb_refresh", OPTION_INTEGER, &option_fb_refresh }, \ + { "fb_device", OPTION_STRING, &option_fb_device }, \ + { "fb_input_devpath", OPTION_STRING, &option_fb_input_devpath }, \ + { "fb_input_glob", OPTION_STRING, &option_fb_input_glob }, \ + { "fb_font_monochrome", OPTION_BOOL, &option_fb_font_monochrome }, \ + { "fb_face_sans_serif", OPTION_STRING, &option_fb_face_sans_serif }, \ + { "fb_face_sans_serif_bold", OPTION_STRING, &option_fb_face_sans_serif_bold }, \ + { "fb_face_sans_serif_italic", OPTION_STRING, &option_fb_face_sans_serif_italic }, \ + { "fb_face_sans_serif_italic_bold", OPTION_STRING, &option_fb_face_sans_serif_italic_bold }, \ + { "fb_face_monospace", OPTION_STRING, &option_fb_face_monospace }, \ + { "fb_face_serif", OPTION_STRING, &option_fb_face_serif }, \ + { "fb_serif_bold", OPTION_STRING, &option_fb_face_serif_bold } + +#endif diff --git a/framebuffer/schedule.c b/framebuffer/schedule.c new file mode 100644 index 000000000..64807370b --- /dev/null +++ b/framebuffer/schedule.c @@ -0,0 +1,202 @@ +/* + * Copyright 2008 Vincent Sanders + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#include +#include + +#include "desktop/browser.h" +#include "framebuffer/schedule.h" + +#include "utils/log.h" + +/* linked list of scheduled callbacks */ +static struct nscallback *schedule_list = NULL; + +/** + * scheduled callback. + */ +struct nscallback +{ + struct nscallback *next; + struct timeval tv; + void (*callback)(void *p); + void *p; +}; + + +/** + * Schedule a callback. + * + * \param tival interval before the callback should be made / cs + * \param callback callback function + * \param p user parameter, passed to callback function + * + * The callback function will be called as soon as possible after t cs have + * passed. + */ + +void schedule(int cs_ival, void (*callback)(void *p), void *p) +{ + struct nscallback *nscb; + struct timeval tv; + + tv.tv_sec = 0; + tv.tv_usec = cs_ival * 10000; + + nscb = calloc(1, sizeof(struct nscallback)); + + LOG(("adding callback %p for %p(%p) at %d cs", nscb, callback, p, cs_ival)); + + gettimeofday(&nscb->tv, NULL); + timeradd(&nscb->tv, &tv, &nscb->tv); + + nscb->callback = callback; + nscb->p = p; + + /* add to list front */ + nscb->next = schedule_list; + schedule_list = nscb; +} + +/** + * Unschedule a callback. + * + * \param callback callback function + * \param p user parameter, passed to callback function + * + * All scheduled callbacks matching both callback and p are removed. + */ + +void schedule_remove(void (*callback)(void *p), void *p) +{ + struct nscallback *cur_nscb; + struct nscallback *prev_nscb; + struct nscallback *unlnk_nscb; + + if (schedule_list == NULL) + return; + + LOG(("removing %p, %p", callback, p)); + + cur_nscb = schedule_list; + prev_nscb = NULL; + + while (cur_nscb != NULL) { + if ((cur_nscb->callback == callback) && + (cur_nscb->p == p)) { + /* item to remove */ + + LOG(("callback entry %p removing %p(%p)", + cur_nscb, cur_nscb->callback, cur_nscb->p)); + + /* remove callback */ + unlnk_nscb = cur_nscb; + cur_nscb = unlnk_nscb->next; + + if (prev_nscb == NULL) { + schedule_list = cur_nscb; + } else { + prev_nscb->next = cur_nscb; + } + free (unlnk_nscb); + } else { + /* move to next element */ + prev_nscb = cur_nscb; + cur_nscb = prev_nscb->next; + } + } +} + +/** + * Process events up to current time. + */ + +bool schedule_run(void) +{ + struct timeval tv; + struct nscallback *cur_nscb; + struct nscallback *prev_nscb; + struct nscallback *unlnk_nscb; + + if (schedule_list == NULL) + return false; + + cur_nscb = schedule_list; + prev_nscb = NULL; + + gettimeofday(&tv, NULL); + + while (cur_nscb != NULL) { + if (timercmp(&tv, &cur_nscb->tv, >)) { + /* scheduled time */ + + /* remove callback */ + unlnk_nscb = cur_nscb; + + if (prev_nscb == NULL) { + schedule_list = unlnk_nscb->next; + } else { + prev_nscb->next = unlnk_nscb->next; + } + + LOG(("callback entry %p running %p(%p)", + unlnk_nscb, unlnk_nscb->callback, unlnk_nscb->p)); + /* call callback */ + unlnk_nscb->callback(unlnk_nscb->p); + + free (unlnk_nscb); + + /* the callback might have modded the list, so start + * again + */ + cur_nscb = schedule_list; + prev_nscb = NULL; + + } else { + /* move to next element */ + prev_nscb = cur_nscb; + cur_nscb = prev_nscb->next; + } + } + return true; +} + +void list_schedule(void) +{ + struct timeval tv; + struct nscallback *cur_nscb; + + gettimeofday(&tv, NULL); + + LOG(("schedule list at %ld:%ld", tv.tv_sec, tv.tv_usec)); + + cur_nscb = schedule_list; + + while (cur_nscb != NULL) { + LOG(("Schedule %p at %ld:%ld", + cur_nscb, cur_nscb->tv.tv_sec, cur_nscb->tv.tv_usec)); + cur_nscb = cur_nscb->next; + } +} + + +/* + * Local Variables: + * c-basic-offset:8 + * End: + */ diff --git a/framebuffer/schedule.h b/framebuffer/schedule.h new file mode 100644 index 000000000..f735a06df --- /dev/null +++ b/framebuffer/schedule.h @@ -0,0 +1,24 @@ +/* + * Copyright 2008 Vincent Sanders + * + * This file is part of NetSurf, http://www.netsurf-browser.org/ + * + * NetSurf is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; version 2 of the License. + * + * NetSurf is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + * + * You should have received a copy of the GNU General Public License + * along with this program. If not, see . + */ + +#ifndef FRAMEBUFFER_SCHEDULE_H +#define FRAMEBUFFER_SCHEDULE_H + +void list_schedule(void); + +#endif diff --git a/nsfb b/nsfb deleted file mode 100755 index 15ee0aa50..000000000 --- a/nsfb +++ /dev/null @@ -1,25 +0,0 @@ -#!/bin/sh -# This file is part of NetSurf, http://netsurf-browser.org/ -# Licensed under the GNU General Public License, -# http://www.opensource.org/licenses/gpl-license -# Copyright 2007 Rob Kendrick - -if [ -d ~/.netsurf ]; then - LOG=~/.netsurf/log.txt -elif [ -d /tmp ]; then - LOG=/tmp/netsurf-log.txt -else - LOG=netsurf-log.txt -fi - -if [ -x $(dirname $0)/nsfb-sdl ]; then -TYPE=-sdl -elif [ -x $(dirname $0)/nsfb-linux ]; then -TYPE=-linux -elif [ -x $(dirname $0)/nsfb-dummy ]; then -TYPE=-dummy -fi - -NETSURFRES=$(dirname $0)/framebuffer/res/ -export NETSURFRES -exec $(dirname $0)/nsfb${TYPE} "$@" 2>$LOG -- cgit v1.2.3