[project @ 2004-10-04 23:54:42 by rjw]

Moved GIF file reading to image/, optimisation of plotting for GIFs, JNGs, PNGs and JPEGs, initial work for toolbar customisation. Possibly some other things too.

svn path=/import/netsurf/; revision=1301
This commit is contained in:
Richard Wilson 2004-10-04 23:54:42 +00:00
parent 7144ce65eb
commit 403f12872d
27 changed files with 568 additions and 238 deletions

View File

@ -78,6 +78,29 @@ ProxyNone:None
ProxyBasic:Basic ProxyBasic:Basic
ProxyNTLM:NTLM 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 menus
Hotlist:Hotlist Hotlist:Hotlist
New:New New:New

Binary file not shown.

View File

@ -33,7 +33,7 @@
#include "netsurf/image/mng.h" #include "netsurf/image/mng.h"
#endif #endif
#ifdef WITH_GIF #ifdef WITH_GIF
#include "netsurf/riscos/gif.h" #include "netsurf/image/gif.h"
#endif #endif
#ifdef WITH_SPRITE #ifdef WITH_SPRITE
#include "netsurf/riscos/sprite.h" #include "netsurf/riscos/sprite.h"

View File

@ -105,7 +105,7 @@
#include "netsurf/image/jpeg.h" #include "netsurf/image/jpeg.h"
#endif #endif
#ifdef WITH_GIF #ifdef WITH_GIF
#include "netsurf/riscos/gif.h" #include "netsurf/image/gif.h"
#endif #endif
#ifdef WITH_PLUGIN #ifdef WITH_PLUGIN
#include "netsurf/riscos/plugin.h" #include "netsurf/riscos/plugin.h"

View File

@ -53,6 +53,8 @@ bool option_ssl_verify_certificates = true;
int option_memory_cache_size = 2 * 1024 * 1024; int option_memory_cache_size = 2 * 1024 * 1024;
/** Whether to block advertisements */ /** Whether to block advertisements */
bool option_block_ads = false; bool option_block_ads = false;
/** Minimum GIF animation delay */
int option_minimum_gif_delay = 10;
/** Whether to send the referer HTTP header */ /** Whether to send the referer HTTP header */
bool option_send_referer = true; bool option_send_referer = true;
@ -76,6 +78,7 @@ struct {
{ "ssl_verify_certificates", OPTION_BOOL, &option_ssl_verify_certificates }, { "ssl_verify_certificates", OPTION_BOOL, &option_ssl_verify_certificates },
{ "memory_cache_size", OPTION_INTEGER, &option_memory_cache_size }, { "memory_cache_size", OPTION_INTEGER, &option_memory_cache_size },
{ "block_advertisements", OPTION_BOOL, &option_block_ads }, { "block_advertisements", OPTION_BOOL, &option_block_ads },
{ "minimum_gif_delay", OPTION_INTEGER, &option_minimum_gif_delay },
{ "send_referer", OPTION_BOOL, &option_send_referer }, { "send_referer", OPTION_BOOL, &option_send_referer },
EXTRA_OPTION_TABLE EXTRA_OPTION_TABLE
}; };

View File

@ -39,6 +39,7 @@ extern char *option_accept_language;
extern bool option_ssl_verify_certificates; extern bool option_ssl_verify_certificates;
extern int option_memory_cache_size; extern int option_memory_cache_size;
extern bool option_block_ads; extern bool option_block_ads;
extern int option_minimum_gif_delay;
extern bool option_send_referer; extern bool option_send_referer;
void options_read(const char *path); void options_read(const char *path);

View File

@ -43,6 +43,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. * Return a pointer to the pixel data in a bitmap.
* *

View File

@ -26,6 +26,8 @@ struct content;
struct bitmap; struct bitmap;
struct bitmap *bitmap_create(int width, int height); 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); char *bitmap_get_buffer(struct bitmap *bitmap);
size_t bitmap_get_rowstride(struct bitmap *bitmap); size_t bitmap_get_rowstride(struct bitmap *bitmap);
void bitmap_destroy(struct bitmap *bitmap); void bitmap_destroy(struct bitmap *bitmap);

