Initial checkin of Pika from heckimp

This commit is contained in:
2023-09-25 15:35:21 -07:00
commit 891e999216
6761 changed files with 5240685 additions and 0 deletions

35
libpikabase/Makefile.gi Normal file
View File

@ -0,0 +1,35 @@
# Introspectable sources for libpikabase
libpikabase_introspectable = \
../libpikabase/pikabaseenums.h \
../libpikabase/pikabasetypes.h \
../libpikabase/pikabasetypes.c \
../libpikabase/pikalimits.h \
../libpikabase/pikaversion.h \
\
../libpikabase/pikachecks.c \
../libpikabase/pikachecks.h \
../libpikabase/pikacpuaccel.c \
../libpikabase/pikacpuaccel.h \
../libpikabase/pikaenv.c \
../libpikabase/pikaenv.h \
../libpikabase/pikamemsize.c \
../libpikabase/pikamemsize.h \
../libpikabase/pikametadata.c \
../libpikabase/pikametadata.h \
../libpikabase/pikaparamspecs.c \
../libpikabase/pikaparamspecs.h \
../libpikabase/pikaparasite.c \
../libpikabase/pikaparasite.h \
../libpikabase/pikaparasiteio.c \
../libpikabase/pikaparasiteio.h \
../libpikabase/pikarectangle.c \
../libpikabase/pikarectangle.h \
../libpikabase/pikasignal.c \
../libpikabase/pikasignal.h \
../libpikabase/pikaunit.c \
../libpikabase/pikaunit.h \
../libpikabase/pikautils.c \
../libpikabase/pikautils.h \
../libpikabase/pikavaluearray.c \
../libpikabase/pikavaluearray.h

152
libpikabase/meson.build Normal file
View File

@ -0,0 +1,152 @@
if platform_osx
add_project_arguments('-ObjC', language : 'c')
endif
pikaversion = configure_file(
input : 'pikaversion.h.in',
output: 'pikaversion.h',
configuration: versionconfig,
)
stamp_base_enums = custom_target('stamp-pikabaseenums.h',
input : [
files(
'pikabaseenums.h'
),
],
output: [ 'stamp-pikabaseenums.h', ],
command: [
mkenums_wrap, perl,
meson.project_source_root(), meson.current_source_dir(),
meson.current_build_dir(),
'pikabase',
'#include <glib-object.h>\n' +
'#undef PIKA_DISABLE_DEPRECATED\n' +
'#include "pikabasetypes.h"\n' +
'#include "libpika/libpika-intl.h"\n',
'',
libpika_mkenums_dtails
],
build_by_default: true
)
stamp_compat_enums = custom_target('stamp-pikacompatenums.h',
input : [
files(
'pikacompatenums.h'
),
],
output: [ 'stamp-pikacompatenums.h', ],
command: [
mkenums_wrap, perl,
meson.project_source_root(), meson.current_source_dir(), meson.current_build_dir(),
'pikacompat',
'#include <glib-object.h>\n' +
'#include "pikabasetypes.h"\n',
'#include "libpika/libpika-intl.h"',
],
build_by_default: true
)
libpikabase_sources_introspectable = files(
'pikabasetypes.c',
'pikachecks.c',
'pikacpuaccel.c',
'pikaenv.c',
'pikamemsize.c',
'pikametadata.c',
'pikaparamspecs.c',
'pikaparasite.c',
'pikaparasiteio.c',
'pikarectangle.c',
'pikasignal.c',
'pikaunit.c',
'pikautils.c',
'pikavaluearray.c',
)
libpikabase_sources = [
libpikabase_sources_introspectable,
'pikabase-private.c',
'pikaprotocol.c',
'pikareloc.c',
'pikawire.c',
'pikabaseenums.c',
stamp_base_enums,
'pikacompatenums.c',
stamp_compat_enums
]
libpikabase_headers_introspectable = files(
'pikabaseenums.h',
'pikabasetypes.h',
'pikachecks.h',
'pikacpuaccel.h',
'pikaenv.h',
'pikalimits.h',
'pikamemsize.h',
'pikametadata.h',
'pikaparamspecs.h',
'pikaparasite.h',
'pikaparasiteio.h',
'pikarectangle.h',
'pikasignal.h',
'pikaunit.h',
'pikautils.h',
'pikavaluearray.h',
) + [
pikaversion,
]
libpikabase_headers = [
libpikabase_headers_introspectable,
'pikabase.h',
pikaversion,
]
libpikabase_introspectable = [
libpikabase_sources_introspectable,
libpikabase_headers_introspectable,
]
libpikabase = library('pikabase-' + pika_api_version,
libpikabase_sources,
include_directories: rootInclude,
dependencies: [
gexiv2, gio, math,
# optionally depend on libexecinfo on platforms where it is not
# internal to the libc.
opt_execinfo,
],
c_args: [
'-DG_LOG_DOMAIN="LibPikaBase"',
'-DPIKA_BASE_COMPILATION',
],
vs_module_defs: 'pikabase.def',
install: true,
version: so_version,
)
install_headers(
libpikabase_headers,
subdir: pika_api_name / 'libpikabase',
)
# Test program, not installed
executable('test-cpu-accel',
'test-cpu-accel.c',
include_directories: rootInclude,
dependencies: [
glib,
],
c_args: [
'-DG_LOG_DOMAIN="LibPikaBase"',
'-DPIKA_BASE_COMPILATION',
],
link_with: [
libpikabase,
],
install: false,
)

View File

@ -0,0 +1,73 @@
/* LIBPIKA - The PIKA Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* pikabase-private.c
* Copyright (C) 2003 Sven Neumann <sven@gimp.org>
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <gio/gio.h>
#include "pikabasetypes.h"
#include "pikabase-private.h"
#include "pikacompatenums.h"
PikaUnitVtable _pika_unit_vtable = { NULL, };
void
pika_base_init (PikaUnitVtable *vtable)
{
static gboolean pika_base_initialized = FALSE;
g_return_if_fail (vtable != NULL);
if (pika_base_initialized)
g_error ("pika_base_init() must only be called once!");
_pika_unit_vtable = *vtable;
pika_base_compat_enums_init ();
pika_base_initialized = TRUE;
}
void
pika_base_compat_enums_init (void)
{
#if 0
static gboolean pika_base_compat_initialized = FALSE;
GQuark quark;
if (pika_base_compat_initialized)
return;
quark = g_quark_from_static_string ("pika-compat-enum");
/* This is how a compat enum is registered, leave one here for
* documentation purposes, remove it as soon as we get a real
* compat enum again
*/
g_type_set_qdata (PIKA_TYPE_ADD_MASK_TYPE, quark,
(gpointer) PIKA_TYPE_ADD_MASK_TYPE_COMPAT);
pika_base_compat_initialized = TRUE;
#endif
}

View File

@ -0,0 +1,69 @@
/* LIBPIKA - The PIKA Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* pikabase-private.h
* Copyright (C) 2003 Sven Neumann <sven@gimp.org>
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <https://www.gnu.org/licenses/>.
*/
#ifndef __PIKA_BASE_PRIVATE_H__
#define __PIKA_BASE_PRIVATE_H__
typedef struct _PikaUnitVtable PikaUnitVtable;
struct _PikaUnitVtable
{
gint (* unit_get_number_of_units) (void);
gint (* unit_get_number_of_built_in_units) (void);
PikaUnit (* unit_new) (gchar *identifier,
gdouble factor,
gint digits,
gchar *symbol,
gchar *abbreviation,
gchar *singular,
gchar *plural);
gboolean (* unit_get_deletion_flag) (PikaUnit unit);
void (* unit_set_deletion_flag) (PikaUnit unit,
gboolean deletion_flag);
gdouble (* unit_get_factor) (PikaUnit unit);
gint (* unit_get_digits) (PikaUnit unit);
const gchar * (* unit_get_identifier) (PikaUnit unit);
const gchar * (* unit_get_symbol) (PikaUnit unit);
const gchar * (* unit_get_abbreviation) (PikaUnit unit);
const gchar * (* unit_get_singular) (PikaUnit unit);
const gchar * (* unit_get_plural) (PikaUnit unit);
void (* _reserved_1) (void);
void (* _reserved_2) (void);
void (* _reserved_3) (void);
void (* _reserved_4) (void);
};
extern PikaUnitVtable _pika_unit_vtable;
G_BEGIN_DECLS
void pika_base_init (PikaUnitVtable *vtable);
void pika_base_compat_enums_init (void);
G_END_DECLS
#endif /* __PIKA_BASE_PRIVATE_H__ */

265
libpikabase/pikabase.def Normal file
View File

@ -0,0 +1,265 @@
EXPORTS
gp_config_write
gp_extension_ack_write
gp_has_init_write
gp_init
gp_proc_install_write
gp_proc_return_write
gp_proc_run_write
gp_proc_uninstall_write
gp_quit_write
gp_temp_proc_return_write
gp_temp_proc_run_write
gp_tile_ack_write
gp_tile_data_write
gp_tile_req_write
pika_add_mask_type_get_type
pika_any_to_utf8
pika_array_copy
pika_array_free
pika_array_get_type
pika_array_new
pika_base_compat_enums_init
pika_base_init
pika_bind_text_domain
pika_brush_generated_shape_get_type
pika_cache_directory
pika_canonicalize_identifier
pika_cap_style_get_type
pika_channel_ops_get_type
pika_channel_type_get_type
pika_check_size_get_type
pika_check_type_get_type
pika_checks_get_colors
pika_clone_type_get_type
pika_color_tag_get_type
pika_component_type_get_type
pika_convert_palette_type_get_type
pika_convolve_type_get_type
pika_cpu_accel_get_support
pika_cpu_accel_set_use
pika_data_directory
pika_data_directory_file
pika_desaturate_mode_get_type
pika_directory
pika_directory_file
pika_dodge_burn_type_get_type
pika_enum_get_desc
pika_enum_get_value
pika_enum_get_value_descriptions
pika_enum_set_value_descriptions
pika_enum_value_get_abbrev
pika_enum_value_get_desc
pika_enum_value_get_help
pika_env_init
pika_escape_uline
pika_file_get_utf8_name
pika_file_has_extension
pika_file_show_in_file_manager
pika_filename_to_utf8
pika_fill_type_get_type
pika_flags_get_first_desc
pika_flags_get_first_value
pika_flags_get_value_descriptions
pika_flags_set_value_descriptions
pika_flags_value_get_abbrev
pika_flags_value_get_desc
pika_flags_value_get_help
pika_float_array_get_type
pika_foreground_extract_mode_get_type
pika_gradient_blend_color_space_get_type
pika_gradient_segment_color_get_type
pika_gradient_segment_type_get_type
pika_gradient_type_get_type
pika_grid_style_get_type
pika_hue_range_get_type
pika_icon_type_get_type
pika_image_base_type_get_type
pika_image_type_get_type
pika_ink_blob_type_get_type
pika_installation_directory
pika_installation_directory_file
pika_int32_array_get_type
pika_interpolation_type_get_type
pika_is_canonical_identifier
pika_join_style_get_type
pika_locale_directory
pika_locale_directory_file
pika_major_version
pika_mask_apply_mode_get_type
pika_memsize_deserialize
pika_memsize_get_type
pika_memsize_serialize
pika_merge_type_get_type
pika_message_handler_type_get_type
pika_metadata_add_xmp_history
pika_metadata_deserialize
pika_metadata_duplicate
pika_metadata_get_colorspace
pika_metadata_get_guid
pika_metadata_get_resolution
pika_metadata_get_type
pika_metadata_is_tag_supported
pika_metadata_load_from_file
pika_metadata_new
pika_metadata_save_to_file
pika_metadata_serialize
pika_metadata_set_bits_per_sample
pika_metadata_set_colorspace
pika_metadata_set_from_exif
pika_metadata_set_from_iptc
pika_metadata_set_from_xmp
pika_metadata_set_pixel_size
pika_metadata_set_resolution
pika_micro_version
pika_minor_version
pika_object_array_copy
pika_object_array_free
pika_object_array_get_type
pika_object_array_new
pika_offset_type_get_type
pika_orientation_type_get_type
pika_paint_application_mode_get_type
pika_param_array_get_type
pika_param_float_array_get_type
pika_param_int32_array_get_type
pika_param_memsize_get_type
pika_param_object_array_get_type
pika_param_parasite_get_type
pika_param_rgb_array_get_type
pika_param_spec_array
pika_param_spec_float_array
pika_param_spec_int32_array
pika_param_spec_memsize
pika_param_spec_object_array
pika_param_spec_parasite
pika_param_spec_rgb_array
pika_param_spec_unit
pika_param_spec_value_array
pika_param_unit_get_type
pika_param_value_array_get_type
pika_parasite_compare
pika_parasite_copy
pika_parasite_free
pika_parasite_get_data
pika_parasite_get_flags
pika_parasite_get_name
pika_parasite_get_type
pika_parasite_has_flag
pika_parasite_is_persistent
pika_parasite_is_type
pika_parasite_is_undoable
pika_parasite_new
pika_path_free
pika_path_get_user_writable_dir
pika_path_parse
pika_path_to_str
pika_pdb_error_handler_get_type
pika_pdb_proc_type_get_type
pika_pdb_status_type_get_type
pika_pixels_to_units
pika_pixpipe_params_build
pika_pixpipe_params_free
pika_pixpipe_params_init
pika_pixpipe_params_parse
pika_plug_in_directory
pika_plug_in_directory_file
pika_precision_get_type
pika_procedure_sensitivity_mask_get_type
pika_progress_command_get_type
pika_range_estimate_settings
pika_rectangle_intersect
pika_rectangle_union
pika_repeat_mode_get_type
pika_rgb_array_get_type
pika_rotation_type_get_type
pika_run_mode_get_type
pika_select_criterion_get_type
pika_signal_private
pika_size_type_get_type
pika_stack_trace_available
pika_stack_trace_mode_get_type
pika_stack_trace_print
pika_stack_trace_query
pika_strip_uline
pika_stroke_method_get_type
pika_sysconf_directory
pika_sysconf_directory_file
pika_temp_directory
pika_text_direction_get_type
pika_text_hint_style_get_type
pika_text_justification_get_type
pika_transfer_mode_get_type
pika_transform_direction_get_type
pika_transform_resize_get_type
pika_type_get_translation_context
pika_type_get_translation_domain
pika_type_set_translation_context
pika_type_set_translation_domain
pika_unit_format_string
pika_unit_get_abbreviation
pika_unit_get_deletion_flag
pika_unit_get_digits
pika_unit_get_factor
pika_unit_get_identifier
pika_unit_get_number_of_built_in_units
pika_unit_get_number_of_units
pika_unit_get_plural
pika_unit_get_scaled_digits
pika_unit_get_singular
pika_unit_get_symbol
pika_unit_get_type
pika_unit_is_metric
pika_unit_new
pika_unit_set_deletion_flag
pika_units_to_pixels
pika_units_to_points
pika_utf8_strtrim
pika_value_array_append
pika_value_array_copy
pika_value_array_get_type
pika_value_array_index
pika_value_array_insert
pika_value_array_length
pika_value_array_new
pika_value_array_new_from_types
pika_value_array_new_from_types_valist
pika_value_array_new_from_values
pika_value_array_prepend
pika_value_array_ref
pika_value_array_remove
pika_value_array_truncate
pika_value_array_unref
pika_value_dup_float_array
pika_value_dup_int32_array
pika_value_dup_object_array
pika_value_dup_rgb_array
pika_value_get_float_array
pika_value_get_int32_array
pika_value_get_object_array
pika_value_get_rgb_array
pika_value_set_float_array
pika_value_set_int32_array
pika_value_set_object_array
pika_value_set_rgb_array
pika_value_set_static_float_array
pika_value_set_static_int32_array
pika_value_set_static_object_array
pika_value_set_static_rgb_array
pika_value_take_float_array
pika_value_take_int32_array
pika_value_take_object_array
pika_value_take_rgb_array
pika_vectors_stroke_type_get_type
pika_wire_clear_error
pika_wire_destroy
pika_wire_error
pika_wire_flush
pika_wire_read
pika_wire_read_msg
pika_wire_register
pika_wire_set_flusher
pika_wire_set_reader
pika_wire_set_writer
pika_wire_write
pika_wire_write_msg

46
libpikabase/pikabase.h Normal file
View File

@ -0,0 +1,46 @@
/* LIBPIKA - The PIKA Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <https://www.gnu.org/licenses/>.
*/
#ifndef __PIKA_BASE_H__
#define __PIKA_BASE_H__
#define __PIKA_BASE_H_INSIDE__
#include <libpikabase/pikabasetypes.h>
#include <libpikabase/pikachecks.h>
#include <libpikabase/pikacpuaccel.h>
#include <libpikabase/pikaenv.h>
#include <libpikabase/pikalimits.h>
#include <libpikabase/pikamemsize.h>
#include <libpikabase/pikametadata.h>
#include <libpikabase/pikaparamspecs.h>
#include <libpikabase/pikaparasite.h>
#include <libpikabase/pikarectangle.h>
#include <libpikabase/pikaunit.h>
#include <libpikabase/pikautils.h>
#include <libpikabase/pikaversion.h>
#include <libpikabase/pikavaluearray.h>
#ifndef G_OS_WIN32
#include <libpikabase/pikasignal.h>
#endif
#undef __PIKA_BASE_H_INSIDE__
#endif /* __PIKA_BASE_H__ */

1930
libpikabase/pikabaseenums.c Normal file

File diff suppressed because it is too large Load Diff

1322
libpikabase/pikabaseenums.h Normal file

File diff suppressed because it is too large Load Diff

244
libpikabase/pikabasetypes.c Normal file
View File

@ -0,0 +1,244 @@
/* LIBPIKA - The PIKA Library
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
*
* pikabasetypes.c
* Copyright (C) 2004 Sven Neumann <sven@gimp.org>
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <glib-object.h>
#include "pikabasetypes.h"
/**
* SECTION: pikabasetypes
* @title: pikabasetypes
* @short_description: Translation between gettext translation domain
* identifier and GType.
*
* Translation between gettext translation domain identifier and
* GType.
**/
static GQuark pika_translation_domain_quark (void) G_GNUC_CONST;
static GQuark pika_translation_context_quark (void) G_GNUC_CONST;
static GQuark pika_value_descriptions_quark (void) G_GNUC_CONST;
/**
* pika_type_set_translation_domain:
* @type: a #GType
* @domain: a constant string that identifies a translation domain or %NULL
*
* This function attaches a constant string as a gettext translation
* domain identifier to a #GType. The only purpose of this function is
* to use it when registering a #G_TYPE_ENUM with translatable value
* names.
*
* Since: 2.2
**/
void
pika_type_set_translation_domain (GType type,
const gchar *domain)
{
g_type_set_qdata (type,
pika_translation_domain_quark (), (gpointer) domain);
}
/**
* pika_type_get_translation_domain:
* @type: a #GType
*
* Retrieves the gettext translation domain identifier that has been
* previously set using pika_type_set_translation_domain(). You should
* not need to use this function directly, use pika_enum_get_value()
* or pika_enum_value_get_desc() instead.
*
* Returns: the translation domain associated with @type
* or %NULL if no domain was set
*
* Since: 2.2
**/
const gchar *
pika_type_get_translation_domain (GType type)
{
return (const gchar *) g_type_get_qdata (type,
pika_translation_domain_quark ());
}
/**
* pika_type_set_translation_context:
* @type: a #GType
* @context: a constant string that identifies a translation context or %NULL
*
* This function attaches a constant string as a translation context
* to a #GType. The only purpose of this function is to use it when
* registering a #G_TYPE_ENUM with translatable value names.
*
* Since: 2.8
**/
void
pika_type_set_translation_context (GType type,
const gchar *context)
{
g_type_set_qdata (type,
pika_translation_context_quark (), (gpointer) context);
}
/**
* pika_type_get_translation_context:
* @type: a #GType
*
* Retrieves the translation context that has been previously set
* using pika_type_set_translation_context(). You should not need to
* use this function directly, use pika_enum_get_value() or
* pika_enum_value_get_desc() instead.
*
* Returns: the translation context associated with @type
* or %NULL if no context was set
*
* Since: 2.8
**/
const gchar *
pika_type_get_translation_context (GType type)
{
return (const gchar *) g_type_get_qdata (type,
pika_translation_context_quark ());
}
/**
* pika_enum_set_value_descriptions:
* @enum_type: a #GType
* @descriptions: a %NULL terminated constant static array of #PikaEnumDesc
*
* Sets the array of human readable and translatable descriptions
* and help texts for enum values.
*
* Since: 2.2
**/
void
pika_enum_set_value_descriptions (GType enum_type,
const PikaEnumDesc *descriptions)
{
g_return_if_fail (g_type_is_a (enum_type, G_TYPE_ENUM));
g_return_if_fail (descriptions != NULL);
g_type_set_qdata (enum_type,
pika_value_descriptions_quark (),
(gpointer) descriptions);
}
/**
* pika_enum_get_value_descriptions:
* @enum_type: a #GType
*
* Retrieves the array of human readable and translatable descriptions
* and help texts for enum values.
*
* Returns: a %NULL terminated constant array of #PikaEnumDesc
*
* Since: 2.2
**/
const PikaEnumDesc *
pika_enum_get_value_descriptions (GType enum_type)
{
g_return_val_if_fail (g_type_is_a (enum_type, G_TYPE_ENUM), NULL);
return (const PikaEnumDesc *)
g_type_get_qdata (enum_type, pika_value_descriptions_quark ());
}
/**
* pika_flags_set_value_descriptions:
* @flags_type: a #GType
* @descriptions: a %NULL terminated constant static array of #PikaFlagsDesc
*
* Sets the array of human readable and translatable descriptions
* and help texts for flags values.
*
* Since: 2.2
**/
void
pika_flags_set_value_descriptions (GType flags_type,
const PikaFlagsDesc *descriptions)
{
g_return_if_fail (g_type_is_a (flags_type, G_TYPE_FLAGS));
g_return_if_fail (descriptions != NULL);
g_type_set_qdata (flags_type,
pika_value_descriptions_quark (),
(gpointer) descriptions);
}
/**
* pika_flags_get_value_descriptions:
* @flags_type: a #GType
*
* Retrieves the array of human readable and translatable descriptions
* and help texts for flags values.
*
* Returns: a %NULL terminated constant array of #PikaFlagsDesc
*
* Since: 2.2
**/
const PikaFlagsDesc *
pika_flags_get_value_descriptions (GType flags_type)
{
g_return_val_if_fail (g_type_is_a (flags_type, G_TYPE_FLAGS), NULL);
return (const PikaFlagsDesc *)
g_type_get_qdata (flags_type, pika_value_descriptions_quark ());
}
/* private functions */
static GQuark
pika_translation_domain_quark (void)
{
static GQuark quark = 0;
if (! quark)
quark = g_quark_from_static_string ("pika-translation-domain-quark");
return quark;
}
static GQuark
pika_translation_context_quark (void)
{
static GQuark quark = 0;
if (! quark)
quark = g_quark_from_static_string ("pika-translation-context-quark");
return quark;
}
static GQuark
pika_value_descriptions_quark (void)
{
static GQuark quark = 0;
if (! quark)
quark = g_quark_from_static_string ("pika-value-descriptions-quark");
return quark;
}

107
libpikabase/pikabasetypes.h Normal file
View File

@ -0,0 +1,107 @@
/* LIBPIKA - The PIKA Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <https://www.gnu.org/licenses/>.
*/
#ifndef __PIKA_BASE_TYPES_H__
#define __PIKA_BASE_TYPES_H__
#include <libpikacolor/pikacolortypes.h>
#include <libpikamath/pikamathtypes.h>
#include <libpikabase/pikabaseenums.h>
G_BEGIN_DECLS
/* For information look into the C source or the html documentation */
/* XXX FIXME move these to a separate file */
#ifdef PIKA_DISABLE_DEPRECATION_WARNINGS
#define PIKA_DEPRECATED
#define PIKA_DEPRECATED_FOR(f)
#define PIKA_UNAVAILABLE(maj,min)
#else
#define PIKA_DEPRECATED G_DEPRECATED
#define PIKA_DEPRECATED_FOR(f) G_DEPRECATED_FOR(f)
#define PIKA_UNAVAILABLE(maj,min) G_UNAVAILABLE(maj,min)
#endif
typedef struct _PikaParasite PikaParasite;
typedef struct _PikaEnumDesc PikaEnumDesc;
typedef struct _PikaFlagsDesc PikaFlagsDesc;
typedef struct _PikaValueArray PikaValueArray;
typedef struct _PikaMetadata PikaMetadata;
/**
* PikaEnumDesc:
* @value: An enum value.
* @value_desc: The value's description.
* @value_help: The value's help text.
*
* This structure is used to register translatable descriptions and
* help texts for enum values. See pika_enum_set_value_descriptions().
**/
struct _PikaEnumDesc
{
gint value;
const gchar *value_desc;
const gchar *value_help;
};
/**
* PikaFlagsDesc:
* @value: A flag value.
* @value_desc: The value's description.
* @value_help: The value's help text.
*
* This structure is used to register translatable descriptions and
* help texts for flag values. See pika_flags_set_value_descriptions().
**/
struct _PikaFlagsDesc
{
guint value;
const gchar *value_desc;
const gchar *value_help;
};
void pika_type_set_translation_domain (GType type,
const gchar *domain);
const gchar * pika_type_get_translation_domain (GType type);
void pika_type_set_translation_context (GType type,
const gchar *context);
const gchar * pika_type_get_translation_context (GType type);
void pika_enum_set_value_descriptions (GType enum_type,
const PikaEnumDesc *descriptions);
const PikaEnumDesc * pika_enum_get_value_descriptions (GType enum_type);
void pika_flags_set_value_descriptions (GType flags_type,
const PikaFlagsDesc *descriptions);
const PikaFlagsDesc * pika_flags_get_value_descriptions (GType flags_type);
G_END_DECLS
#endif /* __PIKA_BASE_TYPES_H__ */

