Harlequin RIP SDK

Implementation of the %config% (configuration) device type. More...

#include "skinkit.h"
#include "kit.h"
#include "ripthread.h"
#include "kitdevs.h"
#include "swdevice.h"
#include "skintimeline.h"
#include "skindevs.h"
#include "hqmemcpy.h"
#include "swcopyf.h"
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <unistd.h>

Enumerations

enum  { CONFIG_FIRST , CONFIG_START , CONFIG_DATA , CONFIG_END }
 Used to maintain the state of the device between read calls. More...
 

Functions

static void config_set_last_error (DEVICE_result error)
 The stub functions for the configuration device to provide appropriate return codes for slots which have nothing else to do.
 
static DEVICE_FILEDESCRIPTOR config_open_file (DEVICELIST *dev, uint8 *filename, int32 openflags)
 The open file routine for the config device type. See DEVICELIST_OPEN(). More...
 
static int32 config_read_file (DEVICELIST *dev, DEVICE_FILEDESCRIPTOR descriptor, uint8 *buff, int32 len)
 The read_file routine for the config device type. See DEVICELIST_READ(). More...
 
static int32 config_write_file (DEVICELIST *dev, DEVICE_FILEDESCRIPTOR descriptor, uint8 *buff, int32 len)
 Stub with correct protopype function pointer. See DEVICELIST_WRITE().
 
static int32 config_close_file (DEVICELIST *dev, DEVICE_FILEDESCRIPTOR descriptor)
 The close_file routine for the config device type. See DEVICELIST_CLOSE().
 
static int32 config_seek_file (DEVICELIST *dev, DEVICE_FILEDESCRIPTOR descriptor, Hq32x2 *destination, int32 flags)
 The seek_file routine for the config device type. See DEVICELIST_SEEK().
 
static int32 config_bytes_file (DEVICELIST *dev, DEVICE_FILEDESCRIPTOR descriptor, Hq32x2 *bytes, int32 reason)
 The bytes_file routine for the config device type, the manifestation in C of the bytesavailable PostScript operator. See DEVICELIST_BYTES(). More...
 
static int32 config_status_file (DEVICELIST *dev, uint8 *filename, STAT *statbuff)
 Call to check status of file. See DEVICELIST_STATUS_FILE().
 
static void * config_start_file_list (DEVICELIST *dev, uint8 *pattern)
 Call to start listing files. See DEVICELIST_START_LIST().
 
static int32 config_buffsize (DEVICELIST *dev)
 The buffsize routine for the config device type. Not required, but provided for example purposes. The 'len' parameter of the config_read_file() function will never exceed the amount we indicate with this function. See DEVICELIST_BUFFER_SIZE().
 
static int32 config_next_file (DEVICELIST *dev, void **handle, uint8 *pattern, FILEENTRY *entry)
 Call to get next file in list. See DEVICELIST_NEXT().
 
static int32 config_end_file_list (DEVICELIST *dev, void *handle)
 Call to end listing. See DEVICELIST_END_LIST().
 
static int32 config_rename_file (DEVICELIST *dev, uint8 *file1, uint8 *file2)
 Rename file on the device. See DEVICELIST_RENAME().
 
static int32 config_delete_file (DEVICELIST *dev, uint8 *filename)
 Remove file from device. See DEVICELIST_DELETE().
 
static int32 config_set_param (DEVICELIST *dev, DEVICEPARAM *param)
 Call to set device parameter. See DEVICELIST_SET_PARAM().
 
static int32 config_start_param (DEVICELIST *dev)
 Call to start getting device parameters. See DEVICELIST_START_PARAM().
 
static int32 config_get_param (DEVICELIST *dev, DEVICEPARAM *param)
 Call to start getting device parameters. See DEVICELIST_GET_PARAM().
 
static int32 config_status_device (DEVICELIST *dev, DEVSTAT *devstat)
 Call to get the status of the device. DEVICELIST_STATUS_DEVICE().
 
static int32 config_spare (void)
 Spare slot. See DEVICELIST_SPARE().
 

Variables

static DEVICE_FILEDESCRIPTOR config_fd = 0
 
static sw_tl_ref skin_job = SW_TL_REF_INVALID
 
static enum { ... }  config_status = CONFIG_FIRST
 Used to maintain the state of the device between read calls. More...
 
DEVICETYPE Config_Device_Type
 The config device type structure.
 

Detailed Description

Implementation of the %config% (configuration) device type.

This is a minimal implementation of the config device type. It provides all the required functions, but only limited functionality.

The purpose of the configuration device type is twofold:

  • to set up the environment in which PostScript jobs run
  • to provide the RIP with jobs to run.

The discussion of the %config% device below is relevant when directly injecting PostScript jobs, and for OEMs who want to extend the input capabilities of the RIP. It is normally not necessary to directly inject PostScript jobs. Global Graphics recommends using the Input queue and source API with the SwLeProcessInputQueue() function to queue and process jobs. That function will set up the first buffer of PostScript returned to the %config% device in such a way that the RIP will detect the type of the job, perform appropriate configuration at the correct save levels, and read the job file directly. The method used to do this uses the /HqnConfigProvider ProcSet to perform the configuration, and the HqnInputTypes ProcSet to perform the input detection.

