/* Common functionality of zgethardwareparms & zgetdeviceparams */ static int zget_device_params(i_ctx_t *i_ctx_p, bool is_hardware) { os_ptr op = osp; ref rkeys; gx_device *dev; stack_param_list list; int code; ref *pmark; check_read_type(op[-1], t_device); rkeys = *op; dev = op[-1].value.pdevice; pop(1); stack_param_list_write(&list, &o_stack, &rkeys, iimemory); code = gs_get_device_or_hardware_params(dev, (gs_param_list *) & list, is_hardware); if (code < 0) { /* We have to put back the top argument. */ if (list.count > 0) ref_stack_pop(&o_stack, list.count * 2 - 1); else ref_stack_push(&o_stack, 1); *osp = rkeys; return code; } pmark = ref_stack_index(&o_stack, list.count * 2); make_mark(pmark); return 0; }
/* <iodevice> .getdevparams <mark> <name> <value> ... */ static int zgetdevparams(i_ctx_t *i_ctx_p) { os_ptr op = osp; gx_io_device *iodev; stack_param_list list; gs_param_list *const plist = (gs_param_list *) & list; int code; ref *pmark; check_read_type(*op, t_string); iodev = gs_findiodevice(imemory, op->value.bytes, r_size(op)); if (iodev == 0) return_error(e_undefined); stack_param_list_write(&list, &o_stack, NULL, iimemory); if ((code = gs_getdevparams(iodev, plist)) < 0) { ref_stack_pop(&o_stack, list.count * 2); return code; } pmark = ref_stack_index(&o_stack, list.count * 2); make_mark(pmark); return 0; }
/* <any> <any> .... /spec_op name .special_op <any> <any> ..... * The special_op operator takes at a minimum the name of the spec_op to execute * and as many additional parameters as are required for the spec_op. It may * return as many additional parameters as required. */ int zspec_op(i_ctx_t *i_ctx_p) { os_ptr op = osp; gx_device *dev = gs_currentdevice(igs); int i, nprocs = sizeof(spec_op_defs) / sizeof(spec_op_t), code, proc = -1; ref opname, nref, namestr; char *data; /* At the very minimum we need a name object telling us which sepc_op to perform */ check_op(1); if (!r_has_type(op, t_name)) return_error(gs_error_typecheck); ref_assign(&opname, op); /* Find the relevant spec_op name */ for (i=0;i<nprocs;i++) { code = names_ref(imemory->gs_lib_ctx->gs_name_table, (const byte *)spec_op_defs[i].name, strlen(spec_op_defs[i].name), &nref, 0); if (code < 0) return code; if (name_eq(&opname, &nref)) { proc = i; break; } } if (proc < 0) return_error(gs_error_undefined); pop(1); /* We don't need the name of the spec_op any more */ op = osp; switch(proc) { case 0: { stack_param_list list; dev_param_req_t request; ref rkeys; /* Get a single device parameter, we should be supplied with * the name of the paramter, as a name object. */ check_op(1); if (!r_has_type(op, t_name)) return_error(gs_error_typecheck); ref_assign(&opname, op); name_string_ref(imemory, &opname, &namestr); data = (char *)gs_alloc_bytes(imemory, r_size(&namestr) + 1, "temporary special_op string"); if (data == 0) return_error(gs_error_VMerror); memset(data, 0x00, r_size(&namestr) + 1); memcpy(data, namestr.value.bytes, r_size(&namestr)); /* Discard the parameter name now, we're done with it */ pop (1); /* Make a null object so that the stack param list won't check for requests */ make_null(&rkeys); stack_param_list_write(&list, &o_stack, &rkeys, iimemory); /* Stuff the data into a structure for passing to the spec_op */ request.Param = data; request.list = &list; code = dev_proc(dev, dev_spec_op)(dev, gxdso_get_dev_param, &request, sizeof(dev_param_req_t)); gs_free_object(imemory, data, "temporary special_op string"); if (code < 0) { if (code == gs_error_undefined) { op = osp; push(1); make_bool(op, 0); } else return_error(code); } else { op = osp; push(1); make_bool(op, 1); } } break; default: /* Belt and braces; it shold not be possible to get here, as the table * containing the names should mirror the entries in this switch. If we * found a name there should be a matching case here. */ return_error(gs_error_undefined); break; } return 0; }
static int current_param_list(i_ctx_t *i_ctx_p, const param_set * pset, const ref * psref /*t_string */ ) { stack_param_list list; gs_param_list *const plist = (gs_param_list *)&list; int code = 0; unsigned int i; stack_param_list_write(&list, &o_stack, NULL, iimemory); for (i = 0; i < pset->long_count; i++) { const char *pname = pset->long_defs[i].pname; if (pname_matches(pname, psref)) { long val = (*pset->long_defs[i].current)(i_ctx_p); code = param_write_long(plist, pname, &val); if (code < 0) return code; } } for (i = 0; i < pset->bool_count; i++) { const char *pname = pset->bool_defs[i].pname; if (pname_matches(pname, psref)) { bool val = (*pset->bool_defs[i].current)(i_ctx_p); code = param_write_bool(plist, pname, &val); if (code < 0) return code; } } for (i = 0; i < pset->string_count; i++) { const char *pname = pset->string_defs[i].pname; if (pname_matches(pname, psref)) { gs_param_string val; (*pset->string_defs[i].current)(i_ctx_p, &val); code = param_write_string(plist, pname, &val); if (code < 0) return code; } } if (psref) { /* * Scanner options can be read, but only individually by .getuserparam. * This avoids putting them into userparams, and being affected by save/restore. */ const char *pname; bool val; int code; switch (ztoken_get_scanner_option(psref, i_ctx_p->scanner_options, &pname)) { case 0: code = param_write_null(plist, pname); break; case 1: val = true; code = param_write_bool(plist, pname, &val); break; default: code = 0; break; } if (code < 0) return code; } return code; }