124
libpikabase/pikachecks.c Normal file
View File

@ -0,0 +1,124 @@
/* LIBPIKA - The PIKA Library
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
*
* pikachecks.c
* Copyright (C) 2004 Sven Neumann <sven@gimp.org>
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <glib-object.h>
#include "pikabasetypes.h"
#include "pikachecks.h"
/**
* SECTION: pikachecks
* @title: pikachecks
* @short_description: Constants and functions related to rendering
* checkerboards.
*
* Constants and functions related to rendering checkerboards.
**/
/**
* pika_checks_get_colors:
* @type: the checkerboard type
* @color1: (inout): current custom color and return location for the first color.
* @color2: (inout): current custom color and return location for the second color.
*
* Retrieves the colors to use when drawing a checkerboard for a certain
* #PikaCheckType and custom colors.
* If @type is %PIKA_CHECK_TYPE_CUSTOM_CHECKS, then @color1 and @color2
* will remain untouched, which means you must initialize them to the
* values expected for custom checks.
*
* To obtain the user-set colors in Preferences, just call:
* |[<!-- language="C" -->
* PikaRGB color1 = *(pika_check_custom_color1 ());
* PikaRGB color2 = *(pika_check_custom_color2 ());
* pika_checks_get_colors (pika_check_type (), &color1, &color2);
* ]|
*
* Since: 3.0
**/
void
pika_checks_get_colors (PikaCheckType type,
PikaRGB *color1,
PikaRGB *color2)
{
g_return_if_fail (color1 != NULL || color2 != NULL);
if (color1)
{
switch (type)
{
case PIKA_CHECK_TYPE_LIGHT_CHECKS:
*color1 = PIKA_CHECKS_LIGHT_COLOR_LIGHT;
break;
case PIKA_CHECK_TYPE_DARK_CHECKS:
*color1 = PIKA_CHECKS_DARK_COLOR_LIGHT;
break;
case PIKA_CHECK_TYPE_WHITE_ONLY:
*color1 = PIKA_CHECKS_WHITE_COLOR;
break;
case PIKA_CHECK_TYPE_GRAY_ONLY:
*color1 = PIKA_CHECKS_GRAY_COLOR;
break;
case PIKA_CHECK_TYPE_BLACK_ONLY:
*color1 = PIKA_CHECKS_BLACK_COLOR;
break;
case PIKA_CHECK_TYPE_CUSTOM_CHECKS:
/* Keep the current value. */
break;
default:
*color1 = PIKA_CHECKS_GRAY_COLOR_LIGHT;
break;
}
}
if (color2)
{
switch (type)
{
case PIKA_CHECK_TYPE_LIGHT_CHECKS:
*color2 = PIKA_CHECKS_LIGHT_COLOR_DARK;
break;
case PIKA_CHECK_TYPE_DARK_CHECKS:
*color2 = PIKA_CHECKS_DARK_COLOR_DARK;
break;
case PIKA_CHECK_TYPE_WHITE_ONLY:
*color2 = PIKA_CHECKS_WHITE_COLOR;
break;
case PIKA_CHECK_TYPE_GRAY_ONLY:
*color2 = PIKA_CHECKS_GRAY_COLOR;
break;
case PIKA_CHECK_TYPE_BLACK_ONLY:
*color2 = PIKA_CHECKS_BLACK_COLOR;
break;
case PIKA_CHECK_TYPE_CUSTOM_CHECKS:
/* Keep the current value. */
break;
default:
*color2 = PIKA_CHECKS_GRAY_COLOR_DARK;
break;
}
}
}

145
libpikabase/pikachecks.h Normal file
View File

@ -0,0 +1,145 @@
/* LIBPIKA - The PIKA Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <https://www.gnu.org/licenses/>.
*/
#if !defined (__PIKA_BASE_H_INSIDE__) && !defined (PIKA_BASE_COMPILATION)
#error "Only <libpikabase/pikabase.h> can be included directly."
#endif
#ifndef __PIKA_CHECKS_H__
#define __PIKA_CHECKS_H__
G_BEGIN_DECLS
/**
* PIKA_CHECK_SIZE:
*
* The default checkerboard size in pixels. This is configurable in
* the core but PIKA plug-ins can't access the user preference and
* should use this constant instead.
**/
#define PIKA_CHECK_SIZE 8
/**
* PIKA_CHECK_SIZE_SM:
*
* The default small checkerboard size in pixels.
**/
#define PIKA_CHECK_SIZE_SM 4
/**
* PIKA_CHECK_DARK:
*
* The dark gray value for the default checkerboard pattern.
**/
#define PIKA_CHECK_DARK 0.4
/**
* PIKA_CHECK_LIGHT:
*
* The dark light value for the default checkerboard pattern.
**/
#define PIKA_CHECK_LIGHT 0.6
/**
* PIKA_CHECKS_LIGHT_COLOR_DARK:
*
* The dark color for the light checkerboard type.
**/
#define PIKA_CHECKS_LIGHT_COLOR_DARK ((PikaRGB) { 0.8, 0.8, 0.8, 1.0 })
/**
* PIKA_CHECKS_LIGHT_COLOR_LIGHT:
*
* The light color for the light checkerboard type.
**/
#define PIKA_CHECKS_LIGHT_COLOR_LIGHT ((PikaRGB) { 1.0, 1.0, 1.0, 1.0 })
/**
* PIKA_CHECKS_GRAY_COLOR_DARK:
*
* The dark color for the gray checkerboard type.
**/
#define PIKA_CHECKS_GRAY_COLOR_DARK ((PikaRGB) { 0.4, 0.4, 0.4, 1.0 })
/**
* PIKA_CHECKS_GRAY_COLOR_LIGHT:
*
* The light color for the gray checkerboard type.
**/
#define PIKA_CHECKS_GRAY_COLOR_LIGHT ((PikaRGB) { 0.6, 0.6, 0.6, 1.0 })
/**
* PIKA_CHECKS_DARK_COLOR_DARK:
*
* The dark color for the dark checkerboard type.
**/
#define PIKA_CHECKS_DARK_COLOR_DARK ((PikaRGB) { 0.0, 0.0, 0.0, 1.0 })
/**
* PIKA_CHECKS_DARK_COLOR_LIGHT:
*
* The light color for the dark checkerboard type.
**/
#define PIKA_CHECKS_DARK_COLOR_LIGHT ((PikaRGB) { 0.2, 0.2, 0.2, 1.0 })
/**
* PIKA_CHECKS_WHITE_COLOR:
*
* The light/dark color for the white checkerboard type.
**/
#define PIKA_CHECKS_WHITE_COLOR ((PikaRGB) { 1.0, 1.0, 1.0, 1.0 })
/**
* PIKA_CHECKS_GRAY_COLOR:
*
* The light/dark color for the gray checkerboard type.
**/
#define PIKA_CHECKS_GRAY_COLOR ((PikaRGB) { 0.5, 0.5, 0.5, 1.0 })
/**
* PIKA_CHECKS_BLACK_COLOR:
*
* The light/dark color for the black checkerboard type.
**/
#define PIKA_CHECKS_BLACK_COLOR ((PikaRGB) { 0.0, 0.0, 0.0, 1.0 })
/**
* PIKA_CHECKS_CUSTOM_COLOR1:
*
* The default color 1 for the custom checkerboard type.
**/
#define PIKA_CHECKS_CUSTOM_COLOR1 PIKA_CHECKS_GRAY_COLOR_LIGHT
/**
* PIKA_CHECKS_CUSTOM_COLOR2:
*
* The default color 2 for the custom checkerboard type.
**/
#define PIKA_CHECKS_CUSTOM_COLOR2 PIKA_CHECKS_GRAY_COLOR_DARK
void pika_checks_get_colors (PikaCheckType type,
PikaRGB *color1,
PikaRGB *color2);
G_END_DECLS
#endif /* __PIKA_CHECKS_H__ */

View File

@ -0,0 +1,12 @@
/* Generated data (by pika-mkenums) */
#include "stamp-pikacompatenums.h"
#include "config.h"
#include <glib-object.h>
#include "pikabasetypes.h"
#include "pikacompatenums.h"
#include "libpika/libpika-intl.h"
/* Generated data ends here */

View File

@ -0,0 +1,54 @@
/* LIBPIKA - The PIKA Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <https://www.gnu.org/licenses/>.
*/
#ifndef __PIKA_COMPAT_ENUMS_H__
#define __PIKA_COMPAT_ENUMS_H__
G_BEGIN_DECLS
/* These enums exist only for compatibility, their nicks are needed
* for config file parsing; they are registered in pika_base_init().
*/
#if 0
/* Leave one enum here for documentation purposes, remove it as
* soon as we need a real compat enum again, also don't have
* that "skip" on the compat enum...
*/
#define PIKA_TYPE_ADD_MASK_TYPE_COMPAT (pika_add_mask_type_compat_get_type ())
GType pika_add_mask_type_compat_get_type (void) G_GNUC_CONST;
typedef enum /*< skip >*/
{
PIKA_ADD_WHITE_MASK = PIKA_ADD_MASK_WHITE,
PIKA_ADD_BLACK_MASK = PIKA_ADD_MASK_BLACK,
PIKA_ADD_ALPHA_MASK = PIKA_ADD_MASK_ALPHA,
PIKA_ADD_ALPHA_TRANSFER_MASK = PIKA_ADD_MASK_ALPHA_TRANSFER,
PIKA_ADD_SELECTION_MASK = PIKA_ADD_MASK_SELECTION,
PIKA_ADD_COPY_MASK = PIKA_ADD_MASK_COPY,
PIKA_ADD_CHANNEL_MASK = PIKA_ADD_MASK_CHANNEL
} PikaAddMaskTypeCompat;
#endif
G_END_DECLS
#endif /* __PIKA_COMPAT_ENUMS_H__ */

531
libpikabase/pikacpuaccel.c Normal file
View File

@ -0,0 +1,531 @@
/* LIBPIKA - The PIKA Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <https://www.gnu.org/licenses/>.
*/
/*
* x86 bits Copyright (C) Manish Singh <yosh@gimp.org>
*/
/*
* PPC CPU acceleration detection was taken from DirectFB but seems to be
* originating from mpeg2dec with the following copyright:
*
* Copyright (C) 1999-2001 Aaron Holtzman <aholtzma@ess.engr.uvic.ca>
*/
#include "config.h"
#include <string.h>
#include <signal.h>
#include <setjmp.h>
#include <glib.h>
#include "pikacpuaccel.h"
/**
* SECTION: pikacpuaccel
* @title: pikacpuaccel
* @short_description: Functions to query and configure CPU acceleration.
*
* Functions to query and configure CPU acceleration.
**/
static PikaCpuAccelFlags cpu_accel (void) G_GNUC_CONST;
static gboolean use_cpu_accel = TRUE;
/**
* pika_cpu_accel_get_support:
*
* Query for CPU acceleration support.
*
* Returns: #PikaCpuAccelFlags as supported by the CPU.
*
* Since: 2.4
*/
PikaCpuAccelFlags
pika_cpu_accel_get_support (void)
{
return use_cpu_accel ? cpu_accel () : PIKA_CPU_ACCEL_NONE;
}
/**
* pika_cpu_accel_set_use:
* @use: whether to use CPU acceleration features or not
*
* This function is for internal use only.
*
* Since: 2.4
*/
void
pika_cpu_accel_set_use (gboolean use)
{
use_cpu_accel = use ? TRUE : FALSE;
}
#if defined(ARCH_X86) && defined(USE_MMX) && defined(__GNUC__)
#define HAVE_ACCEL 1
typedef enum
{
ARCH_X86_VENDOR_NONE,
ARCH_X86_VENDOR_INTEL,
ARCH_X86_VENDOR_AMD,
ARCH_X86_VENDOR_CENTAUR,
ARCH_X86_VENDOR_CYRIX,
ARCH_X86_VENDOR_NSC,
ARCH_X86_VENDOR_TRANSMETA,
ARCH_X86_VENDOR_NEXGEN,
ARCH_X86_VENDOR_RISE,
ARCH_X86_VENDOR_UMC,
ARCH_X86_VENDOR_SIS,
ARCH_X86_VENDOR_HYGON,
ARCH_X86_VENDOR_UNKNOWN = 0xff
} X86Vendor;
enum
{
ARCH_X86_INTEL_FEATURE_MMX = 1 << 23,
ARCH_X86_INTEL_FEATURE_XMM = 1 << 25,
ARCH_X86_INTEL_FEATURE_XMM2 = 1 << 26,
ARCH_X86_AMD_FEATURE_MMXEXT = 1 << 22,
ARCH_X86_AMD_FEATURE_3DNOW = 1 << 31,
ARCH_X86_CENTAUR_FEATURE_MMX = 1 << 23,
ARCH_X86_CENTAUR_FEATURE_MMXEXT = 1 << 24,
ARCH_X86_CENTAUR_FEATURE_3DNOW = 1 << 31,
ARCH_X86_CYRIX_FEATURE_MMX = 1 << 23,
ARCH_X86_CYRIX_FEATURE_MMXEXT = 1 << 24
};
enum
{
ARCH_X86_INTEL_FEATURE_PNI = 1 << 0,
ARCH_X86_INTEL_FEATURE_SSSE3 = 1 << 9,
ARCH_X86_INTEL_FEATURE_SSE4_1 = 1 << 19,
ARCH_X86_INTEL_FEATURE_SSE4_2 = 1 << 20,
ARCH_X86_INTEL_FEATURE_AVX = 1 << 28
};
#if !defined(ARCH_X86_64) && (defined(PIC) || defined(__PIC__))
#define cpuid(op,eax,ebx,ecx,edx) \
__asm__ ("movl %%ebx, %%esi\n\t" \
"cpuid\n\t" \
"xchgl %%ebx,%%esi" \
: "=a" (eax), \
"=S" (ebx), \
"=c" (ecx), \
"=d" (edx) \
: "0" (op))
#else
#define cpuid(op,eax,ebx,ecx,edx) \
__asm__ ("cpuid" \
: "=a" (eax), \
"=b" (ebx), \
"=c" (ecx), \
"=d" (edx) \
: "0" (op))
#endif
static X86Vendor
arch_get_vendor (void)
{
guint32 eax, ebx, ecx, edx;
union{
gchar idaschar[16];
int idasint[4];
}id;
#ifndef ARCH_X86_64
/* Only need to check this on ia32 */
__asm__ ("pushfl\n\t"
"pushfl\n\t"
"popl %0\n\t"
"movl %0,%1\n\t"
"xorl $0x200000,%0\n\t"
"pushl %0\n\t"
"popfl\n\t"
"pushfl\n\t"
"popl %0\n\t"
"popfl"
: "=a" (eax),
"=c" (ecx)
:
: "cc");
if (eax == ecx)
return ARCH_X86_VENDOR_NONE;
#endif
cpuid (0, eax, ebx, ecx, edx);
if (eax == 0)
return ARCH_X86_VENDOR_NONE;
id.idasint[0] = ebx;
id.idasint[1] = edx;
id.idasint[2] = ecx;
id.idaschar[12] = '\0';
#ifdef ARCH_X86_64
if (strcmp (id.idaschar, "AuthenticAMD") == 0)
return ARCH_X86_VENDOR_AMD;
else if (strcmp (id.idaschar, "HygonGenuine") == 0)
return ARCH_X86_VENDOR_HYGON;
else if (strcmp (id.idaschar, "GenuineIntel") == 0)
return ARCH_X86_VENDOR_INTEL;
#else
if (strcmp (id.idaschar, "GenuineIntel") == 0)
return ARCH_X86_VENDOR_INTEL;
else if (strcmp (id.idaschar, "AuthenticAMD") == 0)
return ARCH_X86_VENDOR_AMD;
else if (strcmp (id.idaschar, "HygonGenuine") == 0)
return ARCH_X86_VENDOR_HYGON;
else if (strcmp (id.idaschar, "CentaurHauls") == 0)
return ARCH_X86_VENDOR_CENTAUR;
else if (strcmp (id.idaschar, "CyrixInstead") == 0)
return ARCH_X86_VENDOR_CYRIX;
else if (strcmp (id.idaschar, "Geode by NSC") == 0)
return ARCH_X86_VENDOR_NSC;
else if (strcmp (id.idaschar, "GenuineTMx86") == 0 ||
strcmp (id.idaschar, "TransmetaCPU") == 0)
return ARCH_X86_VENDOR_TRANSMETA;
else if (strcmp (id.idaschar, "NexGenDriven") == 0)
return ARCH_X86_VENDOR_NEXGEN;
else if (strcmp (id.idaschar, "RiseRiseRise") == 0)
return ARCH_X86_VENDOR_RISE;
else if (strcmp (id.idaschar, "UMC UMC UMC ") == 0)
return ARCH_X86_VENDOR_UMC;
else if (strcmp (id.idaschar, "SiS SiS SiS ") == 0)
return ARCH_X86_VENDOR_SIS;
#endif
return ARCH_X86_VENDOR_UNKNOWN;
}
static guint32
arch_accel_intel (void)
{
guint32 caps = 0;
#ifdef USE_MMX
{
guint32 eax, ebx, ecx, edx;
cpuid (1, eax, ebx, ecx, edx);
if ((edx & ARCH_X86_INTEL_FEATURE_MMX) == 0)
return 0;
caps = PIKA_CPU_ACCEL_X86_MMX;
#ifdef USE_SSE
if (edx & ARCH_X86_INTEL_FEATURE_XMM)
caps |= PIKA_CPU_ACCEL_X86_SSE | PIKA_CPU_ACCEL_X86_MMXEXT;
if (edx & ARCH_X86_INTEL_FEATURE_XMM2)
caps |= PIKA_CPU_ACCEL_X86_SSE2;
if (ecx & ARCH_X86_INTEL_FEATURE_PNI)
caps |= PIKA_CPU_ACCEL_X86_SSE3;
if (ecx & ARCH_X86_INTEL_FEATURE_SSSE3)
caps |= PIKA_CPU_ACCEL_X86_SSSE3;
if (ecx & ARCH_X86_INTEL_FEATURE_SSE4_1)
caps |= PIKA_CPU_ACCEL_X86_SSE4_1;
if (ecx & ARCH_X86_INTEL_FEATURE_SSE4_2)
caps |= PIKA_CPU_ACCEL_X86_SSE4_2;
if (ecx & ARCH_X86_INTEL_FEATURE_AVX)
caps |= PIKA_CPU_ACCEL_X86_AVX;
#endif /* USE_SSE */
}
#endif /* USE_MMX */
return caps;
}
static guint32
arch_accel_amd (void)
{
guint32 caps;
caps = arch_accel_intel ();
#ifdef USE_MMX
{
guint32 eax, ebx, ecx, edx;
cpuid (0x80000000, eax, ebx, ecx, edx);
if (eax < 0x80000001)
return caps;
#ifdef USE_SSE
cpuid (0x80000001, eax, ebx, ecx, edx);
if (edx & ARCH_X86_AMD_FEATURE_3DNOW)
caps |= PIKA_CPU_ACCEL_X86_3DNOW;
if (edx & ARCH_X86_AMD_FEATURE_MMXEXT)
caps |= PIKA_CPU_ACCEL_X86_MMXEXT;
#endif /* USE_SSE */
}
#endif /* USE_MMX */
return caps;
}
static guint32
arch_accel_centaur (void)
{
guint32 caps;
caps = arch_accel_intel ();
#ifdef USE_MMX
{
guint32 eax, ebx, ecx, edx;
cpuid (0x80000000, eax, ebx, ecx, edx);
if (eax < 0x80000001)
return caps;
cpuid (0x80000001, eax, ebx, ecx, edx);
if (edx & ARCH_X86_CENTAUR_FEATURE_MMX)
caps |= PIKA_CPU_ACCEL_X86_MMX;
#ifdef USE_SSE
if (edx & ARCH_X86_CENTAUR_FEATURE_3DNOW)
caps |= PIKA_CPU_ACCEL_X86_3DNOW;
if (edx & ARCH_X86_CENTAUR_FEATURE_MMXEXT)
caps |= PIKA_CPU_ACCEL_X86_MMXEXT;
#endif /* USE_SSE */
}
#endif /* USE_MMX */
return caps;
}
static guint32
arch_accel_cyrix (void)
{
guint32 caps;
caps = arch_accel_intel ();
#ifdef USE_MMX
{
guint32 eax, ebx, ecx, edx;
cpuid (0, eax, ebx, ecx, edx);
if (eax != 2)
return caps;
cpuid (0x80000001, eax, ebx, ecx, edx);
if (edx & ARCH_X86_CYRIX_FEATURE_MMX)
caps |= PIKA_CPU_ACCEL_X86_MMX;
#ifdef USE_SSE
if (edx & ARCH_X86_CYRIX_FEATURE_MMXEXT)
caps |= PIKA_CPU_ACCEL_X86_MMXEXT;
#endif /* USE_SSE */
}
#endif /* USE_MMX */
return caps;
}
#ifdef USE_SSE
static jmp_buf sigill_return;
static void
sigill_handler (gint n)
{
longjmp (sigill_return, 1);
}
static gboolean
arch_accel_sse_os_support (void)
{
if (setjmp (sigill_return))
{
return FALSE;
}
else
{
signal (SIGILL, sigill_handler);
__asm__ __volatile__ ("xorps %xmm0, %xmm0");
signal (SIGILL, SIG_DFL);
}
return TRUE;
}
#endif /* USE_SSE */
static guint32
arch_accel (void)
{
guint32 caps;
X86Vendor vendor;
vendor = arch_get_vendor ();
switch (vendor)
{
case ARCH_X86_VENDOR_NONE:
caps = 0;
break;
case ARCH_X86_VENDOR_AMD:
case ARCH_X86_VENDOR_HYGON:
caps = arch_accel_amd ();
break;
case ARCH_X86_VENDOR_CENTAUR:
caps = arch_accel_centaur ();
break;
case ARCH_X86_VENDOR_CYRIX:
case ARCH_X86_VENDOR_NSC:
caps = arch_accel_cyrix ();
break;
/* check for what Intel speced, even if UNKNOWN */
default:
caps = arch_accel_intel ();
break;
}
#ifdef USE_SSE
if ((caps & PIKA_CPU_ACCEL_X86_SSE) && !arch_accel_sse_os_support ())
caps &= ~(PIKA_CPU_ACCEL_X86_SSE | PIKA_CPU_ACCEL_X86_SSE2);
#endif
return caps;
}
#endif /* ARCH_X86 && USE_MMX && __GNUC__ */
#if defined(ARCH_PPC) && defined (USE_ALTIVEC)
#if defined(HAVE_ALTIVEC_SYSCTL)
#include <sys/sysctl.h>
#define HAVE_ACCEL 1
static guint32
arch_accel (void)
{
gint sels[2] = { CTL_HW, HW_VECTORUNIT };
gboolean has_vu = FALSE;
gsize length = sizeof(has_vu);
gint err;
err = sysctl (sels, 2, &has_vu, &length, NULL, 0);
if (err == 0 && has_vu)
return PIKA_CPU_ACCEL_PPC_ALTIVEC;
return 0;
}
#elif defined(__GNUC__)
#define HAVE_ACCEL 1
static sigjmp_buf jmpbuf;
static volatile sig_atomic_t canjump = 0;
static void
sigill_handler (gint sig)
{
if (!canjump)
{
signal (sig, SIG_DFL);
raise (sig);
}
canjump = 0;
siglongjmp (jmpbuf, 1);
}
static guint32
arch_accel (void)
{
signal (SIGILL, sigill_handler);
if (sigsetjmp (jmpbuf, 1))
{
signal (SIGILL, SIG_DFL);
return 0;
}
canjump = 1;
asm volatile ("mtspr 256, %0\n\t"
"vand %%v0, %%v0, %%v0"
:
: "r" (-1));
signal (SIGILL, SIG_DFL);
return PIKA_CPU_ACCEL_PPC_ALTIVEC;
}
#endif /* __GNUC__ */
#endif /* ARCH_PPC && USE_ALTIVEC */
static PikaCpuAccelFlags
cpu_accel (void)
{
#ifdef HAVE_ACCEL
static guint32 accel = ~0U;
if (accel != ~0U)
return accel;
accel = arch_accel ();
return (PikaCpuAccelFlags) accel;
#else /* !HAVE_ACCEL */
return PIKA_CPU_ACCEL_NONE;
#endif
}

View File

