⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 driver2.c

📁 用汇编语言或高级语言编写的源程序翻译成机器可执行的机器语言程序的工具称为“语言处理程序.
💻 C
📖 第 1 页 / 共 3 页
字号:

/*----------------------------------------------------------------------+
 |  DRIVER2.C - FoxPro general printer driver (C version).				|
 |                                                                      |
 |  Copyright (c) 1991, Fox Holdings, Inc.                              |
 |  Fox Software System's Group                                         |
 |  134 W. South Boundary                                               |
 |  Perrysburg, Ohio  43551                                             |
 +----------------------------------------------------------------------*/


#include <pro_ext.h>


#define BADHANDLE       0                       // Not a handle.
typedef unsigned short	USHORT;

#define LoWord(x)       ((USHORT)x)
#define HiWord(x)       ((USHORT)((unsigned long)(x)>>16))
#define P_BOLD          1                       // Bold attrib.
#define P_ITALIC        (1<<1)                  // Italic attrib.
#define P_UNDERLINE     (1<<2)                  // Underline attrib.
#define P_RAISED        (1<<3)                  // Superscript attrib.
#define P_LOWERED       (1<<4)                  // Subscript. attrib.

#define NUMWIDTH		20
#define PDALLOCSIZE		1024					// Allocation size

#define PDELEMENTS      52                      // Number of elements in _PDPARMS
#define CAPTUREBUFFSIZE 64
#define	TIMESLOADED		43						// Array position of the number times we're loaded

static Locator g_pdparms;                       // The locator of _PDPARMS
static MHANDLE g_pdElement[PDELEMENTS];         // Our local copy of _PDPARMS
static int     g_pdELen[PDELEMENTS];            // Length of individual elements
static long    g_docwidth, g_curlin;            // Document width, current line #
static TEXT    g_sendff = FALSE;                // Flag for sending a Form Feed
static TEXT    g_bop = FALSE;                   // Beginning of a page
static MHANDLE g_capture;                       // capture buffer
static int     g_caplen;                        // capture buffer length
static double  g_dots_col=0;					// dots per column
static int     g_curcolumn=0;                   // current column location
static int	   g_graph_width=0;                 // width of a graphic character
static TEXT    g_viadots=FALSE;                 // flag to show if we move by dots
												// or by columns.


/*----------------------------------------------------------------------+
 |  _fltused() is a null function so that WATCOM does not link in       |
 |  unneeded code into our library.  If there is ever a need to add     |
 |  floating point functions like sprintf() and vsprintf() this routine |
 |  should be removed.                                                  |
 +----------------------------------------------------------------------*/
void _fltused()
{

}


/*----------------------------------------------------------------------+
 |  power() will return the base parameter raised to the nth.           |
 +----------------------------------------------------------------------*/
static long power(int base, int n)
{
    long	res=base;

    if (n < 1)
        return 1;

    while (--n)
        res *= base;

    return res;
}


/*----------------------------------------------------------------------+
 |  This routine will do the xBase equivalent of a LTRIM() and return   |
 |  the length of the trimmed string.                                   |
 +----------------------------------------------------------------------*/
static long LeftTrim(Value FAR *val)
{
	TEXT	FAR	*buff;
	int		i;


	_HLock(val->ev_handle);
	buff = _HandToPtr(val->ev_handle);

	for (i=0; i <= val->ev_length && buff[i] == 0x20; i++);

	_MemMove(buff, buff+i, val->ev_length - i);
	_HUnLock(val->ev_handle);
	_SetHandSize(val->ev_handle, val->ev_length - i);

	val->ev_length  -= i;
	return (val->ev_length);

}


/*----------------------------------------------------------------------+
 |  This routine takes a long integer and returns the string equivalent |
 |  of it.                                                              |
 +----------------------------------------------------------------------*/
static NumToStr(long num, TEXT FAR *result)
{
    TEXT	buff[10], *firstch;
    long	temp;

    buff[9] = 0;
    firstch  = buff+9;

    do
    {
	temp = num / 10;
        *--firstch = (num - temp * 10) + '0';   // convert the nibble to ASCII
	num = temp;
    }
    while (num && (firstch > buff));

    _StrCpy(result, firstch);                   // copy the string into result.

    return _StrLen(result);
}

/*----------------------------------------------------------------------+
 |  RealNumToStr() will convert the double real number to a character   |
 |  string and return it in result.                                     |
 +----------------------------------------------------------------------*/
