2004-05-05 02:23:44 +04:00
|
|
|
/*
|
|
|
|
* This file is part of NetSurf, http://netsurf.sourceforge.net/
|
|
|
|
* Licensed under the GNU General Public License,
|
2005-04-08 00:46:22 +04:00
|
|
|
* http://www.opensource.org/licenses/gpl-license
|
2005-04-09 17:23:55 +04:00
|
|
|
* Copyright 2004, 2005 Richard Wilson <info@tinct.net>
|
2004-05-05 02:23:44 +04:00
|
|
|
*/
|
|
|
|
|
|
|
|
/** \file
|
|
|
|
* General RISC OS WIMP/OS library functions (implementation).
|
|
|
|
*/
|
|
|
|
|
|
|
|
#include <assert.h>
|
2004-07-11 17:05:38 +04:00
|
|
|
#include <stdbool.h>
|
2004-05-05 02:23:44 +04:00
|
|
|
#include <stdlib.h>
|
2004-07-11 17:05:38 +04:00
|
|
|
#include <string.h>
|
2004-05-05 02:23:44 +04:00
|
|
|
#include <stdio.h>
|
2005-03-14 16:58:43 +03:00
|
|
|
#include "oslib/colourtrans.h"
|
2004-05-05 02:23:44 +04:00
|
|
|
#include "oslib/os.h"
|
2004-05-23 03:04:44 +04:00
|
|
|
#include "oslib/osfile.h"
|
2004-05-05 02:23:44 +04:00
|
|
|
#include "oslib/wimp.h"
|
|
|
|
#include "oslib/wimpextend.h"
|
2004-05-19 21:31:34 +04:00
|
|
|
#include "oslib/wimpreadsysinfo.h"
|
2004-07-11 17:05:38 +04:00
|
|
|
#include "oslib/wimpspriteop.h"
|
2004-05-23 03:04:44 +04:00
|
|
|
#include "netsurf/desktop/gui.h"
|
2004-07-16 20:33:45 +04:00
|
|
|
#include "netsurf/riscos/gui.h"
|
2005-12-31 07:40:49 +03:00
|
|
|
#include "netsurf/riscos/theme.h"
|
2004-05-05 02:23:44 +04:00
|
|
|
#include "netsurf/riscos/wimp.h"
|
2004-05-19 21:31:34 +04:00
|
|
|
#include "netsurf/utils/log.h"
|
2005-07-16 18:35:25 +04:00
|
|
|
#include "netsurf/utils/utf8.h"
|
2004-06-11 00:41:26 +04:00
|
|
|
#include "netsurf/utils/utils.h"
|
2004-05-05 02:23:44 +04:00
|
|
|
|
2005-04-09 18:58:54 +04:00
|
|
|
static void ro_gui_wimp_cache_furniture_sizes(wimp_w w);
|
2005-04-08 00:46:22 +04:00
|
|
|
static bool ro_gui_wimp_read_eig_factors(os_mode mode, int *xeig, int *yeig);
|
|
|
|
|
2004-05-05 02:23:44 +04:00
|
|
|
static wimpextend_furniture_sizes furniture_sizes;
|
2005-04-08 00:46:22 +04:00
|
|
|
static wimp_w furniture_window = NULL;
|
2004-05-23 16:22:05 +04:00
|
|
|
|
2004-05-05 02:23:44 +04:00
|
|
|
/**
|
2004-06-28 23:35:04 +04:00
|
|
|
* Gets the horzontal scrollbar height
|
2005-04-08 00:46:22 +04:00
|
|
|
*
|
|
|
|
* \param w the window to read (or NULL to read a cached value)
|
2004-05-05 02:23:44 +04:00
|
|
|
*/
|
|
|
|
int ro_get_hscroll_height(wimp_w w) {
|
2005-04-09 17:23:55 +04:00
|
|
|
ro_gui_wimp_cache_furniture_sizes(w);
|
2005-04-09 18:58:54 +04:00
|
|
|
return furniture_sizes.border_widths.y0;
|
2004-05-05 02:23:44 +04:00
|
|
|
}
|
|
|
|
|
2004-05-23 16:22:05 +04:00
|
|
|
|
|
|
|
/**
|
2004-06-28 23:35:04 +04:00
|
|
|
* Gets the vertical scrollbar width
|
2005-04-08 00:46:22 +04:00
|
|
|
*
|
|
|
|
* \param w the window to read (or NULL to read a cached value)
|
2004-05-23 16:22:05 +04:00
|
|
|
*/
|
|
|
|
int ro_get_vscroll_width(wimp_w w) {
|
2005-04-09 17:23:55 +04:00
|
|
|
ro_gui_wimp_cache_furniture_sizes(w);
|
2005-04-09 18:58:54 +04:00
|
|
|
return furniture_sizes.border_widths.x1;
|
2005-04-08 00:46:22 +04:00
|
|
|
}
|
2004-05-23 16:22:05 +04:00
|
|
|
|
2005-04-08 00:46:22 +04:00
|
|
|
/**
|
|
|
|
* Caches window furniture information
|
|
|
|
*
|
|
|
|
* \param w the window to cache information from
|
2005-04-09 17:23:55 +04:00
|
|
|
* \return true on success, false on error (default values cached)
|
2005-04-08 00:46:22 +04:00
|
|
|
*/
|
2005-04-09 18:58:54 +04:00
|
|
|
void ro_gui_wimp_cache_furniture_sizes(wimp_w w) {
|
2005-04-08 00:46:22 +04:00
|
|
|
os_error *error;
|
2004-05-23 16:22:05 +04:00
|
|
|
|
2005-04-09 17:23:55 +04:00
|
|
|
if (!w)
|
|
|
|
w = dialog_debug;
|
|
|
|
if (furniture_window == w)
|
2005-04-09 18:58:54 +04:00
|
|
|
return;
|
|
|
|
furniture_window = w;
|
2005-04-08 00:46:22 +04:00
|
|
|
furniture_sizes.w = w;
|
2005-04-09 18:58:54 +04:00
|
|
|
furniture_sizes.border_widths.y0 = 40;
|
|
|
|
furniture_sizes.border_widths.x1 = 40;
|
2005-04-08 00:46:22 +04:00
|
|
|
error = xwimpextend_get_furniture_sizes(&furniture_sizes);
|
|
|
|
if (error) {
|
|
|
|
LOG(("xwimpextend_get_furniture_sizes: 0x%x: %s",
|
|
|
|
error->errnum, error->errmess));
|
|
|
|
warn_user("WimpError", error->errmess);
|
2005-04-09 17:23:55 +04:00
|
|
|
}
|
2004-05-23 16:22:05 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-05-05 02:23:44 +04:00
|
|
|
/**
|
|
|
|
* Reads a modes EIG factors.
|
|
|
|
*
|
|
|
|
* \param mode mode to read EIG factors for, or -1 for current
|
|
|
|
*/
|
2005-04-08 00:46:22 +04:00
|
|
|
bool ro_gui_wimp_read_eig_factors(os_mode mode, int *xeig, int *yeig) {
|
|
|
|
os_error *error;
|
|
|
|
|
|
|
|
error = xos_read_mode_variable(mode, os_MODEVAR_XEIG_FACTOR, xeig, 0);
|
|
|
|
if (error) {
|
|
|
|
LOG(("xos_read_mode_variable: 0x%x: %s",
|
|
|
|
error->errnum, error->errmess));
|
|
|
|
warn_user("MiscError", error->errmess);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
error = xos_read_mode_variable(mode, os_MODEVAR_YEIG_FACTOR, yeig, 0);
|
|
|
|
if (error) {
|
|
|
|
LOG(("xos_read_mode_variable: 0x%x: %s",
|
|
|
|
error->errnum, error->errmess));
|
|
|
|
warn_user("MiscError", error->errmess);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
2004-05-05 02:23:44 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Converts the supplied os_coord from OS units to pixels.
|
|
|
|
*
|
|
|
|
* \param os_units values to convert
|
2005-04-08 00:46:22 +04:00
|
|
|
* \param mode mode to use EIG factors for, or -1 for current
|
2004-05-05 02:23:44 +04:00
|
|
|
*/
|
|
|
|
void ro_convert_os_units_to_pixels(os_coord *os_units, os_mode mode) {
|
2005-04-12 23:09:09 +04:00
|
|
|
int xeig = 1, yeig = 1;
|
2005-04-08 00:46:22 +04:00
|
|
|
|
|
|
|
ro_gui_wimp_read_eig_factors(mode, &xeig, &yeig);
|
2005-04-12 23:09:09 +04:00
|
|
|
os_units->x = ((os_units->x + (1 << xeig) - 1) >> xeig);
|
|
|
|
os_units->y = ((os_units->y + (1 << yeig) - 1) >> yeig);
|
2004-05-05 02:23:44 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Converts the supplied os_coord from pixels to OS units.
|
|
|
|
*
|
|
|
|
* \param pixels values to convert
|
2005-04-08 00:46:22 +04:00
|
|
|
* \param mode mode to use EIG factors for, or -1 for current
|
2004-05-05 02:23:44 +04:00
|
|
|
*/
|
|
|
|
void ro_convert_pixels_to_os_units(os_coord *pixels, os_mode mode) {
|
2005-04-12 23:09:09 +04:00
|
|
|
int xeig = 1, yeig = 1;
|
2005-04-08 00:46:22 +04:00
|
|
|
|
|
|
|
ro_gui_wimp_read_eig_factors(mode, &xeig, &yeig);
|
|
|
|
pixels->x = (pixels->x << xeig);
|
|
|
|
pixels->y = (pixels->y << yeig);
|
2004-05-05 02:23:44 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Redraws an icon
|
|
|
|
*
|
|
|
|
* \param w window handle
|
|
|
|
* \param i icon handle
|
|
|
|
*/
|
2005-07-24 07:13:33 +04:00
|
|
|
|
2004-05-05 02:23:44 +04:00
|
|
|
#define ro_gui_redraw_icon(w, i) xwimp_set_icon_state(w, i, 0, 0)
|
|
|
|
|
|
|
|
|
2005-01-23 19:09:05 +03:00
|
|
|
/**
|
|
|
|
* Forces an icon to be redrawn entirely (ie not just updated).
|
|
|
|
*
|
|
|
|
* \param w window handle
|
|
|
|
* \param i icon handle
|
|
|
|
*/
|
|
|
|
void ro_gui_force_redraw_icon(wimp_w w, wimp_i i) {
|
|
|
|
wimp_icon_state ic;
|
|
|
|
os_error *error;
|
|
|
|
|
|
|
|
/* Get the icon data
|
|
|
|
*/
|
|
|
|
ic.w = w;
|
|
|
|
ic.i = i;
|
|
|
|
error = xwimp_get_icon_state(&ic);
|
|
|
|
if (error) {
|
|
|
|
LOG(("xwimp_get_icon_state: 0x%x: %s",
|
|
|
|
error->errnum, error->errmess));
|
|
|
|
warn_user("WimpError", error->errmess);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
error = xwimp_force_redraw(w, ic.icon.extent.x0, ic.icon.extent.y0,
|
|
|
|
ic.icon.extent.x1, ic.icon.extent.y1);
|
|
|
|
if (error) {
|
|
|
|
LOG(("xwimp_force_redraw: 0x%x: %s",
|
|
|
|
error->errnum, error->errmess));
|
|
|
|
warn_user("WimpError", error->errmess);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-05-05 02:23:44 +04:00
|
|
|
/**
|
|
|
|
* Read the contents of an icon.
|
|
|
|
*
|
|
|
|
* \param w window handle
|
|
|
|
* \param i icon handle
|
|
|
|
* \return string in icon
|
|
|
|
*/
|
|
|
|
char *ro_gui_get_icon_string(wimp_w w, wimp_i i) {
|
|
|
|
wimp_icon_state ic;
|
2005-04-08 00:46:22 +04:00
|
|
|
os_error *error;
|
|
|
|
|
2004-05-05 02:23:44 +04:00
|
|
|
ic.w = w;
|
|
|
|
ic.i = i;
|
2005-04-08 00:46:22 +04:00
|
|
|
error = xwimp_get_icon_state(&ic);
|
|
|
|
if (error) {
|
|
|
|
LOG(("xwimp_get_icon_state: 0x%x: %s",
|
|
|
|
error->errnum, error->errmess));
|
|
|
|
warn_user("WimpError", error->errmess);
|
|
|
|
return NULL;
|
|
|
|
}
|
2004-05-05 02:23:44 +04:00
|
|
|
return ic.icon.data.indirected_text.text;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the contents of an icon to a string.
|
|
|
|
*
|
2005-04-08 00:46:22 +04:00
|
|
|
* \param w window handle
|
|
|
|
* \param i icon handle
|
2005-07-16 18:35:25 +04:00
|
|
|
* \param text string (UTF-8 encoded) (copied)
|
2004-05-05 02:23:44 +04:00
|
|
|
*/
|
|
|
|
void ro_gui_set_icon_string(wimp_w w, wimp_i i, const char *text) {
|
2004-05-07 01:18:26 +04:00
|
|
|
wimp_caret caret;
|
2004-05-05 02:23:44 +04:00
|
|
|
wimp_icon_state ic;
|
2005-04-08 00:46:22 +04:00
|
|
|
os_error *error;
|
2004-05-05 02:23:44 +04:00
|
|
|
int old_len, len;
|
2005-07-16 18:35:25 +04:00
|
|
|
char *local_text;
|
|
|
|
utf8_convert_ret err;
|
2004-05-07 01:18:26 +04:00
|
|
|
|
2005-04-08 00:46:22 +04:00
|
|
|
/* get the icon data */
|
2004-05-05 02:23:44 +04:00
|
|
|
ic.w = w;
|
|
|
|
ic.i = i;
|
2005-04-08 00:46:22 +04:00
|
|
|
error = xwimp_get_icon_state(&ic);
|
|
|
|
if (error) {
|
|
|
|
LOG(("xwimp_get_icon_state: 0x%x: %s",
|
|
|
|
error->errnum, error->errmess));
|
|
|
|
warn_user("WimpError", error->errmess);
|
2004-05-07 01:18:26 +04:00
|
|
|
return;
|
2005-04-08 00:46:22 +04:00
|
|
|
}
|
2004-05-07 01:18:26 +04:00
|
|
|
|
2005-07-16 18:35:25 +04:00
|
|
|
/* convert text to local encoding */
|
|
|
|
err = utf8_to_local_encoding(text, 0, &local_text);
|
|
|
|
if (err != UTF8_CONVERT_OK) {
|
|
|
|
/* A bad encoding should never happen, so assert this */
|
|
|
|
assert(err != UTF8_CONVERT_BADENC);
|
|
|
|
LOG(("utf8_to_enc failed"));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2005-04-08 00:46:22 +04:00
|
|
|
/* check that the existing text is not the same as the updated text
|
|
|
|
* to stop flicker */
|
|
|
|
if (ic.icon.data.indirected_text.size &&
|
2005-07-16 18:35:25 +04:00
|
|
|
!strncmp(ic.icon.data.indirected_text.text,
|
|
|
|
local_text,
|
2004-05-07 01:18:26 +04:00
|
|
|
(unsigned int)ic.icon.data.indirected_text.size - 1))
|
|
|
|
return;
|
|
|
|
|
2005-04-08 00:46:22 +04:00
|
|
|
/* copy the text across */
|
2004-05-05 02:23:44 +04:00
|
|
|
old_len = strlen(ic.icon.data.indirected_text.text);
|
2004-05-07 01:18:26 +04:00
|
|
|
if (ic.icon.data.indirected_text.size) {
|
2005-07-16 18:35:25 +04:00
|
|
|
strncpy(ic.icon.data.indirected_text.text, local_text,
|
2004-05-07 01:18:26 +04:00
|
|
|
(unsigned int)ic.icon.data.indirected_text.size - 1);
|
2005-04-08 00:46:22 +04:00
|
|
|
ic.icon.data.indirected_text.text[
|
|
|
|
ic.icon.data.indirected_text.size - 1] = '\0';
|
2004-05-07 01:18:26 +04:00
|
|
|
}
|
|
|
|
|
2005-04-08 00:46:22 +04:00
|
|
|
/* handle the caret being in the icon */
|
|
|
|
error = xwimp_get_caret_position(&caret);
|
|
|
|
if (error) {
|
|
|
|
LOG(("xwimp_get_caret_position: 0x%x: %s",
|
|
|
|
error->errnum, error->errmess));
|
|
|
|
warn_user("WimpError", error->errmess);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if ((caret.w == w) && (caret.i == i)) {
|
2005-07-16 18:35:25 +04:00
|
|
|
len = strlen(local_text);
|
2005-04-08 00:46:22 +04:00
|
|
|
if ((caret.index > len) || (caret.index == old_len))
|
|
|
|
caret.index = len;
|
|
|
|
error = xwimp_set_caret_position(w, i, caret.pos.x, caret.pos.y,
|
|
|
|
-1, caret.index);
|
|
|
|
if (error) {
|
|
|
|
LOG(("xwimp_set_caret_position: 0x%x: %s",
|
|
|
|
error->errnum, error->errmess));
|
|
|
|
warn_user("WimpError", error->errmess);
|
2004-05-05 02:23:44 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
ro_gui_redraw_icon(w, i);
|
2005-07-16 18:35:25 +04:00
|
|
|
|
|
|
|
free(local_text);
|
2004-05-05 02:23:44 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the contents of an icon to a number.
|
|
|
|
*
|
2005-04-08 00:46:22 +04:00
|
|
|
* \param w window handle
|
|
|
|
* \param i icon handle
|
2004-05-05 02:23:44 +04:00
|
|
|
* \param value value
|
|
|
|
*/
|
|
|
|
void ro_gui_set_icon_integer(wimp_w w, wimp_i i, int value) {
|
|
|
|
char buffer[20]; // Big enough for 64-bit int
|
|
|
|
sprintf(buffer, "%d", value);
|
|
|
|
ro_gui_set_icon_string(w, i, buffer);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-12-31 07:40:49 +03:00
|
|
|
/**
|
|
|
|
* Set the contents of an icon to a number.
|
|
|
|
*
|
|
|
|
* \param w window handle
|
|
|
|
* \param i icon handle
|
|
|
|
* \param value value
|
|
|
|
*/
|
|
|
|
void ro_gui_set_icon_decimal(wimp_w w, wimp_i i, int value, int decimal_places) {
|
|
|
|
char buffer[20]; // Big enough for 64-bit int
|
|
|
|
|
|
|
|
switch (decimal_places) {
|
|
|
|
case 0:
|
|
|
|
sprintf(buffer, "%d", value);
|
|
|
|
break;
|
|
|
|
case 1:
|
|
|
|
sprintf(buffer, "%.1f", (float)value / 10);
|
|
|
|
break;
|
|
|
|
case 2:
|
|
|
|
sprintf(buffer, "%.2f", (float)value / 100);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
assert("Unsupported decimal format");
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
ro_gui_set_icon_string(w, i, buffer);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Set the contents of an icon to a number.
|
|
|
|
*
|
|
|
|
* \param w window handle
|
|
|
|
* \param i icon handle
|
|
|
|
* \param value value
|
|
|
|
*/
|
|
|
|
int ro_gui_get_icon_decimal(wimp_w w, wimp_i i, int decimal_places) {
|
|
|
|
double value;
|
|
|
|
int multiple = 1;
|
|
|
|
|
|
|
|
for (; decimal_places > 0; decimal_places--)
|
|
|
|
multiple *= 10;
|
|
|
|
|
|
|
|
value = atof(ro_gui_get_icon_string(w, i)) * multiple;
|
|
|
|
return (int)value;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-05-05 02:23:44 +04:00
|
|
|
/**
|
|
|
|
* Set the selected state of an icon.
|
|
|
|
*
|
2005-04-08 00:46:22 +04:00
|
|
|
* \param w window handle
|
|
|
|
* \param i icon handle
|
2004-05-05 02:23:44 +04:00
|
|
|
* \param state selected state
|
|
|
|
*/
|
2004-08-31 22:01:22 +04:00
|
|
|
void ro_gui_set_icon_selected_state(wimp_w w, wimp_i i, bool state) {
|
|
|
|
os_error *error;
|
|
|
|
if (ro_gui_get_icon_selected_state(w, i) == state) return;
|
|
|
|
error = xwimp_set_icon_state(w, i,
|
|
|
|
(state ? wimp_ICON_SELECTED : 0), wimp_ICON_SELECTED);
|
|
|
|
if (error) {
|
2005-01-23 19:09:05 +03:00
|
|
|
LOG(("xwimp_set_icon_state: 0x%x: %s",
|
2004-08-31 22:01:22 +04:00
|
|
|
error->errnum, error->errmess));
|
|
|
|
warn_user("WimpError", error->errmess);
|
|
|
|
}
|
|
|
|
}
|
2004-05-05 02:23:44 +04:00
|
|
|
|
|
|
|
/**
|
|
|
|
* Gets the selected state of an icon.
|
|
|
|
*
|
2005-04-08 00:46:22 +04:00
|
|
|
* \param w window handle
|
|
|
|
* \param i icon handle
|
2004-05-05 02:23:44 +04:00
|
|
|
*/
|
2004-07-22 00:02:13 +04:00
|
|
|
bool ro_gui_get_icon_selected_state(wimp_w w, wimp_i i) {
|
2004-08-31 22:01:22 +04:00
|
|
|
os_error *error;
|
2004-05-05 02:23:44 +04:00
|
|
|
wimp_icon_state ic;
|
|
|
|
ic.w = w;
|
|
|
|
ic.i = i;
|
2004-08-31 22:01:22 +04:00
|
|
|
error = xwimp_get_icon_state(&ic);
|
|
|
|
if (error) {
|
|
|
|
LOG(("xwimp_get_icon_state: 0x%x: %s",
|
|
|
|
error->errnum, error->errmess));
|
|
|
|
warn_user("WimpError", error->errmess);
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return ((ic.icon.flags & wimp_ICON_SELECTED) != 0);
|
2004-05-05 02:23:44 +04:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/**
|
2004-08-31 23:51:29 +04:00
|
|
|
* Set the shaded state of an icon.
|
2004-05-05 02:23:44 +04:00
|
|
|
*
|
2005-04-08 00:46:22 +04:00
|
|
|
* \param w window handle
|
|
|
|
* \param i icon handle
|
2004-05-05 02:23:44 +04:00
|
|
|
* \param state selected state
|
|
|
|
*/
|
2004-08-31 23:51:29 +04:00
|
|
|
void ro_gui_set_icon_shaded_state(wimp_w w, wimp_i i, bool state) {
|
|
|
|
os_error *error;
|
2004-09-01 20:48:25 +04:00
|
|
|
if (ro_gui_get_icon_shaded_state(w, i) == state) return;
|
2004-08-31 23:51:29 +04:00
|
|
|
error = xwimp_set_icon_state(w, i,
|
|
|
|
(state ? wimp_ICON_SHADED : 0), wimp_ICON_SHADED);
|
|
|
|
if (error) {
|
|
|
|
LOG(("xwimp_get_icon_state: 0x%x: %s",
|
|
|
|
error->errnum, error->errmess));
|
|
|
|
warn_user("WimpError", error->errmess);
|
|
|
|
}
|
|
|
|
}
|
2004-05-23 03:04:44 +04:00
|
|
|
|
|
|
|
|
2004-07-22 00:02:13 +04:00
|
|
|
/**
|
|
|
|
* Gets the shaded state of an icon.
|
|
|
|
*
|
2005-04-08 00:46:22 +04:00
|
|
|
* \param w window handle
|
|
|
|
* \param i icon handle
|
2004-07-22 00:02:13 +04:00
|
|
|
*/
|
|
|
|
bool ro_gui_get_icon_shaded_state(wimp_w w, wimp_i i) {
|
|
|
|
wimp_icon_state ic;
|
|
|
|
ic.w = w;
|
|
|
|
ic.i = i;
|
|
|
|
xwimp_get_icon_state(&ic);
|
|
|
|
return (ic.icon.flags & wimp_ICON_SHADED) != 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-01-23 19:09:05 +03:00
|
|
|
/**
|
|
|
|
* Set the button type of an icon.
|
|
|
|
*
|
2005-04-08 00:46:22 +04:00
|
|
|
* \param w window handle
|
|
|
|
* \param i icon handle
|
2005-01-23 19:09:05 +03:00
|
|
|
* \param type button type
|
|
|
|
*/
|
|
|
|
void ro_gui_set_icon_button_type(wimp_w w, wimp_i i, int type) {
|
|
|
|
os_error *error;
|
|
|
|
error = xwimp_set_icon_state(w, i, wimp_ICON_BUTTON_TYPE,
|
|
|
|
(type << wimp_ICON_BUTTON_TYPE_SHIFT));
|
|
|
|
if (error) {
|
|
|
|
LOG(("xwimp_set_icon_state: 0x%x: %s",
|
|
|
|
error->errnum, error->errmess));
|
|
|
|
warn_user("WimpError", error->errmess);
|
2005-04-08 00:46:22 +04:00
|
|
|
}
|
2005-01-23 19:09:05 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
|
2005-07-16 18:35:25 +04:00
|
|
|
/**
|
|
|
|
* Set an icon's sprite
|
|
|
|
*
|
|
|
|
* \param w window handle
|
|
|
|
* \param i icon handle
|
|
|
|
* \param area sprite area containing sprite
|
|
|
|
* \param name name of sprite in area (in local encoding)
|
|
|
|
*/
|
|
|
|
void ro_gui_set_icon_sprite(wimp_w w, wimp_i i, osspriteop_area *area,
|
|
|
|
const char *name)
|
|
|
|
{
|
|
|
|
wimp_icon_state ic;
|
|
|
|
os_error *error;
|
|
|
|
|
|
|
|
/* get the icon data */
|
|
|
|
ic.w = w;
|
|
|
|
ic.i = i;
|
|
|
|
error = xwimp_get_icon_state(&ic);
|
|
|
|
if (error) {
|
|
|
|
LOG(("xwimp_get_icon_state: 0x%x: %s",
|
|
|
|
error->errnum, error->errmess));
|
|
|
|
warn_user("WimpError", error->errmess);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
/* copy the name across */
|
|
|
|
if (ic.icon.data.indirected_text.size) {
|
|
|
|
strncpy(ic.icon.data.indirected_text.text, name,
|
|
|
|
(unsigned int)ic.icon.data.indirected_text.size - 1);
|
|
|
|
ic.icon.data.indirected_text.text[
|
|
|
|
ic.icon.data.indirected_text.size - 1] = '\0';
|
|
|
|
}
|
|
|
|
|
|
|
|
ic.icon.data.indirected_sprite.area = area;
|
|
|
|
|
|
|
|
ro_gui_redraw_icon(w, i);
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-07-09 02:05:35 +04:00
|
|
|
/**
|
2005-07-24 07:13:33 +04:00
|
|
|
* Set a window title
|
2004-07-09 02:05:35 +04:00
|
|
|
*
|
2005-04-08 00:46:22 +04:00
|
|
|
* \param w window handle
|
2004-07-09 02:05:35 +04:00
|
|
|
* \param text new title (copied)
|
|
|
|
*/
|
|
|
|
void ro_gui_set_window_title(wimp_w w, const char *text) {
|
|
|
|
wimp_window_info_base window;
|
|
|
|
os_error *error;
|
2005-07-16 18:35:25 +04:00
|
|
|
char *title_local_enc;
|
|
|
|
utf8_convert_ret err;
|
2004-07-11 17:05:38 +04:00
|
|
|
|
2004-07-09 02:05:35 +04:00
|
|
|
/* Get the window details
|
|
|
|
*/
|
|
|
|
window.w = w;
|
|
|
|
error = xwimp_get_window_info_header_only((wimp_window_info *)&window);
|
|
|
|
if (error) {
|
|
|
|
LOG(("xwimp_get_window_info: 0x%x: %s",
|
|
|
|
error->errnum, error->errmess));
|
|
|
|
warn_user("WimpError", error->errmess);
|
|
|
|
return;
|
|
|
|
}
|
2004-07-11 17:05:38 +04:00
|
|
|
|
2005-07-16 18:35:25 +04:00
|
|
|
/* convert text to local encoding */
|
|
|
|
err = utf8_to_local_encoding(text, 0, &title_local_enc);
|
|
|
|
if (err != UTF8_CONVERT_OK) {
|
|
|
|
/* A bad encoding should never happen,
|
|
|
|
* so assert this */
|
|
|
|
assert(err != UTF8_CONVERT_BADENC);
|
|
|
|
LOG(("utf8_to_enc failed"));
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2004-07-09 02:05:35 +04:00
|
|
|
/* Set the title string
|
|
|
|
*/
|
2005-07-16 18:35:25 +04:00
|
|
|
strncpy(window.title_data.indirected_text.text, title_local_enc,
|
2005-04-08 00:46:22 +04:00
|
|
|
(unsigned int)window.title_data.indirected_text.size
|
|
|
|
- 1);
|
|
|
|
window.title_data.indirected_text.text[
|
|
|
|
window.title_data.indirected_text.size - 1] = '\0';
|
2004-12-09 13:30:44 +03:00
|
|
|
|
|
|
|
/* Redraw accordingly
|
|
|
|
*/
|
|
|
|
error = xwimp_force_redraw_title(w);
|
|
|
|
if (error) {
|
|
|
|
LOG(("xwimp_force_redraw_title: 0x%x: %s",
|
|
|
|
error->errnum, error->errmess));
|
|
|
|
warn_user("WimpError", error->errmess);
|
|
|
|
return;
|
2005-04-08 00:46:22 +04:00
|
|
|
}
|
2005-07-16 18:35:25 +04:00
|
|
|
|
|
|
|
free(title_local_enc);
|
2004-07-09 02:05:35 +04:00
|
|
|
}
|
2004-07-11 17:05:38 +04:00
|
|
|
|
2004-07-09 02:05:35 +04:00
|
|
|
|
2004-07-12 01:45:51 +04:00
|
|
|
/**
|
|
|
|
* Places the caret in the first available icon
|
|
|
|
*/
|
|
|
|
void ro_gui_set_caret_first(wimp_w w) {
|
2005-04-08 00:46:22 +04:00
|
|
|
int icon, b;
|
2004-08-31 01:57:47 +04:00
|
|
|
wimp_window_state win_state;
|
2004-07-12 01:45:51 +04:00
|
|
|
wimp_window_info_base window;
|
|
|
|
wimp_icon_state state;
|
|
|
|
os_error *error;
|
|
|
|
|
2005-04-08 00:46:22 +04:00
|
|
|
/* check the window is open */
|
2004-08-31 01:57:47 +04:00
|
|
|
win_state.w = w;
|
|
|
|
error = xwimp_get_window_state(&win_state);
|
|
|
|
if (error) {
|
|
|
|
LOG(("xwimp_get_window_state: 0x%x: %s",
|
|
|
|
error->errnum, error->errmess));
|
|
|
|
warn_user("WimpError", error->errmess);
|
|
|
|
return;
|
|
|
|
}
|
2005-04-08 00:46:22 +04:00
|
|
|
if (!(win_state.flags & wimp_WINDOW_OPEN))
|
|
|
|
return;
|
|
|
|
|
|
|
|
/* get the window details for the icon count */
|
2004-07-12 01:45:51 +04:00
|
|
|
window.w = w;
|
|
|
|
error = xwimp_get_window_info_header_only((wimp_window_info *)&window);
|
|
|
|
if (error) {
|
|
|
|
LOG(("xwimp_get_window_info: 0x%x: %s",
|
|
|
|
error->errnum, error->errmess));
|
|
|
|
warn_user("WimpError", error->errmess);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
2005-04-08 00:46:22 +04:00
|
|
|
/* work through all the icons */
|
2004-07-12 01:45:51 +04:00
|
|
|
state.w = w;
|
|
|
|
for (icon = 0; icon < window.icon_count; icon++) {
|
|
|
|
state.i = icon;
|
|
|
|
error = xwimp_get_icon_state(&state);
|
|
|
|
if (error) {
|
2004-08-31 01:57:47 +04:00
|
|
|
LOG(("xwimp_get_icon_state: 0x%x: %s",
|
2004-07-12 01:45:51 +04:00
|
|
|
error->errnum, error->errmess));
|
|
|
|
warn_user("WimpError", error->errmess);
|
|
|
|
return;
|
|
|
|
}
|
2004-07-27 19:49:28 +04:00
|
|
|
|
2005-04-08 00:46:22 +04:00
|
|
|
/* ignore if it's shaded or not writable */
|
2004-08-09 10:29:46 +04:00
|
|
|
if (state.icon.flags & wimp_ICON_SHADED)
|
|
|
|
continue;
|
2005-04-08 00:46:22 +04:00
|
|
|
b = (state.icon.flags >> wimp_ICON_BUTTON_TYPE_SHIFT) & 0xf;
|
|
|
|
if ((b != wimp_BUTTON_WRITE_CLICK_DRAG) &&
|
|
|
|
(b != wimp_BUTTON_WRITABLE))
|
|
|
|
continue;
|
2004-08-09 10:29:46 +04:00
|
|
|
|
2005-04-08 00:46:22 +04:00
|
|
|
/* move the caret */
|
|
|
|
error = xwimp_set_caret_position(w, icon, 0, 0, -1,
|
|
|
|
strlen(state.icon.data.indirected_text.text));
|
|
|
|
if (error) {
|
|
|
|
LOG(("xwimp_set_caret_position: 0x%x: %s",
|
|
|
|
error->errnum, error->errmess));
|
|
|
|
warn_user("WimpError", error->errmess);
|
2004-07-12 01:45:51 +04:00
|
|
|
}
|
2005-04-08 00:46:22 +04:00
|
|
|
return;
|
2004-07-12 01:45:51 +04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-05-23 03:04:44 +04:00
|
|
|
/**
|
|
|
|
* Load a sprite file into memory.
|
|
|
|
*
|
|
|
|
* \param pathname file to load
|
|
|
|
* \return sprite area, or 0 on memory exhaustion or error and error reported
|
|
|
|
*/
|
|
|
|
|
|
|
|
osspriteop_area *ro_gui_load_sprite_file(const char *pathname)
|
|
|
|
{
|
|
|
|
int len;
|
|
|
|
fileswitch_object_type obj_type;
|
|
|
|
osspriteop_area *area;
|
|
|
|
os_error *error;
|
|
|
|
|
|
|
|
error = xosfile_read_stamped_no_path(pathname,
|
|
|
|
&obj_type, 0, 0, &len, 0, 0);
|
|
|
|
if (error) {
|
|
|
|
LOG(("xosfile_read_stamped_no_path: 0x%x: %s",
|
|
|
|
error->errnum, error->errmess));
|
|
|
|
warn_user("MiscError", error->errmess);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (obj_type != fileswitch_IS_FILE) {
|
|
|
|
warn_user("FileError", pathname);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
area = malloc(len + 4);
|
|
|
|
if (!area) {
|
|
|
|
warn_user("NoMemory", 0);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
area->size = len + 4;
|
|
|
|
area->sprite_count = 0;
|
|
|
|
area->first = 16;
|
|
|
|
area->used = 16;
|
|
|
|
|
|
|
|
error = xosspriteop_load_sprite_file(osspriteop_USER_AREA,
|
|
|
|
area, pathname);
|
|
|
|
if (error) {
|
|
|
|
LOG(("xosspriteop_load_sprite_file: 0x%x: %s",
|
|
|
|
error->errnum, error->errmess));
|
|
|
|
warn_user("MiscError", error->errmess);
|
|
|
|
free(area);
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
return area;
|
|
|
|
}
|
2004-07-11 17:05:38 +04:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Check if a sprite is present in the Wimp sprite pool.
|
|
|
|
*
|
|
|
|
* \param sprite name of sprite
|
|
|
|
* \return true if the sprite is present
|
|
|
|
*/
|
|
|
|
|
|
|
|
bool ro_gui_wimp_sprite_exists(const char *sprite)
|
|
|
|
{
|
|
|
|
os_error *error;
|
|
|
|
|
|
|
|
error = xwimpspriteop_select_sprite(sprite, 0);
|
|
|
|
if (error) {
|
|
|
|
if (error->errnum != error_SPRITE_OP_DOESNT_EXIST) {
|
|
|
|
LOG(("xwimpspriteop_select_sprite: 0x%x: %s",
|
|
|
|
error->errnum, error->errmess));
|
|
|
|
warn_user("MiscError", error->errmess);
|
|
|
|
}
|
|
|
|
return false;
|
|
|
|
}
|
|
|
|
return true;
|
|
|
|
}
|
2004-07-27 19:49:28 +04:00
|
|
|
|
|
|
|
|
2005-07-16 09:54:45 +04:00
|
|
|
/**
|
|
|
|
* Locate a sprite in the Wimp sprite pool, returning a pointer to it.
|
|
|
|
*
|
2005-12-31 07:40:49 +03:00
|
|
|
* \param name sprite name
|
2005-07-16 09:54:45 +04:00
|
|
|
* \param sprite receives pointer to sprite if found
|
|
|
|
* \return error ptr iff not found
|
|
|
|
*/
|
|
|
|
|
|
|
|
os_error *ro_gui_wimp_get_sprite(const char *name, osspriteop_header **sprite)
|
|
|
|
{
|
|
|
|
osspriteop_area *rom_base, *ram_base;
|
|
|
|
os_error *error;
|
|
|
|
|
|
|
|
error = xwimp_base_of_sprites(&rom_base, &ram_base);
|
|
|
|
if (error) return error;
|
|
|
|
|
|
|
|
error = xosspriteop_select_sprite(osspriteop_USER_AREA,
|
|
|
|
rom_base, (osspriteop_id)name, sprite);
|
|
|
|
|
|
|
|
if (error && error->errnum == error_SPRITE_OP_DOESNT_EXIST)
|
|
|
|
error = xosspriteop_select_sprite(osspriteop_USER_AREA,
|
|
|
|
ram_base, (osspriteop_id)name, sprite);
|
|
|
|
|
|
|
|
return error;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2004-07-27 19:49:28 +04:00
|
|
|
/**
|
|
|
|
* Open a window as a pane in another window.
|
|
|
|
*
|
|
|
|
* \param parent parent window
|
2005-04-08 00:46:22 +04:00
|
|
|
* \param pane pane to open in parent window
|
2004-08-31 01:03:48 +04:00
|
|
|
* \param offset inset of pane from parent
|
2004-07-27 19:49:28 +04:00
|
|
|
*/
|
|
|
|
|
|
|
|
void ro_gui_open_pane(wimp_w parent, wimp_w pane, int offset)
|
|
|
|
{
|
|
|
|
wimp_window_state state;
|
|
|
|
os_error *error;
|
|
|
|
|
|
|
|
state.w = parent;
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
state.w = pane;
|
|
|
|
state.visible.x0 += offset;
|
2004-08-31 01:03:48 +04:00
|
|
|
state.visible.x1 -= offset;
|
|
|
|
state.visible.y0 += offset;
|
2004-07-27 19:49:28 +04:00
|
|
|
state.visible.y1 -= offset;
|
|
|
|
state.xscroll = 0;
|
|
|
|
state.yscroll = 0;
|
|
|
|
state.next = wimp_TOP;
|
|
|
|
error = xwimp_open_window_nested((wimp_open *) &state, parent,
|
|
|
|
wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT
|
|
|
|
<< wimp_CHILD_XORIGIN_SHIFT |
|
|
|
|
wimp_CHILD_LINKS_PARENT_VISIBLE_TOP_OR_RIGHT
|
|
|
|
<< wimp_CHILD_YORIGIN_SHIFT |
|
|
|
|
wimp_CHILD_LINKS_PARENT_VISIBLE_BOTTOM_OR_LEFT
|
2004-08-31 01:03:48 +04:00
|
|
|
<< wimp_CHILD_LS_EDGE_SHIFT |
|
2004-07-27 19:49:28 +04:00
|
|
|
wimp_CHILD_LINKS_PARENT_VISIBLE_TOP_OR_RIGHT
|
|
|
|
<< wimp_CHILD_BS_EDGE_SHIFT |
|
|
|
|
wimp_CHILD_LINKS_PARENT_VISIBLE_TOP_OR_RIGHT
|
|
|
|
<< wimp_CHILD_RS_EDGE_SHIFT |
|
|
|
|
wimp_CHILD_LINKS_PARENT_VISIBLE_TOP_OR_RIGHT
|
|
|
|
<< wimp_CHILD_TS_EDGE_SHIFT);
|
|
|
|
if (error) {
|
|
|
|
LOG(("xwimp_open_window_nested: 0x%x: %s",
|
|
|
|
error->errnum, error->errmess));
|
|
|
|
warn_user("WimpError", error->errmess);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
2005-03-14 16:58:43 +03:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Performs simple user redraw for a window.
|
|
|
|
*
|
2005-04-08 00:46:22 +04:00
|
|
|
* \param user_fill whether to fill the redraw area
|
2005-03-14 16:58:43 +03:00
|
|
|
* \param user_colour the colour to use when filling
|
|
|
|
*/
|
|
|
|
|
2005-04-08 00:46:22 +04:00
|
|
|
void ro_gui_user_redraw(wimp_draw *redraw, bool user_fill,
|
|
|
|
os_colour user_colour) {
|
2005-03-14 16:58:43 +03:00
|
|
|
os_error *error;
|
|
|
|
osbool more;
|
|
|
|
|
|
|
|
error = xwimp_redraw_window(redraw, &more);
|
|
|
|
if (error) {
|
|
|
|
LOG(("xwimp_redraw_window: 0x%x: %s",
|
|
|
|
error->errnum, error->errmess));
|
|
|
|
warn_user("WimpError", error->errmess);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
while (more) {
|
2005-04-08 00:46:22 +04:00
|
|
|
if (user_fill) {
|
2005-03-14 16:58:43 +03:00
|
|
|
error = xcolourtrans_set_gcol(user_colour,
|
|
|
|
colourtrans_SET_BG,
|
|
|
|
os_ACTION_OVERWRITE, 0, 0);
|
|
|
|
if (error) {
|
|
|
|
LOG(("xcolourtrans_set_gcol: 0x%x: %s",
|
|
|
|
error->errnum, error->errmess));
|
|
|
|
warn_user("MiscError", error->errmess);
|
|
|
|
}
|
|
|
|
os_clg();
|
2005-04-08 00:46:22 +04:00
|
|
|
}
|
2005-03-14 16:58:43 +03:00
|
|
|
error = xwimp_get_rectangle(redraw, &more);
|
|
|
|
if (error) {
|
|
|
|
LOG(("xwimp_get_rectangle: 0x%x: %s",
|
|
|
|
error->errnum, error->errmess));
|
|
|
|
warn_user("WimpError", error->errmess);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2005-04-08 00:46:22 +04:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Sets whether a piece of window furniture is present for a window.
|
|
|
|
*
|
|
|
|
* \param w the window to modify
|
|
|
|
* \param bic_mask the furniture flags to clear
|
|
|
|
* \param xor_mask the furniture flags to toggle
|
|
|
|
*/
|
|
|
|
void ro_gui_wimp_update_window_furniture(wimp_w w, wimp_window_flags bic_mask,
|
|
|
|
wimp_window_flags xor_mask) {
|
|
|
|
wimp_window_state state;
|
|
|
|
os_error *error;
|
|
|
|
bool open;
|
|
|
|
|
|
|
|
state.w = w;
|
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
|
|
|
open = state.flags & wimp_WINDOW_OPEN;
|
|
|
|
state.flags &= ~(63 << 16); /* clear bits 16-21 */
|
|
|
|
state.flags &= ~bic_mask;
|
|
|
|
state.flags ^= xor_mask;
|
|
|
|
if (!open)
|
|
|
|
state.next = wimp_HIDDEN;
|
|
|
|
error = xwimp_open_window_nested_with_flags(&state, (wimp_w)-1, 0);
|
|
|
|
if (error) {
|
|
|
|
LOG(("xwimp_open_window: 0x%x: %s",
|
|
|
|
error->errnum, error->errmess));
|
|
|
|
warn_user("WimpError", error->errmess);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
if (!open) {
|
|
|
|
error = xwimp_close_window(w);
|
|
|
|
if (error) {
|
|
|
|
LOG(("xwimp_close_window: 0x%x: %s",
|
|
|
|
error->errnum, error->errmess));
|
|
|
|
warn_user("WimpError", error->errmess);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2005-12-01 04:22:23 +03:00
|
|
|
|
|
|
|
|
|
|
|
/**
|
|
|
|
* Checks whether a piece of window furniture is present for a window.
|
|
|
|
*
|
|
|
|
* \param w the window to modify
|
2005-12-31 07:40:49 +03:00
|
|
|
* \param mask the furniture flags to check
|
2005-12-01 04:22:23 +03:00
|
|
|
*/
|
|
|
|
bool ro_gui_wimp_check_window_furniture(wimp_w w, wimp_window_flags mask) {
|
|
|
|
wimp_window_state state;
|
|
|
|
os_error *error;
|
|
|
|
|
|
|
|
state.w = w;
|
|
|
|
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 false;
|
|
|
|
}
|
|
|
|
return state.flags & mask;
|
|
|
|
}
|