The RIP simply runs the configuration file. Therefore the read function of the configuration device provides PostScript fragments which the RIP executes. Like a PostScript procedure, this PostScript is expected to manipulate the operand stack. In particular it consumes no operands, and leaves a boolean object on top of the stack. If the boolean is true, two further items are expected on the stack: a pair of file objects, the first of which is a file open for reading which is the PostScript job to be executed, and second is a file opened for writing, to which anything written to PostScript's %stdout% pseudo-device will be directed. If the boolean is false, the system will re-run the config device again.

Therefore the read call for the config device could just return in the supplied buffer the characters

  (%console%)(r) file (%console%)(w) file true

on the first call; and no characters on the second call (indicating end-of-file to the RIP) - and the RIP would then act on the PostScript shown as described above, causing it to read PostScript from a file opened on a device called %console%. %console% must have been mounted and had its device type set in order for this to succeed. Normally this would be done in the file %os%Sys/ExtraDevices, but could be done anywhere - for example it could be included in the PostScript emitted by the %config% device.

Normally, however, the PostScript emitted by %config% will be somewhat more complex. The device may require to choose its input from among several possible input sources; and it will certainly want to set up some default environment in which the job may run. Even if the PostScript emitted is quite simple, the implementation of the %config% device may be quite complex - involving perhaps manipulating user interface dialogs which allow the user to select the job to be run.

A useful technique appropriate in some circumstances is to implement the function of the config device wholly in PostScript in which case the PostScript emitted by the config% device would simply be

  (%os%my-config-file) run

and the PostScript file my-config-file on the %os% device would then be responsible for putting the two files and true onto the operand stack.

However, in our example below, we obtain this configuration PostScript by calling KGetConfigData(), repeatedly if necessary. This returns the PostScript provided to SwLeJobStart().

Finally, in order for the RIP to run %config%, the device must exist. It should be created (that is, mounted, enabled and assigned a device type number) in the Sys/ExtraDevices file, using PostScript similar to this:

  statusdict begin
  (%config%) dup devmount pop
  <<
    /Password 0
    /DeviceType 16#ffff0002
    /Enable true
  >> setdevparams
  end

(See kitdevs.h for a discussion of how 16#ffff0002 arises as the device type number).

This config device implementation accepts no device parameters. It is a non-relative device, so therefore many routines can be provided as stubs only. Furthermore, it will not be written to by the RIP as supplied so that functionality need not be supported. (However, you might consider implementing a write call on %config% for your own use, in place of a separate device type to receive PostScript messages written to standard error or standard output - see the discussion alongside the definition of the %console% device in monitor.c).

Note however that config_bytes_file() (bytesavailable in PostScript) MUST be implemented for the config device in order that the RIP can determine whether or not to run the %config% file.

This example also illustrates the use of the buffer size function, config_buffsize(). This is not a requirement, but since only a very small buffer is required in this example, we choose not to allow the RIP to waste space on a larger buffer as it would if this routine were not implemented.

Enumeration Type Documentation

◆ anonymous enum

anonymous enum

Used to maintain the state of the device between read calls.

For a more comprehensive implementation this would be considerably more complex since more than one buffer full of information may have to be returned by the read file function.

Enumerator
CONFIG_FIRST 

No jobs have been run yet.

CONFIG_START 

Starting a new job on next read.

CONFIG_DATA 

Acquiring configuration data for job.

CONFIG_END 

Completed configuration data for job.

Function Documentation

◆ config_bytes_file()

static int32 config_bytes_file ( DEVICELIST dev,
DEVICE_FILEDESCRIPTOR  descriptor,
Hq32x2 bytes,
int32  reason 
)
static

The bytes_file routine for the config device type, the manifestation in C of the bytesavailable PostScript operator. See DEVICELIST_BYTES().

This routine has special significance for the config device. This implementation simply returns the length of the PostScript string we would supply. If the amount of data which will be emitted is not known exactly, any strictly positive number (e.g. 1) will cause the RIP to proceed to open the %config% file rather than continuing to idle.

If there is no input pending, this function should return 0 (NOT -1 which would be an error condition), so that the RIP can continue to do any idle-time tasks allocated to it. It will then call bytesavailable at frequent intervals until there is some input pending. This is preferable to blocking either here or in the read or open functions when this condition arises.

◆ config_open_file()

static DEVICE_FILEDESCRIPTOR config_open_file ( DEVICELIST dev,
uint8 filename,
int32  openflags 
)
static

The open file routine for the config device type. See DEVICELIST_OPEN().

Since we are not implementing write functionality, it will be an error to attempt an open for other than reading. Also the semantics of the device mean that it does not make sense to have more than one file open at once for the whole device type, therefore this too is an error.

◆ config_read_file()

static int32 config_read_file ( DEVICELIST dev,
DEVICE_FILEDESCRIPTOR  descriptor,
uint8 buff,
int32  len 
)
static

The read_file routine for the config device type. See DEVICELIST_READ().

On the first read, we emit the PostScript required to set up the environment and set up the two files and true on the operand stack as described at the head of the file.

On the second call we return zero bytes which indicates end of file to the RIP.

Variable Documentation

◆ config_fd

DEVICE_FILEDESCRIPTOR config_fd = 0
static

The file descriptor for config device.

◆ 

enum { ... } config_status

Used to maintain the state of the device between read calls.

For a more comprehensive implementation this would be considerably more complex since more than one buffer full of information may have to be returned by the read file function.

◆ skin_job

sw_tl_ref skin_job = SW_TL_REF_INVALID
static

The skin job timeline.