static int RealNumToStr(double d, TEXT FAR *result, int decpl)
{
    TEXT	buff[NUMWIDTH * 2];
    long	lval;
    int		reslen, i;


    lval = d * power(10, decpl) + 0.5001;

    NumToStr(lval, buff);
    reslen = _StrLen(buff);

    if (reslen <= decpl)
    {
        _StrCpy(result, "0.");

	i = decpl - reslen;
	_MemFill(result + 2, '0', i);

	_StrCpy(result + 2 + i, buff);
    }
    else
    {
	i = reslen - decpl;
	_MemMove(result, buff, i);

	if (decpl)
	{
	    result[i] = '.';
	    _MemMove(result + i + 1, buff + i, decpl);

	    i += (decpl + 1);
	}

	result[i] = 0;
    }

    return _StrLen(result);
}

/*----------------------------------------------------------------------+
 |  StrToNum will convert the string passed in cp into a number.        |
 +----------------------------------------------------------------------*/
static double StrToNum(TEXT FAR *cp, int numlen)
{
    double	resnum = 0.0;
    int		j;

    for(; *cp == ' '; cp++, numlen--);

    for (; isdigit(*cp) && numlen; cp++, numlen--)
	resnum = (resnum * 10) + (*cp - '0');

    if ((*cp == '.') && numlen--)
    {
        cp++;

	for (j=10 ; isdigit(*cp) && numlen; cp++, numlen--, j *= 10)
	    resnum += ((*cp - '0') / j);
    }

    return resnum;
}


/*----------------------------------------------------------------------+
 |  Retrieve all values from _pdparms directly (except for 'C' type).   |
 +----------------------------------------------------------------------*/
static pdVal(int element, TEXT type, Value FAR *val)
{
    Locator	loc;

    loc = g_pdparms;                            // The locator of _PDPARMS.
    loc.l_sub1 = element;

    if (_Load(&loc, val) != 0)                  // Load the element
	return NO;

    if (val->ev_type != type)                   // Check if it's the type we want
    {
        if ((val->ev_type == 'C') && (val->ev_handle != BADHANDLE))
	{
            _FreeHand(val->ev_handle);          // If it's a Character type, then
            val->ev_handle = BADHANDLE;         // free the handle.
	}

	return NO;
    }

    return YES;
}


/*----------------------------------------------------------------------+
 |  Retrieve the numeric values from _PDPARMS                           |
 +----------------------------------------------------------------------*/
static double pdNval(int element)
{
    Value	val;
    double	retval;

    if (pdVal(element, 'N', &val) || pdVal(element, 'I', &val))
    {
        retval = (val.ev_type == 'N') ? val.ev_real : val.ev_long;
	return (retval);
    }

    return (double)0.0;
}

/*----------------------------------------------------------------------+
 |  Retrieve the character values from _PDPARMS                         |
 +----------------------------------------------------------------------*/
static pdCval(int element, TEXT FAR *dest, int FAR *destlen)
{
    int		len;

    --element;                          // decrement element for our copy

    len = g_pdELen[element];            // get the length of the element

    if (len == 0)                       // if the length is zero, it isn't good
        return;

                                        // move the element into the destination
    _MemMove(dest + *destlen,
             _HandToPtr(g_pdElement[element]),
	     len);

    *destlen += len;
}


/*----------------------------------------------------------------------+
 |  Store a numeric value in _PDPARMS                                   |
 +----------------------------------------------------------------------*/
static void pdStoreNVal(int element, long nval)
{
    Locator	loc;
    Value	val;

    val.ev_type = 'I';                  // Setup the Value Structure for the _Store
    val.ev_width = 10;
    val.ev_long = nval;
    val.ev_handle = BADHANDLE;

    loc = g_pdparms;                    // Specify what element we want to use
    loc.l_sub1 = element;

    _Store(&loc, &val);                 // Store the value into _PDPARMS.
}

/*----------------------------------------------------------------------+
 |  Store a numeric real value in _PDPARMS                              |
 +----------------------------------------------------------------------*/
static void pdStoreRVal(int element, double nval)
{
    Locator	loc;
    Value	val;

    val.ev_type = 'N';                  // Setup the Value Structure for the _Store
    val.ev_width = 10;
    val.ev_real = nval;
	val.ev_length = 2;
    val.ev_handle = BADHANDLE;

    loc = g_pdparms;                    // Specify what element we want to use
    loc.l_sub1 = element;

    _Store(&loc, &val);                 // Store the value into _PDPARMS.
}