@ -0,0 +1,76 @@
/* LIBPIKA - The PIKA Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <https://www.gnu.org/licenses/>.
*/
#if !defined (__PIKA_BASE_H_INSIDE__) && !defined (PIKA_BASE_COMPILATION)
#error "Only <libpikabase/pikabase.h> can be included directly."
#endif
#ifndef __PIKA_CPU_ACCEL_H__
#define __PIKA_CPU_ACCEL_H__
G_BEGIN_DECLS
/**
* PikaCpuAccelFlags:
* @PIKA_CPU_ACCEL_NONE: None
* @PIKA_CPU_ACCEL_X86_MMX: MMX
* @PIKA_CPU_ACCEL_X86_3DNOW: 3dNow
* @PIKA_CPU_ACCEL_X86_MMXEXT: MMXEXT
* @PIKA_CPU_ACCEL_X86_SSE: SSE
* @PIKA_CPU_ACCEL_X86_SSE2: SSE2
* @PIKA_CPU_ACCEL_X86_SSE3: SSE3
* @PIKA_CPU_ACCEL_X86_SSSE3: SSSE3
* @PIKA_CPU_ACCEL_X86_SSE4_1: SSE4_1
* @PIKA_CPU_ACCEL_X86_SSE4_2: SSE4_2
* @PIKA_CPU_ACCEL_X86_AVX: AVX
* @PIKA_CPU_ACCEL_PPC_ALTIVEC: Altivec
*
* Types of detectable CPU accelerations
**/
typedef enum
{
PIKA_CPU_ACCEL_NONE = 0x0,
/* x86 accelerations */
PIKA_CPU_ACCEL_X86_MMX = 0x80000000,
PIKA_CPU_ACCEL_X86_3DNOW = 0x40000000,
PIKA_CPU_ACCEL_X86_MMXEXT = 0x20000000,
PIKA_CPU_ACCEL_X86_SSE = 0x10000000,
PIKA_CPU_ACCEL_X86_SSE2 = 0x08000000,
PIKA_CPU_ACCEL_X86_SSE3 = 0x02000000,
PIKA_CPU_ACCEL_X86_SSSE3 = 0x01000000,
PIKA_CPU_ACCEL_X86_SSE4_1 = 0x00800000,
PIKA_CPU_ACCEL_X86_SSE4_2 = 0x00400000,
PIKA_CPU_ACCEL_X86_AVX = 0x00200000,
/* powerpc accelerations */
PIKA_CPU_ACCEL_PPC_ALTIVEC = 0x04000000
} PikaCpuAccelFlags;
PikaCpuAccelFlags pika_cpu_accel_get_support (void);
/* for internal use only */
void pika_cpu_accel_set_use (gboolean use);
G_END_DECLS
#endif /* __PIKA_CPU_ACCEL_H__ */

1205
libpikabase/pikaenv.c Normal file

File diff suppressed because it is too large Load Diff

87
libpikabase/pikaenv.h Normal file
View File

@ -0,0 +1,87 @@
/* LIBPIKA - The PIKA Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* pikaenv.h
* Copyright (C) 1999 Tor Lillqvist <tml@iki.fi>
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <https://www.gnu.org/licenses/>.
*/
#if !defined (__PIKA_BASE_H_INSIDE__) && !defined (PIKA_BASE_COMPILATION)
#error "Only <libpikabase/pikabase.h> can be included directly."
#endif
#ifndef __PIKA_ENV_H__
#define __PIKA_ENV_H__
G_BEGIN_DECLS
/* For information look into the C source or the html documentation */
#ifdef G_OS_WIN32
# ifdef __PIKA_ENV_C__
# define PIKAVAR extern __declspec(dllexport)
# else /* !__PIKA_ENV_C__ */
# define PIKAVAR extern __declspec(dllimport)
# endif /* !__PIKA_ENV_C__ */
#else /* !G_OS_WIN32 */
# define PIKAVAR extern
#endif
PIKAVAR const guint pika_major_version;
PIKAVAR const guint pika_minor_version;
PIKAVAR const guint pika_micro_version;
const gchar * pika_directory (void) G_GNUC_CONST;
const gchar * pika_installation_directory (void) G_GNUC_CONST;
const gchar * pika_data_directory (void) G_GNUC_CONST;
const gchar * pika_locale_directory (void) G_GNUC_CONST;
const gchar * pika_sysconf_directory (void) G_GNUC_CONST;
const gchar * pika_plug_in_directory (void) G_GNUC_CONST;
const gchar * pika_cache_directory (void) G_GNUC_CONST;
const gchar * pika_temp_directory (void) G_GNUC_CONST;
GFile * pika_directory_file (const gchar *first_element,
...) G_GNUC_MALLOC;
GFile * pika_installation_directory_file (const gchar *first_element,
...) G_GNUC_MALLOC;
GFile * pika_data_directory_file (const gchar *first_element,
...) G_GNUC_MALLOC;
GFile * pika_locale_directory_file (const gchar *first_element,
...) G_GNUC_MALLOC;
GFile * pika_sysconf_directory_file (const gchar *first_element,
...) G_GNUC_MALLOC;
GFile * pika_plug_in_directory_file (const gchar *first_element,
...) G_GNUC_MALLOC;
GList * pika_path_parse (const gchar *path,
gint max_paths,
gboolean check,
GList **check_failed);
gchar * pika_path_to_str (GList *path) G_GNUC_MALLOC;
void pika_path_free (GList *path);
gchar * pika_path_get_user_writable_dir (GList *path) G_GNUC_MALLOC;
/* should be considered private, don't use! */
void pika_env_init (gboolean plug_in);
G_END_DECLS
#endif /* __PIKA_ENV_H__ */

97
libpikabase/pikalimits.h Normal file
View File

@ -0,0 +1,97 @@
/* LIBPIKA - The PIKA Library
* Copyright (C) 1995-1999 Peter Mattis and Spencer Kimball
*
* pikalimits.h
* Copyright (C) 1999 Michael Natterer <mitschel@cs.tu-berlin.de>
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <https://www.gnu.org/licenses/>.
*/
#if !defined (__PIKA_BASE_H_INSIDE__) && !defined (PIKA_BASE_COMPILATION)
#error "Only <libpikabase/pikabase.h> can be included directly."
#endif
#ifndef __PIKA_LIMITS_H__
#define __PIKA_LIMITS_H__
G_BEGIN_DECLS
/**
* SECTION: pikalimits
* @title: pikalimits
* @short_description: Boundaries of some PIKA data types and some
* global constants.
*
* Boundaries of some PIKA data types and some global constants.
**/
/**
* PIKA_MIN_IMAGE_SIZE:
*
* The minimum width and height of a PIKA image in pixels.
**/
#define PIKA_MIN_IMAGE_SIZE 1
/**
* PIKA_MAX_IMAGE_SIZE:
*
* The maximum width and height of a PIKA image in pixels. This is a
* somewhat arbitrary value that can be used when an upper value for
* pixel sizes is needed; for example to give a spin button an upper
* limit.
**/
#define PIKA_MAX_IMAGE_SIZE 524288 /* 2^19 */
/**
* PIKA_MIN_RESOLUTION:
*
* The minimum resolution of a PIKA image in pixels per inch. This is
* a somewhat arbitrary value that can be used when a lower value for a
* resolution is needed. PIKA will not accept resolutions smaller than
* this value.
**/
#define PIKA_MIN_RESOLUTION 5e-3 /* shouldn't display as 0.000 */
/**
* PIKA_MAX_RESOLUTION:
*
* The maximum resolution of a PIKA image in pixels per inch. This is
* a somewhat arbitrary value that can be used to when an upper value
* for a resolution is needed. PIKA will not accept resolutions larger
* than this value.
**/
#define PIKA_MAX_RESOLUTION 1048576.0
/**
* PIKA_MAX_MEMSIZE:
*
* A large but arbitrary value that can be used when an upper limit
* for a memory size (in bytes) is needed. It is smaller than
* %G_MAXDOUBLE since the #PikaMemsizeEntry doesn't handle larger
* values.
**/
#define PIKA_MAX_MEMSIZE ((guint64) 1 << 42) /* 4 terabyte;
* needs a 64bit variable
* and must be < G_MAXDOUBLE
*/
G_END_DECLS
#endif /* __PIKA_LIMITS_H__ */

273
libpikabase/pikamemsize.c Normal file
View File

@ -0,0 +1,273 @@
/* LIBPIKA - The PIKA Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <errno.h>
#include <glib-object.h>
#include "pikabasetypes.h"
#include "pikamemsize.h"
#include "libpika/libpika-intl.h"
/**
* SECTION: pikamemsize
* @title: pikamemsize
* @short_description: Functions to (de)serialize a given memory size.
*
* Functions to (de)serialize a given memory size.
**/
static void memsize_to_string (const GValue *src_value,
GValue *dest_value);
static void string_to_memsize (const GValue *src_value,
GValue *dest_value);
GType
pika_memsize_get_type (void)
{
static GType memsize_type = 0;
if (! memsize_type)
{
const GTypeInfo type_info = { 0, };
memsize_type = g_type_register_static (G_TYPE_UINT64, "PikaMemsize",
&type_info, 0);
g_value_register_transform_func (memsize_type, G_TYPE_STRING,
memsize_to_string);
g_value_register_transform_func (G_TYPE_STRING, memsize_type,
string_to_memsize);
}
return memsize_type;
}
/**
* pika_memsize_serialize:
* @memsize: memory size in bytes
*
* Creates a string representation of a given memory size. This string
* can be parsed by pika_memsize_deserialize() and can thus be used in
* config files. It should not be displayed to the user. If you need a
* nice human-readable string please use g_format_size().
*
* Returns: A newly allocated string representation of @memsize.
*
* Since: 2.2
**/
gchar *
pika_memsize_serialize (guint64 memsize)
{
if (memsize > (1 << 30) && memsize % (1 << 30) == 0)
return g_strdup_printf ("%" G_GUINT64_FORMAT "G", memsize >> 30);
else if (memsize > (1 << 20) && memsize % (1 << 20) == 0)
return g_strdup_printf ("%" G_GUINT64_FORMAT "M", memsize >> 20);
else if (memsize > (1 << 10) && memsize % (1 << 10) == 0)
return g_strdup_printf ("%" G_GUINT64_FORMAT "k", memsize >> 10);
else
return g_strdup_printf ("%" G_GUINT64_FORMAT, memsize);
}
/**
* pika_memsize_deserialize:
* @string: a string as returned by pika_memsize_serialize()
* @memsize: return location for memory size in bytes
*
* Parses a string representation of a memory size as returned by
* pika_memsize_serialize().
*
* Returns: %TRUE if the @string was successfully parsed and
* @memsize has been set, %FALSE otherwise.
*
* Since: 2.2
**/
gboolean
pika_memsize_deserialize (const gchar *string,
guint64 *memsize)
{
gchar *end;
guint64 size;
g_return_val_if_fail (string != NULL, FALSE);
g_return_val_if_fail (memsize != NULL, FALSE);
size = g_ascii_strtoull (string, &end, 0);
if (size == G_MAXUINT64 && errno == ERANGE)
return FALSE;
if (end && *end)
{
guint shift;
switch (g_ascii_tolower (*end))
{
case 'b':
shift = 0;
break;
case 'k':
shift = 10;
break;
case 'm':
shift = 20;
break;
case 'g':
shift = 30;
break;
default:
return FALSE;
}
/* protect against overflow */
if (shift)
{
guint64 limit = G_MAXUINT64 >> shift;
if (size != (size & limit))
return FALSE;
size <<= shift;
}
}
*memsize = size;
return TRUE;
}
static void
memsize_to_string (const GValue *src_value,
GValue *dest_value)
{
g_value_take_string (dest_value,
pika_memsize_serialize (g_value_get_uint64 (src_value)));
}
static void
string_to_memsize (const GValue *src_value,
GValue *dest_value)
{
const gchar *str;
guint64 memsize;
str = g_value_get_string (src_value);
if (str && pika_memsize_deserialize (str, &memsize))
{
g_value_set_uint64 (dest_value, memsize);
}
else
{
g_warning ("Can't convert string to PikaMemsize.");
}
}
/*
* PIKA_TYPE_PARAM_MEMSIZE
*/
static void pika_param_memsize_class_init (GParamSpecClass *class);
/**
* pika_param_memsize_get_type:
*
* Reveals the object type
*
* Returns: the #GType for a memsize object
*
* Since: 2.4
**/
GType
pika_param_memsize_get_type (void)
{
static GType spec_type = 0;
if (! spec_type)
{
const GTypeInfo type_info =
{
sizeof (GParamSpecClass),
NULL, NULL,
(GClassInitFunc) pika_param_memsize_class_init,
NULL, NULL,
sizeof (GParamSpecUInt64),
0, NULL, NULL
};
spec_type = g_type_register_static (G_TYPE_PARAM_UINT64,
"PikaParamMemsize",
&type_info, 0);
}
return spec_type;
}
static void
pika_param_memsize_class_init (GParamSpecClass *class)
{
class->value_type = PIKA_TYPE_MEMSIZE;
}
/**
* pika_param_spec_memsize:
* @name: Canonical name of the param
* @nick: Nickname of the param
* @blurb: Brief description of param.
* @minimum: Smallest allowed value of the parameter.
* @maximum: Largest allowed value of the parameter.
* @default_value: Value to use if none is assigned.
* @flags: a combination of #GParamFlags
*
* Creates a param spec to hold a memory size value.
* See g_param_spec_internal() for more information.
*
* Returns: (transfer full): a newly allocated #GParamSpec instance
*
* Since: 2.4
**/
GParamSpec *
pika_param_spec_memsize (const gchar *name,
const gchar *nick,
const gchar *blurb,
guint64 minimum,
guint64 maximum,
guint64 default_value,
GParamFlags flags)
{
GParamSpecUInt64 *pspec;
pspec = g_param_spec_internal (PIKA_TYPE_PARAM_MEMSIZE,
name, nick, blurb, flags);
pspec->minimum = minimum;
pspec->maximum = maximum;
pspec->default_value = default_value;
return G_PARAM_SPEC (pspec);
}

65
libpikabase/pikamemsize.h Normal file
View File

@ -0,0 +1,65 @@
/* LIBPIKA - The PIKA Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <https://www.gnu.org/licenses/>.
*/
#if !defined (__PIKA_BASE_H_INSIDE__) && !defined (PIKA_BASE_COMPILATION)
#error "Only <libpikabase/pikabase.h> can be included directly."
#endif
#ifndef __PIKA_MEMSIZE_H__
#define __PIKA_MEMSIZE_H__
G_BEGIN_DECLS
/**
* PIKA_TYPE_MEMSIZE:
*
* #PIKA_TYPE_MEMSIZE is a #GType derived from #G_TYPE_UINT64.
**/
#define PIKA_TYPE_MEMSIZE (pika_memsize_get_type ())
#define PIKA_VALUE_HOLDS_MEMSIZE(value) (G_TYPE_CHECK_VALUE_TYPE ((value), PIKA_TYPE_MEMSIZE))
GType pika_memsize_get_type (void) G_GNUC_CONST;
gchar * pika_memsize_serialize (guint64 memsize) G_GNUC_MALLOC;
gboolean pika_memsize_deserialize (const gchar *string,
guint64 *memsize);
/*
* PIKA_TYPE_PARAM_MEMSIZE
*/
#define PIKA_TYPE_PARAM_MEMSIZE (pika_param_memsize_get_type ())
#define PIKA_IS_PARAM_SPEC_MEMSIZE(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), PIKA_TYPE_PARAM_MEMSIZE))
GType pika_param_memsize_get_type (void) G_GNUC_CONST;
GParamSpec * pika_param_spec_memsize (const gchar *name,
const gchar *nick,
const gchar *blurb,
guint64 minimum,
guint64 maximum,
guint64 default_value,
GParamFlags flags);
G_END_DECLS
#endif /* __PIKA_MEMSIZE_H__ */

2027
libpikabase/pikametadata.c Normal file

File diff suppressed because it is too large Load Diff

157
libpikabase/pikametadata.h Normal file
View File

@ -0,0 +1,157 @@
/* LIBPIKABASE - The PIKA Basic Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* pikametadata.h
* Copyright (C) 2013 Hartmut Kuhse <hartmutkuhse@src.gnome.org>
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <https://www.gnu.org/licenses/>.
*/
#ifndef __PIKA_METADATA_H__
#define __PIKA_METADATA_H__
G_BEGIN_DECLS
#define PIKA_TYPE_METADATA (pika_metadata_get_type ())
#define PIKA_METADATA(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), PIKA_TYPE_METADATA, PikaMetadata))
#define PIKA_METADATA_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), PIKA_TYPE_METADATA, PikaMetadataClass))
#define PIKA_IS_METADATA(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), PIKA_TYPE_METADATA))
#define PIKA_IS_METADATA_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), PIKA_TYPE_METADATA))
#define PIKA_METADATA_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), PIKA_TYPE_METADATA, PikaMetadataClass))
/**
* PikaMetadataLoadFlags:
* @PIKA_METADATA_LOAD_COMMENT: Load the comment
* @PIKA_METADATA_LOAD_RESOLUTION: Load the resolution
* @PIKA_METADATA_LOAD_ORIENTATION: Load the orientation (rotation)
* @PIKA_METADATA_LOAD_COLORSPACE: Load the colorspace
* @PIKA_METADATA_LOAD_ALL: Load all of the above
*
* What metadata to load when importing images.
**/
typedef enum
{
PIKA_METADATA_LOAD_COMMENT = 1 << 0,
PIKA_METADATA_LOAD_RESOLUTION = 1 << 1,
PIKA_METADATA_LOAD_ORIENTATION = 1 << 2,
PIKA_METADATA_LOAD_COLORSPACE = 1 << 3,
PIKA_METADATA_LOAD_ALL = 0xffffffff
} PikaMetadataLoadFlags;
/**
* PikaMetadataSaveFlags:
* @PIKA_METADATA_SAVE_EXIF: Save EXIF
* @PIKA_METADATA_SAVE_XMP: Save XMP
* @PIKA_METADATA_SAVE_IPTC: Save IPTC
* @PIKA_METADATA_SAVE_THUMBNAIL: Save a thumbnail of the image
* @PIKA_METADATA_SAVE_COLOR_PROFILE: Save the image's color profile
* Since: 2.10.10
* @PIKA_METADATA_SAVE_COMMENT: Save the image's comment
* Since: 3.0
* @PIKA_METADATA_SAVE_ALL: Save all of the above
*
* What kinds of metadata to save when exporting images.
**/
typedef enum
{
PIKA_METADATA_SAVE_EXIF = 1 << 0,
PIKA_METADATA_SAVE_XMP = 1 << 1,
PIKA_METADATA_SAVE_IPTC = 1 << 2,
PIKA_METADATA_SAVE_THUMBNAIL = 1 << 3,
PIKA_METADATA_SAVE_COLOR_PROFILE = 1 << 4,
PIKA_METADATA_SAVE_COMMENT = 1 << 5,
PIKA_METADATA_SAVE_ALL = 0xffffffff
} PikaMetadataSaveFlags;
/**
* PikaMetadataColorspace:
* @PIKA_METADATA_COLORSPACE_UNSPECIFIED: Unspecified
* @PIKA_METADATA_COLORSPACE_UNCALIBRATED: Uncalibrated
* @PIKA_METADATA_COLORSPACE_SRGB: sRGB
* @PIKA_METADATA_COLORSPACE_ADOBERGB: Adobe RGB
*
* Well-defined colorspace information available from metadata
**/
typedef enum
{
PIKA_METADATA_COLORSPACE_UNSPECIFIED,
PIKA_METADATA_COLORSPACE_UNCALIBRATED,
PIKA_METADATA_COLORSPACE_SRGB,
PIKA_METADATA_COLORSPACE_ADOBERGB
} PikaMetadataColorspace;
GType pika_metadata_get_type (void) G_GNUC_CONST;
PikaMetadata * pika_metadata_new (void);
PikaMetadata * pika_metadata_duplicate (PikaMetadata *metadata);
PikaMetadata * pika_metadata_deserialize (const gchar *metadata_xml);
gchar * pika_metadata_serialize (PikaMetadata *metadata);
gchar * pika_metadata_get_guid (void);
void pika_metadata_add_xmp_history (PikaMetadata *metadata,
gchar *state_status);
PikaMetadata * pika_metadata_load_from_file (GFile *file,
GError **error);
gboolean pika_metadata_save_to_file (PikaMetadata *metadata,
GFile *file,
GError **error);
gboolean pika_metadata_set_from_exif (PikaMetadata *metadata,
const guchar *exif_data,
gint exif_data_length,
GError **error);
gboolean pika_metadata_set_from_iptc (PikaMetadata *metadata,
const guchar *iptc_data,
gint iptc_data_length,
GError **error);
gboolean pika_metadata_set_from_xmp (PikaMetadata *metadata,
const guchar *xmp_data,
gint xmp_data_length,
GError **error);
void pika_metadata_set_pixel_size (PikaMetadata *metadata,
gint width,
gint height);
void pika_metadata_set_bits_per_sample (PikaMetadata *metadata,
gint bits_per_sample);
gboolean pika_metadata_get_resolution (PikaMetadata *metadata,
gdouble *xres,
gdouble *yres,
PikaUnit *unit);
void pika_metadata_set_resolution (PikaMetadata *metadata,
gdouble xres,
gdouble yres,
PikaUnit unit);
PikaMetadataColorspace
pika_metadata_get_colorspace (PikaMetadata *metadata);
void pika_metadata_set_colorspace (PikaMetadata *metadata,
PikaMetadataColorspace colorspace);
gboolean pika_metadata_is_tag_supported (const gchar *tag,
const gchar *mime_type);
G_END_DECLS
#endif /* __PIKA_METADATA_H__ */

1139
libpikabase/pikaparamspecs.c Normal file

File diff suppressed because it is too large Load Diff

View File

@ -0,0 +1,343 @@
/* LIBPIKA - The PIKA Library
* Copyright (C) 1995-2003 Peter Mattis and Spencer Kimball
*
* pikaparamspecs.h
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <https://www.gnu.org/licenses/>.
*/
#if !defined (__PIKA_BASE_H_INSIDE__) && !defined (PIKA_BASE_COMPILATION)
#error "Only <libpikabase/pikabase.h> can be included directly."
#endif
#ifndef __PIKA_PARAM_SPECS_H__
#define __PIKA_PARAM_SPECS_H__
G_BEGIN_DECLS
/* For information look into the C source or the html documentation */
/**
* PIKA_PARAM_NO_VALIDATE:
*
* Since 3.0
*/
/*
* Keep in sync with libpikaconfig/pikaconfig-params.h
*/
#define PIKA_PARAM_NO_VALIDATE (1 << (6 + G_PARAM_USER_SHIFT))
/**
* PIKA_PARAM_STATIC_STRINGS:
*
* Since: 2.4
**/
#define PIKA_PARAM_STATIC_STRINGS (G_PARAM_STATIC_NAME | \
G_PARAM_STATIC_NICK | \
G_PARAM_STATIC_BLURB)
/**
* PIKA_PARAM_READABLE:
*
* Since: 2.4
**/
#define PIKA_PARAM_READABLE (G_PARAM_READABLE | \
PIKA_PARAM_STATIC_STRINGS)
/**
* PIKA_PARAM_WRITABLE:
*
* Since: 2.4
**/
#define PIKA_PARAM_WRITABLE (G_PARAM_WRITABLE | \
PIKA_PARAM_STATIC_STRINGS)
/**
* PIKA_PARAM_READWRITE:
*
* Since: 2.4
**/
#define PIKA_PARAM_READWRITE (G_PARAM_READWRITE | \
PIKA_PARAM_STATIC_STRINGS)
/*
* PIKA_TYPE_ARRAY
*/
/**
* PikaArray:
* @data: (array length=length): pointer to the array's data.
* @length: length of @data, in bytes.
* @static_data: whether @data points to statically allocated memory.
**/
typedef struct _PikaArray PikaArray;
struct _PikaArray
{
guint8 *data;
gsize length;
gboolean static_data;
};
PikaArray * pika_array_new (const guint8 *data,
gsize length,
gboolean static_data);
PikaArray * pika_array_copy (const PikaArray *array);
void pika_array_free (PikaArray *array);
#define PIKA_TYPE_ARRAY (pika_array_get_type ())
#define PIKA_VALUE_HOLDS_ARRAY(value) (G_TYPE_CHECK_VALUE_TYPE ((value), PIKA_TYPE_ARRAY))
GType pika_array_get_type (void) G_GNUC_CONST;
/*
* PIKA_TYPE_PARAM_ARRAY
*/
#define PIKA_TYPE_PARAM_ARRAY (pika_param_array_get_type ())
#define PIKA_PARAM_SPEC_ARRAY(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), PIKA_TYPE_PARAM_ARRAY, PikaParamSpecArray))
#define PIKA_IS_PARAM_SPEC_ARRAY(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), PIKA_TYPE_PARAM_ARRAY))
typedef struct _PikaParamSpecArray PikaParamSpecArray;
struct _PikaParamSpecArray
{
GParamSpecBoxed parent_instance;
};
GType pika_param_array_get_type (void) G_GNUC_CONST;
GParamSpec * pika_param_spec_array (const gchar *name,
const gchar *nick,
const gchar *blurb,
GParamFlags flags);
/*
* PIKA_TYPE_INT32_ARRAY
*/
#define PIKA_TYPE_INT32_ARRAY (pika_int32_array_get_type ())
#define PIKA_VALUE_HOLDS_INT32_ARRAY(value) (G_TYPE_CHECK_VALUE_TYPE ((value), PIKA_TYPE_INT32_ARRAY))
GType pika_int32_array_get_type (void) G_GNUC_CONST;
/*
* PIKA_TYPE_PARAM_INT32_ARRAY
*/
#define PIKA_TYPE_PARAM_INT32_ARRAY (pika_param_int32_array_get_type ())
#define PIKA_PARAM_SPEC_INT32_ARRAY(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), PIKA_TYPE_PARAM_INT32_ARRAY, PikaParamSpecInt32Array))
#define PIKA_IS_PARAM_SPEC_INT32_ARRAY(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), PIKA_TYPE_PARAM_INT32_ARRAY))
typedef struct _PikaParamSpecInt32Array PikaParamSpecInt32Array;
struct _PikaParamSpecInt32Array
{
PikaParamSpecArray parent_instance;
};
GType pika_param_int32_array_get_type (void) G_GNUC_CONST;
GParamSpec * pika_param_spec_int32_array (const gchar *name,
const gchar *nick,
const gchar *blurb,
GParamFlags flags);
const gint32 * pika_value_get_int32_array (const GValue *value);
gint32 * pika_value_dup_int32_array (const GValue *value);
void pika_value_set_int32_array (GValue *value,
const gint32 *data,
gsize length);
void pika_value_set_static_int32_array (GValue *value,
const gint32 *data,
gsize length);
void pika_value_take_int32_array (GValue *value,
gint32 *data,
gsize length);
/*
* PIKA_TYPE_FLOAT_ARRAY
*/
#define PIKA_TYPE_FLOAT_ARRAY (pika_float_array_get_type ())
#define PIKA_VALUE_HOLDS_FLOAT_ARRAY(value) (G_TYPE_CHECK_VALUE_TYPE ((value), PIKA_TYPE_FLOAT_ARRAY))
GType pika_float_array_get_type (void) G_GNUC_CONST;
/*
* PIKA_TYPE_PARAM_FLOAT_ARRAY
*/
#define PIKA_TYPE_PARAM_FLOAT_ARRAY (pika_param_float_array_get_type ())
#define PIKA_PARAM_SPEC_FLOAT_ARRAY(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), PIKA_TYPE_PARAM_FLOAT_ARRAY, PikaParamSpecFloatArray))
#define PIKA_IS_PARAM_SPEC_FLOAT_ARRAY(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), PIKA_TYPE_PARAM_FLOAT_ARRAY))
typedef struct _PikaParamSpecFloatArray PikaParamSpecFloatArray;
struct _PikaParamSpecFloatArray
{
PikaParamSpecArray parent_instance;
};
GType pika_param_float_array_get_type (void) G_GNUC_CONST;
GParamSpec * pika_param_spec_float_array (const gchar *name,
const gchar *nick,
const gchar *blurb,
GParamFlags flags);
const gdouble * pika_value_get_float_array (const GValue *value);
gdouble * pika_value_dup_float_array (const GValue *value);
void pika_value_set_float_array (GValue *value,
const gdouble *data,
gsize length);
void pika_value_set_static_float_array (GValue *value,
const gdouble *data,
gsize length);
void pika_value_take_float_array (GValue *value,
gdouble *data,
gsize length);
/*
* PIKA_TYPE_RGB_ARRAY
*/
#define PIKA_TYPE_RGB_ARRAY (pika_rgb_array_get_type ())
#define PIKA_VALUE_HOLDS_RGB_ARRAY(value) (G_TYPE_CHECK_VALUE_TYPE ((value), PIKA_TYPE_RGB_ARRAY))
GType pika_rgb_array_get_type (void) G_GNUC_CONST;
/*
* PIKA_TYPE_PARAM_RGB_ARRAY
*/
#define PIKA_TYPE_PARAM_RGB_ARRAY (pika_param_rgb_array_get_type ())
#define PIKA_PARAM_SPEC_RGB_ARRAY(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), PIKA_TYPE_PARAM_RGB_ARRAY, PikaParamSpecRGBArray))
#define PIKA_IS_PARAM_SPEC_RGB_ARRAY(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), PIKA_TYPE_PARAM_RGB_ARRAY))
typedef struct _PikaParamSpecRGBArray PikaParamSpecRGBArray;
struct _PikaParamSpecRGBArray
{
GParamSpecBoxed parent_instance;
};
GType pika_param_rgb_array_get_type (void) G_GNUC_CONST;
GParamSpec * pika_param_spec_rgb_array (const gchar *name,
const gchar *nick,
const gchar *blurb,
GParamFlags flags);
const PikaRGB * pika_value_get_rgb_array (const GValue *value);
PikaRGB * pika_value_dup_rgb_array (const GValue *value);
void pika_value_set_rgb_array (GValue *value,
const PikaRGB *data,
gsize length);
void pika_value_set_static_rgb_array (GValue *value,
const PikaRGB *data,
gsize length);
void pika_value_take_rgb_array (GValue *value,
PikaRGB *data,
gsize length);
/*
* PIKA_TYPE_OBJECT_ARRAY
*/
/**
* PikaObjectArray:
* @object_type: #GType of the contained objects.
* @data: (array length=length): pointer to the array's data.
* @length: length of @data, in number of objects.
* @static_data: whether @data points to statically allocated memory.
**/
typedef struct _PikaObjectArray PikaObjectArray;
struct _PikaObjectArray
{
GType object_type;
GObject **data;
gsize length;
gboolean static_data;
};
PikaObjectArray * pika_object_array_new (GType object_type,
GObject **data,
gsize length,
gboolean static_data);
PikaObjectArray * pika_object_array_copy (const PikaObjectArray *array);
void pika_object_array_free (PikaObjectArray *array);
#define PIKA_TYPE_OBJECT_ARRAY (pika_object_array_get_type ())
#define PIKA_VALUE_HOLDS_OBJECT_ARRAY(value) (G_TYPE_CHECK_VALUE_TYPE ((value), PIKA_TYPE_OBJECT_ARRAY))
GType pika_object_array_get_type (void) G_GNUC_CONST;
/*
* PIKA_TYPE_PARAM_OBJECT_ARRAY
*/
#define PIKA_TYPE_PARAM_OBJECT_ARRAY (pika_param_object_array_get_type ())
#define PIKA_PARAM_SPEC_OBJECT_ARRAY(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), PIKA_TYPE_PARAM_OBJECT_ARRAY, PikaParamSpecObjectArray))
#define PIKA_IS_PARAM_SPEC_OBJECT_ARRAY(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), PIKA_TYPE_PARAM_OBJECT_ARRAY))
typedef struct _PikaParamSpecObjectArray PikaParamSpecObjectArray;
struct _PikaParamSpecObjectArray
{
GParamSpecBoxed parent_instance;
GType object_type;
};
GType pika_param_object_array_get_type (void) G_GNUC_CONST;
GParamSpec * pika_param_spec_object_array (const gchar *name,
const gchar *nick,
const gchar *blurb,
GType object_type,
GParamFlags flags);
GObject ** pika_value_get_object_array (const GValue *value);
GObject ** pika_value_dup_object_array (const GValue *value);
void pika_value_set_object_array (GValue *value,
GType object_type,
GObject **data,
gsize length);
void pika_value_set_static_object_array (GValue *value,
GType object_type,
GObject **data,
gsize length);
void pika_value_take_object_array (GValue *value,
GType object_type,
GObject **data,
gsize length);
G_END_DECLS
#endif /* __PIKA_PARAM_SPECS_H__ */

444
libpikabase/pikaparasite.c Normal file
View File

@ -0,0 +1,444 @@
/* LIBPIKA - The PIKA Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* pikaparasite.c
* Copyright (C) 1998 Jay Cox <jaycox@gimp.org>
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <stdio.h>
#ifdef HAVE_UNISTD_H
#include <unistd.h>
#endif
#include <string.h>
#include <glib-object.h>
#ifdef G_OS_WIN32
#include <process.h> /* For _getpid() */
#endif
#include "pikabasetypes.h"
#include "pikaparasite.h"
/**
* SECTION: pikaparasite
* @title: PikaParasite
* @short_description: Arbitrary pieces of data which can be attached
* to various PIKA objects.
* @see_also: pika_image_attach_parasite(), pika_item_attach_parasite(),
* pika_attach_parasite() and their related functions.
*
* Arbitrary pieces of data which can be attached to various PIKA objects.
**/
/*
* PIKA_TYPE_PARASITE
*/
G_DEFINE_BOXED_TYPE (PikaParasite, pika_parasite, pika_parasite_copy, pika_parasite_free)
/*
* PIKA_TYPE_PARAM_PARASITE
*/
#define PIKA_PARAM_SPEC_PARASITE(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), PIKA_TYPE_PARAM_PARASITE, PikaParamSpecParasite))
struct _PikaParamSpecParasite
{
GParamSpecBoxed parent_instance;
};
static void pika_param_parasite_class_init (GParamSpecClass *class);
static void pika_param_parasite_init (GParamSpec *pspec);
static gboolean pika_param_parasite_validate (GParamSpec *pspec,
GValue *value);
static gint pika_param_parasite_values_cmp (GParamSpec *pspec,
const GValue *value1,
const GValue *value2);
GType
pika_param_parasite_get_type (void)
{
static GType type = 0;
if (! type)
{
const GTypeInfo type_info =
{
sizeof (GParamSpecClass),
NULL, NULL,
(GClassInitFunc) pika_param_parasite_class_init,
NULL, NULL,
sizeof (PikaParamSpecParasite),
0,
(GInstanceInitFunc) pika_param_parasite_init
};
type = g_type_register_static (G_TYPE_PARAM_BOXED,
"PikaParamParasite",
&type_info, 0);
}
return type;
}
static void
pika_param_parasite_class_init (GParamSpecClass *class)
{
class->value_type = PIKA_TYPE_PARASITE;
class->value_validate = pika_param_parasite_validate;
class->values_cmp = pika_param_parasite_values_cmp;
}
static void
pika_param_parasite_init (GParamSpec *pspec)
{
}
static gboolean
pika_param_parasite_validate (GParamSpec *pspec,
GValue *value)
{
PikaParasite *parasite = value->data[0].v_pointer;
if (! parasite)
{
return TRUE;
}
else if (parasite->name == NULL ||
*parasite->name == '\0' ||
! g_utf8_validate (parasite->name, -1, NULL) ||
(parasite->size == 0 && parasite->data != NULL) ||
(parasite->size > 0 && parasite->data == NULL))
{
g_value_set_boxed (value, NULL);
return TRUE;
}
return FALSE;
}
static gint
pika_param_parasite_values_cmp (GParamSpec *pspec,
const GValue *value1,
const GValue *value2)
{
PikaParasite *parasite1 = value1->data[0].v_pointer;
PikaParasite *parasite2 = value2->data[0].v_pointer;
/* try to return at least *something*, it's useless anyway... */
if (! parasite1)
return parasite2 != NULL ? -1 : 0;
else if (! parasite2)
return parasite1 != NULL;
else
return pika_parasite_compare (parasite1, parasite2);
}
/**
* pika_param_spec_parasite:
* @name: Canonical name of the property specified.
* @nick: Nick name of the property specified.
* @blurb: Description of the property specified.
* @flags: Flags for the property specified.
*
* Creates a new #PikaParamSpecParasite specifying a
* [type@Parasite] property.
*
* See g_param_spec_internal() for details on property names.
*
* Returns: (transfer full): The newly created #PikaParamSpecParasite.
*
* Since: 2.4
**/
GParamSpec *
pika_param_spec_parasite (const gchar *name,
const gchar *nick,
const gchar *blurb,
GParamFlags flags)
{
PikaParamSpecParasite *parasite_spec;
parasite_spec = g_param_spec_internal (PIKA_TYPE_PARAM_PARASITE,
name, nick, blurb, flags);
return G_PARAM_SPEC (parasite_spec);
}
#ifdef DEBUG
static void
pika_parasite_print (PikaParasite *parasite)
{
if (parasite == NULL)
{
g_print ("pid %d: attempt to print a null parasite\n", getpid ());
return;
}
g_print ("pid %d: parasite: %p\n", getpid (), parasite);
if (parasite->name)
g_print ("\tname: %s\n", parasite->name);
else
g_print ("\tname: NULL\n");
g_print ("\tflags: %d\n", parasite->flags);
g_print ("\tsize: %d\n", parasite->size);
if (parasite->size > 0)
g_print ("\tdata: %p\n", parasite->data);
}
#endif
/**
* pika_parasite_new:
* @name: the new #PikaParasite name.
* @flags: see libpikabase/pikaparasite.h macros.
* @size: the size of @data, including a terminal %NULL byte if needed.
* @data: (nullable) (array length=size) (element-type char): the data to save in a parasite.
*
* Creates a new parasite and save @data which may be a proper text (in
* which case you may want to set @size as strlen(@data) + 1) or not.
*
* Returns: (transfer full): a new #PikaParasite.
*/
PikaParasite *
pika_parasite_new (const gchar *name,
guint32 flags,
guint32 size,
gconstpointer data)
{
PikaParasite *parasite;
if (! (name && *name))
return NULL;
parasite = g_slice_new (PikaParasite);
parasite->name = g_strdup (name);
parasite->flags = (flags & 0xFF);
parasite->size = size;
if (size)
parasite->data = g_memdup2 (data, size);
else
parasite->data = NULL;
return parasite;
}
/**
* pika_parasite_free:
* @parasite: a #PikaParasite
*
* Free @parasite's dynamically allocated memory.
*/
void
pika_parasite_free (PikaParasite *parasite)
{
if (parasite == NULL)
return;
if (parasite->name)
g_free (parasite->name);
if (parasite->data)
g_free (parasite->data);
g_slice_free (PikaParasite, parasite);
}
/**
* pika_parasite_is_type:
* @parasite: a #PikaParasite
* @name: a parasite name.
*
* Compare parasite's names.
*
* Returns: %TRUE if @parasite is named @name, %FALSE otherwise.
*/
gboolean
pika_parasite_is_type (const PikaParasite *parasite,
const gchar *name)
{
if (!parasite || !parasite->name)
return FALSE;
return (strcmp (parasite->name, name) == 0);
}
/**
* pika_parasite_copy:
* @parasite: a #PikaParasite
*
* Create a new parasite with all the same values.
*
* Returns: (transfer full): a newly allocated #PikaParasite with same contents.
*/
PikaParasite *
pika_parasite_copy (const PikaParasite *parasite)
{
if (parasite == NULL)
return NULL;
return pika_parasite_new (parasite->name, parasite->flags,
parasite->size, parasite->data);
}
/**
* pika_parasite_compare:
* @a: a #PikaParasite
* @b: a #PikaParasite
*
* Compare parasite's contents.
*
* Returns: %TRUE if @a and @b have same contents, %FALSE otherwise.
*/
gboolean
pika_parasite_compare (const PikaParasite *a,
const PikaParasite *b)
{
if (a && b &&
a->name && b->name &&
strcmp (a->name, b->name) == 0 &&
a->flags == b->flags &&
a->size == b->size)
{
if (a->data == NULL && b->data == NULL)
return TRUE;
else if (a->data && b->data && memcmp (a->data, b->data, a->size) == 0)
return TRUE;
}
return FALSE;
}
/**
* pika_parasite_get_flags:
* @parasite: a #PikaParasite
*
* Returns: @parasite flags.
*/
gulong
pika_parasite_get_flags (const PikaParasite *parasite)
{
if (parasite == NULL)
return 0;
return parasite->flags;
}
/**
* pika_parasite_is_persistent:
* @parasite: a #PikaParasite
*
* Returns: %TRUE if @parasite is persistent, %FALSE otherwise.
*/
gboolean
pika_parasite_is_persistent (const PikaParasite *parasite)
{
if (parasite == NULL)
return FALSE;
return (parasite->flags & PIKA_PARASITE_PERSISTENT);
}
/**
* pika_parasite_is_undoable:
* @parasite: a #PikaParasite
*
* Returns: %TRUE if @parasite is undoable, %FALSE otherwise.
*/
gboolean
pika_parasite_is_undoable (const PikaParasite *parasite)
{
if (parasite == NULL)
return FALSE;
return (parasite->flags & PIKA_PARASITE_UNDOABLE);
}
/**
* pika_parasite_has_flag:
* @parasite: a #PikaParasite
* @flag: a parasite flag
*
* Returns: %TRUE if @parasite has @flag set, %FALSE otherwise.
*/
gboolean
pika_parasite_has_flag (const PikaParasite *parasite,
gulong flag)
{
if (parasite == NULL)
return FALSE;
return (parasite->flags & flag);
}
/**
* pika_parasite_get_name:
* @parasite: a #PikaParasite
*
* Returns: @parasite's name.
*/
const gchar *
pika_parasite_get_name (const PikaParasite *parasite)
{
if (parasite)
return parasite->name;
return NULL;
}
/**
* pika_parasite_get_data:
* @parasite: a #PikaParasite
* @num_bytes: (out) (nullable): size of the returned data.
*
* Gets the parasite's data. It may not necessarily be text, nor is it
* guaranteed to be %NULL-terminated. It is your responsibility to know
* how to deal with this data.
* Even when you expect a nul-terminated string, it is advised not to
* assume the returned data to be, as parasites can be edited by third
* party scripts. You may end up reading out-of-bounds data. So you
* should only ignore @num_bytes when you all you care about is checking
* if the parasite has contents.
*
* Returns: (array length=num_bytes) (element-type char): parasite's data.
*/
gconstpointer
pika_parasite_get_data (const PikaParasite *parasite,
guint32 *num_bytes)
{
if (parasite)
{
if (num_bytes)
*num_bytes = parasite->size;
return parasite->data;
}
if (num_bytes)
*num_bytes = 0;
return NULL;
}

115
libpikabase/pikaparasite.h Normal file
View File

@ -0,0 +1,115 @@
/* LIBPIKA - The PIKA Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* pikaparasite.h
* Copyright (C) 1998 Jay Cox <jaycox@gimp.org>
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <https://www.gnu.org/licenses/>.
*/
#if !defined (__PIKA_BASE_H_INSIDE__) && !defined (PIKA_BASE_COMPILATION)
#error "Only <libpikabase/pikabase.h> can be included directly."
#endif
#ifndef __PIKA_PARASITE_H__
#define __PIKA_PARASITE_H__
G_BEGIN_DECLS
/* For information look into the C source or the html documentation */
/*
* PIKA_TYPE_PARASITE
*/
#define PIKA_TYPE_PARASITE (pika_parasite_get_type ())
#define PIKA_VALUE_HOLDS_PARASITE(value) (G_TYPE_CHECK_VALUE_TYPE ((value), PIKA_TYPE_PARASITE))
GType pika_parasite_get_type (void) G_GNUC_CONST;
/*
* PIKA_TYPE_PARAM_PARASITE
*/
#define PIKA_TYPE_PARAM_PARASITE (pika_param_parasite_get_type ())
#define PIKA_IS_PARAM_SPEC_PARASITE(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), PIKA_TYPE_PARAM_PARASITE))
typedef struct _PikaParamSpecParasite PikaParamSpecParasite;
GType pika_param_parasite_get_type (void) G_GNUC_CONST;
GParamSpec * pika_param_spec_parasite (const gchar *name,
const gchar *nick,
const gchar *blurb,
GParamFlags flags);
#define PIKA_PARASITE_PERSISTENT 1
#define PIKA_PARASITE_UNDOABLE 2
#define PIKA_PARASITE_ATTACH_PARENT (0x80 << 8)
#define PIKA_PARASITE_PARENT_PERSISTENT (PIKA_PARASITE_PERSISTENT << 8)
#define PIKA_PARASITE_PARENT_UNDOABLE (PIKA_PARASITE_UNDOABLE << 8)
#define PIKA_PARASITE_ATTACH_GRANDPARENT (0x80 << 16)
#define PIKA_PARASITE_GRANDPARENT_PERSISTENT (PIKA_PARASITE_PERSISTENT << 16)
#define PIKA_PARASITE_GRANDPARENT_UNDOABLE (PIKA_PARASITE_UNDOABLE << 16)
/**
* PikaParasite:
* @name: the parasite name, USE A UNIQUE PREFIX
* @flags: the parasite flags, like save in XCF etc.
* @size: the parasite size in bytes
* @data: (array length=size): the parasite data, the owner os the parasite is responsible
* for tracking byte order and internal structure
**/
struct _PikaParasite
{
gchar *name;
guint32 flags;
guint32 size;
gpointer data;
};
PikaParasite * pika_parasite_new (const gchar *name,
guint32 flags,
guint32 size,
gconstpointer data);
void pika_parasite_free (PikaParasite *parasite);
PikaParasite * pika_parasite_copy (const PikaParasite *parasite);
gboolean pika_parasite_compare (const PikaParasite *a,
const PikaParasite *b);
gboolean pika_parasite_is_type (const PikaParasite *parasite,
const gchar *name);
gboolean pika_parasite_is_persistent (const PikaParasite *parasite);
gboolean pika_parasite_is_undoable (const PikaParasite *parasite);
gboolean pika_parasite_has_flag (const PikaParasite *parasite,
gulong flag);
gulong pika_parasite_get_flags (const PikaParasite *parasite);
const gchar * pika_parasite_get_name (const PikaParasite *parasite);
gconstpointer pika_parasite_get_data (const PikaParasite *parasite,
guint32 *num_bytes);
G_END_DECLS
#endif /* __PIKA_PARASITE_H__ */

View File

@ -0,0 +1,204 @@
/* LIBPIKA - The PIKA Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* pikaparasiteio.c
* Copyright (C) 1999 Tor Lillqvist <tml@iki.fi>
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <https://www.gnu.org/licenses/>.
*/
/*
* Functions for building and parsing string representations of
* various standard parasite types.
*/
#include "config.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <glib.h>
#include "pikaparasiteio.h"
/**
* SECTION: pikaparasiteio
* @title: pikaparasiteio
* @short_description: Utility functions to (de)serialize certain C
* structures to/from #PikaParasite's.
* @see_also: #PikaParasite
*
* Utility functions to (de)serialize certain C structures to/from*
* #PikaParasite's.
**/
void
pika_pixpipe_params_init (PikaPixPipeParams *params)
{
gint i;
g_return_if_fail (params != NULL);
params->step = 100;
params->ncells = 1;
params->cellwidth = 1;
params->cellheight = 1;
params->dim = 1;
params->cols = 1;
params->rows = 1;
params->placement = g_strdup ("constant");
for (i = 0; i < PIKA_PIXPIPE_MAXDIM; i++)
params->selection[i] = g_strdup ("random");
params->rank[0] = 1;
for (i = 1; i < PIKA_PIXPIPE_MAXDIM; i++)
params->rank[i] = 0;
}
void
pika_pixpipe_params_parse (const gchar *string,
PikaPixPipeParams *params)
{
gchar *copy;
gchar *p, *q, *r;
gint i;
g_return_if_fail (string != NULL);
g_return_if_fail (params != NULL);
copy = g_strdup (string);
q = copy;
while ((p = strtok (q, " \r\n")) != NULL)
{
q = NULL;
r = strchr (p, ':');
if (r)
*r = 0;
if (strcmp (p, "ncells") == 0)
{
if (r)
params->ncells = atoi (r + 1);
}
else if (strcmp (p, "step") == 0)
{
if (r)
params->step = atoi (r + 1);
}
else if (strcmp (p, "dim") == 0)
{
if (r)
{
params->dim = atoi (r + 1);
params->dim = CLAMP (params->dim, 1, PIKA_PIXPIPE_MAXDIM);
}
}
else if (strcmp (p, "cols") == 0)
{
if (r)
params->cols = atoi (r + 1);
}
else if (strcmp (p, "rows") == 0)
{
if (r)
params->rows = atoi (r + 1);
}
else if (strcmp (p, "cellwidth") == 0)
{
if (r)
params->cellwidth = atoi (r + 1);
}
else if (strcmp (p, "cellheight") == 0)
{
if (r)
params->cellheight = atoi (r + 1);
}
else if (strcmp (p, "placement") == 0)
{
if (r)
{
g_free (params->placement);
params->placement = g_strdup (r + 1);
}
}
else if (strncmp (p, "rank", strlen ("rank")) == 0 && r)
{
if (r)
{
i = atoi (p + strlen ("rank"));
if (i >= 0 && i < params->dim)
params->rank[i] = atoi (r + 1);
}
}
else if (strncmp (p, "sel", strlen ("sel")) == 0 && r)
{
if (r)
{
i = atoi (p + strlen ("sel"));
if (i >= 0 && i < params->dim)
{
g_free (params->selection[i]);
params->selection[i] = g_strdup (r + 1);
}
}
}
if (r)
*r = ':';
}
g_free (copy);
}
gchar *
pika_pixpipe_params_build (PikaPixPipeParams *params)
{
GString *str;
gint i;
g_return_val_if_fail (params != NULL, NULL);
str = g_string_new (NULL);
g_string_printf (str, "ncells:%d cellwidth:%d cellheight:%d "
"step:%d dim:%d cols:%d rows:%d placement:%s",
params->ncells, params->cellwidth, params->cellheight,
params->step, params->dim,
params->cols, params->rows,
params->placement);
for (i = 0; i < params->dim; i++)
{
g_string_append_printf (str, " rank%d:%d", i, params->rank[i]);
g_string_append_printf (str, " sel%d:%s", i, params->selection[i]);
}
return g_string_free (str, FALSE);
}
void
pika_pixpipe_params_free (PikaPixPipeParams *params)
{
gint i;
g_free (params->placement);
for (i = 0; i < PIKA_PIXPIPE_MAXDIM; i++)
g_free (params->selection[i]);
}

View File

@ -0,0 +1,87 @@
/* LIBPIKA - The PIKA Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* pikaparasiteio.h
* Copyright (C) 1999 Tor Lillqvist <tml@iki.fi>
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <https://www.gnu.org/licenses/>.
*/
#ifndef __PIKA_PARASITE_IO_H__
#define __PIKA_PARASITE_IO_H__
G_BEGIN_DECLS
/* For information look into the C source or the html documentation */
/* Data structures for various standard parasites used by plug-ins and
* the PIKA core, and functions to build and parse their string
* representations.
*/
/*
* Pixmap brush pipes.
*/
#define PIKA_PIXPIPE_MAXDIM 4
typedef struct _PikaPixPipeParams PikaPixPipeParams;
/**
* PikaPixPipeParams:
* @step: Step
* @ncells: Number of cells
* @dim: Dimension
* @cols: Columns
* @rows: Rows
* @cellwidth: Cell width
* @cellheight: Cell height
* @placement: Placement
* @rank: Rank
* @selection: Selection
*
* PLease somebody help documenting this.
**/
struct _PikaPixPipeParams
{
gint step;
gint ncells;
gint dim;
gint cols;
gint rows;
gint cellwidth;
gint cellheight;
gchar *placement;
gint rank[PIKA_PIXPIPE_MAXDIM];
gchar *selection[PIKA_PIXPIPE_MAXDIM];
};
/* Initialize with dummy values */
void pika_pixpipe_params_init (PikaPixPipeParams *params);
/* Parse a string into a PikaPixPipeParams */
void pika_pixpipe_params_parse (const gchar *parameters,
PikaPixPipeParams *params);
/* Build a string representation of PikaPixPipeParams */
gchar * pika_pixpipe_params_build (PikaPixPipeParams *params) G_GNUC_MALLOC;
/* Free the internal values. It does not free the struct itself. */
void pika_pixpipe_params_free (PikaPixPipeParams *params);
G_END_DECLS
#endif /* __PIKA_PARASITE_IO_H__ */