View File

@ -3,7 +3,7 @@
* Licensed under the GNU General Public License, * Licensed under the GNU General Public License,
* http://www.opensource.org/licenses/gpl-license * http://www.opensource.org/licenses/gpl-license
* Copyright 2003 John M Bell <jmb202@ecs.soton.ac.uk> * 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> #include <assert.h>
@ -14,11 +14,11 @@
#include "oslib/osspriteop.h" #include "oslib/osspriteop.h"
#include "netsurf/utils/config.h" #include "netsurf/utils/config.h"
#include "netsurf/content/content.h" #include "netsurf/content/content.h"
#include "netsurf/riscos/gif.h" #include "netsurf/desktop/browser.h"
#include "netsurf/riscos/gifread.h" #include "netsurf/desktop/options.h"
#include "netsurf/riscos/gui.h" #include "netsurf/image/bitmap.h"
#include "netsurf/riscos/image.h" #include "netsurf/image/gif.h"
#include "netsurf/riscos/options.h" #include "netsurf/image/gifread.h"
#include "netsurf/utils/log.h" #include "netsurf/utils/log.h"
#include "netsurf/utils/messages.h" #include "netsurf/utils/messages.h"
#include "netsurf/utils/utils.h" #include "netsurf/utils/utils.h"
@ -115,6 +115,7 @@ bool nsgif_convert(struct content *c, int iwidth, int iheight) {
/* Exit as a success /* Exit as a success
*/ */
c->bitmap = gif->frame_image;
c->status = CONTENT_STATUS_DONE; c->status = CONTENT_STATUS_DONE;
return true; 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 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. 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) { if (ro_gui_current_redraw_gui->option.animate_images) {
current_frame = c->data.gif.current_frame; */ current_frame = c->data.gif.current_frame;
} else { /* } else {
current_frame = 0; current_frame = 0;
} }
} else { } else {
@ -149,23 +150,22 @@ bool nsgif_redraw(struct content *c, int x, int y,
} }
} }
} }
*/
/* Decode from the last frame to the current frame /* Decode from the last frame to the current frame
*/ */
if (current_frame < c->data.gif.gif->decoded_frame) { if (current_frame < c->data.gif.gif->decoded_frame) {
previous_frame = 0; previous_frame = 0;
} else { } else {
previous_frame = c->data.gif.gif->decoded_frame + 1; previous_frame = c->data.gif.gif->decoded_frame + 1;
} }
for (frame = previous_frame; frame <= current_frame; frame++) { for (frame = previous_frame; frame <= current_frame; frame++) {
gif_decode_frame(c->data.gif.gif, 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, return bitmap_redraw(c, x, y, width, height,
height, c->width * 2, c->height * 2, clip_x0, clip_y0, clip_x1, clip_y1,
background_colour, false, false, scale, background_colour);
IMAGE_PLOT_TINCT_ALPHA);
} }

View File

@ -2,26 +2,19 @@
* This file is part of NetSurf, http://netsurf.sourceforge.net/ * This file is part of NetSurf, http://netsurf.sourceforge.net/
* Licensed under the GNU General Public License, * Licensed under the GNU General Public License,
* http://www.opensource.org/licenses/gpl-license * http://www.opensource.org/licenses/gpl-license
* Copyright 2003 Philip Pemberton <philpem@users.sourceforge.net> * Copyright 2004 Richard Wilson <not_ginger_matt@users.sourceforge.net>
* Copyright 2004 Richard Wilson <not_ginger_matt@sourceforge.net>
*/ */
#ifndef _NETSURF_RISCOS_GIF_H_ #ifndef _NETSURF_IMAGE_GIF_H_
#define _NETSURF_RISCOS_GIF_H_ #define _NETSURF_IMAGE_GIF_H_
#include "netsurf/riscos/gifread.h" #include "netsurf/image/gifread.h"
struct content; struct content;
struct content_gif_data { struct content_gif_data {
struct gif_animation *gif; /**< GIF animation data */
/* The GIF data unsigned int current_frame; /**< current frame to display [0...(max-1)] */
*/
struct gif_animation *gif;
/** The current frame number of the GIF to display, [0...(max-1)]
*/
unsigned int current_frame;
}; };
bool nsgif_create(struct content *c, const char *params[]); bool nsgif_create(struct content *c, const char *params[]);

View File

@ -2,14 +2,16 @@
* This file is part of NetSurf, http://netsurf.sourceforge.net/ * This file is part of NetSurf, http://netsurf.sourceforge.net/
* Licensed under the GNU General Public License, * Licensed under the GNU General Public License,
* http://www.opensource.org/licenses/gpl-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 <stdio.h>
#include <string.h> #include <string.h>
#include <stdlib.h> #include <stdlib.h>
#include "gifread.h" #include "gifread.h"
#include "netsurf/image/bitmap.h"
#include "netsurf/utils/log.h" #include "netsurf/utils/log.h"
#include "oslib/osspriteop.h" #include "oslib/osspriteop.h"
#include "oslib/osfile.h" #include "oslib/osfile.h"
@ -110,7 +112,6 @@ int gif_initialise(struct gif_animation *gif) {
unsigned int index; unsigned int index;
int return_value; int return_value;
unsigned int frame; unsigned int frame;
osspriteop_header *header;
/* Check for sufficient data to be a GIF /* 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)) || if (((gif->width == 640) && (gif->width == 480)) ||
((gif->width == 640) && (gif->width == 512)) || ((gif->width == 640) && (gif->width == 512)) ||
((gif->width == 800) && (gif->width == 600)) || ((gif->width == 800) && (gif->width == 600)) ||
((gif->width == 1280) && (gif->width == 1024))) { ((gif->width == 1024) && (gif->width == 768)) ||
gif->width = 0; ((gif->width == 1280) && (gif->width == 1024)) ||
gif->height = 0; ((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 /* 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 /* Initialise the sprite header
*/ */
if ((gif->frame_image = (osspriteop_area *)malloc(sizeof(osspriteop_area) + if ((gif->frame_image = bitmap_create(gif->width, gif->height)) == NULL) {
sizeof(osspriteop_header) + (gif->width * gif->height * 4))) == NULL) {
gif_finalise(gif); gif_finalise(gif);
return GIF_INSUFFICIENT_MEMORY; 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 /* Remember we've done this now
*/ */
@ -334,11 +319,9 @@ int gif_initialise(struct gif_animation *gif) {
0 for success 0 for success
*/ */
static int gif_initialise_sprite(struct gif_animation *gif, unsigned int width, unsigned int height) { 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_width;
unsigned int max_height; unsigned int max_height;
unsigned int frame_bytes; struct bitmap *buffer;
/* Check if we've changed /* 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_width = (width > gif->width) ? width : gif->width;
max_height = (height > gif->height) ? height : gif->height; 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 /* 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; return GIF_INSUFFICIENT_MEMORY;
} }
bitmap_destroy(gif->frame_image);
gif->frame_image = buffer; 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 /* Invalidate our currently decoded image
*/ */
gif->decoded_frame = 0xffffffff; 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. start off with one frame allocated so we can always use realloc.
*/ */
gif->frames[frame].frame_pointer = gif->buffer_position; gif->frames[frame].frame_pointer = gif->buffer_position;
gif->frames[frame].virgin = true;
gif->frames[frame].frame_delay = 100; // Paranoia gif->frames[frame].frame_delay = 100; // Paranoia
gif->frames[frame].redraw_required = 0; // 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 sprite and clear what we need as some frames have multiple images which would
produce errors. 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 (!clear_image) {
if ((frame == 0) || (gif->decoded_frame == 0xffffffff)) { if ((frame == 0) || (gif->decoded_frame == 0xffffffff)) {
memset((char*)frame_data, 0x00, gif->width * gif->height * sizeof(int)); 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; if ((gif_bytes < 1) || (gif_data[0] == 0x3b)) more_images = 0;
gif->buffer_position++; 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 /* Restore the buffer position
*/ */

75
image/gifread.h Normal file
View File

@ -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

View File

@ -102,6 +102,7 @@ bool nsjpeg_convert(struct content *c, int w, int h)
warn_user("NoMemory", 0); warn_user("NoMemory", 0);
return false; return false;
} }
bitmap_set_opaque(bitmap, true);
pixels = bitmap_get_buffer(bitmap); pixels = bitmap_get_buffer(bitmap);
rowstride = bitmap_get_rowstride(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 + 0] = r;
scanlines[0][i * 4 + 1] = g; scanlines[0][i * 4 + 1] = g;
scanlines[0][i * 4 + 2] = b; scanlines[0][i * 4 + 2] = b;
scanlines[0][i * 4 + 3] = 0xff; /* 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;
} }
#endif #endif
} while (cinfo.output_scanline != cinfo.output_height); } while (cinfo.output_scanline != cinfo.output_height);

View File

@ -258,6 +258,12 @@ bool nsmng_convert(struct content *c, int width, int height) {
LOG(("Unable to start display (%i)", status)); LOG(("Unable to start display (%i)", status));
return nsmng_broadcast_error(c); 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; return true;
} }

View File

@ -156,6 +156,7 @@ void info_callback(png_structp png, png_infop info)
c->data.png.interlace = (interlace == PNG_INTERLACE_ADAM7); c->data.png.interlace = (interlace == PNG_INTERLACE_ADAM7);
c->width = width; c->width = width;
c->height = height; c->height = height;
bitmap_set_opaque(c->bitmap, bitmap_test_opaque(c->bitmap));
LOG(("size %li * %li, bpp %i, rowbytes %u", width, LOG(("size %li * %li, bpp %i, rowbytes %u", width,
height, bit_depth, rowbytes)); height, bit_depth, rowbytes));

View File

@ -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 += messages.o pool.o translit.o url.o utils.o # utils/
OBJECTS_COMMON += imagemap.o loginlist.o options.o # desktop/ 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 = $(OBJECTS_COMMON) $(OBJECTS_IMAGE)
OBJECTS_RISCOS += browser.o netsurf.o version.o # desktop/ OBJECTS_RISCOS += browser.o netsurf.o version.o # desktop/
OBJECTS_RISCOS += 401login.o bitmap.o debugwin.o \ OBJECTS_RISCOS += 401login.o bitmap.o debugwin.o \
buffer.o dialog.o download.o draw.o filetype.o font.o gif.o \ buffer.o dialog.o download.o draw.o filetype.o font.o \
gifread.o gui.o help.o history.o hotlist.o htmlredraw.o image.o \ gui.o help.o history.o hotlist.o htmlredraw.o image.o \
menus.o mouseactions.o plugin.o print.o \ menus.o mouseactions.o plugin.o print.o \
save.o save_complete.o save_draw.o save_text.o \ save.o save_complete.o save_draw.o save_text.o \
schedule.o search.o sprite.o textselection.o theme.o thumbnail.o \ schedule.o search.o sprite.o textselection.o theme.o thumbnail.o \

View File

@ -39,8 +39,11 @@ struct bitmap *bitmap_create(int width, int height)
osspriteop_area *sprite_area; osspriteop_area *sprite_area;
osspriteop_header *sprite; osspriteop_header *sprite;
if ((width == 0) || (height == 0))
return NULL;
area_size = 16 + 44 + width * height * 4; area_size = 16 + 44 + width * height * 4;
bitmap = calloc(area_size, 1); bitmap = calloc(sizeof(struct bitmap) + area_size, 1);
if (!bitmap) if (!bitmap)
return NULL; return NULL;
@ -54,7 +57,7 @@ struct bitmap *bitmap_create(int width, int height)
/* sprite control block */ /* sprite control block */
sprite = (osspriteop_header *) (sprite_area + 1); sprite = (osspriteop_header *) (sprite_area + 1);
sprite->size = area_size - 16; sprite->size = area_size - 16;
memset(sprite->name, 0x00, 12); /* memset(sprite->name, 0x00, 12); */
strncpy(sprite->name, "bitmap", 12); strncpy(sprite->name, "bitmap", 12);
sprite->width = width - 1; sprite->width = width - 1;
sprite->height = height - 1; sprite->height = height - 1;
@ -67,6 +70,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. * Return a pointer to the pixel data in a bitmap.
* *
@ -80,7 +117,7 @@ struct bitmap *bitmap_create(int width, int height)
char *bitmap_get_buffer(struct bitmap *bitmap) char *bitmap_get_buffer(struct bitmap *bitmap)
{ {
assert(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, return image_redraw(&(c->bitmap->sprite_area), x, y, width, height,
c->width * 2, c->height * 2, background_colour, 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));
} }

View File

@ -11,6 +11,7 @@
struct osspriteop_area; struct osspriteop_area;
struct bitmap { struct bitmap {
bool opaque;
osspriteop_area sprite_area; osspriteop_area sprite_area;
}; };

View File

@ -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

View File

@ -32,7 +32,7 @@ extern wimp_w dialog_info, dialog_saveas, dialog_config, dialog_config_br,
extern wimp_w history_window; extern wimp_w history_window;
extern wimp_w hotlist_window; extern wimp_w hotlist_window;
extern wimp_menu *iconbar_menu, *browser_menu, *combo_menu, *hotlist_menu, 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 int iconbar_menu_height;
extern struct form_control *current_gadget; extern struct form_control *current_gadget;
extern bool gui_reformat_pending; 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 *current_gui;
extern struct gui_window *ro_gui_current_redraw_gui; extern struct gui_window *ro_gui_current_redraw_gui;
extern struct gui_window *ro_gui_current_zoom_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_BOOKMARK 8
#define ICON_TOOLBAR_SCALE 9 #define ICON_TOOLBAR_SCALE 9
#define ICON_TOOLBAR_SEARCH 10 #define ICON_TOOLBAR_SEARCH 10
#define ICON_TOOLBAR_UP 11 #define ICON_TOOLBAR_URL 11 // Must be after highest toolbar icon
#define ICON_TOOLBAR_URL 12 // Must be after highest toolbar icon #define ICON_TOOLBAR_THROBBER 12
#define ICON_TOOLBAR_THROBBER 13
/* icon numbers for hotlist toolbars */ /* icon numbers for hotlist toolbars */
#define ICON_TOOLBAR_CREATE 0 #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_EXPAND 2
#define ICON_TOOLBAR_OPEN 3 #define ICON_TOOLBAR_OPEN 3
#define ICON_TOOLBAR_LAUNCH 4 #define ICON_TOOLBAR_LAUNCH 4
#define ICON_TOOLBAR_SORT 5 #define ICON_TOOLBAR_HOTLIST_LAST 5
#define ICON_TOOLBAR_HOTLIST_LAST 6
/* icon numbers for toolbar status window */ /* icon numbers for toolbar status window */
#define ICON_STATUS_RESIZE 0 #define ICON_STATUS_RESIZE 0

View File

@ -2296,9 +2296,17 @@ bool ro_gui_hotlist_keypress(int key) {
void ro_gui_hotlist_toolbar_click(wimp_pointer* pointer) { void ro_gui_hotlist_toolbar_click(wimp_pointer* pointer) {
int selection; 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 /* Handle the buttons appropriately
*/ */

View File

@ -48,6 +48,7 @@ static void translate_menu(wimp_menu *menu);
static void build_languages_menu(void); static void build_languages_menu(void);
static void ro_gui_menu_prepare_images(void); static void ro_gui_menu_prepare_images(void);
static void ro_gui_menu_prepare_window(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_toolbars(void);
static void ro_gui_menu_prepare_render(void); static void ro_gui_menu_prepare_render(void);
static void ro_gui_menu_prepare_help(int forced); static void ro_gui_menu_prepare_help(int forced);
@ -196,7 +197,7 @@ static wimp_MENU(5) image_menu = {
/* Toolbar submenu /* Toolbar submenu
*/ */
static wimp_MENU(4) toolbar_menu = { static wimp_MENU(4) show_toolbar_menu = {
{ "Toolbars" }, 7,2,7,0, 300, 44, 0, { "Toolbars" }, 7,2,7,0, 300, 44, 0,
{ {
{ 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "ToolButtons" } }, { 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, { "All" } },
{ 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "Folders" } }, { 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, { "All" } },
{ 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "Folders" } }, { 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, { "URI" } },
{ wimp_MENU_GIVE_WARNING, (wimp_menu*)1, DEFAULT_FLAGS, { "URL" } }, { 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_NO_SUB_MENU, DEFAULT_FLAGS, { "Save" } },
{ wimp_MENU_GIVE_WARNING | wimp_MENU_SEPARATE, (wimp_menu *)1, DEFAULT_FLAGS, { "Export" } }, { wimp_MENU_GIVE_WARNING | wimp_MENU_SEPARATE, (wimp_menu *)1, DEFAULT_FLAGS, { "Export" } },
{ 0, (wimp_menu *)&hotlist_expand, DEFAULT_FLAGS, { "Expand" } }, { 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" } }, { 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, { "Launch" } },
{ 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "Delete" } }, { 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" } }, { 0, (wimp_menu *)&hotlist_file, DEFAULT_FLAGS, { "Hotlist" } },
{ wimp_MENU_GIVE_WARNING, (wimp_menu *)&hotlist_select, DEFAULT_FLAGS, { "Selection" } }, { wimp_MENU_GIVE_WARNING, (wimp_menu *)&hotlist_select, DEFAULT_FLAGS, { "Selection" } },
{ 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "SelectAll" } }, { 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; 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 = { static wimp_MENU(3) proxy_menu = {
{ "ProxyAuth" }, 7,2,7,0, 200, 44, 0, { "ProxyAuth" }, 7,2,7,0, 200, 44, 0,
{ {
{ 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "ProxyNone" } }, { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "ProxyNone" } },
{ 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "ProxyBasic" } }, { 0, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "ProxyBasic" } },
{ wimp_MENU_LAST, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "ProxyNTLM" } }, { wimp_MENU_LAST, wimp_NO_SUB_MENU, DEFAULT_FLAGS, { "ProxyNTLM" } }
} }
}; };
wimp_menu *proxyauth_menu = (wimp_menu *) &proxy_menu; 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) /* Languages popup menu (used in browser choices dialog)
*/ */
wimp_menu *languages_menu = NULL; wimp_menu *languages_menu = NULL;
/* Toolbar menu
*/
wimp_menu *toolbar_icon_menu = NULL;
/* Font popup menu (used in font choices dialog) /* Font popup menu (used in font choices dialog)
*/ */
static wimp_menu *font_menu = NULL; 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_navigate_menu = (wimp_menu *)&navigate_menu;
static wimp_menu *browser_view_menu = (wimp_menu *)&view_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_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_render_menu = (wimp_menu *)&render_menu;
static wimp_menu *browser_window_menu = (wimp_menu *)&window_menu; static wimp_menu *browser_window_menu = (wimp_menu *)&window_menu;
static wimp_menu *browser_utilities_menu = (wimp_menu *)&utilities_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_save_menu);
translate_menu(hotlist_select_menu); translate_menu(hotlist_select_menu);
translate_menu(toolbar_menu);
translate_menu(toolbar_browser_menu);
translate_menu(toolbar_hotlist_menu);
translate_menu(proxyauth_menu); translate_menu(proxyauth_menu);
build_languages_menu(); build_languages_menu();
@ -565,7 +628,7 @@ void build_languages_menu(void)
languages_menu = temp; languages_menu = temp;
languages_menu->entries[entries].menu_flags = 0; languages_menu->entries[entries].menu_flags = 0;
languages_menu->entries[entries].sub_menu = wimp_NO_SUB_MENU; 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.text = lang_name;
languages_menu->entries[entries].data.indirected_text.validation = (char *)-1; languages_menu->entries[entries].data.indirected_text.validation = (char *)-1;
languages_menu->entries[entries].data.indirected_text.size = strlen(lang_name) + 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 else
menu->entries[1].icon_flags |= wimp_ICON_SHADED; menu->entries[1].icon_flags |= wimp_ICON_SHADED;
if ((current_gui->bw) && (current_gui->bw->current_content)) { 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 { } 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) { } else if (menu == hotlist_menu) {
ro_gui_menu_prepare_hotlist(); 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) 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_pointer pointer;
wimp_window_state state; wimp_window_state state;
os_error *error; os_error *error;
@ -695,6 +774,66 @@ void ro_gui_menu_selection(wimp_selection *selection)
break; 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) { } else if (current_menu == hotlist_menu) {
switch (selection->items[0]) { switch (selection->items[0]) {
case 0: /* Hotlist-> */ case 0: /* Hotlist-> */
@ -1398,7 +1537,7 @@ void ro_gui_prepare_navigate(struct gui_window *gui) {
/* Set the scale view icon /* Set the scale view icon
*/ */
if (c) { 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) { 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_SEARCH, false);
ro_gui_set_icon_shaded_state(t->toolbar_handle, ICON_TOOLBAR_SCALE, 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); ro_gui_set_icon_shaded_state(t->toolbar_handle, ICON_TOOLBAR_PRINT, false);
} }
} else { } 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) { 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_SEARCH, true);
ro_gui_set_icon_shaded_state(t->toolbar_handle, ICON_TOOLBAR_SCALE, true); ro_gui_set_icon_shaded_state(t->toolbar_handle, ICON_TOOLBAR_SCALE, true);
@ -1526,16 +1665,85 @@ 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 * Update toolbar menu status
*/ */
static void ro_gui_menu_prepare_toolbars(void) { static void ro_gui_menu_prepare_toolbars(void) {
int index; int index;
struct toolbar *toolbar; struct toolbar *toolbar;
if (current_menu != browser_menu) return;
/* Check we have a toolbar /* Check we have a toolbar
*/ */
if (!current_gui) return;
toolbar = current_gui->toolbar; toolbar = current_gui->toolbar;
/* Set our ticks, or shade everything if there's no 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].icon_flags &= ~wimp_ICON_SHADED;
browser_toolbar_menu->entries[index].menu_flags &= ~wimp_MENU_TICKED; 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_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; if (toolbar->display_throbber) browser_toolbar_menu->entries[2].menu_flags |= wimp_MENU_TICKED;
} else { } else {
@ -1720,7 +1928,7 @@ void ro_gui_menu_object_reload(void)
/** /**
* Display a menu of options for a form select control. * 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 * \param control form control of type GADGET_SELECT
*/ */

View File

@ -40,7 +40,6 @@ extern int option_window_screen_width;
extern int option_window_screen_height; extern int option_window_screen_height;
extern bool option_window_stagger; extern bool option_window_stagger;
extern bool option_window_size_clone; extern bool option_window_size_clone;
extern int option_minimum_gif_delay;
extern bool option_background_images; extern bool option_background_images;
extern bool option_background_blending; extern bool option_background_blending;
extern bool option_buffer_animations; extern bool option_buffer_animations;
@ -99,7 +98,6 @@ int option_window_screen_width = 0; \
int option_window_screen_height = 0; \ int option_window_screen_height = 0; \
bool option_window_stagger = true; \ bool option_window_stagger = true; \
bool option_window_size_clone = true; \ bool option_window_size_clone = true; \
int option_minimum_gif_delay = 10; \
bool option_background_images = true; \ bool option_background_images = true; \
bool option_background_blending = true; \ bool option_background_blending = true; \
bool option_buffer_animations = 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_screen_height", OPTION_INTEGER, &option_window_screen_height }, \
{ "window_stagger", OPTION_BOOL, &option_window_stagger }, \ { "window_stagger", OPTION_BOOL, &option_window_stagger }, \
{ "window_size_clone", OPTION_BOOL, &option_window_size_clone }, \ { "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_images", OPTION_BOOL, &option_background_images }, \
{ "background_blending", OPTION_BOOL, &option_background_blending }, \ { "background_blending", OPTION_BOOL, &option_background_blending }, \
{ "buffer_animations", OPTION_BOOL, &option_buffer_animations }, \ { "buffer_animations", OPTION_BOOL, &option_buffer_animations }, \

View File

@ -725,7 +725,7 @@ static bool add_graphic(struct content *content, struct box *box,
#endif #endif
#ifdef WITH_GIF #ifdef WITH_GIF
case CONTENT_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; break;
#endif #endif
#ifdef WITH_SPRITE #ifdef WITH_SPRITE
@ -768,7 +768,7 @@ static bool add_graphic(struct content *content, struct box *box,
#endif #endif
#ifdef WITH_GIF #ifdef WITH_GIF
case CONTENT_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; break;
#endif #endif
#ifdef WITH_SPRITE #ifdef WITH_SPRITE

View File

@ -35,16 +35,6 @@
#define THEME_THROBBER_MEMORY 12 #define THEME_THROBBER_MEMORY 12
#define THEME_STATUS_MEMORY 256 #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 { struct theme_file_header {
unsigned int magic_value; unsigned int magic_value;
unsigned int parser_version; unsigned int parser_version;
@ -96,8 +86,8 @@ static wimp_window theme_toolbar_window = {
12, 12,
1, 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.data.indirected_text.size = 1;
new_icon.icon.flags = wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_INDIRECTED | new_icon.icon.flags = wimp_ICON_TEXT | wimp_ICON_SPRITE | wimp_ICON_INDIRECTED |
wimp_ICON_HCENTRED | wimp_ICON_VCENTRED | 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) { if (toolbar->descriptor) {
new_icon.icon.flags |= (toolbar->descriptor->browser_background new_icon.icon.flags |= (toolbar->descriptor->browser_background
<< wimp_ICON_BG_COLOUR_SHIFT); << 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_height = toolbar->height;
int old_width = toolbar->toolbar_current; int old_width = toolbar->toolbar_current;
struct toolbar_icon *toolbar_icon; struct toolbar_icon *toolbar_icon;
struct toolbar_icon *last_icon = NULL;
bool visible_icon = false; 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, /* Find the parent window handle if we need to process the status window,
or the caller has requested we calculate the width ourself. 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; visible_icon = true;
bottom_edge = (toolbar->height - bottom_edge = (toolbar->height -
toolbar_icon->height) / 2; toolbar_icon->height) / 2;
toolbar_icon->x = left_edge;
toolbar_icon->y = bottom_edge;
xwimp_resize_icon(toolbar->toolbar_handle, xwimp_resize_icon(toolbar->toolbar_handle,
toolbar_icon->icon_number, toolbar_icon->icon_number,
left_edge, bottom_edge, left_edge, bottom_edge,
@ -1313,6 +1327,14 @@ void ro_gui_theme_destroy_toolbar(struct toolbar *toolbar) {
free(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) { void ro_gui_theme_add_toolbar_icon(struct toolbar *toolbar, const char *name, int icon_number) {
if (!toolbar) return; if (!toolbar) return;
struct toolbar_icon *toolbar_icon; 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" /* Separators are really a sprite called "separator"
*/ */
if (name == NULL) name = "separator"; if (name == NULL) {
name = "separator";
icon_number = -1;
}
/* Create a new toolbar /* 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) { void ro_gui_theme_destroy_toolbar_icon(struct toolbar_icon *icon) {
free(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;
}

View File

@ -19,7 +19,17 @@ typedef enum {
THEME_HOTLIST_TOOLBAR THEME_HOTLIST_TOOLBAR
} toolbar_type; } 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 { struct theme {
osspriteop_area *sprite_area; /**< sprite area for 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 toolbar_icon *icon; /**< first toolbar icon (read only) */
struct theme_descriptor *descriptor; /**< theme descriptor (read only) */ struct theme_descriptor *descriptor; /**< theme descriptor (read only) */
toolbar_type type; /**< toolbar type (read only) */ toolbar_type type; /**< toolbar type (read only) */
bool locked; /**< toolbar is locked from editing */
}; };
struct theme_descriptor { 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); bool ro_gui_theme_process_toolbar(struct toolbar *toolbar, int width);
void ro_gui_theme_destroy_toolbar(struct toolbar *toolbar); 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 #endif

View File

@ -1064,10 +1064,17 @@ void ro_gui_toolbar_click(struct gui_window *g, wimp_pointer *pointer)
{ {
char url[80]; 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; return;
}
/* Handle the buttons appropriately /* Handle the buttons appropriately
*/ */