static loadPDParms(int start, int end)
{
    int         element;                // the element we are addressing
    int         errcode=0;              // internal error code
    Locator     loc;                    // a locator to _PDPARMS
    Value       val;                    // the value structure for _PDPARMS

    /*  Load in the values of each element of _PDPARMS in our local
        copy.                                                       */

    for (element=start; (element < end) && (element < PDELEMENTS); element++)
    {
        loc = g_pdparms;
        loc.l_sub1 = element+1;             // Increment the element # for xBase

        if (errcode = _Load(&loc, &val))    // Load the value
            break;

        //  Check the type of the element is not character or we don't have a handle
        if ((val.ev_type != 'C') || (val.ev_handle == BADHANDLE))
        {
            g_pdElement[element] = BADHANDLE;
            g_pdELen[element]  = 0;
        }
        else                // otherwise, it's a character type
        {
            g_pdElement[element] = val.ev_handle;           // save the handle and
            g_pdELen[element]  = val.ev_length;             // and the length
        }
    }

    return (-errcode);               // Set a flag if there was an error

}

/*----------------------------------------------------------------------+
 |  This routine is called on loading of the api printer driver.  It    |
 |  checks to see if _PDPARMS has been created and if so, it then loads |
 |  in the values of the elements of the array into an internal copy.   |
 |  This is done once, so any changes made to the xBase version of      |
 |  _PDPARMS after this, will not take any effect on our copy.  This is |
 |  done so we don't continually have to call back to FoxPro to obtain  |
 |  the value of a certain element in _PDPARMS array.                   |
 +----------------------------------------------------------------------*/
FAR pdonload()
{
    Locator     loc;                    // a locator to _PDPARMS
    int         errcode;                // internal error code
    NTI         nti;                    // the Name Table Index of _PDPARMS
    Value       val;                    // the value structure for _PDPARMS
    int         element;                // the element we are addressing
    TEXT        varflag = FALSE,
                create = FALSE;
    FPFI        load_func;
    TEXT        load_elem[20];
    int         load_len=0;
    long        chksum;

    //  check if there is a Name Table Index
    if ((nti = _NameTableIndex("_PDPARMS")) >= 0)
    {
        if (_FindVar(nti, -1, &loc))            // Load the Locator for _PDPARMS
	{
            if (loc.l_subs == 0)                // If there aren't any subscripts,
                varflag = TRUE;                 // flag that there is an error with it
	    else
	    {
                g_pdparms = loc;

                varflag = loadPDParms(0, loc.l_sub1);


/*----------------------------------------------------------------------+
 |  The following line tells us how many times this api routine has been|
 |  loaded.  This is needed in case a user loads a printer drivers and  |
 |  thus the api, and then loads the api routine via the SET LIBRARY TO |
 |  command.  Without this, we would release the local copy of _PDPARMS |
 |  (which rely heavily upon.)                                          |
 +----------------------------------------------------------------------*/

				if (loc.l_subs >= TIMESLOADED)
                	pdStoreNVal(TIMESLOADED, pdNval(TIMESLOADED) + 1);
				else
					varflag = TRUE;

/*----------------------------------------------------------------------+
 |  The following code was added as and enhancement request.  It stores |
 |  the address of the procedure loadPDParms and a four byte checksum   |
 |  of this address into the last element of _PDPARMS.  If the user     |
 |  wants to update the api's internal copy of _PDPARMS, it can now     |
 |  be done by loading the library PDUDATE.PLB.                         |
 |                                                                      |
 |  Note:  The address of loadPDParms() function must be placed in the  |
 |  last element in the _PDPARMS array in order for PDUPDATE to work.   |
 +----------------------------------------------------------------------*/

                load_func = loadPDParms;
                _MemMove(load_elem, &load_func, 4);
                load_len = 4;

                chksum = ~(long) load_func;
                _MemMove(load_elem + load_len, &chksum, 4);
                load_len +=4;

                val.ev_type = 'C';
                val.ev_handle = _AllocHand(load_len);

                if (val.ev_handle != BADHANDLE)
                {
                    val.ev_length = load_len;
                    _MemMove(_HandToPtr(val.ev_handle), load_elem, load_len);
                }
                else
                    val.ev_length = 0;


                if ((loc.l_sub1 = _ALen(nti, AL_ELEMENTS)) >= 0)
                    _Store(&loc, &val);


	    }
	}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -