13ff48bf5SDavid du Colombier /* Copyright (C) 1993, 2000 Aladdin Enterprises. All rights reserved. 27dd7cddfSDavid du Colombier 3*593dc095SDavid du Colombier This software is provided AS-IS with no warranty, either express or 4*593dc095SDavid du Colombier implied. 57dd7cddfSDavid du Colombier 6*593dc095SDavid du Colombier This software is distributed under license and may not be copied, 7*593dc095SDavid du Colombier modified or distributed except as expressly authorized under the terms 8*593dc095SDavid du Colombier of the license contained in the file LICENSE in this distribution. 97dd7cddfSDavid du Colombier 10*593dc095SDavid du Colombier For more information about licensing, please refer to 11*593dc095SDavid du Colombier http://www.ghostscript.com/licensing/. For information on 12*593dc095SDavid du Colombier commercial licensing, go to http://www.artifex.com/licensing/ or 13*593dc095SDavid du Colombier contact Artifex Software, Inc., 101 Lucas Valley Road #110, 14*593dc095SDavid du Colombier San Rafael, CA 94903, U.S.A., +1(415)492-9861. 157dd7cddfSDavid du Colombier */ 167dd7cddfSDavid du Colombier 17*593dc095SDavid du Colombier /* $Id: gsparam.h,v 1.13 2005/09/05 13:58:55 leonardo Exp $ */ 187dd7cddfSDavid du Colombier /* Client interface to parameter dictionaries */ 197dd7cddfSDavid du Colombier 207dd7cddfSDavid du Colombier #ifndef gsparam_INCLUDED 217dd7cddfSDavid du Colombier # define gsparam_INCLUDED 227dd7cddfSDavid du Colombier 233ff48bf5SDavid du Colombier #include "gsstype.h" 243ff48bf5SDavid du Colombier 257dd7cddfSDavid du Colombier /* 267dd7cddfSDavid du Colombier * Several interfaces use parameter dictionaries to communicate sets of 277dd7cddfSDavid du Colombier * (key, value) pairs between a client and an object with complex state. 287dd7cddfSDavid du Colombier * (Several of these correspond directly to similar interfaces in the 297dd7cddfSDavid du Colombier * PostScript language.) This file defines the API for parameter dictionaries. 307dd7cddfSDavid du Colombier */ 317dd7cddfSDavid du Colombier 327dd7cddfSDavid du Colombier /* ---------------- Generic interfaces ---------------- */ 337dd7cddfSDavid du Colombier 347dd7cddfSDavid du Colombier /* Define the abstract type for a parameter list. */ 357dd7cddfSDavid du Colombier #ifndef gs_param_list_DEFINED 367dd7cddfSDavid du Colombier # define gs_param_list_DEFINED 377dd7cddfSDavid du Colombier typedef struct gs_param_list_s gs_param_list; 387dd7cddfSDavid du Colombier #endif 397dd7cddfSDavid du Colombier 407dd7cddfSDavid du Colombier /* Define the type for a parameter key name. */ 417dd7cddfSDavid du Colombier typedef const char *gs_param_name; 427dd7cddfSDavid du Colombier 437dd7cddfSDavid du Colombier /* 447dd7cddfSDavid du Colombier * Parameter values fall into three categories: 457dd7cddfSDavid du Colombier * - Scalar (null, Boolean, int, long, float); 467dd7cddfSDavid du Colombier * - Homogenous collection (string/name, int array, float array, 477dd7cddfSDavid du Colombier * string/name array); 487dd7cddfSDavid du Colombier * - Heterogenous collection (dictionary, int-keyed dictionary, array). 497dd7cddfSDavid du Colombier * Each category has its own representation and memory management issues. 507dd7cddfSDavid du Colombier */ 517dd7cddfSDavid du Colombier typedef enum { 527dd7cddfSDavid du Colombier /* Scalar */ 537dd7cddfSDavid du Colombier gs_param_type_null, gs_param_type_bool, gs_param_type_int, 547dd7cddfSDavid du Colombier gs_param_type_long, gs_param_type_float, 557dd7cddfSDavid du Colombier /* Homogenous collection */ 567dd7cddfSDavid du Colombier gs_param_type_string, gs_param_type_name, 577dd7cddfSDavid du Colombier gs_param_type_int_array, gs_param_type_float_array, 587dd7cddfSDavid du Colombier gs_param_type_string_array, gs_param_type_name_array, 597dd7cddfSDavid du Colombier /* Heterogenous collection */ 607dd7cddfSDavid du Colombier gs_param_type_dict, gs_param_type_dict_int_keys, gs_param_type_array 617dd7cddfSDavid du Colombier } gs_param_type; 627dd7cddfSDavid du Colombier 637dd7cddfSDavid du Colombier /* Define a "don't care" type for reading typed values. */ 647dd7cddfSDavid du Colombier #define gs_param_type_any ((gs_param_type)-1) 657dd7cddfSDavid du Colombier 667dd7cddfSDavid du Colombier /* 677dd7cddfSDavid du Colombier * Define the structures for homogenous collection values 687dd7cddfSDavid du Colombier * (string/name, integer array, or floating point array). 697dd7cddfSDavid du Colombier * The size is the number of elements, not the size in bytes. 707dd7cddfSDavid du Colombier * A value is persistent if it is defined as static const, 717dd7cddfSDavid du Colombier * or if it is allocated in garbage-collectable space and never freed. 727dd7cddfSDavid du Colombier */ 737dd7cddfSDavid du Colombier 747dd7cddfSDavid du Colombier #define _param_array_struct(sname,etype)\ 757dd7cddfSDavid du Colombier struct sname { const etype *data; uint size; bool persistent; } 767dd7cddfSDavid du Colombier typedef _param_array_struct(gs_param_int_array_s, int) gs_param_int_array; 777dd7cddfSDavid du Colombier typedef _param_array_struct(gs_param_float_array_s, float) gs_param_float_array; 787dd7cddfSDavid du Colombier typedef _param_array_struct(gs_param_string_array_s, gs_param_string) gs_param_string_array; 797dd7cddfSDavid du Colombier 807dd7cddfSDavid du Colombier #define param_string_from_string(ps, str)\ 817dd7cddfSDavid du Colombier ((ps).data = (const byte *)(str),\ 827dd7cddfSDavid du Colombier (ps).size = strlen((const char *)(ps).data),\ 837dd7cddfSDavid du Colombier (ps).persistent = true) 847dd7cddfSDavid du Colombier 853ff48bf5SDavid du Colombier #define param_string_from_transient_string(ps, str)\ 863ff48bf5SDavid du Colombier ((ps).data = (const byte *)(str),\ 873ff48bf5SDavid du Colombier (ps).size = strlen((const char *)(ps).data),\ 883ff48bf5SDavid du Colombier (ps).persistent = false) 893ff48bf5SDavid du Colombier 907dd7cddfSDavid du Colombier /* 917dd7cddfSDavid du Colombier * Define the structure for heterogenous collection values (dictionaries 927dd7cddfSDavid du Colombier * and heterogenous arrays). 937dd7cddfSDavid du Colombier */ 947dd7cddfSDavid du Colombier typedef struct gs_param_collection_s { 957dd7cddfSDavid du Colombier gs_param_list *list; 967dd7cddfSDavid du Colombier uint size; 977dd7cddfSDavid du Colombier } gs_param_collection; 987dd7cddfSDavid du Colombier typedef gs_param_collection gs_param_dict; 997dd7cddfSDavid du Colombier typedef gs_param_collection gs_param_array; 1007dd7cddfSDavid du Colombier 1017dd7cddfSDavid du Colombier /* 1027dd7cddfSDavid du Colombier * Define the sizes of the various parameter value types, indexed by type. 1037dd7cddfSDavid du Colombier */ 1047dd7cddfSDavid du Colombier #define GS_PARAM_TYPE_SIZES(dict_size)\ 1057dd7cddfSDavid du Colombier 0, sizeof(bool), sizeof(int), sizeof(long), sizeof(float),\ 1067dd7cddfSDavid du Colombier sizeof(gs_param_string), sizeof(gs_param_string),\ 1077dd7cddfSDavid du Colombier sizeof(gs_param_int_array), sizeof(gs_param_float_array),\ 1087dd7cddfSDavid du Colombier sizeof(gs_param_string_array), sizeof(gs_param_string_array),\ 1097dd7cddfSDavid du Colombier (dict_size), (dict_size), (dict_size) 1107dd7cddfSDavid du Colombier /* 1117dd7cddfSDavid du Colombier * Define the sizes of the underlying data types contained in or pointed 1127dd7cddfSDavid du Colombier * to by the various value types. 1137dd7cddfSDavid du Colombier */ 1147dd7cddfSDavid du Colombier #define GS_PARAM_TYPE_BASE_SIZES(dict_elt_size)\ 1157dd7cddfSDavid du Colombier 0, sizeof(bool), sizeof(int), sizeof(long), sizeof(float),\ 1167dd7cddfSDavid du Colombier 1, 1, sizeof(int), sizeof(float),\ 1177dd7cddfSDavid du Colombier sizeof(gs_param_string), sizeof(gs_param_string),\ 1187dd7cddfSDavid du Colombier (dict_elt_size), (dict_elt_size), (dict_elt_size) 1197dd7cddfSDavid du Colombier 1207dd7cddfSDavid du Colombier /* Define tables with 0 for the sizes of the heterogenous collections. */ 1217dd7cddfSDavid du Colombier extern const byte gs_param_type_sizes[]; 1227dd7cddfSDavid du Colombier extern const byte gs_param_type_base_sizes[]; 1237dd7cddfSDavid du Colombier 1247dd7cddfSDavid du Colombier /* Define a union capable of holding any parameter value. */ 1257dd7cddfSDavid du Colombier #define GS_PARAM_VALUE_UNION(dict_type)\ 1267dd7cddfSDavid du Colombier bool b;\ 1277dd7cddfSDavid du Colombier int i;\ 1287dd7cddfSDavid du Colombier long l;\ 1297dd7cddfSDavid du Colombier float f;\ 1307dd7cddfSDavid du Colombier gs_param_string s;\ 1317dd7cddfSDavid du Colombier gs_param_string n;\ 1327dd7cddfSDavid du Colombier gs_param_int_array ia;\ 1337dd7cddfSDavid du Colombier gs_param_float_array fa;\ 1347dd7cddfSDavid du Colombier gs_param_string_array sa;\ 1357dd7cddfSDavid du Colombier gs_param_string_array na;\ 1367dd7cddfSDavid du Colombier dict_type d 1377dd7cddfSDavid du Colombier typedef union gs_param_value_s { 1387dd7cddfSDavid du Colombier GS_PARAM_VALUE_UNION(gs_param_collection); 1397dd7cddfSDavid du Colombier } gs_param_value; 1407dd7cddfSDavid du Colombier 1417dd7cddfSDavid du Colombier /* 1427dd7cddfSDavid du Colombier * Define a structure containing a dynamically typed value (a value along 1433ff48bf5SDavid du Colombier * with its type). 1447dd7cddfSDavid du Colombier */ 1457dd7cddfSDavid du Colombier typedef struct gs_param_typed_value_s { 1467dd7cddfSDavid du Colombier gs_param_value value; 1477dd7cddfSDavid du Colombier gs_param_type type; 1487dd7cddfSDavid du Colombier } gs_param_typed_value; 1493ff48bf5SDavid du Colombier /* 1503ff48bf5SDavid du Colombier * Garbage collection of gs_param_values depends on the value type and on 1513ff48bf5SDavid du Colombier * the 'd' member of the union. We provide enum_ptrs and reloc_ptrs 1523ff48bf5SDavid du Colombier * procedures that handle all the other cases -- i.e., cases other than 1533ff48bf5SDavid du Colombier * heterogenous collections. 1543ff48bf5SDavid du Colombier */ 1553ff48bf5SDavid du Colombier struct_proc_enum_ptrs(gs_param_typed_value_enum_ptrs); 1563ff48bf5SDavid du Colombier struct_proc_reloc_ptrs(gs_param_typed_value_reloc_ptrs); 1573ff48bf5SDavid du Colombier #define gs_param_typed_value_max_ptrs 1 1587dd7cddfSDavid du Colombier 1597dd7cddfSDavid du Colombier /* 1607dd7cddfSDavid du Colombier * Define the representation alternatives for heterogenous collections. 1617dd7cddfSDavid du Colombier * _any must be 0, for Boolean testing. 1627dd7cddfSDavid du Colombier */ 1637dd7cddfSDavid du Colombier typedef enum { 1647dd7cddfSDavid du Colombier 1657dd7cddfSDavid du Colombier /* Create or accept a general dictionary. */ 1667dd7cddfSDavid du Colombier 1677dd7cddfSDavid du Colombier gs_param_collection_dict_any = 0, 1687dd7cddfSDavid du Colombier 1697dd7cddfSDavid du Colombier /* Create a dictionary with integer string keys ("0", "1", ...); */ 1707dd7cddfSDavid du Colombier /* accept a dictionary with integer string keys, or a heterogenous */ 1717dd7cddfSDavid du Colombier /* array. */ 1727dd7cddfSDavid du Colombier 1737dd7cddfSDavid du Colombier gs_param_collection_dict_int_keys = 1, 1747dd7cddfSDavid du Colombier 1757dd7cddfSDavid du Colombier /* Create an array if possible, otherwise a dictionary with integer */ 1767dd7cddfSDavid du Colombier /* string keys; accept the same types as dict_int_keys. */ 1777dd7cddfSDavid du Colombier 1787dd7cddfSDavid du Colombier gs_param_collection_array = 2 1797dd7cddfSDavid du Colombier 1807dd7cddfSDavid du Colombier } gs_param_collection_type_t; 1817dd7cddfSDavid du Colombier 1827dd7cddfSDavid du Colombier /* 1837dd7cddfSDavid du Colombier * Define the 'policies' for handling out-of-range parameter values. 1847dd7cddfSDavid du Colombier * This is not an enum, because some parameters may recognize other values. 1857dd7cddfSDavid du Colombier */ 1867dd7cddfSDavid du Colombier #define gs_param_policy_signal_error 0 1877dd7cddfSDavid du Colombier #define gs_param_policy_ignore 1 1887dd7cddfSDavid du Colombier #define gs_param_policy_consult_user 2 1897dd7cddfSDavid du Colombier 1907dd7cddfSDavid du Colombier /* 1917dd7cddfSDavid du Colombier * Define an enumerator used to iterate through the keys in a list. 1927dd7cddfSDavid du Colombier * 1937dd7cddfSDavid du Colombier * All the members of the union must be used such that memset(0) entire 1947dd7cddfSDavid du Colombier * union means 'beginning of enumeration'. 1957dd7cddfSDavid du Colombier */ 1967dd7cddfSDavid du Colombier typedef union gs_param_enumerator_s { 1977dd7cddfSDavid du Colombier int intval; 1987dd7cddfSDavid du Colombier long longval; 1997dd7cddfSDavid du Colombier void *pvoid; 2007dd7cddfSDavid du Colombier char *pchar; 2017dd7cddfSDavid du Colombier } gs_param_enumerator_t; 2023ff48bf5SDavid du Colombier typedef gs_param_string gs_param_key_t; 2037dd7cddfSDavid du Colombier 2047dd7cddfSDavid du Colombier /* 2057dd7cddfSDavid du Colombier * Define the object procedures. Note that the same interface is used 2067dd7cddfSDavid du Colombier * both for getting and for setting parameter values. (This is a bit 2077dd7cddfSDavid du Colombier * of a hack, and we might change it someday.) The procedures return 2087dd7cddfSDavid du Colombier * as follows: 2097dd7cddfSDavid du Colombier * - 'reading' procedures ('put' operations from the client's viewpoint) 2107dd7cddfSDavid du Colombier * return 1 for a missing parameter, 0 for a valid parameter, <0 on error. 2117dd7cddfSDavid du Colombier * - 'writing' procedures ('get' operations from the client's viewpoint) 2127dd7cddfSDavid du Colombier * return 0 or 1 if successful, <0 on error. 2137dd7cddfSDavid du Colombier * 2147dd7cddfSDavid du Colombier * A lazy implementation can use the default procedures for scalar and 2157dd7cddfSDavid du Colombier * homogenous collection types: these just called xmit_typed. 2167dd7cddfSDavid du Colombier */ 2177dd7cddfSDavid du Colombier 2187dd7cddfSDavid du Colombier /* 2197dd7cddfSDavid du Colombier * Transmitting variable-size objects requires some extra care. 2207dd7cddfSDavid du Colombier * - When writing an array, string, name, or dictionary, the 2217dd7cddfSDavid du Colombier * implementation (not the client) sets all the fields of the value. 2227dd7cddfSDavid du Colombier * - When reading an array, string, or name, the client must set 2237dd7cddfSDavid du Colombier * all the fields of the value. 2247dd7cddfSDavid du Colombier * - When reading a dictionary, the client must set the size field 2257dd7cddfSDavid du Colombier * before calling begin_write_dict; the implementation of begin_write_dict 2267dd7cddfSDavid du Colombier * allocates the list. 2277dd7cddfSDavid du Colombier */ 2287dd7cddfSDavid du Colombier 2297dd7cddfSDavid du Colombier /* 2307dd7cddfSDavid du Colombier * Setting parameters must use a "two-phase commit" policy. Specifically, 2317dd7cddfSDavid du Colombier * any put_params procedure must observe the following discipline: 2327dd7cddfSDavid du Colombier 2337dd7cddfSDavid du Colombier 1. For each parameter known to the device, ask the parameter list if 2347dd7cddfSDavid du Colombier there is a new value, and if so, make all necessary validity checks. If any 2357dd7cddfSDavid du Colombier check fails, call param_signal_error for that parameter, but continue to 2367dd7cddfSDavid du Colombier check further parameters. Normally, this step should not alter the state of 2377dd7cddfSDavid du Colombier the device; however, if the device allows changing any parameters that are 2387dd7cddfSDavid du Colombier read-only by default (for example, BitsPerPixel or ProcessColorModel), or if 2397dd7cddfSDavid du Colombier it replaces the default put_params behavior for any parameter (for example, 2407dd7cddfSDavid du Colombier if it handles MediaSize or Resolution itself to forestall the normal closing 2417dd7cddfSDavid du Colombier of the device when these are set), step 1 of put_params must change the 2427dd7cddfSDavid du Colombier parameters in the device state, and step 2 must undo the changes if 2437dd7cddfSDavid du Colombier returning an error. 2447dd7cddfSDavid du Colombier 2457dd7cddfSDavid du Colombier 2. Call the "superclass" put_params routine. For printer devices, 2467dd7cddfSDavid du Colombier this is gdev_prn_put_params; for other devices, it is gx_default_put_params. 2477dd7cddfSDavid du Colombier Note that this must be done even if errors were detected in step 1. If this 2487dd7cddfSDavid du Colombier routine returns an error code, or if step 1 detected an error, undo any 2497dd7cddfSDavid du Colombier changes that step 1 made in the device state, and return the error code. 2507dd7cddfSDavid du Colombier 2517dd7cddfSDavid du Colombier 3. Install the new parameter values in the device. If necessary, 2527dd7cddfSDavid du Colombier close the device first; a higher-level routine (gs_putdeviceparams) will 2537dd7cddfSDavid du Colombier reopen the device if necessary. 2547dd7cddfSDavid du Colombier 2557dd7cddfSDavid du Colombier */ 2567dd7cddfSDavid du Colombier 2577dd7cddfSDavid du Colombier typedef struct gs_param_list_procs_s { 2587dd7cddfSDavid du Colombier 2597dd7cddfSDavid du Colombier /* Transmit a typed value. */ 2607dd7cddfSDavid du Colombier /* 2617dd7cddfSDavid du Colombier * Note that read/write_typed do a begin_read/write_collection 2627dd7cddfSDavid du Colombier * if the type is one of the heterogenous collection types. 2637dd7cddfSDavid du Colombier * Note also that even for reading, the caller must set pvalue->type 2647dd7cddfSDavid du Colombier * to the desired type or to gs_param_type_any. 2657dd7cddfSDavid du Colombier */ 2667dd7cddfSDavid du Colombier 2677dd7cddfSDavid du Colombier #define param_proc_xmit_typed(proc)\ 268*593dc095SDavid du Colombier int proc(gs_param_list *, gs_param_name, gs_param_typed_value *) 2697dd7cddfSDavid du Colombier param_proc_xmit_typed((*xmit_typed)); 2707dd7cddfSDavid du Colombier /* See below for param_read_[requested_]typed */ 2717dd7cddfSDavid du Colombier #define param_write_typed(plist, pkey, pvalue)\ 2727dd7cddfSDavid du Colombier (*(plist)->procs->xmit_typed)(plist, pkey, pvalue) 2737dd7cddfSDavid du Colombier 2747dd7cddfSDavid du Colombier /* Start transmitting a dictionary or heterogenous value. */ 2757dd7cddfSDavid du Colombier 2767dd7cddfSDavid du Colombier #define param_proc_begin_xmit_collection(proc)\ 277*593dc095SDavid du Colombier int proc(gs_param_list *, gs_param_name, gs_param_dict *,\ 278*593dc095SDavid du Colombier gs_param_collection_type_t) 2797dd7cddfSDavid du Colombier param_proc_begin_xmit_collection((*begin_xmit_collection)); 2807dd7cddfSDavid du Colombier #define param_begin_read_collection(plist, pkey, pvalue, coll_type)\ 2817dd7cddfSDavid du Colombier (*(plist)->procs->begin_xmit_collection)(plist, pkey, pvalue, coll_type) 2827dd7cddfSDavid du Colombier #define param_begin_read_dict(l, k, v, int_keys)\ 2837dd7cddfSDavid du Colombier param_begin_read_collection(l, k, v,\ 2847dd7cddfSDavid du Colombier (int_keys ? gs_param_collection_dict_int_keys :\ 2857dd7cddfSDavid du Colombier gs_param_collection_dict_any)) 2867dd7cddfSDavid du Colombier #define param_begin_write_collection(plist, pkey, pvalue, coll_type)\ 2877dd7cddfSDavid du Colombier (*(plist)->procs->begin_xmit_collection)(plist, pkey, pvalue, coll_type) 2887dd7cddfSDavid du Colombier #define param_begin_write_dict(l, k, v, int_keys)\ 2897dd7cddfSDavid du Colombier param_begin_write_collection(l, k, v,\ 2907dd7cddfSDavid du Colombier (int_keys ? gs_param_collection_dict_int_keys :\ 2917dd7cddfSDavid du Colombier gs_param_collection_dict_any)) 2927dd7cddfSDavid du Colombier 2937dd7cddfSDavid du Colombier /* Finish transmitting a collection value. */ 2947dd7cddfSDavid du Colombier 2957dd7cddfSDavid du Colombier #define param_proc_end_xmit_collection(proc)\ 296*593dc095SDavid du Colombier int proc(gs_param_list *, gs_param_name, gs_param_dict *) 2977dd7cddfSDavid du Colombier param_proc_end_xmit_collection((*end_xmit_collection)); 2987dd7cddfSDavid du Colombier #define param_end_read_collection(plist, pkey, pvalue)\ 2997dd7cddfSDavid du Colombier (*(plist)->procs->end_xmit_collection)(plist, pkey, pvalue) 3007dd7cddfSDavid du Colombier #define param_end_read_dict(l, k, v) param_end_read_collection(l, k, v) 3017dd7cddfSDavid du Colombier #define param_end_write_collection(plist, pkey, pvalue)\ 3027dd7cddfSDavid du Colombier (*(plist)->procs->end_xmit_collection)(plist, pkey, pvalue) 3037dd7cddfSDavid du Colombier #define param_end_write_dict(l, k, v) param_end_write_collection(l, k, v) 3047dd7cddfSDavid du Colombier 3057dd7cddfSDavid du Colombier /* 3067dd7cddfSDavid du Colombier * Get the next key in sequence. 3077dd7cddfSDavid du Colombier * (Only used when reading.) 3087dd7cddfSDavid du Colombier * Use param_init_enumerator(...) to reset to first key. 3097dd7cddfSDavid du Colombier */ 3107dd7cddfSDavid du Colombier 3117dd7cddfSDavid du Colombier #define param_proc_next_key(proc)\ 312*593dc095SDavid du Colombier int proc(gs_param_list *, gs_param_enumerator_t *, gs_param_key_t *) 3137dd7cddfSDavid du Colombier param_proc_next_key((*next_key)); 3147dd7cddfSDavid du Colombier #define param_get_next_key(plist, penum, pkey)\ 3157dd7cddfSDavid du Colombier (*(plist)->procs->next_key)(plist, penum, pkey) 3167dd7cddfSDavid du Colombier 3177dd7cddfSDavid du Colombier /* 3187dd7cddfSDavid du Colombier * Request a specific parameter. (Only used when writing, before 3197dd7cddfSDavid du Colombier * writing any values.) If no specific parameters are requested, 3207dd7cddfSDavid du Colombier * param_requested always returns -1; if specific parameters 3217dd7cddfSDavid du Colombier * are requested, param_requested will return 1 for those, 3227dd7cddfSDavid du Colombier * and may return either 0 or 1 for others. 3237dd7cddfSDavid du Colombier */ 3247dd7cddfSDavid du Colombier 3257dd7cddfSDavid du Colombier #define param_proc_request(proc)\ 326*593dc095SDavid du Colombier int proc(gs_param_list *, gs_param_name) 3277dd7cddfSDavid du Colombier param_proc_request((*request)); 3287dd7cddfSDavid du Colombier 3297dd7cddfSDavid du Colombier #define param_request(plist, pkey)\ 3307dd7cddfSDavid du Colombier ((plist)->procs->request(plist, pkey)) 3317dd7cddfSDavid du Colombier 3327dd7cddfSDavid du Colombier /* 3337dd7cddfSDavid du Colombier * Determine whether a given key has been requested. (Only used 3347dd7cddfSDavid du Colombier * when writing.) A return value of -1 means that no specific 3357dd7cddfSDavid du Colombier * parameters have been requested; 0 means specific parameters have 3367dd7cddfSDavid du Colombier * been requested, but not this one; 1 means this parameter has 3377dd7cddfSDavid du Colombier * been requested specifically. 3387dd7cddfSDavid du Colombier */ 3397dd7cddfSDavid du Colombier 3407dd7cddfSDavid du Colombier #define param_proc_requested(proc)\ 341*593dc095SDavid du Colombier int proc(const gs_param_list *, gs_param_name) 3427dd7cddfSDavid du Colombier param_proc_requested((*requested)); 3437dd7cddfSDavid du Colombier #define param_requested(plist, pkey)\ 3447dd7cddfSDavid du Colombier (*(plist)->procs->requested)(plist, pkey) 3457dd7cddfSDavid du Colombier 3467dd7cddfSDavid du Colombier /* Get the 'policy' associated with an out-of-range parameter value. */ 3477dd7cddfSDavid du Colombier /* (Only used when reading.) */ 3487dd7cddfSDavid du Colombier 3497dd7cddfSDavid du Colombier #define param_proc_get_policy(proc)\ 350*593dc095SDavid du Colombier int proc(gs_param_list *, gs_param_name) 3517dd7cddfSDavid du Colombier param_proc_get_policy((*get_policy)); 3527dd7cddfSDavid du Colombier #define param_get_policy(plist, pkey)\ 3537dd7cddfSDavid du Colombier (*(plist)->procs->get_policy)(plist, pkey) 3547dd7cddfSDavid du Colombier 3557dd7cddfSDavid du Colombier /* 3567dd7cddfSDavid du Colombier * Signal an error. (Only used when reading.) 3577dd7cddfSDavid du Colombier * The procedure may return a different error code, 3587dd7cddfSDavid du Colombier * or may return 0 indicating that the error is to be ignored. 3597dd7cddfSDavid du Colombier */ 3607dd7cddfSDavid du Colombier 3617dd7cddfSDavid du Colombier #define param_proc_signal_error(proc)\ 362*593dc095SDavid du Colombier int proc(gs_param_list *, gs_param_name, int) 3637dd7cddfSDavid du Colombier param_proc_signal_error((*signal_error)); 3647dd7cddfSDavid du Colombier #define param_signal_error(plist, pkey, code)\ 3657dd7cddfSDavid du Colombier (*(plist)->procs->signal_error)(plist, pkey, code) 3667dd7cddfSDavid du Colombier #define param_return_error(plist, pkey, code)\ 3677dd7cddfSDavid du Colombier return_error(param_signal_error(plist, pkey, code)) 3687dd7cddfSDavid du Colombier 3697dd7cddfSDavid du Colombier /* 3707dd7cddfSDavid du Colombier * "Commit" a set of changes. (Only used when reading.) 3717dd7cddfSDavid du Colombier * This is called at the end of the first phase. 3727dd7cddfSDavid du Colombier */ 3737dd7cddfSDavid du Colombier 3747dd7cddfSDavid du Colombier #define param_proc_commit(proc)\ 375*593dc095SDavid du Colombier int proc(gs_param_list *) 3767dd7cddfSDavid du Colombier param_proc_commit((*commit)); 3777dd7cddfSDavid du Colombier #define param_commit(plist)\ 3787dd7cddfSDavid du Colombier (*(plist)->procs->commit)(plist) 3797dd7cddfSDavid du Colombier 3807dd7cddfSDavid du Colombier } gs_param_list_procs; 3817dd7cddfSDavid du Colombier 3827dd7cddfSDavid du Colombier /* Transmit typed parameters. */ 383*593dc095SDavid du Colombier int param_read_requested_typed(gs_param_list *, gs_param_name, 384*593dc095SDavid du Colombier gs_param_typed_value *); 3857dd7cddfSDavid du Colombier 3867dd7cddfSDavid du Colombier #define param_read_typed(plist, pkey, pvalue)\ 3877dd7cddfSDavid du Colombier ((pvalue)->type = gs_param_type_any,\ 3887dd7cddfSDavid du Colombier param_read_requested_typed(plist, pkey, pvalue)) 3897dd7cddfSDavid du Colombier 3907dd7cddfSDavid du Colombier /* Transmit parameters of specific types. */ 391*593dc095SDavid du Colombier int param_read_null(gs_param_list *, gs_param_name); 392*593dc095SDavid du Colombier int param_write_null(gs_param_list *, gs_param_name); 393*593dc095SDavid du Colombier int param_read_bool(gs_param_list *, gs_param_name, bool *); 394*593dc095SDavid du Colombier int param_write_bool(gs_param_list *, gs_param_name, const bool *); 395*593dc095SDavid du Colombier int param_read_int(gs_param_list *, gs_param_name, int *); 396*593dc095SDavid du Colombier int param_write_int(gs_param_list *, gs_param_name, const int *); 397*593dc095SDavid du Colombier int param_read_long(gs_param_list *, gs_param_name, long *); 398*593dc095SDavid du Colombier int param_write_long(gs_param_list *, gs_param_name, const long *); 399*593dc095SDavid du Colombier int param_read_float(gs_param_list *, gs_param_name, float *); 400*593dc095SDavid du Colombier int param_write_float(gs_param_list *, gs_param_name, const float *); 401*593dc095SDavid du Colombier int param_read_string(gs_param_list *, gs_param_name, gs_param_string *); 402*593dc095SDavid du Colombier int param_write_string(gs_param_list *, gs_param_name, 403*593dc095SDavid du Colombier const gs_param_string *); 404*593dc095SDavid du Colombier int param_read_name(gs_param_list *, gs_param_name, gs_param_string *); 405*593dc095SDavid du Colombier int param_write_name(gs_param_list *, gs_param_name, 406*593dc095SDavid du Colombier const gs_param_string *); 407*593dc095SDavid du Colombier int param_read_int_array(gs_param_list *, gs_param_name, 408*593dc095SDavid du Colombier gs_param_int_array *); 409*593dc095SDavid du Colombier int param_write_int_array(gs_param_list *, gs_param_name, 410*593dc095SDavid du Colombier const gs_param_int_array *); 411*593dc095SDavid du Colombier int param_write_int_values(gs_param_list *, gs_param_name, 412*593dc095SDavid du Colombier const int *, uint, bool); 413*593dc095SDavid du Colombier int param_read_float_array(gs_param_list *, gs_param_name, 414*593dc095SDavid du Colombier gs_param_float_array *); 415*593dc095SDavid du Colombier int param_write_float_array(gs_param_list *, gs_param_name, 416*593dc095SDavid du Colombier const gs_param_float_array *); 417*593dc095SDavid du Colombier int param_write_float_values(gs_param_list *, gs_param_name, 418*593dc095SDavid du Colombier const float *, uint, bool); 419*593dc095SDavid du Colombier int param_read_string_array(gs_param_list *, gs_param_name, 420*593dc095SDavid du Colombier gs_param_string_array *); 421*593dc095SDavid du Colombier int param_write_string_array(gs_param_list *, gs_param_name, 422*593dc095SDavid du Colombier const gs_param_string_array *); 423*593dc095SDavid du Colombier int param_read_name_array(gs_param_list *, gs_param_name, 424*593dc095SDavid du Colombier gs_param_string_array *); 425*593dc095SDavid du Colombier int param_write_name_array(gs_param_list *, gs_param_name, 426*593dc095SDavid du Colombier const gs_param_string_array *); 4277dd7cddfSDavid du Colombier 4283ff48bf5SDavid du Colombier /* 4293ff48bf5SDavid du Colombier * Define an abstract parameter list. Implementations are concrete 4303ff48bf5SDavid du Colombier * subclasses. 4313ff48bf5SDavid du Colombier * 4323ff48bf5SDavid du Colombier * The persisent_keys flag allows for both statically and dynamically 4333ff48bf5SDavid du Colombier * allocated keys. The default is static (the keys are normally C string 4343ff48bf5SDavid du Colombier * literals). 4353ff48bf5SDavid du Colombier */ 4367dd7cddfSDavid du Colombier #define gs_param_list_common\ 4377dd7cddfSDavid du Colombier const gs_param_list_procs *procs;\ 4383ff48bf5SDavid du Colombier gs_memory_t *memory; /* for allocating coerced arrays */\ 4393ff48bf5SDavid du Colombier bool persistent_keys 4407dd7cddfSDavid du Colombier struct gs_param_list_s { 4417dd7cddfSDavid du Colombier gs_param_list_common; 4427dd7cddfSDavid du Colombier }; 4437dd7cddfSDavid du Colombier 4443ff48bf5SDavid du Colombier /* Set whether the keys for param_write_XXX are persistent. */ 4453ff48bf5SDavid du Colombier /* VMS limits procedure names to 31 characters. */ 4463ff48bf5SDavid du Colombier #define gs_param_list_set_persistent_keys gs_param_list_set_persist_keys 447*593dc095SDavid du Colombier void gs_param_list_set_persistent_keys(gs_param_list *, bool); 4483ff48bf5SDavid du Colombier 4497dd7cddfSDavid du Colombier /* Initialize a parameter list key enumerator. */ 450*593dc095SDavid du Colombier void param_init_enumerator(gs_param_enumerator_t * penum); 4517dd7cddfSDavid du Colombier 4527dd7cddfSDavid du Colombier /* 4537dd7cddfSDavid du Colombier * The following interface provides a convenient way to read and set 4547dd7cddfSDavid du Colombier * collections of parameters of any type other than dictionaries. 4557dd7cddfSDavid du Colombier */ 4567dd7cddfSDavid du Colombier 4577dd7cddfSDavid du Colombier typedef struct gs_param_item_s { 4587dd7cddfSDavid du Colombier const char *key; 4597dd7cddfSDavid du Colombier byte /*gs_param_type */ type; 4607dd7cddfSDavid du Colombier short offset; /* offset of value in structure */ 4617dd7cddfSDavid du Colombier } gs_param_item_t; 4627dd7cddfSDavid du Colombier #define gs_param_item_end { 0 } /* list terminator */ 4637dd7cddfSDavid du Colombier /* 4647dd7cddfSDavid du Colombier * Transfer a collection of parameters. 4657dd7cddfSDavid du Colombier * For param_write_items, if a parameter value is equal to the value in 4667dd7cddfSDavid du Colombier * the optional default_obj, the item isn't transferred. 4677dd7cddfSDavid du Colombier */ 468*593dc095SDavid du Colombier int gs_param_read_items(gs_param_list * plist, void *obj, 469*593dc095SDavid du Colombier const gs_param_item_t * items); 470*593dc095SDavid du Colombier int gs_param_write_items(gs_param_list * plist, const void *obj, 4717dd7cddfSDavid du Colombier const void *default_obj, 472*593dc095SDavid du Colombier const gs_param_item_t * items); 4737dd7cddfSDavid du Colombier 4743ff48bf5SDavid du Colombier /* Internal procedure to initialize the common part of a parameter list. */ 475*593dc095SDavid du Colombier void gs_param_list_init(gs_param_list *, const gs_param_list_procs *, 476*593dc095SDavid du Colombier gs_memory_t *); 4773ff48bf5SDavid du Colombier 4783ff48bf5SDavid du Colombier /* 4793ff48bf5SDavid du Colombier * Internal procedure to read a value, with coercion if requested, needed, 4803ff48bf5SDavid du Colombier * and possible. If mem != 0, we can coerce int arrays to float arrays, and 4813ff48bf5SDavid du Colombier * possibly do other coercions later. 4823ff48bf5SDavid du Colombier */ 483*593dc095SDavid du Colombier int param_coerce_typed(gs_param_typed_value * pvalue, 484*593dc095SDavid du Colombier gs_param_type req_type, gs_memory_t * mem); 4853ff48bf5SDavid du Colombier 4867dd7cddfSDavid du Colombier /* ---------------- Default implementation ---------------- */ 4877dd7cddfSDavid du Colombier 4887dd7cddfSDavid du Colombier /* 4897dd7cddfSDavid du Colombier * Provide default generic implementations of param_request and 4907dd7cddfSDavid du Colombier * param_requested. 4917dd7cddfSDavid du Colombier */ 4927dd7cddfSDavid du Colombier param_proc_request(gs_param_request_default); /* does nothing */ 4937dd7cddfSDavid du Colombier param_proc_requested(gs_param_requested_default); /* always returns true */ 4947dd7cddfSDavid du Colombier 4957dd7cddfSDavid du Colombier /* 4967dd7cddfSDavid du Colombier * Define a default implementation, intended to be usable easily 4977dd7cddfSDavid du Colombier * from C code. The intended usage pattern is: 4987dd7cddfSDavid du Colombier gs_c_param_list list; 4997dd7cddfSDavid du Colombier [... other code here ...] 5007dd7cddfSDavid du Colombier gs_c_param_list_write(&list, mem); 5017dd7cddfSDavid du Colombier [As many as needed:] 5027dd7cddfSDavid du Colombier code = param_write_XXX(&list, "ParamName", ¶m_value); 5037dd7cddfSDavid du Colombier [Check code for <0] 5047dd7cddfSDavid du Colombier gs_c_param_list_read(&list); 5057dd7cddfSDavid du Colombier code = gs_putdeviceparams(dev, &list); 5067dd7cddfSDavid du Colombier gs_c_param_list_release(&list); 5077dd7cddfSDavid du Colombier [Check code for <0] 5087dd7cddfSDavid du Colombier if ( code == 1 ) 5097dd7cddfSDavid du Colombier { 5107dd7cddfSDavid du Colombier code = (*dev_proc(dev, open_device))(dev); 5117dd7cddfSDavid du Colombier [Check code for <0] 5127dd7cddfSDavid du Colombier } 5137dd7cddfSDavid du Colombier * 5143ff48bf5SDavid du Colombier * This implementation also has the special property that it can forward 5153ff48bf5SDavid du Colombier * unrecognized param_read_ calls to another parameter list, called the 5163ff48bf5SDavid du Colombier * target. This allows constructing incrementally modified parameter lists. 5173ff48bf5SDavid du Colombier * Note that this is only relevant for put_params (reading from the 5183ff48bf5SDavid du Colombier * parameter list). 5197dd7cddfSDavid du Colombier */ 5207dd7cddfSDavid du Colombier 5217dd7cddfSDavid du Colombier typedef struct gs_c_param_s gs_c_param; /* opaque here */ 5227dd7cddfSDavid du Colombier typedef struct gs_c_param_list_s { 5237dd7cddfSDavid du Colombier gs_param_list_common; 5247dd7cddfSDavid du Colombier gs_c_param *head; 5257dd7cddfSDavid du Colombier gs_param_list *target; 5267dd7cddfSDavid du Colombier uint count; 5277dd7cddfSDavid du Colombier bool any_requested; 5287dd7cddfSDavid du Colombier gs_param_collection_type_t coll_type; 5297dd7cddfSDavid du Colombier } gs_c_param_list; 5307dd7cddfSDavid du Colombier #define private_st_c_param_list() /* in gsparam.c */\ 5317dd7cddfSDavid du Colombier gs_private_st_ptrs2(st_c_param_list, gs_c_param_list, "c_param_list",\ 5327dd7cddfSDavid du Colombier c_param_list_enum_ptrs, c_param_list_reloc_ptrs, head, target) 5337dd7cddfSDavid du Colombier 534*593dc095SDavid du Colombier /* Define a GC descriptor for gs_param_string. */ 535*593dc095SDavid du Colombier /* This structure descriptor is only for non persistent gs_param_strings. */ 536*593dc095SDavid du Colombier #define private_st_gs_param_string() /* in gdevdevn.c */\ 537*593dc095SDavid du Colombier gs_private_st_composite(st_gs_param_string, gs_param_string, "gs_param_string",\ 538*593dc095SDavid du Colombier param_string_enum_ptrs, param_string_reloc_ptrs) 539*593dc095SDavid du Colombier 5407dd7cddfSDavid du Colombier /* Set the target of a C parameter list. */ 541*593dc095SDavid du Colombier void gs_c_param_list_set_target(gs_c_param_list *, gs_param_list *); 5427dd7cddfSDavid du Colombier 5433ff48bf5SDavid du Colombier /* 5443ff48bf5SDavid du Colombier * Clients normally allocate the gs_c_param_list on the stack, but we 5453ff48bf5SDavid du Colombier * provide a procedure for allocating one in memory. 5463ff48bf5SDavid du Colombier */ 547*593dc095SDavid du Colombier gs_c_param_list *gs_c_param_list_alloc(gs_memory_t *, client_name_t); 548*593dc095SDavid du Colombier void gs_c_param_list_write(gs_c_param_list *, gs_memory_t *); 549*593dc095SDavid du Colombier void gs_c_param_list_write_more(gs_c_param_list *); /* switch back to writing, no init */ 550*593dc095SDavid du Colombier void gs_c_param_list_read(gs_c_param_list *); /* switch to reading */ 551*593dc095SDavid du Colombier void gs_c_param_list_release(gs_c_param_list *); 5527dd7cddfSDavid du Colombier 5537dd7cddfSDavid du Colombier #endif /* gsparam_INCLUDED */ 554