T168_111\appl\Parser\Dpl 文件:中间4个独立文件

DplFuncExtSysLv.c  /

/******************************************************************************
 *                                                                            *
 *                         M O D U L E   D E F I N E                          *
 *                                                                            *
 ******************************************************************************/

#define DPLFUNCEXTSYSLV_C

/******************************************************************************
 *                                                                            *
 *        C O M P I L E R   D E F I N E D   I N C L U D E   F I L E S         *
 *                                                                            *
 ******************************************************************************/

#include <string.h>

/******************************************************************************
 *                                                                            *
 *            U S E R   D E F I N E D   I N C L U D E   F I L E S             *
 *                                                                            *
 ******************************************************************************/

#include "Common.h"
#include "XCore.h"
#include "XRTC.h"
#include "XFunction.h"
#include "..\ParserUtil.h"
#include "DplCtrlCode.h"
#include "DplConfig.h"
#include "DplModule.h"
#include "DplUtil.h"
#include "DplFunc.h"

/******************************************************************************
 *                                                                            *
 *                         L O C A L   D E F I N E S                          *
 *                                                                            *
 ******************************************************************************/

#if defined(DPL)

/******************************************************************************
 *                                                                            *
 *                        L O C A L   T Y P E D E F S                         *
 *                                                                            *
 ******************************************************************************/

/******************************************************************************
 *                                                                            *
 *             L O C A L   F U N C T I O N   P R O T O T Y P E S              *
 *                                                                            *
 ******************************************************************************/

/******************************************************************************
 *                                                                            *
 *    L O C A L   I N I T I A L I Z E D   D A T A   D E F I N I T I O N S     *
 *                                                                            *
 ******************************************************************************/

//------------------------------------------------------------------------------
// Configuration Set Command Functions ( DplFuncCfgSet.c )
//------------------------------------------------------------------------------

STATIC CONST _CmdEntry DplCfgSetEntry[] =
{
    {"AL",            Cfg_AL},        // (AL) Alignment Length
    {"AS",            Cfg_AS},        // (AS) Single Byte Symbol Set
    {"BA",            Cfg_BA},        // (BA) Backup After Print
    {"BD",            Cfg_BD},        // (BD) Backup Delay
    {"BL",            Cfg_BL},        // (BL) Backup Label
    {"BP",            Cfg_BP},        // (BP) British Pound
    {"BS",            Cfg_BS},        // (BS or bS) Backup Speed
    {"bS",            Cfg_BS},        // (BS or bS) Backup Speed
    {"BZ",            Cfg_BZ},        // (BZ) Buzzer Enable
    {"CA",            Cfg_CA},        // (CA) Column Adjust
    {"CB",            Cfg_CB},        // (CB) Cut Behind
    {"CC",            Cfg_CC},        // (CC) Control Codes
    {"CE",            Cfg_CE},        // (CE) Cutter Equipped
    {"CF",            Cfg_CF},        // (CF) Column Adjust Fine Tune
    {"CH",            Cfg_CH},        // (CH) Communicated Heat Commands
    {"CL",            Cfg_CL},        // (CL) Continuous Label Length
    {"CO",            Cfg_CO},        // (CO) Column Offset
    {"CS",            Cfg_CS},        // (CS) Communicated Speed Commands
    {"CT",            Cfg_CT},        // (CT) Communicated TOF Commands
    {"DE",            Cfg_DE},        // (DE) DPI Emulation
    {"DK",            Cfg_DK},        // (DK) Darkness
    {"DM",            Cfg_DM},        // (DM) Default Module
    {"DR",            Cfg_DR},        // (DR) Delay Rate
    {"DS",            Cfg_DS},        // (DS) Double Byte Symbol Set
    {"EM",            Cfg_EM},        // (EM) Input Mode
    {"EN",            Cfg_EN},        // (EN) End Character
    {"EP",            Cfg_EP},        // (EP) End of Print
    {"EQ",            Cfg_EQ},        // (EQ) Start of Print
    {"ES",            Cfg_ES},        // (ES) ESC Sequences
    {"ET",            Cfg_ET},        // (ET) Exact Time
    {"EV",            Cfg_EV},        // (EV) Empty Sensor Level
    {"FA",            Cfg_FA},        // (FA) Format Attribute
    {"FE",            Cfg_FE},        // (FE) Font Emulation
    {"FH",            Cfg_FH},        // (FH) Fault Handling
    {"FM",            Cfg_FM},        // (FM) Feedback Mode
    {"FS",            Cfg_FS},        // (FS) Slew Speed
    {"GE",            Cfg_GE},        // (GE) GPIO Equipped
    {"GM",            Cfg_GM},        // (GM) Gap / Mark Value
    {"GR",            Cfg_GR},        // (GR) Gain Reflective Value
    {"GS",            Cfg_GS},        // (GS) GPIO Slew
    {"HB",            Cfg_HB},        // (HB) Head Bias
    {"HC",            Cfg_HC},        // (HC) Head Cleaning
    {"HE",            Cfg_HE},        // (HE) Heat
    {"HT",            Cfg_HT},        // (HT) Host Timeout
    {"IC",            Cfg_IC},        // (IC) Ignore Control Codes
    {"IE",            Cfg_IE},        // (IE) Ignore Distances
    {"IL",            Cfg_IL},        // (IL) Imaging Mode
    {"IM",            Cfg_IM},        // (IM) Internal Module
    {"LA",            Cfg_LA},        // (LA) Label Alignment
    {"LE",            Cfg_LE},        // (LE) Legacy Emulation
    {"LR",            Cfg_LR},        // (LR) Label Rotation
    {"LS",            Cfg_LS},        // (LS) Language Select
    {"LM",            Cfg_LM},        // (LM) Label Store
    {"LW",            Cfg_LW},        // (LW) Label Width
    {"MC",            Cfg_MC},        // (MCC) Module Command
    {"ML",            Cfg_ML},        // (ML) Maximum (Label) Length
    {"MM",            Cfg_MM},        // (MM) Menu Mode
    {"MT",            Cfg_MT},        // (MT) Media Type
    {"MV",            Cfg_MV},        // (MV) Mark Value
    {"NT",            Cfg_NT},        // (NT) Network Setup
    {"NR",            Cfg_NR},        // (NR) No Reprint
    {"NS",            Cfg_NS},        // (NS) Disable Symbol Set Selection
    {"OF",            Cfg_OF},        // (OF) Option Feedback Mode
    {"PA",            Cfg_PA},        // (PA) Present Adjust
    {"PC",            Cfg_PC},        // (PC) Print Contrast
    {"PD",            Cfg_PD},        // (PD) Present Distance
    {"PE",            Cfg_PE},        // (PE) Peel Mode
    {"PJ",            Cfg_PJ},        // (PJ) Present Adjust Fine Tune
    {"PL",            Cfg_PL},        // (PL) Printer Level
    {"PM",            Cfg_PM},        // (PM) Pause Mode
    {"PO",            Cfg_PO},        // (PO) Paper Empty
    {"PP",            Cfg_PP},        // (PP) Parallel Direction
    {"PS",            Cfg_PS},        // (PS) Present Sensor Equipped
    {"pS",            Cfg_pS},        // (pS) Print Speed
    {"PT",            Cfg_PT},        // (PT) Tear Position
    {"PV",            Cfg_PV},        // (PV) Paper Value
    {"PW",            Cfg_PW},        // (PW) Password
    {"QQ",            Cfg_QQ},        // (QQ) Configuration Query
    {"RA",            Cfg_RA},        // (RA) Row Adjust
    {"RB",            Cfg_RB},        // (RA) Row Adjust
    {"RD",            Cfg_RD},        // (RD) Reflective TOF Delta
    {"RE",            Cfg_RE},        // (RE) Ribbon Saver Equipped
    {"RF",            Cfg_RF},        // (RF) Row Adjust Fine Tune
    {"RG",            Cfg_RG},        // (RG) Reflective TOF Gain
    {"RI",            Cfg_RI},        // (RI) RFID Configuration
    {"RL",            Cfg_RL},        // (RL) Ribbon Low Diameter
    {"RM",            Cfg_RM},        // (RM) Rewinder Equipped
    {"RN",            Cfg_RN},        // (RN) Reflective No Paper Minimum
    {"RO",            Cfg_RO},        // (RO) Row Offset
    {"RP",            Cfg_RP},        // (RP) Ribbon Low Pause
    {"RR",            Cfg_RR},        // (RR) Rewinder Adjust
    {"RS",            Cfg_RS},        // (RS) Ribbon Low Signal
    {"RV",            Cfg_RV},        // (RV) Reflective Paper Value
    {"RW",            Cfg_RW},        // (RW) Retract Delay
    {"SA",            Cfg_SA},        // (SA) SOP Adjust
    {"SC",            Cfg_SC},        // (SC) Scalable Cache
    {"SE",            Cfg_SE},        // (SE) SOP Emulation
    {"SF",            Cfg_SF},        // (SF) Save As Filename
    {"SG",            Cfg_SG},        // (SG) Sensor Gain Value
    {"SH",            Cfg_SH},        // (SH) Scalable Heap
    {"Sl",            Cfg_Sl},        // (Sl) Security Lock
    {"SL",            Cfg_SL},        // (SL) Stop Location
    {"SM",            Cfg_SM},        // (SM) Maximum (Label) Length Ignore
    {"SN",            Cfg_SN},        // (SN) Scanner Configuration
    {"SP",            Cfg_SP},        // (SP) Serial Port
    {"SS",            Cfg_SS},        // (SS or sS) Feed Speed
    {"sS",            Cfg_SS},        // (SS or sS) Feed Speed
    {"ST",            Cfg_ST},        // (ST) Sensor Type
    {"SV",            Cfg_SV},        // (SV) Switch Settings
    {"TB",            Cfg_TB},        // (TB) TOF Bias
    {"TD",            Cfg_TD},        // (TD) TOF Delta
    {"TG",            Cfg_TG},        // (TG) TOF Gain
    {"TN",            Cfg_TN},        // (TN) No Paper Min
    {"TP",            Cfg_TP},        // (TP) TOF Precedence
    {"UM",            Cfg_UM},        // (UM) Units of Measure
    {"UT",            Cfg_UT},        // (UT) User Terminator
    {"VE",            Cfg_VE},        // (VE) Verifier Equipped
    {"VT",            Cfg_VT},        // (VT) Verifier Type
    {"WE",            Cfg_WE},        // (WE) Wifi Setup
    {"WS",            Cfg_WS},        // (WS) Wifi Security
    {(CHAR *)_NULL,    _NULL}
};

/******************************************************************************
 *                                                                            *
 *    L O C A L   U N I T I A L I Z E D   D A T A   D E F I N I T I O N S     *
 *                                                                            *
 ******************************************************************************/

/******************************************************************************
 *
 * DPL Commands:
 *        Calibration (Non-Display Models only)
 *
 * Description:
 *
 * Syntax:
 *
 * Where:
 *
 ******************************************************************************/
INT Ext_Cal(VOID)
{
    STATIC CONST _CmdEntry ExtEntry[] =
    {
         {"E",            Ext_CalE},    // Empty Sensor Calibration (Non-Display Models only)
        {"M",            Ext_CalM},    // Manual Media Calibration (Non-Display Models only)
        {"Q",            Ext_CalQ},    // Quick Media Calibration (Non-Display Models only)
        {(CHAR *)_NULL,    _NULL}
    };

    _CmdEntry *CmdEntry;
    CHAR data;

    data = DmxNextByte();
    if (CmdEntry = CheckSingleCommand(data, ExtEntry))
        return CmdEntry->func();
    return _ERROR;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Empty Sensor Calibration (Non-Display Models only)
 *
 * Description:
 *        This command causes the printer to determine and save the calibration
 *        value for an empty media sensor condition. This calibration function
 *        should be performed when no material is installed in the media sensor.
 *        Depending upon the printer model, different front panel LED flash
 *        sequences and printer responses (below) will indicate calibration 
 *        progress and outcome; see the corresponding printer operator manual for
 *        LED flash sequences details.
 *
 * Syntax:
 *        <STX>K}E<CR>
 *
 * Where:
 *
 ******************************************************************************/
INT Ext_CalE(VOID)
{
    // Supported series
    if (DatamaxModel.Display == NON_DISPLAY)
    {
        // ... not finish
    }
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Manual Media Calibration (Non-Display Models only)
 *
 * Description:
 *        This command causes the printer to save the sampled calibration values
 *        as an operator places different portions of label stock within the media
 *        sensor. Depending upon the printer model, different front panel LED flash
 *        sequences and printer responses (below) will indicate calibration progress
 *        and outcome; see the corresponding printer operator manual for LED flash
 *        sequences details. Sending <ESC> to the printer instead of <CR> will
 *        terminate the process and leave the TOF Sensor values unchanged.
 *
 * Syntax:
 *        <STX>K}M<CR>
 *
 * Where:
 *
 ******************************************************************************/
INT Ext_CalM(VOID)
{
    // Supported series
    if (DatamaxModel.Display == NON_DISPLAY)
    {
        // ... not finish
    }
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Quick Media Calibration (Non-Display Models only)
 *
 * Description:
 *        This command causes the printer to move media, sample, and then save
 *        sensor samples as calibration values. This calibration function should
 *        be performed with media installed in the printer. Depending upon the
 *        printer model, different front panel LED flash sequences and printer
 *        responses (below) will indicate calibration progress and outcome; see
 *        the corresponding printer operator manual for LED flash sequences details.
 *
 * Syntax:
 *        <STX>K}Q<CR>
 *
 * Where:
 *
 ******************************************************************************/