1989
libpikabase/pikaprotocol.c Normal file

File diff suppressed because it is too large Load Diff

334
libpikabase/pikaprotocol.h Normal file
View File

@ -0,0 +1,334 @@
/* LIBPIKA - The PIKA Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <https://www.gnu.org/licenses/>.
*/
#ifndef __PIKA_PROTOCOL_H__
#define __PIKA_PROTOCOL_H__
G_BEGIN_DECLS
/* For information look into the C source or the html documentation */
/* Increment every time the protocol changes
*/
#define PIKA_PROTOCOL_VERSION 0x010F
enum
{
GP_QUIT,
GP_CONFIG,
GP_TILE_REQ,
GP_TILE_ACK,
GP_TILE_DATA,
GP_PROC_RUN,
GP_PROC_RETURN,
GP_TEMP_PROC_RUN,
GP_TEMP_PROC_RETURN,
GP_PROC_INSTALL,
GP_PROC_UNINSTALL,
GP_EXTENSION_ACK,
GP_HAS_INIT
};
typedef enum
{
GP_PARAM_DEF_TYPE_DEFAULT,
GP_PARAM_DEF_TYPE_INT,
GP_PARAM_DEF_TYPE_UNIT,
GP_PARAM_DEF_TYPE_ENUM,
GP_PARAM_DEF_TYPE_BOOLEAN,
GP_PARAM_DEF_TYPE_FLOAT,
GP_PARAM_DEF_TYPE_STRING,
GP_PARAM_DEF_TYPE_COLOR,
GP_PARAM_DEF_TYPE_ID,
GP_PARAM_DEF_TYPE_ID_ARRAY
} GPParamDefType;
typedef enum
{
GP_PARAM_TYPE_INT,
GP_PARAM_TYPE_FLOAT,
GP_PARAM_TYPE_STRING,
GP_PARAM_TYPE_STRV,
GP_PARAM_TYPE_BYTES,
GP_PARAM_TYPE_FILE,
GP_PARAM_TYPE_COLOR,
GP_PARAM_TYPE_PARASITE,
GP_PARAM_TYPE_ARRAY,
GP_PARAM_TYPE_ID_ARRAY,
GP_PARAM_TYPE_PARAM_DEF
} GPParamType;
typedef struct _GPConfig GPConfig;
typedef struct _GPTileReq GPTileReq;
typedef struct _GPTileAck GPTileAck;
typedef struct _GPTileData GPTileData;
typedef struct _GPParamDef GPParamDef;
typedef struct _GPParamDefInt GPParamDefInt;
typedef struct _GPParamDefUnit GPParamDefUnit;
typedef struct _GPParamDefEnum GPParamDefEnum;
typedef struct _GPParamDefBoolean GPParamDefBoolean;
typedef struct _GPParamDefFloat GPParamDefFloat;
typedef struct _GPParamDefString GPParamDefString;
typedef struct _GPParamStrv GPParamStrv;
typedef struct _GPParamDefColor GPParamDefColor;
typedef struct _GPParamDefID GPParamDefID;
typedef struct _GPParamDefIDArray GPParamDefIDArray;
typedef struct _GPParam GPParam;
typedef struct _GPParamArray GPParamArray;
typedef struct _GPParamIDArray GPParamIDArray;
typedef struct _GPProcRun GPProcRun;
typedef struct _GPProcReturn GPProcReturn;
typedef struct _GPProcInstall GPProcInstall;
typedef struct _GPProcUninstall GPProcUninstall;
struct _GPConfig
{
guint32 tile_width;
guint32 tile_height;
gint32 shm_id;
gint8 check_size;
gint8 check_type;
gint8 show_help_button;
gint8 use_cpu_accel;
gint8 use_opencl;
gint8 export_color_profile;
gint8 export_comment;
gint8 export_exif;
gint8 export_xmp;
gint8 export_iptc;
gint32 default_display_id;
gchar *app_name;
gchar *wm_class;
gchar *display_name;
gint32 monitor_number;
guint32 timestamp;
gchar *icon_theme_dir;
guint64 tile_cache_size;
gchar *swap_path;
gchar *swap_compression;
gint32 num_processors;
/* since protocol version 0x010F: */
PikaRGB check_custom_color1;
PikaRGB check_custom_color2;
};
struct _GPTileReq
{
gint32 drawable_id;
guint32 tile_num;
guint32 shadow;
};
struct _GPTileData
{
gint32 drawable_id;
guint32 tile_num;
guint32 shadow;
guint32 bpp;
guint32 width;
guint32 height;
guint32 use_shm;
guchar *data;
};
struct _GPParamDefInt
{
gint64 min_val;
gint64 max_val;
gint64 default_val;
};
struct _GPParamDefUnit
{
gint32 allow_pixels;
gint32 allow_percent;
gint32 default_val;
};
struct _GPParamDefEnum
{
gint32 default_val;
};
struct _GPParamDefBoolean
{
gint32 default_val;
};
struct _GPParamDefFloat
{
gdouble min_val;
gdouble max_val;
gdouble default_val;
};
struct _GPParamDefString
{
gchar *default_val;
};
struct _GPParamDefColor
{
gint32 has_alpha;
PikaRGB default_val;
};
struct _GPParamDefID
{
gint32 none_ok;
};
struct _GPParamDefIDArray
{
gchar *type_name;
};
struct _GPParamDef
{
GPParamDefType param_def_type;
gchar *type_name;
gchar *value_type_name;
gchar *name;
gchar *nick;
gchar *blurb;
guint flags;
union
{
GPParamDefInt m_int;
GPParamDefUnit m_unit;
GPParamDefEnum m_enum;
GPParamDefBoolean m_boolean;
GPParamDefFloat m_float;
GPParamDefString m_string;
GPParamDefColor m_color;
GPParamDefID m_id;
GPParamDefIDArray m_id_array;
} meta;
};
struct _GPParamArray
{
guint32 size;
guint8 *data;
};
struct _GPParamIDArray
{
gchar *type_name;
guint32 size;
gint32 *data;
};
struct _GPParam
{
GPParamType param_type;
gchar *type_name;
union
{
gint32 d_int;
gdouble d_float;
gchar *d_string;
gchar **d_strv;
GBytes *d_bytes;
PikaRGB d_color;
PikaParasite d_parasite;
GPParamArray d_array;
GPParamIDArray d_id_array;
GPParamDef d_param_def;
} data;
};
struct _GPProcRun
{
gchar *name;
guint32 n_params;
GPParam *params;
};
struct _GPProcReturn
{
gchar *name;
guint32 n_params;
GPParam *params;
};
struct _GPProcInstall
{
gchar *name;
guint32 type;
guint32 n_params;
guint32 n_return_vals;
GPParamDef *params;
GPParamDef *return_vals;
};
struct _GPProcUninstall
{
gchar *name;
};
void gp_init (void);
gboolean gp_quit_write (GIOChannel *channel,
gpointer user_data);
gboolean gp_config_write (GIOChannel *channel,
GPConfig *config,
gpointer user_data);
gboolean gp_tile_req_write (GIOChannel *channel,
GPTileReq *tile_req,
gpointer user_data);
gboolean gp_tile_ack_write (GIOChannel *channel,
gpointer user_data);
gboolean gp_tile_data_write (GIOChannel *channel,
GPTileData *tile_data,
gpointer user_data);
gboolean gp_proc_run_write (GIOChannel *channel,
GPProcRun *proc_run,
gpointer user_data);
gboolean gp_proc_return_write (GIOChannel *channel,
GPProcReturn *proc_return,
gpointer user_data);
gboolean gp_temp_proc_run_write (GIOChannel *channel,
GPProcRun *proc_run,
gpointer user_data);
gboolean gp_temp_proc_return_write (GIOChannel *channel,
GPProcReturn *proc_return,
gpointer user_data);
gboolean gp_proc_install_write (GIOChannel *channel,
GPProcInstall *proc_install,
gpointer user_data);
gboolean gp_proc_uninstall_write (GIOChannel *channel,
GPProcUninstall *proc_uninstall,
gpointer user_data);
gboolean gp_extension_ack_write (GIOChannel *channel,
gpointer user_data);
gboolean gp_has_init_write (GIOChannel *channel,
gpointer user_data);
G_END_DECLS
#endif /* __PIKA_PROTOCOL_H__ */

137
libpikabase/pikarectangle.c Normal file
View File

@ -0,0 +1,137 @@
/* LIBPIKA - The PIKA Library
* Copyright (C) 1995-1997 Spencer Kimball and Peter Mattis
*
* pikarectangle.c
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <glib.h>
#include "pikarectangle.h"
/**
* SECTION: pikarectangle
* @title: pikarectangle
* @short_description: Utility functions dealing with rectangle extents.
*
* Utility functions dealing with rectangle extents.
**/
/**
* pika_rectangle_intersect:
* @x1: origin of first rectangle
* @y1: origin of first rectangle
* @width1: width of first rectangle
* @height1: height of first rectangle
* @x2: origin of second rectangle
* @y2: origin of second rectangle
* @width2: width of second rectangle
* @height2: height of second rectangle
* @dest_x: (out) (optional): return location for origin of intersection,
* or %NULL
* @dest_y: (out) (optional): return location for origin of intersection,
* or %NULL
* @dest_width: (out) (optional): return location for width of intersection,
* or %NULL
* @dest_height: (out) (optional): return location for height of intersection,
* or %NULL
*
* Calculates the intersection of two rectangles.
*
* Returns: %TRUE if the intersection is non-empty, %FALSE otherwise
*
* Since: 2.4
**/
gboolean
pika_rectangle_intersect (gint x1,
gint y1,
gint width1,
gint height1,
gint x2,
gint y2,
gint width2,
gint height2,
gint *dest_x,
gint *dest_y,
gint *dest_width,
gint *dest_height)
{
gint d_x, d_y;
gint d_w, d_h;
d_x = MAX (x1, x2);
d_y = MAX (y1, y2);
d_w = MIN (x1 + width1, x2 + width2) - d_x;
d_h = MIN (y1 + height1, y2 + height2) - d_y;
if (dest_x) *dest_x = d_x;
if (dest_y) *dest_y = d_y;
if (dest_width) *dest_width = d_w;
if (dest_height) *dest_height = d_h;
return (d_w > 0 && d_h > 0);
}
/**
* pika_rectangle_union:
* @x1: origin of first rectangle
* @y1: origin of first rectangle
* @width1: width of first rectangle
* @height1: height of first rectangle
* @x2: origin of second rectangle
* @y2: origin of second rectangle
* @width2: width of second rectangle
* @height2: height of second rectangle
* @dest_x: (out) (optional): return location for origin of union, or %NULL
* @dest_y: (out) (optional): return location for origin of union, or %NULL
* @dest_width: (out) (optional): return location for width of union, or %NULL
* @dest_height: (out) (optional): return location for height of union, or %NULL
*
* Calculates the union of two rectangles.
*
* Since: 2.8
**/
void
pika_rectangle_union (gint x1,
gint y1,
gint width1,
gint height1,
gint x2,
gint y2,
gint width2,
gint height2,
gint *dest_x,
gint *dest_y,
gint *dest_width,
gint *dest_height)
{
gint d_x, d_y;
gint d_w, d_h;
d_x = MIN (x1, x2);
d_y = MIN (y1, y2);
d_w = MAX (x1 + width1, x2 + width2) - d_x;
d_h = MAX (y1 + height1, y2 + height2) - d_y;
if (dest_x) *dest_x = d_x;
if (dest_y) *dest_y = d_y;
if (dest_width) *dest_width = d_w;
if (dest_height) *dest_height = d_h;
}

View File

@ -0,0 +1,60 @@
/* LIBPIKA - The PIKA Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <https://www.gnu.org/licenses/>.
*/
#if !defined (__PIKA_BASE_H_INSIDE__) && !defined (PIKA_BASE_COMPILATION)
#error "Only <libpikabase/pikabase.h> can be included directly."
#endif
#ifndef __PIKA_RECTANGLE_H__
#define __PIKA_RECTANGLE_H__
G_BEGIN_DECLS
/* For information look into the C source or the html documentation */
gboolean pika_rectangle_intersect (gint x1,
gint y1,
gint width1,
gint height1,
gint x2,
gint y2,
gint width2,
gint height2,
gint *dest_x,
gint *dest_y,
gint *dest_width,
gint *dest_height);
void pika_rectangle_union (gint x1,
gint y1,
gint width1,
gint height1,
gint x2,
gint y2,
gint width2,
gint height2,
gint *dest_x,
gint *dest_y,
gint *dest_width,
gint *dest_height);
G_END_DECLS
#endif /* __PIKA_RECTANGLE_H__ */

469
libpikabase/pikareloc.c Normal file
View File

@ -0,0 +1,469 @@
/*
* BinReloc - a library for creating relocatable executables
* Written by: Hongli Lai <h.lai@chello.nl>
* http://autopackage.org/
*
* This source code is public domain. You can relicense this code
* under whatever license you want.
*
* See http://autopackage.org/docs/binreloc/ for
* more information and how to use this.
*/
#include "config.h"
#include <stdlib.h>
#include <limits.h>
#include <string.h>
#if defined(ENABLE_RELOCATABLE_RESOURCES) && ! defined(G_OS_WIN32)
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#endif /* ENABLE_RELOCATABLE_RESOURCES && ! G_OS_WIN32 */
#include <gio/gio.h>
#include <glib.h>
#include <glib/gstdio.h>
#include "pikareloc.h"
/*
* Find the canonical filename of the executable. Returns the filename
* (which must be freed) or NULL on error. If the parameter 'error' is
* not NULL, the error code will be stored there, if an error occurred.
*/
static char *
_br_find_exe (PikaBinrelocInitError *error)
{
#if ! defined(ENABLE_RELOCATABLE_RESOURCES) || defined(G_OS_WIN32) || defined(__APPLE__)
if (error)
*error = PIKA_RELOC_INIT_ERROR_DISABLED;
return NULL;
#else
GDataInputStream *data_input;
GInputStream *input;
GFile *file;
GError *gerror = NULL;
gchar *path;
gchar *sym_path;
gchar *maps_line;
sym_path = g_strdup ("/proc/self/exe");
while (1)
{
struct stat stat_buf;
int i;
/* Do not use readlink() with a buffer of size PATH_MAX because
* some systems actually allow paths of bigger size. Thus this
* macro is kind of bogus. Some systems like Hurd will not even
* define it (see MR !424).
* g_file_read_link() on the other hand will return a size of
* appropriate size, with newline removed and NUL terminator
* added.
*/
path = g_file_read_link (sym_path, &gerror);
g_free (sym_path);
if (! path)
{
/* Read link fails but we can try reading /proc/self/maps as
* an alternate method.
*/
g_printerr ("%s: %s\n", G_STRFUNC, gerror->message);
g_clear_error (&gerror);
break;
}
/* Check whether the symlink's target is also a symlink.
* We want to get the final target. */
i = stat (path, &stat_buf);
if (i == -1)
{
/* Error. */
break;
}
/* stat() success. */
if (! S_ISLNK (stat_buf.st_mode))
{
/* path is not a symlink. Done. */
return path;
}
/* path is a symlink. Continue loop and resolve this. */
sym_path = path;
}
/* readlink() or stat() failed; this can happen when the program is
* running in Valgrind 2.2. Read from /proc/self/maps as fallback. */
file = g_file_new_for_path ("/proc/self/maps");
input = G_INPUT_STREAM (g_file_read (file, NULL, &gerror));
g_object_unref (file);
if (! input)
{
g_printerr ("%s: %s", G_STRFUNC, gerror->message);
g_clear_error (&gerror);
if (error)
*error = PIKA_RELOC_INIT_ERROR_OPEN_MAPS;
return NULL;
}
data_input = g_data_input_stream_new (input);
g_object_unref (input);
/* The first entry with r-xp permission should be the executable name. */
while ((maps_line = g_data_input_stream_read_line (data_input, NULL, NULL, &gerror)))
{
if (maps_line == NULL)
{
if (gerror)
{
g_printerr ("%s: %s\n", G_STRFUNC, gerror->message);
g_error_free (gerror);
}
g_object_unref (data_input);
if (error)
*error = PIKA_RELOC_INIT_ERROR_READ_MAPS;
return NULL;
}
/* Extract the filename; it is always an absolute path. */
path = strchr (maps_line, '/');
/* Sanity check. */
if (path && strstr (maps_line, " r-xp "))
{
/* We found the executable name. */
path = g_strdup (path);
break;
}
g_free (maps_line);
maps_line = NULL;
path = NULL;
}
if (path == NULL && error)
*error = PIKA_RELOC_INIT_ERROR_INVALID_MAPS;
g_object_unref (data_input);
g_free (maps_line);
return path;
#endif /* ! ENABLE_RELOCATABLE_RESOURCES || G_OS_WIN32 */
}
/*
* Find the canonical filename of the executable which owns symbol.
* Returns a filename which must be freed, or NULL on error.
*/
static char *
_br_find_exe_for_symbol (const void *symbol, PikaBinrelocInitError *error)
{
#if ! defined(ENABLE_RELOCATABLE_RESOURCES) || defined(G_OS_WIN32) || defined(__APPLE__)
if (error)
*error = PIKA_RELOC_INIT_ERROR_DISABLED;
return (char *) NULL;
#else
GDataInputStream *data_input;
GInputStream *input;
GFile *file;
GError *gerror = NULL;
gchar *maps_line;
char *found = NULL;
char *address_string;
size_t address_string_len;
if (symbol == NULL)
return (char *) NULL;
file = g_file_new_for_path ("/proc/self/maps");
input = G_INPUT_STREAM (g_file_read (file, NULL, &gerror));
g_object_unref (file);
if (! input)
{
g_printerr ("%s: %s", G_STRFUNC, gerror->message);
g_error_free (gerror);
if (error)
*error = PIKA_RELOC_INIT_ERROR_OPEN_MAPS;
return NULL;
}
data_input = g_data_input_stream_new (input);
g_object_unref (input);
address_string_len = 4;
address_string = g_try_new (char, address_string_len);
while ((maps_line = g_data_input_stream_read_line (data_input, NULL, NULL, &gerror)))
{
char *start_addr, *end_addr, *end_addr_end;
char *path;
void *start_addr_p, *end_addr_p;
size_t len;
if (maps_line == NULL)
{
if (gerror)
{
g_printerr ("%s: %s\n", G_STRFUNC, gerror->message);
g_error_free (gerror);
}
if (error)
*error = PIKA_RELOC_INIT_ERROR_READ_MAPS;
break;
}
/* Sanity check. */
/* XXX Early versions of this code would check that the mapped
* region was with r-xp permission. It might have been true at
* some point in time, but last I tested, the searched pointer was
* in a r--p region for libpikabase. Thus _br_find_exe_for_symbol()
* would fail to find the executable's path.
* So now we don't test the region's permission anymore.
*/
if (strchr (maps_line, '/') == NULL)
{
g_free (maps_line);
continue;
}
/* Parse line. */
start_addr = maps_line;
end_addr = strchr (maps_line, '-');
path = strchr (maps_line, '/');
/* More sanity check. */
if (!(path > end_addr && end_addr != NULL && end_addr[0] == '-'))
{
g_free (maps_line);
continue;
}
end_addr[0] = '\0';
end_addr++;
end_addr_end = strchr (end_addr, ' ');
if (end_addr_end == NULL)
{
g_free (maps_line);
continue;
}
end_addr_end[0] = '\0';
len = strlen (path);
if (len == 0)
{
g_free (maps_line);
continue;
}
if (path[len - 1] == '\n')
path[len - 1] = '\0';
/* Get rid of "(deleted)" from the filename. */
len = strlen (path);
if (len > 10 && strcmp (path + len - 10, " (deleted)") == 0)
path[len - 10] = '\0';
/* I don't know whether this can happen but better safe than sorry. */
len = strlen (start_addr);
if (len != strlen (end_addr))
{
g_free (maps_line);
continue;
}
/* Transform the addresses into a string in the form of 0xdeadbeef,
* then transform that into a pointer. */
if (address_string_len < len + 3)
{
address_string_len = len + 3;
address_string = (char *) g_try_realloc (address_string, address_string_len);
}
memcpy (address_string, "0x", 2);
memcpy (address_string + 2, start_addr, len);
address_string[2 + len] = '\0';
sscanf (address_string, "%p", &start_addr_p);
memcpy (address_string, "0x", 2);
memcpy (address_string + 2, end_addr, len);
address_string[2 + len] = '\0';
sscanf (address_string, "%p", &end_addr_p);
if (symbol >= start_addr_p && symbol < end_addr_p)
{
found = g_strdup (path);
g_free (maps_line);
break;
}
g_free (maps_line);
}
g_free (address_string);
g_object_unref (data_input);
return found;
#endif /* ! ENABLE_RELOCATABLE_RESOURCES || G_OS_WIN32 */
}
static gchar *exe = NULL;
static void set_gerror (GError **error, PikaBinrelocInitError errcode);
/* Initialize the BinReloc library (for applications).
*
* This function must be called before using any other BinReloc functions.
* It attempts to locate the application's canonical filename.
*
* @note If you want to use BinReloc for a library, then you should call
* _pika_reloc_init_lib() instead.
* @note Initialization failure is not fatal. BinReloc functions will just
* fallback to the supplied default path.
*
* @param error If BinReloc failed to initialize, then the error report will
* be stored in this variable. Set to NULL if you don't want an
* error report. See the #PikaBinrelocInitError for a list of error
* codes.
*
* @returns TRUE on success, FALSE if BinReloc failed to initialize.
*/
gboolean
_pika_reloc_init (GError **error)
{
PikaBinrelocInitError errcode;
/* Shut up compiler warning about uninitialized variable. */
errcode = PIKA_RELOC_INIT_ERROR_NOMEM;
/* Locate the application's filename. */
exe = _br_find_exe (&errcode);
if (exe != NULL)
/* Success! */
return TRUE;
else
{
/* Failed :-( */
set_gerror (error, errcode);
return FALSE;
}
}
/* Initialize the BinReloc library (for libraries).
*
* This function must be called before using any other BinReloc functions.
* It attempts to locate the calling library's canonical filename.
*
* @note The BinReloc source code MUST be included in your library, or this
* function won't work correctly.
* @note Initialization failure is not fatal. BinReloc functions will just
* fallback to the supplied default path.
*
* @returns TRUE on success, FALSE if a filename cannot be found.
*/
gboolean
_pika_reloc_init_lib (GError **error)
{
PikaBinrelocInitError errcode;
/* Shut up compiler warning about uninitialized variable. */
errcode = PIKA_RELOC_INIT_ERROR_NOMEM;
exe = _br_find_exe_for_symbol ((const void *) "", &errcode);
if (exe != NULL)
{
/* Success! */
return TRUE;
}
else
{
/* Failed :-( */
set_gerror (error, errcode);
return exe != NULL;
}
}
static void
set_gerror (GError **error, PikaBinrelocInitError errcode)
{
const gchar *error_message;
if (error == NULL)
return;
switch (errcode)
{
case PIKA_RELOC_INIT_ERROR_NOMEM:
error_message = "Cannot allocate memory.";
break;
case PIKA_RELOC_INIT_ERROR_OPEN_MAPS:
error_message = "Unable to open /proc/self/maps for reading.";
break;
case PIKA_RELOC_INIT_ERROR_READ_MAPS:
error_message = "Unable to read from /proc/self/maps.";
break;
case PIKA_RELOC_INIT_ERROR_INVALID_MAPS:
error_message = "The file format of /proc/self/maps is invalid.";
break;
case PIKA_RELOC_INIT_ERROR_DISABLED:
error_message = "Binary relocation support is disabled.";
break;
default:
error_message = "Unknown error.";
break;
};
g_set_error (error, g_quark_from_static_string ("GBinReloc"),
errcode, "%s", error_message);
}
/* Locate the prefix in which the current application is installed.
*
* The prefix is generated by the following pseudo-code evaluation:
* \code
* dirname(dirname(exename))
* \endcode
*
* @param default_prefix A default prefix which will used as fallback.
* @return A string containing the prefix, which must be freed when no
* longer necessary. If BinReloc is not initialized, or if the
* initialization function failed, then a copy of default_prefix
* will be returned. If default_prefix is NULL, then NULL will be
* returned.
*/
gchar *
_pika_reloc_find_prefix (const gchar *default_prefix)
{
gchar *dir1, *dir2;
if (exe == NULL)
{
/* BinReloc not initialized. */
if (default_prefix != NULL)
return g_strdup (default_prefix);
else
return NULL;
}
dir1 = g_path_get_dirname (exe);
dir2 = g_path_get_dirname (dir1);
g_free (dir1);
return dir2;
}

46
libpikabase/pikareloc.h Normal file
View File

@ -0,0 +1,46 @@
/*
* BinReloc - a library for creating relocatable executables
* Written by: Hongli Lai <h.lai@chello.nl>
* http://autopackage.org/
*
* This source code is public domain. You can relicense this code
* under whatever license you want.
*
* See http://autopackage.org/docs/binreloc/ for
* more information and how to use this.
*/
#ifndef __PIKA_RELOC_H__
#define __PIKA_RELOC_H__
G_BEGIN_DECLS
/* These error codes can be returned from _pika_reloc_init() or
* _pika_reloc_init_lib().
*/
typedef enum
{
/** Cannot allocate memory. */
PIKA_RELOC_INIT_ERROR_NOMEM,
/** Unable to open /proc/self/maps; see errno for details. */
PIKA_RELOC_INIT_ERROR_OPEN_MAPS,
/** Unable to read from /proc/self/maps; see errno for details. */
PIKA_RELOC_INIT_ERROR_READ_MAPS,
/** The file format of /proc/self/maps is invalid; kernel bug? */
PIKA_RELOC_INIT_ERROR_INVALID_MAPS,
/** BinReloc is disabled (the ENABLE_BINRELOC macro is not defined). */
PIKA_RELOC_INIT_ERROR_DISABLED
} PikaBinrelocInitError;
G_GNUC_INTERNAL gboolean _pika_reloc_init (GError **error);
G_GNUC_INTERNAL gboolean _pika_reloc_init_lib (GError **error);
G_GNUC_INTERNAL gchar * _pika_reloc_find_prefix (const gchar *default_prefix);
G_END_DECLS
#endif /* _PIKARELOC_H_ */

