CAPS Universe documentation  1.0.4
All you need to know to be successful
Functions | Variables
samsung-spl2-ml-1640-2240.c File Reference

ML-1640/ML-2240. Monochrome Laser Printer, second generation, SPL2 (aka 'QPDL') language. More...

Functions

static void samsung_ml1640_feature_selection_add (struct caps_ppd_selection *selection)
 
static void samsung_ml1640_options_add (struct caps_ppd_option *option, size_t entries)
 
static ssize_t samsung_spl2_selection_entry_get (const struct caps_ppd_selection_entry *selection_list, size_t selection_cnt, const char *entry)
 
static void samsung_spl2_adapt_paper_type (struct caps_drv *drvi)
 
static void samsung_spl2_adapt_jam_recovery (struct caps_drv *drvi, struct spl2_drv *info)
 
static void samsung_spl2_adapt_econo_mode (struct caps_drv *drvi)
 
static void samsung_spl2_adapt_powersave (struct caps_drv *drvi)
 
static void samsung_spl2_adapt_altitude (struct caps_drv *drvi, struct spl2_drv *info)
 
static void samsung_spl2_adapt_paper_name (struct caps_drv *drvi)
 
static unsigned samsung_spl2_opc_width (struct caps_drv *drvi, const char *key)
 
static void samsung_spl2_opc_default (unsigned dflt, unsigned res, const char *key)
 
static void samsung_spl2_adapt_resolution (struct caps_drv *drvi, struct spl2_drv *info)
 
int printer_driver_module_init (struct caps_drv *drvi, struct spl2_drv *info)
 
int printer_driver_runtime_adaptions (struct caps_drv *drvi, struct spl2_drv *info)
 
static enum format_type samsung_ml1640_paper_format_assign (const char *paper_name)
 
static void drv_spl2_pjl_header_create (FILE *prn_stream, const struct spl2_drv *info)
 
static void drv_spl2_pjl_footer_create (FILE *prn_stream)
 
static int ml1640_driver_job_setup (struct caps_drv *drvi, void *d)
 
static int ml1640_driver_page_setup (struct caps_drv *drvi, void *d)
 
static int ml1640_driver_job_finish (struct caps_drv *drvi, void *d)
 

Variables

static size_t samsung_ml1640_features_selections_count = 0
 
static struct caps_ppd_selectionsamsung_ml1640_features_selections [3]
 
static size_t samsung_ml1640_options_count = 0
 
static struct caps_ppd_option samsung_ml1640_options [3]
 
static const struct caps_ppd_selection_entry samsung_spl2_paper_type_selections []
 
static struct caps_ppd_selection drv_spl2_media_type_selection
 
static const struct caps_ppd_selection_entry samsung_spl2_econo_mode_selections []
 
static struct caps_ppd_selection samsung_spl2_econo_mode_selection
 
static const struct caps_ppd_selection_entry samsung_spl2_powersave_selections []
 
static struct caps_ppd_selection samsung_spl2_powersave_selection
 
static const struct caps_ppd_media_size samsung_ml1640_printable_media
 
static const struct caps_ppd_media_margins samsung_ml1640_printable_margins
 
static struct caps_ppd_base samsung_ml1640_features
 
const struct caps_generic_driver caps_spl2_driver
 

Detailed Description

This driver creates wire data in the format SPL2 (Samsung Printer Language 2) aka 'QPDL' (e.g. Quick Page Description Language). It supports the ML-1640 and ML-2240 monochrome laser printer.

Todo:
Cancel the current job, if a paper jam happens and 'jam_recovery' is set to 'true'!

Function Documentation

◆ samsung_ml1640_feature_selection_add()

static void samsung_ml1640_feature_selection_add ( struct caps_ppd_selection selection)
static

◆ samsung_ml1640_options_add()

static void samsung_ml1640_options_add ( struct caps_ppd_option option,
size_t  entries 
)
static

◆ samsung_spl2_selection_entry_get()

static ssize_t samsung_spl2_selection_entry_get ( const struct caps_ppd_selection_entry selection_list,
size_t  selection_cnt,
const char *  entry 
)
static

Search for a specific selection name (via .option)

Parameters
[in]selection_listThe list to search in
[in]selection_cntEntries in the selection list
[in]entryThe entry to search for, or negative index if not found
Note
The search is case insensitive

◆ samsung_spl2_adapt_paper_type()

static void samsung_spl2_adapt_paper_type ( struct caps_drv drvi)
static

Handle default paper type (like 'plain' or 'label')