INT Ext_CalQ(VOID)
{
    // Supported series
    if (DatamaxModel.Display == NON_DISPLAY)
    {
        // ... not finish
    }
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Direct Mode - Generic Read/Write Interface
 *
 * Description:
 *
 * Syntax:
 *
 * Where:
 *
 ******************************************************************************/
INT Ext_a(VOID)
{
    STATIC CONST _CmdEntry ExtEntry[] =
    {
         {"R",            Ext_aR},    // Read Data from RFID Tag
        {"W",            Ext_aW},    // Write Data to RFID Tag
        {(CHAR *)_NULL,    _NULL}
    };

    _CmdEntry *CmdEntry;
    CHAR data;

    data = DmxNextByte();
    if (CmdEntry = CheckSingleCommand(data, ExtEntry))
        return CmdEntry->func();
    return _ERROR;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Read Data from RFID Tag (Direct Mode - Generic Read/Write Interface)
 *
 * Description:
 *        This command instructs the RFID device to read data from the tag and
 *        then place that data into a replaceable field. It is expected that the
 *        tag transponder will be within the read / write distance of the RFID
 *        programming device; otherwise, "Void" will be printed in the text or
 *        bar code label field.
 *
 * Syntax:
 *        <STX>KaRAaaabbbcdee<CR>
 *
 * Where:
 *        A   - Optional - for data in the ASCII format.
 *        aaa - The number of bytes to read.
 *        bbb - HF  - Starting block number (000 .. maximum block number).*
 *              UHF - Should be 000.
 *        c   - Command 1. Reserved. Should be 0.
 *        d   - Command 2. Reserved. Should be 0.
 *        ee  - Field number in which to place the data (must be 01, 02, 03, etc.)
 *              matching the order of Label Formatting command U.
 *
 ******************************************************************************/
INT Ext_aR(VOID)
{
    return _ERROR;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Write Data to RFID Tag (Direct Mode - Generic Read/Write Interface)
 *
 * Description:
 *        This command instructs the RFID device to write data to the tag. It is
 *        expected that the tag transponder will be within the read / write distance
 *        of the RFID programming device; otherwise, a warning will occur and a
 *        warning message (Read / Write Fail) will be displayed.
 *
 * Syntax:
 *        <STX>KaWAaaabbbcdee..Ke<CR>
 *
 * Where:
 *        Aaaa  - Optional - for data in the ASCII format, followed by the byte
 *                           count (000-999).
 *        bbb   - HF  - Starting block number (000 .. maximum block number).*
 *                UHF - Should be 000.
 *        c     - Command 1. Reserved for Future (should be 0)
 *        d     - Command 2. Reserved for Future (should be 0)
 *        ee..e - Data to be encoded on RFID tag (HF  the last used block will be
 *                null-padded, if necessary).
 *
 ******************************************************************************/
INT Ext_aW(VOID)
{
    return _ERROR;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Backfeed Time Delay (Non-Display Models only)
 *
 * Description:
 *        The backfeed time delay command controls the time a printed label is
 *        allowed to remain "presented" before being retracted to the start of
 *        print position.
 *
 * Syntax:
 *        <STX>Kbnnn<CR>
 *
 * Where:
 *        nnn - Seconds/10
 *
 ******************************************************************************/
INT Ext_b(VOID)
{
    LONG Num;

    // nnn - Seconds/10
    if (DmxGetNumber(&Num, 3) != 3)
        return _ERROR;

    // Supported series
    if (DatamaxModel.Display == NON_DISPLAY)
        pDmxCfg->BackupDelay = (SHORT)(Num* 100);    // Convert 1/10 second to ms

    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Get Configuration
 *
 * Description:
 *        This command returns the configuration of the printer. The form of the
 *        returned data is similar to that of a printed Configuration Label. This
 *        command should be parsed by KEYWORDS, not by Character POSITIONS. Each
 *        line is terminated by a CR (0x0d) & LF (0x0a). Datamax will make every
 *        effort to keep Keyword consistent.
 *
 * Syntax:
 *        <STX>KC<CR>
 *
 * Where:
 *
 ******************************************************************************/
INT Ext_C(VOID)
{
    // ... not finish
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Configuration Set
 *
 * Description:
 *        This command specifies the Power-up Configuration parameter values for
 *        the printer and is equivalent to using other system commands followed by
 *        the <SOH>U.
 *
 * Syntax:
 *        <STX>Kcaa1val1[;aa2val2][;aanvaln]<CR>
 *
 * Where:
 *        aa1,  aa2,  aan  - Are two letter parameter names.
 *        val1, val2, valn - Are parameter values, with ranges appropriate for
 *                           the associated parameter.
 *
 ******************************************************************************/
INT Ext_c(VOID)
{
    _CmdEntry *CmdEntry;
    CHAR ParamName[3];
    CHAR data;

    UpdateDatabase = FALSE;

    CfgSetCmdMod = TRUE;
    while (CfgSetCmdMod)
    {
        // Are two letter parameter names.
        if (!DmxGetAlpha(ParamName, 2))
            break;
        ParamName[2] = '\0';

        if ((data = DmxNextByte()) == ';')
            continue;
        DmxBackByte(data);

        if (CmdEntry = CheckStringCommand(ParamName, DplCfgSetEntry))
            CmdEntry->func();

        if ((data = DmxNextByte()) == ';')
            continue;
        DmxBackByte(data);

        break;
    }
    if (DatamaxModel.Display == DISPLAY_EQUIPPED || UpdateDatabase)
        PrinterReboot();

    DmxRemoveInvalidByte();
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Database Configuration (Non-Display Models only)
 *
 * Description:
 *        This command, stored in Flash memory for future power-ups, controls the
 *        printer's environment and operates as a pseudo DIP switch. The <STX>Kc
 *        command is recommended for use over <STX>KD.
 *
 * Syntax:
 *        <STX>KDwxyz<CR>
 *
 * Where:
 *        w, x, y, and z are binary values with respective bit settings as defined
 *        in the following table. (Bit 0 is least significant.)
 *
 ******************************************************************************/
INT Ext_D(VOID)
{
    CHAR w, x, y, z;
    INT wBaudRate, wLengthParity;
    INT xPrintMethod, xPresent, xCtrlCode, xCutter, xIgnoreDis, xAltCtrlCode;
    INT yPaperType, yLinerless;

    w = DmxNextByte();    // Parameter w
    wBaudRate     = ((w >> 0) & 0x07);    // Bit 0-2 BaudRate
    wLengthParity = ((w >> 3) & 0x01);    // Bit  3  Word Length and Parity
                                        // Bit 4-5 Unused Set to 0
                                        // Bit  6  Always1
                                        // Bit  7  Always0
    x = DmxNextByte();    // Parameter x
    xPrintMethod  = ((x >> 0) & 0x01);    // Bit  0  Print Method
    xPresent      = ((x >> 1) & 0x01);    // Bit  1  Present Sensor
    xCtrlCode     = ((x >> 2) & 0x01);    // Bit  2  Control Character
    xCutter       = ((x >> 3) & 0x01);    // Bit  3  Cutter
    xIgnoreDis    = ((x >> 4) & 0x01);    // Bit  4  Ignore Host Distance
    xAltCtrlCode  = ((x >> 5) & 0x01);    // Bit  5  Alt-2 Control Codes
                                        // Bit  6  Always1
                                        // Bit  7  Always0
    y = DmxNextByte();    // Parameter y
    yPaperType    = ((y >> 0) & 0x03);    // Bit 0-1 Paper Type (Media Sensor)
    yLinerless    = ((y >> 2) & 0x01);    // Bit  2  Linerless
                                        // Bit 3-5 Unused Set to 0
                                        // Bit  6  Always1
                                        // Bit  7  Always0
    z = DmxNextByte();    // Parameter z
                                        // Bit 0-2 Reserved Set to 0
                                        // Bit 3-5 Unused Set to 0
                                        // Bit  6  Always1
                                        // Bit  7  Always0
    // Supported series
    if (DatamaxModel.Display == NON_DISPLAY)
    {
        LONG  BaudRate = 9600;
        CHAR  Parity   = 'N';
        SHORT Data     = 8;
        SHORT Stop     = 1;

        // Parameter w
        if (wBaudRate == 0)    // 0 = 9600
            BaudRate = 9600;
        if (wBaudRate == 1)    // 1 = 600
            BaudRate = 600;
        if (wBaudRate == 2)    // 2 = 2400
            BaudRate = 2400;
        if (wBaudRate == 3)    // 3 = 19200
            BaudRate = 19200;
        if (wBaudRate == 4)    // 4 = 4800
            BaudRate = 4800;
        if (wBaudRate == 5)    // 5 = 38400
            BaudRate = 38400;
        if (wBaudRate == 6)    // 6 = 1200
            BaudRate = 1200;
        if (wBaudRate == 7)    // 7 = 9600 Test Mode
            BaudRate = 9600;

        if (wLengthParity == 0)    // 0 = 8 bits, no parity
        {
            Data = 8;
            Parity = 'N';
        }
        if (wLengthParity == 1)    // 1 = 7 bits, even parity
        {
            Data = 7;
            Parity = 'E';
        }

        SetSerialPort(BaudRate, Data, Parity, Stop);

        // Parameter x
        if (xPrintMethod == 0)    // 0 = direct thermal;
            pDmxCfg->MediaType = 'D';
        if (xPrintMethod == 1)    // 1 = thermal transfer
            pDmxCfg->MediaType = 'T';

        if (xPresent == 0)    // 0 = not equipped
            pDmxCfg->PresentSensorEquipped = EQUIPPED_DISABLE;
        if (xPresent == 1)    // 1 = equipped
            pDmxCfg->PresentSensorEquipped = EQUIPPED_ENABLE;
        SensePresentSensorOption(pDmxCfg->PresentSensorEquipped);

        if (xCutter == 0)        // 0 = disabled
            pDmxCfg->CutterEquipped = EQUIPPED_DISABLE;
        if (xCutter == 1)        // 1 = enabled
            pDmxCfg->CutterEquipped = EQUIPPED_ENABLE;
        SenseCutterOption(pDmxCfg->CutterEquipped);

        if (xIgnoreDis == 0)    // 0 = disabled
            pDmxCfg->IgnoreDistances = 'N';
        if (xIgnoreDis == 1)    // 1 = enabled
            pDmxCfg->IgnoreDistances = 'Y';

        if (xCtrlCode == 0)        // 0 = standard
            pDmxCfg->ControlCodes = CONTROL_CODE_STANDARD;
        if (xCtrlCode == 1)        // 1 = alternate characters
        {
            if (xAltCtrlCode == 0)    // 0 = disabled
                pDmxCfg->ControlCodes = CONTROL_CODE_ALTERNATE_1;
            if (xAltCtrlCode == 1)    // 1 = alternate-2 characters
                pDmxCfg->ControlCodes = CONTROL_CODE_ALTERNATE_2;
        }
        SetControlCode(pDmxCfg->ControlCodes);

        // Parameter y
        if (yPaperType == 0)        // 0 = gap (edge)
            pDmxCfg->SensorType = EDGE_SENSOR_TYPE;
        if (yPaperType == 1)        // 1 = reflective
            pDmxCfg->SensorType = REFLECTIVE_SENSOR_TYPE;
        if (yPaperType == 2)        // 2 = continuous
            pDmxCfg->SensorType = CONTINUOUS_SENSOR_TYPE;
        SelectSensorType(pDmxCfg->SensorType);

        if (yLinerless == 0)        // 0 = not equipped
        {
            // ... not finish
        }
        if (yLinerless == 1)        // 1 = equipped
        {
            // ... not finish
        }
    }
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Set File as Factory Default (Display-Equipped Models only)
 *
 * Description:
 *        This command selects the specified file name as the "factory default"
 *        for the printer's configuration. After execution, subsequent "Select
 *        Factory Default" commands will configure the printer to the file's
 *        configuration. Currently there are three ways to "Select Factory Defaults"
 *        : 1) by the <STX>KF command; 2) power-up the printer while pressing the
 *        PAUSE and CANCEL Keys; or, 3) via the printer's menu system entry System
 *        Settings / Set Factory Defaults.
 *
 * Syntax:
 *        <STX>KdName<CR>
 *
 * Where:
 *        Name - The name, up to 16 characters, of the configuration file.
 *        <CR> - 0x0d terminates the name.
 *
 ******************************************************************************/
INT Ext_d(VOID)
{
    CHAR Name[17];

    if (DmxGetString(Name, sizeof(Name)) > 16)
        return _ERROR;

    // Supported series
    if (DatamaxModel.Display == DISPLAY_EQUIPPED)
    {
        // ... not finish
    }
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Character Encoding
 *
 * Description:
 *        This command is provided primarily as a means for users of 7-bit
 *        communication and to embed control characters and extended ASCII
 *        characters in their data streams. Any character in the DPL data stream
 *        may be substituted with a delimited two-character ASCII hexadecimal
 *        numeric equivalent. The command allows the delimiting character to be
 *        selected, and the encoding to be enabled or disabled. When character
 *        encoding is enabled, the printer will decode any ASCII hexadecimal numeric
 *        pairs following the delimiter as single-byte values. Character encoding
 *        is used where control characters cannot be transmitted or where control
 *        characters within data may prematurely terminate a label format record.
 *        Although the delimiter may be changed at any time (except within a label
 *        format definition), there cannot be more than one defined delimiter, and
 *        character encoding must be disabled with <STX>KEN prior to re-enabling,
 *        regardless of any change in the delimiter.
 *
 * Syntax:
 *        <STX>KEex<CR>
 *
 * Where:
 *        e - Y - character encoding enabled
 *            N - character encoding disabled
 *        x - Delimiter: one ASCII character (Do not include when e = N)
 *
 ******************************************************************************/
INT Ext_E(VOID)
{
    CHAR Encoding;
    CHAR Delimiter;

    Encoding = DmxNextByte();
    if (Encoding == 'Y')
        EncodeDelimiter = DmxNextByte();
    if (Encoding == 'N')
        EncodeDelimiter = '\0';

    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Select Factory Defaults (Display-Equipped and EX2 Models only)
 *
 * Description:
 *        This command restores the configuration of the printer to the factory
 *        default settings. These settings may be Datamax default values or the
 *        values previously specified by a configuration file (see <STX>Kd).
 *
 * Syntax:
 *        <STX>KFn<CR>
 *
 * Where:
 *        n - 2 = Level One Reset, returning the factory default settings
 *                (and, if saved, restoring the Factory Setting File).
 *          - 3 = Level Two Reset, returning the factory default settings,
 *                and clearing all calibration and custom adjustment parameters.
 *
 ******************************************************************************/
INT Ext_F(VOID)
{
    CHAR Level;

    Level = DmxNextByte();

    InitialDefaultVar();
    PrinterReboot();
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Set Present Distance
 *
 * Description:
 *        This command specifies an additional amount to advance the label after
 *        printing. This command has the same effect as the <STX>f command, but
 *        specifies a distance to advance relative to the start of print (<STX>O
 *        command) of the next label.
 *
 *        Non-Display Models: The printer Option Control must be set (via the menu)
 *                            to 'Host' for this command to have effect.
 *
 *        Display-Equipped Models: SOP Emulation selection has no effect on this command.
 *
 * Syntax:
 *        <STX>Kfnnnn<CR>
 *
 * Where:
 *        nnnn - A four-digit present distance in inches/100 or mm/10.
 *
 ******************************************************************************/
INT Ext_f(VOID)
{
    LONG Num;

    // nnnn - A four-digit present distance in inches/100 or mm/10.
    if (DmxGetNumber(&Num, 3) != 3)
        return _ERROR;

    pDmxCfg->PresentDistance = TransformDot(Num, pDmxCfg->UnitMeasure);
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Assign Communication Port (MCL Command)
 *
 * Description:
 *        This command assigns a communication port for specific use. When
 *        activating MCL, all ports are assigned to MCL; this command allows
 *        changes to that assignment.
 *
 * Syntax:
 *        <STX>KJpf<CR>
 *
 * Where:
 *        p - Port ID: P = Parallel
 *                     S = Serial (A)
 *                     U = USB
 *                     N = Ethernet
 *                     L = Wireless
 *                     A = Serial (B)
 *        f - Flag: 1 = DPL
 *                  0 = MCL
 *
 ******************************************************************************/
INT Ext_J(VOID)
{
    CHAR PortID;
    CHAR Flag;

    PortID = DmxNextByte();
    Flag = DmxNextByte();

    // ... not finish
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        GPIO Input
 *
 * Description:
 *        This command configures the GPIO input channels of the Applicator
 *        Interface Card; see Appendix J for details.
 *
 * Syntax:
 *        <STX>KIffnspwww<CR>
 *
 * Where:
 *        ff  - 2 character function name abbreviation (e.g., PS [Print Start],
 *              I1 [User Input 1], etc).
 *        n   - Pin number, where 1  8 is the valid range.
 *        s   - Signal type, where: L = Level; P = Positive Pulse;
 *              and N = Negative Pulse
 *        p   - Polarity, where: 0 = Active Low; and 1 = Active High
 *        www - 3 character filter pulse width, in milliseconds.
 *
 ******************************************************************************/
INT Ext_I(VOID)
{
    return _ERROR;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Memory Configuration, Internal Module (Non-Display Models only)
 *
 * Description:
 *        Represents the start of a sequence (up to five characters) that assigns
 *        memory to the Internal Module. If this field does not appear, then the
 *        Internal Module is not affected. If no Internal Module exists, it will be
 *        created and formatted. Existing Internal Modules will be erased, resized
 *        and formatted. The number that follows the M is a decimal number (up to
 *        four digits) that specifies the size in 4KB blocks of memory to assign to
 *        the Internal Module. A value of "0000" will delete the Internal Module
 *        (see Appendix J for additional information).
 *
 * Syntax:
 *        <STX>Kix[:jy][:kz]<CR>
 *
 * Where:
 *        i, j, k are M, S, or W; x, y, z are four-digit maximum numbers of 4K
 *        byte blocks or inches/100 or (mm/10) as described below.
 *
 ******************************************************************************/
INT Ext_M(VOID)
{
    STATIC CONST _CmdEntry ExtEntry[] =
    {
         {"M",            Ext_M},    // Memory Configuration, Internal Module
        {"S",            Ext_S},    // Memory Configuration, Scalable Font Cache
        {"W",            Ext_W},    // Memory Configuration, Printable Label Width
        {(CHAR *)_NULL,    _NULL}
    };

    _CmdEntry *CmdEntry;
    CHAR data;
    LONG Size;

    if (DmxGetNumber(&Size, 4) != 4)
        return _ERROR;

    // Supported series
    if (DatamaxModel.Display == NON_DISPLAY)
        pDmxCfg->InternalModule = (SHORT)(Size * 4);    // Convert 4KB to KB

    data = DmxNextByte();
    if (data == ':')
    {
        data = DmxNextByte();
        if (CmdEntry = CheckSingleCommand(data, ExtEntry))
            return CmdEntry->func();
    }
    else
        DmxBackByte(data);

    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        NIC Reset
 *
 * Description:
 *        This command resets the NIC to factory defaults.
 *
 * Syntax:
 *        <STX>Knx
 *
 * Where:
 *        x - Specifies the action to take, where:
 *             F = Returns the NIC to the factory default settings; and,
 *             H = Reports settings to host (wireless, only).
 *
 ******************************************************************************/
INT Ext_n(VOID)
{
    CHAR Action;

    Action = DmxNextByte();

    // ... not finish
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        GPIO Output
 *
 * Description:
 *        This command configures the GPIO output channels of the Applicator
 *        Interface Card; see Appendix J for details.
 *
 * Syntax:
 *        <STX>KOffnsptd0pw0td1pw1<cr>
 *
 * Where:
 *        ff  - 2 character function name abbreviation (e.g., LC [Label
 *              Complete], LM [Label Movement], etc).
 *        n   - Pin number, where 1 - 8 is the valid range.
 *        s   - Signal type, where: L = Level; P = Positive Pulse;
 *              and N = Negative Pulse
 *        p   - Polarity, where: 0 = Active Low; and 1 = Active High
 *        td0 - 3 character delay time from function condition "true" to
 *              output signal.
 *        pw0 - 3 character pulse width corresponding to the function
 *              condition becoming "true". (Ignored for level-type signals.)
 *        td0 - 3 character delay time from function condition "false" to
 *              output signal.
 *        pw0 - 3 character pulse width corresponding to the function
 *              condition becoming "false". (Ignored for level-type signals.)
 *
 ******************************************************************************/
INT Ext_O(VOID)
{
    return _ERROR;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Module Protection (Display-Equipped Models only)
 *
 * Description:
 *        This command controls memory module protection. When "protected", a module
 *        will ignore format, downloads and delete commands. This command can be
 *        useful to add data to Datamax reserved modules, Z (ILPC) and Y (EFIGS).
 *        See Appendix K for a listing of the memory modules.
 *
 * Syntax:
 *        <STX>Kpmf
 *
 * Where:
 *        m - Module ID - Range A to Z (See Appendix K).
 *        f - Flag specifying Enable or Disable protection.
 *             0 = disable protection
 *             1 = enable protection
 *
 ******************************************************************************/
INT Ext_p(VOID)
{
    CHAR ModuleID;
    CHAR Flag;

    ModuleID = DmxNextByte();
    Flag = DmxNextByte();

    // Supported series
    if (DatamaxModel.Display == DISPLAY_EQUIPPED)
    {
        // ... not finish
    }
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Query Memory Configuration
 *
 * Description:
 *        This command causes the printer to transmit, in a model-dependent format,
 *        its DRAM memory configuration (i.e., total amount installed, amount
 *        available for configuration, and amount currently assigned to specific
 *        functions or entities) to the host device.
 *
 * Syntax:
 *        <STX>KQ<CR>
 *
 * Where:
 *
 ******************************************************************************/
INT Ext_Q(VOID)
{
    // ... not finish
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Query Memory Configuration (new format, Display-Equipped Models only)
 *
 * Description:
 *        This command causes the printer to transmit its internal DRAM memory
 *        configuration to the host device. The transmitted data provides information
 *        regarding the total amount of internal DRAM installed, the amount available
 *        for configuration, and the amount currently assigned to specific functions
 *        or entities.
 *
 * Syntax:
 *        <STX>Kq<CR>
 *
 * Where:
 *
 ******************************************************************************/
INT Ext_q(VOID)
{
    // ... not finish
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Reset Memory Configuration (Non-Display Models only)
 *
 * Description:
 *        This command resets the printer's DRAM configuration to the default
 *        settings; see <STX>KM.
 *
 * Syntax:
 *        <STX>KR<CR>
 *
 * Where:
 *
 ******************************************************************************/
INT Ext_R(VOID)
{
    // Supported series
    if (DatamaxModel.Display == NON_DISPLAY)
    {
        // ... not finish
    }
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Resettable Counter Reset
 *
 * Description:
 *        This command resets the internal counters. Follow this command with an
 *        <SOH>U command to retain the reset or the counters will revert to the
 *        previous values after cycling power.
 *
 * Syntax:
 *        <STX>Kr<CR>
 *
 * Where:
 *
 ******************************************************************************/
INT Ext_r(VOID)
{
    // ... not finish
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Memory Configuration, Scalable Font Cache (Non-Display Models only)
 *
 * Description:
 *        Represents the start of a sequence (up to five characters) that assigns the
 *        amount of internal memory allocated to the smooth scalable font processor.
 *        This field is optional; if it does not appear, the current amount of memory
 *        assigned to the smooth scalable font processor will remain unchanged. The
 *        allocation must be at least 15 (60KB) to print scalable fonts, and at least
 *        30 for double-byte fonts. The number that follows the S is a decimal number
 *        (up to four digits) that specifies the size in 4 KB blocks to assign to the
 *        smooth scalable font processor. Any value less than the minimum requirement
 *        results in the amount assigned to be zero (0), thereby disabling the printing
 *        of smooth scalable fonts. The recommended value is 0025 (100KB).
 *
 * Syntax:
 *        <STX>Kix[:jy][:kz]<CR>
 *
 * Where:
 *        i, j, k are M, S, or W; x, y, z are four-digit maximum numbers of 4K
 *        byte blocks or inches/100 or (mm/10) as described below.
 *
 ******************************************************************************/
INT Ext_S(VOID)
{
    STATIC CONST _CmdEntry ExtEntry[] =
    {
         {"M",            Ext_M},    // Memory Configuration, Internal Module
        {"S",            Ext_S},    // Memory Configuration, Scalable Font Cache
        {"W",            Ext_W},    // Memory Configuration, Printable Label Width
        {(CHAR *)_NULL,    _NULL}
    };

    _CmdEntry *CmdEntry;
    CHAR data;
    LONG Cache;

    if (DmxGetNumber(&Cache, 4) != 4)
        return _ERROR;

    // Supported series
    if (DatamaxModel.Display == NON_DISPLAY)
        pDmxCfg->ScalableCache = (SHORT)(Cache * 4);    // Convert 4KB to KB

    data = DmxNextByte();
    if (data == ':')
    {
        data = DmxNextByte();
        if (CmdEntry = CheckSingleCommand(data, ExtEntry))
            return CmdEntry->func();
    }
    else
        DmxBackByte(data);

    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Direct Mode - HF [13.56 MHz] ISO15693 Tag Interface
 *
 * Description:
 *
 * Syntax:
 *
 * Where:
 *
 ******************************************************************************/
INT Ext_t(VOID)
{
    STATIC CONST _CmdEntry ExtEntry[] =
    {
         {"A",            Ext_tA},    // Write Application Family Identifier (AFI) to Tag
        {"D",            Ext_tD},    // Write Data Storage Format Identifier (DSFID) to Tag
        {"E",            Ext_tE},    // Write Electronic Article Surveillance (EAS) Bit
        {"H",            Ext_tH},    // Read and Feedback Tag Information to Host
        {"R",            Ext_tR},    // Read Data from RFID Tag
        {"U",            Ext_tU},    // Read Unique Serial Number from RFID Tag
        {"W",            Ext_tW},    // Write Data to RFID Tag
        {(CHAR *)_NULL,    _NULL}
    };

    _CmdEntry *CmdEntry;
    CHAR data;

    data = DmxNextByte();
    if (CmdEntry = CheckSingleCommand(data, ExtEntry))
        return CmdEntry->func();
    return _ERROR;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Write Application Family Identifier (AFI) to Tag
 *        (Direct Mode - HF [13.56 MHz] ISO15693 Tag Interface)
 *
 * Description:
 *        This command writes the AFI data to the tag.
 *
 * Syntax:
 *        <STX>KtAabcc
 *
 * Where:
 *        a  - The number of retry attempts, 0-9.
 *        b  - Lock the Application Family Identifier (AFI) after writing:
 *              0 = No Protection
 *              1 = Write Protect
 *        cc - Two character AFI value representing one byte.
 *
 ******************************************************************************/
INT Ext_tA(VOID)
{
    return _ERROR;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Write Data Storage Format Identifier (DSFID) to Tag
 *        (Direct Mode - HF [13.56 MHz] ISO15693 Tag Interface)
 *
 * Description:
 *        This command writes the DSFID data to the tag.
 *
 * Syntax:
 *        <STX>KtDabcc
 *
 * Where:
 *        a  - The number of retry attempts, 0-9.
 *        b  - Lock the Data Storage Format Identifier (DSFID) after writing:
 *              0 = No Protection
 *              1 = Write Protect
 *        cc - Two character DFSID value representing one byte.
 *
 ******************************************************************************/
INT Ext_tD(VOID)
{
    return _ERROR;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Write Electronic Article Surveillance (EAS) Bit
 *        (Direct Mode - HF [13.56 MHz] ISO15693 Tag Interface)
 *
 * Description:
 *        This command writes the EAS bit for Philips ISO tags.
 *
 * Syntax:
 *        <STX>KtEabcc
 *
 * Where:
 *        a  - The number of retry attempts, 0-9.
 *        b  - Electronic Article Surveillance (EAS) option:
 *              0 = Set EAS
 *              1 = Reset EAS
 *              2 = Test EAS
 *        cc - Two character Manufacturer's Code, representing one byte.
 *
 ******************************************************************************/
INT Ext_tE(VOID)
{
    return _ERROR;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Read and Feedback Tag Information to Host
 *        (Direct Mode - HF [13.56 MHz] ISO15693 Tag Interface)
 *
 * Description:
 *        This command returns the tag info to host.
 *
 * Syntax:
 *        <STX>KtH
 *
 * Where:
 *
 ******************************************************************************/
INT Ext_tH(VOID)
{
    return _ERROR;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Read Data from RFID Tag
 *        (Direct Mode - HF [13.56 MHz] ISO15693 Tag Interface)
 *
 * Description:
 *        This command instructs the RFID device to read data from the tag and
 *        then put that data into a replaceable field. It is expected that the
 *        tag transponder will be within the read / write distance of the RFID
 *        programming device; otherwise, "Void" will be printed in the text or
 *        bar code label field(s).
 *
 * Syntax:
 *        <STX>KtRUn1..n16Haaabbbcdee<CR>
 *
 * Where:
 *        Un1..n16 - (Optional) Where n1n16 is the Unique Identifier (UID) in
 *                   hexadecimal format. Must be sixteen characters long.
 *        H        - (Optional) Hexadecimal data  An "H" may be added directly
 *                   after "R" to return a two character hex value of the data. Since
 *                   there are two digits per hex value, replaceable fields should be
 *                   twice as long than if using ASCII data (e.g., the character "A"
 *                   would be returned as "41").
 *        aaa      - Starting block number (000 .. maximum block number).*
 *        bbb      - The number of blocks to read (001 .. maximum block number).*
 *        c        - The number of retry attempts, 0-9.
 *        d        - Reserved. Should be 0.
 *        ee       - Field number in which to place the data (must be 01, 02, 03,
 *                   etc.) matching the order of Label Formatting command, U.
 *
 ******************************************************************************/
INT Ext_tR(VOID)
{
    return _ERROR;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Read Unique Serial Number from RFID Tag
 *        (Direct Mode - HF [13.56 MHz] ISO15693 Tag Interface)
 *
 * Description:
 *        This command instructs the RFID device to read the unique serial number
 *        data from the tag and then place that data into a replaceable field. It
 *        is expected that the tag transponder will be within the read / write
 *        distance of the RFID programming device; otherwise, "Void" will be printed
 *        in the text or bar code label field(s).
 *
 * Syntax:
 *        <STX>KtUabcc<CR>
 *
 * Where:
 *        a  - The number of retry attempts, 0-9.
 *        b  - Reserved. Should be 0.
 *        cc - Field number in which to place the data (must be 01, 02, 03, etc.)
 *             matching the order of Label Formatting command, U.
 *
 ******************************************************************************/
INT Ext_tU(VOID)
{
    return _ERROR;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Write Data to RFID Tag
 *        (Direct Mode - HF [13.56 MHz] ISO15693 Tag Interface)
 *
 * Description:
 *        This command instructs the RFID device to write data to the tag. It is
 *        expected that the tag transponder will be within the read / write
 *        distance of the RFID programming device; otherwise, a warning will occur
 *        and a warning message (Read / Write Fail) will be displayed.
 *
 * Syntax:
 *        <STX>KtWUn1..n16Bncncncaaabcdee..e<CR>
 *
 * Where:
 *        Un1..n16 - (Optional) Where n1..n16 is the Unique Identifier (UID) in
 *                   hexadecimal format. Must be sixteen characters long.
 *        Bncncnc  - (Optional) Where ncncnc is the data byte count, to allow
 *                   nonprintable characters (i.e., characters with hex values
 *                   less than 0x20) to be encoded.
 *        aaa      - Starting block number (000 .. maximum block number).*
 *        b        - The number of retry attempts, 0-9.
 *        c        - Lock block after writing:
 *                    0 = No Protection
 *                    1 = Write Protect
 *        d        - Reserved. Should be 0.
 *        ee..e    - Data to be encoded on RFID tag.
 *
 ******************************************************************************/
INT Ext_tW(VOID)
{
    return _ERROR;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Direct Mode - UHF Interface
 *
 * Description:
 *
 * Syntax:
 *
 * Where:
 *
 ******************************************************************************/
INT Ext_u(VOID)
{
    STATIC CONST _CmdEntry ExtEntry[] =
    {
         {"F",            Ext_uF},    // Send RFID Device Firmware Version
         {"R",            Ext_uR},    // Read Data from RFID Tag
         {"W",            Ext_uW},    // Write Data to RFID Tag
        {(CHAR *)_NULL,    _NULL}
    };

    _CmdEntry *CmdEntry;
    CHAR data;

    data = DmxNextByte();
    if (CmdEntry = CheckSingleCommand(data, ExtEntry))
        return CmdEntry->func();
    return _ERROR;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Send RFID Device Firmware Version
 *
 * Description:
 *        This command instructs the RFID device to return the firmware version.
 *
 * Syntax:
 *        <STX>KuF<CR>
 *
 * Where:
 *
 ******************************************************************************/
INT Ext_uF(VOID)
{
    return _ERROR;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Read Data from RFID Tag
 *        (Direct Mode - UHF Interface  Hexadecimal Data Only)
 *
 * Description:
 *        This command instructs the RFID device to read data from the tag and
 *        then place that data into a replaceable field. It is expected that the
 *        tag transponder is within the read / write distance of the RFID 
 *        programming device; otherwise, "Void" will be printed in the text or bar
 *        code label field(s).
 *
 * Syntax:
 *        <STX>KuRaa<CR>
 *
 * Where:
 *        aa - Field number in which to place the data (must be 01, 02, 03, etc.)
 *             matching the order of Label Formatting command, U.
 *
 ******************************************************************************/
INT Ext_uR(VOID)
{
    return _ERROR;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Write Data to RFID Tag
 *        (Direct Mode - UHF Interface  Hexadecimal Data Only)
 *
 * Description:
 *        This command instructs the RFID device to write data to the tag. It is
 *        expected that the tag transponder will be within the read / write
 *        distance of the RFID programming device; otherwise, a warning will occur
 *        and a warning message (Read / Write Fail) will be displayed.
 *
 * Syntax:
 *        <STX>KuWabcc..c<CR>
 *
 * Where:
 *        a     - The number of attempts to locate, erase, and program the tag, 1-9.
 *        b     - Reserved. Should be 0.
 *        cc..c - Data to be encoded in the ASCII format. Must be sixteen
 *                characters in length. The valid characters are 0-9, A-F.
 *
 ******************************************************************************/
INT Ext_uW(VOID)
{
    return _ERROR;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Verifier Enable/Disable (Display-Equipped Models only)
 *
 * Description:
 *        This command allows the verifier (option, if installed), to be enabled
 *        and disabled.
 *
 * Syntax:
 *        <STX>KVa<CR>
 *
 * Where:
 *        a - Y = verifier enable
 *            N = verifier disable
 *
 ******************************************************************************/
INT Ext_V(VOID)
{
    CHAR Verifier;

    Verifier = DmxNextByte();
    if (Verifier == 'Y')
        Verifier = EQUIPPED_AUTO;
    pDmxCfg->VerifierEquipped = Verifier;
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Memory Configuration, Printable Label Width (Non-Display Models only)
 *
 * Description:
 *        Represents the start of a sequence (up to five characters) that sets the
 *        printable label width. Setting a width smaller than the natural (maximum)
 *        width of the printer effectively extends printable label length. This
 *        field is optional; if it does not appear, the current printable label
 *        width is left unchanged. The number that follows the W is a decimal number
 *        (up to four digits) that specifies the printable label width in either
 *        100ths of an inch or in millimeters, depending on the current units setting
 *        of the printer (imperial or metric). If the value specified exceeds the
 *        printable width of the printer, the printable label width is set to the
 *        maximum. If the value specified is less than the minimum value allowed
 *        (200) then the printable label width is set to the minimum allowed value.
 *
 * Syntax:
 *        <STX>Kix[:jy][:kz]<CR>
 *
 * Where:
 *        i, j, k are M, S, or W; x, y, z are four-digit maximum numbers of 4K
 *        byte blocks or inches/100 or (mm/10) as described below.
 *
 ******************************************************************************/
INT Ext_W(VOID)
{
    STATIC CONST _CmdEntry ExtEntry[] =
    {
         {"M",            Ext_M},    // Memory Configuration, Internal Module
        {"S",            Ext_S},    // Memory Configuration, Scalable Font Cache
        {"W",            Ext_W},    // Memory Configuration, Printable Label Width
        {(CHAR *)_NULL,    _NULL}
    };

    _CmdEntry *CmdEntry;
    CHAR data;
    LONG Width;

    if (DmxGetNumber(&Width, 4) != 4)
        return _ERROR;

    // Supported series
    if (DatamaxModel.Display == NON_DISPLAY)
        pDmxCfg->LabelWidth = TransformDot(Width, pDmxCfg->UnitMeasure);

    data = DmxNextByte();
    if (data == ':')
    {
        data = DmxNextByte();
        if (CmdEntry = CheckSingleCommand(data, ExtEntry))
            return CmdEntry->func();
    }
    else
        DmxBackByte(data);

    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Delete Configuration File (Display-Equipped Models only)
 *
 * Description:
 *        This command deletes the specified configuration file.
 *
 * Syntax:
 *        <STX>KxmName<CR>
 *
 * Where:
 *        m    - Valid Module ID - Range A to Z.
 *        Name - The name, up to 16 characters, of the configuration file.
 *        <CR> - 0x0d terminates the name.
 *
 ******************************************************************************/
INT Ext_x(VOID)
{
    CHAR ModuleID;
    CHAR Name[17];

    ModuleID = DmxNextByte();

    if (DmxGetString(Name, sizeof(Name)) > 16)
        return _ERROR;

    // Supported series
    if (DatamaxModel.Display == DISPLAY_EQUIPPED)
        DeleteModuleFile(ModuleID, Name, 'C');

    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Immediately Set Parameter
 *
 * Description:
 *        This command immediately sets the specified parameter.
 *
 * Syntax:
 *        <STX>KZax<CR>
 *
 * Where:
 *        a  - Valid parameter identifier, as follows:
 *             F = Feed Speed
 *             H = Heat Setting
 *             P = Print Speed
 *             S = Slew Speed
 *        x  - Speed Parameter Range - A to e (see Appendix L).
 *          or
 *        xx - Heat Parameter Range - A two-digit value (00-30); see the
 *             'H' Label Formatting Command.
 *
 ******************************************************************************/
INT Ext_Z(VOID)
{
    CHAR ParamID;
    CHAR Speed;
    LONG Heat;

    ParamID = DmxNextByte();

    if (ParamID == 'F')    // Feed Speed
    {
        Speed = DmxNextByte();

        // Valid ranges
        if (Speed  >= DatamaxModel.FeedSpeed.Minimum &&
            Speed  <= DatamaxModel.FeedSpeed.Maximum)
        {
            if (pDmxCfg->CommSpeedCommands == 'Y')
                pDmxCfg->FeedSpeed = Speed;
        }
    }
    if (ParamID == 'H')    // Heat Setting
    {
        if (DmxGetNumber(&Heat, 2) != 2)
            return _ERROR;

        // Valid ranges
        if (Heat>= 0 && Heat <= 30)
        {
            if (pDmxCfg->CommHeatCommands == 'Y')
                pDmxCfg->Heat = (SHORT)Heat;
        }
    }
    if (ParamID == 'P')    // Print Speed
    {
        Speed = DmxNextByte();

        // Valid ranges
        if (Speed  >= DatamaxModel.PrintSpeed.Minimum &&
            Speed  <= DatamaxModel.PrintSpeed.Maximum)
        {
            if (pDmxCfg->CommSpeedCommands == 'Y')
                pDmxCfg->PrintSpeed = Speed;
        }
    }
    if (ParamID == 'S')    // Slew Speed
    {
        Speed = DmxNextByte();

        // Valid ranges
        if (Speed  >= DatamaxModel.SlewSpeed.Minimum &&
            Speed  <= DatamaxModel.SlewSpeed.Maximum)
        {
            if (pDmxCfg->CommSpeedCommands == 'Y')
                pDmxCfg->SlewSpeed = Speed;
        }
    }
    return _SUCCESS;
}

#endif

DplFuncFntLoad.c 

/******************************************************************************
 *                                                                            *
 *                         M O D U L E   D E F I N E                          *
 *                                                                            *
 ******************************************************************************/

#define DPLFUNCFNTLOAD_C

/******************************************************************************
 *                                                                            *
 *        C O M P I L E R   D E F I N E D   I N C L U D E   F I L E S         *
 *                                                                            *
 ******************************************************************************/

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

/******************************************************************************
 *                                                                            *
 *            U S E R   D E F I N E D   I N C L U D E   F I L E S             *
 *                                                                            *
 ******************************************************************************/

#include "Common.h"
#include "XCore.h"
#include "XFileSys.h"
#include "..\ParserUtil.h"
#include "DplConfig.h"
#include "DplUtil.h"
#include "DplFunc.h"

/******************************************************************************
 *                                                                            *
 *                         L O C A L   D E F I N E S                          *
 *                                                                            *
 ******************************************************************************/

#if defined(DPL)

/******************************************************************************
 *                                                                            *
 *                        L O C A L   T Y P E D E F S                         *
 *                                                                            *
 ******************************************************************************/

/*
 * Format 0 Font Header (for PCL Bitmapped Fonts)
 */
typedef struct
{
    WORD FontDescriptorSize;    // (64)
    BYTE HeaderFormat;            // (0)
    BYTE FontType;
    BYTE StyleMSB;
    BYTE Reserved;
    WORD BaselinePosition;
    WORD CellWidth;
    WORD CellHeight;
    BYTE Orientation;
    BYTE Spacing;
    WORD SymbolSet;

    WORD Pitch;                    // (Default HMI)
    WORD Height;
    WORD xHeight;
    CHAR WidthType;
    BYTE StyleLSB;
    CHAR StrokeWeight;
    BYTE TypefaceLSB;
    BYTE TypefaceMSB;
    BYTE SerifStyle;
    BYTE Quality;
    CHAR Placement;
    CHAR UnderlinePosition;     // (Distance)
    BYTE UnderlineThickness;    // (Height)

    WORD TextHeight;
    WORD TextWidth;
    WORD FirstCode;
    WORD LastCode;
    BYTE PitchExtended;
    BYTE HeightExtended;
    WORD CapHeight;
    UINT FontNum;

    BYTE FontName[16];
} FONTDESC;

/*
 * PCL Bitmap Character Descriptor
 */
typedef struct
{
    BYTE  Format;                // (4)
    BYTE  Continuation;            // (0)
    BYTE  DescriptorSize;        // (14)
    BYTE  Class;                // (1)
    BYTE  Orientation;
    BYTE  Reserved;                // (0)
    SHORT LeftOffset;
    SHORT TopOffset;
    SHORT CharacterWidth;
    WORD  CharacterHeight;
    SHORT DeltaX;
} CHARDESC;

typedef struct
{
/* PCL Font */
    INT          FontID;
    FONTDESC     Header;
    WORD         CharCode;
/* File system */
    _FileHandle *Handle;
    INT          State;
/* VF3 Font */
    BYTE         Table[6 * 256];
    INT          Index;
    INT          Offset;
} PCLFONT;


/******************************************************************************
 *                                                                            *
 *             L O C A L   F U N C T I O N   P R O T O T Y P E S              *
 *                                                                            *
 ******************************************************************************/

/******************************************************************************
 *                                                                            *
 *    L O C A L   I N I T I A L I Z E D   D A T A   D E F I N I T I O N S     *
 *                                                                            *
 ******************************************************************************/

/******************************************************************************
 *                                                                            *
 *    L O C A L   U N I T I A L I Z E D   D A T A   D E F I N I T I O N S     *
 *                                                                            *
 ******************************************************************************/

/*
 * Describes the font header and character definition formats for PCL Bitmap fonts
 */
STATIC PCLFONT PCL;


STATIC VOID PCLFileClose(PCLFONT *pcl)
{
    _eFileDevice device = TransformFileDevice(pDmxCfg->DefaultModule);
    FONTDESC *header = &(pcl->Header);
    CHAR fontname[16];
    BYTE fonthead[32] =    // VF3 Font type
    {
        'B',  0x01, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
        0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 
    };

    if (pcl->Index < 256)
    {
        WORD space = header->Pitch / 4;    // The number of quarter dots
        WORD bytes = (space + 7) / 8 * header->CellHeight;

        // Write Space Width to file
        pcl->State = Fputc((INT)(space & 0xff), pcl->Handle);
        pcl->State = Fputc((INT)(space >> 8), pcl->Handle);

        // Write Space Data to file
        while (bytes--)
        {
            if (pcl->State != END_OF_FILE)
                pcl->State = Fputc(0, pcl->Handle);
        }

        // Save VF3 Table
        pcl->Table[pcl->Index * 6]     = 0x20;
        pcl->Table[pcl->Index * 6 + 1] = 0x00;
        pcl->Table[pcl->Index * 6 + 2] = (BYTE)(pcl->Offset & 0xff);
        pcl->Table[pcl->Index * 6 + 3] = (BYTE)((pcl->Offset >> 8) & 0xff);;
        pcl->Table[pcl->Index * 6 + 4] = (BYTE)((pcl->Offset >> 16) & 0xff);
        pcl->Table[pcl->Index * 6 + 5] = (BYTE)((pcl->Offset >> 24) & 0xff);
        pcl->Index += 1;
    }

    // 5-6 : Font Height
    fonthead[5] = (BYTE)(header->CellHeight & 0xff);
    fonthead[6] = (BYTE)(header->CellHeight >> 8);
    // 7-8 : Font Width
    fonthead[7] = (BYTE)(header->CellWidth & 0xff);
    fonthead[8] = (BYTE)(header->CellWidth >> 8);
    // 15-16 : Font Character Total
    fonthead[15] = (BYTE)(pcl->Index & 0xff);
    fonthead[16] = (BYTE)(pcl->Index >> 8);

    Fseek(pcl->Handle, 0, SEEK_SET);

    // Write font head to file
    if (pcl->State != END_OF_FILE)
    {
        if (Fwrite(fonthead, sizeof(CHAR), sizeof(fonthead), pcl->Handle) != sizeof(fonthead))
            pcl->State = END_OF_FILE;
    }
    // Write address table to file
    if (pcl->State != END_OF_FILE)
    {
        if (Fwrite(pcl->Table, sizeof(CHAR), sizeof(pcl->Table), pcl->Handle) != sizeof(pcl->Table))
            pcl->State = END_OF_FILE;
    }
    Fclose(pcl->Handle);

    if (pcl->State == END_OF_FILE)
    {
        sprintf(fontname, "%03d", pcl->FontID);
        strcat(fontname, "DMX.BMF");
        Remove(device, fontname);
    }
    pcl->Handle = _NULL;
    pcl->State = _NULL;
}

STATIC VOID PCLFileOpen(PCLFONT *pcl)
{
    _eFileDevice device = TransformFileDevice(pDmxCfg->DefaultModule);
    CHAR fontname[16];
    BYTE fonthead[32];

    sprintf(fontname, "%03d", pcl->FontID);
    strcat(fontname, "DMX.BMF");

    Remove(device, fontname);
    pcl->Handle = Fopen(device, fontname, "w");
    pcl->State = _NULL;

    // Set font head to 0xff
    memset(fonthead, 0xff, sizeof(fonthead));
    // Set address table is 0xff
    memset(pcl->Table, 0xff, sizeof(pcl->Table));

    // Write dummy head to file
    if (pcl->State != END_OF_FILE)
    {
        if (Fwrite(fonthead, sizeof(CHAR), sizeof(fonthead), pcl->Handle) != sizeof(fonthead))
            pcl->State = END_OF_FILE;
    }
    // Write dummy address table to file
    if (pcl->State != END_OF_FILE)
    {
        if (Fwrite(pcl->Table, sizeof(CHAR), sizeof(pcl->Table), pcl->Handle) != sizeof(pcl->Table))
            pcl->State = END_OF_FILE;
    }

    pcl->CharCode = 0;
    pcl->Index = 0;
    pcl->Offset = sizeof(fonthead) + sizeof(pcl->Table);
}

/******************************************************************************
 *
 * DPL Commands:
 *        *c###D - Assign Font ID Number
 *        *c###E - Character Code
 *
 * Description:
 *        *c###D - This command is the first command required for downloading a
 *                 font to either RAM or Flash Memory modules. ESC represents the
 *                 ASCII control character 27.
 *
 *        *c###E - This code is the ASCII decimal value corresponding to the next
 *                 downloaded character.
 *
 * Syntax:
 *        <ESC>*c###D
 *        <ESC>*c###E
 *
 * Where:
 *        ###D - Is the font ID numbers 100-999 (000 - 099 are reserved for resident fonts).
 *        ###E - Is the ASCII value of the character, three digits maximum, 0 to 999.
 *
 ******************************************************************************/
INT Fnt_CodeID(VOID)
{
    PCLFONT *pcl = &PCL;
    LONG number;
    CHAR data;

    data = DmxNextByte();
    if (data != 'c')
        return _ERROR;

    if (DmxGetNumber(&number, 3) == 0)
        return _ERROR;

    data = DmxNextByte();

    // *c###D - Assign Font ID Numbe
    if (data == 'D')
    {
        if (pcl->Handle != _NULL)
            PCLFileClose(pcl);
        pcl->FontID = number;
        PCLFileOpen(pcl);
        return _SUCCESS;
    }
    // *c###E - Character Code
    if (data == 'E')
    {
        pcl->CharCode = number;
        return _SUCCESS;
    }
    return _ERROR;
}

/******************************************************************************
 *
 * DPL Commands:
 *        )s###W - Font Descriptor
 *
 * Description:
 *        This command (typically first data in a font file) contains all of the
 *        information about the font contained in the file. Different font generation
 *        software will create different length header information, but the initial
 *        64 bytes will remain consistent with the PCL-4 (HP LaserJet II) format.
 *
 * Syntax:
 *        <ESC>)s###Wddd..d
 *
 * Where:
 *        ###   - Is the number of bytes of font descriptor data from 1 to 3
 *                ASCII decimal digits.
 *        dd..d - Is the descriptor.
 *
 ******************************************************************************/
INT Fnt_Descriptor(VOID)
{
    PCLFONT *pcl = &PCL;
    FONTDESC *header = &(pcl->Header);
    LONG bytes;
    CHAR data;
    CHAR *p;
    INT n;

    data = DmxNextByte();
    if (data != 's')
        return _ERROR;

    // ### - Is the number of bytes of font descriptor data from 1 to 3 ASCII decimal digits.
    if (DmxGetNumber(&bytes, 3) == 0)
        return _ERROR;

    data = DmxNextByte();
    if (data != 'W')
        return _ERROR;

    p = (CHAR *)header;

    // dd..d - Is the descriptor.
    for (n = 0; n < bytes; n++)
    {
        data = DmxNextByte();
        if (n < sizeof(FONTDESC))
            *p++ = data;
    }
    header->FontDescriptorSize = be16_to_cpu(header->FontDescriptorSize);
    header->BaselinePosition   = be16_to_cpu(header->BaselinePosition);
    header->CellWidth          = be16_to_cpu(header->CellWidth);
    header->CellHeight         = be16_to_cpu(header->CellHeight);
    header->SymbolSet          = be16_to_cpu(header->SymbolSet);
    header->Pitch              = be16_to_cpu(header->Pitch);
    header->Height             = be16_to_cpu(header->Height);
    header->xHeight            = be16_to_cpu(header->xHeight);
    header->TextHeight         = be16_to_cpu(header->TextHeight);
    header->TextWidth          = be16_to_cpu(header->TextWidth);
    header->FirstCode          = be16_to_cpu(header->FirstCode);
    header->LastCode           = be16_to_cpu(header->LastCode);
    header->CapHeight          = be16_to_cpu(header->CapHeight);
    header->FontNum            = be32_to_cpu(header->FontNum);
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        (s###W - Character Download Data
 *
 * Description:
 *        This command contains all of the information for one downloaded character.
 *
 * Syntax:
 *        <ESC>(s###Wnn..n
 *
 * Where:
 *        ###   - Is the number of bytes of bit-mapped data, three digits maximum,
 *                from 1 to 999.
 *        nn..n - Is the bit-mapped data.
 *
 ******************************************************************************/
INT Fnt_Data(VOID)
{
    PCLFONT *pcl = &PCL;
    FONTDESC *header = &(pcl->Header);
    CHARDESC charHeader;
    _ImgBuf dstimg, srcimg;
    LONG bytes;
    CHAR data;
    CHAR *image;
    CHAR *buffer;
    CHAR *p;
    INT imgsize;
    INT total;
    INT x, y, n;

    data = DmxNextByte();
    if (data != 's')
        return _ERROR;

    // ### - Is the number of bytes of bit-mapped data, three digits maximum, from 1 to 999.
    if (DmxGetNumber(&bytes, 3) == 0)
        return _ERROR;

    data = DmxNextByte();
    if (data != 'W')
        return _ERROR;

    p = (CHAR *) & charHeader;

    // Get Character Header 16 Bytes
    for (n = 0; n < sizeof(CHARDESC); n++)
        *p++ = DmxNextByte();

    charHeader.LeftOffset      = be16_to_cpu(charHeader.LeftOffset);
    charHeader.TopOffset       = be16_to_cpu(charHeader.TopOffset);
    charHeader.CharacterWidth  = be16_to_cpu(charHeader.CharacterWidth);
    charHeader.CharacterHeight = be16_to_cpu(charHeader.CharacterHeight);
    charHeader.DeltaX          = be16_to_cpu(charHeader.DeltaX);

    if (charHeader.Orientation == 1 || charHeader.Orientation == 3)
    {
        x = charHeader.TopOffset - charHeader.CharacterHeight;
        y = header->BaselinePosition + charHeader.LeftOffset;
    }
    else
    {
        x = charHeader.LeftOffset;
        y = header->BaselinePosition - charHeader.TopOffset;
    }

    srcimg.iHeight = charHeader.CharacterHeight;
    srcimg.iWidth  = charHeader.CharacterWidth;
    srcimg.iByteWidth = (srcimg.iWidth + 7) / 8;

    imgsize = srcimg.iByteWidth * srcimg.iHeight;

    if (image = malloc(imgsize))
    {
        memset(image, 0, imgsize);

        p = image;

        // Get Character Data
        for (n = sizeof(CHARDESC); n < bytes; n++)
        {
            data = DmxNextByte();
            if (p < image + imgsize)
                *p++ = data;
        }

        dstimg.iHeight = header->CellHeight;
        dstimg.iWidth  = charHeader.DeltaX / 4;    // The number of quarter dots
        dstimg.iByteWidth = (dstimg.iWidth + 7) / 8;

        total = dstimg.iByteWidth * dstimg.iHeight + sizeof(WORD);

        if (buffer = malloc(total))
        {
            memset(buffer, 0, total);

            p = buffer;

            // VF3 Character Width
            *p++ = (BYTE)(dstimg.iWidth & 0xff);
            *p++ = (BYTE)(dstimg.iWidth >> 8);

            // Put Image Data
            srcimg.pBuffer = (BYTE *)image;
            dstimg.pBuffer = (BYTE *)p;
            PutImage(&dstimg, &srcimg, x, y, charHeader.Orientation * 90, PUT_OR);

            // Write Character Data to file
            if (pcl->State != END_OF_FILE)
            {
                if (Fwrite(buffer, sizeof(BYTE), total, pcl->Handle) != total)
                    pcl->State = END_OF_FILE;
            }

            // Save VF3 Table
            pcl->Table[pcl->Index * 6]     = (BYTE)(pcl->CharCode & 0xff);
            pcl->Table[pcl->Index * 6 + 1] = (BYTE)(pcl->CharCode >> 8);
            pcl->Table[pcl->Index * 6 + 2] = (BYTE)(pcl->Offset & 0xff);
            pcl->Table[pcl->Index * 6 + 3] = (BYTE)((pcl->Offset >> 8) & 0xff);;
            pcl->Table[pcl->Index * 6 + 4] = (BYTE)((pcl->Offset >> 16) & 0xff);
            pcl->Table[pcl->Index * 6 + 5] = (BYTE)((pcl->Offset >> 24) & 0xff);
            pcl->Index += 1;
            pcl->Offset += total;

            free(buffer);
        }

        free(image);
    }

    data = DmxNextByte();
    DmxBackByte(data);

    if (data != ESC_CHAR)
        PCLFileClose(pcl);

    return _SUCCESS;
}

#endif

DplFuncImmed.c  //

/******************************************************************************
 *                                                                            *
 *                         M O D U L E   D E F I N E                          *
 *                                                                            *
 ******************************************************************************/

#define DPLFUNCIMMED_C

/******************************************************************************
 *                                                                            *
 *        C O M P I L E R   D E F I N E D   I N C L U D E   F I L E S         *
 *                                                                            *
 ******************************************************************************/

#include <string.h>

/******************************************************************************
 *                                                                            *
 *            U S E R   D E F I N E D   I N C L U D E   F I L E S             *
 *                                                                            *
 ******************************************************************************/

#include "Common.h"
#include "XCore.h"
#include "XFunction.h"
#include "..\ParserUtil.h"
#include "DplConfig.h"
#include "DplFunc.h"

/******************************************************************************
 *                                                                            *
 *                         L O C A L   D E F I N E S                          *
 *                                                                            *
 ******************************************************************************/

#if defined(DPL)

/******************************************************************************
 *                                                                            *
 *                        L O C A L   T Y P E D E F S                         *
 *                                                                            *
 ******************************************************************************/

/******************************************************************************
 *                                                                            *
 *             L O C A L   F U N C T I O N   P R O T O T Y P E S              *
 *                                                                            *
 ******************************************************************************/

/******************************************************************************
 *                                                                            *
 *    L O C A L   I N I T I A L I Z E D   D A T A   D E F I N I T I O N S     *
 *                                                                            *
 ******************************************************************************/

/******************************************************************************
 *                                                                            *
 *    L O C A L   U N I T I A L I Z E D   D A T A   D E F I N I T I O N S     *
 *                                                                            *
 ******************************************************************************/

#if defined(__HITACHI__)
#pragma section ISR
#endif

/******************************************************************************
 *
 * DPL Commands:
 *        Reset
 *
 * Description:
 *        This command resets the printer. Resetting the printer returns all
 *        settings to default and clears both the communications and printing
 *        buffers. The command also clears DRAM memory.
 *
 * Syntax:
 *        <SOH>#
 *
 * Where:
 *
 ******************************************************************************/
INT Imm_Rst(VOID)
{
    PrinterReboot();
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Reset (Display-Equipped Models only)
 *
 * Description:
 *        This command forces a soft reset of the microprocessor, which resets the
 *        printer. Resetting the printer returns all settings to default and clears
 *        the communications and print buffers.
 *
 * Syntax:
 *        <SOH>*
 *
 * Where:
 *
 ******************************************************************************/
INT Imm_RstDsp(VOID)
{
    // Supported series
    if (DatamaxModel.Display == DISPLAY_EQUIPPED)
        PrinterReboot();

    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Send ASCII Status String
 *
 * Description:
 *        This command allows the host computer to check the current printer status.
 *        The printer returns a string of eight characters, followed by a carriage
 *        return. Each character (see below) indicates an associated condition,
 *        either true (Y) or false (N). Byte 1 is transmitted first. See <SOH>F.
 *
 * Syntax:
 *        <SOH>A
 *
 * Where:
 *
 ******************************************************************************/
INT Imm_A(VOID)
{
    _eMotorStatus MotorStatus = GetMotorStatus();
    WORD JobError = GetJobErrorState();
    BOOL JobLock = CheckJobLock();
    CHAR Response[] = { 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', CR_CHAR };

    //--------------------------------------------
    // Byte | Value | Interpretation
    //  1   |  Y/N  |  Interpreter busy (imaging)
    //  2   |  Y/N  |  Paper out or fault
    //  3   |  Y/N  |  Ribbon out or fault
    //  4   |  Y/N  |  Printing batch
    //  5   |  Y/N  |  Busy printing
    //  6   |  Y/N  |  Printer paused
    //  7   |  Y/N  |  Label presented
    //  8   |   N   |  Always No
    //--------------------------------------------

    if (JobError & ERROR_PAPER_JAM || JobError & ERROR_PAPER_EMPTY)
        Response[2 - 1] = 'Y';    // Paper out or Fault
    if (JobError & ERROR_RIBBON_JAM || JobError & ERROR_RIBBON_EMPTY)
        Response[3 - 1] = 'Y';    // Ribbon out or Fault
    if (MotorStatus == STATUS_MOTOR_FORWARD || MotorStatus == STATUS_MOTOR_BACKWARD)
        Response[5 - 1] = 'Y';    // Busy printing
    if (JobLock)
        Response[6 - 1] = 'Y';    // Printer paused

    SendImmedPort(Response, sizeof(Response));
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Send ASCII Extended Status String
 *
 * Description:
 *        This command allows the host computer to check an extended current printer
 *        status. The printer returns a string of seventeen characters, followed by
 *        a carriage return. Most characters (see below) indicate an associated
 *        condition, either true (Y) or false (N). Byte 1 is transmitted first.
 *        See <SOH>F.
 *
 * Syntax:
 *        <SOH>a
 *
 * Where:
 *
 ******************************************************************************/
INT Imm_a(VOID)
{
    _eMotorStatus MotorStatus = GetMotorStatus();
    WORD JobError = GetJobErrorState();
    BOOL JobLock = CheckJobLock();
    CHAR Response[] = { 'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', ':',
                        'N', 'N', 'N', 'N', 'N', 'N', 'N', 'N', CR_CHAR };

    //--------------------------------------------
    // Byte | Value | Interpretation
    //  1   |  Y/N  |  Interpreter busy (imaging)
    //  2   |  Y/N  |  Paper out or fault
    //  3   |  Y/N  |  Ribbon out or fault
    //  4   |  Y/N  |  Printing batch
    //  5   |  Y/N  |  Busy printing
    //  6   |  Y/N  |  Printer paused
    //  7   |  Y/N  |  Label presented
    //  8   |   N   |  Always No
    //  9   |   :   |  Always :
    //  10  |  Y/N  |  Cutter Fault
    //  11  |  Y/N  |  Paper Out
    //  12  |  Y/N  |  Ribbon Saver Fault
    //  13  |  Y/N  |  Print Head Up
    //  14  |  Y/N  |  Top of Form Fault
    //  15  |  Y/N  |  Ribbon Low
    //  16  |  Y/N  |  N (reserved for future)
    //  17  |  Y/N  |  N (reserved for future)
    //--------------------------------------------

    if (JobError & ERROR_PAPER_JAM || JobError & ERROR_PAPER_EMPTY)
        Response[2  - 1] = 'Y';    // Paper out or Fault
    if (JobError & ERROR_RIBBON_JAM || JobError & ERROR_RIBBON_EMPTY)
        Response[3  - 1] = 'Y';    // Ribbon out or Fault
    if (MotorStatus == STATUS_MOTOR_FORWARD || MotorStatus == STATUS_MOTOR_BACKWARD)
        Response[5  - 1] = 'Y';    // Busy printing
    if (JobLock)
        Response[6  - 1] = 'Y';    // Printer paused
    if (JobError & ERROR_CUTTER)
        Response[10 - 1] = 'Y';    // Cutter Fault
    if (JobError & ERROR_PAPER_EMPTY)
        Response[11 - 1] = 'Y';    // Paper Out

#if defined(CARRIAGE_OPEN_MODEL)
    if (IsCarriageOpen() && pPrintCfg->CarriageOpen)
        Response[13 - 1] = 'Y';    // Print Head Up
#endif

    SendImmedPort(Response, sizeof(Response));
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Toggle Pause
 *
 * Description:
 *        This command toggles the printerˇs paused state between on and off.
 *        (This is the same function achieved by pressing the PAUSE Key on the printer.)
 *
 * Syntax:
 *        <SOH>B
 *
 * Where:
 *
 ******************************************************************************/
INT Imm_B(VOID)
{
    TogglePause();
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Stop/Cancel
 *
 * Description:
 *        This command performs the same function as pressing the STOP/CANCEL Key
 *        on the printer. This function clears the current label format from the
 *        print buffer, pauses the printer, and illuminates the Paused/Stop Indicator.
 *        (The pause condition is terminated as described under <SOH>B.)
 *
 * Syntax:
 *        <SOH>C
 *
 * Where:
 *
 ******************************************************************************/
INT Imm_C(VOID)
{
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        SOH Shutdown (Non-Display Models only)
 *
 * Description:
 *        This commands the printer to ignore Immediate Commands (^A). The SOH
 *        shutdown command is required before loading images or fonts because some
 *        may contain data sequences that could be interpreted as Immediate Commands.
 *        After the SOH shutdown command is sent, Immediate Commands can be turned
 *        back on by sending a valid SOH command three times, separated by a one
 *        second delay between each command, or by manually resetting the printer.
 *        It is good practice to check batch quantities (<SOH>E) to verify that the
 *        SOH commands are working.
 *
 * Syntax:
 *        <SOH>D
 *
 * Where:
 *
 ******************************************************************************/
INT Imm_D(VOID)
{
    // Supported series
    if (DatamaxModel.Display == NON_DISPLAY)
        ShutdownSOH = TRUE;

    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Send Batch Remaining Quantity
 *
 * Description:
 *        This command causes the printer to return a four-digit number indicating
 *        the quantity of labels that remain to be printed in the current batch,
 *        followed by a carriage return. Communications latency may cause this value
 *        to be higher than actual on some printers.
 *
 * Syntax:
 *        <SOH>E
 *
 * Where:
 *
 ******************************************************************************/
INT Imm_E(VOID)
{
    STATIC CONST CHAR *Response = "0000\r";

    SendImmedPort(Response, strlen(Response));
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Send Batch Printed Quantity
 *
 * Description:
 *        This command causes the printer to return a four-digit number indicating
 *        the quantity of labels that have been printed in the current batch,
 *        followed by a carriage return. Communications latency may cause this value
 *        to be lower than actual on some printers.
 *
 * Syntax:
 *        <SOH>e
 *
 * Where:
 *
 ******************************************************************************/
INT Imm_e(VOID)
{
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Send Status Byte
 *
 * Description:
 *        This command instructs the printer to send a single status byte where
 *        each bit (1 or 0) represents one of the printer's status flags, followed
 *        by a carriage return (see below). If an option is unavailable for the
 *        printer, the single bit will always be zero. See <SOH>A.
 *
 * Syntax:
 *        <SOH>F
 *
 * Where:
 *
 ******************************************************************************/
INT Imm_F(VOID)
{
    _eMotorStatus MotorStatus = GetMotorStatus();
    WORD JobError = GetJobErrorState();
    BOOL JobLock = CheckJobLock();
    BYTE Response[] = { 0x00, CR_CHAR };

    //---------------------------------------------------
    // Bit | Value | Condition
    //    8  |   0   |  Always zero
    //    7  |  0-1  |  Label presented
    //    6  |  0-1  |  Printer paused
    //    5  |  0-1  |  Busy printing
    //    4  |  0-1  |  Printing batch
    //    3  |  0-1  |  Ribbon out or Fault
    //    2  |  0-1  |  Paper out or Fault
    //    1  |  0-1  |  Command interpreter busy (imaging)
    //---------------------------------------------------

    if (JobLock)
        Response[0] |= 0x20;    // Printer paused
    if (MotorStatus == STATUS_MOTOR_FORWARD || MotorStatus == STATUS_MOTOR_BACKWARD)
        Response[0] |= 0x10;    // Busy printing
    if (JobError & ERROR_RIBBON_JAM || JobError & ERROR_RIBBON_EMPTY)
        Response[0] |= 0x04;    // Ribbon out or Fault
    if (JobError & ERROR_PAPER_JAM || JobError & ERROR_PAPER_EMPTY)
        Response[0] |= 0x02;    // Paper out or Fault

    SendImmedPort(Response, sizeof(Response));
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Update System Database with Current Database
 *
 * Description:
 *        This command saves the current printer configuration to Flash memory.
 *        Only those parameters stored in Flash memory are affected. These are all
 *        the parameters that can be modified via the Setup Menu. The values of any
 *        <STX> System Commands issued prior to <SOH>U and affecting printer
 *        configuration items will also be saved. See the <SOH># command, above,
 *        for details on what events occur during a reset.
 *
 * Syntax:
 *        <SOH>U
 *
 * Where:
 *
 ******************************************************************************/
INT Imm_U(VOID)
{
    PrinterReboot();
    return _SUCCESS;
}

#endif

DplFuncLabFmt.c  ///

/******************************************************************************
 *                                                                            *
 *                         M O D U L E   D E F I N E                          *
 *                                                                            *
 ******************************************************************************/

#define DPLFUNCLABFMT_C

/******************************************************************************
 *                                                                            *
 *        C O M P I L E R   D E F I N E D   I N C L U D E   F I L E S         *
 *                                                                            *
 ******************************************************************************/

#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <time.h>

/******************************************************************************
 *                                                                            *
 *            U S E R   D E F I N E D   I N C L U D E   F I L E S             *
 *                                                                            *
 ******************************************************************************/

#include "Common.h"
#include "XCore.h"
#include "XRTC.h"
#include "..\ParserUtil.h"
#include "DplCtrlCode.h"
#include "DplConfig.h"
#include "DplUtil.h"
#include "DplModule.h"
#include "DplLabel.h"
#include "DplFunc.h"

/******************************************************************************
 *                                                                            *
 *                         L O C A L   D E F I N E S                          *
 *                                                                            *
 ******************************************************************************/

#if defined(DPL)

/******************************************************************************
 *                                                                            *
 *                        L O C A L   T Y P E D E F S                         *
 *                                                                            *
 ******************************************************************************/

/******************************************************************************
 *                                                                            *
 *             L O C A L   F U N C T I O N   P R O T O T Y P E S              *
 *                                                                            *
 ******************************************************************************/

/******************************************************************************
 *                                                                            *
 *    L O C A L   I N I T I A L I Z E D   D A T A   D E F I N I T I O N S     *
 *                                                                            *
 ******************************************************************************/

/******************************************************************************
 *                                                                            *
 *    L O C A L   U N I T I A L I Z E D   D A T A   D E F I N I T I O N S     *
 *                                                                            *
 ******************************************************************************/

_LabRecHeader CurRecHeader;            // Label format record
_LabRecData   CurRecData;

STATIC VOID SpecLabFmtCmdFunc(_LabRecData *pData)
{
    STATIC CONST CHAR *WeekName[] = { "SUN","MON","TUE","WED","THU","FRI","SAT" };
    STATIC CONST CHAR *MonthName[] = { "JANUARY","FEBRUARY","MARCH","APRIL","MAY","JUNE",
        "JULY","AUGUST","SEPTEMBER","OCTOBER","NOVEMBER","DECEMBER" };

    CHAR *Src, *Dst, *Onset;
    CHAR Format[35];
    INT Num;

    // <STX>S - Recall Global Data and Place in Field
    if (pData->Content[0] == CtrlCode.STX && pData->Content[1] == 'S')
    {
        if (pData->Content[2] >= 'A' && pData->Content[2] <= 'P')
        {
            Num = pData->Content[2] - 'A';
            if (Num < GlbRegNum)
            {
                memcpy(pData->Content, GlobalRegister[Num].Content, GlobalRegister[Num].Length);
                pData->Length = GlobalRegister[Num].Length;
                pData->Content[pData->Length] = '\0';
            }
        }
    }

    // <STX>T - Print Time and Date
    Dst = Onset = (CHAR *)pData->Content;
    if ((Src = memchr(pData->Content, CtrlCode.STX, pData->Length)) && *(Src + 1) == 'T')
    {
        time_t t = time(_NULL);
        struct tm gmt = *gmtime(&t);

        sprintf(Format, "%01u%-3s%02u%-9s%02u%04u%02u%02u%02u%-2s%03u%02u",
            gmt.tm_wday ? gmt.tm_wday : 7,    // A     - Day of the week (Mon = 1, Sun = 7)
            WeekName[gmt.tm_wday],            // BCD   - Day of the week name
            gmt.tm_mon + 1,                   // EF    - Month number
            MonthName[gmt.tm_mon],            // GH..O - Month name
            gmt.tm_mday,                      // PQ    - Day
            gmt.tm_year + 1900,               // RSTU  - Year
            gmt.tm_hour,                      // VW    - Hour in 24 hour format
            (gmt.tm_hour % 12) ? (gmt.tm_hour % 12) : 12, // XY    - Hour in 12 hour format
            gmt.tm_min,                       // Za    - Minutes
            (gmt.tm_hour < 12) ? "AM" : "PM", // bc    - AM or PM
            gmt.tm_yday,                      // def   - Julian date
            gmt.tm_sec                        // gh    - Seconds
        );

        do
        {
            memmove(Dst, Onset, (INT)(Src - Onset));
            Dst += (INT)(Src - Onset);

            Src += 2;
            while (Src < (CHAR *)pData->Content + pData->Length)
            {
                CHAR c = *Src++;
                if (c == CtrlCode.STX)
                    break;
                else if (isupper(c))
                    *Dst++ = Format[c - 'A'];
                else if (c >= 'a' && c <= 'h')
                    *Dst++ = Format[c - 'a' + 26];
                else
                    *Dst++ = c;
            }
            Onset = Src;
            Num = (INT)pData->Content + pData->Length - (INT)Onset;
        }
        while ((Src = memchr(Onset, CtrlCode.STX, Num)) && *(Src + 1) == 'T');
        memmove(Dst, Onset, Num);
        pData->Length = Dst - pData->Content + Num;
        pData->Content[pData->Length] = '\0';
    }
}

STATIC SHORT LimitWidth(SHORT Column, SHORT Width)
{
    Column = Column - LabelParam.ColumnOffset - pPrintCfg->ShiftDisX - ShiftXBase;
    if (Width > pDmxCfg->LabelWidth - Column)
        Width = pDmxCfg->LabelWidth - Column;
    return Width;
}

STATIC INT Lab_InternalFont(VOID)
{
    _LabFontField *pFont = &CurRecHeader.Field.Font;
    CHAR Data;
    LONG Num;
    INT i;

    // c : Width Multiplier
    pFont->WidthMul = LabGetMul();

    // d : Height Multiplier
    pFont->HeightMul = LabGetMul();

    // eee : 000
    for (i = 0; i < 3; i++)
    {
        Data = LabNextByte();
    //    if (Data != '0')
    //        return _ERROR;
    }

    // ffff : Get Row Position
    if (LabGetNumLen(&Num, 4) != 4)
        return _ERROR;
    pFont->Row = TransformDot(Num, LabelParam.UnitMeasure) + LabelParam.RowOffset;

    // gggg : Get Column Position
    if (LabGetNumLen(&Num, 4) != 4)
        return _ERROR;
    pFont->Column = TransformDot(Num, LabelParam.UnitMeasure) + LabelParam.ColumnOffset + pPrintCfg->ShiftDisX + ShiftXBase;

    // jj..j : Data String
    CurRecData.Length =
        LabGetStrTerm(CurRecData.Content, sizeof(CurRecData.Content));

    SpecLabFmtCmdFunc(&CurRecData);
    return _SUCCESS;
}

STATIC INT Lab_ExpandFont(VOID)
{
    _LabFontField *pFont = &CurRecHeader.Field.Font;
    CHAR Data;
    LONG Num;
    INT i;
    BOOL ScalableFont;

    // c : Width Multiplier
    pFont->WidthMul = LabGetMul();

    // d : Height Multiplier
    pFont->HeightMul = LabGetMul();

    // eee : 000
    Data = LabNextByte();
    if (Data == 'S' || toupper(Data) == 'U')
        ScalableFont = TRUE;
    else if ((Data >= '0' && Data <= '9') || Data == 'A')
        ScalableFont = FALSE;
    else
        return _ERROR;

    pFont->ID[0] = Data;
    pFont->ID[1] = LabNextByte();
    pFont->ID[2] = LabNextByte();

    // ffff : Get Row Position
    if (LabGetNumLen(&Num, 4) != 4)
        return _ERROR;
    pFont->Row = TransformDot(Num, LabelParam.UnitMeasure) + LabelParam.RowOffset;

    // gggg : Get Column Position
    if (LabGetNumLen(&Num, 4) != 4)
        return _ERROR;
    pFont->Column = TransformDot(Num, LabelParam.UnitMeasure) + LabelParam.ColumnOffset + pPrintCfg->ShiftDisX + ShiftXBase;

    if (ScalableFont)
    {
        // hhhh : Font Height
        Data = LabNextByte();
        if (toupper(Data) == 'P')
        {
            if (LabGetNumLen(&Num, 3) != 3)
                return _ERROR;
            Num = (FLOAT)Num * TPH_DPI / (FLOAT)72;
        }
        else
        {
            LabBackByte(Data);
            if (LabGetNumLen(&Num, 4) != 4)
                return _ERROR;
        }
        pFont->FontHeight = Num;

        // iiii : Font Width 
        Data = LabNextByte();
        if (toupper(Data) == 'P')
        {
            if (LabGetNumLen(&Num, 3) != 3)
                return _ERROR;
            Num = (FLOAT)Num * TPH_DPI / (FLOAT)72;
        }
        else
        {
            LabBackByte(Data);
            if (LabGetNumLen(&Num, 4) != 4)
                return _ERROR;
        }
        pFont->FontWidth = Num;
    }

    // jj..j : Data String
    CurRecData.Length =
        LabGetStrTerm(CurRecData.Content, sizeof(CurRecData.Content));

    SpecLabFmtCmdFunc(&CurRecData);
    return _SUCCESS;
}

STATIC INT Lab_Barcode(VOID)
{
    _LabBarcodeField *pBarcode = &CurRecHeader.Field.Barcode;
    LONG Num;

    // Expnad Barcode
    if (CurRecHeader.Type == 'W')
    {
        pBarcode->Expnad = LabNextByte();
        if (pBarcode->Expnad == '1')
            pBarcode->Expnad = LabNextByte();
    }

    // c : Wide Bar
    pBarcode->Wide = LabGetMul();

    // d : Narrow Bar
    pBarcode->Narrow = LabGetMul();

    // eee : Bar code Height
    if (LabGetNumLen(&Num, 3) != 3)
        return _ERROR;
    pBarcode->Height = TransformDot(Num, LabelParam.UnitMeasure);

    // ffff : Get Row Position
    if (LabGetNumLen(&Num, 4) != 4)
        return _ERROR;
    pBarcode->Row = TransformDot(Num, LabelParam.UnitMeasure) + LabelParam.RowOffset;

    // gggg : Get Column Position
    if (LabGetNumLen(&Num, 4) != 4)
        return _ERROR;
    pBarcode->Column = TransformDot(Num, LabelParam.UnitMeasure) + LabelParam.ColumnOffset + pPrintCfg->ShiftDisX + ShiftXBase;

    if ((CurRecHeader.Type == 'W' && pBarcode->Expnad == 'C') ||    // DataMatrix
        (CurRecHeader.Type == 'W' && pBarcode->Expnad == 'F') ||    // Aztec
        (CurRecHeader.Type == 'W' && pBarcode->Expnad == 'Z') ||    // MicroPDF417
        CurRecHeader.Type == 'U' || CurRecHeader.Type == 'Z')        // MaxiCode and PDF-417
    {
        // get Data Length
        if (LabGetNumLen(&Num, 4) != 4)
            return _ERROR;
        if (Num >= RECORD_DATA_CONTENT)
            return _ERROR;
        LabGetStrLen(CurRecData.Content, Num);
        CurRecData.Length = Num;
    }
    else
    {
        // jj..j : Data String
        CurRecData.Length =
            LabGetStrTerm(CurRecData.Content, sizeof(CurRecData.Content));
    }

    SpecLabFmtCmdFunc(&CurRecData);
    return _SUCCESS;
}

STATIC INT Lab_Graphics(VOID)
{
    _LabGraphicField *pGraphic = &CurRecHeader.Field.Graphic;
    CHAR Data;
    LONG Num;

    // c : Get Width Multiplier
    Data = LabNextByte();
    if (Data != '1')
        return _ERROR;

    // d : Get Height Multiplier
    Data = LabNextByte();
    if (Data != '1')
        return _ERROR;

    // eee : Get ID
    if (LabGetNumLen(&Num, 3) != 3)
        return _ERROR;
    pGraphic->FillPatern = Num;

    // ffff : Get Row Position
    if (LabGetNumLen(&Num, 4) != 4)
        return _ERROR;
    pGraphic->Row = TransformDot(Num, LabelParam.UnitMeasure) + LabelParam.RowOffset;

    // gggg : Get Column Position
    if (LabGetNumLen(&Num, 4) != 4)
        return _ERROR;
    pGraphic->Column = TransformDot(Num, LabelParam.UnitMeasure) + LabelParam.ColumnOffset + pPrintCfg->ShiftDisX + ShiftXBase;

    pGraphic->Type = LabNextByte();

    if (pGraphic->Type == 'L')
    {
        // hhh : horizontal width of line
        if (LabGetNumLen(&Num, 3) != 3)
            return _ERROR;
        pGraphic->Width = TransformDot(Num, LabelParam.UnitMeasure);
        pGraphic->Width = LimitWidth(pGraphic->Column, pGraphic->Width);

        // vvv : vertical height of line
        if (LabGetNumLen(&Num, 3) != 3)
            return _ERROR;
        pGraphic->Height = TransformDot(Num, LabelParam.UnitMeasure);
    }
    else if (pGraphic->Type == 'l')
    {
        // hhhh : horizontal width of line
        if (LabGetNumLen(&Num, 4) != 4)
            return _ERROR;
        pGraphic->Width = TransformDot(Num, LabelParam.UnitMeasure);
        pGraphic->Width = LimitWidth(pGraphic->Column, pGraphic->Width);

        // vvvv : vertical height of line
        if (LabGetNumLen(&Num, 4) != 4)
            return _ERROR;
        pGraphic->Height = TransformDot(Num, LabelParam.UnitMeasure);
    }
    else if (pGraphic->Type == 'B')
    {
        // hhh : horizontal width of line
        if (LabGetNumLen(&Num, 3) != 3)
            return _ERROR;
        pGraphic->Width = TransformDot(Num, LabelParam.UnitMeasure);
        pGraphic->Width = LimitWidth(pGraphic->Column, pGraphic->Width);

        // vvv : vertical height of line
        if (LabGetNumLen(&Num, 3) != 3)
            return _ERROR;
        pGraphic->Height = TransformDot(Num, LabelParam.UnitMeasure);

        // bbb : thickness of bottom and top
        if (LabGetNumLen(&Num, 3) != 3)
            return _ERROR;
        pGraphic->TopThick = TransformDot(Num, LabelParam.UnitMeasure);

        // sss : thickness of sides
        if (LabGetNumLen(&Num, 3) != 3)
            return _ERROR;
        pGraphic->SideThick = TransformDot(Num, LabelParam.UnitMeasure);
    }
    else if (pGraphic->Type == 'b')
    {
        // hhhh : horizontal width of line
        if (LabGetNumLen(&Num, 4) != 4)
            return _ERROR;
        pGraphic->Width = TransformDot(Num, LabelParam.UnitMeasure);
        pGraphic->Width = LimitWidth(pGraphic->Column, pGraphic->Width);

        // vvvv : vertical height of line
        if (LabGetNumLen(&Num, 4) != 4)
            return _ERROR;
        pGraphic->Height = TransformDot(Num, LabelParam.UnitMeasure);

        // bbbb : thickness of bottom and top
        if (LabGetNumLen(&Num, 4) != 4)
            return _ERROR;
        pGraphic->TopThick = TransformDot(Num, LabelParam.UnitMeasure);

        // ssss : thickness of sides
        if (LabGetNumLen(&Num, 4) != 4)
            return _ERROR;
        pGraphic->SideThick = TransformDot(Num, LabelParam.UnitMeasure);
    }
    else if (pGraphic->Type == 'P')
    {
        // Fixed value :001
        if (LabGetNumLen(&Num, 3) != 3)
            return _ERROR;

        // Fixed value :0001
        if (LabGetNumLen(&Num, 4) != 4)
            return _ERROR;

        pGraphic->Width  = 1;
        pGraphic->Height = 1;

        while (1)
        {
            // rrrr Row of point
            if (LabGetNumLen(&Num, 4) != 4)
                return _ERROR;
            Num = TransformDot(Num, LabelParam.UnitMeasure) + LabelParam.RowOffset;
            if (pGraphic->Height < Num - pGraphic->Row + 1)
                pGraphic->Height = Num - pGraphic->Row + 1;

            // cccc Column of point
            if (LabGetNumLen(&Num, 4) != 4)
                return _ERROR;
            Num = TransformDot(Num, LabelParam.UnitMeasure) + LabelParam.ColumnOffset + ShiftXBase;
            if (pGraphic->Width < Num - pGraphic->Column + 1)
                pGraphic->Width = Num - pGraphic->Column + 1;

            Data = LabNextByte();
            LabBackByte(Data);
            if (!isdigit(Data))
                break;
        }
    }
    else if (pGraphic->Type == 'C')
    {
        // Fixed value :001
        if (LabGetNumLen(&Num, 3) != 3)
            return _ERROR;

        // Fixed value :0001
        if (LabGetNumLen(&Num, 4) != 4)
            return _ERROR;

        // rrrr : Radius of the circle
        if (LabGetNumLen(&Num, 4) != 4)
            return _ERROR;
        pGraphic->Radius = TransformDot(Num, LabelParam.UnitMeasure);
    }
    else
        return _ERROR;

    return _SUCCESS;
}

STATIC INT Lab_Image(VOID)
{
    _LabImageField *pImage = &CurRecHeader.Field.Image;
    CHAR Data;
    LONG Num;
    INT i;

    // c : Width Multiplier
    pImage->WidthMul = LabGetMul();

    // d : Height Multiplier
    pImage->HeightMul = LabGetMul();
    
    // eee : 000
    for (i = 0; i < 3; i++)
    {
        Data = LabNextByte();
        //if (Data != '0')
        //    return _ERROR;
    }

    // ffff : Get Row Position
    if (LabGetNumLen(&Num, 4) != 4)
        return _ERROR;
    pImage->Row = TransformDot(Num, LabelParam.UnitMeasure) + LabelParam.RowOffset;

    // gggg : Get Column Position
    if (LabGetNumLen(&Num, 4) != 4)
        return _ERROR;
    pImage->Column = TransformDot(Num, LabelParam.UnitMeasure) + LabelParam.ColumnOffset + pPrintCfg->ShiftDisX + ShiftXBase;

    // jj..j : ASCII string, up to 16 characters followed by a termination character.
    if (LabGetStrTerm(pImage->Name, sizeof(pImage->Name)) > 16)
        return _ERROR;

    return _SUCCESS;
}

INT Lab_Rec(CHAR Rotation)
{
    INT Status;

    // Initial Record Data
    CurRecHeader.FormatAttrib  = LabelParam.FormatAttrib;
    CurRecHeader.BarcodeMag    = LabelParam.BarcodeMag;
    CurRecHeader.DotWidthMul   = LabelParam.DotWidthMul;
    CurRecHeader.DotHeightMul  = LabelParam.DotHeightMul;
    CurRecHeader.MirrorMode    = LabelParam.MirrorMode;
    CurRecHeader.Justification = LabelParam.Justification;
    CurRecHeader.ZeroConvert   = LabelParam.ZeroConvert;
    memcpy(CurRecHeader.SingleByteSymbolSet, LabelParam.SingleByteSymbolSet, 2);
    memcpy(CurRecHeader.DoubleByteSymbolSet, LabelParam.DoubleByteSymbolSet, 2);

    // Get Rotation
    CurRecHeader.Rotation = Rotation;

    // Get Fonts, Bar Codes, Graphics and Images    
    CurRecHeader.Type = LabNextByte();

    // Internal Font Record
    if (CurRecHeader.Type >= '0' && CurRecHeader.Type <= '8')
        Status = Lab_InternalFont();

    // Scalable Fonts, Smooth Font, and Downloaded Bit-Mapped Fonts Record
    if (CurRecHeader.Type == '9')
        Status = Lab_ExpandFont();

    // Barcode Record
    if ((CurRecHeader.Type >= 'A' && CurRecHeader.Type <= 'U') ||
        (CurRecHeader.Type >= 'a' && CurRecHeader.Type <= 'z') ||
        (CurRecHeader.Type == 'W') || (CurRecHeader.Type == 'Z'))
        Status = Lab_Barcode();

    // Graphics Record
    if (CurRecHeader.Type == 'X')
        Status = Lab_Graphics();

    // Imgae Record
    if (CurRecHeader.Type == 'Y')
        Status = Lab_Image();

    if (Status == _SUCCESS)
    {
        DrawRecord(&CurRecHeader, &CurRecData);
        SaveRecordHeader(&CurRecHeader);
        return _SUCCESS;
    }
    return _ERROR;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Set Cut By Amount
 *
 * Description:
 *        This command allows a predetermined number of labels to be printed before
 *        a cut is initiated. This feature is useful when it is necessary to print
 *        an uncut strip of labels. Between 1 and 9999 labels may be printed before
 *        a cut is made. The amount must be smaller than the quantity of labels printed.
 *
 * Syntax:
 *        :nnnn
 *
 * Where:
 *        nnnn - Is a four digit decimal number indicating the number of labels to
 *               be printed before a cut is performed.
 *
 ******************************************************************************/
INT Lab_Cut(VOID)
{
    LONG Num;

    // nnnn - Is a four digit decimal number indicating the number of labels to
    //        be printed before a cut is performed.
    if (LabGetNumLen(&Num, 4) != 4)
        return _ERROR;

    LabelParam.CutByAmount = Num;
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Set Format Attribute
 *
 * Description:
 *        This command specifies the type of format operation and remains in effect
 *        until another format command is specified or another label format has
 *        begun (<STX>L). Each label format defaults to Attribute 2 (Transparent Mode).
 *
 * Syntax:
 *        An
 *
 * Where:
 *         n - Is attribute mode 1, 2, 3, or 5; see table below.
 *            The default is 1, (XOR Mode).
 *
 ******************************************************************************/
INT Lab_A(VOID)
{
    LONG Num;

    // n - Is attribute mode 1, 2, 3, or 5; see table below. The default is 1, (XOR Mode).
    if (LabGetNumLen(&Num, 1) != 1)
        return _ERROR;

    if ((Num != 1) && (Num != 2) && (Num != 3) && (Num != 5))
        return _ERROR;

    LabelParam.FormatAttrib = Num;
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Bar Code Magnification
 *
 * Description:
 *        This command provides a mechanism to specify bar codes greater than 36
 *        dots (0-9,A-Z in the field record). The value is reset to 1 at the start
 *        of every label and stays active for the entire label or set to a new value.
 *
 * Syntax:
 *        Bnn
 *
 * Where:
 *         nn - Is a two digit decimal number indicating the magnification value.
 *
 ******************************************************************************/
INT Lab_B(VOID)
{
    LONG Num;

    // nn - Is a two digit decimal number indicating the magnification value.
    if (LabGetNumLen(&Num, 2) != 2)
        return _ERROR;

    // Supported series
    if (DatamaxModel.Display == DISPLAY_EQUIPPED)
        LabelParam.BarcodeMag = Num;

    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Set Column Offset Amount
 *
 * Description:
 *        This command allows horizontal adjustment of the point where printing
 *        begins. The printer is instructed to print label formats nnnn units to
 *        the right of the position that the format specifies. This feature is
 *        useful when a single format is to be printed on labels containing
 *        preprinted information.
 *
 * Syntax:
 *        Cnnnn
 *
 * Where:
 *         nnnn - Is a four-digit number for the column offset, inches/100 or mm/10.
 *               The printer default is 0 for offset.
 *
 ******************************************************************************/
INT Lab_C(VOID)
{
    LONG Num;

    // nnnn - Is a four-digit number for the column offset, inches/100 or mm/10.
    //        The printer default is 0 for offset.
    if (LabGetNumLen(&Num, 4) != 4)
        return _ERROR;

    LabelParam.ColumnOffset = TransformDot(Num, LabelParam.UnitMeasure);
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Set Cut By Amount
 *
 * Description:
 *        This command is the same as the ':' command except only a two-digit
 *        value can be entered. This command allows a predetermined number of
 *        labels to be printed before a cut is made. 1 to 99 labels may be printed
 *        before a cut is made.
 *
 * Syntax:
 *        cnn
 *
 * Where:
 *         nn - Is a two-digit number indicating the number of labels to be printed
 *             before a cut is made. The default is one.
 *
 ******************************************************************************/
INT Lab_c(VOID)
{
    LONG Num;

    // nn - Is a two-digit number indicating the number of labels to be printed
    //       before a cut is made. The default is one.
    if (LabGetNumLen(&Num, 2) != 2)
        return _ERROR;

    if (Num == 0)
        Num = 1;

    LabelParam.CutByAmount = Num;
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Set Dot Size Width and Height
 *
 * Description:
 *        This command is used to change the size of a printed dot, hence the
 *        print resolution  dots per inch (DPI) of the print head. By changing
 *        the height of a dot, the maximum length of a label can be increased or
 *        decreased. For the element sizes see Appendix K.
 *
 * Syntax:
 *        Dwh
 *
 * Where:
 *         w - Is Dot Width multiplier 1 or 2.
 *        h - Is Dot Height multiplier 1, 2, or 3.
 *
 ******************************************************************************/
INT Lab_D(VOID)
{
    SHORT WidthMul, HeightMul;
    LONG Num;

    // w - Is Dot Width multiplier 1 or 2.
    if (LabGetNumLen(&Num, 1) != 1)
        return _ERROR;
    if (Num < 1) Num = 1;
    if (Num > 2) Num = 2;
    WidthMul = Num;

    // h - Is Dot Height multiplier 1, 2, or 3.
    if (LabGetNumLen(&Num, 1) != 1)
        return _ERROR;
    if (Num < 1) Num = 1;
    if (Num > 3) Num = 2;
    HeightMul = Num;

    LabelParam.DotWidthMul = WidthMul;
    LabelParam.DotHeightMul = HeightMul;
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Terminate Label Formatting Mode and Print Label
 *
 * Description:
 *        This command causes the printer, when the processing Label Formatting
 *        commands, to terminate the Label Formatting Mode then generate, print,
 *        and feed a label. The label generated will be based on whatever data has
 *        been received to that point, even if no printable data has been received.
 *        Other termination commands are 'X' and 's'. Commands sent to the printer
 *        after the Terminate Label command must be of the Immediate, System-Level,
 *        or Font Download type.
 *
 * Syntax:
 *        E
 *
 * Where:
 *
 ******************************************************************************/
INT Lab_E(VOID)
{
    LabFmtCmdMod = FALSE;
    PrintLabelFormat(LabelParam.Quantity);
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Recall Printer Configuration
 *
 * Description:
 *        This command recalls a previously stored printer configuration. It is
 *        highly recommended that only one Recall Printer Configuration command
 *        be used per label, and that it be used at the beginning of the label;
 *        otherwise, unpredictable results will occur. (Printer configurations
 *        may be stored using the    Extended System-Level Commands or the printer's
 *        menu system.)
 *
 * Syntax:
 *        eName<CR>
 *
 * Where:
 *         Name - The name, up to 16 characters, of the configuration file.
 *        <CR> - 0x0d terminates the name.
 *
 ******************************************************************************/
INT Lab_e(VOID)
{
    CHAR Name[17];

    // Name - The name, up to 16 characters, of the configuration file.
    // <CR> - 0x0d terminates the name.
    if (LabGetStrTerm(Name, sizeof(Name)) > 16)
        return _ERROR;

    // Supported series
    if (DatamaxModel.Display == DISPLAY_EQUIPPED)
    {
        // ... not finish
    }

    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands :
 *        Advanced Format Attributes
 *
 * Description:
 *        These commends extend the text presentation capabilities for Scalable
 *        Fonts. The format attribute allows a set of label format records to
 *        select Bolding, Italicizing and Underlining. Additional commands allow
 *        the specification of line rotation and font changes within a label field.
 *        Reference Section 8.0, Generating Label Formats / Advanced Format
 *        Attributes for details.
 *
 * Syntax:
 *        
 * Where: 
 *
 ******************************************************************************/
INT Lab_F(VOID)
{
    // ... not finish
    return _ERROR;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Set Present Speed
 *
 * Description:
 *        This command controls the rate at which the present distance is positioned,
 *        allowing the media movement to be slowed during 'presentation' (the distance
 *        traveled after printing is completed to the label stop position). This
 *        command is used only within the context of a label format. The speed
 *        assigned is retained until another label format is received or until power
 *        is removed; if a subsequent format does not contain a present speed command
 *        then the present speed reverts to the feed speed.
 *
 * Syntax:
 *        fa
 *
 * Where:
 *        a - Is a single alpha character representing a speed, limited by the
 *            feed speed range; see Appendix L. The default is the feed speed.
 *
 ******************************************************************************/
INT Lab_f(VOID)
{
    CHAR Data;

    // a - Is a single alpha character representing a speed, limited by the
    //     feed speed range; see Appendix L. The default is the feed speed.
    Data =  LabNextByte();

    // Supported series
    if (DatamaxModel.Display == NON_DISPLAY)
    {
        if (pDmxCfg->CommSpeedCommands == 'Y')
            LabelParam.PresentSpeed = Data;
    }
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Place Data in Global Register
 *
 * Description:
 *        The G command saves the print data of a print format record in a global
 *        register (temporary storage). This data may be retrieved and copied to
 *        another record in the same label format using the special Label Formatting
 *        Command: <STX>S. Global registers are named in the order received, beginning
 *        with register A, ending at register P, and incrementing with each instance
 *        of the G command use.
 *
 * Syntax:
 *        G
 *
 * Where:
 *
 ******************************************************************************/
INT Lab_G(VOID)
{
    INT Length;

    // Place Data in Global Register
    Length = (CurRecData.Length < GLOBAL_REGISTER_CONTENT) ? CurRecData.Length : GLOBAL_REGISTER_CONTENT;
    memcpy(GlobalRegister[GlbRegNum].Content, CurRecData.Content, Length);
    GlobalRegister[GlbRegNum].Length = Length;
    if (GlbRegNum < GLOBAL_REGISTER_TOTAL)
        GlbRegNum++;

    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Enter Heat Setting
 *
 * Description:
 *        This command changes the "on time" of elements of the print head. The
 *        default setting is 10 (except in the case of printers with a menu, where
 *        the default setting can be changed through the keypad). An increase or
 *        decrease in this value results in a change of heat applied by the print
 *        head to the media, lightening or darkening the print contrast accordingly.
 *        This is helpful when using different media types, each requiring a different
 *        amount of heat to properly image the media. The host device can send this
 *        command value to correct the heat setting per the application.
 *
 * Syntax:
 *        Hnn
 *
 * Where:
 *        nn - Is a two-digit heat value (00-30)
 *
 ******************************************************************************/
INT Lab_H(VOID)
{
    LONG Num;

    // nn - Is a two-digit heat value (00-30)
    if (LabGetNumLen(&Num, 2) != 2)
        return _ERROR;

    if (Num >= 0 && Num <= 30)
    {
        if (pDmxCfg->CommHeatCommands == 'Y')
            LabelParam.HeatSetting = Num;
    }
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Justification
 *
 * Description:
 *        This command changes the printing justification.
 *
 * Syntax:
 *        Ja
 *
 * Where:
 *        a - Is a single-digit alpha character:
 *            L = left justified (default)
 *            R = right justified
 *            C = center justified
 *
 ******************************************************************************/
INT Lab_J(VOID)
{
    CHAR Data;

    Data =  LabNextByte();
    if (Data == 'L' || Data == 'R' || Data == 'C')
        LabelParam.Justification = Data;

    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Select Mirror Mode
 *
 * Description:
 *        This command instructs the printer to "mirror" all subsequent print field
 *        records. This command toggles the mirroring mode. Mirrored fields are
 *        transposed visually, as if the object is viewed in a mirror.
 *
 * Syntax:
 *        M
 *
 * Where:
 *
 ******************************************************************************/
INT Lab_M(VOID)
{
    if (LabelParam.MirrorMode == 'Y')
    {
        LabelParam.MirrorMode = 'N';
        return _SUCCESS;
    }

    LabelParam.MirrorMode = 'Y';
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Set Metric Mode
 *
 * Description:
 *        This command sets the printer to measure in metric. When this command
 *        is sent, all measurements will be interpreted as metric values, (e.g.,
 *        a column offset of 0010 will be interpreted as 1.0 mm). All printers
 *        default to Imperial (inch) mode.
 *
 * Syntax:
 *        m
 *
 * Where:
 *
 ******************************************************************************/
INT Lab_m(VOID)
{
    LabelParam.UnitMeasure = METRIC_MODE;
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Set Inch (Imperial) Mode
 *
 * Description:
 *        This command sets the printer to measure in inches. When this command
 *        is sent, all measurements will change to inches. All printers default
 *        to Imperial units. Menu selectable.
 *
 * Syntax:
 *        m
 *
 * Where:
 *
 ******************************************************************************/
INT Lab_n(VOID)
{
    LabelParam.UnitMeasure = INCH_MODE;
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Set Print Speed
 *
 * Description:
 *        This command sets a print speed for a label or batch of labels.
 *
 * Syntax:
 *        Pa
 *
 * Where:
 *        a - Is a single character representing a speed; see Appendix L for
 *            valid ranges.
 *
 ******************************************************************************/
INT Lab_P(VOID)
{
    CHAR Data;

    // a - Is a single character representing a speed; see Appendix L for valid ranges.
    Data =  LabNextByte();

    // Valid ranges
    if (Data >= DatamaxModel.PrintSpeed.Minimum &&
        Data <= DatamaxModel.PrintSpeed.Maximum)
    {
        if (pDmxCfg->CommSpeedCommands == 'Y')
            LabelParam.PrintSpeed = Data;
    }
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Set Backfeed Speed
 *
 * Description:
 *        This command, typically used in conjunction with the Cut or Peel and
 *        Present operations, controls the rate at which the labels will reverse
 *        to align to the next start of print position. The setting remains in
 *        effect until another backfeed speed command is received or until the
 *        printer is reset.
 *
 * Syntax:
 *        pa
 *
 * Where:
 *        a - Is a single alpha character representing a speed; see Appendix L
 *            for valid ranges.
 *
 ******************************************************************************/
INT Lab_p(VOID)
{
    CHAR Data;

    // a - Is a single alpha character representing a speed; see Appendix L
    //     for valid ranges.
    Data =  LabNextByte();

    // Valid ranges
    if (Data >= DatamaxModel.ReverseSpeed.Minimum &&
        Data <= DatamaxModel.ReverseSpeed.Maximum)
    {
        if (pDmxCfg->CommSpeedCommands == 'Y')
            LabelParam.BackfeedSpeed = Data;
    }
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Set Quantity of Labels to Print
 *
 * Description:
 *        This command sets the number of the label copies to be printed. A one
 *        to five digit value is allowed, if the command is delimited by a carriage
 *        return <CR>. This permits host applications to generate label quantity
 *        commands without the need to pad leading zeros. (A four-digit command
 *        value does not need to be <CR> terminated.)
 *
 * Syntax:
 *        Qnnnnn
 *
 * Where:
 *        nnnnn - Is a one to five-digit delimited value setting for the number of
 *                labels to be printed. The default value is one.
 *
 ******************************************************************************/
INT Lab_Q(VOID)
{
    LONG Num;
    CHAR Data;
    INT i;

    // nnnnn - Is a one to five-digit delimited value setting for the number of
    //         labels to be printed. The default value is one.
    Num = 0;
    i = 0;
    while (1)
    {
        Data = LabNextByte();

        if (isdigit(Data))
            Num = Num * 10 + (Data - '0');
        else if (LabIsTerminate(Data))
            break;
        else if (i == 4)
        {
            LabBackByte(Data);
            break;
        }

        if (i == 5)
        {
            LabBackByte(Data);
            return _ERROR;
        }
        i++;
    }
    if (Num == 0)
        Num = 1;

    LabelParam.Quantity = Num;
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Set Row Offset Amount
 *
 * Description:
 *        This command allows vertical adjustment of the point where printing
 *        begins. The printer is instructed to print label formats nnnn units above
 *        the position that the format specifies. This feature is useful when a
 *        single format is to be printed on labels containing preprinted information.
 *
 * Syntax:
 *        Rnnnn
 *
 * Where:
 *        nnnn - Is a four-digit number (0000-9999) for the row offset, in
 *               inches/100 or millimeters/10. The printer default is 0.
 *
 ******************************************************************************/
INT Lab_R(VOID)
{
    LONG Num;

    // nnnn - Is a four-digit number (0000-9999) for the row offset,
    //        in inches/100 or millimeters/10. The printer default is 0.
    if (LabGetNumLen(&Num, 4) != 4)
        return _ERROR;

    LabelParam.RowOffset = TransformDot(Num, LabelParam.UnitMeasure);
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Recall Stored Label Format
 *
 * Description:
 *        This command is used to retrieve label formats stored on a memory module.
 *
 * Syntax:
 *        rnn..n
 *
 * Where:
 *        nn..n - Is a label name, up to 16 characters in length.
 *
 ******************************************************************************/
INT Lab_r(VOID)
{
    CHAR Name[17];

    // nnn - Is a label name, up to 16 characters in length.
    if (LabGetStrTerm(Name, sizeof(Name)) > 16)
        return _ERROR;

    RecallLabelFormat(Name);
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Set Feed Speed
 *
 * Description:
 *        This command controls the rate at which the label is moved through
 *        non-printed areas. The setting remains unchanged unless another feed
 *        speed command is received or until the printer is reset.
 *
 * Syntax:
 *        Sa
 *
 * Where:
 *        a - Is a single alpha character representing a speed; see Appendix L
 *            for valid ranges.
 *
 ******************************************************************************/
INT Lab_S(VOID)
{
    CHAR Data;

    // a - Is a single alpha character representing a speed; see Appendix L
    //     for valid ranges.
    Data =  LabNextByte();

    // Valid ranges
    if (Data >= DatamaxModel.FeedSpeed.Minimum &&
        Data <= DatamaxModel.FeedSpeed.Maximum)
    {
        if (pDmxCfg->CommSpeedCommands == 'Y')
            LabelParam.FeedSpeed = Data;
    }
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Store Label Format in Module
 *
 * Description:
 *        This command stores a label format to a specified module as a .dlb file.
 *        Supplying the module name will store the label to that module; otherwise,
 *        using C will cause the label format to be stored in the selected default
 *        module (see <STX>X). In addition, this command terminates the Label
 *        Formatting Command.
 *
 * Syntax:
 *        sann..n
 *
 * Where:
 *        a     - Is the module designator representing a single character module
 *                name; see Appendix K.
 *        nn..n - Represents the name of the label (maximum 16 characters).
 *
 ******************************************************************************/
INT Lab_s(VOID)
{
    CHAR ModuleName;
    CHAR Name[17];

    // a - Is the module designator representing a single character module name;
    //     see Appendix K.
    ModuleName = LabNextByte();

    // nn..n - Is a label name, up to 16 characters in length.
    if (LabGetStrTerm(Name, sizeof(Name)) > 16)
        return _ERROR;

    StoreLabelFormat(ModuleName, Name);
    LabFmtCmdMod = FALSE;
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Set Field Data Line Terminator
 *
 * Description:
 *        This command, intended for use with record types that accept binary data
 *        (e.g., PDF417), allows special binary control codes (e.g., a carriage
 *        return) to be embedded in the printed data by setting an alternate data
 *        line terminator. It remains valid only for the next format record, then
 *        the terminator defaults back to the carriage return.
 *
 * Syntax:
 *        Tnn
 *
 * Where:
 *        nn - Is an ASCII two-character representation of a HEX code to be used
 *             for the end of data terminator.
 *
 ******************************************************************************/
INT Lab_T(VOID)
{
    CHAR Data;

    if (!LabGetHex(&Data))
        return _ERROR;

    LabelParam.Terminate = Data;
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Mark Previous Field as a String Replacement Field
 *
 * Description:
 *        This command controls the way replacement data is formatted. Specifying
 *        a field as a string replacement for dynamic fields, and not for static
 *        fields, will optimize label throughput. See the <STX>U command.
 *
 * Syntax:
 *        U
 *
 * Where:
 *
 ******************************************************************************/
INT Lab_U(VOID)
{
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Terminate Label Formatting Mode
 *
 * Description:
 *        This command causes the printer, when in label formatting mode, to
 *        immediately switch to the system command mode and generate a label format
 *        based on the data received at that point. However, unlike the 'E' command,
 *        it will not print a label. (Other termination commands are the 'E' and 's'.)
 *
 * Syntax:
 *        X
 *
 * Where:
 *
 ******************************************************************************/
INT Lab_X(VOID)
{
    LabFmtCmdMod = FALSE;
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Select Font Symbol Set
 *
 * Description:
 *        This command, like the <STX>y, selects the scalable font symbol set. The
 *        selected symbol set remains active until another symbol set is selected;
 *        see the <STX>y command for details.
 *
 * Syntax:
 *        ySxx
 *
 * Where:
 *
 *        S  - Byte-size designation; see Appendix H:
 *             S = Single byte symbol sets.
 *             U = Double byte symbol sets.
 *        xx - Symbol set selection.
 *
 ******************************************************************************/
INT Lab_y(VOID)
{
    CHAR ByteSize;
    CHAR SymbolSet[3];

    // S  - Byte-size designation
    ByteSize = LabNextByte();

    // xx - Symbol set selection
    if (LabGetStrTerm(SymbolSet, sizeof(SymbolSet)) != 2)
        return _ERROR;

    if (pDmxCfg->DisableSymbolSet == 'N')
    {
        if (ByteSize == 'S' && DescribeSymbolSet(ByteSize, SymbolSet))
            memcpy(LabelParam.SingleByteSymbolSet, SymbolSet, 2);
        if (ByteSize == 'U' && DescribeSymbolSet(ByteSize, SymbolSet))
            memcpy(LabelParam.DoubleByteSymbolSet, SymbolSet, 2);
    }
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Zero (O) Conversion to "0"
 *
 * Description:
 *        This command removes the slash zero in fonts 0 to 8, and in the human
 *        readable field (if any) of the bar codes A to Z. The command applies
 *        only to format records containing those fonts and bar codes, and is
 *        effective only for the label format in which it appears.
 *
 * Syntax:
 *        z
 *
 * Where:
 *
 ******************************************************************************/
INT Lab_z(VOID)
{
    LabelParam.ZeroConvert = 'Y';
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Make Last Field Entered Increment Numeric(Alphanumeric)(Hexadecimal)
 *
 * Description:
 *        This command, useful in printing sequenced labels, causes the printer to
 *        automatically increment a field on the labels in a batch. The numeric
 *        data in the field will increment by the value assigned after the plus
 *        sign (+) each time a label is produced (or the greater than symbol [>]
 *        can be substituted to make the field increment alphabetically, or the
 *        left parenthesis [(] can be substituted to make the field increment
 *        hexadecimal data*). This command is effective only on the label format
 *        record that it follows, and is intended to be used with the Q, <STX>E,
 *        or <STX>G commands.
 *
 * Syntax:
 *        *pii
 *
 * Where:
 *        *  - Is + for numeric increment, > for alphanumeric increment, or
 *             ( for hexadecimal increment.
 *        p  - Is the fill character for the left-hand character of the field.
 *        ii - Is the amount by which to increment the field.
 *
 ******************************************************************************/
INT Lab_IncNum(VOID)
{
    CHAR FillChar;
    LONG Amount = 1;

    // p - Is the fill character for the left-hand character of the field.
    FillChar = LabNextByte();
    // ii - Is the amount by which to increment the field.
    if (!LabGetNumTerm(&Amount, 10))
        return _ERROR;

    SaveLabelCounter('+', FillChar, Amount, &CurRecData);
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Make Last Field Entered Increment Numeric(Alphanumeric)(Hexadecimal)
 *
 * Description:
 *        This command, useful in printing sequenced labels, causes the printer to
 *        automatically increment a field on the labels in a batch. The numeric
 *        data in the field will increment by the value assigned after the plus
 *        sign (+) each time a label is produced (or the greater than symbol [>]
 *        can be substituted to make the field increment alphabetically, or the
 *        left parenthesis [(] can be substituted to make the field increment
 *        hexadecimal data*). This command is effective only on the label format
 *        record that it follows, and is intended to be used with the Q, <STX>E,
 *        or <STX>G commands.
 *
 * Syntax:
 *        *pii
 *
 * Where:
 *        *  - Is + for numeric increment, > for alphanumeric increment, or
 *             ( for hexadecimal increment.
 *        p  - Is the fill character for the left-hand character of the field.
 *        ii - Is the amount by which to increment the field.
 *
 ******************************************************************************/
INT Lab_IncAlpha(VOID)
{
    CHAR FillChar;
    LONG Amount = 1;

    // p - Is the fill character for the left-hand character of the field.
    FillChar = LabNextByte();
    // ii - Is the amount by which to increment the field.
    if (!LabGetNumTerm(&Amount, 10))
        return _ERROR;

    SaveLabelCounter('>', FillChar, Amount, &CurRecData);
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Make Last Field Entered Increment Numeric(Alphanumeric)(Hexadecimal)
 *
 * Description:
 *        This command, useful in printing sequenced labels, causes the printer to
 *        automatically increment a field on the labels in a batch. The numeric
 *        data in the field will increment by the value assigned after the plus
 *        sign (+) each time a label is produced (or the greater than symbol [>]
 *        can be substituted to make the field increment alphabetically, or the
 *        left parenthesis [(] can be substituted to make the field increment
 *        hexadecimal data*). This command is effective only on the label format
 *        record that it follows, and is intended to be used with the Q, <STX>E,
 *        or <STX>G commands.
 *
 * Syntax:
 *        *pii
 *
 * Where:
 *        *  - Is + for numeric increment, > for alphanumeric increment, or
 *             ( for hexadecimal increment.
 *        p  - Is the fill character for the left-hand character of the field.
 *        ii - Is the amount by which to increment the field.
 *
 ******************************************************************************/
INT Lab_IncHex(VOID)
{
    CHAR FillChar;
    LONG Amount = 1;

    // p - Is the fill character for the left-hand character of the field.
    FillChar = LabNextByte();
    // ii - Is the amount by which to increment the field.
    if (!LabGetNumTerm(&Amount, 10))
        return _ERROR;

    SaveLabelCounter('(', FillChar, Amount, &CurRecData);
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Make Last Field Entered Decrement Numeric (Alphanumeric)(Hexadecimal)
 *
 * Description:
 *        This command, useful in printing sequenced labels, causes the printer to
 *        automatically decrement a field on the labels in a batch. The numeric
 *        data in the field will decrement by the value assigned after the minus
 *        (-) sign each time a label is produced (or the less than character [<]
 *        can be substituted to make the field decrement alphabetically, or the
 *        right parenthesis [ )] can be substituted to make the field decrement
 *        hexadecimal data*). This command is effective only on the label format
 *        record that it follows, and is intended to be used with the Q, <STX>E
 *        or <STX>G commands.
 *
 * Syntax:
 *        *pii
 *
 * Where:
 *        *  - Is  for numeric decrement, < for alphanumeric decrement, or
 *             ) for hexadecimal decrement.
 *        p  - Is the fill character for the leftmost character of the field.
 *        ii - Is the amount by which to decrement the field.
 *
 ******************************************************************************/
INT Lab_DecNum(VOID)
{
    CHAR FillChar;
    LONG Amount = 1;

    // p - Is the fill character for the left-hand character of the field.
    FillChar = LabNextByte();
    // ii - Is the amount by which to increment the field.
    if (!LabGetNumTerm(&Amount, 10))
        return _ERROR;

    SaveLabelCounter('-', FillChar, Amount, &CurRecData);
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Make Last Field Entered Decrement Numeric (Alphanumeric)(Hexadecimal)
 *
 * Description:
 *        This command, useful in printing sequenced labels, causes the printer to
 *        automatically decrement a field on the labels in a batch. The numeric
 *        data in the field will decrement by the value assigned after the minus
 *        (-) sign each time a label is produced (or the less than character [<]
 *        can be substituted to make the field decrement alphabetically, or the
 *        right parenthesis [ )] can be substituted to make the field decrement
 *        hexadecimal data*). This command is effective only on the label format
 *        record that it follows, and is intended to be used with the Q, <STX>E
 *        or <STX>G commands.
 *
 * Syntax:
 *        *pii
 *
 * Where:
 *        *  - Is  for numeric decrement, < for alphanumeric decrement, or
 *             ) for hexadecimal decrement.
 *        p  - Is the fill character for the leftmost character of the field.
 *        ii - Is the amount by which to decrement the field.
 *
 ******************************************************************************/
INT Lab_DecAlpha(VOID)
{
    CHAR FillChar;
    LONG Amount = 1;

    // p - Is the fill character for the left-hand character of the field.
    FillChar = LabNextByte();
    // ii - Is the amount by which to increment the field.
    if (!LabGetNumTerm(&Amount, 10))
        return _ERROR;

    SaveLabelCounter('<', FillChar, Amount, &CurRecData);
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Make Last Field Entered Decrement Numeric (Alphanumeric)(Hexadecimal)
 *
 * Description:
 *        This command, useful in printing sequenced labels, causes the printer to
 *        automatically decrement a field on the labels in a batch. The numeric
 *        data in the field will decrement by the value assigned after the minus
 *        (-) sign each time a label is produced (or the less than character [<]
 *        can be substituted to make the field decrement alphabetically, or the
 *        right parenthesis [ )] can be substituted to make the field decrement
 *        hexadecimal data*). This command is effective only on the label format
 *        record that it follows, and is intended to be used with the Q, <STX>E
 *        or <STX>G commands.
 *
 * Syntax:
 *        *pii
 *
 * Where:
 *        *  - Is  for numeric decrement, < for alphanumeric decrement, or
 *             ) for hexadecimal decrement.
 *        p  - Is the fill character for the leftmost character of the field.
 *        ii - Is the amount by which to decrement the field.
 *
 ******************************************************************************/
INT Lab_DecHex(VOID)
{
    CHAR FillChar;
    LONG Amount = 1;

    // p - Is the fill character for the left-hand character of the field.
    FillChar = LabNextByte();
    // ii - Is the amount by which to increment the field.
    if (!LabGetNumTerm(&Amount, 10))
        return _ERROR;

    SaveLabelCounter(')', FillChar, Amount, &CurRecData);
    return _SUCCESS;
}

/******************************************************************************
 *
 * DPL Commands:
 *        Set Count By Amount
 *
 * Description:
 *        This command allows applications using the increment / decrement field
 *        command to print more than one label with the same field value before
 *        the field data is updated. All printers default to 1.
 *
 * Syntax:
 *        ^nn
 *
 * Where:
 *        ^  - May be 0x55 or 0x40; see Control Codes.
 *        nn - Is a two-digit value that specifies the number of labels to be
 *             generated before incrementing (or decrementing) the field value.
 *
 ******************************************************************************/
INT Lab_Cnt(VOID)
{
    LONG Num;

    // nn - Is a two-digit value that specifies the number of labels to be
    //      generated before incrementing (or decrementing) the field value.
    if (LabGetNumLen(&Num, 2) != 2)
        return _ERROR;
    if (Num == 0)
        Num = 1;

    LabelParam.CounterByAmount = Num;
    return _SUCCESS;
}

#endif

  • 14
    点赞
  • 18
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值