mirror of
https://github.com/netsurf-browser/netsurf
synced 2024-11-24 23:39:51 +03:00
411 lines
12 KiB
C
411 lines
12 KiB
C
/*
|
|
* Copyright 2005 Richard Wilson <info@tinct.net>
|
|
*
|
|
* This file is part of NetSurf, http://www.netsurf-browser.org/
|
|
*
|
|
* NetSurf is free software; you can redistribute it and/or modify
|
|
* it under the terms of the GNU General Public License as published by
|
|
* the Free Software Foundation; version 2 of the License.
|
|
*
|
|
* NetSurf is distributed in the hope that it will be useful,
|
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
* GNU General Public License for more details.
|
|
*
|
|
* You should have received a copy of the GNU General Public License
|
|
* along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
*/
|
|
|
|
/**
|
|
* \file
|
|
* RISC OS option setting (implementation).
|
|
*/
|
|
|
|
#include <assert.h>
|
|
#include <stdbool.h>
|
|
#include <stdlib.h>
|
|
#include <stdio.h>
|
|
#include <string.h>
|
|
#include <oslib/os.h>
|
|
#include <oslib/osbyte.h>
|
|
#include <oslib/territory.h>
|
|
#include <oslib/wimp.h>
|
|
|
|
#include "utils/log.h"
|
|
#include "utils/messages.h"
|
|
|
|
#include "riscos/gui.h"
|
|
#include "riscos/dialog.h"
|
|
#include "riscos/configure.h"
|
|
#include "riscos/wimp.h"
|
|
#include "riscos/wimp_event.h"
|
|
#include "riscos/configure/configure.h"
|
|
|
|
#define CONFIGURE_ICON_PADDING_H 32
|
|
#define CONFIGURE_ICON_PADDING_V 32
|
|
#define CONFIGURE_DEFAULT_ICON_WIDTH (68 + CONFIGURE_ICON_PADDING_H)
|
|
#define CONFIGURE_DEFAULT_ICON_HEIGHT (128 + CONFIGURE_ICON_PADDING_V)
|
|
|
|
struct configure_tool {
|
|
const char *name;
|
|
#define CONFIGURE_TOOL_TRANSLATED_SIZE 64
|
|
char translated[CONFIGURE_TOOL_TRANSLATED_SIZE];
|
|
char *validation;
|
|
bool (*initialise)(wimp_w w);
|
|
void (*finalise)(wimp_w w);
|
|
wimp_w w;
|
|
wimp_i i;
|
|
bool open;
|
|
struct configure_tool *next;
|
|
};
|
|
|
|
static wimp_w configure_window;
|
|
static int configure_current_encoding;
|
|
static int configure_icons = 0;
|
|
static struct configure_tool *configure_tools = NULL;
|
|
static int configure_icon_width = CONFIGURE_DEFAULT_ICON_WIDTH;
|
|
static int configure_icon_height = CONFIGURE_DEFAULT_ICON_HEIGHT;
|
|
static int configure_icons_per_line = 0;
|
|
static int configure_width;
|
|
static int configure_height;
|
|
|
|
static bool ro_gui_configure_click(wimp_pointer *pointer);
|
|
static void ro_gui_configure_open_window(wimp_open *open);
|
|
static void ro_gui_configure_close(wimp_w w);
|
|
static bool ro_gui_configure_translate(void);
|
|
static void ro_gui_configure_register(const char *window,
|
|
bool (*initialise)(wimp_w w), void (*finalise)(wimp_w w));
|
|
|
|
void ro_gui_configure_initialise(void)
|
|
{
|
|
/* create our window */
|
|
configure_window = ro_gui_dialog_create("configure");
|
|
ro_gui_wimp_event_register_open_window(configure_window,
|
|
ro_gui_configure_open_window);
|
|
ro_gui_wimp_event_register_mouse_click(configure_window,
|
|
ro_gui_configure_click);
|
|
ro_gui_wimp_event_set_help_prefix(configure_window, "HelpConfigure");
|
|
|
|
/* add in our option windows */
|
|
ro_gui_configure_register("con_cache",
|
|
ro_gui_options_cache_initialise,
|
|
ro_gui_wimp_event_finalise);
|
|
ro_gui_configure_register("con_connect",
|
|
ro_gui_options_connection_initialise,
|
|
ro_gui_wimp_event_finalise);
|
|
ro_gui_configure_register("con_content",
|
|
ro_gui_options_content_initialise,
|
|
ro_gui_wimp_event_finalise);
|
|
ro_gui_configure_register("con_fonts",
|
|
ro_gui_options_fonts_initialise,
|
|
ro_gui_wimp_event_finalise);
|
|
ro_gui_configure_register("con_home",
|
|
ro_gui_options_home_initialise,
|
|
ro_gui_wimp_event_finalise);
|
|
ro_gui_configure_register("con_image",
|
|
ro_gui_options_image_initialise,
|
|
ro_gui_options_image_finalise);
|
|
ro_gui_configure_register("con_inter",
|
|
ro_gui_options_interface_initialise,
|
|
ro_gui_wimp_event_finalise);
|
|
ro_gui_configure_register("con_lang",
|
|
ro_gui_options_language_initialise,
|
|
ro_gui_wimp_event_finalise);
|
|
ro_gui_configure_register("con_theme",
|
|
ro_gui_options_theme_initialise,
|
|
ro_gui_options_theme_finalise);
|
|
ro_gui_configure_register("con_secure",
|
|
ro_gui_options_security_initialise,
|
|
ro_gui_wimp_event_finalise);
|
|
|
|
/* translate the icons */
|
|
if (!ro_gui_configure_translate())
|
|
die("ro_gui_configure_translate failed");
|
|
}
|
|
|
|
void ro_gui_configure_show(void)
|
|
{
|
|
int width, height;
|
|
|
|
width = configure_icon_width << 2;
|
|
height = ((configure_icons + 3) >> 2) * configure_icon_height;
|
|
ro_gui_dialog_open_top(configure_window, NULL, width, height);
|
|
}
|
|
|
|
bool ro_gui_configure_click(wimp_pointer *pointer)
|
|
{
|
|
struct configure_tool *tool;
|
|
|
|
if (pointer->buttons == wimp_CLICK_MENU)
|
|
return true;
|
|
|
|
for (tool = configure_tools; tool; tool = tool->next) {
|
|
if (tool->i == pointer->i) {
|
|
if (!tool->open) {
|
|
tool->open = true;
|
|
if (!tool->initialise(tool->w))
|
|
return false;
|
|
ro_gui_dialog_open_persistent(
|
|
configure_window,
|
|
tool->w, true);
|
|
ro_gui_wimp_event_register_close_window(
|
|
tool->w,
|
|
ro_gui_configure_close);
|
|
} else {
|
|
ro_gui_dialog_open_top(tool->w, NULL, 0, 0);
|
|
}
|
|
break;
|
|
}
|
|
}
|
|
return true;
|
|
}
|
|
|
|
void ro_gui_configure_close(wimp_w w)
|
|
{
|
|
struct configure_tool *tool;
|
|
|
|
for (tool = configure_tools; tool; tool = tool->next) {
|
|
if (tool->w == w) {
|
|
tool->open = false;
|
|
if (tool->finalise)
|
|
tool->finalise(w);
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
void ro_gui_configure_open_window(wimp_open *open)
|
|
{
|
|
os_error *error;
|
|
int screen_width, screen_height;
|
|
int height, width;
|
|
int icons_per_line, icon_lines;
|
|
int max_height;
|
|
os_box extent = { 0, 0, 0, 0 };
|
|
struct configure_tool *tool;
|
|
|
|
if (!ro_gui_configure_translate()) {
|
|
ro_warn_user("ro_gui_configure_translate failed", 0);
|
|
return;
|
|
}
|
|
|
|
width = open->visible.x1 - open->visible.x0;
|
|
height = open->visible.y1 - open->visible.y0;
|
|
icons_per_line = width / configure_icon_width;
|
|
if (icons_per_line < 1)
|
|
icons_per_line = 1;
|
|
|
|
/* move our icons */
|
|
if (icons_per_line != configure_icons_per_line) {
|
|
int x, y, l;
|
|
configure_icons_per_line = icons_per_line;
|
|
x = CONFIGURE_ICON_PADDING_H / 2;
|
|
y = -configure_icon_height + (CONFIGURE_ICON_PADDING_V / 2);
|
|
l = 0;
|
|
for (tool = configure_tools; tool; tool = tool->next) {
|
|
error = xwimp_resize_icon(configure_window,
|
|
tool->i,
|
|
x,
|
|
y,
|
|
x + configure_icon_width -
|
|
CONFIGURE_ICON_PADDING_H,
|
|
y + configure_icon_height -
|
|
CONFIGURE_ICON_PADDING_V);
|
|
if (error) {
|
|
LOG("xwimp_resize_icon: 0x%x: %s", error->errnum, error->errmess);
|
|
}
|
|
x += configure_icon_width;
|
|
l++;
|
|
if (l >= icons_per_line) {
|
|
x = CONFIGURE_ICON_PADDING_H / 2;
|
|
l = 0;
|
|
y -= configure_icon_height;
|
|
}
|
|
}
|
|
error = xwimp_force_redraw(configure_window,
|
|
0, -16384, 16384, 0);
|
|
if (error) {
|
|
LOG("xwimp_force_redraw: 0x%x: %s", error->errnum, error->errmess);
|
|
ro_warn_user("WimpError", error->errmess);
|
|
}
|
|
}
|
|
|
|
/* restrict our height */
|
|
icon_lines = (configure_icons + icons_per_line - 1) /
|
|
icons_per_line;
|
|
max_height = (icon_lines * configure_icon_height);
|
|
if (height > max_height)
|
|
open->visible.y0 = open->visible.y1 - max_height;
|
|
|
|
/* set the extent */
|
|
if ((configure_height != height) || (configure_width != width)) {
|
|
int max_icons_per_line;
|
|
ro_gui_screen_size(&screen_width, &screen_height);
|
|
max_icons_per_line = screen_width / configure_icon_width;
|
|
if (max_icons_per_line > configure_icons)
|
|
max_icons_per_line = configure_icons;
|
|
extent.x1 = configure_icon_width * max_icons_per_line;
|
|
extent.y0 = -max_height;
|
|
error = xwimp_set_extent(open->w, &extent);
|
|
if (error) {
|
|
LOG("xwimp_set_extent: 0x%x: %s", error->errnum, error->errmess);
|
|
ro_warn_user("WimpError", error->errmess);
|
|
return;
|
|
}
|
|
configure_height = height;
|
|
configure_width = width;
|
|
}
|
|
|
|
/* open the window */
|
|
error = xwimp_open_window(open);
|
|
if (error) {
|
|
LOG("xwimp_open_window: 0x%x: %s", error->errnum, error->errmess);
|
|
ro_warn_user("WimpError", error->errmess);
|
|
return;
|
|
}
|
|
}
|
|
|
|
void ro_gui_configure_register(const char *window,
|
|
bool (*initialise)(wimp_w w), void (*finalise)(wimp_w w))
|
|
{
|
|
wimp_icon_create new_icon;
|
|
struct configure_tool *tool;
|
|
struct configure_tool *link;
|
|
os_error *error;
|
|
|
|
/* create our tool */
|
|
tool = calloc(sizeof(struct configure_tool), 1);
|
|
if (!tool) {
|
|
LOG("Insufficient memory for calloc()");
|
|
die("Insufficient memory");
|
|
return; /* For the benefit of scan-build */
|
|
}
|
|
tool->name = window;
|
|
tool->translated[0] = '\0';
|
|
tool->validation = malloc(strlen(window) + 2);
|
|
if (!tool->validation) {
|
|
LOG("Insufficient memory for malloc()");
|
|
die("Insufficient memory");
|
|
}
|
|
sprintf(tool->validation, "S%s", window);
|
|
tool->initialise = initialise;
|
|
tool->finalise = finalise;
|
|
tool->w = ro_gui_dialog_create(tool->name);
|
|
|
|
/* create the icon */
|
|
new_icon.w = configure_window;
|
|
new_icon.icon.extent.x0 = 0;
|
|
new_icon.icon.extent.x1 = configure_icon_width;
|
|
new_icon.icon.extent.y1 = 0;
|
|
new_icon.icon.extent.y0 = -configure_icon_height;
|
|
new_icon.icon.flags = wimp_ICON_TEXT | wimp_ICON_SPRITE |
|
|
wimp_ICON_INDIRECTED | wimp_ICON_HCENTRED |
|
|
(wimp_COLOUR_VERY_LIGHT_GREY << wimp_ICON_BG_COLOUR_SHIFT) |
|
|
(wimp_COLOUR_BLACK << wimp_ICON_FG_COLOUR_SHIFT) |
|
|
(wimp_BUTTON_CLICK << wimp_ICON_BUTTON_TYPE_SHIFT);
|
|
new_icon.icon.data.indirected_text_and_sprite.text =
|
|
tool->translated;
|
|
new_icon.icon.data.indirected_text_and_sprite.validation =
|
|
tool->validation;
|
|
new_icon.icon.data.indirected_text_and_sprite.size =
|
|
CONFIGURE_TOOL_TRANSLATED_SIZE;
|
|
error = xwimp_create_icon(&new_icon, &tool->i);
|
|
if (error) {
|
|
LOG("xwimp_create_icon: 0x%x: %s", error->errnum, error->errmess);
|
|
die(error->errmess);
|
|
}
|
|
|
|
/* Set the icon's text in current local encoding */
|
|
ro_gui_set_icon_string(configure_window, tool->i,
|
|
messages_get(tool->name), true);
|
|
|
|
/* link into our list alphabetically */
|
|
if ((!configure_tools) ||
|
|
(strcmp(configure_tools->translated,
|
|
tool->translated) > 0)) {
|
|
tool->next = configure_tools;
|
|
configure_tools = tool;
|
|
} else {
|
|
for (link = configure_tools; link; link = link->next) {
|
|
if (link->next) {
|
|
if (strcmp(link->next->translated,
|
|
tool->translated) > 0) {
|
|
tool->next = link->next;
|
|
link->next = tool;
|
|
break;
|
|
}
|
|
} else {
|
|
link->next = tool;
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
configure_icons++;
|
|
}
|
|
|
|
/**
|
|
* Translate tool icons into the system local encoding.
|
|
* This will also recalculate the minimum required icon width.
|
|
*
|
|
* \return true on success, false on memory exhaustion
|
|
*/
|
|
bool ro_gui_configure_translate(void)
|
|
{
|
|
int alphabet;
|
|
struct configure_tool *tool;
|
|
int icon_width;
|
|
os_error *error;
|
|
|
|
/* read current alphabet */
|
|
error = xosbyte1(osbyte_ALPHABET_NUMBER, 127, 0,
|
|
&alphabet);
|
|
if (error) {
|
|
LOG("failed reading alphabet: 0x%x: %s", error->errnum, error->errmess);
|
|
/* assume Latin1 */
|
|
alphabet = territory_ALPHABET_LATIN1;
|
|
}
|
|
|
|
if (alphabet == configure_current_encoding)
|
|
/* text is already in the correct encoding */
|
|
return true;
|
|
|
|
/* reset icon width */
|
|
configure_icon_width = CONFIGURE_DEFAULT_ICON_WIDTH;
|
|
|
|
for (tool = configure_tools; tool; tool = tool->next) {
|
|
/* re-translate the text */
|
|
ro_gui_set_icon_string(configure_window, tool->i,
|
|
messages_get(tool->name), true);
|
|
|
|
/* update the width */
|
|
error = xwimptextop_string_width(tool->translated,
|
|
strlen(tool->translated), &icon_width);
|
|
if (error) {
|
|
LOG("xwimptextop_string_width: 0x%x: %s", error->errnum, error->errmess);
|
|
return false;
|
|
}
|
|
icon_width += CONFIGURE_ICON_PADDING_H;
|
|
if (icon_width > configure_icon_width)
|
|
configure_icon_width = icon_width;
|
|
|
|
error = xwimp_resize_icon(configure_window,
|
|
tool->i,
|
|
0,
|
|
-configure_icon_height,
|
|
configure_icon_width,
|
|
0);
|
|
if (error) {
|
|
LOG("xwimp_resize_icon: 0x%x: %s", error->errnum, error->errmess);
|
|
}
|
|
}
|
|
|
|
/* invalidate our global icons_per_line setting
|
|
* so the icons get reflowed */
|
|
configure_icons_per_line = 0;
|
|
|
|
/* finally, set the current encoding */
|
|
configure_current_encoding = alphabet;
|
|
|
|
return true;
|
|
}
|