Parameters
[in]drviThe framework handle
Returns
0 on success, negative errno else

Setup the paper type if only one paper is provided (due to single input tray) If not set, a list of supprted media types are included into the PPD and the user must select one

Precondition
Last entry in samsung_ml1640_features_selections must be the paper type selection
selection_count in samsung_ml1640_features must one less than required to include be the paper type selection
The "NORMAL" entry must always be the first in samsung_spl2_paper_type_selections list
Todo:
If the user does not set any paper type in the INI files, a regular paper type list will be part of the PPD, to let the user select one of it.

◆ samsung_spl2_adapt_jam_recovery()

static void samsung_spl2_adapt_jam_recovery ( struct caps_drv drvi,
struct spl2_drv info 
)
static

Setup the 'paper jam recovery' setting for the printer

Parameters
[in]drviThe framework handle
[in,out]infoOur private data
Todo:
Generic function for all ML printers and thus, can be moved to samsung-spl2-series.c?

◆ samsung_spl2_adapt_econo_mode()

static void samsung_spl2_adapt_econo_mode ( struct caps_drv drvi)
static

Setup the PPD's default for the economic setting

Parameters
[in]drviThe framework handle
Attention
This only defines the default. A list in the PPD to change it on a per print job base is still available

◆ samsung_spl2_adapt_powersave()

static void samsung_spl2_adapt_powersave ( struct caps_drv drvi)
static

Setup the 'power saving' setting for the printer

Parameters
[in]drviThe framework handle
Attention
This only defines the default. A list in the PPD to change it on a per print job base is still available

◆ samsung_spl2_adapt_altitude()

static void samsung_spl2_adapt_altitude ( struct caps_drv drvi,
struct spl2_drv info 
)
static

Setup the 'altitude' setting for the printer

Parameters
[in]drviThe framework handle
[in]infoOur private data

It's unclear what the values LOW and HIGH mean. The manual states "Printing is possible below 1000 m".

◆ samsung_spl2_adapt_paper_name()

static void samsung_spl2_adapt_paper_name ( struct caps_drv drvi)
static

Setup the paper format which is fed into the printer

Parameters
[in]drviThe framework handle

The user can set in the [paper].format INI entry the loaded paper. The used paper format name must be one of the paper format names known by 'libpaper'. The user can refer 'man paperconf' or 'paperconf -a' for the available format names.

Todo:
If Letter or A4 is selected in a static manner via INI file, it would be possible to adapt the margins according to the selected format and the strange mechanical behavior of the printer device.

◆ samsung_spl2_opc_width()

static unsigned samsung_spl2_opc_width ( struct caps_drv drvi,
const char *  key 
)
static

Extract an integer from the INI settings set

Parameters
[in]drviThe framework handle
[in]keyThe key variable to extract its value
Return values
PositiveExtracted value
0Key not available or invalid value

◆ samsung_spl2_opc_default()

static void samsung_spl2_opc_default ( unsigned  dflt,
unsigned  res,
const char *  key 
)
static

Just emit a warning about undefined OPC width

Parameters
[in]dfltThe default value for the print head's dot count
[in]resThe resolution value dflt is for
[in]keyThe keyname a user should define instead

Just convenience to avoid code duplication.

◆ samsung_spl2_adapt_resolution()

static void samsung_spl2_adapt_resolution ( struct caps_drv drvi,
struct spl2_drv info 
)
static

Setup the resolutions the printer is capable to print

Parameters
[in]drviThe framework handle
[in,out]infoOur driver info

Three resolutions are known, but not supported by all printers:

  • 1200x600 DPI (rectangle dot)
  • 600x600 DPI (square dot)
  • 300x300 DPI (square dot)

Here the supported resolutions are enabled based on INI file settings.

Todo:
This function is generic to all ML printers and can be moved to samsung-spl2-series.c

◆ printer_driver_module_init()

int printer_driver_module_init ( struct caps_drv drvi,
struct spl2_drv info 
)

Printer driver specific initialisation, in contrast to the generic spl2_driver_module_init()

Called by the generic spl2_driver_module_init().

◆ printer_driver_runtime_adaptions()

int printer_driver_runtime_adaptions ( struct caps_drv drvi,
struct spl2_drv info 
)

Printer driver specific run-time adaptions, in contrast to the generic spl2_driver_runtime_adaptions()

Called by the generic spl2_driver_runtime_adaptions().

◆ samsung_ml1640_paper_format_assign()

static enum format_type samsung_ml1640_paper_format_assign ( const char *  paper_name)
static

Assign an SPL2 protocol specific value for the paper format

