diff options
-rw-r--r-- | !NetSurf/Resources/en/Messages | 23 | ||||
-rw-r--r-- | !NetSurf/Themes/NetSurf,ffd | bin | 16714 -> 16895 bytes | |||
-rw-r--r-- | content/content.c | 2 | ||||
-rw-r--r-- | content/content.h | 2 | ||||
-rw-r--r-- | desktop/options.c | 3 | ||||
-rw-r--r-- | desktop/options.h | 1 | ||||
-rw-r--r-- | gtk/gtk_bitmap.c | 27 | ||||
-rw-r--r-- | image/bitmap.h | 2 | ||||
-rw-r--r-- | image/gif.c (renamed from riscos/gif.c) | 30 | ||||
-rw-r--r-- | image/gif.h (renamed from riscos/gif.h) | 19 | ||||
-rw-r--r-- | image/gifread.c (renamed from riscos/gifread.c) | 68 | ||||
-rw-r--r-- | image/gifread.h | 75 | ||||
-rw-r--r-- | image/jpeg.c | 9 | ||||
-rw-r--r-- | image/mng.c | 6 | ||||
-rw-r--r-- | image/png.c | 1 | ||||
-rw-r--r-- | makefile | 6 | ||||
-rw-r--r-- | riscos/bitmap.c | 46 | ||||
-rw-r--r-- | riscos/bitmap.h | 1 | ||||
-rw-r--r-- | riscos/gifread.h | 98 | ||||
-rw-r--r-- | riscos/gui.h | 11 | ||||
-rw-r--r-- | riscos/hotlist.c | 12 | ||||
-rw-r--r-- | riscos/menus.c | 248 | ||||
-rw-r--r-- | riscos/options.h | 3 | ||||
-rw-r--r-- | riscos/save_draw.c | 4 | ||||
-rw-r--r-- | riscos/theme.c | 83 | ||||
-rw-r--r-- | riscos/theme.h | 15 | ||||
-rw-r--r-- | riscos/window.c | 11 |
27 files changed, 568 insertions, 238 deletions
diff --git a/!NetSurf/Resources/en/Messages b/!NetSurf/Resources/en/Messages index 3e966d449..80b110cb0 100644 --- a/!NetSurf/Resources/en/Messages +++ b/!NetSurf/Resources/en/Messages @@ -78,6 +78,29 @@ ProxyNone:None ProxyBasic:Basic ProxyNTLM:NTLM +# Toolbar menus +Toolbar:Toolbar +Icons:Buttons +IconBack:Back +IconForward:Forward +IconStop:Stop +IconReload:Reload +IconHome:Home +IconSearch:Search +IconHistory:History +IconScale:Scale view +IconHotlist:Hotlist +IconSave:Save +IconPrint:Print +IconCreate:Create entry +IconDelete:Delete entry +IconLaunch:Launch +IconOpen:Open directories +IconExpand:Expand entries +AddGap:Add separator +DeleteGap:Remove separator +LockToolbar:Lock toolbar + # Hotlist menus Hotlist:Hotlist New:New diff --git a/!NetSurf/Themes/NetSurf,ffd b/!NetSurf/Themes/NetSurf,ffd Binary files differindex 13e5c83e3..d0e8425e3 100644 --- a/!NetSurf/Themes/NetSurf,ffd +++ b/!NetSurf/Themes/NetSurf,ffd diff --git a/content/content.c b/content/content.c index cf15364e7..2999e2676 100644 --- a/content/content.c +++ b/content/content.c @@ -33,7 +33,7 @@ #include "netsurf/image/mng.h" #endif #ifdef WITH_GIF -#include "netsurf/riscos/gif.h" +#include "netsurf/image/gif.h" #endif #ifdef WITH_SPRITE #include "netsurf/riscos/sprite.h" diff --git a/content/content.h b/content/content.h index 19d60fe6e..cb5d411e6 100644 --- a/content/content.h +++ b/content/content.h @@ -105,7 +105,7 @@ #include "netsurf/image/jpeg.h" #endif #ifdef WITH_GIF -#include "netsurf/riscos/gif.h" +#include "netsurf/image/gif.h" #endif #ifdef WITH_PLUGIN #include "netsurf/riscos/plugin.h" diff --git a/desktop/options.c b/desktop/options.c index 8dafb98f5..a777f6d12 100644 --- a/desktop/options.c +++ b/desktop/options.c @@ -53,6 +53,8 @@ bool option_ssl_verify_certificates = true; int option_memory_cache_size = 2 * 1024 * 1024; /** Whether to block advertisements */ bool option_block_ads = false; +/** Minimum GIF animation delay */ +int option_minimum_gif_delay = 10; /** Whether to send the referer HTTP header */ bool option_send_referer = true; @@ -76,6 +78,7 @@ struct { { "ssl_verify_certificates", OPTION_BOOL, &option_ssl_verify_certificates }, { "memory_cache_size", OPTION_INTEGER, &option_memory_cache_size }, { "block_advertisements", OPTION_BOOL, &option_block_ads }, + { "minimum_gif_delay", OPTION_INTEGER, &option_minimum_gif_delay }, { "send_referer", OPTION_BOOL, &option_send_referer }, EXTRA_OPTION_TABLE }; diff --git a/desktop/options.h b/desktop/options.h index ee34c2097..0724f8c65 100644 --- a/desktop/options.h +++ b/desktop/options.h @@ -39,6 +39,7 @@ extern char *option_accept_language; extern bool option_ssl_verify_certificates; extern int option_memory_cache_size; extern bool option_block_ads; +extern int option_minimum_gif_delay; extern bool option_send_referer; void options_read(const char *path); diff --git a/gtk/gtk_bitmap.c b/gtk/gtk_bitmap.c index 7aaedf075..3a228a5ef 100644 --- a/gtk/gtk_bitmap.c +++ b/gtk/gtk_bitmap.c @@ -44,6 +44,33 @@ struct bitmap *bitmap_create(int width, int height) /**
+ * 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(struct bitmap *bitmap, bool opaque)
+{
+ assert(bitmap);
+/* todo: set bitmap as 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(struct bitmap *bitmap)
+{
+ assert(bitmap);
+/* todo: test if bitmap as opaque */
+ return false;
+}
+
+
+/**
* Return a pointer to the pixel data in a bitmap.
*
* \param bitmap a bitmap, as returned by bitmap_create()
diff --git a/image/bitmap.h b/image/bitmap.h index 052a3a4f4..0c06f836f 100644 --- a/image/bitmap.h +++ b/image/bitmap.h @@ -26,6 +26,8 @@ struct content; struct bitmap;
struct bitmap *bitmap_create(int width, int height);
+void bitmap_set_opaque(struct bitmap *bitmap, bool opaque);
+bool bitmap_test_opaque(struct bitmap *bitmap);
char *bitmap_get_buffer(struct bitmap *bitmap);
size_t bitmap_get_rowstride(struct bitmap *bitmap);
void bitmap_destroy(struct bitmap *bitmap);
diff --git a/riscos/gif.c b/image/gif.c index 3f450b209..091c7c2ed 100644 --- a/riscos/gif.c +++ b/image/gif.c @@ -3,7 +3,7 @@ * Licensed under the GNU General Public License, * http://www.opensource.org/licenses/gpl-license * Copyright 2003 John M Bell <jmb202@ecs.soton.ac.uk> - * Copyright 2004 Richard Wilson <not_ginger_matt@sourceforge.net> + * Copyright 2004 Richard Wilson <not_ginger_matt@users.sourceforge.net> */ #include <assert.h> @@ -14,11 +14,11 @@ #include "oslib/osspriteop.h" #include "netsurf/utils/config.h" #include "netsurf/content/content.h" -#include "netsurf/riscos/gif.h" -#include "netsurf/riscos/gifread.h" -#include "netsurf/riscos/gui.h" -#include "netsurf/riscos/image.h" -#include "netsurf/riscos/options.h" +#include "netsurf/desktop/browser.h" +#include "netsurf/desktop/options.h" +#include "netsurf/image/bitmap.h" +#include "netsurf/image/gif.h" +#include "netsurf/image/gifread.h" #include "netsurf/utils/log.h" #include "netsurf/utils/messages.h" #include "netsurf/utils/utils.h" @@ -115,6 +115,7 @@ bool nsgif_convert(struct content *c, int iwidth, int iheight) { /* Exit as a success */ + c->bitmap = gif->frame_image; c->status = CONTENT_STATUS_DONE; return true; } @@ -132,10 +133,10 @@ bool nsgif_redraw(struct content *c, int x, int y, settings. We default to the first image if we don't have a GUI as we are drawing a thumbnail unless something has gone very wrong somewhere else. */ - if (ro_gui_current_redraw_gui) { +/* if (ro_gui_current_redraw_gui) { if (ro_gui_current_redraw_gui->option.animate_images) { - current_frame = c->data.gif.current_frame; - } else { +*/ current_frame = c->data.gif.current_frame; +/* } else { current_frame = 0; } } else { @@ -149,23 +150,22 @@ bool nsgif_redraw(struct content *c, int x, int y, } } } - +*/ /* Decode from the last frame to the current frame */ if (current_frame < c->data.gif.gif->decoded_frame) { previous_frame = 0; } else { previous_frame = c->data.gif.gif->decoded_frame + 1; - } for (frame = previous_frame; frame <= current_frame; frame++) { gif_decode_frame(c->data.gif.gif, frame); } + c->bitmap = c->data.gif.gif->frame_image; - return image_redraw(c->data.gif.gif->frame_image, x, y, width, - height, c->width * 2, c->height * 2, - background_colour, false, false, - IMAGE_PLOT_TINCT_ALPHA); + return bitmap_redraw(c, x, y, width, height, + clip_x0, clip_y0, clip_x1, clip_y1, + scale, background_colour); } diff --git a/riscos/gif.h b/image/gif.h index 891991b4a..c7fa6f281 100644 --- a/riscos/gif.h +++ b/image/gif.h @@ -2,26 +2,19 @@ * This file is part of NetSurf, http://netsurf.sourceforge.net/ * Licensed under the GNU General Public License, * http://www.opensource.org/licenses/gpl-license - * Copyright 2003 Philip Pemberton <philpem@users.sourceforge.net> - * Copyright 2004 Richard Wilson <not_ginger_matt@sourceforge.net> + * Copyright 2004 Richard Wilson <not_ginger_matt@users.sourceforge.net> */ -#ifndef _NETSURF_RISCOS_GIF_H_ -#define _NETSURF_RISCOS_GIF_H_ +#ifndef _NETSURF_IMAGE_GIF_H_ +#define _NETSURF_IMAGE_GIF_H_ -#include "netsurf/riscos/gifread.h" +#include "netsurf/image/gifread.h" struct content; struct content_gif_data { - - /* The GIF data - */ - struct gif_animation *gif; - - /** The current frame number of the GIF to display, [0...(max-1)] - */ - unsigned int current_frame; + struct gif_animation *gif; /**< GIF animation data */ + unsigned int current_frame; /**< current frame to display [0...(max-1)] */ }; bool nsgif_create(struct content *c, const char *params[]); diff --git a/riscos/gifread.c b/image/gifread.c index 64038ea6e..fb6a7d2fa 100644 --- a/riscos/gifread.c +++ b/image/gifread.c @@ -2,14 +2,16 @@ * This file is part of NetSurf, http://netsurf.sourceforge.net/ * Licensed under the GNU General Public License, * http://www.opensource.org/licenses/gpl-license - * Copyright 2004 Richard Wilson <not_ginger_matt@sourceforge.net> + * Copyright 2004 Richard Wilson <not_ginger_matt@users.sourceforge.net> */ +#include <stdbool.h> #include <stdio.h> #include <string.h> #include <stdlib.h> #include "gifread.h" +#include "netsurf/image/bitmap.h" #include "netsurf/utils/log.h" #include "oslib/osspriteop.h" #include "oslib/osfile.h" @@ -110,7 +112,6 @@ int gif_initialise(struct gif_animation *gif) { unsigned int index; int return_value; unsigned int frame; - osspriteop_header *header; /* Check for sufficient data to be a GIF */ @@ -173,9 +174,11 @@ int gif_initialise(struct gif_animation *gif) { if (((gif->width == 640) && (gif->width == 480)) || ((gif->width == 640) && (gif->width == 512)) || ((gif->width == 800) && (gif->width == 600)) || - ((gif->width == 1280) && (gif->width == 1024))) { - gif->width = 0; - gif->height = 0; + ((gif->width == 1024) && (gif->width == 768)) || + ((gif->width == 1280) && (gif->width == 1024)) || + ((gif->width == 1600) && (gif->width == 1200))) { + gif->width = 1; + gif->height = 1; } /* Allocate some data irrespective of whether we've got any colour tables. We @@ -204,28 +207,10 @@ int gif_initialise(struct gif_animation *gif) { /* Initialise the sprite header */ - if ((gif->frame_image = (osspriteop_area *)malloc(sizeof(osspriteop_area) + - sizeof(osspriteop_header) + (gif->width * gif->height * 4))) == NULL) { + if ((gif->frame_image = bitmap_create(gif->width, gif->height)) == NULL) { gif_finalise(gif); return GIF_INSUFFICIENT_MEMORY; } - gif->frame_image->size = sizeof(osspriteop_area) + sizeof(osspriteop_header) + - (gif->width * gif->height * 4); - gif->frame_image->sprite_count = 1; - gif->frame_image->first = 16; - gif->frame_image->used = gif->frame_image->size; - header = (osspriteop_header*)((char*)gif->frame_image + - gif->frame_image->first); - header->size = sizeof(osspriteop_header) + (gif->width * gif->height * 4); - memset(header->name, 0x00, 12); - strcpy(header->name, "gif"); - header->left_bit = 0; - header->right_bit = 31; - header->width = gif->width - 1; - header->height = gif->height - 1; - header->image = sizeof(osspriteop_header); - header->mask = sizeof(osspriteop_header); - header->mode = (os_mode) 0x301680b5; /* Remember we've done this now */ @@ -334,11 +319,9 @@ int gif_initialise(struct gif_animation *gif) { 0 for success */ static int gif_initialise_sprite(struct gif_animation *gif, unsigned int width, unsigned int height) { - struct osspriteop_area *buffer; - struct osspriteop_header *header; unsigned int max_width; unsigned int max_height; - unsigned int frame_bytes; + struct bitmap *buffer; /* Check if we've changed */ @@ -348,31 +331,15 @@ static int gif_initialise_sprite(struct gif_animation *gif, unsigned int width, */ max_width = (width > gif->width) ? width : gif->width; max_height = (height > gif->height) ? height : gif->height; - frame_bytes = max_width * max_height * 4 + - sizeof(osspriteop_header) + sizeof(osspriteop_area); /* Allocate some more memory */ - if ((buffer = (osspriteop_area *)realloc(gif->frame_image, frame_bytes)) == NULL) { + if ((buffer = bitmap_create(max_width, max_height)) == NULL) { return GIF_INSUFFICIENT_MEMORY; } + bitmap_destroy(gif->frame_image); gif->frame_image = buffer; - /* Update the sizes - */ - gif->width = max_width; - gif->height = max_height; - - /* Update our sprite image - */ - buffer->size = frame_bytes; - buffer->used = frame_bytes; - header = (osspriteop_header*)((char*)gif->frame_image + - gif->frame_image->first); - header->size = frame_bytes - sizeof(osspriteop_area); - header->width = max_width - 1; - header->height = max_height - 1; - /* Invalidate our currently decoded image */ gif->decoded_frame = 0xffffffff; @@ -443,6 +410,7 @@ int gif_initialise_frame(struct gif_animation *gif) { start off with one frame allocated so we can always use realloc. */ gif->frames[frame].frame_pointer = gif->buffer_position; + gif->frames[frame].virgin = true; gif->frames[frame].frame_delay = 100; // Paranoia gif->frames[frame].redraw_required = 0; // Paranoia @@ -668,7 +636,7 @@ int gif_decode_frame(struct gif_animation *gif, unsigned int frame) { sprite and clear what we need as some frames have multiple images which would produce errors. */ - frame_data = (unsigned int*)((char *)gif->frame_image + gif->frame_image->first + sizeof(osspriteop_header)); + frame_data = (unsigned int *)bitmap_get_buffer(gif->frame_image); if (!clear_image) { if ((frame == 0) || (gif->decoded_frame == 0xffffffff)) { memset((char*)frame_data, 0x00, gif->width * gif->height * sizeof(int)); @@ -871,6 +839,14 @@ gif_decode_frame_exit: if ((gif_bytes < 1) || (gif_data[0] == 0x3b)) more_images = 0; gif->buffer_position++; } + + /* Check if we should test for optimisation + */ + if (gif->frames[frame].virgin) { + gif->frames[frame].opaque = bitmap_test_opaque(gif->frame_image); + gif->frames[frame].virgin = false; + } + bitmap_set_opaque(gif->frame_image, gif->frames[frame].opaque); /* Restore the buffer position */ diff --git a/image/gifread.h b/image/gifread.h new file mode 100644 index 000000000..a19409898 --- /dev/null +++ b/image/gifread.h @@ -0,0 +1,75 @@ +/* + * This file is part of NetSurf, http://netsurf.sourceforge.net/ + * Licensed under the GNU General Public License, + * http://www.opensource.org/licenses/gpl-license + * Copyright 2004 Richard Wilson <not_ginger_matt@users.sourceforge.net> + */ + +/** \file + * Progressive animated GIF file decoding (interface). + */ + +#ifndef _NETSURF_IMAGE_GIFREAD_H_ +#define _NETSURF_IMAGE_GIFREAD_H_ + +#include "netsurf/image/bitmap.h" + +/* Error return values +*/ +#define GIF_INSUFFICIENT_FRAME_DATA -1 +#define GIF_FRAME_DATA_ERROR -2 +#define GIF_INSUFFICIENT_DATA -3 +#define GIF_DATA_ERROR -4 +#define GIF_INSUFFICIENT_MEMORY -5 + +/* Maximum colour table size +*/ +#define GIF_MAX_COLOURS 256 + +/* Maximum LZW bits available +*/ +#define GIF_MAX_LZW 12 + +/* The GIF frame data +*/ +typedef struct gif_frame { + unsigned int frame_pointer; /**< offset (in bytes) to the GIF frame data */ + unsigned int frame_delay; /**< delay (in cs) before animating the frame */ + bool virgin; /**< whether the frame has previously been used */ + bool opaque; /**< whether the frame is totally opaque */ + bool redraw_required; /**< whether a forcable screen redraw is required */ + unsigned int redraw_x; /**< x co-ordinate of redraw rectangle */ + unsigned int redraw_y; /**< y co-ordinate of redraw rectangle */ + unsigned int redraw_width; /**< width of redraw rectangle */ + unsigned int redraw_height; /**< height of redraw rectangle */ +} gif_frame; + +/* The GIF animation data +*/ +typedef struct gif_animation { + unsigned char *gif_data; /**< pointer to GIF data */ + unsigned int buffer_position; /**< current index into GIF data */ + unsigned int buffer_size; /**< total number of bytes of GIF data available */ + unsigned int frame_holders; /**< current number of frame holders */ + unsigned int decoded_frame; /**< current frame decoded to bitmap */ + int loop_count; /**< number of times to loop animation */ + gif_frame *frames; /**< decoded frames */ + unsigned int width; /**< width of GIF (may increase during decoding) */ + unsigned int height; /**< heigth of GIF (may increase during decoding) */ + unsigned int frame_count; /**< number of frames decoded */ + unsigned int frame_count_partial; /**< number of frames partially decoded */ + unsigned int background_colour; /**< image background colour */ + unsigned int aspect_ratio; /**< image aspect ratio (ignored) */ + unsigned int colour_table_size; /**< size of colour table (in entries) */ + bool global_colours; /**< whether the GIF has a global colour table */ + unsigned int *global_colour_table; /**< global colour table */ + unsigned int *local_colour_table; /**< local colour table */ + bool dirty_frame; /**< whether the curent frame needs erasing on animation */ + struct bitmap *frame_image; /**< currently decoded image */ +} gif_animation; + +int gif_initialise(struct gif_animation *gif); +int gif_decode_frame(struct gif_animation *gif, unsigned int frame); +void gif_finalise(struct gif_animation *gif); + +#endif diff --git a/image/jpeg.c b/image/jpeg.c index 47a8f4b5e..01c075d4b 100644 --- a/image/jpeg.c +++ b/image/jpeg.c @@ -102,6 +102,7 @@ bool nsjpeg_convert(struct content *c, int w, int h) warn_user("NoMemory", 0); return false; } + bitmap_set_opaque(bitmap, true); pixels = bitmap_get_buffer(bitmap); rowstride = bitmap_get_rowstride(bitmap); @@ -120,13 +121,7 @@ bool nsjpeg_convert(struct content *c, int w, int h) scanlines[0][i * 4 + 0] = r; scanlines[0][i * 4 + 1] = g; scanlines[0][i * 4 + 2] = b; - scanlines[0][i * 4 + 3] = 0xff; - } -#else - /* make fully opaque for alpha plotting - * (is there a better way?) */ - for (int i = width - 1; 0 <= i; i--) { - scanlines[0][i * 4 + 3] = 0xff; +/* scanlines[0][i * 4 + 3] = 0xff; */ } #endif } while (cinfo.output_scanline != cinfo.output_height); diff --git a/image/mng.c b/image/mng.c index fecebe6f3..d1b9c9cfc 100644 --- a/image/mng.c +++ b/image/mng.c @@ -258,6 +258,12 @@ bool nsmng_convert(struct content *c, int width, int height) { LOG(("Unable to start display (%i)", status)); return nsmng_broadcast_error(c); } + + /* Optimise the plotting of JNG/PNGs + */ + if ((c->type == CONTENT_PNG) || (c->type == CONTENT_JNG)) { + bitmap_set_opaque(c->bitmap, bitmap_test_opaque(c->bitmap)); + } return true; } diff --git a/image/png.c b/image/png.c index 5fa4d9af7..9fd79f2fd 100644 --- a/image/png.c +++ b/image/png.c @@ -156,6 +156,7 @@ void info_callback(png_structp png, png_infop info) c->data.png.interlace = (interlace == PNG_INTERLACE_ADAM7); c->width = width; c->height = height; + bitmap_set_opaque(c->bitmap, bitmap_test_opaque(c->bitmap)); LOG(("size %li * %li, bpp %i, rowbytes %u", width, height, bit_depth, rowbytes)); @@ -23,13 +23,13 @@ OBJECTS_COMMON += box.o form.o html.o layout.o textplain.o # render/ OBJECTS_COMMON += messages.o pool.o translit.o url.o utils.o # utils/ OBJECTS_COMMON += imagemap.o loginlist.o options.o # desktop/ -OBJECTS_IMAGE = jpeg.o mng.o # image/ +OBJECTS_IMAGE = jpeg.o mng.o gif.o gifread.o # image/ OBJECTS_RISCOS = $(OBJECTS_COMMON) $(OBJECTS_IMAGE) OBJECTS_RISCOS += browser.o netsurf.o version.o # desktop/ OBJECTS_RISCOS += 401login.o bitmap.o debugwin.o \ - buffer.o dialog.o download.o draw.o filetype.o font.o gif.o \ - gifread.o gui.o help.o history.o hotlist.o htmlredraw.o image.o \ + buffer.o dialog.o download.o draw.o filetype.o font.o \ + gui.o help.o history.o hotlist.o htmlredraw.o image.o \ menus.o mouseactions.o plugin.o print.o \ save.o save_complete.o save_draw.o save_text.o \ schedule.o search.o sprite.o textselection.o theme.o thumbnail.o \ diff --git a/riscos/bitmap.c b/riscos/bitmap.c index 892aed3b6..b758e82e7 100644 --- a/riscos/bitmap.c +++ b/riscos/bitmap.c @@ -39,8 +39,11 @@ struct bitmap *bitmap_create(int width, int height) osspriteop_area *sprite_area;
osspriteop_header *sprite;
+ if ((width == 0) || (height == 0))
+ return NULL;
+
area_size = 16 + 44 + width * height * 4;
- bitmap = calloc(area_size, 1);
+ bitmap = calloc(sizeof(struct bitmap) + area_size, 1);
if (!bitmap)
return NULL;
@@ -54,7 +57,7 @@ struct bitmap *bitmap_create(int width, int height) /* sprite control block */
sprite = (osspriteop_header *) (sprite_area + 1);
sprite->size = area_size - 16;
- memset(sprite->name, 0x00, 12);
+/* memset(sprite->name, 0x00, 12); */
strncpy(sprite->name, "bitmap", 12);
sprite->width = width - 1;
sprite->height = height - 1;
@@ -68,6 +71,40 @@ struct bitmap *bitmap_create(int width, int height) /**
+ * 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(struct bitmap *bitmap, bool opaque)
+{
+ assert(bitmap);
+ bitmap->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(struct bitmap *bitmap)
+{
+ assert(bitmap);
+ char *sprite = bitmap_get_buffer(bitmap);
+ unsigned int width = bitmap_get_rowstride(bitmap);
+ osspriteop_header *sprite_header =
+ (osspriteop_header *) (&(bitmap->sprite_area) + 1);
+ unsigned int height = (sprite_header->height + 1);
+ unsigned int size = width * height;
+ for (unsigned int i = 3; i < size; i += 4)
+ if (sprite[i] != 0xff)
+ return false;
+ return true;
+}
+
+/**
* Return a pointer to the pixel data in a bitmap.
*
* \param bitmap a bitmap, as returned by bitmap_create()
@@ -80,7 +117,7 @@ struct bitmap *bitmap_create(int width, int height) char *bitmap_get_buffer(struct bitmap *bitmap)
{
assert(bitmap);
- return ((char *) bitmap) + 16 + 44;
+ return ((char *) (&(bitmap->sprite_area))) + 16 + 44;
}
@@ -124,7 +161,8 @@ bool bitmap_redraw(struct content *c, int x, int y, {
return image_redraw(&(c->bitmap->sprite_area), x, y, width, height,
c->width * 2, c->height * 2, background_colour,
- false, false, IMAGE_PLOT_TINCT_ALPHA);
+ false, false, ((c->bitmap->opaque) ?
+ IMAGE_PLOT_TINCT_OPAQUE : IMAGE_PLOT_TINCT_ALPHA));
}
diff --git a/riscos/bitmap.h b/riscos/bitmap.h index 4c8545cb4..17ff16340 100644 --- a/riscos/bitmap.h +++ b/riscos/bitmap.h @@ -11,6 +11,7 @@ struct osspriteop_area; struct bitmap { + bool opaque; osspriteop_area sprite_area; }; diff --git a/riscos/gifread.h b/riscos/gifread.h deleted file mode 100644 index 5e956aff7..000000000 --- a/riscos/gifread.h +++ /dev/null @@ -1,98 +0,0 @@ -/* - * This file is part of NetSurf, http://netsurf.sourceforge.net/ - * Licensed under the GNU General Public License, - * http://www.opensource.org/licenses/gpl-license - * Copyright 2004 Richard Wilson <not_ginger_matt@sourceforge.net> - */ - -/** \file - * Progressive animated GIF file decoding (interface). - */ - -#ifndef _NETSURF_RISCOS_GIFREAD_H_ -#define _NETSURF_RISCOS_GIFREAD_H_ - -#include "oslib/osspriteop.h" - -/* Error return values -*/ -#define GIF_INSUFFICIENT_FRAME_DATA -1 -#define GIF_FRAME_DATA_ERROR -2 -#define GIF_INSUFFICIENT_DATA -3 -#define GIF_DATA_ERROR -4 -#define GIF_INSUFFICIENT_MEMORY -5 - -/* Colour map size constant. Because we don't want to allocate - memory each time we decode a frame we get enough so all frames - will fit in there. -*/ -#define GIF_MAX_COLOURS 256 - -/* Maximum LZW bits available -*/ -#define GIF_MAX_LZW 12 - -/* The GIF frame dats -*/ -typedef struct gif_frame { - /* Frame data - */ - unsigned int frame_pointer; - unsigned int frame_delay; - - /* Redraw characteristics - */ - unsigned int redraw_required; - unsigned int redraw_x; - unsigned int redraw_y; - unsigned int redraw_width; - unsigned int redraw_height; - -} gif_frame; - - -/* A simple hold-all for our GIF data -*/ -typedef struct gif_animation { - /* Encoded GIF data - */ - unsigned char *gif_data; - unsigned int buffer_position; - unsigned int buffer_size; - - /* Progressive decoding data - */ - unsigned int global_colours; - unsigned int frame_holders; - unsigned int colour_table_size; - - /* Animation data - */ - unsigned int decoded_frame; - int loop_count; - gif_frame *frames; - - /* Decoded GIF data - */ - unsigned int width; - unsigned int height; - unsigned int frame_count; - unsigned int frame_count_partial; - unsigned int background_colour; - unsigned int aspect_ratio; - unsigned int *global_colour_table; - unsigned int *local_colour_table; - - /* Decoded frame data - */ - unsigned int dirty_frame; // Frame needs erasing before next - osspriteop_area *frame_image; -} gif_animation; - -/* Function declarations -*/ -int gif_initialise(struct gif_animation *gif); -int gif_decode_frame(struct gif_animation *gif, unsigned int frame); -void gif_finalise(struct gif_animation *gif); - -#endif diff --git a/riscos/gui.h b/riscos/gui.h index b6c68e07d..f2394e641 100644 --- a/riscos/gui.h +++ b/riscos/gui.h @@ -32,7 +32,7 @@ extern wimp_w dialog_info, dialog_saveas, dialog_config, dialog_config_br, extern wimp_w history_window; extern wimp_w hotlist_window; extern wimp_menu *iconbar_menu, *browser_menu, *combo_menu, *hotlist_menu, - *proxyauth_menu, *languages_menu; + *proxyauth_menu, *languages_menu, *toolbar_menu; extern int iconbar_menu_height; extern struct form_control *current_gadget; extern bool gui_reformat_pending; @@ -98,6 +98,7 @@ struct gui_window { }; +extern struct toolbar *current_toolbar; extern struct gui_window *current_gui; extern struct gui_window *ro_gui_current_redraw_gui; extern struct gui_window *ro_gui_current_zoom_gui; @@ -265,9 +266,8 @@ bool ro_gui_print_keypress(wimp_key *key); #define ICON_TOOLBAR_BOOKMARK 8 #define ICON_TOOLBAR_SCALE 9 #define ICON_TOOLBAR_SEARCH 10 -#define ICON_TOOLBAR_UP 11 -#define ICON_TOOLBAR_URL 12 // Must be after highest toolbar icon -#define ICON_TOOLBAR_THROBBER 13 +#define ICON_TOOLBAR_URL 11 // Must be after highest toolbar icon +#define ICON_TOOLBAR_THROBBER 12 /* icon numbers for hotlist toolbars */ #define ICON_TOOLBAR_CREATE 0 @@ -275,8 +275,7 @@ bool ro_gui_print_keypress(wimp_key *key); #define ICON_TOOLBAR_EXPAND 2 #define ICON_TOOLBAR_OPEN 3 #define ICON_TOOLBAR_LAUNCH 4 -#define ICON_TOOLBAR_SORT 5 -#define ICON_TOOLBAR_HOTLIST_LAST 6 +#define ICON_TOOLBAR_HOTLIST_LAST 5 /* icon numbers for toolbar status window */ #define ICON_STATUS_RESIZE 0 diff --git a/riscos/hotlist.c b/riscos/hotlist.c index 3b787a536..f7ed7516b 100644 --- a/riscos/hotlist.c +++ b/riscos/hotlist.c @@ -2296,9 +2296,17 @@ bool ro_gui_hotlist_keypress(int key) { void ro_gui_hotlist_toolbar_click(wimp_pointer* pointer) { int selection; - /* Reject Menu clicks + /* Store the toolbar */ - if (pointer->buttons == wimp_CLICK_MENU) return; + current_toolbar = hotlist_toolbar; + + /* Handle Menu clicks + */ + if (pointer->buttons == wimp_CLICK_MENU) { + ro_gui_create_menu(toolbar_menu, pointer->pos.x, + pointer->pos.y, NULL); + return; + } /* Handle the buttons appropriately */ diff --git a/riscos/menus.c b/riscos/menus.c index eb368e7de..cdf2592f8 100644 --- a/riscos/menus.c +++ b/riscos/menus.c @@ -48,6 +48,7 @@ static void translate_menu(wimp_menu *menu); static void build_languages_menu(void); static void ro_gui_menu_prepare_images(void); static void ro_gui_menu_prepare_window(void); +static void ro_gui_menu_prepare_theme(void); static void ro_gui_menu_prepare_toolbars(void); static void ro_gui_menu_prepare_render(void); static void ro_gui_menu_prepare_help(int forced); @@ -196,7 +197,7 @@ static wimp_MENU(5) image_menu = { /* Toolbar submenu */ -static wimp_MENU(4) toolbar_menu = { +static wimp_MENU(4) show_toolbar_menu = { { "Toolbars" }, 7,2,7,0, 300, 44, 0, { { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "ToolButtons" } }, @@ -321,7 +322,7 @@ static wimp_MENU(3) hotlist_expand = { { { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "All" } }, { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "Folders" } }, - { wimp_MENU_LAST, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "Links" } }, + { wimp_MENU_LAST, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "Links" } } } }; @@ -332,7 +333,7 @@ static wimp_MENU(3) hotlist_collapse = { { { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "All" } }, { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "Folders" } }, - { wimp_MENU_LAST, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "Links" } }, + { wimp_MENU_LAST, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "Links" } } } }; @@ -342,7 +343,7 @@ static wimp_MENU(3) hotlist_save = { { { wimp_MENU_GIVE_WARNING, (wimp_menu*)1, DEFAULT_FLAGS, { "URI" } }, { wimp_MENU_GIVE_WARNING, (wimp_menu*)1, DEFAULT_FLAGS, { "URL" } }, - { wimp_MENU_LAST | wimp_MENU_GIVE_WARNING, (wimp_menu*)1, DEFAULT_FLAGS, { "HTML" } }, + { wimp_MENU_LAST | wimp_MENU_GIVE_WARNING, (wimp_menu*)1, DEFAULT_FLAGS, { "HTML" } } } }; @@ -355,7 +356,7 @@ static wimp_MENU(5) hotlist_file = { { wimp_MENU_GIVE_WARNING, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "Save" } }, { wimp_MENU_GIVE_WARNING | wimp_MENU_SEPARATE, (wimp_menu *)1, DEFAULT_FLAGS, { "Export" } }, { 0, (wimp_menu *)&hotlist_expand, DEFAULT_FLAGS, { "Expand" } }, - { wimp_MENU_LAST, (wimp_menu *)&hotlist_collapse, DEFAULT_FLAGS, { "Collapse" } }, + { wimp_MENU_LAST, (wimp_menu *)&hotlist_collapse, DEFAULT_FLAGS, { "Collapse" } } } }; @@ -369,7 +370,7 @@ static wimp_MENU(5) hotlist_select = { { wimp_MENU_GIVE_WARNING, (wimp_menu *)1, DEFAULT_FLAGS, { "Edit" } }, { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "Launch" } }, { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "Delete" } }, - { wimp_MENU_LAST, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "ResetUsage" } }, + { wimp_MENU_LAST, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "ResetUsage" } } } }; @@ -382,7 +383,7 @@ static wimp_MENU(4) hotlist_root = { { 0, (wimp_menu *)&hotlist_file, DEFAULT_FLAGS, { "Hotlist" } }, { wimp_MENU_GIVE_WARNING, (wimp_menu *)&hotlist_select, DEFAULT_FLAGS, { "Selection" } }, { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "SelectAll" } }, - { wimp_MENU_LAST, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "Clear" } }, + { wimp_MENU_LAST, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "Clear" } } } }; wimp_menu *hotlist_menu = (wimp_menu *)&hotlist_root; @@ -393,17 +394,75 @@ wimp_menu *hotlist_menu = (wimp_menu *)&hotlist_root; static wimp_MENU(3) proxy_menu = { { "ProxyAuth" }, 7,2,7,0, 200, 44, 0, { - { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "ProxyNone" } }, - { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "ProxyBasic" } }, - { wimp_MENU_LAST, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "ProxyNTLM" } }, + { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "ProxyNone" } }, + { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "ProxyBasic" } }, + { wimp_MENU_LAST, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "ProxyNTLM" } } } }; wimp_menu *proxyauth_menu = (wimp_menu *) &proxy_menu; + +/* Toolbar icon submenus. + The index of the name must be identical to the toolbar icon number. +*/ +static wimp_MENU(11) toolbar_browser = { + { "Icons" }, 7,2,7,0, 200, 44, 0, + { + { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "IconBack" } }, + { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "IconForward" } }, + { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "IconStop" } }, + { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "IconReload" } }, + { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "IconHome" } }, + { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "IconHistory" } }, + { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "IconSave" } }, + { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "IconPrint" } }, + { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "IconHotlist" } }, + { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "IconScale" } }, + { wimp_MENU_LAST, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "IconSearch" } } + } +}; +wimp_menu *toolbar_browser_menu = (wimp_menu *)&toolbar_browser; + +static wimp_MENU(5) toolbar_hotlist = { + { "Icons" }, 7,2,7,0, 200, 44, 0, + { + { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "IconCreate" } }, + { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "IconDelete" } }, + { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "IconExpand" } }, + { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "IconOpen" } }, + { wimp_MENU_LAST, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "IconLaunch" } } + } +}; +wimp_menu *toolbar_hotlist_menu = (wimp_menu *)&toolbar_hotlist; + +/* Toolbar icon menu +*/ +static wimp_MENU(5) toolbar = { + { "Toolbar" }, 7,2,7,0, 200, 44, 0, + { + { 0, (wimp_menu *)&toolbar_browser, DEFAULT_FLAGS, { "Icons" } }, + { 0, (wimp_menu *)&show_toolbar_menu, DEFAULT_FLAGS, { "Toolbars" } }, + { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "AddGap" } }, + { wimp_MENU_SEPARATE, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "DeleteGap" } }, + { wimp_MENU_LAST, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "LockToolbar" } } + } +}; +wimp_menu *toolbar_menu = (wimp_menu *)&toolbar; + + +/* Current toolbar +*/ +struct toolbar *current_toolbar; +static struct toolbar_icon *current_toolbar_icon; + /* Languages popup menu (used in browser choices dialog) */ wimp_menu *languages_menu = NULL; +/* Toolbar menu +*/ +wimp_menu *toolbar_icon_menu = NULL; + /* Font popup menu (used in font choices dialog) */ static wimp_menu *font_menu = NULL; @@ -418,7 +477,7 @@ static wimp_menu *browser_selection_menu = (wimp_menu *)&selection_menu; static wimp_menu *browser_navigate_menu = (wimp_menu *)&navigate_menu; static wimp_menu *browser_view_menu = (wimp_menu *)&view_menu; static wimp_menu *browser_image_menu = (wimp_menu *)&image_menu; -static wimp_menu *browser_toolbar_menu = (wimp_menu *)&toolbar_menu; +static wimp_menu *browser_toolbar_menu = (wimp_menu *)&show_toolbar_menu; static wimp_menu *browser_render_menu = (wimp_menu *)&render_menu; static wimp_menu *browser_window_menu = (wimp_menu *)&window_menu; static wimp_menu *browser_utilities_menu = (wimp_menu *)&utilities_menu; @@ -466,6 +525,10 @@ void ro_gui_menus_init(void) translate_menu(hotlist_save_menu); translate_menu(hotlist_select_menu); + translate_menu(toolbar_menu); + translate_menu(toolbar_browser_menu); + translate_menu(toolbar_hotlist_menu); + translate_menu(proxyauth_menu); build_languages_menu(); @@ -565,7 +628,7 @@ void build_languages_menu(void) languages_menu = temp; languages_menu->entries[entries].menu_flags = 0; languages_menu->entries[entries].sub_menu = wimp_NO_SUB_MENU; - languages_menu->entries[entries].icon_flags = wimp_ICON_TEXT | wimp_ICON_FILLED | wimp_ICON_INDIRECTED | (wimp_COLOUR_BLACK << wimp_ICON_FG_COLOUR_SHIFT) | (wimp_COLOUR_WHITE << wimp_ICON_BG_COLOUR_SHIFT); + languages_menu->entries[entries].icon_flags = DEFAULT_FLAGS | wimp_ICON_INDIRECTED; languages_menu->entries[entries].data.indirected_text.text = lang_name; languages_menu->entries[entries].data.indirected_text.validation = (char *)-1; languages_menu->entries[entries].data.indirected_text.size = strlen(lang_name) + 1; @@ -622,11 +685,25 @@ void ro_gui_create_menu(wimp_menu *menu, int x, int y, struct gui_window *g) else menu->entries[1].icon_flags |= wimp_ICON_SHADED; if ((current_gui->bw) && (current_gui->bw->current_content)) { - menu->entries[0].icon_flags &= ~wimp_ICON_SHADED; + menu->entries[0].icon_flags &= ~wimp_ICON_SHADED; } else { - menu->entries[0].icon_flags |= wimp_ICON_SHADED; + menu->entries[0].icon_flags |= wimp_ICON_SHADED; + } + + } else if (menu == toolbar_menu) { + state.w = current_toolbar->toolbar_handle; + error = xwimp_get_window_state(&state); + if (error) { + LOG(("xwimp_get_window_state: 0x%x: %s", + error->errnum, error->errmess)); + warn_user("WimpError", error->errmess); + return; } + current_toolbar_icon = ro_gui_theme_toolbar_get_icon(current_toolbar, + x - state.visible.x0, y - state.visible.y0); + LOG(("Toolbar (%i,%i)", x - state.visible.x0, y - state.visible.y0)); + ro_gui_menu_prepare_theme(); } else if (menu == hotlist_menu) { ro_gui_menu_prepare_hotlist(); } @@ -665,7 +742,9 @@ void ro_gui_popup_menu(wimp_menu *menu, wimp_w w, wimp_i i) void ro_gui_menu_selection(wimp_selection *selection) { - char url[80]; + struct toolbar_icon *icon; + struct toolbar_icon *next; + char url[80]; wimp_pointer pointer; wimp_window_state state; os_error *error; @@ -695,6 +774,66 @@ void ro_gui_menu_selection(wimp_selection *selection) break; } + } else if (current_menu == toolbar_menu) { + switch (selection->items[0]) { + case 0: /* Icons-> */ + if (selection->items[1] == -1) break; + next = current_toolbar->icon; + while ((icon = next) != NULL) { + next = icon->next; + if (icon->icon_number == selection->items[1]) { + icon->display = !icon->display; + } + } + current_toolbar->reformat_buttons = true; + height = current_toolbar->height; + ro_gui_theme_process_toolbar(current_toolbar, -1); + if ((height != current_toolbar->height) && (current_gui)) + ro_gui_window_update_dimensions(current_gui, + height - current_toolbar->height); + if ((height != current_toolbar->height) && + (current_toolbar == hotlist_toolbar)) { + xwimp_force_redraw(hotlist_window, 0, -16384, 16384, 16384); + } + ro_gui_menu_prepare_theme(); + + break; + case 1: /* Toolbars-> */ + switch (selection->items[1]) { + case 0: + current_toolbar->display_buttons = + !current_toolbar->display_buttons; + break; + case 1: + current_toolbar->display_url = + !current_toolbar->display_url; + break; + case 2: + current_toolbar->display_throbber = + !current_toolbar->display_throbber; + break; + case 3: + current_toolbar->display_status = + !current_toolbar->display_status; + break; + } + current_toolbar->reformat_buttons = true; + height = current_toolbar->height; + ro_gui_theme_process_toolbar(current_toolbar, -1); + if ((height != current_toolbar->height) && (current_gui)) + ro_gui_window_update_dimensions(current_gui, + height - current_toolbar->height); + ro_gui_menu_prepare_theme(); + break; + case 2: /* Add separator */ + break; + case 3: /* Remove separator */ + break; + case 4: /* Lock toolbar */ + current_toolbar->locked = !current_toolbar->locked; + ro_gui_menu_prepare_theme(); + break; + } } else if (current_menu == hotlist_menu) { switch (selection->items[0]) { case 0: /* Hotlist-> */ @@ -1398,7 +1537,7 @@ void ro_gui_prepare_navigate(struct gui_window *gui) { /* Set the scale view icon */ if (c) { - if (update_menu) menu.entries[0].icon_flags &= ~wimp_ICON_SHADED; + if (update_menu) menu.entries[0].icon_flags &= ~wimp_ICON_SHADED; if (t) { ro_gui_set_icon_shaded_state(t->toolbar_handle, ICON_TOOLBAR_SEARCH, false); ro_gui_set_icon_shaded_state(t->toolbar_handle, ICON_TOOLBAR_SCALE, false); @@ -1406,7 +1545,7 @@ void ro_gui_prepare_navigate(struct gui_window *gui) { ro_gui_set_icon_shaded_state(t->toolbar_handle, ICON_TOOLBAR_PRINT, false); } } else { - if (update_menu) menu.entries[0].icon_flags |= wimp_ICON_SHADED; + if (update_menu) menu.entries[0].icon_flags |= wimp_ICON_SHADED; if (t) { ro_gui_set_icon_shaded_state(t->toolbar_handle, ICON_TOOLBAR_SEARCH, true); ro_gui_set_icon_shaded_state(t->toolbar_handle, ICON_TOOLBAR_SCALE, true); @@ -1529,13 +1668,82 @@ static void ro_gui_menu_prepare_window(void) { /** * Update toolbar menu status */ +static void ro_gui_menu_prepare_theme(void) { + struct toolbar_icon *icon; + struct toolbar_icon *next; + wimp_menu *sub_menu; + + if (!current_toolbar) return; + + /* Set the icon states + */ + if (current_toolbar->display_buttons) { + toolbar_menu->entries[0].icon_flags &= ~wimp_ICON_SHADED; + toolbar_menu->entries[2].icon_flags &= ~wimp_ICON_SHADED; + toolbar_menu->entries[3].icon_flags &= ~wimp_ICON_SHADED; + if (current_toolbar->type == THEME_BROWSER_TOOLBAR) { + toolbar_menu->entries[0].sub_menu = toolbar_browser_menu; + } else if (current_toolbar->type == THEME_HOTLIST_TOOLBAR) { + toolbar_menu->entries[0].sub_menu = toolbar_hotlist_menu; + } else { + LOG(("Unknown toolbar type")); + return; /* unknown toolbar type */ + } + sub_menu = toolbar_menu->entries[0].sub_menu; + next = current_toolbar->icon; + while ((icon = next) != NULL) { + next = icon->next; + if (icon->icon_number >= 0) { + if (icon->width == 0) { + sub_menu->entries[icon->icon_number].icon_flags |= + wimp_ICON_SHADED; + sub_menu->entries[icon->icon_number].menu_flags &= + ~wimp_MENU_TICKED; + } else { + if (icon->display) { + sub_menu->entries[icon->icon_number].menu_flags |= + wimp_MENU_TICKED; + } else { + sub_menu->entries[icon->icon_number].menu_flags &= + ~wimp_MENU_TICKED; + } + } + } + } + } else { + toolbar_menu->entries[0].icon_flags |= wimp_ICON_SHADED; + toolbar_menu->entries[2].icon_flags |= wimp_ICON_SHADED; + toolbar_menu->entries[3].icon_flags |= wimp_ICON_SHADED; + } + + /* Set the toolbars submenu state + */ + if (current_gui) { + toolbar_menu->entries[1].icon_flags &= ~wimp_ICON_SHADED; + ro_gui_menu_prepare_toolbars(); + } else { + toolbar_menu->entries[1].icon_flags |= wimp_ICON_SHADED; + } + + /* Set the locked state + */ + if (current_toolbar->locked) { + toolbar_menu->entries[4].menu_flags |= wimp_MENU_TICKED; + } else { + toolbar_menu->entries[4].menu_flags &= ~wimp_MENU_TICKED; + } +} + +/** + * Update toolbar menu status + */ static void ro_gui_menu_prepare_toolbars(void) { int index; struct toolbar *toolbar; - if (current_menu != browser_menu) return; /* Check we have a toolbar */ + if (!current_gui) return; toolbar = current_gui->toolbar; /* Set our ticks, or shade everything if there's no toolbar @@ -1545,7 +1753,7 @@ static void ro_gui_menu_prepare_toolbars(void) { browser_toolbar_menu->entries[index].icon_flags &= ~wimp_ICON_SHADED; browser_toolbar_menu->entries[index].menu_flags &= ~wimp_MENU_TICKED; } - if ((toolbar->descriptor) && (toolbar->descriptor->theme)) { + if ((toolbar->descriptor) && (toolbar->descriptor->theme)) { if (toolbar->display_buttons) browser_toolbar_menu->entries[0].menu_flags |= wimp_MENU_TICKED; if (toolbar->display_throbber) browser_toolbar_menu->entries[2].menu_flags |= wimp_MENU_TICKED; } else { @@ -1720,7 +1928,7 @@ void ro_gui_menu_object_reload(void) /** * Display a menu of options for a form select control. * - * \param bw browser window containing form control + * \param bw browser window containing form control * \param control form control of type GADGET_SELECT */ diff --git a/riscos/options.h b/riscos/options.h index b7b22d64f..66970ca28 100644 --- a/riscos/options.h +++ b/riscos/options.h @@ -40,7 +40,6 @@ extern int option_window_screen_width; extern int option_window_screen_height; extern bool option_window_stagger; extern bool option_window_size_clone; -extern int option_minimum_gif_delay; extern bool option_background_images; extern bool option_background_blending; extern bool option_buffer_animations; @@ -99,7 +98,6 @@ int option_window_screen_width = 0; \ int option_window_screen_height = 0; \ bool option_window_stagger = true; \ bool option_window_size_clone = true; \ -int option_minimum_gif_delay = 10; \ bool option_background_images = true; \ bool option_background_blending = true; \ bool option_buffer_animations = true; \ @@ -158,7 +156,6 @@ bool option_font_ufont = false; { "window_screen_height", OPTION_INTEGER, &option_window_screen_height }, \ { "window_stagger", OPTION_BOOL, &option_window_stagger }, \ { "window_size_clone", OPTION_BOOL, &option_window_size_clone }, \ -{ "minimum_gif_delay", OPTION_INTEGER, &option_minimum_gif_delay }, \ { "background_images", OPTION_BOOL, &option_background_images }, \ { "background_blending", OPTION_BOOL, &option_background_blending }, \ { "buffer_animations", OPTION_BOOL, &option_buffer_animations }, \ diff --git a/riscos/save_draw.c b/riscos/save_draw.c index 297cc34d2..b4e775532 100644 --- a/riscos/save_draw.c +++ b/riscos/save_draw.c @@ -725,7 +725,7 @@ static bool add_graphic(struct content *content, struct box *box, #endif #ifdef WITH_GIF case CONTENT_GIF: - sprite_length = ((osspriteop_header*)((char*)content->data.gif.gif->frame_image+content->data.gif.gif->frame_image->first))->size; + sprite_length = ((osspriteop_header*)((char*)&content->bitmap->sprite_area+content->bitmap->sprite_area.first))->size; break; #endif #ifdef WITH_SPRITE @@ -768,7 +768,7 @@ static bool add_graphic(struct content *content, struct box *box, #endif #ifdef WITH_GIF case CONTENT_GIF: - memcpy((char*)ds+16, (char*)content->data.gif.gif->frame_image+content->data.gif.gif->frame_image->first, (unsigned)sprite_length); + memcpy((char*)ds+16, (char*)&content->bitmap->sprite_area+content->bitmap->sprite_area.first, (unsigned)sprite_length); break; #endif #ifdef WITH_SPRITE diff --git a/riscos/theme.c b/riscos/theme.c index 8d9b1378f..62488f1dd 100644 --- a/riscos/theme.c +++ b/riscos/theme.c @@ -35,16 +35,6 @@ #define THEME_THROBBER_MEMORY 12 #define THEME_STATUS_MEMORY 256 -struct toolbar_icon { - int icon_number; /**< wimp icon number */ - bool display; /**< whether to display the icon */ - int width; /**< icon width */ - int height; /**< icon height */ - char name[12]; /**< icon name */ - char validation[40]; /**< validation string */ - struct toolbar_icon *next; /**< next toolbar icon, or NULL for no more */ -}; - struct theme_file_header { unsigned int magic_value; unsigned int parser_version; @@ -96,8 +86,8 @@ static wimp_window theme_toolbar_window = { 12, 1, {""}, - 0/*, - { } */ + 0, + { } }; @@ -763,7 +753,7 @@ bool ro_gui_theme_update_toolbar(struct theme_descriptor *descriptor, struct too new_icon.icon.data.indirected_text.size = 1; new_icon.icon.flags = wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_INDIRECTED | wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | - (wimp_BUTTON_CLICK << wimp_ICON_BUTTON_TYPE_SHIFT); + (wimp_BUTTON_RELEASE_DRAG << wimp_ICON_BUTTON_TYPE_SHIFT); if (toolbar->descriptor) { new_icon.icon.flags |= (toolbar->descriptor->browser_background << wimp_ICON_BG_COLOUR_SHIFT); @@ -1024,8 +1014,30 @@ bool ro_gui_theme_process_toolbar(struct toolbar *toolbar, int width) { int old_height = toolbar->height; int old_width = toolbar->toolbar_current; struct toolbar_icon *toolbar_icon; + struct toolbar_icon *last_icon = NULL; bool visible_icon = false; + /* Disable lone separators + */ + if (toolbar->reformat_buttons) { + visible_icon = false; + toolbar_icon = toolbar->icon; + while (toolbar_icon) { + if (toolbar_icon->icon_number < 0) { + toolbar_icon->display = visible_icon; + visible_icon = false; + } else if (toolbar_icon->width > 0) { + visible_icon |= toolbar_icon->display; + } + if (toolbar_icon->display) last_icon = toolbar_icon; + toolbar_icon = toolbar_icon->next; + } + if ((last_icon) && (last_icon->icon_number < 0)) { + last_icon->display = false; + } + visible_icon = false; + } + /* Find the parent window handle if we need to process the status window, or the caller has requested we calculate the width ourself. */ @@ -1129,6 +1141,8 @@ bool ro_gui_theme_process_toolbar(struct toolbar *toolbar, int width) { visible_icon = true; bottom_edge = (toolbar->height - toolbar_icon->height) / 2; + toolbar_icon->x = left_edge; + toolbar_icon->y = bottom_edge; xwimp_resize_icon(toolbar->toolbar_handle, toolbar_icon->icon_number, left_edge, bottom_edge, @@ -1313,6 +1327,14 @@ void ro_gui_theme_destroy_toolbar(struct toolbar *toolbar) { free(toolbar); } + +/** + * Adds a toolbar icon to the end of a toolbar + * + * \param toolbar the toolbar to add the icon to the end of + * \param name the icon name, or NULL for a separator + * \param icon_number the RISC OS Wimp icon number for the icon (not used for separators) + */ void ro_gui_theme_add_toolbar_icon(struct toolbar *toolbar, const char *name, int icon_number) { if (!toolbar) return; struct toolbar_icon *toolbar_icon; @@ -1320,7 +1342,10 @@ void ro_gui_theme_add_toolbar_icon(struct toolbar *toolbar, const char *name, in /* Separators are really a sprite called "separator" */ - if (name == NULL) name = "separator"; + if (name == NULL) { + name = "separator"; + icon_number = -1; + } /* Create a new toolbar */ @@ -1405,3 +1430,33 @@ void ro_gui_theme_update_toolbar_icon(struct toolbar *toolbar, struct toolbar_ic void ro_gui_theme_destroy_toolbar_icon(struct toolbar_icon *icon) { free(icon); } + + +/** + * Returns the toolbar icon at a specified position + * + * \param toolbar the toolbar to examine + * \param x the x co-ordinate to check + * \param y the y co-ordinate to check + * \return the toolbar icon at the specified position, or NULL for no icon + */ +struct toolbar_icon *ro_gui_theme_toolbar_get_icon(struct toolbar *toolbar, int x, int y) { + struct toolbar_icon *icon; + icon = toolbar->icon; +/* FINISH ME */ + return NULL; +} + +/** + * Returns whether a separator can follow the specified icon + * + * \param icon the icon to check + * \return whether a separator can follow + */ +bool ro_gui_theme_toolbar_separator_following(struct toolbar_icon *icon) { + while (icon) { + if (icon->display) return (icon->width > 0); + icon = icon->next; + } + return false; +} diff --git a/riscos/theme.h b/riscos/theme.h index 1ab6793e3..8e34ff66b 100644 --- a/riscos/theme.h +++ b/riscos/theme.h @@ -19,7 +19,17 @@ typedef enum { THEME_HOTLIST_TOOLBAR } toolbar_type; -struct toolbar_icon; +struct toolbar_icon { + int icon_number; /**< wimp icon number */ + bool display; /**< whether to display the icon */ + int x; /**< icon x position (valid only when displayed) */ + int y; /**< icon y position (valid only when displayed) */ + int width; /**< icon width */ + int height; /**< icon height */ + char name[12]; /**< icon name */ + char validation[40]; /**< validation string */ + struct toolbar_icon *next; /**< next toolbar icon, or NULL for no more */ +}; struct theme { osspriteop_area *sprite_area; /**< sprite area for theme */ @@ -48,6 +58,7 @@ struct toolbar { struct toolbar_icon *icon; /**< first toolbar icon (read only) */ struct theme_descriptor *descriptor; /**< theme descriptor (read only) */ toolbar_type type; /**< toolbar type (read only) */ + bool locked; /**< toolbar is locked from editing */ }; struct theme_descriptor { @@ -82,5 +93,7 @@ void ro_gui_theme_resize_toolbar_status(struct toolbar *toolbar); bool ro_gui_theme_process_toolbar(struct toolbar *toolbar, int width); void ro_gui_theme_destroy_toolbar(struct toolbar *toolbar); +struct toolbar_icon *ro_gui_theme_toolbar_get_icon(struct toolbar *toolbar, int x, int y); +bool ro_gui_theme_toolbar_separator_following(struct toolbar_icon *icon); #endif diff --git a/riscos/window.c b/riscos/window.c index 9f0c7dcf6..a1e9ff8bc 100644 --- a/riscos/window.c +++ b/riscos/window.c @@ -1064,10 +1064,17 @@ void ro_gui_toolbar_click(struct gui_window *g, wimp_pointer *pointer) { char url[80]; - /* Reject Menu clicks + /* Store the toolbar */ - if (pointer->buttons == wimp_CLICK_MENU) + current_toolbar = g->toolbar; + + /* Handle Menu clicks + */ + if (pointer->buttons == wimp_CLICK_MENU) { + ro_gui_create_menu(toolbar_menu, pointer->pos.x, + pointer->pos.y, g); return; + } /* Handle the buttons appropriately */ |