110
libpikabase/pikasignal.c Normal file
View File

@ -0,0 +1,110 @@
/* LIBPIKA - The PIKA Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <https://www.gnu.org/licenses/>.
*
* $Revision$
*/
#include "config.h"
#define _GNU_SOURCE /* for the sigaction stuff */
#include <glib.h>
#include "pikasignal.h"
/**
* SECTION: pikasignal
* @title: pikasignal
* @short_description: Portable signal handling.
* @see_also: signal(2), signal(5 or 7), sigaction(2).
*
* Portable signal handling.
**/
/* Courtesy of Austin Donnelly 06-04-2000 to address bug #2742 */
/**
* pika_signal_private: (skip)
* @signum: Selects signal to be handled see man 5 signal (or man 7 signal)
* @handler: Handler that maps to signum. Invoked by O/S.
* Handler gets signal that caused invocation. Corresponds
* to the @sa_handler field of the @sigaction struct.
* @flags: Preferences. OR'ed SA_&lt;xxx&gt;. See man sigaction. Corresponds
* to the @sa_flags field of the @sigaction struct.
*
* This function furnishes a workalike for signal(2) but
* which internally invokes sigaction(2) after certain
* sa_flags are set; these primarily to ensure restarting
* of interrupted system calls. See sigaction(2) It is a
* aid to transition and not new development: that effort
* should employ sigaction directly. [gosgood 18.04.2000]
*
* Cause @handler to be run when @signum is delivered. We
* use sigaction(2) rather than signal(2) so that we can control the
* signal handler's environment completely via @flags: some signal(2)
* implementations differ in their semantics, so we need to nail down
* exactly what we want. [austin 06.04.2000]
*
* Returns: A reference to the signal handling function which was
* active before the call to pika_signal_private().
*/
PikaSignalHandlerFunc
pika_signal_private (gint signum,
PikaSignalHandlerFunc handler,
gint flags)
{
#ifndef G_OS_WIN32
gint ret;
struct sigaction sa;
struct sigaction osa;
/* The sa_handler (mandated by POSIX.1) and sa_sigaction (a
* common extension) are often implemented by the OS as members
* of a union. This means you CAN NOT set both, you set one or
* the other. Caveat programmer!
*/
/* Passing pika_signal_private a pika_sighandler of NULL is not
* an error, and generally results in the action for that signal
* being set to SIG_DFL (default behavior). Many OSes define
* SIG_DFL as (void (*)()0, so setting sa_handler to NULL is
* the same thing as passing SIG_DFL to it.
*/
sa.sa_handler = handler;
/* Mask all signals while handler runs to avoid re-entrancy
* problems.
*/
sigfillset (&sa.sa_mask);
sa.sa_flags = flags;
ret = sigaction (signum, &sa, &osa);
if (ret < 0)
g_error ("unable to set handler for signal %d\n", signum);
return (PikaSignalHandlerFunc) osa.sa_handler;
#else
return NULL; /* Or g_error()? Should all calls to
* this function really be inside
* #ifdef G_OS_UNIX?
*/
#endif
}

48
libpikabase/pikasignal.h Normal file
View File

@ -0,0 +1,48 @@
/* LIBPIKA - The PIKA Library
* Copyright (C) 1995-2000 Peter Mattis and Spencer Kimball
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <https://www.gnu.org/licenses/>.
*/
#ifndef __PIKA_SIGNAL_H__
#define __PIKA_SIGNAL_H__
#include <signal.h>
G_BEGIN_DECLS
/* For information look into the C source or the html documentation */
/**
* PikaSignalHandlerFunc:
* @signum: The number of the signal. Useful if different signals are
* handled by a single handler.
*
* A prototype for a reference to a signal handler functions. Note
* that each function which takes or returns a variable of this type
* also accepts or may return special values defined by your system's
* signal.h header file (like @SIG_DFL or @SIG_IGN).
**/
typedef void (* PikaSignalHandlerFunc) (gint signum);
PikaSignalHandlerFunc pika_signal_private (gint signum,
PikaSignalHandlerFunc handler,
gint flags);
G_END_DECLS
#endif /* __PIKA_SIGNAL_H__ */

747
libpikabase/pikaunit.c Normal file
View File

@ -0,0 +1,747 @@
/* LIBPIKA - The PIKA Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* pikaunit.c
* Copyright (C) 2003 Michael Natterer <mitch@gimp.org>
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <math.h>
#include <string.h>
#include <glib-object.h>
#include "pikabasetypes.h"
#include "pikabase-private.h"
#include "pikaunit.h"
/**
* SECTION: pikaunit
* @title: pikaunit
* @short_description: Provides a collection of predefined units and
* functions for creating user-defined units.
* @see_also: #PikaUnitMenu, #PikaSizeEntry.
*
* Provides a collection of predefined units and functions for
* creating user-defined units.
**/
static void unit_to_string (const GValue *src_value,
GValue *dest_value);
static void string_to_unit (const GValue *src_value,
GValue *dest_value);
GType
pika_unit_get_type (void)
{
static GType unit_type = 0;
if (! unit_type)
{
const GTypeInfo type_info = { 0, };
unit_type = g_type_register_static (G_TYPE_INT, "PikaUnit",
&type_info, 0);
g_value_register_transform_func (unit_type, G_TYPE_STRING,
unit_to_string);
g_value_register_transform_func (G_TYPE_STRING, unit_type,
string_to_unit);
}
return unit_type;
}
static void
unit_to_string (const GValue *src_value,
GValue *dest_value)
{
PikaUnit unit = (PikaUnit) g_value_get_int (src_value);
g_value_set_string (dest_value, pika_unit_get_identifier (unit));
}
static void
string_to_unit (const GValue *src_value,
GValue *dest_value)
{
const gchar *str;
gint num_units;
gint i;
str = g_value_get_string (src_value);
if (!str || !*str)
goto error;
num_units = pika_unit_get_number_of_units ();
for (i = PIKA_UNIT_PIXEL; i < num_units; i++)
if (strcmp (str, pika_unit_get_identifier (i)) == 0)
break;
if (i == num_units)
{
if (strcmp (str, pika_unit_get_identifier (PIKA_UNIT_PERCENT)) == 0)
i = PIKA_UNIT_PERCENT;
else
goto error;
}
g_value_set_int (dest_value, i);
return;
error:
g_warning ("Can't convert string '%s' to PikaUnit.", str);
}
/**
* pika_unit_get_number_of_units:
*
* Returns the number of units which are known to the #PikaUnit system.
*
* Returns: The number of defined units.
**/
gint
pika_unit_get_number_of_units (void)
{
g_return_val_if_fail (_pika_unit_vtable.unit_get_number_of_units != NULL,
PIKA_UNIT_END);
return _pika_unit_vtable.unit_get_number_of_units ();
}
/**
* pika_unit_get_number_of_built_in_units:
*
* Returns the number of #PikaUnit's which are hardcoded in the unit system
* (UNIT_INCH, UNIT_MM, UNIT_POINT, UNIT_PICA and the two "pseudo unit"
* UNIT_PIXEL).
*
* Returns: The number of built-in units.
**/
gint
pika_unit_get_number_of_built_in_units (void)
{
g_return_val_if_fail (_pika_unit_vtable.unit_get_number_of_built_in_units
!= NULL, PIKA_UNIT_END);
return _pika_unit_vtable.unit_get_number_of_built_in_units ();
}
/**
* pika_unit_new:
* @identifier: The unit's identifier string.
* @factor: The unit's factor (how many units are in one inch).
* @digits: The unit's suggested number of digits (see pika_unit_get_digits()).
* @symbol: The symbol of the unit (e.g. "''" for inch).
* @abbreviation: The abbreviation of the unit.
* @singular: The singular form of the unit.
* @plural: The plural form of the unit.
*
* Returns the integer ID of the new #PikaUnit.
*
* Note that a new unit is always created with its deletion flag
* set to %TRUE. You will have to set it to %FALSE with
* pika_unit_set_deletion_flag() to make the unit definition persistent.
*
* Returns: The ID of the new unit.
**/
PikaUnit
pika_unit_new (gchar *identifier,
gdouble factor,
gint digits,
gchar *symbol,
gchar *abbreviation,
gchar *singular,
gchar *plural)
{
g_return_val_if_fail (_pika_unit_vtable.unit_new != NULL, PIKA_UNIT_INCH);
return _pika_unit_vtable.unit_new (identifier, factor, digits,
symbol, abbreviation, singular, plural);
}
/**
* pika_unit_get_deletion_flag:
* @unit: The unit you want to know the @deletion_flag of.
*
* Returns: The unit's @deletion_flag.
**/
gboolean
pika_unit_get_deletion_flag (PikaUnit unit)
{
g_return_val_if_fail (_pika_unit_vtable.unit_get_deletion_flag != NULL, FALSE);
return _pika_unit_vtable.unit_get_deletion_flag (unit);
}
/**
* pika_unit_set_deletion_flag:
* @unit: The unit you want to set the @deletion_flag for.
* @deletion_flag: The new deletion_flag.
*
* Sets a #PikaUnit's @deletion_flag. If the @deletion_flag of a unit is
* %TRUE when PIKA exits, this unit will not be saved in the users's
* "unitrc" file.
*
* Trying to change the @deletion_flag of a built-in unit will be silently
* ignored.
**/
void
pika_unit_set_deletion_flag (PikaUnit unit,
gboolean deletion_flag)
{
g_return_if_fail (_pika_unit_vtable.unit_set_deletion_flag != NULL);
_pika_unit_vtable.unit_set_deletion_flag (unit, deletion_flag);
}
/**
* pika_unit_get_factor:
* @unit: The unit you want to know the factor of.
*
* A #PikaUnit's @factor is defined to be:
*
* distance_in_units == (@factor * distance_in_inches)
*
* Returns 0 for @unit == PIKA_UNIT_PIXEL.
*
* Returns: The unit's factor.
**/
gdouble
pika_unit_get_factor (PikaUnit unit)
{
g_return_val_if_fail (_pika_unit_vtable.unit_get_factor != NULL, 1.0);
if (unit == PIKA_UNIT_PIXEL)
return 0.0;
return _pika_unit_vtable.unit_get_factor (unit);
}
/**
* pika_unit_get_digits:
* @unit: The unit you want to know the digits.
*
* Returns the number of digits set for @unit.
* Built-in units' accuracy is approximately the same as an inch with
* two digits. User-defined units can suggest a different accuracy.
*
* Note: the value is as-set by defaults or by the user and does not
* necessary provide enough precision on high-resolution images.
* When the information is needed for a specific image, the use of
* pika_unit_get_scaled_digits() may be more appropriate.
*
* Returns 0 for @unit == PIKA_UNIT_PIXEL.
*
* Returns: The suggested number of digits.
**/
gint
pika_unit_get_digits (PikaUnit unit)
{
g_return_val_if_fail (_pika_unit_vtable.unit_get_digits != NULL, 2);
return _pika_unit_vtable.unit_get_digits (unit);
}
/**
* pika_unit_get_scaled_digits:
* @unit: The unit you want to know the digits.
* @resolution: the resolution in PPI.
*
* Returns the number of digits a @unit field should provide to get
* enough accuracy so that every pixel position shows a different
* value from neighboring pixels.
*
* Note: when needing digit accuracy to display a diagonal distance,
* the @resolution may not correspond to the image's horizontal or
* vertical resolution, but instead to the result of:
* `distance_in_pixel / distance_in_inch`.
*
* Returns: The suggested number of digits.
**/
gint
pika_unit_get_scaled_digits (PikaUnit unit,
gdouble resolution)
{
gint digits;
g_return_val_if_fail (_pika_unit_vtable.unit_get_digits != NULL, 2);
digits = ceil (log10 (1.0 /
pika_pixels_to_units (1.0, unit, resolution)));
return MAX (digits, pika_unit_get_digits (unit));
}
/**
* pika_unit_get_identifier:
* @unit: The unit you want to know the identifier of.
*
* This is an untranslated string and must not be changed or freed.
*
* Returns: The unit's identifier.
**/
const gchar *
pika_unit_get_identifier (PikaUnit unit)
{
g_return_val_if_fail (_pika_unit_vtable.unit_get_identifier != NULL, NULL);
return _pika_unit_vtable.unit_get_identifier (unit);
}
/**
* pika_unit_get_symbol:
* @unit: The unit you want to know the symbol of.
*
* This is e.g. "''" for UNIT_INCH.
*
* NOTE: This string must not be changed or freed.
*
* Returns: The unit's symbol.
**/
const gchar *
pika_unit_get_symbol (PikaUnit unit)
{
g_return_val_if_fail (_pika_unit_vtable.unit_get_symbol != NULL, NULL);
return _pika_unit_vtable.unit_get_symbol (unit);
}
/**
* pika_unit_get_abbreviation:
* @unit: The unit you want to know the abbreviation of.
*
* For built-in units, this function returns the translated abbreviation
* of the unit.
*
* NOTE: This string must not be changed or freed.
*
* Returns: The unit's abbreviation.
**/
const gchar *
pika_unit_get_abbreviation (PikaUnit unit)
{
g_return_val_if_fail (_pika_unit_vtable.unit_get_abbreviation != NULL, NULL);
return _pika_unit_vtable.unit_get_abbreviation (unit);
}
/**
* pika_unit_get_singular:
* @unit: The unit you want to know the singular form of.
*
* For built-in units, this function returns the translated singular form
* of the unit's name.
*
* NOTE: This string must not be changed or freed.
*
* Returns: The unit's singular form.
**/
const gchar *
pika_unit_get_singular (PikaUnit unit)
{
g_return_val_if_fail (_pika_unit_vtable.unit_get_singular != NULL, NULL);
return _pika_unit_vtable.unit_get_singular (unit);
}
/**
* pika_unit_get_plural:
* @unit: The unit you want to know the plural form of.
*
* For built-in units, this function returns the translated plural form
* of the unit's name.
*
* NOTE: This string must not be changed or freed.
*
* Returns: The unit's plural form.
**/
const gchar *
pika_unit_get_plural (PikaUnit unit)
{
g_return_val_if_fail (_pika_unit_vtable.unit_get_plural != NULL, NULL);
return _pika_unit_vtable.unit_get_plural (unit);
}
static gint print (gchar *buf,
gint len,
gint start,
const gchar *fmt,
...) G_GNUC_PRINTF (4, 5);
static gint
print (gchar *buf,
gint len,
gint start,
const gchar *fmt,
...)
{
va_list args;
gint printed;
va_start (args, fmt);
printed = g_vsnprintf (buf + start, len - start, fmt, args);
if (printed < 0)
printed = len - start;
va_end (args);
return printed;
}
/**
* pika_unit_format_string:
* @format: A printf-like format string which is used to create the unit
* string.
* @unit: A unit.
*
* The @format string supports the following percent expansions:
*
* <informaltable pgwide="1" frame="none" role="enum">
* <tgroup cols="2"><colspec colwidth="1*"/><colspec colwidth="8*"/>
* <tbody>
* <row>
* <entry>% f</entry>
* <entry>Factor (how many units make up an inch)</entry>
* </row>
* <row>
* <entry>% y</entry>
* <entry>Symbol (e.g. "''" for PIKA_UNIT_INCH)</entry>
* </row>
* <row>
* <entry>% a</entry>
* <entry>Abbreviation</entry>
* </row>
* <row>
* <entry>% s</entry>
* <entry>Singular</entry>
* </row>
* <row>
* <entry>% p</entry>
* <entry>Plural</entry>
* </row>
* <row>
* <entry>%%</entry>
* <entry>Literal percent</entry>
* </row>
* </tbody>
* </tgroup>
* </informaltable>
*
* Returns: A newly allocated string with above percent expressions
* replaced with the resp. strings for @unit.
*
* Since: 2.8
**/
gchar *
pika_unit_format_string (const gchar *format,
PikaUnit unit)
{
gchar buffer[1024];
gint i = 0;
g_return_val_if_fail (format != NULL, NULL);
g_return_val_if_fail (unit == PIKA_UNIT_PERCENT ||
(unit >= PIKA_UNIT_PIXEL &&
unit < pika_unit_get_number_of_units ()), NULL);
while (i < (sizeof (buffer) - 1) && *format)
{
switch (*format)
{
case '%':
format++;
switch (*format)
{
case 0:
g_warning ("%s: unit-menu-format string ended within %%-sequence",
G_STRFUNC);
break;
case '%':
buffer[i++] = '%';
break;
case 'f': /* factor (how many units make up an inch) */
i += print (buffer, sizeof (buffer), i, "%f",
pika_unit_get_factor (unit));
break;
case 'y': /* symbol ("''" for inch) */
i += print (buffer, sizeof (buffer), i, "%s",
pika_unit_get_symbol (unit));
break;
case 'a': /* abbreviation */
i += print (buffer, sizeof (buffer), i, "%s",
pika_unit_get_abbreviation (unit));
break;
case 's': /* singular */
i += print (buffer, sizeof (buffer), i, "%s",
pika_unit_get_singular (unit));
break;
case 'p': /* plural */
i += print (buffer, sizeof (buffer), i, "%s",
pika_unit_get_plural (unit));
break;
default:
g_warning ("%s: unit-menu-format contains unknown format "
"sequence '%%%c'", G_STRFUNC, *format);
break;
}
break;
default:
buffer[i++] = *format;
break;
}
format++;
}
buffer[MIN (i, sizeof (buffer) - 1)] = 0;
return g_strdup (buffer);
}
/*
* PIKA_TYPE_PARAM_UNIT
*/
static void pika_param_unit_class_init (GParamSpecClass *class);
static gboolean pika_param_unit_value_validate (GParamSpec *pspec,
GValue *value);
/**
* pika_param_unit_get_type:
*
* Reveals the object type
*
* Returns: the #GType for a unit param object
*
* Since: 2.4
**/
GType
pika_param_unit_get_type (void)
{
static GType spec_type = 0;
if (! spec_type)
{
const GTypeInfo type_info =
{
sizeof (GParamSpecClass),
NULL, NULL,
(GClassInitFunc) pika_param_unit_class_init,
NULL, NULL,
sizeof (PikaParamSpecUnit),
0, NULL, NULL
};
spec_type = g_type_register_static (G_TYPE_PARAM_INT,
"PikaParamUnit",
&type_info, 0);
}
return spec_type;
}
static void
pika_param_unit_class_init (GParamSpecClass *class)
{
class->value_type = PIKA_TYPE_UNIT;
class->value_validate = pika_param_unit_value_validate;
}
static gboolean
pika_param_unit_value_validate (GParamSpec *pspec,
GValue *value)
{
GParamSpecInt *ispec = G_PARAM_SPEC_INT (pspec);
PikaParamSpecUnit *uspec = PIKA_PARAM_SPEC_UNIT (pspec);
gint oval = value->data[0].v_int;
if (!(uspec->allow_percent && value->data[0].v_int == PIKA_UNIT_PERCENT))
{
value->data[0].v_int = CLAMP (value->data[0].v_int,
ispec->minimum,
pika_unit_get_number_of_units () - 1);
}
return value->data[0].v_int != oval;
}
/**
* pika_param_spec_unit:
* @name: Canonical name of the param
* @nick: Nickname of the param
* @blurb: Brief description of param.
* @allow_pixels: Whether "pixels" is an allowed unit.
* @allow_percent: Whether "percent" is an allowed unit.
* @default_value: Unit to use if none is assigned.
* @flags: a combination of #GParamFlags
*
* Creates a param spec to hold a units param.
* See g_param_spec_internal() for more information.
*
* Returns: (transfer full): a newly allocated #GParamSpec instance
*
* Since: 2.4
**/
GParamSpec *
pika_param_spec_unit (const gchar *name,
const gchar *nick,
const gchar *blurb,
gboolean allow_pixels,
gboolean allow_percent,
PikaUnit default_value,
GParamFlags flags)
{
PikaParamSpecUnit *pspec;
GParamSpecInt *ispec;
pspec = g_param_spec_internal (PIKA_TYPE_PARAM_UNIT,
name, nick, blurb, flags);
ispec = G_PARAM_SPEC_INT (pspec);
ispec->default_value = default_value;
ispec->minimum = allow_pixels ? PIKA_UNIT_PIXEL : PIKA_UNIT_INCH;
ispec->maximum = PIKA_UNIT_PERCENT - 1;
pspec->allow_percent = allow_percent;
return G_PARAM_SPEC (pspec);
}
/**
* pika_pixels_to_units:
* @pixels: value in pixels
* @unit: unit to convert to
* @resolution: resolution in DPI
*
* Converts a @value specified in pixels to @unit.
*
* Returns: @pixels converted to units.
*
* Since: 2.8
**/
gdouble
pika_pixels_to_units (gdouble pixels,
PikaUnit unit,
gdouble resolution)
{
if (unit == PIKA_UNIT_PIXEL)
return pixels;
return pixels * pika_unit_get_factor (unit) / resolution;
}
/**
* pika_units_to_pixels:
* @value: value in units
* @unit: unit of @value
* @resolution: resloution in DPI
*
* Converts a @value specified in @unit to pixels.
*
* Returns: @value converted to pixels.
*
* Since: 2.8
**/
gdouble
pika_units_to_pixels (gdouble value,
PikaUnit unit,
gdouble resolution)
{
if (unit == PIKA_UNIT_PIXEL)
return value;
return value * resolution / pika_unit_get_factor (unit);
}
/**
* pika_units_to_points:
* @value: value in units
* @unit: unit of @value
* @resolution: resloution in DPI
*
* Converts a @value specified in @unit to points.
*
* Returns: @value converted to points.
*
* Since: 2.8
**/
gdouble
pika_units_to_points (gdouble value,
PikaUnit unit,
gdouble resolution)
{
if (unit == PIKA_UNIT_POINT)
return value;
if (unit == PIKA_UNIT_PIXEL)
return (value * pika_unit_get_factor (PIKA_UNIT_POINT) / resolution);
return (value *
pika_unit_get_factor (PIKA_UNIT_POINT) / pika_unit_get_factor (unit));
}
/**
* pika_unit_is_metric:
* @unit: The unit
*
* Checks if the given @unit is metric. A simplistic test is used
* that looks at the unit's factor and checks if it is 2.54 multiplied
* by some common powers of 10. Currently it checks for mm, cm, dm, m.
*
* See also: pika_unit_get_factor()
*
* Returns: %TRUE if the @unit is metric.
*
* Since: 2.10
**/
gboolean
pika_unit_is_metric (PikaUnit unit)
{
gdouble factor;
if (unit == PIKA_UNIT_MM)
return TRUE;
factor = pika_unit_get_factor (unit);
if (factor == 0.0)
return FALSE;
return ((ABS (factor - 0.0254) < 1e-7) || /* m */
(ABS (factor - 0.254) < 1e-6) || /* dm */
(ABS (factor - 2.54) < 1e-5) || /* cm */
(ABS (factor - 25.4) < 1e-4)); /* mm */
}

120
libpikabase/pikaunit.h Normal file
View File

@ -0,0 +1,120 @@
/* LIBPIKA - The PIKA Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* pikaunit.h
* Copyright (C) 1999-2003 Michael Natterer <mitch@gimp.org>
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <https://www.gnu.org/licenses/>.
*/
#if !defined (__PIKA_BASE_H_INSIDE__) && !defined (PIKA_BASE_COMPILATION)
#error "Only <libpikabase/pikabase.h> can be included directly."
#endif
#ifndef __PIKA_UNIT_H__
#define __PIKA_UNIT_H__
G_BEGIN_DECLS
/* For information look into the C source or the html documentation */
/**
* PIKA_TYPE_UNIT:
*
* #PIKA_TYPE_UNIT is a #GType derived from #G_TYPE_INT.
**/
#define PIKA_TYPE_UNIT (pika_unit_get_type ())
#define PIKA_VALUE_HOLDS_UNIT(value) (G_TYPE_CHECK_VALUE_TYPE ((value), PIKA_TYPE_UNIT))
GType pika_unit_get_type (void) G_GNUC_CONST;
/*
* PIKA_TYPE_PARAM_UNIT
*/
#define PIKA_TYPE_PARAM_UNIT (pika_param_unit_get_type ())
#define PIKA_PARAM_SPEC_UNIT(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), PIKA_TYPE_PARAM_UNIT, PikaParamSpecUnit))
#define PIKA_IS_PARAM_SPEC_UNIT(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), PIKA_TYPE_PARAM_UNIT))
typedef struct _PikaParamSpecUnit PikaParamSpecUnit;
struct _PikaParamSpecUnit
{
GParamSpecInt parent_instance;
gboolean allow_percent;
};
GType pika_param_unit_get_type (void) G_GNUC_CONST;
GParamSpec * pika_param_spec_unit (const gchar *name,
const gchar *nick,
const gchar *blurb,
gboolean allow_pixels,
gboolean allow_percent,
PikaUnit default_value,
GParamFlags flags);
gint pika_unit_get_number_of_units (void);
gint pika_unit_get_number_of_built_in_units (void) G_GNUC_CONST;
PikaUnit pika_unit_new (gchar *identifier,
gdouble factor,
gint digits,
gchar *symbol,
gchar *abbreviation,
gchar *singular,
gchar *plural);
gboolean pika_unit_get_deletion_flag (PikaUnit unit);
void pika_unit_set_deletion_flag (PikaUnit unit,
gboolean deletion_flag);
gdouble pika_unit_get_factor (PikaUnit unit);
gint pika_unit_get_digits (PikaUnit unit);
gint pika_unit_get_scaled_digits (PikaUnit unit,
gdouble resolution);
const gchar * pika_unit_get_identifier (PikaUnit unit);
const gchar * pika_unit_get_symbol (PikaUnit unit);
const gchar * pika_unit_get_abbreviation (PikaUnit unit);
const gchar * pika_unit_get_singular (PikaUnit unit);
const gchar * pika_unit_get_plural (PikaUnit unit);
gchar * pika_unit_format_string (const gchar *format,
PikaUnit unit);
gdouble pika_pixels_to_units (gdouble pixels,
PikaUnit unit,
gdouble resolution);
gdouble pika_units_to_pixels (gdouble value,
PikaUnit unit,
gdouble resolution);
gdouble pika_units_to_points (gdouble value,
PikaUnit unit,
gdouble resolution);
gboolean pika_unit_is_metric (PikaUnit unit);
G_END_DECLS
#endif /* __PIKA_UNIT_H__ */