Parameters
[in]paper_namePaper type as a word
Return values
typePaper type (one value from #paper_type)
SPL_CUSTOM_TYPEon error (e.g. unknown paper type)
Note
The word for the paper type is checked case insensitive

The original Samsung driver lists these paper names: Letter, Legal, A4, Executive, Folio, JB5/JIS B5, B5-ISO/ISO B5, A5, COM10/No.10 Env., Monarch, DL/DL Env., C5/C5 Env., C6/C6 Env., A6/A6, Oficio,

◆ drv_spl2_pjl_header_create()

static void drv_spl2_pjl_header_create ( FILE *  prn_stream,
const struct spl2_drv info 
)
static

Send a jobs header, e.g. signal the printer a new print job starts

Parameters
[in]prn_streamThe stream to send the data to
[in]infoJob and printer info

The strings sent here do not matter it seems. The printer works even if strings are sent, which do not match the corresponding printer. For example for the ML1640 the original Samsung driver does not send the "DUPLEX" value, but sending it even to the ML1640 (which does not have a duplex unit) does not hurt and it is printing the page. And the Samsung driver sends a "line feed" after each line, but for the last line it sends a "carriage return" and "line feed". But also here, it works with "line feed" for all lines.

For the ML1640 printer the original Samsung driver only sends these entries: "@PJL SET PAPERTYPE = OFF" "@PJL SET JAMRECOVERY = OFF" "@PJL DEFAULT POWERSAVE = ON" "@PJL DEFAULT POWERSAVETIME = 5" "@PJL SET ALTITUDE = LOW" "@PJL DEFAULT SERVICEDATE = 20190817" "@PJL ENTER LANGUAGE = QPDL"

Todo:
What is the difference between "PAPERTYPE = OFF" and a real setting?

There are examples out, were the job's owner is also reported to the printer. Why? To encode this information more or less invisible to the printed paper? So, do not report the printing job's owner to the printer's firmware! The same is valid for the date!

Todo:
Do we need to send the powersave time again and again? Or is it somehow persistent? Same for the altitude setting.
Precondition
The printer's behavior in the case of paper jam must be set (#spl2_drv::jam_recovery_state)
The printer's altitude setting must be set (spl2_drv::altitude_level)

◆ drv_spl2_pjl_footer_create()

static void drv_spl2_pjl_footer_create ( FILE *  prn_stream)
static

Send a job's footer, e.g. signal the printer the current print is done

Parameters
[in]prn_streamThe stream to send the data to

The leading tab char signals a 0x09 (=JOB_TERMINATE) record type to the printer and let its interpreter stop and return into the PJL mode.

◆ ml1640_driver_job_setup()

static int ml1640_driver_job_setup ( struct caps_drv drvi,
void *  d 
)
static

Setup internal info for the new job and send a corresponding header to the printer device

Parameters
[in]drviThe framework handle
[in]dOur private data
Return values
0On success
-EINVALIf this job cannot be printed

With an injected job there is no connected PPD, all settings fall back to their defaults in this case

Todo:

Up to a width of 204 mm there is no real margin required since the OPC drum covers the full width

Letter (216 mm) has a hard left margin of about 6 mm

A4 (210 mm) has a hard left margin of about 3 mm. No! 6 mm as well Everything starts with an offset of 6 mm, but the start position moves with the SPL_*_TYPE sent to the printer. E.g. with SPL_LETTER_TYPE the start moves about 3 mm to left compared to SPL_DINA4_TYPE, but still 6 mm away from the left Letter paper egde. Same for SPL_DINA4_TYPE. Thus, there is no full compensation possible for media wider than about 204 mm, but for smaller media this offset can be compensated.

Refer Mechanical Restrictions for details.

Todo:
4960 dots per line are always required! And the content must always be in the horizontal center. All other dots must be off. Thus, we cannot use the libcapsrster/libcapsdriver capability, since they can align smaller pages on a larger medium differently.

◆ ml1640_driver_page_setup()

static int ml1640_driver_page_setup ( struct caps_drv drvi,
void *  d 
)
static

Setup the next page to rasterize

Parameters
[in]drviThe framework handle
[in]dOur private data
Return values
0On success
-EINVALIf this job cannot be printed

The setup is constant over the whole print job.

◆ ml1640_driver_job_finish()

static int ml1640_driver_job_finish ( struct caps_drv drvi,
void *  d 
)
static

The job is done somehow, free resources

Parameters
[in]drviThe framework handle
[in]dOur private data
Return values
0On success
-EINVALIf this job cannot be printed
Todo:
Called as well if the current job should be terminated! Keep track of the printer state!

Variable Documentation

◆ samsung_ml1640_features_selections_count

size_t samsung_ml1640_features_selections_count = 0
static

◆ samsung_ml1640_features_selections

struct caps_ppd_selection* samsung_ml1640_features_selections[3]
static

◆ samsung_ml1640_options_count

size_t samsung_ml1640_options_count = 0
static

◆ samsung_ml1640_options

struct caps_ppd_option samsung_ml1640_options[3]
static

◆ samsung_spl2_paper_type_selections

const struct caps_ppd_selection_entry samsung_spl2_paper_type_selections[]
static
Initial value:
= {
{ .option = "OFF", .description = ( "Use Printer Default" ), },
{ .option = "NORMAL", .description = ( "Plain" ), },
{ .option = "THICK", .description = ( "Thick 90g...105g" ), },
{ .option = "THIN", .description = ( "Thin 60g...70g" ), },
{ .option = "BOND", .description = ( "Rag Pulp" ), },
{ .option = "OHP", .description = ( "Transparency" ), },
{ .option = "CARD", .description = ( "Card Stock" ), },
{ .option = "LABEL", .description = ( "Label" ), },
{ .option = "USED", .description = ( "Preprinted" ), },
{ .option = "COLOR", .description = ( "Colored" ), },
{ .option = "ENV", .description = ( "Envelope" ), },
}

The printer can handle some various media differently. This list contains the known media types the printer firmware supports.

This value is used in the "@PJL SET PAPERTYPE = <name>" instruction.

◆ drv_spl2_media_type_selection

struct caps_ppd_selection drv_spl2_media_type_selection
static
Initial value:
= {
.option_type = LIBCAPS_OT_PICKONE,
.option = "MediaType",
.description = ( "Paper Type" ),
.default_entry = 0,
}
@ LIBCAPS_OT_PICKONE
Definition: libcapsppd.h:282
static const struct caps_ppd_selection_entry samsung_spl2_paper_type_selections[]
Definition: samsung-spl2-ml-1640-2240.c:127

◆ samsung_spl2_econo_mode_selections

const struct caps_ppd_selection_entry samsung_spl2_econo_mode_selections[]
static
Initial value:
= {
{ .option = "Default", .description = ( "Use Printer Default" ), .value = NULL, },
{ .option = "On", .description = ( "Save" ), .value = "ON", },
{ .option = "Off", .description = ( "Standard" ), .value = "OFF", },
}

Selection entries to control the ECO mode when printing

Corresponds to samsung_spl2_econo_mode_selection

◆ samsung_spl2_econo_mode_selection

struct caps_ppd_selection samsung_spl2_econo_mode_selection
static
Initial value:
= {
.option_type = LIBCAPS_OT_PICKONE,
.option = "EconoMode",
.description = ( "Toner Usage" ),
.default_entry = 0,
}
static const struct caps_ppd_selection_entry samsung_spl2_econo_mode_selections[]
Definition: samsung-spl2-ml-1640-2240.c:273

Handled in the printer's firmware via PJL command

This value is used in the "@PJL SET ECONOMODE = <Value>" instruction.

Note
If the corresponding .value entry lists an empty string, this PJL command should be ommitted.

The default is "Use Printer Default" if not otherwise set in the INI file.

Used by samsung_spl2_adapt_econo_mode()

◆ samsung_spl2_powersave_selections

const struct caps_ppd_selection_entry samsung_spl2_powersave_selections[]
static
Initial value:
= {
{ .option = "OFF", .description = ( "Disabled" ), },
{ .option = "5", .description = ( "5 Minutes" ), },
{ .option = "10", .description = ( "10 Minutes" ), },
{ .option = "15", .description = ( "15 Minutes" ), },
{ .option = "30", .description = ( "30 Minutes" ), },
{ .option = "45", .description = ( "45 Minutes" ), },
{ .option = "60", .description = ( "60 Minutes" ), },
}

Selection entries to control the power save feature when idling

Corresponds to samsung_spl2_powersave_selection

◆ samsung_spl2_powersave_selection

struct caps_ppd_selection samsung_spl2_powersave_selection
static
Initial value:
= {
.option_type = LIBCAPS_OT_PICKONE,
.option = "PowerSave",
.description = ( "Power Save Time" ),
.default_entry = 0,
}
static const struct caps_ppd_selection_entry samsung_spl2_powersave_selections[]
Definition: samsung-spl2-ml-1640-2240.c:360

Handled in the printer's firmware via PJL command

This value is used in the "@PJL DEFAULT POWERSAVETIME = <Value>" instruction.

Used by samsung_spl2_adapt_powersave()

◆ samsung_ml1640_printable_media

const struct caps_ppd_media_size samsung_ml1640_printable_media
static
Initial value:
= {
.width_min = 215.43,
.width_max = 612.3,
.height_min = 357.19,
.height_max = 1009.134,
}

The input tray supports media up to 'letter'

◆ samsung_ml1640_printable_margins

const struct caps_ppd_media_margins samsung_ml1640_printable_margins
static
Initial value:
= {
.left = 12.5, .right = 12.5,
.top = 12.5, .bottom = 12.5,
}

Special hardware margins for the ML-1640

Note
These values are experiences.

left: about 4 mm (~1.41 pt) right: about 0.5 mm top: TBD bottom: TBD

Printer's margins:

The ML1640 has moveable paper guides at both long edges of the print medium. When moving the one paper guide, both guides move to inner or outer directions. Thus, the print medium is always centered in the printer tray.

It seems the OPC drum can print on a width of 210 mm, e.g. 4960 dots at 600 DPI. But it also seems, the OPC drum has an offset of 6 mm at the left paper edge. The first dot in a line sent to the printer gets printed 6 mm away from the edge of a Letter format paper. Sending 4960 dots in this case means, it can print to the right edge of this paper format without any margin.

Letter hardware restriction margins

Since A4 is 6 mm smaller than Letter, the first dot in a line sent to the printer gets printed 3 mm away from its left edge.

A4 hardware restriction margins

Thus, the margins are medium format dependend and not the same for all formats. At least for a widths less than 204 mm there is no reason for horizontal margins at all.

Todo:
Defining custom media is a way here to define individual margins per medium.
Note
The used default margins are from the original vendor PPDs
Todo:
If the loaded medium is defined (e.g. no different selection in the PPD possible) the margins should be adapted here as well

◆ samsung_ml1640_features

struct caps_ppd_base samsung_ml1640_features
static
Initial value:
= {
.domain_name = PACKAGE,
.paper_type = LIBCAPS_PT_SINGLE,
.common_features = 0,
.supported_color_formats = LIBCAPS_CT_MONOCHROME | LIBCAPS_CT_GRAY,
.default_color_format = LIBCAPS_CT_MONOCHROME,
.options_count = 0,
.options = NULL,
.selection_count = 0,
.selections = NULL,
.default_paper_name = NULL,
.media_coverage = &samsung_ml1640_printable_media,
}
@ LIBCAPS_CT_GRAY
Definition: libcapsppd.h:203
@ LIBCAPS_CT_MONOCHROME
Definition: libcapsppd.h:202
@ LIBCAPS_PT_SINGLE
Definition: libcapsppd.h:37
static const struct caps_ppd_media_size samsung_ml1640_printable_media
Definition: samsung-spl2-ml-1640-2240.c:475
static const struct caps_ppd_media_margins samsung_ml1640_printable_margins
Definition: samsung-spl2-ml-1640-2240.c:521

◆ caps_spl2_driver

const struct caps_generic_driver caps_spl2_driver
Initial value:
= {
.printer_adaptions = spl2_driver_runtime_adaptions,
.job_finish = ml1640_driver_job_finish,
.page_setup = ml1640_driver_page_setup,
.page_print = ml1640_driver_page_print,
.printer_monitor = spl2_driver_device_monitor,
}
static int ml1640_driver_job_finish(struct caps_drv *drvi, void *d)
Definition: samsung-spl2-ml-1640-2240.c:1042
static int ml1640_driver_job_setup(struct caps_drv *drvi, void *d)
Definition: samsung-spl2-ml-1640-2240.c:926
static int ml1640_driver_page_setup(struct caps_drv *drvi, void *d)
Definition: samsung-spl2-ml-1640-2240.c:1020
int ml1640_driver_page_print(struct caps_drv *drvi, void *d)
Definition: samsung-spl2-protocol.c:549
int spl2_driver_module_init(struct caps_drv *drvi, void *d)
Definition: samsung-spl2-series.c:84
int spl2_driver_runtime_adaptions(struct caps_drv *drvi, void *d)
Definition: samsung-spl2-series.c:207
int spl2_driver_module_exit(struct caps_drv *drvi, void *d)
Definition: samsung-spl2-series.c:99
int spl2_driver_device_monitor(struct caps_drv *drvi, void *d)
Definition: samsung-spl2-series.c:315