1825
libpikabase/pikautils.c Normal file

File diff suppressed because it is too large Load Diff

96
libpikabase/pikautils.h Normal file
View File

@ -0,0 +1,96 @@
/* LIBPIKA - The PIKA Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <https://www.gnu.org/licenses/>.
*/
#if !defined (__PIKA_BASE_H_INSIDE__) && !defined (PIKA_BASE_COMPILATION)
#error "Only <libpikabase/pikabase.h> can be included directly."
#endif
#ifndef __PIKA_UTILS_H__
#define __PIKA_UTILS_H__
G_BEGIN_DECLS
gchar * pika_utf8_strtrim (const gchar *str,
gint max_chars) G_GNUC_MALLOC;
gchar * pika_any_to_utf8 (const gchar *str,
gssize len,
const gchar *warning_format,
...) G_GNUC_PRINTF (3, 4) G_GNUC_MALLOC;
const gchar * pika_filename_to_utf8 (const gchar *filename);
const gchar * pika_file_get_utf8_name (GFile *file);
gboolean pika_file_has_extension (GFile *file,
const gchar *extension);
gboolean pika_file_show_in_file_manager (GFile *file,
GError **error);
gchar * pika_strip_uline (const gchar *str) G_GNUC_MALLOC;
gchar * pika_escape_uline (const gchar *str) G_GNUC_MALLOC;
gboolean pika_is_canonical_identifier (const gchar *identifier);
gchar * pika_canonicalize_identifier (const gchar *identifier) G_GNUC_MALLOC;
const PikaEnumDesc * pika_enum_get_desc (GEnumClass *enum_class,
gint value);
gboolean pika_enum_get_value (GType enum_type,
gint value,
const gchar **value_name,
const gchar **value_nick,
const gchar **value_desc,
const gchar **value_help);
const gchar * pika_enum_value_get_desc (GEnumClass *enum_class,
const GEnumValue *enum_value);
const gchar * pika_enum_value_get_help (GEnumClass *enum_class,
const GEnumValue *enum_value);
const gchar * pika_enum_value_get_abbrev (GEnumClass *enum_class,
const GEnumValue *enum_value);
const PikaFlagsDesc * pika_flags_get_first_desc (GFlagsClass *flags_class,
guint value);
gboolean pika_flags_get_first_value (GType flags_type,
guint value,
const gchar **value_name,
const gchar **value_nick,
const gchar **value_desc,
const gchar **value_help);
const gchar * pika_flags_value_get_desc (GFlagsClass *flags_class,
const GFlagsValue *flags_value);
const gchar * pika_flags_value_get_help (GFlagsClass *flags_class,
const GFlagsValue *flags_value);
const gchar * pika_flags_value_get_abbrev (GFlagsClass *flags_class,
const GFlagsValue *flags_value);
gboolean pika_stack_trace_available (gboolean optimal);
gboolean pika_stack_trace_print (const gchar *prog_name,
gpointer stream,
gchar **trace);
void pika_stack_trace_query (const gchar *prog_name);
void pika_range_estimate_settings (gdouble lower,
gdouble upper,
gdouble *step,
gdouble *page,
gint *digits);
void pika_bind_text_domain (const gchar *domain_name,
const gchar *dir_name);
G_END_DECLS
#endif /* __PIKA_UTILS_H__ */

View File

@ -0,0 +1,762 @@
/* LIBPIKA - The PIKA Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* pikavaluearray.c ported from GValueArray
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <string.h>
#include <glib-object.h>
#include <gobject/gvaluecollector.h>
#include "pikabasetypes.h"
#include "pikavaluearray.h"
/**
* SECTION:pikavaluearray
* @short_description: A container structure to maintain an array of
* generic values
* @see_also: #GValue, #GParamSpecValueArray, pika_param_spec_value_array()
* @title: PikaValueArray
*
* The prime purpose of a #PikaValueArray is for it to be used as an
* object property that holds an array of values. A #PikaValueArray wraps
* an array of #GValue elements in order for it to be used as a boxed
* type through %PIKA_TYPE_VALUE_ARRAY.
*/
#define GROUP_N_VALUES (1) /* power of 2 !! */
/**
* PikaValueArray:
*
* A #PikaValueArray contains an array of #GValue elements.
*
* Since: 2.10
*/
struct _PikaValueArray
{
gint n_values;
GValue *values;
gint n_prealloced;
gint ref_count;
};
G_DEFINE_BOXED_TYPE (PikaValueArray, pika_value_array,
pika_value_array_ref, pika_value_array_unref)
/**
* pika_value_array_index:
* @value_array: #PikaValueArray to get a value from
* @index: index of the value of interest
*
* Return a pointer to the value at @index contained in @value_array.
*
* Returns: (transfer none): pointer to a value at @index in @value_array
*
* Since: 2.10
*/
GValue *
pika_value_array_index (const PikaValueArray *value_array,
gint index)
{
g_return_val_if_fail (value_array != NULL, NULL);
g_return_val_if_fail (index < value_array->n_values, NULL);
return value_array->values + index;
}
static inline void
value_array_grow (PikaValueArray *value_array,
gint n_values,
gboolean zero_init)
{
g_return_if_fail ((guint) n_values >= (guint) value_array->n_values);
value_array->n_values = n_values;
if (value_array->n_values > value_array->n_prealloced)
{
gint i = value_array->n_prealloced;
value_array->n_prealloced = (value_array->n_values + GROUP_N_VALUES - 1) & ~(GROUP_N_VALUES - 1);
value_array->values = g_renew (GValue, value_array->values, value_array->n_prealloced);
if (!zero_init)
i = value_array->n_values;
memset (value_array->values + i, 0,
(value_array->n_prealloced - i) * sizeof (value_array->values[0]));
}
}
static inline void
value_array_shrink (PikaValueArray *value_array)
{
if (value_array->n_prealloced >= value_array->n_values + GROUP_N_VALUES)
{
value_array->n_prealloced = (value_array->n_values + GROUP_N_VALUES - 1) & ~(GROUP_N_VALUES - 1);
value_array->values = g_renew (GValue, value_array->values, value_array->n_prealloced);
}
}
/**
* pika_value_array_new:
* @n_prealloced: number of values to preallocate space for
*
* Allocate and initialize a new #PikaValueArray, optionally preserve space
* for @n_prealloced elements. New arrays always contain 0 elements,
* regardless of the value of @n_prealloced.
*
* Returns: a newly allocated #PikaValueArray with 0 values
*
* Since: 2.10
*/
PikaValueArray *
pika_value_array_new (gint n_prealloced)
{
PikaValueArray *value_array = g_slice_new0 (PikaValueArray);
value_array_grow (value_array, n_prealloced, TRUE);
value_array->n_values = 0;
value_array->ref_count = 1;
return value_array;
}
/**
* pika_value_array_new_from_types: (skip)
* @error_msg: return location for an error message.
* @first_type: first type in the array, or #G_TYPE_NONE.
* @...: the remaining types in the array, terminated by #G_TYPE_NONE
*
* Allocate and initialize a new #PikaValueArray, and fill it with
* values that are given as a list of (#GType, value) pairs,
* terminated by #G_TYPE_NONE.
*
* Returns: (nullable): a newly allocated #PikaValueArray, or %NULL if
* an error happened.
*
* Since: 3.0
*/
PikaValueArray *
pika_value_array_new_from_types (gchar **error_msg,
GType first_type,
...)
{
PikaValueArray *value_array;
va_list va_args;
g_return_val_if_fail (error_msg == NULL || *error_msg == NULL, NULL);
va_start (va_args, first_type);
value_array = pika_value_array_new_from_types_valist (error_msg,
first_type,
va_args);
va_end (va_args);
return value_array;
}
/**
* pika_value_array_new_from_types_valist: (skip)
* @error_msg: return location for an error message.
* @first_type: first type in the array, or #G_TYPE_NONE.
* @va_args: a va_list of GTypes and values, terminated by #G_TYPE_NONE
*
* Allocate and initialize a new #PikaValueArray, and fill it with
* @va_args given in the order as passed to
* pika_value_array_new_from_types().
*
* Returns: (nullable): a newly allocated #PikaValueArray, or %NULL if
* an error happened.
*
* Since: 3.0
*/
PikaValueArray *
pika_value_array_new_from_types_valist (gchar **error_msg,
GType first_type,
va_list va_args)
{
PikaValueArray *value_array;
GType type;
g_return_val_if_fail (error_msg == NULL || *error_msg == NULL, NULL);
type = first_type;
value_array = pika_value_array_new (type == G_TYPE_NONE ? 0 : 1);
while (type != G_TYPE_NONE)
{
GValue value = G_VALUE_INIT;
gchar *my_error = NULL;
g_value_init (&value, type);
G_VALUE_COLLECT (&value, va_args, G_VALUE_NOCOPY_CONTENTS, &my_error);
if (my_error)
{
if (error_msg)
{
*error_msg = my_error;
}
else
{
g_printerr ("%s: %s", G_STRFUNC, my_error);
g_free (my_error);
}
pika_value_array_unref (value_array);
va_end (va_args);
return NULL;
}
pika_value_array_append (value_array, &value);
g_value_unset (&value);
type = va_arg (va_args, GType);
}
va_end (va_args);
return value_array;
}
/**
* pika_value_array_copy:
* @value_array: #PikaValueArray to copy
*
* Return an exact copy of a #PikaValueArray by duplicating all its values.
*
* Returns: a newly allocated #PikaValueArray.
*
* Since: 3.0
*/
PikaValueArray *
pika_value_array_copy (const PikaValueArray *value_array)
{
g_return_val_if_fail (value_array != NULL, NULL);
return pika_value_array_new_from_values (value_array->values,
value_array->n_values);
}
/**
* pika_value_array_new_from_values:
* @values: (array length=n_values): The #GValue elements
* @n_values: the number of value elements
*
* Allocate and initialize a new #PikaValueArray, and fill it with
* the given #GValues. When no #GValues are given, returns empty #PikaValueArray.
*
* Returns: a newly allocated #PikaValueArray.
*
* Since: 3.0
*/
PikaValueArray *
pika_value_array_new_from_values (const GValue *values,
gint n_values)
{
PikaValueArray *value_array;
gint i;
/* n_values is zero if and only if values is NULL. */
g_return_val_if_fail ((n_values == 0 && values == NULL) ||
(n_values > 0 && values != NULL),
NULL);
value_array = pika_value_array_new (n_values);
for (i = 0; i < n_values; i++)
{
pika_value_array_insert (value_array, i, &values[i]);
}
return value_array;
}
/**
* pika_value_array_ref:
* @value_array: #PikaValueArray to ref
*
* Adds a reference to a #PikaValueArray.
*
* Returns: the same @value_array
*
* Since: 2.10
*/
PikaValueArray *
pika_value_array_ref (PikaValueArray *value_array)
{
g_return_val_if_fail (value_array != NULL, NULL);
value_array->ref_count++;
return value_array;
}
/**
* pika_value_array_unref:
* @value_array: #PikaValueArray to unref
*
* Unref a #PikaValueArray. If the reference count drops to zero, the
* array including its contents are freed.
*
* Since: 2.10
*/
void
pika_value_array_unref (PikaValueArray *value_array)
{
g_return_if_fail (value_array != NULL);
value_array->ref_count--;
if (value_array->ref_count < 1)
{
gint i;
for (i = 0; i < value_array->n_values; i++)
{
GValue *value = value_array->values + i;
if (G_VALUE_TYPE (value) != 0) /* we allow unset values in the array */
g_value_unset (value);
}
g_free (value_array->values);
g_slice_free (PikaValueArray, value_array);
}
}
gint
pika_value_array_length (const PikaValueArray *value_array)
{
g_return_val_if_fail (value_array != NULL, 0);
return value_array->n_values;
}
/**
* pika_value_array_prepend:
* @value_array: #PikaValueArray to add an element to
* @value: (allow-none): #GValue to copy into #PikaValueArray, or %NULL
*
* Insert a copy of @value as first element of @value_array. If @value is
* %NULL, an uninitialized value is prepended.
*
* Returns: (transfer none): the #PikaValueArray passed in as @value_array
*
* Since: 2.10
*/
PikaValueArray *
pika_value_array_prepend (PikaValueArray *value_array,
const GValue *value)
{
g_return_val_if_fail (value_array != NULL, NULL);
return pika_value_array_insert (value_array, 0, value);
}
/**
* pika_value_array_append:
* @value_array: #PikaValueArray to add an element to
* @value: (allow-none): #GValue to copy into #PikaValueArray, or %NULL
*
* Insert a copy of @value as last element of @value_array. If @value is
* %NULL, an uninitialized value is appended.
*
* Returns: (transfer none): the #PikaValueArray passed in as @value_array
*
* Since: 2.10
*/
PikaValueArray *
pika_value_array_append (PikaValueArray *value_array,
const GValue *value)
{
g_return_val_if_fail (value_array != NULL, NULL);
return pika_value_array_insert (value_array, value_array->n_values, value);
}
/**
* pika_value_array_insert:
* @value_array: #PikaValueArray to add an element to
* @index: insertion position, must be &lt;= pika_value_array_length()
* @value: (allow-none): #GValue to copy into #PikaValueArray, or %NULL
*
* Insert a copy of @value at specified position into @value_array. If @value
* is %NULL, an uninitialized value is inserted.
*
* Returns: (transfer none): the #PikaValueArray passed in as @value_array
*
* Since: 2.10
*/
PikaValueArray *
pika_value_array_insert (PikaValueArray *value_array,
gint index,
const GValue *value)
{
gint i;
g_return_val_if_fail (value_array != NULL, NULL);
g_return_val_if_fail (index <= value_array->n_values, value_array);
i = value_array->n_values;
value_array_grow (value_array, value_array->n_values + 1, FALSE);
if (index + 1 < value_array->n_values)
memmove (value_array->values + index + 1, value_array->values + index,
(i - index) * sizeof (value_array->values[0]));
memset (value_array->values + index, 0, sizeof (value_array->values[0]));
if (value)
{
g_value_init (value_array->values + index, G_VALUE_TYPE (value));
g_value_copy (value, value_array->values + index);
}
return value_array;
}
/**
* pika_value_array_remove:
* @value_array: #PikaValueArray to remove an element from
* @index: position of value to remove, which must be less than
* pika_value_array_length()
*
* Remove the value at position @index from @value_array.
*
* Returns: (transfer none): the #PikaValueArray passed in as @value_array
*
* Since: 2.10
*/
PikaValueArray *
pika_value_array_remove (PikaValueArray *value_array,
gint index)
{
g_return_val_if_fail (value_array != NULL, NULL);
g_return_val_if_fail (index < value_array->n_values, value_array);
if (G_VALUE_TYPE (value_array->values + index) != 0)
g_value_unset (value_array->values + index);
value_array->n_values--;
if (index < value_array->n_values)
memmove (value_array->values + index, value_array->values + index + 1,
(value_array->n_values - index) * sizeof (value_array->values[0]));
value_array_shrink (value_array);
if (value_array->n_prealloced > value_array->n_values)
memset (value_array->values + value_array->n_values, 0, sizeof (value_array->values[0]));
return value_array;
}
void
pika_value_array_truncate (PikaValueArray *value_array,
gint n_values)
{
gint i;
g_return_if_fail (value_array != NULL);
g_return_if_fail (n_values > 0 && n_values <= value_array->n_values);
for (i = value_array->n_values; i > n_values; i--)
pika_value_array_remove (value_array, i - 1);
}
/*
* PIKA_TYPE_PARAM_VALUE_ARRAY
*/
static void pika_param_value_array_class_init (GParamSpecClass *klass);
static void pika_param_value_array_init (GParamSpec *pspec);
static void pika_param_value_array_finalize (GParamSpec *pspec);
static void pika_param_value_array_set_default (GParamSpec *pspec,
GValue *value);
static gboolean pika_param_value_array_validate (GParamSpec *pspec,
GValue *value);
static gint pika_param_value_array_values_cmp (GParamSpec *pspec,
const GValue *value1,
const GValue *value2);
GType
pika_param_value_array_get_type (void)
{
static GType type = 0;
if (! type)
{
const GTypeInfo info =
{
sizeof (GParamSpecClass),
NULL, NULL,
(GClassInitFunc) pika_param_value_array_class_init,
NULL, NULL,
sizeof (PikaParamSpecValueArray),
0,
(GInstanceInitFunc) pika_param_value_array_init
};
type = g_type_register_static (G_TYPE_PARAM_BOXED,
"PikaParamValueArray", &info, 0);
}
return type;
}
static void
pika_param_value_array_class_init (GParamSpecClass *klass)
{
klass->value_type = PIKA_TYPE_VALUE_ARRAY;
klass->finalize = pika_param_value_array_finalize;
klass->value_set_default = pika_param_value_array_set_default;
klass->value_validate = pika_param_value_array_validate;
klass->values_cmp = pika_param_value_array_values_cmp;
}
static void
pika_param_value_array_init (GParamSpec *pspec)
{
PikaParamSpecValueArray *aspec = PIKA_PARAM_SPEC_VALUE_ARRAY (pspec);
aspec->element_spec = NULL;
aspec->fixed_n_elements = 0; /* disable */
}
static inline guint
pika_value_array_ensure_size (PikaValueArray *value_array,
guint fixed_n_elements)
{
guint changed = 0;
if (fixed_n_elements)
{
while (pika_value_array_length (value_array) < fixed_n_elements)
{
pika_value_array_append (value_array, NULL);
changed++;
}
while (pika_value_array_length (value_array) > fixed_n_elements)
{
pika_value_array_remove (value_array,
pika_value_array_length (value_array) - 1);
changed++;
}
}
return changed;
}
static void
pika_param_value_array_finalize (GParamSpec *pspec)
{
PikaParamSpecValueArray *aspec = PIKA_PARAM_SPEC_VALUE_ARRAY (pspec);
GParamSpecClass *parent_class;
parent_class = g_type_class_peek (g_type_parent (PIKA_TYPE_PARAM_VALUE_ARRAY));
g_clear_pointer (&aspec->element_spec, g_param_spec_unref);
parent_class->finalize (pspec);
}
static void
pika_param_value_array_set_default (GParamSpec *pspec,
GValue *value)
{
PikaParamSpecValueArray *aspec = PIKA_PARAM_SPEC_VALUE_ARRAY (pspec);
if (! value->data[0].v_pointer && aspec->fixed_n_elements)
value->data[0].v_pointer = pika_value_array_new (aspec->fixed_n_elements);
if (value->data[0].v_pointer)
{
/* g_value_reset (value); already done */
pika_value_array_ensure_size (value->data[0].v_pointer,
aspec->fixed_n_elements);
}
}
static gboolean
pika_param_value_array_validate (GParamSpec *pspec,
GValue *value)
{
PikaParamSpecValueArray *aspec = PIKA_PARAM_SPEC_VALUE_ARRAY (pspec);
PikaValueArray *value_array = value->data[0].v_pointer;
guint changed = 0;
if (! value->data[0].v_pointer && aspec->fixed_n_elements)
value->data[0].v_pointer = pika_value_array_new (aspec->fixed_n_elements);
if (value->data[0].v_pointer)
{
/* ensure array size validity */
changed += pika_value_array_ensure_size (value_array,
aspec->fixed_n_elements);
/* ensure array values validity against a present element spec */
if (aspec->element_spec)
{
GParamSpec *element_spec = aspec->element_spec;
gint length = pika_value_array_length (value_array);
gint i;
for (i = 0; i < length; i++)
{
GValue *element = pika_value_array_index (value_array, i);
/* need to fixup value type, or ensure that the array
* value is initialized at all
*/
if (! g_value_type_compatible (G_VALUE_TYPE (element),
G_PARAM_SPEC_VALUE_TYPE (element_spec)))
{
if (G_VALUE_TYPE (element) != 0)
g_value_unset (element);
g_value_init (element, G_PARAM_SPEC_VALUE_TYPE (element_spec));
g_param_value_set_default (element_spec, element);
changed++;
}
/* validate array value against element_spec */
changed += g_param_value_validate (element_spec, element);
}
}
}
return changed;
}
static gint
pika_param_value_array_values_cmp (GParamSpec *pspec,
const GValue *value1,
const GValue *value2)
{
PikaParamSpecValueArray *aspec = PIKA_PARAM_SPEC_VALUE_ARRAY (pspec);
PikaValueArray *value_array1 = value1->data[0].v_pointer;
PikaValueArray *value_array2 = value2->data[0].v_pointer;
gint length1;
gint length2;
if (!value_array1 || !value_array2)
return value_array2 ? -1 : value_array1 != value_array2;
length1 = pika_value_array_length (value_array1);
length2 = pika_value_array_length (value_array2);
if (length1 != length2)
{
return length1 < length2 ? -1 : 1;
}
else if (! aspec->element_spec)
{
/* we need an element specification for comparisons, so there's
* not much to compare here, try to at least provide stable
* lesser/greater result
*/
return length1 < length2 ? -1 : length1 > length2;
}
else /* length1 == length2 */
{
gint i;
for (i = 0; i < length1; i++)
{
GValue *element1 = pika_value_array_index (value_array1, i);
GValue *element2 = pika_value_array_index (value_array2, i);
gint cmp;
/* need corresponding element types, provide stable result
* otherwise
*/
if (G_VALUE_TYPE (element1) != G_VALUE_TYPE (element2))
return G_VALUE_TYPE (element1) < G_VALUE_TYPE (element2) ? -1 : 1;
cmp = g_param_values_cmp (aspec->element_spec, element1, element2);
if (cmp)
return cmp;
}
return 0;
}
}
/**
* pika_param_spec_value_array:
* @name: Canonical name of the property specified.
* @nick: Nick name of the property specified.
* @blurb: Description of the property specified.
* @element_spec: (nullable): #GParamSpec the contained array's elements
* have comply to, or %NULL.
* @flags: Flags for the property specified.
*
* Creates a new #PikaParamSpecValueArray specifying a
* [type@GObject.ValueArray] property.
*
* See g_param_spec_internal() for details on property names.
*
* Returns: (transfer full): The newly created #PikaParamSpecValueArray.
*
* Since: 3.0
**/
GParamSpec *
pika_param_spec_value_array (const gchar *name,
const gchar *nick,
const gchar *blurb,
GParamSpec *element_spec,
GParamFlags flags)
{
PikaParamSpecValueArray *aspec;
if (element_spec)
g_return_val_if_fail (G_IS_PARAM_SPEC (element_spec), NULL);
aspec = g_param_spec_internal (PIKA_TYPE_PARAM_VALUE_ARRAY,
name,
nick,
blurb,
flags);
if (element_spec)
{
aspec->element_spec = g_param_spec_ref (element_spec);
g_param_spec_sink (element_spec);
}
return G_PARAM_SPEC (aspec);
}

View File

@ -0,0 +1,117 @@
/* LIBPIKA - The PIKA Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* pikavaluearray.h ported from GValueArray
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <https://www.gnu.org/licenses/>.
*/
#if !defined (__PIKA_BASE_H_INSIDE__) && !defined (PIKA_BASE_COMPILATION)
#error "Only <libpikabase/pikabase.h> can be included directly."
#endif
#ifndef __PIKA_VALUE_ARRAY_H__
#define __PIKA_VALUE_ARRAY_H__
G_BEGIN_DECLS
/**
* PIKA_TYPE_VALUE_ARRAY:
*
* The type ID of the "PikaValueArray" type which is a boxed type,
* used to pass around pointers to PikaValueArrays.
*
* Since: 2.10
*/
#define PIKA_TYPE_VALUE_ARRAY (pika_value_array_get_type ())
GType pika_value_array_get_type (void) G_GNUC_CONST;
PikaValueArray * pika_value_array_new (gint n_prealloced);
PikaValueArray * pika_value_array_new_from_types
(gchar **error_msg,
GType first_type,
...);
PikaValueArray * pika_value_array_new_from_types_valist
(gchar **error_msg,
GType first_type,
va_list va_args);
PikaValueArray * pika_value_array_new_from_values
(const GValue *values,
gint n_values);
PikaValueArray * pika_value_array_copy (const PikaValueArray *value_array);
PikaValueArray * pika_value_array_ref (PikaValueArray *value_array);
void pika_value_array_unref (PikaValueArray *value_array);
gint pika_value_array_length (const PikaValueArray *value_array);
GValue * pika_value_array_index (const PikaValueArray *value_array,
gint index);
PikaValueArray * pika_value_array_prepend (PikaValueArray *value_array,
const GValue *value);
PikaValueArray * pika_value_array_append (PikaValueArray *value_array,
const GValue *value);
PikaValueArray * pika_value_array_insert (PikaValueArray *value_array,
gint index,
const GValue *value);
PikaValueArray * pika_value_array_remove (PikaValueArray *value_array,
gint index);
void pika_value_array_truncate (PikaValueArray *value_array,
gint n_values);
/*
* PIKA_TYPE_PARAM_VALUE_ARRAY
*/
#define PIKA_TYPE_PARAM_VALUE_ARRAY (pika_param_value_array_get_type ())
#define PIKA_IS_PARAM_SPEC_VALUE_ARRAY(pspec) (G_TYPE_CHECK_INSTANCE_TYPE ((pspec), PIKA_TYPE_PARAM_VALUE_ARRAY))
#define PIKA_PARAM_SPEC_VALUE_ARRAY(pspec) (G_TYPE_CHECK_INSTANCE_CAST ((pspec), PIKA_TYPE_PARAM_VALUE_ARRAY, PikaParamSpecValueArray))
typedef struct _PikaParamSpecValueArray PikaParamSpecValueArray;
/**
* PikaParamSpecValueArray:
* @parent_instance: private #GParamSpec portion
* @element_spec: the #GParamSpec of the array elements
* @fixed_n_elements: default length of the array
*
* A #GParamSpec derived structure that contains the meta data for
* value array properties.
**/
struct _PikaParamSpecValueArray
{
GParamSpec parent_instance;
GParamSpec *element_spec;
gint fixed_n_elements;
};
GType pika_param_value_array_get_type (void) G_GNUC_CONST;
GParamSpec * pika_param_spec_value_array (const gchar *name,
const gchar *nick,
const gchar *blurb,
GParamSpec *element_spec,
GParamFlags flags);
G_END_DECLS
#endif /* __PIKA_VALUE_ARRAY_H__ */

View File

@ -0,0 +1,68 @@
#ifndef __PIKA_VERSION_H__
#define __PIKA_VERSION_H__
/* pikaversion.h.in -> pikaversion.h
* This file is configured by Meson. Please modify meson.build files.
*/
#if !defined (__PIKA_BASE_H_INSIDE__) && !defined (PIKA_BASE_COMPILATION)
#error "Only <libpikabase/pikabase.h> can be included directly."
#endif
G_BEGIN_DECLS
/**
* SECTION: pikaversion
* @title: pikaversion
* @short_description: Macros and constants useful for determining
* PIKA's version number and capabilities.
*
* Macros and constants useful for determining PIKA's version number and
* capabilities.
**/
/**
* PIKA_MAJOR_VERSION:
*
* The major PIKA version number.
**/
#define PIKA_MAJOR_VERSION (@PIKA_MAJOR_VERSION@)
/**
* PIKA_MINOR_VERSION:
*
* The minor PIKA version number.
**/
#define PIKA_MINOR_VERSION (@PIKA_MINOR_VERSION@)
/**
* PIKA_MICRO_VERSION:
*
* The micro PIKA version number.
**/
#define PIKA_MICRO_VERSION (@PIKA_MICRO_VERSION@)
/**
* PIKA_VERSION:
*
* The PIKA version as a string.
**/
#define PIKA_VERSION "@PIKA_VERSION@"
/**
* PIKA_API_VERSION:
*
* Since: 2.2
**/
#define PIKA_API_VERSION "@PIKA_API_VERSION@"
#define PIKA_CHECK_VERSION(major, minor, micro) \
(PIKA_MAJOR_VERSION > (major) || \
(PIKA_MAJOR_VERSION == (major) && PIKA_MINOR_VERSION > (minor)) || \
(PIKA_MAJOR_VERSION == (major) && PIKA_MINOR_VERSION == (minor) && \
PIKA_MICRO_VERSION >= (micro)))
G_END_DECLS
#endif /* __PIKA_VERSION_H__ */

View File

@ -0,0 +1,99 @@
/* LIBPIKA - The PIKA Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* pikawin32-io.h
* Compatibility defines, you mostly need this as unistd.h replacement
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <https://www.gnu.org/licenses/>.
*/
#ifndef __PIKA_WIN32_IO_H__
#define __PIKA_WIN32_IO_H__
#include <io.h>
#include <direct.h>
G_BEGIN_DECLS
#define mkdir(n,a) _mkdir(n)
#define chmod(n,f) _chmod(n,f)
#define access(f,p) _access(f,p)
#ifndef S_ISREG
#define S_ISREG(m) (((m) & _S_IFMT) == _S_IFREG)
#endif
#ifndef S_ISDIR
#define S_ISDIR(m) (((m) & _S_IFMT) == _S_IFDIR)
#endif
#ifndef S_IRUSR
#define S_IRUSR _S_IREAD
#endif
#ifndef S_IWUSR
#define S_IWUSR _S_IWRITE
#endif
#ifndef S_IXUSR
#define S_IXUSR _S_IEXEC
#endif
#ifndef S_IRGRP
#define S_IRGRP _S_IREAD
#endif
#ifndef S_IXGRP
#define S_IXGRP _S_IEXEC
#endif
#ifndef S_IROTH
#define S_IROTH _S_IREAD
#endif
#ifndef S_IXOTH
#define S_IXOTH _S_IEXEC
#endif
#ifndef _O_BINARY
#define _O_BINARY 0
#endif
#ifndef _O_TEMPORARY
#define _O_TEMPORARY 0
#endif
#ifndef F_OK
#define F_OK 0
#endif
#ifndef W_OK
#define W_OK 2
#endif
#ifndef R_OK
#define R_OK 4
#endif
#ifndef X_OK
#define X_OK 0 /* not really */
#endif
/*
2004-09-15 Tor Lillqvist <tml@iki.fi>
* glib/gwin32.h: Don't define ftruncate as a macro. Was never a
good idea, and it clashes with newest mingw headers, which have a
ftruncate implementation as an inline function. Thanks to Dominik R.
*/
/* needs coorection for msvc though ;( */
#ifdef _MSC_VER
#define ftruncate(f,s) g_win32_ftruncate(f,s)
#endif
G_END_DECLS
#endif /* __PIKA_WIN32_IO_H__ */

695
libpikabase/pikawire.c Normal file
View File

@ -0,0 +1,695 @@
/* LIBPIKA - The PIKA Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library 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
* Library General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <https://www.gnu.org/licenses/>.
*/
#include "config.h"
#include <string.h>
#include <glib-object.h>
#include <libpikacolor/pikacolortypes.h>
#include "pikawire.h"
typedef struct _PikaWireHandler PikaWireHandler;
struct _PikaWireHandler
{
guint32 type;
PikaWireReadFunc read_func;
PikaWireWriteFunc write_func;
PikaWireDestroyFunc destroy_func;
};
static GHashTable *wire_ht = NULL;
static PikaWireIOFunc wire_read_func = NULL;
static PikaWireIOFunc wire_write_func = NULL;
static PikaWireFlushFunc wire_flush_func = NULL;
static gboolean wire_error_val = FALSE;
static void pika_wire_init (void);
void
pika_wire_register (guint32 type,
PikaWireReadFunc read_func,
PikaWireWriteFunc write_func,
PikaWireDestroyFunc destroy_func)
{
PikaWireHandler *handler;
if (! wire_ht)
pika_wire_init ();
handler = g_hash_table_lookup (wire_ht, &type);
if (! handler)
handler = g_slice_new0 (PikaWireHandler);
handler->type = type;
handler->read_func = read_func;
handler->write_func = write_func;
handler->destroy_func = destroy_func;
g_hash_table_insert (wire_ht, &handler->type, handler);
}
void
pika_wire_set_reader (PikaWireIOFunc read_func)
{
wire_read_func = read_func;
}
void
pika_wire_set_writer (PikaWireIOFunc write_func)
{
wire_write_func = write_func;
}
void
pika_wire_set_flusher (PikaWireFlushFunc flush_func)
{
wire_flush_func = flush_func;
}
gboolean
pika_wire_read (GIOChannel *channel,
guint8 *buf,
gsize count,
gpointer user_data)
{
if (wire_read_func)
{
if (!(* wire_read_func) (channel, buf, count, user_data))
{
/* Gives a confusing error message most of the time, disable:
g_warning ("%s: pika_wire_read: error", g_get_prgname ());
*/
wire_error_val = TRUE;
return FALSE;
}
}
else
{
GIOStatus status;
GError *error = NULL;
gsize bytes;
while (count > 0)
{
do
{
bytes = 0;
status = g_io_channel_read_chars (channel,
(gchar *) buf, count,
&bytes,
&error);
}
while (G_UNLIKELY (status == G_IO_STATUS_AGAIN));
if (G_UNLIKELY (status != G_IO_STATUS_NORMAL))
{
if (error)
{
g_warning ("%s: pika_wire_read(): error: %s",
g_get_prgname (), error->message);
g_error_free (error);
}
else
{
g_warning ("%s: pika_wire_read(): error",
g_get_prgname ());
}
wire_error_val = TRUE;
return FALSE;
}
if (G_UNLIKELY (bytes == 0))
{
g_warning ("%s: pika_wire_read(): unexpected EOF",
g_get_prgname ());
wire_error_val = TRUE;
return FALSE;
}
count -= bytes;
buf += bytes;
}
}
return TRUE;
}
gboolean
pika_wire_write (GIOChannel *channel,
const guint8 *buf,
gsize count,
gpointer user_data)
{
if (wire_write_func)
{
if (!(* wire_write_func) (channel, (guint8 *) buf, count, user_data))
{
g_warning ("%s: pika_wire_write: error", g_get_prgname ());
wire_error_val = TRUE;
return FALSE;
}
}
else
{
GIOStatus status;
GError *error = NULL;
gsize bytes;
while (count > 0)
{
do
{
bytes = 0;
status = g_io_channel_write_chars (channel,
(const gchar *) buf, count,
&bytes,
&error);
}
while (G_UNLIKELY (status == G_IO_STATUS_AGAIN));
if (G_UNLIKELY (status != G_IO_STATUS_NORMAL))
{
if (error)
{
g_warning ("%s: pika_wire_write(): error: %s",
g_get_prgname (), error->message);
g_error_free (error);
}
else
{
g_warning ("%s: pika_wire_write(): error",
g_get_prgname ());
}
wire_error_val = TRUE;
return FALSE;
}
count -= bytes;
buf += bytes;
}
}
return TRUE;
}
gboolean
pika_wire_flush (GIOChannel *channel,
gpointer user_data)
{
if (wire_flush_func)
return (* wire_flush_func) (channel, user_data);
return FALSE;
}
gboolean
pika_wire_error (void)
{
return wire_error_val;
}
void
pika_wire_clear_error (void)
{
wire_error_val = FALSE;
}
gboolean
pika_wire_read_msg (GIOChannel *channel,
PikaWireMessage *msg,
gpointer user_data)
{
PikaWireHandler *handler;
if (G_UNLIKELY (! wire_ht))
g_error ("pika_wire_read_msg: the wire protocol has not been initialized");
if (wire_error_val)
return !wire_error_val;
if (! _pika_wire_read_int32 (channel, &msg->type, 1, user_data))
return FALSE;
handler = g_hash_table_lookup (wire_ht, &msg->type);
if (G_UNLIKELY (! handler))
g_error ("pika_wire_read_msg: could not find handler for message: %d",
msg->type);
(* handler->read_func) (channel, msg, user_data);
return !wire_error_val;
}
gboolean
pika_wire_write_msg (GIOChannel *channel,
PikaWireMessage *msg,
gpointer user_data)
{
PikaWireHandler *handler;
if (G_UNLIKELY (! wire_ht))
g_error ("pika_wire_write_msg: the wire protocol has not been initialized");
if (wire_error_val)
return !wire_error_val;
handler = g_hash_table_lookup (wire_ht, &msg->type);
if (G_UNLIKELY (! handler))
g_error ("pika_wire_write_msg: could not find handler for message: %d",
msg->type);
if (! _pika_wire_write_int32 (channel, &msg->type, 1, user_data))
return FALSE;
(* handler->write_func) (channel, msg, user_data);
return !wire_error_val;
}
void
pika_wire_destroy (PikaWireMessage *msg)
{
PikaWireHandler *handler;
if (G_UNLIKELY (! wire_ht))
g_error ("pika_wire_destroy: the wire protocol has not been initialized");
handler = g_hash_table_lookup (wire_ht, &msg->type);
if (G_UNLIKELY (! handler))
g_error ("pika_wire_destroy: could not find handler for message: %d\n",
msg->type);
(* handler->destroy_func) (msg);
}
gboolean
_pika_wire_read_int64 (GIOChannel *channel,
guint64 *data,
gint count,
gpointer user_data)
{
g_return_val_if_fail (count >= 0, FALSE);
if (count > 0)
{
if (! _pika_wire_read_int8 (channel,
(guint8 *) data, count * 8, user_data))
return FALSE;
while (count--)
{
*data = GUINT64_FROM_BE (*data);
data++;
}
}
return TRUE;
}
gboolean
_pika_wire_read_int32 (GIOChannel *channel,
guint32 *data,
gint count,
gpointer user_data)
{
g_return_val_if_fail (count >= 0, FALSE);
if (count > 0)
{
if (! _pika_wire_read_int8 (channel,
(guint8 *) data, count * 4, user_data))
return FALSE;
while (count--)
{
*data = g_ntohl (*data);
data++;
}
}
return TRUE;
}
gboolean
_pika_wire_read_int16 (GIOChannel *channel,
guint16 *data,
gint count,
gpointer user_data)
{
g_return_val_if_fail (count >= 0, FALSE);
if (count > 0)
{
if (! _pika_wire_read_int8 (channel,
(guint8 *) data, count * 2, user_data))
return FALSE;
while (count--)
{
*data = g_ntohs (*data);
data++;
}
}
return TRUE;
}
gboolean
_pika_wire_read_int8 (GIOChannel *channel,
guint8 *data,
gint count,
gpointer user_data)
{
g_return_val_if_fail (count >= 0, FALSE);
return pika_wire_read (channel, data, count, user_data);
}
gboolean
_pika_wire_read_double (GIOChannel *channel,
gdouble *data,
gint count,
gpointer user_data)
{
gdouble *t;
guint8 tmp[8];
gint i;
g_return_val_if_fail (count >= 0, FALSE);
t = (gdouble *) tmp;
for (i = 0; i < count; i++)
{
#if (G_BYTE_ORDER == G_LITTLE_ENDIAN)
gint j;
#endif
if (! _pika_wire_read_int8 (channel, tmp, 8, user_data))
return FALSE;
#if (G_BYTE_ORDER == G_LITTLE_ENDIAN)
for (j = 0; j < 4; j++)
{
guint8 swap;
swap = tmp[j];
tmp[j] = tmp[7 - j];
tmp[7 - j] = swap;
}
#endif
data[i] = *t;
}
return TRUE;
}
gboolean
_pika_wire_read_string (GIOChannel *channel,
gchar **data,
gint count,
gpointer user_data)
{
gint i;
g_return_val_if_fail (count >= 0, FALSE);
for (i = 0; i < count; i++)
{
guint32 tmp;
if (! _pika_wire_read_int32 (channel, &tmp, 1, user_data))
return FALSE;
if (tmp > 0)
{
data[i] = g_try_new (gchar, tmp);
if (! data[i])
{
g_printerr ("%s: failed to allocate %u bytes\n", G_STRFUNC, tmp);
return FALSE;
}
if (! _pika_wire_read_int8 (channel,
(guint8 *) data[i], tmp, user_data))
{
g_free (data[i]);
return FALSE;
}
/* make sure that the string is NULL-terminated */
data[i][tmp - 1] = '\0';
}
else
{
data[i] = NULL;
}
}
return TRUE;
}
gboolean
_pika_wire_read_color (GIOChannel *channel,
PikaRGB *data,
gint count,
gpointer user_data)
{
g_return_val_if_fail (count >= 0, FALSE);
return _pika_wire_read_double (channel,
(gdouble *) data, 4 * count, user_data);
}
gboolean
_pika_wire_write_int64 (GIOChannel *channel,
const guint64 *data,
gint count,
gpointer user_data)
{
g_return_val_if_fail (count >= 0, FALSE);
if (count > 0)
{
gint i;
for (i = 0; i < count; i++)
{
guint64 tmp = GUINT64_TO_BE (data[i]);
if (! _pika_wire_write_int8 (channel,
(const guint8 *) &tmp, 8, user_data))
return FALSE;
}
}
return TRUE;
}
gboolean
_pika_wire_write_int32 (GIOChannel *channel,
const guint32 *data,
gint count,
gpointer user_data)
{
g_return_val_if_fail (count >= 0, FALSE);
if (count > 0)
{
gint i;
for (i = 0; i < count; i++)
{
guint32 tmp = g_htonl (data[i]);
if (! _pika_wire_write_int8 (channel,
(const guint8 *) &tmp, 4, user_data))
return FALSE;
}
}
return TRUE;
}
gboolean
_pika_wire_write_int16 (GIOChannel *channel,
const guint16 *data,
gint count,
gpointer user_data)
{
g_return_val_if_fail (count >= 0, FALSE);
if (count > 0)
{
gint i;
for (i = 0; i < count; i++)
{
guint16 tmp = g_htons (data[i]);
if (! _pika_wire_write_int8 (channel,
(const guint8 *) &tmp, 2, user_data))
return FALSE;
}
}
return TRUE;
}
gboolean
_pika_wire_write_int8 (GIOChannel *channel,
const guint8 *data,
gint count,
gpointer user_data)
{
g_return_val_if_fail (count >= 0, FALSE);
return pika_wire_write (channel, data, count, user_data);
}
gboolean
_pika_wire_write_double (GIOChannel *channel,
const gdouble *data,
gint count,
gpointer user_data)
{
gdouble *t;
guint8 tmp[8];
gint i;
#if (G_BYTE_ORDER == G_LITTLE_ENDIAN)
gint j;
#endif
g_return_val_if_fail (count >= 0, FALSE);
t = (gdouble *) tmp;
for (i = 0; i < count; i++)
{
*t = data[i];
#if (G_BYTE_ORDER == G_LITTLE_ENDIAN)
for (j = 0; j < 4; j++)
{
guint8 swap;
swap = tmp[j];
tmp[j] = tmp[7 - j];
tmp[7 - j] = swap;
}
#endif
if (! _pika_wire_write_int8 (channel, tmp, 8, user_data))
return FALSE;
#if 0
{
gint k;
g_print ("Wire representation of %f:\t", data[i]);
for (k = 0; k < 8; k++)
g_print ("%02x ", tmp[k]);
g_print ("\n");
}
#endif
}
return TRUE;
}
gboolean
_pika_wire_write_string (GIOChannel *channel,
gchar **data,
gint count,
gpointer user_data)
{
gint i;
g_return_val_if_fail (count >= 0, FALSE);
for (i = 0; i < count; i++)
{
guint32 tmp;
if (data[i])
tmp = strlen (data[i]) + 1;
else
tmp = 0;
if (! _pika_wire_write_int32 (channel, &tmp, 1, user_data))
return FALSE;
if (tmp > 0)
if (! _pika_wire_write_int8 (channel,
(const guint8 *) data[i], tmp, user_data))
return FALSE;
}
return TRUE;
}
gboolean
_pika_wire_write_color (GIOChannel *channel,
const PikaRGB *data,
gint count,
gpointer user_data)
{
g_return_val_if_fail (count >= 0, FALSE);
return _pika_wire_write_double (channel,
(gdouble *) data, 4 * count, user_data);
}
static guint
pika_wire_hash (const guint32 *key)
{
return *key;
}
static gboolean
pika_wire_compare (const guint32 *a,
const guint32 *b)
{
return (*a == *b);
}
static void
pika_wire_init (void)
{
if (! wire_ht)
wire_ht = g_hash_table_new ((GHashFunc) pika_wire_hash,
(GCompareFunc) pika_wire_compare);
}

146
libpikabase/pikawire.h Normal file
View File

@ -0,0 +1,146 @@
/* LIBPIKA - The PIKA Library
* Copyright (C) 1995-1997 Peter Mattis and Spencer Kimball
*
* This library is free software: you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 3 of the License, or (at your option) any later version.
*
* This library 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
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see
* <https://www.gnu.org/licenses/>.
*/
#ifndef __PIKA_WIRE_H__
#define __PIKA_WIRE_H__
G_BEGIN_DECLS
/* For information look into the C source or the html documentation */
typedef struct _PikaWireMessage PikaWireMessage;
typedef void (* PikaWireReadFunc) (GIOChannel *channel,
PikaWireMessage *msg,
gpointer user_data);
typedef void (* PikaWireWriteFunc) (GIOChannel *channel,
PikaWireMessage *msg,
gpointer user_data);
typedef void (* PikaWireDestroyFunc) (PikaWireMessage *msg);
typedef gboolean (* PikaWireIOFunc) (GIOChannel *channel,
const guint8 *buf,
gulong count,
gpointer user_data);
typedef gboolean (* PikaWireFlushFunc) (GIOChannel *channel,
gpointer user_data);
struct _PikaWireMessage
{
guint32 type;
gpointer data;
};
void pika_wire_register (guint32 type,
PikaWireReadFunc read_func,
PikaWireWriteFunc write_func,
PikaWireDestroyFunc destroy_func);
void pika_wire_set_reader (PikaWireIOFunc read_func);
void pika_wire_set_writer (PikaWireIOFunc write_func);
void pika_wire_set_flusher (PikaWireFlushFunc flush_func);
gboolean pika_wire_read (GIOChannel *channel,
guint8 *buf,
gsize count,
gpointer user_data);
gboolean pika_wire_write (GIOChannel *channel,
const guint8 *buf,
gsize count,
gpointer user_data);
gboolean pika_wire_flush (GIOChannel *channel,
gpointer user_data);
gboolean pika_wire_error (void);
void pika_wire_clear_error (void);
gboolean pika_wire_read_msg (GIOChannel *channel,
PikaWireMessage *msg,
gpointer user_data);
gboolean pika_wire_write_msg (GIOChannel *channel,
PikaWireMessage *msg,
gpointer user_data);
void pika_wire_destroy (PikaWireMessage *msg);
/* for internal use in libpikabase */
G_GNUC_INTERNAL gboolean _pika_wire_read_int64 (GIOChannel *channel,
guint64 *data,
gint count,
gpointer user_data);
G_GNUC_INTERNAL gboolean _pika_wire_read_int32 (GIOChannel *channel,
guint32 *data,
gint count,
gpointer user_data);
G_GNUC_INTERNAL gboolean _pika_wire_read_int16 (GIOChannel *channel,
guint16 *data,
gint count,
gpointer user_data);
G_GNUC_INTERNAL gboolean _pika_wire_read_int8 (GIOChannel *channel,
guint8 *data,
gint count,
gpointer user_data);
G_GNUC_INTERNAL gboolean _pika_wire_read_double (GIOChannel *channel,
gdouble *data,
gint count,
gpointer user_data);
G_GNUC_INTERNAL gboolean _pika_wire_read_string (GIOChannel *channel,
gchar **data,
gint count,
gpointer user_data);
G_GNUC_INTERNAL gboolean _pika_wire_read_color (GIOChannel *channel,
PikaRGB *data,
gint count,
gpointer user_data);
G_GNUC_INTERNAL gboolean _pika_wire_write_int64 (GIOChannel *channel,
const guint64 *data,
gint count,
gpointer user_data);
G_GNUC_INTERNAL gboolean _pika_wire_write_int32 (GIOChannel *channel,
const guint32 *data,
gint count,
gpointer user_data);
G_GNUC_INTERNAL gboolean _pika_wire_write_int16 (GIOChannel *channel,
const guint16 *data,
gint count,
gpointer user_data);
G_GNUC_INTERNAL gboolean _pika_wire_write_int8 (GIOChannel *channel,
const guint8 *data,
gint count,
gpointer user_data);
G_GNUC_INTERNAL gboolean _pika_wire_write_double (GIOChannel *channel,
const gdouble *data,
gint count,
gpointer user_data);
G_GNUC_INTERNAL gboolean _pika_wire_write_string (GIOChannel *channel,
gchar **data,
gint count,
gpointer user_data);
G_GNUC_INTERNAL gboolean _pika_wire_write_color (GIOChannel *channel,
const PikaRGB *data,
gint count,
gpointer user_data);
G_END_DECLS
#endif /* __PIKA_WIRE_H__ */

View File

@ -0,0 +1,48 @@
/* A small test program for the CPU detection code */
#include "config.h"
#include <stdlib.h>
#include <glib.h>
#include "pikacpuaccel.h"
static void
cpu_accel_print_results (void)
{
PikaCpuAccelFlags support;
g_printerr ("Testing CPU features...\n");
support = pika_cpu_accel_get_support ();
#ifdef ARCH_X86
g_printerr (" mmx : %s\n",
(support & PIKA_CPU_ACCEL_X86_MMX) ? "yes" : "no");
g_printerr (" 3dnow : %s\n",
(support & PIKA_CPU_ACCEL_X86_3DNOW) ? "yes" : "no");
g_printerr (" mmxext : %s\n",
(support & PIKA_CPU_ACCEL_X86_MMXEXT) ? "yes" : "no");
g_printerr (" sse : %s\n",
(support & PIKA_CPU_ACCEL_X86_SSE) ? "yes" : "no");
g_printerr (" sse2 : %s\n",
(support & PIKA_CPU_ACCEL_X86_SSE2) ? "yes" : "no");
g_printerr (" sse3 : %s\n",
(support & PIKA_CPU_ACCEL_X86_SSE3) ? "yes" : "no");
#endif
#ifdef ARCH_PPC
g_printerr (" altivec : %s\n",
(support & PIKA_CPU_ACCEL_PPC_ALTIVEC) ? "yes" : "no");
#endif
g_printerr ("\n");
}
int
main (void)
{
cpu_accel_print_results ();
return EXIT_SUCCESS;
}