diff options
author | Kaleb Keithley <kaleb@freedesktop.org> | 2003-11-14 15:54:54 +0000 |
---|---|---|
committer | Kaleb Keithley <kaleb@freedesktop.org> | 2003-11-14 15:54:54 +0000 |
commit | ded6147bfb5d75ff1e67c858040a628b61bc17d1 (patch) | |
tree | 82355105e93cdac89ef7d987424351c77545faf0 /Xprint | |
parent | cb6ef07bf01e72d1a6e6e83ceb7f76d6534da941 (diff) |
R6.6 is the Xorg base-line
Diffstat (limited to 'Xprint')
62 files changed, 28418 insertions, 0 deletions
diff --git a/Xprint/AttrValid.c b/Xprint/AttrValid.c new file mode 100644 index 000000000..1303701af --- /dev/null +++ b/Xprint/AttrValid.c @@ -0,0 +1,702 @@ +/* $Xorg: AttrValid.c,v 1.4 2001/03/14 18:43:17 pookie Exp $ */ +/* +(c) Copyright 1996 Hewlett-Packard Company +(c) Copyright 1996 International Business Machines Corp. +(c) Copyright 1996 Sun Microsystems, Inc. +(c) Copyright 1996 Novell, Inc. +(c) Copyright 1996 Digital Equipment Corp. +(c) Copyright 1996 Fujitsu Limited +(c) Copyright 1996 Hitachi, Ltd. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the names of the copyright holders shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from said +copyright holders. +*/ +#include <scrnintstr.h> + +#define _XP_PRINT_SERVER_ +#include "extensions/Printstr.h" +#undef _XP_PRINT_SERVER_ + +#include "AttrValid.h" + +/* + * default medium-source-sizes supported = na-letter w/.25" margins + */ +static XpOidMediumDiscreteSize DefaultMediumSize = { + xpoid_val_medium_size_na_letter, xFalse, {6.35, 209.55, 6.35, 273.05} +}; +static XpOidMediumDiscreteSizeList DefaultMediumSizeList = { + &DefaultMediumSize, 1 +}; +static XpOidMediumSourceSize DefaultMediumSourceSize = { + xpoid_unspecified, XpOidMediumSS_DISCRETE, &DefaultMediumSizeList +}; +static XpOidMediumSS DefaultMediumSS = { + &DefaultMediumSourceSize, 1 +}; + +/* + * if 'valid_oid_list' is NULL any oid found is considered valid + */ +XpOid +XpGetOidAttr(XpContextPtr pContext, + XPAttributes pool, + XpOid oid, + const XpOidList* valid_oid_list) +{ + XpOid value_oid; + + value_oid = XpOidFromString(XpGetStringAttr(pContext, pool, oid)); + if((const XpOidList*)NULL == valid_oid_list + || + XpOidListHasOid(valid_oid_list, value_oid)) + { + return value_oid; + } + else + { + return xpoid_none; + } +} + +void +XpPutOidAttr(XpContextPtr pContext, + XPAttributes pool, + XpOid oid, + XpOid value_oid) +{ + XpPutStringAttr(pContext, pool, oid, XpOidString(value_oid)); +} + +void +XpValidateOidAttr(XpContextPtr pContext, + XPAttributes pool, + XpOid oid, + const XpOidList* valid_oids, + XpOid default_oid) +{ + XpOid value_oid; + value_oid = XpGetOidAttr(pContext, pool, oid, valid_oids); + XpPutOidAttr(pContext, pool, oid, + value_oid == xpoid_none ? default_oid : value_oid); +} + +/* + * if 'valid_card_list' is NULL any cardinal found is considered valid + */ +unsigned long +XpGetCardAttr(XpContextPtr pContext, + XPAttributes pool, + XpOid oid, + const XpOidCardList* valid_card_list) +{ + unsigned long value_card; + + if(XpOidParseUnsignedValue(XpGetStringAttr(pContext, pool, oid), + (const char**)NULL, + &value_card)) + { + if((const XpOidCardList*)NULL == valid_card_list + || + XpOidCardListHasCard(valid_card_list, value_card)) + { + return value_card; + } + } + return 0; +} + +void +XpPutCardAttr(XpContextPtr pContext, + XPAttributes pool, + XpOid oid, + unsigned long value_card) +{ + if(value_card > 0) + { + char value_out[16]; + sprintf(value_out, "%lu", value_card); + XpPutStringAttr(pContext, pool, oid, value_out); + } + else + XpPutStringAttr(pContext, pool, oid, (const char*)NULL); +} + +void +XpValidateCardAttr(XpContextPtr pContext, + XPAttributes pool, + XpOid oid, + const XpOidCardList* valid_cards, + unsigned long default_card) +{ + unsigned long value_card; + value_card = XpGetCardAttr(pContext, pool, oid, valid_cards); + XpPutCardAttr(pContext, pool, oid, + value_card == 0 ? default_card : value_card); +} + +XpOidList* +XpGetListAttr(XpContextPtr pContext, + XPAttributes pool, + XpOid oid, + const XpOidList* valid_oid_list) +{ + return XpOidListNew(XpGetStringAttr(pContext, pool, oid), valid_oid_list); +} + +void +XpPutListAttr(XpContextPtr pContext, + XPAttributes pool, + XpOid oid, + const XpOidList* list) +{ + char* value_out; + + value_out = XpOidListString(list); + XpPutStringAttr(pContext, pool, oid, value_out); + XpOidFree(value_out); +} + +void +XpValidateListAttr(XpContextPtr pContext, + XPAttributes pool, + XpOid oid, + const XpOidList* valid_oids, + const XpOidList* default_oids) +{ + XpOidList* list = XpGetListAttr(pContext, pool, oid, valid_oids); + if(XpOidListCount(list) == 0) + XpPutListAttr(pContext, pool, oid, default_oids); + else + XpPutListAttr(pContext, pool, oid, list); + XpOidListDelete(list); +} + +XpOidCardList* +XpGetCardListAttr(XpContextPtr pContext, + XPAttributes pool, + XpOid oid, + const XpOidCardList* valid_card_list) +{ + return XpOidCardListNew(XpGetStringAttr(pContext, pool, oid), + valid_card_list); +} + +void +XpPutCardListAttr(XpContextPtr pContext, + XPAttributes pool, + XpOid oid, + const XpOidCardList* list) +{ + char* value_out; + + value_out = XpOidCardListString(list); + XpPutStringAttr(pContext, pool, oid, value_out); + XpOidFree(value_out); +} + +void +XpValidateCardListAttr(XpContextPtr pContext, + XPAttributes pool, + XpOid oid, + const XpOidCardList* valid_cards, + const XpOidCardList* default_cards) +{ + XpOidCardList* list = XpGetCardListAttr(pContext, pool, oid, valid_cards); + if(XpOidCardListCount(list) == 0 && (XpOidCardList*)NULL != default_cards) + XpPutCardListAttr(pContext, pool, oid, default_cards); + else + XpPutCardListAttr(pContext, pool, oid, list); + XpOidCardListDelete(list); +} + +XpOidDocFmtList* +XpGetDocFmtListAttr(XpContextPtr pContext, + XPAttributes pool, + XpOid oid, + const XpOidDocFmtList* valid_fmt_list) +{ + return XpOidDocFmtListNew(XpGetStringAttr(pContext, pool, oid), + valid_fmt_list); +} + +void +XpPutDocFmtListAttr(XpContextPtr pContext, + XPAttributes pool, + XpOid oid, + const XpOidDocFmtList* list) +{ + char* value_out; + + value_out = XpOidDocFmtListString(list); + XpPutStringAttr(pContext, pool, oid, value_out); + XpOidFree(value_out); +} + +void +XpValidateDocFmtListAttr(XpContextPtr pContext, + XPAttributes pool, + XpOid oid, + const XpOidDocFmtList* valid_fmts, + const XpOidDocFmtList* default_fmts) +{ + XpOidDocFmtList* list; + + list = XpGetDocFmtListAttr(pContext, pool, oid, valid_fmts); + if(XpOidDocFmtListCount(list) == 0 + && + (XpOidDocFmtList*)NULL != default_fmts) + { + XpPutDocFmtListAttr(pContext, pool, oid, default_fmts); + } + else + { + XpPutDocFmtListAttr(pContext, pool, oid, list); + } + XpOidDocFmtListDelete(list); +} + +XpOidMediumSS* +XpGetMediumSSAttr(XpContextPtr pContext, + XPAttributes pool, + XpOid oid, + const XpOidList* valid_trays, + const XpOidList* valid_sizes) +{ + return XpOidMediumSSNew(XpGetStringAttr(pContext, pool, oid), + valid_trays, valid_sizes); +} + +void +XpPutMediumSSAttr(XpContextPtr pContext, + XPAttributes pool, + XpOid oid, + const XpOidMediumSS* msss) +{ + char* value_out; + + value_out = XpOidMediumSSString(msss); + XpPutStringAttr(pContext, pool, oid, value_out); + XpOidFree(value_out); +} + +const XpOidMediumSS* +XpGetDefaultMediumSS() +{ + return &DefaultMediumSS; +} + +XpOidTrayMediumList* +XpGetTrayMediumListAttr(XpContextPtr pContext, + XPAttributes pool, + XpOid oid, + const XpOidList* valid_trays, + const XpOidMediumSS* msss) +{ + return XpOidTrayMediumListNew(XpGetStringAttr(pContext, pool, oid), + valid_trays, msss); +} + +void +XpPutTrayMediumListAttr(XpContextPtr pContext, + XPAttributes pool, + XpOid oid, + const XpOidTrayMediumList* tm) +{ + char* value_out; + + value_out = XpOidTrayMediumListString(tm); + XpPutStringAttr(pContext, pool, oid, value_out); + XpOidFree(value_out); +} + +void +XpValidatePrinterMediaAttrs(XpContextPtr pContext, + const XpOidList* valid_trays, + const XpOidList* valid_sizes) +{ + const XpOidMediumSS* msss; + XpOidMediumSS* pool_msss; + XpOidTrayMediumList* tm; + + pool_msss = XpGetMediumSSAttr(pContext, XPPrinterAttr, + xpoid_att_medium_source_sizes_supported, + valid_trays, valid_sizes); + if(0 == XpOidMediumSSCount(pool_msss)) + msss = XpGetDefaultMediumSS(); + else + msss = pool_msss; + XpPutMediumSSAttr(pContext, XPPrinterAttr, + xpoid_att_medium_source_sizes_supported, msss); + + tm = XpGetTrayMediumListAttr(pContext, XPPrinterAttr, + xpoid_att_input_trays_medium, + valid_trays, msss); + XpPutTrayMediumListAttr(pContext, XPPrinterAttr, + xpoid_att_input_trays_medium, tm); + + XpOidMediumSSDelete(pool_msss); + XpOidTrayMediumListDelete(tm); +} + + +void +XpValidatePrinterPool(XpContextPtr pContext, + const XpValidatePoolsRec* vpr) +{ + /* + * content-orientations-supported + */ + XpValidateListAttr(pContext, XPPrinterAttr, + xpoid_att_content_orientations_supported, + vpr->valid_content_orientations_supported, + vpr->default_content_orientations_supported); + /* + * document-formats-supported + */ + XpValidateDocFmtListAttr(pContext, XPPrinterAttr, + xpoid_att_document_formats_supported, + vpr->valid_document_formats_supported, + vpr->default_document_formats_supported); + /* + * plexes-supported + */ + XpValidateListAttr(pContext, XPPrinterAttr, xpoid_att_plexes_supported, + vpr->valid_plexes_supported, + vpr->default_plexes_supported); + /* + * printer-resolutions-supported + */ + XpValidateCardListAttr(pContext, XPPrinterAttr, + xpoid_att_printer_resolutions_supported, + vpr->valid_printer_resolutions_supported, + vpr->default_printer_resolutions_supported); + /* + * xp-embedded-formats-supported + */ + XpValidateDocFmtListAttr(pContext, XPPrinterAttr, + xpoid_att_xp_embedded_formats_supported, + vpr->valid_xp_embedded_formats_supported, + vpr->default_xp_embedded_formats_supported); + /* + * xp-listfonts-modes-supported + */ + XpValidateListAttr(pContext, XPPrinterAttr, + xpoid_att_xp_listfonts_modes_supported, + vpr->valid_xp_listfonts_modes_supported, + vpr->default_xp_listfonts_modes_supported); + /* + * xp-raw-formats-supported + */ + XpValidateDocFmtListAttr(pContext, XPPrinterAttr, + xpoid_att_xp_raw_formats_supported, + vpr->valid_xp_raw_formats_supported, + vpr->default_xp_raw_formats_supported); + /* + * xp-setup-proviso + */ + XpValidateOidAttr(pContext, XPPrinterAttr, xpoid_att_xp_setup_proviso, + vpr->valid_xp_setup_proviso, xpoid_none); + /* + * medium-source-sizes-supported + * input-trays-mdeium + */ + XpValidatePrinterMediaAttrs(pContext, + vpr->valid_input_trays, + vpr->valid_medium_sizes); + /* + * available-compressions-supported + */ + XpValidateListAttr(pContext, XPPrinterAttr, + xpoid_att_available_compressions_supported, + vpr->valid_available_compressions_supported, + vpr->default_available_compressions_supported); +} + + +void +XpValidateNotificationProfile(XpContextPtr pContext) +{ + const char* value_in; + const char* value_out; + + value_in = XpGetStringAttr(pContext, XPJobAttr, + xpoid_att_notification_profile); + value_out = XpOidNotifyString(XpOidNotifyParse(value_in)); + XpPutStringAttr(pContext, XPJobAttr, + xpoid_att_notification_profile, value_out); +} + +void +XpValidateJobPool(XpContextPtr pContext, + const XpValidatePoolsRec* vpr) +{ + /* + * Note: the 'vpr' argument is unused in this + * implementation; it is reserved for future use + */ + XpOidList* job_attrs_supported; + /* + * only validate attributes found in job-attributes-supported + */ + job_attrs_supported = XpGetListAttr(pContext, XPPrinterAttr, + xpoid_att_job_attributes_supported, + (const XpOidList*)NULL); + /* + * notification-profile + */ + if(XpOidListHasOid(job_attrs_supported, xpoid_att_notification_profile)) + { + XpValidateNotificationProfile(pContext); + } + /* + * clean up + */ + XpOidListDelete(job_attrs_supported); +} + + +static void +XpValidateDocOrPagePool(XpContextPtr pContext, + XPAttributes pool, /* XPDocAttr or XPPageAttr */ + const XpOidList* attrs_supported, + const XpValidatePoolsRec* vpr) +{ + /* + * content-orientation + */ + if(XpOidListHasOid(attrs_supported, xpoid_att_content_orientation)) + { + XpOidList* content_orientations_supported; + content_orientations_supported = + XpGetListAttr(pContext, XPPrinterAttr, + xpoid_att_content_orientations_supported, + vpr->valid_content_orientations_supported); + XpValidateOidAttr(pContext, pool, xpoid_att_content_orientation, + content_orientations_supported, xpoid_none); + XpOidListDelete(content_orientations_supported); + } + /* + * copy-count + */ + if(XpOidListHasOid(attrs_supported, xpoid_att_copy_count)) + XpValidateCardAttr(pContext, pool, xpoid_att_copy_count, + (const XpOidCardList*)NULL, 0); + /* + * default-printer-resolution + */ + if(XpOidListHasOid(attrs_supported, xpoid_att_default_printer_resolution)) + { + XpOidCardList* printer_resolutions_supported; + printer_resolutions_supported = + XpGetCardListAttr(pContext, XPPrinterAttr, + xpoid_att_printer_resolutions_supported, + vpr->valid_printer_resolutions_supported); + XpValidateCardAttr(pContext, pool, + xpoid_att_default_printer_resolution, + printer_resolutions_supported, 0); + XpOidCardListDelete(printer_resolutions_supported); + } + /* + * default-input-tray + */ + if(XpOidListHasOid(attrs_supported, xpoid_att_default_input_tray)) + { + XpOidTrayMediumList* input_trays_medium; + const char* value_in; + XpOid value_tray; + + input_trays_medium = + XpGetTrayMediumListAttr(pContext, XPPrinterAttr, + xpoid_att_input_trays_medium, + (const XpOidList*)NULL, + (const XpOidMediumSS*)NULL); + value_in = + XpGetStringAttr(pContext, pool, xpoid_att_default_input_tray); + value_tray = XpOidFromString(value_in); + if(!XpOidTrayMediumListHasTray(input_trays_medium, value_tray)) + value_tray = xpoid_none; + XpPutOidAttr(pContext, pool, xpoid_att_default_input_tray, value_tray); + XpOidTrayMediumListDelete(input_trays_medium); + } + /* + * default-medium + */ + if(XpOidListHasOid(attrs_supported, xpoid_att_default_medium)) + { + XpOidMediumSS* msss; + const char* value_in; + XpOid value_size; + + msss = XpGetMediumSSAttr(pContext, XPPrinterAttr, + xpoid_att_medium_source_sizes_supported, + (const XpOidList*)NULL, + (const XpOidList*)NULL); + value_in = XpGetStringAttr(pContext, pool, xpoid_att_default_medium); + value_size = XpOidFromString(value_in); + if(!XpOidMediumSSHasSize(msss, value_size)) + value_size = xpoid_none; + XpPutOidAttr(pContext, pool, xpoid_att_default_medium, value_size); + XpOidMediumSSDelete(msss); + } + /* + * document-format + */ + if(XpOidListHasOid(attrs_supported, xpoid_att_document_format)) + { + XpOidDocFmtList* document_formats_supported; + const char* value_in; + XpOidDocFmt* document_format; + const char* value_out; + + document_formats_supported = + XpGetDocFmtListAttr(pContext, XPPrinterAttr, + xpoid_att_document_formats_supported, + vpr->valid_document_formats_supported); + value_in = XpGetStringAttr(pContext, pool, xpoid_att_document_format); + document_format = XpOidDocFmtNew(value_in); + if(XpOidDocFmtListHasFmt(document_formats_supported, document_format)) + value_out = XpOidDocFmtString(document_format); + else + value_out = XpOidDocFmtString(vpr->default_document_format); + XpOidDocFmtListDelete(document_formats_supported); + XpOidDocFmtDelete(document_format); + XpPutStringAttr(pContext, pool, xpoid_att_document_format, value_out); + XpOidFree(value_out); + } + /* + * plex + */ + if(XpOidListHasOid(attrs_supported, xpoid_att_plex)) + { + XpOidList* plexes_supported; + plexes_supported = + XpGetListAttr(pContext, XPPrinterAttr, xpoid_att_plexes_supported, + vpr->valid_plexes_supported); + XpValidateOidAttr(pContext, pool, xpoid_att_plex, + plexes_supported, xpoid_none); + XpOidListDelete(plexes_supported); + } + /* + * xp-listfonts-modes + */ + if(XpOidListHasOid(attrs_supported, xpoid_att_xp_listfonts_modes)) + { + XpOidList* xp_listfonts_modes_supported; + xp_listfonts_modes_supported = + XpGetListAttr(pContext, XPPrinterAttr, + xpoid_att_xp_listfonts_modes_supported, + vpr->valid_xp_listfonts_modes_supported); + XpValidateListAttr(pContext, pool, xpoid_att_xp_listfonts_modes, + xp_listfonts_modes_supported, + (const XpOidList*)NULL); + XpOidListDelete(xp_listfonts_modes_supported); + } + /* + * available-compressions + */ + if(XpOidListHasOid(attrs_supported, xpoid_att_available_compression)) + { + XpOidList* available_compressions_supported; + available_compressions_supported = + XpGetListAttr(pContext, XPPrinterAttr, + xpoid_att_available_compressions_supported, + vpr->valid_available_compressions_supported); + XpValidateOidAttr(pContext, pool, xpoid_att_available_compression, + available_compressions_supported, xpoid_none); + XpOidListDelete(available_compressions_supported); + } +} + +void +XpValidateDocumentPool(XpContextPtr pContext, + const XpValidatePoolsRec* vpr) +{ + XpOidList* document_attrs_supported; + /* + * only validate attributes found in document-attributes-supported + */ + document_attrs_supported = + XpGetListAttr(pContext, XPPrinterAttr, + xpoid_att_document_attributes_supported, + (const XpOidList*)NULL); + /* + * validate + */ + XpValidateDocOrPagePool(pContext, XPDocAttr, + document_attrs_supported, vpr); + /* + * clean up + */ + XpOidListDelete(document_attrs_supported); +} + +void +XpValidatePagePool(XpContextPtr pContext, + const XpValidatePoolsRec* vpr) +{ + XpOidList* page_attrs_supported; + /* + * only validate attributes found in xp-page-attributes-supported + */ + page_attrs_supported = + XpGetListAttr(pContext, XPPrinterAttr, + xpoid_att_xp_page_attributes_supported, + (const XpOidList*)NULL); + /* + * validate + */ + XpValidateDocOrPagePool(pContext, XPPageAttr, + page_attrs_supported, vpr); + /* + * clean up + */ + XpOidListDelete(page_attrs_supported); +} + +void +XpValidateAttributePool(XpContextPtr pContext, + XPAttributes pool, + const XpValidatePoolsRec* vpr) +{ + switch(pool) + { + case XPPrinterAttr: + XpValidatePrinterPool(pContext, vpr); + break; + + case XPDocAttr: + XpValidateDocumentPool(pContext, vpr); + break; + + case XPJobAttr: + XpValidateJobPool(pContext, vpr); + break; + + case XPPageAttr: + XpValidatePagePool(pContext, vpr); + break; + + default: + break; + } +} diff --git a/Xprint/AttrValid.h b/Xprint/AttrValid.h new file mode 100644 index 000000000..dab3c2def --- /dev/null +++ b/Xprint/AttrValid.h @@ -0,0 +1,208 @@ +/* $Xorg: AttrValid.h,v 1.4 2001/03/14 18:43:40 pookie Exp $ */ +/* +(c) Copyright 1996 Hewlett-Packard Company +(c) Copyright 1996 International Business Machines Corp. +(c) Copyright 1996 Sun Microsystems, Inc. +(c) Copyright 1996 Novell, Inc. +(c) Copyright 1996 Digital Equipment Corp. +(c) Copyright 1996 Fujitsu Limited +(c) Copyright 1996 Hitachi, Ltd. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the names of the copyright holders shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from said +copyright holders. +*/ + +#ifndef _Xp_AttrValid_h +#define _Xp_AttrValid_h + +#include "Oid.h" +#include "attributes.h" + +#define XpNumber(a) (sizeof(a) / sizeof(*(a))) + +/* + * Attribute pool validation valid values and defaults + */ +typedef struct +{ + XpOidList* valid_content_orientations_supported; + XpOidList* default_content_orientations_supported; + + XpOidDocFmtList* valid_document_formats_supported; + XpOidDocFmtList* default_document_formats_supported; + + XpOidList* valid_input_trays; + XpOidList* valid_medium_sizes; + + XpOidList* valid_plexes_supported; + XpOidList* default_plexes_supported; + + XpOidCardList* valid_printer_resolutions_supported; + XpOidCardList* default_printer_resolutions_supported; + + XpOidDocFmtList* valid_xp_embedded_formats_supported; + XpOidDocFmtList* default_xp_embedded_formats_supported; + + XpOidList* valid_xp_listfonts_modes_supported; + XpOidList* default_xp_listfonts_modes_supported; + + XpOidDocFmtList* valid_xp_raw_formats_supported; + XpOidDocFmtList* default_xp_raw_formats_supported; + + XpOidList* valid_xp_setup_proviso; + + XpOidDocFmt* default_document_format; + XpOidList* valid_available_compressions_supported; + XpOidList* default_available_compressions_supported; + +} XpValidatePoolsRec; + +/* + * XpOid resource access + */ +#define XpGetStringAttr(pContext, pool, oid) \ + (const char*)XpGetOneAttribute(pContext, pool, (char*)XpOidString(oid)) +#define XpPutStringAttr(pContext, pool, oid, value) \ + XpPutOneAttribute(pContext, pool, XpOidString(oid), value) +/* + * XpOid-valued attribute access + */ +XpOid XpGetOidAttr(XpContextPtr pContext, + XPAttributes pool, + XpOid oid, + const XpOidList* valid_oid_list); +void XpPutOidAttr(XpContextPtr pContext, + XPAttributes pool, + XpOid oid, + XpOid value_oid); +void XpValidateOidAttr(XpContextPtr pContext, + XPAttributes pool, + XpOid oid, + const XpOidList* valid_oids, + XpOid default_oid); +/* + * cardinal-valued attribute access + */ +unsigned long XpGetCardAttr(XpContextPtr pContext, + XPAttributes pool, + XpOid oid, + const XpOidCardList* valid_card_list); +void XpPutCardAttr(XpContextPtr pContext, + XPAttributes pool, + XpOid oid, + unsigned long value_card); +void XpValidateCardAttr(XpContextPtr pContext, + XPAttributes pool, + XpOid oid, + const XpOidCardList* valid_cards, + unsigned long default_card); +/* + * XpOidList-valued attribute access + */ +XpOidList* XpGetListAttr(XpContextPtr pContext, + XPAttributes pool, + XpOid oid, + const XpOidList* valid_oid_list); +void XpPutListAttr(XpContextPtr pContext, + XPAttributes pool, + XpOid oid, + const XpOidList* list); +void XpValidateListAttr(XpContextPtr pContext, + XPAttributes pool, + XpOid oid, + const XpOidList* valid_oids, + const XpOidList* default_oids); +/* + * XpOidCardList-valued attribute access + */ +XpOidCardList* XpGetCardListAttr(XpContextPtr pContext, + XPAttributes pool, + XpOid oid, + const XpOidCardList* valid_card_list); +void XpPutCardListAttr(XpContextPtr pContext, + XPAttributes pool, + XpOid oid, + const XpOidCardList* list); +void XpValidateCardListAttr(XpContextPtr pContext, + XPAttributes pool, + XpOid oid, + const XpOidCardList* valid_cards, + const XpOidCardList* default_cards); +/* + * XpOidDocFmtList-valued attribute access + */ +XpOidDocFmtList* XpGetDocFmtListAttr(XpContextPtr pContext, + XPAttributes pool, + XpOid oid, + const XpOidDocFmtList* valid_fmt_list); +void XpPutDocFmtListAttr(XpContextPtr pContext, + XPAttributes pool, + XpOid oid, + const XpOidDocFmtList* list); +void XpValidateDocFmtListAttr(XpContextPtr pContext, + XPAttributes pool, + XpOid oid, + const XpOidDocFmtList* valid_fmts, + const XpOidDocFmtList* default_fmts); +/* + * XpOidMediumSS-valued attribute access + */ +XpOidMediumSS* XpGetMediumSSAttr(XpContextPtr pContext, + XPAttributes pool, + XpOid oid, + const XpOidList* valid_trays, + const XpOidList* valid_sizes); +void XpPutMediumSSAttr(XpContextPtr pContext, + XPAttributes pool, + XpOid oid, + const XpOidMediumSS* msss); +const XpOidMediumSS* XpGetDefaultMediumSS(); + +/* + * XpOidTrayMediumList-valued attribute access + */ +XpOidTrayMediumList* XpGetTrayMediumListAttr(XpContextPtr pContext, + XPAttributes pool, + XpOid oid, + const XpOidList* valid_trays, + const XpOidMediumSS* msss); +void XpPutTrayMediumListAttr(XpContextPtr pContext, + XPAttributes pool, + XpOid oid, + const XpOidTrayMediumList* tm); +/* + * Attribute pool validation + */ +void XpValidateAttributePool(XpContextPtr pContext, + XPAttributes pool, + const XpValidatePoolsRec* vpr); +void XpValidatePrinterPool(XpContextPtr pContext, + const XpValidatePoolsRec* vpr); +void XpValidateJobPool(XpContextPtr pContext, + const XpValidatePoolsRec* vpr); +void XpValidateDocumentPool(XpContextPtr pContext, + const XpValidatePoolsRec* vpr); +void XpValidatePagePool(XpContextPtr pContext, + const XpValidatePoolsRec* vpr); + + +#endif /* _Xp_AttrValid_h - don't add anything after this line */ diff --git a/Xprint/DiPrint.h b/Xprint/DiPrint.h new file mode 100644 index 000000000..a4b969141 --- /dev/null +++ b/Xprint/DiPrint.h @@ -0,0 +1,54 @@ +/* $Xorg: DiPrint.h,v 1.3 2000/08/17 19:48:04 cpqbld Exp $ */ +/* +(c) Copyright 1996 Hewlett-Packard Company +(c) Copyright 1996 International Business Machines Corp. +(c) Copyright 1996 Sun Microsystems, Inc. +(c) Copyright 1996 Novell, Inc. +(c) Copyright 1996 Digital Equipment Corp. +(c) Copyright 1996 Fujitsu Limited +(c) Copyright 1996 Hitachi, Ltd. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the names of the copyright holders shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from said +copyright holders. +*/ +/* + * The XpDiListEntry struct is the type of each element of the array + * handed back to the extension code to handle a GetPrinterList request. + * We don't use the printerDb directly because of the desire to handle + * multiple locales. Creating this new array for each GetPrinterList + * request will allow us to build it with the description in the locale of + * the requesting client. + */ +typedef struct _diListEntry { + char *name; + char *description; + char *localeName; + unsigned long rootWinId; +} XpDiListEntry; + +extern void XpDiFreePrinterList(XpDiListEntry **list); + +extern XpDiListEntry **XpDiGetPrinterList( + int nameLen, + char *name, + int localeLen, + char *locale); diff --git a/Xprint/Init.c b/Xprint/Init.c new file mode 100644 index 000000000..06757fa77 --- /dev/null +++ b/Xprint/Init.c @@ -0,0 +1,1805 @@ +/* $Xorg: Init.c,v 1.5 2001/03/07 17:31:33 pookie Exp $ */ +/* +(c) Copyright 1996 Hewlett-Packard Company +(c) Copyright 1996 International Business Machines Corp. +(c) Copyright 1996 Sun Microsystems, Inc. +(c) Copyright 1996 Novell, Inc. +(c) Copyright 1996 Digital Equipment Corp. +(c) Copyright 1996 Fujitsu Limited +(c) Copyright 1996 Hitachi, Ltd. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the names of the copyright holders shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from said +copyright holders. +*/ +/******************************************************************* +** +** ********************************************************* +** * +** * File: printer/Init.c +** * +** * Contents: +** * The InitOutput routine here would presumably +** * be called from the normal server's InitOutput +** * after all display screens have been added. +** * There is are ifdef'd routines suitable for +** * use in building a printer-only server. Turn +** * on the "PRINTER_ONLY_SERVER" define if this is +** * to be the only ddx-level driver. +** * +** * Copyright: Copyright 1993,1995 Hewlett-Packard Company +** * +** ********************************************************* +** +********************************************************************/ + +#include <unistd.h> +#include <stdlib.h> +#include <stdio.h> +#include <ctype.h> +#include <signal.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <string.h> +#include <locale.h> +#ifdef __hpux +#include <sys/sysmacros.h> +#endif + +#include "X.h" +#define NEED_EVENTS 1 +#include "Xproto.h" +#include <servermd.h> + +#include "screenint.h" +#include "input.h" +#include "cursor.h" +#include "misc.h" +#include "windowstr.h" +#include "scrnintstr.h" +#include "inputstr.h" + +#include "gcstruct.h" +#include "fonts/fontstruct.h" +#include "errno.h" + +#define _XP_PRINT_SERVER_ +#include "Printstr.h" +#undef _XP_PRINT_SERVER_ + +typedef char *XPointer; +#define Status int +#include <Xresource.h> + +#include "DiPrint.h" +#include "AttrValid.h" +#include "attributes.h" + +extern char *display; /* display number as a string */ + +#if 0 +/* extern char *Xalloc(); */ +extern void Xfree(); +/* extern char *Xrealloc(); */ +#else +#include "os.h" +#endif + +extern char *getenv(); +extern void XpAddPrinterAttribute(); +extern char *XpGetConfigDir(); +extern XpContextPtr XpContextOfClient(); + +/* +extern int GiveUp(); +*/ + +extern WindowPtr *WindowTable; /* declared in dix:globals.c */ + + +#if NeedFunctionPrototypes + +static void GetDriverFromPrinterName( + char *printerName, + char **driverName, + Bool (**initScreenFunc)()); +static void GenericScreenInit( + int index, + ScreenPtr pScreen, + int argc, + char **argv); +static Bool InitPrintDrivers( + int index, + ScreenPtr pScreen, + int argc, + char **argv); + +#else + +static void GetDriverFromPrinterName(); +static void GenericScreenInit(); +static Bool InitPrintDrivers(); + +#endif + + +/* + * The following two defines are used to build the name "X*printers", where + * the "*" is replaced by the display number. This is used to construct + * the name of the default printers configuration file if the -XpFile + * command line option was not specified. + */ +#define XNPRINTERSFILEPREFIX "/X" +#define XNPRINTERSFILESUFFIX "printers" +#define XPRINTERSFILENAME "Xprinters" + +#define MODELDIRNAME "/models" +#define FONTDIRNAME "/fonts" + +/* + * The string LIST_QUEUES is fed to a shell to generate an ordered + * list of available printers on the system. These string definitions + * are taken from the file PrintSubSys.C within the code for the + * dtprintinfo program. + */ +#ifdef AIXV4 +const char *LIST_QUEUES = "lsallq | grep -v '^bsh$' | sort"; +#else +#ifdef hpux +const char *LIST_QUEUES = "LANG=C lpstat -v | " + "awk '" + " $2 == \"for\" " + " { " + " x = match($3, /:/); " + " print substr($3, 1, x-1)" + " }' | sort"; +#else +#ifdef __osf__ + const char *LIST_QUEUES = "LANG=C lpstat -v | " + "nawk '" + " $2 == \"for\" " + " { print $4 }' " + " | sort"; +#else +#ifdef __uxp__ +const char *LIST_QUEUES = "LANG=C lpstat -v | " + "nawk '" + " $4 == \"for\" " + " { " + " x = match($5, /:/); " + " print substr($5, 1, x-1)" + " }' | sort"; +#else +#if defined(CSRG_BASED) || defined(linux) +const char *LIST_QUEUES = "LANG=C lpc status | grep -v '^\t' | " + "sed -e /:/s/// | sort"; +#else +const char *LIST_QUEUES = "LANG=C lpstat -v | " + "nawk '" + " $2 == \"for\" " + " { " + " x = match($3, /:/); " + " print substr($3, 1, x-1)" + " }' | sort"; +#endif +#endif +#endif +#endif +#endif + +#ifdef XPRASTERDDX + +static +PixmapFormatRec RasterPixmapFormats[] = { + 1, 1, BITMAP_SCANLINE_PAD +}; +#define NUMRASTFORMATS (sizeof RasterPixmapFormats)/(sizeof RasterPixmapFormats[0]) + +extern Bool InitializeRasterDriver(); +extern XpValidatePoolsRec RasterValidatePoolsRec; /* From RasterAttVal.c */ + +#endif + +#ifdef XPPCLDDX + +static +PixmapFormatRec ColorPclPixmapFormats[] = { + 1, 1, BITMAP_SCANLINE_PAD, + 8, 8, BITMAP_SCANLINE_PAD, + 24,32, BITMAP_SCANLINE_PAD +}; + +#define NUMCPCLFORMATS (sizeof ColorPclPixmapFormats)/(sizeof ColorPclPixmapFormats[0]) + +extern Bool InitializeColorPclDriver(); +extern XpValidatePoolsRec PclValidatePoolsRec; + +#endif + +#ifdef XPMONOPCLDDX + +static +PixmapFormatRec MonoPclPixmapFormats[] = { + 1, 1, BITMAP_SCANLINE_PAD +}; + +#define NUMMPCLFORMATS (sizeof MonoPclPixmapFormats)/(sizeof MonoPclPixmapFormats[0]) + +extern Bool InitializeMonoPclDriver(); +extern XpValidatePoolsRec PclValidatePoolsRec; + +#endif + +#ifdef XPPSDDX + +static +PixmapFormatRec PSPixmapFormats[] = { + 1, 1, BITMAP_SCANLINE_PAD, + 8, 8, BITMAP_SCANLINE_PAD, + 24,32, BITMAP_SCANLINE_PAD +}; + +#define NUMPSFORMATS (sizeof PSPixmapFormats)/(sizeof PSPixmapFormats[0]) + +extern Bool InitializePsDriver(); +extern XpValidatePoolsRec PsValidatePoolsRec; + +#endif + + +typedef Bool (*pBFunc)(); +typedef void (*pVFunc)(); +/* + * The driverInitArray contains an entry for each driver the + * server knows about. Each element contains pointers to pixmap formats, the + * driver's initialization routine, and pointers to the driver's + * attribute validation rec, and/or a driver function which + * returns the maximum medium width&height, and maximum resolution + * given a printer name. Either the validation rec OR the dimension + * function can be NULL. If the function is non-NULL then it + * will be called, and will be passed the (possibly NULL) validation rec. + * If the function is NULL, then XpGetMaxWidthHeightRes() is called. + */ +typedef struct _driverInitRec { + char *driverName; + pBFunc initFunc; + XpValidatePoolsRec *pValRec; + pVFunc dimensionsFunc; + PixmapFormatRec *pFmts; + int numFmts; +} driverInitRec; + +static driverInitRec driverInits[] = { +#ifdef XPRASTERDDX + { + "XP-RASTER", + InitializeRasterDriver, + &RasterValidatePoolsRec, + (pVFunc) NULL, + RasterPixmapFormats, + NUMRASTFORMATS + }, +#endif +#ifdef XPPCLDDX + { + "XP-PCL-COLOR", + InitializeColorPclDriver, + &PclValidatePoolsRec, + (pVFunc) NULL, + ColorPclPixmapFormats, + NUMCPCLFORMATS + }, +#endif +#ifdef XPMONOPCLDDX + { + "XP-PCL-MONO", + InitializeMonoPclDriver, + &PclValidatePoolsRec, + (pVFunc) NULL, + MonoPclPixmapFormats, + NUMMPCLFORMATS + }, +#endif +#ifdef XPPSDDX + { + "XP-POSTSCRIPT", + InitializePsDriver, + &PsValidatePoolsRec, + (pVFunc) NULL, + PSPixmapFormats, + NUMPSFORMATS + }, +#endif +}; + + +/* + * The printerDb variable points to a list of PrinterDbEntry structs + * which map printer names with screen numbers and driver names. + */ +typedef struct _printerDbEntry { + struct _printerDbEntry *next; + char *name; + char *qualifier; + int screenNum; + char *driverName; +} PrinterDbEntry, *PrinterDbPtr; + +static PrinterDbPtr printerDb = (PrinterDbPtr)NULL; + +/* + * The nameMap is a list used in initializing the attribute store + * for each printer. The list is freed once the printerDb is built + * and the attribute stores for all printers have been initialized. + */ +typedef struct _nameMapEntry { + struct _nameMapEntry *next; + char *name; + char *qualifier; +} NameMapEntry, *NameMapPtr; + +static NameMapPtr nameMap = (NameMapPtr)NULL; + +/* + * The driverMap is a list which provides the mapping between driver names + * and screen numbers. It is built and used + * by RehashPrinterList to correctly fill in the screenNum field in the + * printerDb entries. The list is freed before RehashPrinterList terminates. + */ +typedef struct _driverMapping { + struct _driverMapping *next; + char *driverName; + int screenNum; +} DriverMapEntry, *DriverMapPtr; + +static const char configFilePath[] = +"/etc/dt/config/print:/usr/dt/config/print"; + +static const char printServerConfigDir[] = "XPSERVERCONFIGDIR"; + +static int printScreenPrivIndex, + printWindowPrivIndex, + printGCPrivIndex; +static unsigned long printGeneration = 0; +static char *configFileName = (char *)NULL; +static Bool freeDefaultFontPath = FALSE; +static char *origFontPath = (char *)NULL; + +/* + * XprintOptions checks argv[i] to see if it is our command line + * option specifying a configuration file name. It returns the index + * of the next option to process. + */ +int +XprintOptions(argc, argv, i) + int argc; + char **argv; + int i; +{ + extern void ddxUseMsg(); + if(strcmp(argv[i], "-XpFile") == 0) + { + if ((i + 1) >= argc) { + ddxUseMsg (); + return i + 2; + } + configFileName = argv[i + 1]; + return i + 2; + } + else + return i; +} + +/************************************************************ + * GetInitFunc -- + * + * This routine is called from the InitPrintDrivers function. + * Given the name of a driver, return a pointer to the driver's + * initialization function. + * + * Results: + * Returns a pointer to the initialization function for the driver. + * + * + ************************************************************/ + +/* +typedef Bool (*pIFunc)(); +static pIFunc +GetInitFunc(driverName) +*/ + +static Bool (* +GetInitFunc(driverName))() + char *driverName; +{ + driverInitRec *pInitRec; + int numDrivers = sizeof(driverInits)/sizeof(driverInitRec); + int i; + + for(pInitRec = driverInits, i = 0; i < numDrivers; pInitRec++, i++) + { + if( !strcmp( driverName, pInitRec->driverName ) ) + return pInitRec->initFunc; + } + + return (Bool(*)())NULL; +} + +static void +GetDimFuncAndRec( + char *driverName, + XpValidatePoolsRec **pValRec, + pVFunc *dimensionsFunc) +{ + driverInitRec *pInitRec; + int numDrivers = sizeof(driverInits)/sizeof(driverInitRec); + int i; + + for(pInitRec = driverInits, i = 0; i < numDrivers; pInitRec++, i++) + { + if( !strcmp( driverName, pInitRec->driverName ) ) + { + *dimensionsFunc = pInitRec->dimensionsFunc; + *pValRec = pInitRec->pValRec; + return ; + } + } + + *dimensionsFunc = (pVFunc)NULL; + *pValRec = (XpValidatePoolsRec *)NULL; + return; +} + +static void +FreePrinterDb() +{ + PrinterDbPtr pCurEntry, pNextEntry; + + for(pCurEntry = printerDb, pNextEntry = (PrinterDbPtr)NULL; + pCurEntry != (PrinterDbPtr)NULL; pCurEntry = pNextEntry) + { + pNextEntry = pCurEntry->next; + if(pCurEntry->name != (char *)NULL) + xfree(pCurEntry->name); + /* + * We don't free the driver name, because it's expected to simply + * be a pointer into the xrm database. + */ + xfree(pCurEntry); + } + printerDb = (PrinterDbPtr)NULL; +} + +/* + * AddPrinterDbName allocates an entry in the printerDb list, and + * initializes the "name". It returns TRUE if the element was + * successfully added, and FALSE if an allocation error ocurred. + * XXX AddPrinterDbName needs to check for (and not add) duplicate names. + */ +static Bool +AddPrinterDbName(name) + char *name; +{ + PrinterDbPtr pEntry = (PrinterDbPtr)xalloc(sizeof(PrinterDbEntry)); + + if(pEntry == (PrinterDbPtr)NULL) return FALSE; + pEntry->name = strdup(name); + pEntry->qualifier = (char *)NULL; + + if(printerDb == (PrinterDbPtr)NULL) + { + pEntry->next = (PrinterDbPtr)NULL; + printerDb = pEntry; + } + else + { + pEntry->next = printerDb; + printerDb = pEntry; + } + return TRUE; +} + +static void +AugmentPrinterDb(command) + char *command; +{ + FILE *fp; + char name[256]; + + fp = popen(command, "r"); + /* XXX is a 256 character limit overly restrictive for printer names? */ + while(fgets(name, 256, fp) != (char *)NULL && strlen(name)) + { + name[strlen(name) - 1] = (char)'\0'; /* strip the \n */ + AddPrinterDbName(name); + } + pclose(fp); +} + +/* + * FreeNameMap frees all remaining memory associated with the nameMap. + */ +static void +FreeNameMap() +{ + NameMapPtr pEntry, pTmp; + + for(pEntry = nameMap, pTmp = (NameMapPtr)NULL; + pEntry != (NameMapPtr)NULL; + pEntry = pTmp) + { + if(pEntry->name != (char *)NULL) + xfree(pEntry->name); + if(pEntry->qualifier != (char *)NULL) + xfree(pEntry->qualifier); + pTmp = pEntry->next; + xfree(pEntry); + } + nameMap = (NameMapPtr)NULL; +} + +/* + * AddNameMap adds an element to the nameMap linked list. + */ +static Bool +AddNameMap(name, qualifier) + char *name; + char *qualifier; +{ + NameMapPtr pEntry; + + if((pEntry = (NameMapPtr)xalloc(sizeof(NameMapEntry))) == (NameMapPtr)NULL) + return FALSE; + pEntry->name = name; + pEntry->qualifier = qualifier; + pEntry->next = nameMap; + nameMap = pEntry; + return TRUE; +} + +/* + * MergeNameMap - puts the "map" names (aka qualifiers, aliases) into + * the printerDb. This should be called once, after both the printerDb + * and nameMap lists are complete. When/if MergeNameMap finds a map for + * an entry in the printerDb, the qualifier is _moved_ (not copied) to + * the printerDb. This means that the qualifier pointer in the nameMap + * is NULLed out. + */ +static void +MergeNameMap() +{ + NameMapPtr pMap; + PrinterDbPtr pDb; + + for(pMap = nameMap; pMap != (NameMapPtr)NULL; pMap = pMap->next) + { + for(pDb = printerDb; pDb != (PrinterDbPtr)NULL; pDb = pDb->next) + { + if(!strcmp(pMap->name, pDb->name)) + { + pDb->qualifier = pMap->qualifier; + pMap->qualifier = (char *)NULL; + } + } + } +} + +/* + * CreatePrinterAttrs causes the attribute stores to be built for + * each printer in the printerDb. + */ +static void +CreatePrinterAttrs() +{ + PrinterDbPtr pDb; + + for(pDb = printerDb; pDb != (PrinterDbPtr)NULL; pDb = pDb->next) + { + XpBuildAttributeStore(pDb->name, (pDb->qualifier)? + pDb->qualifier : pDb->name); + } +} + +#ifdef XPPSDDX +#define defaultDriver "XP-POSTSCRIPT" +#else +#ifdef XPPCLDDX +#define defaultDriver "XP-PCL-COLOR" +#else +#ifdef XPMONOPCLDDX +#define defaultDriver "XP-PCL-MONO" +#else +#define defaultDriver "XP-RASTER" +#endif +#endif +#endif + +/* + * StoreDriverNames - queries the attribute store for the ddx-identifier. + * if the ddx-identifier is not in the attribute database, then a default + * ddx-identifier is store in both the attribute store for the printer, + * and in the printerDb. + * The ddx-identifier is stored in the printerDb for use in initializing + * the screens. + */ +static void +StoreDriverNames() +{ + PrinterDbPtr pEntry; + + for(pEntry = printerDb; pEntry != (PrinterDbPtr)NULL; + pEntry = pEntry->next) + { + pEntry->driverName = (char*)XpGetPrinterAttribute(pEntry->name, + "xp-ddx-identifier"); + if(pEntry->driverName == (char *)NULL || + strlen(pEntry->driverName) == 0 || + GetInitFunc(pEntry->driverName) == (Bool(*)())NULL) + { + if (pEntry->driverName && (strlen(pEntry->driverName) != 0)) { + ErrorF("Xp Extension: Can't load driver %s\n", + pEntry->driverName); + ErrorF(" init function missing\n"); + } + + pEntry->driverName = defaultDriver; + XpAddPrinterAttribute(pEntry->name, + (pEntry->qualifier != (char *)NULL)? + pEntry->qualifier : pEntry->name, + "*xp-ddx-identifier", pEntry->driverName); + } + } +} + +char * +MbStrchr( + char *str, + int ch) +{ + size_t mbCurMax = MB_CUR_MAX; + wchar_t targetChar, curChar; + char tmpChar; + int i, numBytes, byteLen; + + if(mbCurMax <= 1) return strchr(str, ch); + + tmpChar = (char)ch; + mbtowc(&targetChar, &tmpChar, mbCurMax); + for(i = 0, numBytes = 0, byteLen = strlen(str); i < byteLen; i += numBytes) + { + numBytes = mbtowc(&curChar, &str[i], mbCurMax); + if(curChar == targetChar) return &str[i]; + } + return (char *)NULL; +} + +/* + * GetConfigFileName - Looks for a "Xprinters" file in + * $(XPRINTDIR)/$LANG/print, and then in $(XPRINTDIR)/C/print. If it + * finds such a file, it returns the path to the file. The returned + * string must be freed by the caller. + */ +static char * +GetConfigFileName() +{ + /* + * We need to find the system-wide file, if one exists. This + * file can be in either $(XPRINTDIR)/$LANG/print, or in + * $(PRINTDIR)/C/print, and the file itself is named "Xprinters". + */ + char *dirName, *filePath; + + /* + * Check for a LANG-specific file. + */ + if(dirName = XpGetConfigDir(TRUE)) + { + filePath = (char *)xalloc(strlen(dirName) + + strlen(XPRINTERSFILENAME) + 2); + + if(filePath == (char *)NULL) + { + xfree(dirName); + return (char *)NULL; + } + + sprintf(filePath, "%s/%s", dirName, XPRINTERSFILENAME); + xfree(dirName); + if(access(filePath, R_OK) == 0) + return filePath; + + xfree(filePath); + } + + if(dirName = XpGetConfigDir(FALSE)) + { + filePath = (char *)xalloc(strlen(dirName) + + strlen(XPRINTERSFILENAME) + 2); + if(filePath == (char *)NULL) + { + xfree(dirName); + return (char *)NULL; + } + sprintf(filePath, "%s/%s", dirName, XPRINTERSFILENAME); + xfree(dirName); + if(access(filePath, R_OK) == 0) + return filePath; + xfree(filePath); + } + return (char *)NULL; +} + +/* + * BuildPrinterDb - reads the config file if it exists, and if necessary + * executes a command such as lpstat to generate a list of printers. + * XXX + * XXX BuildPrinterDb must be rewritten to allow 16-bit characters in + * XXX printer names. The will involve replacing the use of strtok() and its + * XXX related functions. + * XXX At the same time, BuildPrinterDb and it's support routines should have + * XXX allocation error checking added. + * XXX + */ +static PrinterDbPtr +BuildPrinterDb() +{ + char *printerList, *augmentCmd = (char *)NULL; + Bool defaultAugment = TRUE, freeConfigFileName; + + if(configFileName && access(configFileName, R_OK) != 0) + { + ErrorF("Xp Extension: Can't open file %s\n", configFileName); + } + if(!configFileName && (configFileName = GetConfigFileName())) + freeConfigFileName = TRUE; + else + freeConfigFileName = FALSE; + + if(configFileName != (char *)NULL && access(configFileName, R_OK) == 0) + { + char line[256]; + FILE *fp = fopen(configFileName, "r"); + + while(fgets(line, 256, fp) != (char *)NULL) + { + char *tok, *ptr; + if((tok = strtok(line, " \t\012")) != (char *)NULL) + { + if(tok[0] == (char)'#') continue; + if(strcmp(tok, "Printer") == 0) + { + while((tok = strtok((char *)NULL, " \t")) != (char *)NULL) + { + if(ptr = MbStrchr(tok, '\012')) + *ptr = (char)'\0'; + AddPrinterDbName(tok); + } + } + else if(strcmp(tok, "Map") == 0) + { + char *name, *qualifier; + + if((tok = strtok((char *)NULL, " \t\012")) == (char *)NULL) + continue; + name = strdup(tok); + if((tok = strtok((char *)NULL, " \t\012")) == (char *)NULL) + { + xfree(name); + continue; + } + qualifier = strdup(tok); + AddNameMap(name, qualifier); + } + else if(strcmp(tok, "Augment_Printer_List") == 0) + { + if((tok = strtok((char *)NULL, " \t\012")) == (char *)NULL) + continue; + + if(strcmp(tok, "%default%") == 0) + continue; + defaultAugment = FALSE; + if(strcmp(tok, "%none%") == 0) + continue; + AugmentPrinterDb(tok); + } + else + break; /* XXX Generate an error? */ + } + } + fclose(fp); + } + + if(defaultAugment == TRUE) + { + AugmentPrinterDb(LIST_QUEUES); + } + + MergeNameMap(); + FreeNameMap(); + + /* Create the attribute stores for all printers */ + CreatePrinterAttrs(); + + /* + * Find the drivers for each printers, and store the driver names + * in the printerDb + */ + StoreDriverNames(); + + if(freeConfigFileName) + { + xfree(configFileName); + configFileName = (char *)NULL; + } + + return printerDb; +} + +static void +FreeDriverMap(driverMap) + DriverMapPtr driverMap; +{ + DriverMapPtr pCurEntry, pNextEntry; + + for(pCurEntry = driverMap, pNextEntry = (DriverMapPtr)NULL; + pCurEntry != (DriverMapPtr)NULL; pCurEntry = pNextEntry) + { + pNextEntry = pCurEntry->next; + if(pCurEntry->driverName != (char *)NULL) + xfree(pCurEntry->driverName); + xfree(pCurEntry); + } +} + +/* + * XpRehashPrinterList rebuilds the list of printers known to the + * server. It first walks the printerDb to build a table mapping + * driver names and screen numbers, since this is not an easy mapping + * to change in the sample server. The normal configuration files are + * then read & parsed to create the new list of printers. Printers + * which require drivers other than those already initialized are + * deleted from the printerDb. This leaves attribute stores in place + * for inaccessible printers, but those stores will be cleaned up in + * the next rehash or server recycle. + */ +int +XpRehashPrinterList() +{ + PrinterDbPtr pEntry, pPrev; + DriverMapPtr driverMap = (DriverMapPtr)NULL, pDrvEnt; + int result; + + /* Build driverMap */ + for(pEntry = printerDb; pEntry != (PrinterDbPtr)NULL; pEntry = pEntry->next) + { + for(pDrvEnt = driverMap; pDrvEnt != (DriverMapPtr)NULL; + pDrvEnt = pDrvEnt->next) + { + if(!strcmp(pEntry->driverName, pDrvEnt->driverName)) + break; + } + + if(pDrvEnt != (DriverMapPtr)NULL) + continue; + + if((pDrvEnt = (DriverMapPtr)xalloc(sizeof(DriverMapEntry))) == + (DriverMapPtr)NULL) + { + FreeDriverMap(driverMap); + return BadAlloc; + } + pDrvEnt->driverName = strdup(pEntry->driverName); + pDrvEnt->screenNum = pEntry->screenNum; + pDrvEnt->next = driverMap; + driverMap = pDrvEnt; + } + + /* Free the old printerDb */ + FreePrinterDb(); + + /* Free/Rehash attribute stores */ + if((result = XpRehashAttributes()) != Success) + return result; + + /* Build a new printerDb */ + if(BuildPrinterDb() == (PrinterDbPtr)NULL) + return BadAlloc; + + /* Walk PrinterDb & either store screenNum, or delete printerDb entry */ + for(pEntry = printerDb, pPrev = (PrinterDbPtr)NULL; + pEntry != (PrinterDbPtr)NULL; pEntry = pEntry->next) + { + for(pDrvEnt = driverMap; pDrvEnt != (DriverMapPtr)NULL; + pDrvEnt = pDrvEnt->next) + { + if(!strcmp(printerDb->driverName, pDrvEnt->driverName)) + break; + } + + /* + * Either store the screen number, or delete the printerDb entry. + * Deleting the entry leaves orphaned attribute stores, but they'll + * get cleaned up at the next rehash or server recycle. + */ + if(pDrvEnt != (DriverMapPtr)NULL) + { + pEntry->screenNum = pDrvEnt->screenNum; + pPrev = pEntry; + } + else { + if(pPrev) + pPrev->next = pEntry->next; + else + pPrev = pEntry->next; + if(pEntry->name != (char *)NULL) + xfree(pEntry->name); + xfree(pEntry); + pEntry = pPrev; + } + } + + FreeDriverMap(driverMap); + + return Success; +} + +/* + * ValidateFontDir looks for a valid font directory for the specified + * printer model within the specified configuration directory. It returns + * the directory name, or NULL if no valid font directory was found. + * It is the caller's responsibility to free the returned font directory + * name. + */ +static char * +ValidateFontDir( + char *configDir, + char *modelName) +{ + char *pathName; + + if(!configDir || !modelName) + return (char *)NULL; + + pathName = (char *)xalloc(strlen(configDir) + strlen(MODELDIRNAME) + + strlen(modelName) + strlen(FONTDIRNAME) + + strlen("fonts.dir") + 5); + if(!pathName) + return (char *)NULL; + sprintf(pathName, "%s/%s/%s/%s/%s", configDir, MODELDIRNAME, modelName, + FONTDIRNAME, "fonts.dir"); + if(access(pathName, R_OK) != 0) + { + xfree(pathName); + return (char *)NULL; + } + pathName[strlen(pathName) - 9] = (char)'\0'; /* erase fonts.dir */ + return pathName; +} + +/* + * FindFontDir returns a pointer to the path name of the font directory + * for the specified printer model name, if such a directory exists. + * The directory contents are superficially checked for validity. + * The caller must free the returned char *. + * + * We first look in the locale-specific model-config directory, and + * then fall back to the C language model-config directory. + */ +static char * +FindFontDir( + char *modelName) +{ + char *configDir, *fontDir; + + if(!modelName || !strlen(modelName)) + return (char *)NULL; + + configDir = XpGetConfigDir(TRUE); + if(fontDir = ValidateFontDir(configDir, modelName)) + { + xfree(configDir); + return fontDir; + } + + if(configDir) + xfree(configDir); + configDir = XpGetConfigDir(FALSE); + fontDir = ValidateFontDir(configDir, modelName); + + xfree(configDir); + + return fontDir; +} + +/* + * AddToFontPath adds the specified font path element to the global + * defaultFontPath string. It adds the keyword "PRINTER:" to the front + * of the path to denote that this is a printer-specific font path + * element. + */ +static char PATH_PREFIX[] = "PRINTER:"; +static int PATH_PREFIX_LEN = sizeof(PATH_PREFIX) - 1; /* same as strlen() */ + +static void +AddToFontPath( + char *pathName) +{ + char *newPath; + Bool freeOldPath; + + if(defaultFontPath == origFontPath) + freeOldPath = FALSE; + else + freeOldPath = TRUE; + + newPath = (char *)xalloc(strlen(defaultFontPath) + strlen(pathName) + + PATH_PREFIX_LEN + 2); + + sprintf(newPath, "%s%s,%s", PATH_PREFIX, pathName, defaultFontPath); + + if(freeOldPath) + xfree(defaultFontPath); + + defaultFontPath = newPath; + return; +} + +/* + * AugmentFontPath adds printer-model-specific font path elements to + * the front of the font path global variable "defaultFontPath" (dix/globals.c). + * We can't call SetFontPath() because the font code has not yet been + * initialized when InitOutput is called (from whence this routine is called). + * + * This utilizes the static variables origFontPath and + * freeDefaultFontPath to track the original contents of defaultFontPath, + * and to properly free the modified version upon server recycle. + */ +static void +AugmentFontPath() +{ + char *newPath, *modelID, **allIDs = (char **)NULL; + PrinterDbPtr pDb, pDbEntry; + int numModels, i; + + if(!origFontPath) + origFontPath = defaultFontPath; + + if(freeDefaultFontPath) + { + xfree(defaultFontPath); + defaultFontPath = origFontPath; + freeDefaultFontPath = FALSE; + } + + /* + * Build a list of printer models to check for internal fonts. + */ + for(pDbEntry = printerDb, numModels = 0; + pDbEntry != (PrinterDbPtr)NULL; + pDbEntry = pDbEntry->next) + { + modelID = + (char*)XpGetPrinterAttribute(pDbEntry->name, + "xp-model-identifier"); + + if(modelID && strlen(modelID) != 0) + { + /* look for current model in the list of allIDs */ + for(i = 0; i < numModels; i++) + { + if(!strcmp(modelID, allIDs[i])) + { + modelID = (char *)NULL; + break; + } + } + } + + /* + * If this printer's model-identifier isn't in the allIDs list, + * then add it to allIDs. + */ + if(modelID && strlen(modelID) != 0) + { + allIDs = (char **)xrealloc(allIDs, (numModels+2) * sizeof(char *)); + if(allIDs == (char **)NULL) + return; + allIDs[numModels] = modelID; + allIDs[numModels + 1] = (char *)NULL; + numModels++; + } + } + + /* for each model, check for a valid font directory, and add it to + * the front of defaultFontPath. + */ + for(i = 0; allIDs != (char **)NULL && allIDs[i] != (char *)NULL; i ++) + { + char *fontDir; + if(fontDir = FindFontDir(allIDs[i])) + { + AddToFontPath(fontDir); + xfree(fontDir); + freeDefaultFontPath = TRUE; + } + } + + if(allIDs) + xfree(allIDs); + + return; +} + +/* + * XpClientIsBitmapClient is called by the font code to find out if + * a particular client should be granted access to bitmap fonts. + * This function works by + * calling XpContextOfClient (in Xserver/Xext/xprint.c) to determine + * the context associated with the client, and then queries the context's + * attributes to determine whether the bitmap fonts should be visible. + * It looks at the value of the xp-listfonts-mode document/page attribute to + * see if xp-list-glyph-fonts has been left out of the mode list. Only + * if the xp-listfonts-mode attribute exists, and it does not contain + * xp-list-glyph-fonts does this function return FALSE. In any other + * case the funtion returns TRUE, indicating that the bitmap fonts + * should be visible to the client. + */ +Bool +XpClientIsBitmapClient( + ClientPtr client) +{ + XpContextPtr pContext; + char *mode; + + if(!(pContext = XpContextOfClient(client))) + return TRUE; + + /* + * Check the page attributes, and if it's not defined there, then + * check the document attributes. + */ + mode = XpGetOneAttribute(pContext, XPPageAttr, "xp-listfonts-mode"); + if(!mode || !strlen(mode)) + { + mode = XpGetOneAttribute(pContext, XPDocAttr, "xp-listfonts-mode"); + if(!mode || !strlen(mode)) + return TRUE; + } + + if(!strstr(mode, "xp-list-glyph-fonts")) + return FALSE; + + return TRUE; +} +/* + * XpClientIsPrintClient is called by the font code to find out if + * a particular client has set a context which references a printer + * which utilizes a particular font path. This function works by + * calling XpContextOfClient (in Xserver/Xext/xprint.c) to determine + * the context associated with the client, and then looks up the + * font directory for the context. The font directory is then compared + * with the directory specified in the FontPathElement which is passed in. + */ +Bool +XpClientIsPrintClient( + ClientPtr client, + FontPathElementPtr fpe) +{ + XpContextPtr pContext; + char *modelID, *fontDir; + + if(!(pContext = XpContextOfClient(client))) + return FALSE; + + if (!fpe) + return TRUE; + + modelID = XpGetOneAttribute(pContext, XPPrinterAttr, "xp-model-identifier"); + if(!modelID || !strlen(modelID)) + return FALSE; + + if(!(fontDir = FindFontDir(modelID))) + return FALSE; + + /* + * The grunge here is to ignore the PATH_PREFIX at the front of the + * fpe->name. + */ + if(fpe->name_length < PATH_PREFIX_LEN || + (strlen(fontDir) != (fpe->name_length - PATH_PREFIX_LEN)) || + strncmp(fontDir, fpe->name + PATH_PREFIX_LEN, + fpe->name_length - PATH_PREFIX_LEN)) + { + xfree(fontDir); + return FALSE; + } + xfree(fontDir); + return TRUE; +} + +static void +AddFormats(pScreenInfo, driverName) + ScreenInfo *pScreenInfo; + char *driverName; +{ + int i, j; + driverInitRec *pInitRec; + int numDrivers = sizeof(driverInits)/sizeof(driverInitRec); + PixmapFormatRec *formats; + int numfmts; + + for (pInitRec = driverInits, i = 0; i < numDrivers; pInitRec++, i++) + { + if ( !strcmp( driverName, pInitRec->driverName ) ) + break; + } + if (i >= numDrivers) + return; + formats = pInitRec->pFmts; + numfmts = pInitRec->numFmts; + for (i = 0; i < numfmts && pScreenInfo->numPixmapFormats < MAXFORMATS; i++) + { + for (j = 0; j < pScreenInfo->numPixmapFormats; j++) { + if (pScreenInfo->formats[j].depth == formats[i].depth && + pScreenInfo->formats[j].bitsPerPixel == formats[i].bitsPerPixel && + pScreenInfo->formats[j].scanlinePad == formats[i].scanlinePad) + break; + } + if (j == pScreenInfo->numPixmapFormats) { + pScreenInfo->formats[j] = formats[i]; + pScreenInfo->numPixmapFormats++; + } + } +} + +/************************************************************ + * PrinterInitOutput -- + * This routine is to be called from a ddx's InitOutput + * during the server startup initialization, and when + * the server is to be reset. The routine creates the + * screens associated with configured printers by calling + * dix:AddScreen. The configuration information comes from a + * database read from the X*printers file. + * + * Results: + * The array of ScreenRec pointers referenced by + * pScreenInfo->screen is increased by the addition + * of the printer screen(s), as is the value of + * pScreenInfo->numScreens. This is done via calls + * to AddScreen() in dix. + * + ************************************************************/ + +void +PrinterInitOutput(pScreenInfo, argc, argv) + ScreenInfo *pScreenInfo; + int argc; + char **argv; +{ + PrinterDbPtr pDb, pDbEntry; + int driverCount = 0, i; + char **driverNames; + char *configDir; + + /* + * this little test is just a warning at startup to make sure + * that the config directory exists. + * + * what this ugly looking if says is that if both ways of + * calling configDir works and both directories don't exist, + * then print an error saying we can't find the non-lang one. + */ + if (((configDir = XpGetConfigDir(TRUE)) != NULL) && + (access(configDir, F_OK) == 0)) + { + xfree(configDir); + } + else if (((configDir = XpGetConfigDir(FALSE)) != NULL) && + (access(configDir, F_OK) == 0)) + { + xfree(configDir); + } + else { + ErrorF("Xp Extension: could not find config dir %s\n", + configDir ? configDir : XPRINTDIR); + + if (configDir) xfree(configDir); + } + + if(printerDb != (PrinterDbPtr)NULL) + FreePrinterDb(); + + /* + * Calling BuildPrinterDb serves to build the printer database, + * and to initialize the attribute store for each printer. + * The driver can, if it so desires, modify the attribute + * store at a later time. + */ + if((pDb = BuildPrinterDb()) == (PrinterDbPtr)NULL) return; + + /* + * We now have to decide how many screens to initialize, and call + * AddScreen for each one. The printerDb must be properly initialized + * for at least one screen's worth of printers prior to calling AddScreen + * because InitPrintDrivers reads the printerDb to determine which + * driver(s) to init on a particular screen. + * We put each driver's printers on a different + * screen, and call AddScreen for each screen/driver pair. + */ + /* count the number of printers */ + for(pDbEntry = pDb, driverCount = 0; pDbEntry != (PrinterDbPtr)NULL; + pDbEntry = pDbEntry->next, driverCount++) + ; + /* + * Allocate memory for the worst case - a driver per printer + */ + driverNames = (char **)xalloc(sizeof(char *) * driverCount); + + /* + * Assign the driver for the first printer to the first screen + */ + pDb->screenNum = screenInfo.numScreens; + driverNames[0] = pDb->driverName; + driverCount = 1; + AddFormats(pScreenInfo, pDb->driverName); + + /* + * For each printer, look to see if its driver is already assigned + * to a screen, and if so copy that screen number into the printerDb. + * Otherwise, assign a new screen number to the driver for this + * printer. + */ + for(pDbEntry = pDb; pDbEntry != (PrinterDbPtr)NULL; + pDbEntry = pDbEntry->next) + { + Bool foundMatch; + + for(i = 0, foundMatch = FALSE; i < driverCount; i++) + { + if(!strcmp(driverNames[i], pDbEntry->driverName)) + { + foundMatch = TRUE; + pDbEntry->screenNum = screenInfo.numScreens + i; + break; + } + } + if(foundMatch == FALSE) + { + driverNames[driverCount] = pDbEntry->driverName; + pDbEntry->screenNum = screenInfo.numScreens + driverCount; + AddFormats(pScreenInfo, pDbEntry->driverName); + driverCount++; + } + } + + for(i = 0; i < driverCount; i++) + { + int curScreen = screenInfo.numScreens; + if(AddScreen(InitPrintDrivers, argc, argv) < 0) + { + PrinterDbPtr pPrev; + /* + * AddScreen failed, so we pull the associated printers + * from the list. + */ + ErrorF("Xp Extension: Could not add screen for driver %s\n", + driverNames[i]); + for(pPrev = pDbEntry = printerDb; pDbEntry != (PrinterDbPtr)NULL; + pDbEntry = pDbEntry->next) + { + if(pDbEntry->screenNum == curScreen) + { + if(pPrev == printerDb) + { + printerDb = pDbEntry->next; + pPrev = printerDb; + } + else + pPrev->next = pDbEntry->next; + + xfree(pDbEntry->name); + xfree(pDbEntry); + pDbEntry = pPrev; + } + else + { + if(pDbEntry->screenNum > curScreen) + pDbEntry->screenNum--; + pPrev = pDbEntry; + } + } + } + } + + xfree(driverNames); + + AugmentFontPath(); + + if(pScreenInfo->numScreens > MAXSCREENS) + { + ErrorF("The number of printer screens requested "); + ErrorF("exceeds the allowable limit of %d screens.\n", MAXSCREENS); + ErrorF("Please reduce the number of requested printers in your "); + ErrorF("\nX%sprinters file.", display); + ErrorF("Server exiting...\n"); + exit(-1); + } +} + +/* + * InitPrintDrivers is called from dix:AddScreen. It in turn calls the + * driver initialization routine for any and all drivers which are + * implicated in supporting printers on the particular screen number + * specified by the "index" parameter. The printerDb variable is used + * to determine which printers are to be associated with a particular + * screen. + */ +static Bool +InitPrintDrivers(index, pScreen, argc, argv) + int index; + ScreenPtr pScreen; + int argc; + char **argv; +{ + PrinterDbPtr pDb, pDb2; + + GenericScreenInit(index, pScreen, argc, argv); + + for(pDb = printerDb; pDb != (PrinterDbPtr)NULL; pDb = pDb->next) + { + if(pDb->screenNum == index) + { + Bool callInit = TRUE; + for(pDb2 = printerDb; pDb2 != pDb; pDb2 = pDb2->next) + { + if(!strcmp(pDb->driverName, pDb2->driverName)) + { + callInit = FALSE; + break; + } + } + if(callInit == TRUE) + { + Bool (*initFunc)(); + initFunc = GetInitFunc(pDb->driverName); + if(initFunc(index, pScreen, argc, argv) == FALSE) + { + /* XXX - What do I do if the driver's init fails? */ + } + } + } + } + return TRUE; +} + +void +_XpVoidNoop() +{ + return; +} + +Bool +_XpBoolNoop() +{ + return TRUE; +} + +/* + * GenericScreenInit - The common initializations required by all + * printer screens and drivers. It sets the screen's cursor functions + * to Noops, and computes the maximum screen (i.e. medium) dimensions. + */ + +static void +GenericScreenInit( index, pScreen, argc, argv ) + int index; + ScreenPtr pScreen; + int argc; + char **argv; +{ + int i; + float fWidth, fHeight, maxWidth, maxHeight; + unsigned short width, height; + PrinterDbPtr pDb, pDb2; + int res, maxRes; + + /* + * Set the cursor ops to no-op functions. + */ + pScreen->DisplayCursor = (DisplayCursorProcPtr)_XpBoolNoop; + pScreen->RealizeCursor = (RealizeCursorProcPtr)_XpBoolNoop; + pScreen->UnrealizeCursor = (UnrealizeCursorProcPtr)_XpBoolNoop; + pScreen->SetCursorPosition = (SetCursorPositionProcPtr)_XpBoolNoop; + pScreen->ConstrainCursor = (ConstrainCursorProcPtr)_XpVoidNoop; + pScreen->CursorLimits = (CursorLimitsProcPtr)_XpVoidNoop; + pScreen->RecolorCursor = (RecolorCursorProcPtr)_XpVoidNoop; + + /* + * Find the largest paper size for all the printers on the given + * screen. + */ + maxRes = 0; + maxWidth = maxHeight = 0.0; + for( pDb = printerDb; pDb != (PrinterDbPtr)NULL; pDb = pDb->next) + { + if(pDb->screenNum == index) + { + + XpValidatePoolsRec *pValRec; + pVFunc dimensionsFunc; + + GetDimFuncAndRec(pDb->driverName, &pValRec, &dimensionsFunc); + if(dimensionsFunc != (pVFunc)NULL) + dimensionsFunc(pDb->name, pValRec, &fWidth, &fHeight, &res); + else + XpGetMaxWidthHeightRes(pDb->name, pValRec, &fWidth, + &fHeight, &res); + if( res > maxRes ) + maxRes = res; + if( fWidth > maxWidth ) + maxWidth = fWidth; + if( fHeight > maxHeight ) + maxHeight = fHeight; + } + } + + width = (unsigned short) (maxWidth * maxRes / 25.4); + height = (unsigned short) (maxHeight * maxRes / 25.4); + pScreen->width = pScreen->height = ( width > height ) ? width : + height; + + pScreen->mmWidth = pScreen->mmHeight = ( maxWidth > maxHeight ) ? + (unsigned short)(maxWidth + 0.5) : + (unsigned short)(maxHeight + 0.5); +} + +/* + * QualifyName - takes an unqualified file name such as X6printers and + * a colon-separated list of directory path names such as + * /etc/opt/dt:/opt/dt/config. + * + * Returns a fully qualified file path name such as /etc/opt/dt/X6printers. + * The returned value is malloc'd, and the caller is responsible for + * freeing the associated memory. + */ +static char * +QualifyName(fileName, searchPath) + char *fileName; + char *searchPath; +{ + char * curPath = searchPath; + char * nextPath; + char * chance; + FILE *pFile; + + if (fileName == NULL || searchPath == NULL) + return NULL; + + while (1) { + if ((nextPath = strchr(curPath, ':')) != NULL) + *nextPath = 0; + + chance = (char *)xalloc(strlen(curPath) + strlen(fileName) + 2); + sprintf(chance,"%s/%s",curPath,fileName); + + /* see if we can read from the file */ + if((pFile = fopen(chance, "r")) != (FILE *)NULL) + { + fclose(pFile); + /* ... restore the colon, .... */ + if (nextPath) + *nextPath = ':'; + + return chance; + } + + xfree(chance); + + if (nextPath == NULL) /* End of path list? */ + break; + + /* try the next path */ + curPath = nextPath + 1; + } + return NULL; +} + +/* + * FillPrinterListEntry fills in a single XpDiListEntry element with data + * derived from the supplied PrinterDbPtr element. + * + * XXX A smarter (i.e. future) version of this routine might inspect the + * XXX "locale" parameter and attempt to match the "description" and + * XXX "localeName" elements of the XpDiListEntry to the specified locale. + */ +static void +FillPrinterListEntry(pEntry, pDb, localeLen, locale) + XpDiListEntry *pEntry; + PrinterDbPtr pDb; + int localeLen; + char *locale; +{ + static char *localeStr = (char *)NULL; + + if(localeStr == (char *)NULL) + localeStr = strdup(setlocale(LC_ALL, (const char *)NULL)); + + pEntry->name = pDb->name; + pEntry->description = + (char*)XpGetPrinterAttribute(pDb->name, "descriptor"); + pEntry->localeName = localeStr; + pEntry->rootWinId = WindowTable[pDb->screenNum]->drawable.id; +} + +/* + * GetPrinterListInfo fills in the XpDiListEntry struct pointed to by the + * parameter pEntry with the information regarding the printer specified + * by the name and nameLen parameters. The pointers placed in the + * XpDiListEntry structure MUST NOT be freed by the caller. They are + * pointers into existing long-lived databases. + * + */ +static Bool +GetPrinterListInfo(pEntry, nameLen, name, localeLen, locale) + XpDiListEntry *pEntry; + int nameLen; + char *name; + int localeLen; + char *locale; +{ + PrinterDbPtr pDb, pDb2; + + for(pDb = printerDb; pDb != (PrinterDbPtr)NULL; pDb = pDb->next) + { + if(strlen(pDb->name) == nameLen && !strncmp(pDb->name, name, nameLen)) + { + FillPrinterListEntry(pEntry, pDb, localeLen, locale); + return TRUE; + } + } + return FALSE; +} + +/* + * XpDiFreePrinterList is the approved method of releasing memory used + * for a printer list. + */ +void +XpDiFreePrinterList(list) + XpDiListEntry **list; +{ + int i; + + for(i = 0; list[i] != (XpDiListEntry *)NULL; i++) + xfree(list[i]); + xfree(list); +} + +/* + * XpDiGetPrinterList returns a pointer to a NULL-terminated array of + * XpDiListEntry pointers. Each entry structure contains the name, + * description, root window, and locale of a printer. The call returns + * either a list of all printers configured on the server, or it returns + * the information for one specific printer depending on the values passed + * in. Non-NULL values passed in indicate that only the information for + * the one specific printer is desired, while NULL values indicate that + * the information for all printers is desired. + */ +XpDiListEntry ** +XpDiGetPrinterList(nameLen, name, localeLen, locale) + int nameLen; + char *name; + int localeLen; + char *locale; +{ + XpDiListEntry **pList; + + if(!nameLen || name == (char *)NULL) + { + int i; + PrinterDbPtr pDb, pDb2; + + for(pDb = printerDb, i = 0; pDb != (PrinterDbPtr)NULL; + pDb = pDb->next, i++) + ; + + if((pList = (XpDiListEntry **)xalloc((i+1) * sizeof(XpDiListEntry *))) + == (XpDiListEntry **)NULL) + return pList; + + pList[i] = (XpDiListEntry *)NULL; + for(pDb = printerDb, i = 0; pDb != (PrinterDbPtr)NULL; + pDb = pDb->next, i++) + { + if((pList[i] = (XpDiListEntry *)xalloc(sizeof(XpDiListEntry)))== + (XpDiListEntry *)NULL) + { + XpDiFreePrinterList(pList); + return (XpDiListEntry **)NULL; + } + FillPrinterListEntry(pList[i], pDb, localeLen, locale); + } + } + else + { + if((pList = (XpDiListEntry **)xalloc(2 * sizeof(XpDiListEntry *))) == + (XpDiListEntry **)NULL) + return pList; + + if((pList[0] = (XpDiListEntry *)xalloc(sizeof(XpDiListEntry))) == + (XpDiListEntry *)NULL) + { + xfree(pList); + return (XpDiListEntry **)NULL; + } + pList[1] = (XpDiListEntry *)NULL; + if(GetPrinterListInfo(pList[0], nameLen, name, localeLen, locale) == + FALSE) + { + xfree(pList[0]); + pList[0] = (XpDiListEntry *)NULL; + } + } + return pList; +} + +WindowPtr +XpDiValidatePrinter(printerName, printerNameLen) + char *printerName; + int printerNameLen; +{ + PrinterDbPtr pCurEntry; + WindowPtr pWin; + + for(pCurEntry = printerDb; + pCurEntry != (PrinterDbPtr)NULL; pCurEntry = pCurEntry->next) + { + if(strlen(pCurEntry->name) == printerNameLen && + !strncmp(pCurEntry->name, printerName, printerNameLen)) + return WindowTable[pCurEntry->screenNum]; + } + return (WindowPtr)NULL; +} + +/* + * XpDiGetDriverName takes a screen index and a printer name, and returns + * a pointer to the name of the driver to be used for the specified printer + * on the specified screen. + */ +char * +XpDiGetDriverName(index, printerName) + int index; + char *printerName; +{ + + PrinterDbPtr pCurEntry; + + for(pCurEntry = printerDb; + pCurEntry != (PrinterDbPtr)NULL; pCurEntry = pCurEntry->next) + { + if(pCurEntry->screenNum == index && + !strcmp(pCurEntry->name, printerName)) + return pCurEntry->driverName; + } + + return (char *)NULL; /* XXX Should we supply a default driverName? */ +} diff --git a/Xprint/Oid.c b/Xprint/Oid.c new file mode 100644 index 000000000..3fe926c00 --- /dev/null +++ b/Xprint/Oid.c @@ -0,0 +1,3177 @@ +/* $Xorg: Oid.c,v 1.3 2000/08/17 19:48:06 cpqbld Exp $ */ +/* +(c) Copyright 1996 Hewlett-Packard Company +(c) Copyright 1996 International Business Machines Corp. +(c) Copyright 1996 Sun Microsystems, Inc. +(c) Copyright 1996 Novell, Inc. +(c) Copyright 1996 Digital Equipment Corp. +(c) Copyright 1996 Fujitsu Limited +(c) Copyright 1996 Hitachi, Ltd. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the names of the copyright holders shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from said +copyright holders. +*/ +#include <stdio.h> +#include <stdlib.h> +#include <ctype.h> +#include "Oid.h" +#include <X11/Xfuncs.h> /* for memmove */ + +/* + * XpOidNotify value strings + */ +#define NOTIFY_EMAIL_STR "{{event-report-job-completed} electronic-mail}" +#define NOTIFY_NONE_STR "{}" + +#define SafeStrLen(s) ((s) ? strlen((s)) : 0) + +/* + * entry type for the object identifier string map + */ +typedef struct _XpOidStringMapEntry +{ + const char* string; + int length; + int msg_set; + int msg_number; + const char* default_message; + +} XpOidStringMapEntry; + +/* + * include the auto-generated static XpOidStringMap + */ +#include "OidStrs.h" + +/* + * XpOid static function declarations + */ +static XpOid XpOidParse(const char* value_string, + const char** ptr_return); +/* + * XpOidList static function declarations + */ +static XpOidList* XpOidListParse(const char* value_string, + const XpOidList* valid_oids, + const char** ptr_return, int i); + +/* + * XpOidList static function declarations + */ +static XpOidCardList* XpOidCardListParse(const char* value_string, + const XpOidCardList* valid_cards, + const char** ptr_return, int i); + +/* + * XpOidMediumSourceSize static function declarations + */ +static XpOidMediumSS* MediumSSParse(const char* value_string, + const XpOidList* valid_trays, + const XpOidList* valid_medium_sizes, + const char** ptr_return, int i); +static XpOidMediumContinuousSize* MediumContinuousSizeParse(const char*, + const char**); +static void MediumContinuousSizeDelete(XpOidMediumContinuousSize* me); +static XpOidMediumDiscreteSizeList* MediumDiscreteSizeListParse(const char*, + const XpOidList*, + const char**, + int i); +static void MediumDiscreteSizeListDelete(XpOidMediumDiscreteSizeList* list); + +static BOOL ParseArea(const char* value_string, + const char** ptr_return, + XpOidArea* area_return); +static BOOL ParseRealRange(const char* value_string, + const char** ptr_return, + XpOidRealRange* range_return); + +/* + * XpOidTrayMediumList static function declarations + */ +static XpOidTrayMediumList* TrayMediumListParse(const char* value_string, + const XpOidList* valid_trays, + const char** ptr_return, + int i); +static void TrayMediumListValidate(XpOidTrayMediumList* me, + const XpOidMediumSS* msss); + +/* + * XpOidDocFmt + */ +static BOOL XpOidDocFmtNext(XpOidDocFmt* doc_fmt, + const char* value_string, + const char** ptr_return); + +/* + * XpOidDocFmtListParse + */ +static XpOidDocFmtList* XpOidDocFmtListParse(const char* value_string, + const XpOidDocFmtList* valid_fmts, + const char** ptr_return, int i); + +/* + * misc. parsing static function declarations + */ +static BOOL ParseBoolValue(const char* value_string, + const char** ptr_return, + BOOL* bool_return); +static BOOL ParseRealValue(const char* value_string, + const char** ptr_return, + float* real_return); +static BOOL ParseSeqEnd( + const char* value_string, + const char** ptr_return); +static BOOL ParseSeqStart( + const char* value_string, + const char** ptr_return); +static BOOL ParseUnspecifiedValue( + const char* value_string, + const char** ptr_return); +static int SpanToken( + const char* string); +static int SpanWhitespace( + const char* string); + +/* + * String comparison function. + */ +#ifdef HAVE_STRCASECMP +# define StrnCaseCmp(s1, s2, len) strncasecmp(s1, s2, len) +#else +static int StrnCaseCmp(const char *s1, const char *s2, size_t len); +#endif + +/* + * ------------------------------------------------------------------------ + * Name: XpOidString + * + * Description: + * + * Obtain the string representation of an XpOid. + * + * Example: XpOidString(xpoid_copy_count) returns "copy-count". + * + * Return value: + * + * A const pointer to the string. + */ +const char* +XpOidString(XpOid xp_oid) +{ + /* + * XpOid enum values are index values into the string map + */ + return XpOidStringMap[xp_oid].string; +} + +/* + * ------------------------------------------------------------------------ + * Name: XpOidStringLength + * + * Description: + * + * Obtain the length of the string representation for a given + * XpOid. + * + * Return value: + * + * The string length in bytes. + * + */ +int +XpOidStringLength(XpOid xp_oid) +{ + /* + * XpOid enum values are index values into the string map + */ + return XpOidStringMap[xp_oid].length; +} + +/* + * ------------------------------------------------------------------------ + * Name: XpOidFromString + * + * Description: + * + * Obtains the XpOid given a string representation of an XpOid. + * + * Example: XpOidFromString("copy-count") returns 'xpoid_copy_count'. + * + * Return value: + * + * The XpOid if successful. 'xpoid_none' if the string pointed to by + * 'value is not recognized or if 'value' is NULL. + */ +XpOid +XpOidFromString(const char* value) +{ + if(value == (const char*)NULL) + return xpoid_none; + else + return XpOidParse(value, (const char**)NULL); +} + +/* + * ------------------------------------------------------------------------ + * Name: XpOidParse + * + * Description: + * + * Parse the next whitespace-delimited string from 'value_string' + * updating 'ptr_return' to point to the next unparsed location in + * 'value_string'. 'ptr_return' can be NULL. + * + * Return value: + * + * The corresponding XpOid for the parsed name string. + * A return value of xpoid_none is returned if the parsed name + * was not a valid oid or if no name was found. + * + */ +static XpOid +XpOidParse(const char* value_string, + const char** ptr_return) +{ + const char* ptr; + int length; + int i; + /* + * skip leading whitespace + */ + ptr = value_string + SpanWhitespace(value_string); + /* + * get the whitespace-delimited token length + */ + length = SpanToken(ptr); + /* + * match the oid string in the map + */ + for(i = 0; i < XpOidStringMapCount; i++) + if(length == XpOidStringMap[i].length) + if(strncmp(ptr, XpOidStringMap[i].string, length) == 0) + break; + if(i == XpOidStringMapCount) + i = xpoid_none; + /* + * update the return pointer and return + */ + if(ptr_return != (const char**)NULL) + *ptr_return = ptr+length; + return i; +} + +/* + * ------------------------------------------------------------------------ + * Name: XpOidListNew + * + * Description: + * + * Creates a new XpOidList initialized from a whitespace-delimited + * list of recognized string representations of oids. The returned + * list will contain only oids found within the passed 'valid_oids' + * XpOidList. + * + * Note: One may notice that in order to create an XpOidList with + * this function, an XpOidList is needed; the 'valid_oids' list + * is often an statically initialized structure. XpOidListInit + * can also be used. + * + * Return value: + * + * NULL if the passed 'value_string' is NULL. + * + * If the list indicated by 'value_string' is empty or contains only + * unrecognized oid string representations, a new XpOidList + * containing zero elements is returned. + * + * If 'valid_oids' is NULL all oids are considered valid. + * + */ +XpOidList* +XpOidListNew(const char* value_string, + const XpOidList* valid_oids) +{ + if(value_string == (const char*)NULL) + return (XpOidList*)NULL; + else + { + const char* ptr; + return XpOidListParse(value_string, valid_oids, &ptr, 0); + } +} + +/* + * ------------------------------------------------------------------------ + * Name: XpOidListDelete + * + * Description: + * + * Frees the memory allocated for 'list'. + * + * Return value: + * + * None. + * + */ +void +XpOidListDelete(XpOidList* list) +{ + if(list != (XpOidList*)NULL) + { + XpOidFree((char*)list->list); + XpOidFree((char*)list); + } +} + +/* + * ------------------------------------------------------------------------ + * Name: XpOidListParse + * + * Description: + * + * This function recursively parses the whitespace-delimited list of + * oid string representations passed via 'value_string'. Oids are + * only added to the resulting list if they are found within the + * passed 'valid_oids' XpOidList. + * + * 'ptr_return' points to a char* variable allocated by the + * caller, and is really only of use during recursion (upon return to + * the original caller, it will point to the end of value_string). + * + * 'value_string' and 'ptr_return' *cannot* be NULL. + * + * Return value: + * + * A newly allocated and initialized XpOidList. + * + * If the list indicated by 'value_string' is empty or contains only + * unrecognized oid string representations, a new XpOidList + * containing zero elements is returned. + * + * If 'valid_oids' is NULL all oids are considered valid. + * + */ +static XpOidList* +XpOidListParse(const char* value_string, + const XpOidList* valid_oids, + const char** ptr_return, + int i) +{ + XpOid oid; + XpOidList* list; + /* + * parse the next valid oid out of the value string + */ + ptr_return = &value_string; + while(1) + { + if(**ptr_return == '\0') + { + /* + * end of value string; stop parsing + */ + oid = xpoid_none; + break; + } + /* + * parse the next oid from the value + */ + oid = XpOidParse(*ptr_return, ptr_return); + if(xpoid_none == oid) + { + /* + * unrecognized oid; keep parsing + */ + continue; + } + if((const XpOidList*)NULL == valid_oids + || + XpOidListHasOid(valid_oids, oid)) + { + /* + * valid oid found; stop parsing + */ + break; + } + } + + if(oid == xpoid_none) + { + /* + * end of value string; allocate the list structure + */ + list = (XpOidList*)XpOidCalloc(1, sizeof(XpOidList)); + list->count = i; + list->list = (XpOid*)XpOidCalloc(i, sizeof(XpOid)); + } + else + { + /* + * recurse + */ + list = XpOidListParse(*ptr_return, valid_oids, ptr_return, i+1); + /* + * set the oid in the list + */ + list->list[i] = oid; + } + /* + * return + */ + return list; +} + +/* + * ------------------------------------------------------------------------ + * Name: XpOidListHasOid + * + * Description: + * + * Determines if 'oid' is an element of 'list'. + * + * Return value: + * + * xTrue if the oid is found in the list. + * + * xFalse if the oid is not in the list, or if 'list' is NULL. + * + */ +BOOL +XpOidListHasOid(const XpOidList* list, XpOid oid) +{ + int i; + if(list != (XpOidList*)NULL) + for(i = 0; i < list->count; i++) + if(list->list[i] == oid) + return xTrue; + return xFalse; +} + +/* + * ------------------------------------------------------------------------ + * Name: XpOidListGetIndex + * + * Description: + * + * Returns the array index of 'oid' in 'list' + * + * Return value: + * + * The index of 'oid' in list. + * + * -1 if the oid is not in the list, or if 'list' is NULL. + * + */ +int +XpOidListGetIndex(const XpOidList* list, XpOid oid) +{ + int i; + if(list != (XpOidList*)NULL) + for(i = 0; i < list->count; i++) + if(list->list[i] == oid) + return i; + return -1; +} + +/* + * ------------------------------------------------------------------------ + * Name: XpOidListString + * + * Description: + * + * Creates a string representation of an XpOidList structure. + * + * Return value: + * + * A newly allocated + * + */ +char* +XpOidListString(const XpOidList* me) +{ + int i; + int length; + char* str; + char* ptr; + /* + * allocate enough memory for the oid string representations, + * including intervening whitespace + */ + for(i = 0, length = 0; i < XpOidListCount(me); i++) + length += XpOidStringLength(XpOidListGetOid(me, i)) + 1; + str = XpOidMalloc(length+1); + /* + * format the list + */ + for(i = 0, ptr = str; i < XpOidListCount(me); i++) +#if defined(sun) && !defined(SVR4) + { + sprintf(ptr, "%s ", XpOidString(XpOidListGetOid(me, i))); + ptr += strlen(ptr); + } +#else + ptr += sprintf(ptr, "%s ", XpOidString(XpOidListGetOid(me, i))); +#endif + /* + * chop trailing whitespace or terminate empty string + */ + str[length] = '\0'; + /* + * return + */ + return str; +} + +/* + * ------------------------------------------------------------------------ + * Name: XpOidLinkedListNew + * + * Description: + * + * Creates a new instance of an empty XpOidLinkedList. + * + * Return value: + * + * The new XpOidLinkedList. + * + */ +XpOidLinkedList* +XpOidLinkedListNew() +{ + return (XpOidLinkedList*)XpOidCalloc(1, sizeof(XpOidLinkedList)); +} + +/* + * ------------------------------------------------------------------------ + * Name: XpOidLinkedListDelete + * + * Description: + * + * Frees the memory allocated for a XpOidLinkedList. + * + * Return value: + * + * None. + * + */ +void +XpOidLinkedListDelete(XpOidLinkedList* me) +{ + if(me != (XpOidLinkedList*)NULL) + { + while(me->head) + { + me->current = me->head; + me->head = me->current->next; + XpOidFree((char*)me->current); + } + XpOidFree((char*)me); + } +} + +/* + * ------------------------------------------------------------------------ + * Name: XpOidLinkedListGetOid + * + * Description: + * + * Retrieves the oid at position 'i' (zero-based) in the + * XpOidLinkedList 'me'. + * + * Return value: + * + * The oid at position 'i'. + * + * xpoid_none if the oid was not found, or the list is empty (or if + * the list contains xpoid_none at position 'i'). + */ +XpOid +XpOidLinkedListGetOid(XpOidLinkedList* me, int i) +{ + if(me == (XpOidLinkedList*)NULL || i < 0 || i >= me->count) + { + return xpoid_none; + } + else + { + me->current = me->head; + while(i--) me->current = me->current->next; + return me->current->oid; + } +} + +/* + * ------------------------------------------------------------------------ + * Name: XpOidLinkedListAddOid + * + * Description: + * + * Adds an oid to the end of an XpOidLinkedList. + * + * Return value: + * + * None. + * + */ +void +XpOidLinkedListAddOid(XpOidLinkedList* me, XpOid oid) +{ + me->current = (XpOidNode)XpOidCalloc(1, sizeof(struct XpOidNodeStruct)); + me->current->oid = oid; + ++me->count; + if(me->tail) + { + me->tail->next = me->current; + me->tail = me->current; + } + else + me->head = me->tail = me->current; +} + +/* + * ------------------------------------------------------------------------ + * Name: XpOidLinkedListGetIndex + * + * Description: + * + * Returns the position of an oid in a XpOidLinkedList. + * + * Return value: + * + * The zero-based position of 'oid' in the list. + * + * -1 if the oid is not in the list, or if 'me' is NULL. + * + */ +int +XpOidLinkedListGetIndex(XpOidLinkedList* me, XpOid oid) +{ + if((XpOidLinkedList*)NULL != me) + { + int i = 0; + me->current = me->head; + while(me->current) + if(me->current->oid == oid) + { + return i; + } + else + { + ++i; + me->current = me->current->next; + } + } + return -1; +} + +/* + * ------------------------------------------------------------------------ + * Name: XpOidLinkedListHasOid + * + * Description: + * + * Determines if an oid is an element of a XpOidLinkedList. + * + * Return value: + * + * xTrue if the oid is found in the list. + * + * xFalse if the oid is not in the list, or if 'me' is NULL. + */ +BOOL +XpOidLinkedListHasOid(XpOidLinkedList* me, + XpOid oid) +{ + if((XpOidLinkedList*)NULL != me) + { + me->current = me->head; + while(me->current) + if(me->current->oid == oid) + return xTrue; + else + me->current = me->current->next; + } + return xFalse; +} + +/* + * ------------------------------------------------------------------------ + * Name: XpOidLinkedListFirstOid + * + * Description: + * + * Positions the XpOidLinkedList 'current' pointer to the first entry + * in the list. + * + * Return value: + * + * The first oid in the list, or xpoid_none if the list NULL or + * empty. + */ +XpOid +XpOidLinkedListFirstOid(XpOidLinkedList* me) +{ + if((XpOidLinkedList*)NULL != me && (me->current = me->head)) + return me->current->oid; + else + return xpoid_none; +} + +/* + * ------------------------------------------------------------------------ + * Name: XpOidLinkedListNextOid + * + * Description: + * + * Positions the XpOidLinkedList 'current' pointer to the next entry + * in the list. + * + * Return value: + * + * The next oid, or xpoid_none if the end of the list has been + * reached. + */ +XpOid +XpOidLinkedListNextOid(XpOidLinkedList* me) +{ + if(me->current ? me->current = me->current->next : xFalse) + return me->current->oid; + else + return xpoid_none; +} + +/* + * ------------------------------------------------------------------------ + * Name: XpOidMediumSSNew + * + * Description: + * + * Creates a new XpOidMediumSS initialized from a string value + * specified using the medium-source-sizes syntax. See + * MediumSSParse() below for parsing details. + * + * Return value: + * + * NULL if the passed 'value_string' is NULL, or if a syntax error is + * encountered while parsing the medium-source-sizes value. + * + */ +XpOidMediumSS* +XpOidMediumSSNew(const char* value_string, + const XpOidList* valid_trays, + const XpOidList* valid_medium_sizes) +{ + if(value_string == (const char*)NULL) + return (XpOidMediumSS*)NULL; + else + { + const char* ptr = value_string + SpanWhitespace(value_string); + if(*ptr == '\0') + return (XpOidMediumSS*)NULL; + else + return MediumSSParse(ptr, valid_trays, valid_medium_sizes, + &ptr, 0); + } +} + +/* + * ------------------------------------------------------------------------ + * Name: MediumSSParse + * + * Description: + * + * 'ptr_return' *cannot* be NULL. + * + * + * Return value: + * + * + * + */ +static XpOidMediumSS* +MediumSSParse(const char* value_string, + const XpOidList* valid_trays, + const XpOidList* valid_medium_sizes, + const char** ptr_return, + int i) +{ + XpOidMediumSS* medium_ss; + XpOidMediumSourceSize mss; + /* + * check for the start of a new MediumSourceSize sequence + */ + if(ParseSeqStart(value_string, ptr_return)) + { + /* + * check for an unspecified tray value + */ + if(ParseUnspecifiedValue(*ptr_return, ptr_return)) + mss.input_tray = xpoid_unspecified; + else + { + const char* tray_str; + *ptr_return += SpanWhitespace(*ptr_return); + tray_str = *ptr_return; + /* + * parse out the input tray + */ + mss.input_tray = XpOidParse(*ptr_return, ptr_return); + if((const XpOidList*)NULL != valid_trays + && + !XpOidListHasOid(valid_trays, mss.input_tray) + ) + mss.input_tray = xpoid_none; + if(xpoid_none == mss.input_tray) + { + char* invalid_tray_str; + int len = *ptr_return - tray_str; + if(len > 0) + { + invalid_tray_str = XpOidMalloc(len+1); + strncpy(invalid_tray_str, tray_str, len); + invalid_tray_str[len] = '\0'; + ErrorF("%s\nInvalid tray (%s) found. Will attempt to continue parsing.\n", + XPMSG_WARN_MSS, invalid_tray_str); + XpOidFree(invalid_tray_str); + } + } + } + /* + * attempt to parse a Continuous MediumSize sequence + */ + mss.ms.continuous_size = + MediumContinuousSizeParse(*ptr_return, ptr_return); + if(mss.ms.continuous_size != (XpOidMediumContinuousSize*)NULL) + { + mss.mstag = XpOidMediumSS_CONTINUOUS; + } + else + { + /* + * not continuous, try Discrete MediumSize + */ + mss.ms.discrete = + MediumDiscreteSizeListParse(*ptr_return, valid_medium_sizes, + ptr_return, 0); + if(mss.ms.discrete == (XpOidMediumDiscreteSizeList*)NULL) + { + const char* tray_str; + /* + * syntax error (MediumDiscreteSizeListParse reports error) + */ + switch(mss.input_tray) + { + case xpoid_none: + tray_str = "an invalid"; + break; + case xpoid_unspecified: + tray_str = "default (tray specifier omitted)"; + break; + default: + tray_str = XpOidString(mss.input_tray); + break; + } + ErrorF("%s\nError occurred while parsing medium sizes for %s tray.\n", + XPMSG_WARN_MSS, tray_str); + return NULL; + } + mss.mstag = XpOidMediumSS_DISCRETE; + } + /* + * parse out the MediumSourceSize sequence end + */ + if(!ParseSeqEnd(*ptr_return, ptr_return)) + { + /* + * syntax error + */ + ErrorF("%s\nSequence End expected. Unparsed data: %s\n", + XPMSG_WARN_MSS, *ptr_return); + return NULL; + } + /* + * recurse to parse the next MediumSourceSize sequence + */ + medium_ss = MediumSSParse(*ptr_return, + valid_trays, valid_medium_sizes, + ptr_return, + xpoid_none == mss.input_tray ? i : i+1); + if(medium_ss == (XpOidMediumSS*)NULL + || + xpoid_none == mss.input_tray) + { + /* + * syntax error or invalid tray - clean up + */ + switch(mss.mstag) + { + case XpOidMediumSS_CONTINUOUS: + MediumContinuousSizeDelete(mss.ms.continuous_size); + break; + case XpOidMediumSS_DISCRETE: + MediumDiscreteSizeListDelete(mss.ms.discrete); + break; + } + if(medium_ss == (XpOidMediumSS*)NULL) + /* + * syntax error - return + */ + return NULL; + } + if(xpoid_none != mss.input_tray) + { + /* + * copy the current MediumSourceSize into the array + */ + memmove((medium_ss->mss)+i, &mss, sizeof(XpOidMediumSourceSize)); + } + } + else + { + /* + * MediumSourceSize sequence start not found + */ + if(**ptr_return == '\0') + { + if(0 == i) + { + ErrorF("%s\nNo valid trays found.\n", XPMSG_WARN_MSS); + return NULL; + } + /* + * end of value string; allocate the MediumSS structure + */ + medium_ss = (XpOidMediumSS*)XpOidCalloc(1, sizeof(XpOidMediumSS)); + medium_ss->count = i; + medium_ss->mss = (XpOidMediumSourceSize*) + XpOidCalloc(i, sizeof(XpOidMediumSourceSize)); + } + else + { + /* + * syntax error + */ + ErrorF("%s\nSequence Start expected.\nunparsed data: %s\n", + XPMSG_WARN_MSS, *ptr_return); + return NULL; + } + } + return medium_ss; +} + +/* + * ------------------------------------------------------------------------ + * Name: XpOidMediumSSDelete + * + * Description: + * + * + * + * Return value: + * + * + * + */ +void +XpOidMediumSSDelete(XpOidMediumSS* me) +{ + if(me != (XpOidMediumSS*)NULL) + { + int i; + for(i = 0; i < me->count; i++) + { + switch((me->mss)[i].mstag) + { + case XpOidMediumSS_CONTINUOUS: + MediumContinuousSizeDelete((me->mss)[i].ms.continuous_size); + break; + case XpOidMediumSS_DISCRETE: + MediumDiscreteSizeListDelete((me->mss)[i].ms.discrete); + break; + } + } + XpOidFree((char*)me); + } +} + +/* + * ------------------------------------------------------------------------ + * Name: XpOidMediumSSHasSize + * + * Description: + * + * + * + * Return value: + * + * + * + */ +BOOL +XpOidMediumSSHasSize(XpOidMediumSS* me, XpOid page_size) +{ + int i_mss, i_ds; + XpOidMediumDiscreteSizeList* ds_list; + + if(me != (XpOidMediumSS*)NULL && page_size != xpoid_none) + for(i_mss = 0; i_mss < me->count; i_mss++) + { + switch((me->mss)[i_mss].mstag) + { + case XpOidMediumSS_DISCRETE: + ds_list = (me->mss)[i_mss].ms.discrete; + for(i_ds = 0; i_ds < ds_list->count; i_ds++) + if(page_size == (ds_list->list)[i_ds].page_size) + return xTrue; + break; + + case XpOidMediumSS_CONTINUOUS: + /* + * unsupported + */ + break; + } + } + /* + * return + */ + return xFalse; +} + +/* + * ------------------------------------------------------------------------ + * Name: XpOidMediumSSString + * + * Description: + * + * Creates a string representation of an XpOidMediumSS structure. + * + * Return value: + * + * A newly allocated + * + */ +char* XpOidMediumSSString(const XpOidMediumSS* me) +{ + int itray, isize; + int valid_size_count; + int length; + char* str; + char* ptr; + XpOidMediumDiscreteSize* ds; + char buf[128]; + /* + * determine the size of the string representation + */ + for(itray = 0, length = 0; itray < XpOidMediumSSCount(me); itray++) + { + if(xpoid_none == me->mss[itray].input_tray + || + XpOidMediumSS_CONTINUOUS == me->mss[itray].mstag) + { + /* + * skip invalid tray or unsupported continuous size spec + */ + continue; + } + for(isize = 0, valid_size_count = 0; + isize < me->mss[itray].ms.discrete->count; + isize++) + { + ds = me->mss[itray].ms.discrete->list+isize; + if(ds->page_size == xpoid_none) + continue; + ++valid_size_count; + length += XpOidStringLength(ds->page_size); + length += ds->long_edge_feeds ? 4 : 5; /* "True" or "False" */ +#if defined(sun) && !defined(SVR4) + sprintf(buf, "{%.4f %.4f %.4f %.4f}", + ds->assured_reproduction_area.minimum_x, + ds->assured_reproduction_area.maximum_x, + ds->assured_reproduction_area.minimum_y, + ds->assured_reproduction_area.maximum_y); + length += strlen(buf); +#else + length += sprintf(buf, "{%.4f %.4f %.4f %.4f}", + ds->assured_reproduction_area.minimum_x, + ds->assured_reproduction_area.maximum_x, + ds->assured_reproduction_area.minimum_y, + ds->assured_reproduction_area.maximum_y); +#endif + length += 5; /* "{<size> <feed> <area>} " */ + } + if(valid_size_count == 0) + { + /* + * no valid sizes, skip + */ + continue; + } + if(xpoid_unspecified == me->mss[itray].input_tray) + length += 2; /* "''" */ + else + length += XpOidStringLength(me->mss[itray].input_tray); + length += 4; /* "{<tray> <sizes>} " */ + } + /* + * allocate + */ + str = XpOidMalloc(length+1); + /* + * format + */ + for(itray = 0, ptr = str; itray < XpOidMediumSSCount(me); itray++) + { + if(xpoid_none == me->mss[itray].input_tray + || + XpOidMediumSS_CONTINUOUS == me->mss[itray].mstag) + { + /* + * skip invalid tray or unsupported continuous size spec + */ + continue; + } + /* + * check to ensure all of the specified sizes are valid + */ + for(isize = 0, valid_size_count = 0; + isize < me->mss[itray].ms.discrete->count; + isize++) + { + ds = me->mss[itray].ms.discrete->list+isize; + if(ds->page_size != xpoid_none) + ++valid_size_count; + } + if(valid_size_count == 0) + { + /* + * no valid sizes, skip + */ + continue; + } + + if(xpoid_unspecified == me->mss[itray].input_tray) + { +#if defined(sun) && !defined(SVR4) + sprintf(ptr, "{'' "); + ptr += strlen(ptr); +#else + ptr += sprintf(ptr, "{'' "); +#endif + } + else + { +#if defined(sun) && !defined(SVR4) + sprintf(ptr, "{%s ", XpOidString(me->mss[itray].input_tray)); + ptr += strlen(ptr); +#else + ptr += sprintf(ptr, "{%s ", + XpOidString(me->mss[itray].input_tray)); +#endif + } + for(isize = 0; isize < me->mss[itray].ms.discrete->count; isize++) + { + ds = me->mss[itray].ms.discrete->list+isize; + if(ds->page_size != xpoid_none) +#if defined(sun) && !defined(SVR4) + { + sprintf(ptr, "{%s %s {%.4f %.4f %.4f %.4f}} ", + XpOidString(ds->page_size), + ds->long_edge_feeds ? "True" : "False", + ds->assured_reproduction_area.minimum_x, + ds->assured_reproduction_area.maximum_x, + ds->assured_reproduction_area.minimum_y, + ds->assured_reproduction_area.maximum_y); + ptr += strlen(ptr); + } +#else + ptr += sprintf(ptr, "{%s %s {%.4f %.4f %.4f %.4f}} ", + XpOidString(ds->page_size), + ds->long_edge_feeds ? "True" : "False", + ds->assured_reproduction_area.minimum_x, + ds->assured_reproduction_area.maximum_x, + ds->assured_reproduction_area.minimum_y, + ds->assured_reproduction_area.maximum_y); +#endif + } +#if defined(sun) && !defined(SVR4) + sprintf(ptr, "} "); + ptr += strlen(ptr); +#else + ptr += sprintf(ptr, "} "); +#endif + } + /* + * chop trailing whitespace or terminate empty string + */ + str[length] = '\0'; + /* + * return + */ + return str; +} + +/* + * ------------------------------------------------------------------------ + * Name: MediumContinuousSizeParse + * + * Description: + * + * 'ptr_return' *cannot* be NULL. + * + * + * Return value: + * + * + * + */ +static XpOidMediumContinuousSize* +MediumContinuousSizeParse(const char* value_string, + const char** ptr_return) +{ + const char* first_nonws_ptr; + XpOidMediumContinuousSize* mcs = NULL; + /* + * skip leading whitespace + */ + first_nonws_ptr = value_string + SpanWhitespace(value_string); + /* + * parse out the MediumSize sequence start char + */ + if(!ParseSeqStart(first_nonws_ptr, ptr_return)) + goto MediumContinuousSizeParse_error; + /* + * peek ahead to see if it looks like we actually have a continuous + * size spec (looking for the sequence start char on the 1st range spec) + */ + if(!ParseSeqStart(*ptr_return, (const char**)NULL)) + goto MediumContinuousSizeParse_error; + /* + * Ok, let's go for it + */ + mcs = (XpOidMediumContinuousSize*) + XpOidCalloc(1, sizeof(XpOidMediumContinuousSize)); + /* + * "range across the feed direction" + */ + if(!ParseRealRange(*ptr_return, ptr_return, &mcs->range_across_feed)) + goto MediumContinuousSizeParse_error; + /* + * "increment across the feed direction" (optional, default 0) + */ + if(!ParseUnspecifiedValue(*ptr_return, ptr_return)) + if(!ParseRealValue(*ptr_return, ptr_return, + &mcs->increment_across_feed)) + goto MediumContinuousSizeParse_error; + /* + * "range in the feed direction" + */ + if(!ParseRealRange(*ptr_return, ptr_return, &mcs->range_in_feed)) + goto MediumContinuousSizeParse_error; + /* + * "increment in the feed direction" (optional, default 0) + */ + if(!ParseUnspecifiedValue(*ptr_return, ptr_return)) + if(!ParseRealValue(*ptr_return, ptr_return, + &mcs->increment_in_feed)) + goto MediumContinuousSizeParse_error; + /* + * "long edge feeds" flag (default TRUE) + */ + if(ParseUnspecifiedValue(*ptr_return, ptr_return)) + mcs->long_edge_feeds = xTrue; + else + if(!ParseBoolValue(*ptr_return, ptr_return, &mcs->long_edge_feeds)) + goto MediumContinuousSizeParse_error; + /* + * "generic assured reproduction area" + */ + if(!ParseArea(*ptr_return, ptr_return, &mcs->assured_reproduction_area)) + goto MediumContinuousSizeParse_error; + /* + * parse out the MediumSize sequence end character + */ + if(!ParseSeqEnd(*ptr_return, ptr_return)) + goto MediumContinuousSizeParse_error; + /* + * return + */ + return mcs; + + + MediumContinuousSizeParse_error: + /* + * syntax error - don't log since this function may be called + * as a lookahead + */ + *ptr_return = first_nonws_ptr; + XpOidFree((char*)mcs); + return NULL; +} + +/* + * ------------------------------------------------------------------------ + * Name: MediumContinuousSizeDelete + * + * Description: + * + * 'ptr_return' *cannot* be NULL. + * + * + * Return value: + * + * + * + */ +static void +MediumContinuousSizeDelete(XpOidMediumContinuousSize* me) +{ + XpOidFree((char*)me); +} + +/* + * ------------------------------------------------------------------------ + * Name: MediumDiscreteSizeListParse + * + * Description: + * + * 'ptr_return' *cannot* be NULL. + * + * Return value: + * + * + * + */ +static XpOidMediumDiscreteSizeList* +MediumDiscreteSizeListParse(const char* value_string, + const XpOidList* valid_medium_sizes, + const char** ptr_return, + int i) +{ + XpOidMediumDiscreteSizeList* list; + XpOidMediumDiscreteSize mds; + /* + * check for the start of a new MediumSize sequence + */ + if(ParseSeqStart(value_string, ptr_return)) + { + /* + * "page size" + */ + mds.page_size = XpOidParse(*ptr_return, ptr_return); + if((const XpOidList*)NULL != valid_medium_sizes + && + !XpOidListHasOid(valid_medium_sizes, mds.page_size) + ) + mds.page_size = xpoid_none; + /* + * "long edge feeds" flag (default TRUE) + */ + if(ParseUnspecifiedValue(*ptr_return, ptr_return)) + mds.long_edge_feeds = xTrue; + else + if(!ParseBoolValue(*ptr_return, ptr_return, + &mds.long_edge_feeds)) + { + /* + * syntax error + */ + ErrorF("%s\nBoolean expected.\nunparsed data: %s\n", + XPMSG_WARN_MSS, *ptr_return); + return (XpOidMediumDiscreteSizeList*)NULL; + } + /* + * "assured reproduction area" + */ + if(!ParseArea(*ptr_return, ptr_return, + &mds.assured_reproduction_area)) + { + /* + * syntax error + */ + ErrorF("%s\nArea specification error.\nunparsed data: %s\n", + XPMSG_WARN_MSS, *ptr_return); + return (XpOidMediumDiscreteSizeList*)NULL; + } + /* + * parse out the MediumSize sequence end character + */ + if(!ParseSeqEnd(*ptr_return, ptr_return)) + { + ErrorF("%s\nSequence End expected. Unparsed data: %s\n", + XPMSG_WARN_MSS, *ptr_return); + return (XpOidMediumDiscreteSizeList*)NULL; + } + /* + * recurse to parse the next Discrete MediumSize sequence + */ + if(mds.page_size == xpoid_none) + { + list = MediumDiscreteSizeListParse(*ptr_return, valid_medium_sizes, + ptr_return, i); + } + else + { + list = MediumDiscreteSizeListParse(*ptr_return, valid_medium_sizes, + ptr_return, i+1); + if(list != (XpOidMediumDiscreteSizeList*)NULL) + { + /* + * copy the current discrete MediumSize into the list + */ + memmove((list->list)+i, &mds, sizeof(XpOidMediumDiscreteSize)); + } + } + } + else + { + /* + * MediumSize sequence start not found; end of the discrete sizes + * list + */ + if(0 == i) + { + ErrorF("%s\nNo valid medium sizes found for tray.\n", + XPMSG_WARN_MSS); + return (XpOidMediumDiscreteSizeList*)NULL; + } + list = (XpOidMediumDiscreteSizeList*) + XpOidCalloc(1, sizeof(XpOidMediumDiscreteSizeList)); + list->count = i; + list->list = (XpOidMediumDiscreteSize*) + XpOidCalloc(i, sizeof(XpOidMediumDiscreteSize)); + } + return list; +} + +/* + * ------------------------------------------------------------------------ + * Name: MediumDiscreteSizeListDelete + * + * Description: + * + * + * + * Return value: + * + * + * + */ +static void +MediumDiscreteSizeListDelete(XpOidMediumDiscreteSizeList* list) +{ + if(list != (XpOidMediumDiscreteSizeList*)NULL) + { + XpOidFree((char*)list->list); + XpOidFree((char*)list); + } +} + +/* + * ------------------------------------------------------------------------ + * Name: XpOidTrayMediumListNew + * + * Description: + * + * Only need the valid trays; validation requires bumping up against + * msss using TrayMediumListValidate; this needs valid trays + * because of unspecified trays ion msss, but + * TrayMediumListValidate will take care of invalid sizes... + * + * Return value: + * + * + * + */ +XpOidTrayMediumList* +XpOidTrayMediumListNew(const char* value_string, + const XpOidList* valid_trays, + const XpOidMediumSS* msss) +{ + if(value_string == (const char*)NULL) + return (XpOidTrayMediumList*)NULL; + else + { + const char* ptr; + XpOidTrayMediumList* me; + me = TrayMediumListParse(value_string, valid_trays, &ptr, 0); + if((XpOidTrayMediumList*)NULL != me) + TrayMediumListValidate(me, msss); + return me; + } +} + +/* + * ------------------------------------------------------------------------ + * Name: XpOidTrayMediumListDelete + * + * Description: + * + * + * + * Return value: + * + * + * + */ +void +XpOidTrayMediumListDelete(XpOidTrayMediumList* list) +{ + if(list != (XpOidTrayMediumList*)NULL) + { + XpOidFree((char*)list->list); + XpOidFree((char*)list); + } +} + +/* + * ------------------------------------------------------------------------ + * Name: TrayMediumListParse + * + * Description: + * + * 'ptr_return' *cannot* be NULL. + * + * Return value: + * + * + * + */ +static XpOidTrayMediumList* +TrayMediumListParse(const char* value_string, + const XpOidList* valid_trays, + const char** ptr_return, int i) +{ + XpOidTrayMedium tm; + XpOidTrayMediumList* list; + /* + * check for the start of a new InputTrayMedium sequence + */ + if(ParseSeqStart(value_string, ptr_return)) + { + /* + * "input tray" + */ + tm.input_tray = XpOidParse(*ptr_return, ptr_return); + if((XpOidList*)NULL != valid_trays + && + !XpOidListHasOid(valid_trays, tm.input_tray) + ) + tm.input_tray = xpoid_none; + /* + * "medium" + */ + tm.medium = XpOidParse(*ptr_return, ptr_return); + /* + * parse out the InputTrayMedium sequence end character + */ + if(!ParseSeqEnd(*ptr_return, ptr_return)) + { + ErrorF("%s\n", XPMSG_WARN_ITM); + return NULL; + } + /* + * recurse to parse the next InputTrayMedium sequence + */ + list = TrayMediumListParse(*ptr_return, valid_trays, ptr_return, i+1); + if(list != (XpOidTrayMediumList*)NULL) + { + /* + * copy the current InputTrayMedium into the list + */ + memmove((list->list)+i, &tm, sizeof(XpOidTrayMedium)); + } + } + else + { + /* + * InputTrayMedium sequence start not found + */ + if(**ptr_return == '\0') + { + /* + * end of the list + */ + list = (XpOidTrayMediumList*) + XpOidCalloc(1, sizeof(XpOidTrayMediumList)); + list->count = i; + list->list = (XpOidTrayMedium*) + XpOidCalloc(i, sizeof(XpOidTrayMedium)); + } + else + { + /* + * syntax error + */ + ErrorF("%s\n", XPMSG_WARN_ITM); + return NULL; + } + } + /* + * return + */ + return list; +} + +/* + * ------------------------------------------------------------------------ + * Name: TrayMediumListValidate + * + * Description: + * + * Validate the input-trays-medium list based on a passed + * medium-source-sizes-supported structure. The validated + * input-trays-medium list will have the same number of entries upon + * return from this function. Invalid entries are indicated by + * setting the tray specification to xpoid_none. + * + * Return value: + * + * None. + * + */ +static void +TrayMediumListValidate(XpOidTrayMediumList* me, + const XpOidMediumSS* msss) +{ + int i_mss, i_ds, i_itm; + XpOidMediumDiscreteSizeList* ds_list; + int tray_count; + XpOid current_tray, current_medium; + XpOidMediumDiscreteSizeList* unspecified_tray_ds; + XpOidMediumDiscreteSizeList* tray_ds; + + if(msss == (XpOidMediumSS*)NULL + || + me == (XpOidTrayMediumList*)NULL) + { + return; + } + /* + * loop through the input trays medium list + */ + for(i_itm = 0; i_itm < XpOidTrayMediumListCount(me); i_itm++) + { + current_tray = XpOidTrayMediumListTray(me, i_itm); + if(current_tray == xpoid_none) + continue; + current_medium = XpOidTrayMediumListMedium(me, i_itm); + if(current_medium == xpoid_none) + { + /* + * no medium; invalidate this entry + */ + me->list[i_itm].input_tray = xpoid_none; + continue; + } + /* + * loop through the MediumSourceSizes, looking for an appropriate + * discrete sizes spec for the current tray + */ + unspecified_tray_ds = (XpOidMediumDiscreteSizeList*)NULL; + tray_ds = (XpOidMediumDiscreteSizeList*)NULL; + for(i_mss = 0; + i_mss < msss->count && + tray_ds == (XpOidMediumDiscreteSizeList*)NULL; + i_mss++) + { + switch((msss->mss)[i_mss].mstag) + { + case XpOidMediumSS_DISCRETE: + if((msss->mss)[i_mss].input_tray == current_tray) + tray_ds = (msss->mss)[i_mss].ms.discrete; + else if((msss->mss)[i_mss].input_tray == xpoid_unspecified) + unspecified_tray_ds = (msss->mss)[i_mss].ms.discrete; + break; + + case XpOidMediumSS_CONTINUOUS: + /* + * unsupported + */ + break; + } + } + /* + * if the tray was not matched, use the unspecified tray size + * list + */ + if(tray_ds == (XpOidMediumDiscreteSizeList*)NULL) + if(unspecified_tray_ds == (XpOidMediumDiscreteSizeList*)NULL) + { + /* + * not even an unspecified tray, invalidate this + * input-trays-medium entry. + */ + me->list[i_itm].input_tray = xpoid_none; + continue; + } + else + tray_ds = unspecified_tray_ds; + /* + * loop through the discrete sizes list, looking for a size that + * matches the medium for the current input tray + */ + for(i_ds = 0; i_ds < tray_ds->count; i_ds++) + { + /* + * check to see if the current input tray's medium size + * matches the current discrete size + * + * Note: in the CDEnext SI, medium identifiers coincide with + * medium-size identifiers. If the DP-Medium object is + * ever implemented, this check would need to be + * changed so that the input tray's medium size is + * obtained from the indicated Medium object, and not + * inferred from the medium identifier itself. + */ + if((tray_ds->list)[i_ds].page_size == current_medium) + { + /* + * The current input tray's medium size matches the + * current discrete medium size. + */ + break; + } + } + if(i_ds == tray_ds->count) + { + /* + * The current input tray's medium size was not found in the + * discrete size list; mark the input tray medium entry + * invalid + */ + me->list[i_itm].input_tray = xpoid_none; + } + + } +} + +/* + * ------------------------------------------------------------------------ + * Name: XpOidTrayMediumListString + * + * Description: + * + * Creates a string representation of an XpOidTrayMediumList structure. + * + * Return value: + * + * A newly allocated + * + */ +char* XpOidTrayMediumListString(const XpOidTrayMediumList* me) +{ + int i; + int length; + char* str; + char* ptr; + XpOid tray; + /* + * allocate enough memory for the string representation, + * including intervening delimiters and whitespace + */ + for(i = 0, length = 0; i < XpOidTrayMediumListCount(me); i++) + { + tray = XpOidTrayMediumListTray(me, i); + if(xpoid_none != tray) + { + length += XpOidStringLength(tray); + length += XpOidStringLength(XpOidTrayMediumListMedium(me, i)); + length += 4; + } + } + str = XpOidMalloc(length+1); + /* + * format the list + */ + for(i = 0, ptr = str; i < XpOidTrayMediumListCount(me); i++) + { + tray = XpOidTrayMediumListTray(me, i); + if(xpoid_none != tray) + { +#if defined(sun) && !defined(SVR4) + sprintf(ptr, "{%s %s} ", + XpOidString(tray), + XpOidString(XpOidTrayMediumListMedium(me, i))); + ptr += strlen(ptr); +#else + ptr += sprintf(ptr, "{%s %s} ", + XpOidString(tray), + XpOidString(XpOidTrayMediumListMedium(me, i))); +#endif + } + } + /* + * chop trailing whitespace or terminate empty string + */ + str[length] = '\0'; + /* + * return + */ + return str; +} + +/* + * ------------------------------------------------------------------------ + * Name: XpOidTrayMediumListHasTray + * + * Description: + * + * Determines if 'tray' is found in 'list'. + * + * Return value: + * + * xTrue if the tray is found in the list. + * + * xFalse if the tray is not in the list, or if 'list' is NULL. + * + */ +BOOL +XpOidTrayMediumListHasTray(const XpOidTrayMediumList* list, XpOid tray) +{ + int i; + if(list != (XpOidTrayMediumList*)NULL && tray != xpoid_none) + for(i = 0; i < list->count; i++) + if(XpOidTrayMediumListTray(list, i) == tray) + return xTrue; + return xFalse; +} + +/* + * ------------------------------------------------------------------------ + * Name: ParseArea + * + * Description: + * + * Skips leading whitespace and parses out and returns a XpOidArea. + * + * Return value: + * + * xTrue if the XpOidArea was successfully parsed. ptr_return is + * updated to point to location where the parsing ended. + * + * xFalse if a XpOidArea was not found; ptr_return is updated + * to point to the first non-whitespace char in value_string. + * + */ +static BOOL +ParseArea(const char* value_string, + const char** ptr_return, + XpOidArea* area_return) +{ + const char* first_nonws_ptr; + const char* ptr; + /* + * skip leading whitespace + */ + first_nonws_ptr = value_string + SpanWhitespace(value_string); + /* + * parse out the area sequence start + */ + if(!ParseSeqStart(first_nonws_ptr, &ptr)) + goto ParseArea_error; + /* + * parse the minimum x value + */ + if(!ParseRealValue(ptr, &ptr, + area_return ? &area_return->minimum_x : NULL)) + goto ParseArea_error; + /* + * parse the maximum x value + */ + if(!ParseRealValue(ptr, &ptr, + area_return ? &area_return->maximum_x : NULL)) + goto ParseArea_error; + /* + * parse the minimum y value + */ + if(!ParseRealValue(ptr, &ptr, + area_return ? &area_return->minimum_y : NULL)) + goto ParseArea_error; + /* + * parse the maximum y value + */ + if(!ParseRealValue(ptr, &ptr, + area_return ? &area_return->maximum_y : NULL)) + goto ParseArea_error; + /* + * parse out the area sequence end + */ + if(!ParseSeqEnd(ptr, &ptr)) + goto ParseArea_error; + /* + * update the return pointer + */ + if(ptr_return != (const char**)NULL) + *ptr_return = ptr; + /* + * return + */ + return xTrue; + + + ParseArea_error: + /* + * syntax error + */ + if(ptr_return != (const char**)NULL) + *ptr_return = first_nonws_ptr; + return xFalse; +} + +/* + * ------------------------------------------------------------------------ + * Name: ParseRealRange + * + * Description: + * + * Skips leading whitespace and parses out and returns a + * XpOidRealRange. + * + * Return value: + * + * xTrue if the XpOidRealRange was successfully + * parsed. ptr_return is updated to point to location where the + * parsing ended. + * + * xFalse if a XpOidRealRange was not found; ptr_return is + * updated to point to the first non-whitespace char in value_string. + * + */ +static BOOL +ParseRealRange(const char* value_string, + const char** ptr_return, + XpOidRealRange* range_return) +{ + const char* first_nonws_ptr; + const char* ptr; + /* + * skip leading whitespace + */ + first_nonws_ptr = value_string + SpanWhitespace(value_string); + /* + * parse out the range sequence start + */ + if(!ParseSeqStart(first_nonws_ptr, &ptr)) + goto ParseRealRange_error; + /* + * parse the lower bound + */ + if(!ParseRealValue(ptr, &ptr, + range_return ? &range_return->lower_bound : NULL)) + goto ParseRealRange_error; + /* + * parse the upper bound + */ + if(!ParseRealValue(ptr, &ptr, + range_return ? &range_return->upper_bound : NULL)) + goto ParseRealRange_error; + /* + * parse out the range sequence end + */ + if(!ParseSeqEnd(ptr, &ptr)) + goto ParseRealRange_error; + /* + * update the return pointer + */ + if(ptr_return != (const char**)NULL) + *ptr_return = ptr; + /* + * return + */ + return xTrue; + + + ParseRealRange_error: + /* + * syntax error + */ + if(ptr_return != (const char**)NULL) + *ptr_return = first_nonws_ptr; + return xFalse; +} + +/* + * ------------------------------------------------------------------------ + * Name: XpOidNotifyParse + * + * Description: + * + * + * Return value: + * + * + */ +XpOidNotify XpOidNotifyParse(const char* value_string) +{ + const char* ptr = value_string; + + if(value_string == (const char*)NULL) + return XPOID_NOTIFY_NONE; + /* + * look for an event handling profile sequence start + */ + if(!ParseSeqStart(value_string, &ptr)) + { + if('\0' == *ptr) + /* + * empty value is valid + */ + return XPOID_NOTIFY_NONE; + else + return XPOID_NOTIFY_UNSUPPORTED; + } + /* + * look for an event set sequence start + */ + if(!ParseSeqStart(ptr, &ptr)) + { + /* + * check for an empty event handling profile + */ + if(ParseSeqEnd(ptr, &ptr)) + { + ptr += SpanWhitespace(ptr); + if(*ptr == '\0') + /* + * valid empty event handling profile sequence + */ + return XPOID_NOTIFY_NONE; + } + return XPOID_NOTIFY_UNSUPPORTED; + } + /* + * the only event in the set should be report job completed + */ + if(xpoid_val_event_report_job_completed != XpOidParse(ptr, &ptr)) + return XPOID_NOTIFY_UNSUPPORTED; + /* + * event set sequence end + */ + if(!ParseSeqEnd(ptr, &ptr)) + return XPOID_NOTIFY_UNSUPPORTED; + /* + * delivery method of electronic mail + */ + if(xpoid_val_delivery_method_electronic_mail != XpOidParse(ptr, &ptr)) + return XPOID_NOTIFY_UNSUPPORTED; + /* + * event handling profile sequence end + */ + if(!ParseSeqEnd(ptr, &ptr)) + return XPOID_NOTIFY_UNSUPPORTED; + /* + * end of value + */ + ptr += SpanWhitespace(ptr); + if('\0' == *ptr) + /* + * valid supported notification profile + */ + return XPOID_NOTIFY_EMAIL; + else + return XPOID_NOTIFY_UNSUPPORTED; +} + +/* + * ------------------------------------------------------------------------ + * Name: XpOidNotifyString + * + * Description: + * + * + * Return value: + * + * + */ +const char* XpOidNotifyString(XpOidNotify notify) +{ + switch(notify) + { + case XPOID_NOTIFY_UNSUPPORTED: + return (const char*)NULL; + break; + case XPOID_NOTIFY_NONE: + return NOTIFY_NONE_STR; + break; + case XPOID_NOTIFY_EMAIL: + return NOTIFY_EMAIL_STR; + break; + } +} + +/* + * ------------------------------------------------------------------------ + * Name: XpOidDocFmtNew + * + * Description: + * + * + * Return value: + * + * + */ +XpOidDocFmt* +XpOidDocFmtNew(const char* value_string) +{ + XpOidDocFmt* doc_fmt; + const char* ptr; + + if((const char*)NULL == value_string) + return (XpOidDocFmt*)NULL; + ptr = value_string + SpanWhitespace(value_string); + if('\0' == *ptr) + return (XpOidDocFmt*)NULL; + /* + * get the document format from the value string + */ + doc_fmt = (XpOidDocFmt*)XpOidCalloc(1, sizeof(XpOidDocFmt)); + if(xTrue == XpOidDocFmtNext(doc_fmt, ptr, &ptr)) + { + /* + * verify that the document format is the only value specified + */ + ptr += SpanWhitespace(ptr); + if('\0' == *ptr) + /* + * valid document-format value + */ + return doc_fmt; + } + /* + * invalid + */ + XpOidDocFmtDelete(doc_fmt); + ErrorF("%s\n", XPMSG_WARN_DOC_FMT); + return (XpOidDocFmt*)NULL; +} + +/* + * ------------------------------------------------------------------------ + * Name: XpOidDocFmtDelete + * + * Description: + * + * + * Return value: + * + * + */ +void +XpOidDocFmtDelete(XpOidDocFmt* doc_fmt) +{ + if((XpOidDocFmt*)NULL != doc_fmt) + { + XpOidFree(doc_fmt->format); + XpOidFree(doc_fmt->variant); + XpOidFree(doc_fmt->version); + XpOidFree(doc_fmt); + } +} + +/* + * ------------------------------------------------------------------------ + * Name: XpOidDocFmtString + * + * Description: + * + * + * Return value: + * + * + */ +char* +XpOidDocFmtString(XpOidDocFmt* doc_fmt) +{ + if((XpOidDocFmt*)NULL != doc_fmt) + { + if((char*)NULL != doc_fmt->format) + { + char* str = XpOidMalloc(1+SafeStrLen(doc_fmt->format)+ + 1+SafeStrLen(doc_fmt->variant)+ + 1+SafeStrLen(doc_fmt->version)+ + 1+1); + sprintf(str, "{%s %s %s}", doc_fmt->format, + (char*)NULL != doc_fmt->variant ? doc_fmt->variant : "", + (char*)NULL != doc_fmt->version ? doc_fmt->version : ""); + return str; + } + } + return (char*)NULL; +} + +/* + * ------------------------------------------------------------------------ + * Name: XpOidDocFmtNext + * + * Description: + * + * Assumes non-NULL value string. + * + * Return value: + * + * + */ +static BOOL +XpOidDocFmtNext(XpOidDocFmt* doc_fmt, + const char* value_string, + const char** ptr_return) +{ + const char* ptr; + const char* first_nonws_ptr; + const char* format; + const char* variant; + const char* version; + int format_len; + int variant_len; + int version_len; + /* + * skip leading whitespace + */ + ptr = value_string + SpanWhitespace(value_string); + first_nonws_ptr = ptr; + /* + * sequence start + */ + if(!ParseSeqStart(ptr, &ptr)) + goto XpOidDocFmtNext_error; + /* + * skip whitepace to the start of the document format, and save the + * location + */ + ptr += SpanWhitespace(ptr); + format = ptr; + /* + * document format + */ + if(0 == (format_len = SpanToken(ptr))) + goto XpOidDocFmtNext_error; + ptr += format_len; + /* + * optional variant + */ + ptr += SpanWhitespace(ptr); + variant = ptr; + if(0 != (variant_len = SpanToken(ptr))) + { + ptr += variant_len; + /* + * optional version + */ + ptr += SpanWhitespace(ptr); + version = ptr; + version_len = SpanToken(ptr); + ptr += version_len; + } + else + version_len = 0; + /* + * sequence end + */ + if(!ParseSeqEnd(ptr, &ptr)) + goto XpOidDocFmtNext_error; + /* + * update return pointer + */ + if((const char**)NULL != ptr_return) + *ptr_return = ptr; + /* + * update the passed document format struct + */ + memset(doc_fmt, 0, sizeof(XpOidDocFmt)); + doc_fmt->format = XpOidMalloc(format_len+1); + strncpy(doc_fmt->format, format, format_len); + doc_fmt->format[format_len] = '\0'; + if(0 < variant_len) + { + doc_fmt->variant = XpOidMalloc(variant_len+1); + strncpy(doc_fmt->variant, variant, variant_len); + doc_fmt->variant[variant_len] = '\0'; + if(0 < version_len) + { + doc_fmt->version = XpOidMalloc(version_len+1); + strncpy(doc_fmt->version, version, version_len); + doc_fmt->version[version_len] = '\0'; + } + } + return xTrue; + + XpOidDocFmtNext_error: + if((const char**)NULL != ptr_return) + *ptr_return = first_nonws_ptr; + return xFalse; +} + +/* + * ------------------------------------------------------------------------ + * Name: XpOidDocFmtListNew + * + * Description: + * + * + * Return value: + * + * + */ +XpOidDocFmtList* +XpOidDocFmtListNew(const char* value_string, + const XpOidDocFmtList* valid_fmts) +{ + if((char*)NULL != value_string) + { + const char* ptr; + return XpOidDocFmtListParse(value_string, valid_fmts, &ptr, 0); + } + return (XpOidDocFmtList*)NULL; +} + +/* + * ------------------------------------------------------------------------ + * Name: XpOidDocFmtListDelete + * + * Description: + * + * + * Return value: + * + * + */ +void +XpOidDocFmtListDelete(XpOidDocFmtList* list) +{ + if((XpOidDocFmtList*)NULL != list) + { + int i; + for(i = 0; i < list->count; i++) + { + XpOidFree(list->list[i].format); + XpOidFree(list->list[i].variant); + XpOidFree(list->list[i].version); + } + XpOidFree(list->list); + XpOidFree(list); + } +} + +/* + * ------------------------------------------------------------------------ + * Name: XpOidDocFmtListString + * + * Description: + * + * Assumes the passed structure is valid. + * + * Return value: + * + * + */ +char* +XpOidDocFmtListString(const XpOidDocFmtList* list) +{ + if((XpOidDocFmtList*)NULL != list) + { + if(0 < list->count) + { + int i; + int str_len; + char* str; + char* ptr; + /* + * allocate the return string + */ + for(i = 0, str_len = 0; i < list->count; i++) + { + str_len += + 1 + SafeStrLen(list->list[i].format) + + 1 + SafeStrLen(list->list[i].variant) + + 1 + SafeStrLen(list->list[i].version) + 2; + } + str = XpOidMalloc(str_len+1); + /* + * print the list into the string and return it + */ + ptr = str; + for(i = 0; i < list->count; i++) + { + XpOidDocFmt* df = &list->list[i]; + +#if defined(sun) && !defined(SVR4) + sprintf(ptr, "{%s %s %s} ", + df->format, + (char*)NULL != df->variant ? df->variant : "", + (char*)NULL != df->version ? df->version : ""); + ptr += strlen(ptr); +#else + ptr += + sprintf(ptr, "{%s %s %s} ", + df->format, + (char*)NULL != df->variant ? df->variant : "", + (char*)NULL != df->version ? df->version : ""); +#endif + } + return str; + } + } + return (char*)NULL; +} + +/* + * ------------------------------------------------------------------------ + * Name: XpOidDocFmtListParse + * + * Description: + * + * Assumes the passed value_string and ptr_return are non-NULL. + * + * Return value: + * + * + */ +static XpOidDocFmtList* +XpOidDocFmtListParse(const char* value_string, + const XpOidDocFmtList* valid_fmts, + const char** ptr_return, + int i) +{ + XpOidDocFmt doc_fmt; + XpOidDocFmtList* list; + BOOL status; + /* + * get the next document-format from the value string, skipping + * values not found in the passed list of valid formats + */ + *ptr_return = value_string; + while((status = XpOidDocFmtNext(&doc_fmt, *ptr_return, ptr_return)) + && + (const XpOidDocFmtList*)NULL != valid_fmts + && + !XpOidDocFmtListHasFmt(valid_fmts, &doc_fmt) + ); + + if(xFalse == status) + { + if('\0' == **ptr_return) + { + if(0 == i) + { + /* + * empty value string + */ + return (XpOidDocFmtList*)NULL; + } + else + { + /* + * done parsing; allocate the list and return + */ + list = + (XpOidDocFmtList*)XpOidCalloc(1, sizeof(XpOidDocFmtList)); + list->count = i; + list->list = (XpOidDocFmt*)XpOidCalloc(i, sizeof(XpOidDocFmt)); + return list; + } + } + else + { + /* + * invalid document format + */ + ErrorF("%s\n", XPMSG_WARN_DOCFMT_LIST); + return (XpOidDocFmtList*)NULL; + } + } + else + { + /* + * recurse to parse remaining document formats + */ + list = XpOidDocFmtListParse(*ptr_return, valid_fmts, ptr_return, i+1); + if((XpOidDocFmtList*)NULL != list) + { + /* + * add this doc fmt to the list + */ + list->list[i].format = doc_fmt.format; + list->list[i].variant = doc_fmt.variant; + list->list[i].version = doc_fmt.version; + } + return list; + } +} + +/* + * ------------------------------------------------------------------------ + * Name: XpOidDocFmtListHasFmt + * + * Description: + * + * Assumes the passed structure is valid. + * + * Return value: + * + * + */ +BOOL +XpOidDocFmtListHasFmt(const XpOidDocFmtList* list, + const XpOidDocFmt* fmt) +{ + int i; + if(list != (XpOidDocFmtList*)NULL + && + fmt != (XpOidDocFmt*)NULL + && + fmt->format != (char*)NULL + ) + { + for(i = 0; i < list->count; i++) + { + /* + * formats must match + */ + if(strcmp(fmt->format, list->list[i].format) != 0) + continue; + /* + * variants must both be NULL or match + */ + if(fmt->variant == (char*)NULL) + if(list->list[i].variant == (char*)NULL) + return xTrue; + else + continue; + if(list->list[i].variant == (char*)NULL) + continue; + if(strcmp(fmt->variant, list->list[i].variant) != 0) + continue; + /* + * versions must both be NULL or match + */ + if(fmt->version == (char*)NULL) + if(list->list[i].version == (char*)NULL) + return xTrue; + else + continue; + if(list->list[i].version == (char*)NULL) + continue; + if(strcmp(fmt->version, list->list[i].version) == 0) + return xTrue; + } + } + return xFalse; +} + +/* + * ------------------------------------------------------------------------ + * Name: XpOidCardListNew + * + * Description: + * + * + * Return value: + * + * + */ +XpOidCardList* +XpOidCardListNew(const char* value_string, const XpOidCardList* valid_cards) +{ + if((const char*)NULL != value_string) + { + const char* ptr; + + return XpOidCardListParse(value_string, valid_cards, &ptr, 0); + } + else + return (XpOidCardList*)NULL; +} + +/* + * ------------------------------------------------------------------------ + * Name: XpOidCardListDelete + * + * Description: + * + * + * Return value: + * + * + */ +void +XpOidCardListDelete(XpOidCardList* list) +{ + if((XpOidCardList*)NULL != list) + { + XpOidFree(list->list); + XpOidFree(list); + } +} + +/* + * ------------------------------------------------------------------------ + * Name: XpOidCardListString + * + * Description: + * + * + * Return value: + * + * + */ +char* +XpOidCardListString(const XpOidCardList* list) +{ + if((XpOidCardList*)NULL != list) + { + char buf[48]; + int str_len; + char* str; + int i; + char* ptr; + /* + * allocate the output string + */ + for(i = 0, str_len = 0; i < list->count; i++) +#if defined(sun) && !defined(SVR4) + { + sprintf(buf, "%lu", list->list[i]) + 1; + str_len += strlen(buf); + } +#else + str_len += sprintf(buf, "%lu", list->list[i]) + 1; +#endif + str = XpOidMalloc(str_len+1); + /* + * write the list to the string + */ + for(i = 0, ptr = str; i < list->count; i++) +#if defined(sun) && !defined(SVR4) + { + sprintf(ptr, "%lu ", list->list[i]); + ptr += strlen(ptr); + } +#else + ptr += sprintf(ptr, "%lu ", list->list[i]); +#endif + return str; + } + else + return (char*)NULL; +} + +/* + * ------------------------------------------------------------------------ + * Name: XpOidCardListHasCard + * + * Description: + * + * Determines if 'card' is an element of 'list'. + * + * Return value: + * + * xTrue if the card is found in the list. + * + * xFalse if the card is not in the list, or if 'list' is NULL. + * + */ +BOOL +XpOidCardListHasCard(const XpOidCardList* list, unsigned long card) +{ + int i; + if(list != (XpOidCardList*)NULL) + for(i = 0; i < list->count; i++) + if(list->list[i] == card) + return xTrue; + return xFalse; +} + +/* + * ------------------------------------------------------------------------ + * Name: XpOidCardListParse + * + * Description: + * + * Assumes the passed value_string and ptr_return are non-NULL. + * + * Return value: + * + * + */ +static XpOidCardList* +XpOidCardListParse(const char* value_string, + const XpOidCardList* valid_cards, + const char** ptr_return, + int i) +{ + unsigned long card; + XpOidCardList* list; + BOOL status; + + /* + * get the next card from the value string, skipping values not + * found in the passed list of valid cards + */ + *ptr_return = value_string; + while((status = XpOidParseUnsignedValue(*ptr_return, ptr_return, &card)) + && + (const XpOidCardList*)NULL != valid_cards + && + !XpOidCardListHasCard(valid_cards, card) + ); + + if(xFalse == status) + { + if('\0' == **ptr_return) + { + if(0 == i) + { + /* + * empty value string + */ + return (XpOidCardList*)NULL; + } + else + { + /* + * done parsing; allocate the list and return + */ + list = (XpOidCardList*)XpOidCalloc(1, sizeof(XpOidCardList)); + list->count = i; + list->list = + (unsigned long*)XpOidCalloc(i, sizeof(unsigned long)); + return list; + } + } + else + { + /* + * parsing error + */ + ErrorF("%s\n", XPMSG_WARN_CARD_LIST); + return (XpOidCardList*)NULL; + } + } + else + { + /* + * recurse to parse remaining cardinal values + */ + list = XpOidCardListParse(*ptr_return, valid_cards, ptr_return, i+1); + if((XpOidCardList*)NULL != list) + { + /* + * add this value to the list + */ + list->list[i] = card; + } + return list; + } +} + +/* + * ------------------------------------------------------------------------ + * Name: ParseBoolValue + * + * Description: + * + * + * Return value: + * + * + */ +static BOOL +ParseBoolValue(const char* value_string, + const char** ptr_return, + BOOL* bool_return) +{ + const char* ptr; + int length; + BOOL status; + /* + * skip leading whitespace + */ + ptr = value_string + SpanWhitespace(value_string); + /* + * get the whitespace-delimited token length + */ + length = SpanToken(ptr); + /* + * determine if true or false or bad + */ + if(StrnCaseCmp(ptr, "TRUE", length) == 0) + { + if(bool_return != (BOOL*)NULL) + *bool_return = xTrue; + status = xTrue; + } + else if(StrnCaseCmp(ptr, "FALSE", length) == 0) + { + if(bool_return != (BOOL*)NULL) + *bool_return = xFalse; + status = xTrue; + } + else + { + /* + * syntax error + */ + status = xFalse; + } + /* + * update the return pointer and return + */ + if(ptr_return != (const char**)NULL) + *ptr_return = status ? ptr+length : ptr; + return status; +} + +/* + * ------------------------------------------------------------------------ + * Name: XpOidParseUnsignedValue + * + * Description: + * + * Skips leading whitespace and parses out and returns a unsigned number. + * + * Return value: + * + * xTrue if a unsigned number was successfully parsed. ptr_return is + * updated to point to location where the unsigned number parsing + * ended. + * + * xFalse if a unsigned number was not found; ptr_return is updated + * to point to the first non-whitespace char in value_string. + * + */ +BOOL +XpOidParseUnsignedValue(const char* value_string, + const char** ptr_return, + unsigned long* unsigned_return) +{ + long value; + BOOL status; + const char* first_nonws_ptr; + const char* ptr; + /* + * skip leading whitespace + */ + first_nonws_ptr = value_string + SpanWhitespace(value_string); + value = strtol(first_nonws_ptr, (char**)(&ptr), 0); + if(ptr == first_nonws_ptr || value < 0) + status = xFalse; + else + status = xTrue; + /* + * update return parms + */ + if(ptr_return != (const char**)NULL) + *ptr_return = ptr; + if(unsigned_return != (unsigned long*)NULL) + *unsigned_return = (unsigned long)value; + /* + * return + */ + return status; +} + +/* + * ------------------------------------------------------------------------ + * Name: ParseRealValue + * + * Description: + * + * Skips leading whitespace and parses out and returns a real number. + * + * Return value: + * + * xTrue if a real number was successfully parsed. ptr_return is + * updated to point to location where the real number parsing + * ended. + * + * xFalse if a real number was not found; ptr_return is updated + * to point to the first non-whitespace char in value_string. + * + */ +static BOOL +ParseRealValue(const char* value_string, + const char** ptr_return, + float* real_return) +{ + float real_value; + BOOL status; + const char* first_nonws_ptr; + const char* ptr; + /* + * skip leading whitespace + */ + first_nonws_ptr = value_string + SpanWhitespace(value_string); + real_value = (float)strtod(first_nonws_ptr, (char**)(&ptr)); + if(ptr == first_nonws_ptr) + status = xFalse; + else + status = xTrue; + /* + * update return parms + */ + if(ptr_return != (const char**)NULL) + *ptr_return = ptr; + if(real_return != (float*)NULL) + *real_return = real_value; + /* + * return + */ + return status; +} + +/* + * ------------------------------------------------------------------------ + * Name: ParseSeqEnd + * + * Description: + * + * Description: + * + * Skips leading whitespace and parses out the sequence end + * character '}'. + * + * Return value: + * + * xTrue if the sequence end character was parsed; ptr_return is + * updated to point to the first char following the sequence end + * character. + * + * xFalse if the sequence end character was not found; ptr_return is + * updated to point to the first non-whitespace char in value_string. + * + */ +static BOOL +ParseSeqEnd(const char* value_string, + const char** ptr_return) +{ + const char* ptr; + BOOL status; + /* + * skip leading whitespace + */ + ptr = value_string + SpanWhitespace(value_string); + /* + * parse out the sequence end character + */ + if(*ptr == '}') + { + status = xTrue; + ++ptr; + } + else + status = xFalse; + /* + * update the return pointer + */ + if(ptr_return != (const char**)NULL) + *ptr_return = ptr; + /* + * return + */ + return status; +} + +/* + * ------------------------------------------------------------------------ + * Name: ParseSeqStart + * + * Description: + * + * Skips leading whitespace and parses out the sequence start + * character '{'. + * + * Return value: + * + * xTrue if the sequence start character was parsed; ptr_return is + * updated to point to the first char following the sequence start + * character. + * + * xFalse if the sequence start character was not found; ptr_return is + * updated to point to the first non-whitespace char in value_string. + * + */ +static BOOL +ParseSeqStart(const char* value_string, + const char** ptr_return) +{ + const char* ptr; + BOOL status; + /* + * skip leading whitespace + */ + ptr = value_string + SpanWhitespace(value_string); + /* + * parse out the sequence start character + */ + if(*ptr == '{') + { + status = xTrue; + ++ptr; + } + else + status = xFalse; + /* + * update the return pointer + */ + if(ptr_return != (const char**)NULL) + *ptr_return = ptr; + /* + * return + */ + return status; +} + +/* + * ------------------------------------------------------------------------ + * Name: ParseUnspecifiedValue + * + * Description: + * + * Skips leading whitespace and parses out an unspecified optional + * value (i.e. matching '' or "" - skips all data between the set of + * quotes). + * + * Return value: + * + * xTrue if an unspecified value was parsed; ptr_return is updated to + * point to the first char following the trailing quote. + * + * xFalse if an unspecified value was not found; ptr_return is updated + * to point to the first non-whitespace char in value_string. + * + */ +static BOOL +ParseUnspecifiedValue(const char* value_string, + const char** ptr_return) +{ + BOOL status; + const char* ptr; + /* + * skip leading whitespace + */ + ptr = value_string + SpanWhitespace(value_string); + /* + * parse out an unspecified optional value ('' or "") + */ + if(*ptr == '\'' || *ptr == '"') + { + char delim[2]; + + if(ptr_return != (const char**)NULL) + { + delim[0] = *ptr; + delim[1] = '\0'; + /* + * skip over the matching delimiter + */ + ++ptr; + ptr += strcspn(ptr, delim); + if(*ptr != '\0') + ++ptr; + } + status = xTrue; + } + else + status = xFalse; + /* + * update the return pointer + */ + if(ptr_return != (const char**)NULL) + *ptr_return = ptr; + /* + * return + */ + return status; +} + +/* + * ------------------------------------------------------------------------ + * Name: SpanToken + * + * Description: + * + * Returns the length of the initial segment of the passed string + * that consists entirely of non-whitespace and non-sequence + * delimiter characters. + * + * + */ +static int +SpanToken(const char* string) +{ + const char* ptr; + for(ptr = string; + *ptr != '\0' && !isspace(*ptr) && *ptr != '{' && *ptr != '}'; + ++ptr); + return ptr - string; +} + +/* + * ------------------------------------------------------------------------ + * Name: SpanWhitespace + * + * Description: + * + * Returns the length of the initial segment of the passed string + * that consists entirely of whitespace characters. + * + * + */ +static int +SpanWhitespace(const char* string) +{ + const char* ptr; + for(ptr = string; *ptr != '\0' && isspace(*ptr); ++ptr); + return ptr - string; +} + +#ifndef HAVE_STRCASECMP +/* + * ------------------------------------------------------------------------ + * Name: StrnCaseCmp + * + * Description: + * + * Implements strncasecmp() for those platforms that need it. + * + * + */ +static int +StrnCaseCmp(const char *s1, const char *s2, size_t len) +{ + char c1, c2; + int result; + + while (len--) + { + c1 = *s1++; + c2 = *s2++; + result = tolower(c1) - tolower(c2); + + if (result != 0) + return result; + } + + return 0; +} +#endif diff --git a/Xprint/Oid.h b/Xprint/Oid.h new file mode 100644 index 000000000..70bd8d3e5 --- /dev/null +++ b/Xprint/Oid.h @@ -0,0 +1,289 @@ +/* $Xorg: Oid.h,v 1.3 2000/08/17 19:48:06 cpqbld Exp $ */ +/* +(c) Copyright 1996 Hewlett-Packard Company +(c) Copyright 1996 International Business Machines Corp. +(c) Copyright 1996 Sun Microsystems, Inc. +(c) Copyright 1996 Novell, Inc. +(c) Copyright 1996 Digital Equipment Corp. +(c) Copyright 1996 Fujitsu Limited +(c) Copyright 1996 Hitachi, Ltd. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the names of the copyright holders shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from said +copyright holders. +*/ + +#ifndef _Xp_Oid_h +#define _Xp_Oid_h + +#include <Xproto.h> + +/* + * include the auto-generated XpOid enum definition + */ +#include "OidDefs.h" + +/* + * messages + */ +#define XPMSG_WARN_MSS "Syntax error parsing medium-source-sizes" +#define XPMSG_WARN_ITM "Syntax error parsing input-trays-medium" +#define XPMSG_WARN_DOC_FMT "Syntax error parsing document format" +#define XPMSG_WARN_DOCFMT_LIST "Syntax error parsing document format list" +#define XPMSG_WARN_CARD_LIST "Syntax error parsing cardinal list" + +/* + * macros for memory allocation + */ +#define XpOidMalloc(size) ((char*)Xalloc((unsigned long)(size))) +#define XpOidCalloc(count, size) \ + ((char*)Xcalloc((unsigned long)((count)*(size)))) +#define XpOidFree(mem) (Xfree((unsigned long*)(mem))) + +/* + * list of object identifiers + */ +typedef struct _XpOidList +{ + XpOid* list; + int count; +} XpOidList; + +/* + * linked list of object identifiers + */ +typedef struct XpOidNodeStruct +{ + XpOid oid; + struct XpOidNodeStruct* next; +} *XpOidNode; + +typedef struct _XpOidLinkedList +{ + XpOidNode head; + XpOidNode tail; + XpOidNode current; + int count; +} XpOidLinkedList; + +/* + * XpOidMediumSourceSize and related definitions + */ +typedef struct +{ + float minimum_x; + float maximum_x; + float minimum_y; + float maximum_y; +} XpOidArea; + +typedef struct +{ + float lower_bound; + float upper_bound; +} XpOidRealRange; + +typedef struct +{ + XpOidRealRange range_across_feed; + float increment_across_feed; + XpOidRealRange range_in_feed; + float increment_in_feed; + BOOL long_edge_feeds; + XpOidArea assured_reproduction_area; +} XpOidMediumContinuousSize; + +typedef struct +{ + XpOid page_size; + BOOL long_edge_feeds; + XpOidArea assured_reproduction_area; +} XpOidMediumDiscreteSize; + +typedef struct +{ + XpOidMediumDiscreteSize* list; + int count; +} XpOidMediumDiscreteSizeList; + +typedef struct +{ + XpOid input_tray; /* may be set to xpoid_none or xpoid_unspecified */ + enum { XpOidMediumSS_DISCRETE, XpOidMediumSS_CONTINUOUS } mstag; + union + { + XpOidMediumDiscreteSizeList* discrete; + XpOidMediumContinuousSize* continuous_size; + } ms; /* "ms" is short for medium-size */ + +} XpOidMediumSourceSize; + +typedef struct +{ + XpOidMediumSourceSize* mss; + int count; +} XpOidMediumSS; + + +typedef struct +{ + XpOid input_tray; /* may be set to xpoid_none */ + XpOid medium; +} XpOidTrayMedium; + +typedef struct +{ + XpOidTrayMedium* list; + int count; +} XpOidTrayMediumList; + +typedef enum { + XPOID_NOTIFY_UNSUPPORTED, + XPOID_NOTIFY_NONE, + XPOID_NOTIFY_EMAIL +} XpOidNotify; + +typedef struct +{ + unsigned long *list; + int count; +} XpOidCardList; + +typedef struct +{ + char* format; + char* variant; + char* version; +} XpOidDocFmt; + +typedef struct +{ + XpOidDocFmt* list; + int count; +} XpOidDocFmtList; + + +/* + * XpOid public methods + */ +const char* XpOidString(XpOid); +int XpOidStringLength(XpOid); +XpOid XpOidFromString(const char* value); + +/* + * XpOidList public methods + */ +XpOidList* XpOidListNew(const char* value_string, + const XpOidList* valid_oids); +#define XpOidListInit(l, a, c) { (l)->list = (a); (l)->count = (c); } +void XpOidListDelete(XpOidList*); +#define XpOidListCount(l) ((l) ? (l)->count : 0) +#define XpOidListGetOid(l, i) ((l) ? (l)->list[(i)] : xpoid_none) +int XpOidListGetIndex(const XpOidList* list, XpOid oid); +BOOL XpOidListHasOid(const XpOidList* list, XpOid oid); +char* XpOidListString(const XpOidList*); + + +/* + * XpOidLinkedList public methods + */ +XpOidLinkedList* XpOidLinkedListNew(); +void XpOidLinkedListDelete(XpOidLinkedList*); +#define XpOidLinkedListCount(l) ((l) ? (l)->count : 0) +XpOid XpOidLinkedListGetOid(XpOidLinkedList* list, int i); +void XpOidLinkedListAddOid(XpOidLinkedList* list, XpOid oid); +int XpOidLinkedListGetIndex(XpOidLinkedList* list, XpOid oid); +BOOL XpOidLinkedListHasOid(XpOidLinkedList* list, + XpOid oid); +XpOid XpOidLinkedListFirstOid(XpOidLinkedList* list); +XpOid XpOidLinkedListNextOid(XpOidLinkedList* list); + +/* + * XpOidMediumSourceSize public methods + */ +XpOidMediumSS* XpOidMediumSSNew(const char* value_string, + const XpOidList* valid_trays, + const XpOidList* valid_medium_sizes); +void XpOidMediumSSDelete(XpOidMediumSS*); +#define XpOidMediumSSCount(me) ((me) ? (me)->count : 0) +BOOL XpOidMediumSSHasSize(XpOidMediumSS*, XpOid medium_size); +char* XpOidMediumSSString(const XpOidMediumSS*); + +/* + * XpOidTrayMediumList public methods + */ +XpOidTrayMediumList* XpOidTrayMediumListNew(const char* value_string, + const XpOidList* valid_trays, + const XpOidMediumSS* msss); +void XpOidTrayMediumListDelete(XpOidTrayMediumList* me); +#define XpOidTrayMediumListCount(me) ((me) ? (me)->count : 0) +#define XpOidTrayMediumListTray(me, i) \ + ((me) ? (me)->list[(i)].input_tray : xpoid_none) +#define XpOidTrayMediumListMedium(me, i) \ + ((me) ? (me)->list[(i)].medium : xpoid_none) +char* XpOidTrayMediumListString(const XpOidTrayMediumList*); + +/* + * XpOidNotify public methods + */ +XpOidNotify XpOidNotifyParse(const char* value_string); +const char* XpOidNotifyString(XpOidNotify notify); + +/* + * XpOidDocFmt public methods + */ +XpOidDocFmt* XpOidDocFmtNew(const char* value_string); +void XpOidDocFmtDelete(XpOidDocFmt*); +char* XpOidDocFmtString(XpOidDocFmt*); + +/* + * XpOidDocFmtList public methods + */ +XpOidDocFmtList* XpOidDocFmtListNew(const char* value_string, + const XpOidDocFmtList* valid_fmts); +void XpOidDocFmtListDelete(XpOidDocFmtList*); +char* XpOidDocFmtListString(const XpOidDocFmtList*); +#define XpOidDocFmtListCount(me) ((me) ? (me)->count : 0) +#define XpOidDocFmtListGetDocFmt(me, i) \ + ((me) ? &(me)->list[(i)] : (XpDocFmt*)NULL) +BOOL XpOidDocFmtListHasFmt(const XpOidDocFmtList* list, + const XpOidDocFmt* fmt); +/* + * XpOidCardList public methods + */ +XpOidCardList* XpOidCardListNew(const char* value_string, + const XpOidCardList* valid_cards); +#define XpOidCardListInit(l, a, c) { (l)->list = (a); (l)->count = (c); } +void XpOidCardListDelete(XpOidCardList*); +char* XpOidCardListString(const XpOidCardList*); +#define XpOidCardListCount(me) ((me) ? (me)->count : 0) +#define XpOidCardListGetCard(me, i) ((me) ? (me)->list[(i)] : 0) +BOOL XpOidCardListHasCard(const XpOidCardList*, unsigned long); + +/* + * misc parsing functions + */ +BOOL XpOidParseUnsignedValue(const char* value_string, + const char** ptr_return, + unsigned long* unsigned_return); + + +#endif /* _Xp_Oid_h - don't add anything after this line */ diff --git a/Xprint/OidDefs.h b/Xprint/OidDefs.h new file mode 100644 index 000000000..03e530cb2 --- /dev/null +++ b/Xprint/OidDefs.h @@ -0,0 +1,163 @@ +/* $Xorg: OidDefs.h,v 1.4 2001/03/14 18:45:13 pookie Exp $ */ +/* +(c) Copyright 1996 Hewlett-Packard Company +(c) Copyright 1996 International Business Machines Corp. +(c) Copyright 1996 Sun Microsystems, Inc. +(c) Copyright 1996 Novell, Inc. +(c) Copyright 1996 Digital Equipment Corp. +(c) Copyright 1996 Fujitsu Limited +(c) Copyright 1996 Hitachi, Ltd. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the names of the copyright holders shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from said +copyright holders. +*/ +/* This is an automatically-generated file. Do not edit. */ + +typedef enum { + xpoid_none, + xpoid_unspecified, + xpoid_att_descriptor, + xpoid_att_content_orientation, + xpoid_att_copy_count, + xpoid_att_default_printer_resolution, + xpoid_att_default_input_tray, + xpoid_att_default_medium, + xpoid_att_document_format, + xpoid_att_plex, + xpoid_att_xp_listfonts_modes, + xpoid_att_job_name, + xpoid_att_job_owner, + xpoid_att_notification_profile, + xpoid_att_xp_setup_state, + xpoid_att_xp_spooler_command_options, + xpoid_att_content_orientations_supported, + xpoid_att_document_formats_supported, + xpoid_att_dt_pdm_command, + xpoid_att_input_trays_medium, + xpoid_att_medium_source_sizes_supported, + xpoid_att_plexes_supported, + xpoid_att_printer_model, + xpoid_att_printer_name, + xpoid_att_printer_resolutions_supported, + xpoid_att_xp_embedded_formats_supported, + xpoid_att_xp_listfonts_modes_supported, + xpoid_att_xp_page_attributes_supported, + xpoid_att_xp_raw_formats_supported, + xpoid_att_xp_setup_proviso, + xpoid_att_document_attributes_supported, + xpoid_att_job_attributes_supported, + xpoid_att_locale, + xpoid_att_multiple_documents_supported, + xpoid_att_available_compression, + xpoid_att_available_compressions_supported, + xpoid_val_content_orientation_portrait, + xpoid_val_content_orientation_landscape, + xpoid_val_content_orientation_reverse_portrait, + xpoid_val_content_orientation_reverse_landscape, + xpoid_val_medium_size_iso_a0, + xpoid_val_medium_size_iso_a1, + xpoid_val_medium_size_iso_a2, + xpoid_val_medium_size_iso_a3, + xpoid_val_medium_size_iso_a4, + xpoid_val_medium_size_iso_a5, + xpoid_val_medium_size_iso_a6, + xpoid_val_medium_size_iso_a7, + xpoid_val_medium_size_iso_a8, + xpoid_val_medium_size_iso_a9, + xpoid_val_medium_size_iso_a10, + xpoid_val_medium_size_iso_b0, + xpoid_val_medium_size_iso_b1, + xpoid_val_medium_size_iso_b2, + xpoid_val_medium_size_iso_b3, + xpoid_val_medium_size_iso_b4, + xpoid_val_medium_size_iso_b5, + xpoid_val_medium_size_iso_b6, + xpoid_val_medium_size_iso_b7, + xpoid_val_medium_size_iso_b8, + xpoid_val_medium_size_iso_b9, + xpoid_val_medium_size_iso_b10, + xpoid_val_medium_size_na_letter, + xpoid_val_medium_size_na_legal, + xpoid_val_medium_size_executive, + xpoid_val_medium_size_folio, + xpoid_val_medium_size_invoice, + xpoid_val_medium_size_ledger, + xpoid_val_medium_size_quarto, + xpoid_val_medium_size_iso_c3, + xpoid_val_medium_size_iso_c4, + xpoid_val_medium_size_iso_c5, + xpoid_val_medium_size_iso_c6, + xpoid_val_medium_size_iso_designated_long, + xpoid_val_medium_size_na_10x13_envelope, + xpoid_val_medium_size_na_9x12_envelope, + xpoid_val_medium_size_na_number_10_envelope, + xpoid_val_medium_size_na_7x9_envelope, + xpoid_val_medium_size_na_9x11_envelope, + xpoid_val_medium_size_na_10x14_envelope, + xpoid_val_medium_size_na_number_9_envelope, + xpoid_val_medium_size_na_6x9_envelope, + xpoid_val_medium_size_na_10x15_envelope, + xpoid_val_medium_size_monarch_envelope, + xpoid_val_medium_size_a, + xpoid_val_medium_size_b, + xpoid_val_medium_size_c, + xpoid_val_medium_size_d, + xpoid_val_medium_size_e, + xpoid_val_medium_size_jis_b0, + xpoid_val_medium_size_jis_b1, + xpoid_val_medium_size_jis_b2, + xpoid_val_medium_size_jis_b3, + xpoid_val_medium_size_jis_b4, + xpoid_val_medium_size_jis_b5, + xpoid_val_medium_size_jis_b6, + xpoid_val_medium_size_jis_b7, + xpoid_val_medium_size_jis_b8, + xpoid_val_medium_size_jis_b9, + xpoid_val_medium_size_jis_b10, + xpoid_val_plex_simplex, + xpoid_val_plex_duplex, + xpoid_val_plex_tumble, + xpoid_val_input_tray_top, + xpoid_val_input_tray_middle, + xpoid_val_input_tray_bottom, + xpoid_val_input_tray_envelope, + xpoid_val_input_tray_manual, + xpoid_val_input_tray_large_capacity, + xpoid_val_input_tray_main, + xpoid_val_input_tray_side, + xpoid_val_event_report_job_completed, + xpoid_val_delivery_method_electronic_mail, + xpoid_val_xp_setup_mandatory, + xpoid_val_xp_setup_optional, + xpoid_val_xp_setup_ok, + xpoid_val_xp_setup_incomplete, + xpoid_val_xp_list_glyph_fonts, + xpoid_val_xp_list_internal_printer_fonts, + xpoid_val_available_compressions_0, + xpoid_val_available_compressions_01, + xpoid_val_available_compressions_02, + xpoid_val_available_compressions_03, + xpoid_val_available_compressions_012, + xpoid_val_available_compressions_013, + xpoid_val_available_compressions_023, + xpoid_val_available_compressions_0123 +} XpOid; diff --git a/Xprint/OidStrs.h b/Xprint/OidStrs.h new file mode 100644 index 000000000..81119378c --- /dev/null +++ b/Xprint/OidStrs.h @@ -0,0 +1,165 @@ +/* $Xorg: OidStrs.h,v 1.4 2001/03/14 18:45:40 pookie Exp $ */ +/* +(c) Copyright 1996 Hewlett-Packard Company +(c) Copyright 1996 International Business Machines Corp. +(c) Copyright 1996 Sun Microsystems, Inc. +(c) Copyright 1996 Novell, Inc. +(c) Copyright 1996 Digital Equipment Corp. +(c) Copyright 1996 Fujitsu Limited +(c) Copyright 1996 Hitachi, Ltd. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the names of the copyright holders shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from said +copyright holders. +*/ +/* This is an automatically-generated file. Do not edit. */ + +static int XpOidStringMapCount = 127; + +static const XpOidStringMapEntry XpOidStringMap[] = { + { "", 0 }, + { "", 0 }, + { "descriptor", 10 }, + { "content-orientation", 19 }, + { "copy-count", 10 }, + { "default-printer-resolution", 26 }, + { "default-input-tray", 18 }, + { "default-medium", 14 }, + { "document-format", 15 }, + { "plex", 4 }, + { "xp-listfonts-modes", 18 }, + { "job-name", 8 }, + { "job-owner", 9 }, + { "notification-profile", 20 }, + { "xp-setup-state", 14 }, + { "xp-spooler-command-options", 26 }, + { "content-orientations-supported", 30 }, + { "document-formats-supported", 26 }, + { "dt-pdm-command", 14 }, + { "input-trays-medium", 18 }, + { "medium-source-sizes-supported", 29 }, + { "plexes-supported", 16 }, + { "printer-model", 13 }, + { "printer-name", 12 }, + { "printer-resolutions-supported", 29 }, + { "xp-embedded-formats-supported", 29 }, + { "xp-listfonts-modes-supported", 28 }, + { "xp-page-attributes-supported", 28 }, + { "xp-raw-formats-supported", 24 }, + { "xp-setup-proviso", 16 }, + { "document-attributes-supported", 29 }, + { "job-attributes-supported", 24 }, + { "locale", 6 }, + { "multiple-documents-supported", 28 }, + { "available-compression", 21 }, + { "available-compressions-supported", 32 }, + { "portrait", 8 }, + { "landscape", 9 }, + { "reverse-portrait", 16 }, + { "reverse-landscape", 17 }, + { "iso-a0", 6 }, + { "iso-a1", 6 }, + { "iso-a2", 6 }, + { "iso-a3", 6 }, + { "iso-a4", 6 }, + { "iso-a5", 6 }, + { "iso-a6", 6 }, + { "iso-a7", 6 }, + { "iso-a8", 6 }, + { "iso-a9", 6 }, + { "iso-a10", 7 }, + { "iso-b0", 6 }, + { "iso-b1", 6 }, + { "iso-b2", 6 }, + { "iso-b3", 6 }, + { "iso-b4", 6 }, + { "iso-b5", 6 }, + { "iso-b6", 6 }, + { "iso-b7", 6 }, + { "iso-b8", 6 }, + { "iso-b9", 6 }, + { "iso-b10", 7 }, + { "na-letter", 9 }, + { "na-legal", 8 }, + { "executive", 9 }, + { "folio", 5 }, + { "invoice", 7 }, + { "ledger", 6 }, + { "quarto", 6 }, + { "iso-c3", 6 }, + { "iso-c4", 6 }, + { "iso-c5", 6 }, + { "iso-c6", 6 }, + { "iso-designated-long", 19 }, + { "na-10x13-envelope", 17 }, + { "na-9x12-envelope", 16 }, + { "na-number-10-envelope", 21 }, + { "na-7x9-envelope", 15 }, + { "na-9x11-envelope", 16 }, + { "na-10x14-envelope", 17 }, + { "na-number-9-envelope", 20 }, + { "na-6x9-envelope", 15 }, + { "na-10x15-envelope", 17 }, + { "monarch-envelope", 16 }, + { "a", 1 }, + { "b", 1 }, + { "c", 1 }, + { "d", 1 }, + { "e", 1 }, + { "jis-b0", 6 }, + { "jis-b1", 6 }, + { "jis-b2", 6 }, + { "jis-b3", 6 }, + { "jis-b4", 6 }, + { "jis-b5", 6 }, + { "jis-b6", 6 }, + { "jis-b7", 6 }, + { "jis-b8", 6 }, + { "jis-b9", 6 }, + { "jis-b10", 7 }, + { "simplex", 7 }, + { "duplex", 6 }, + { "tumble", 6 }, + { "top", 3 }, + { "middle", 6 }, + { "bottom", 6 }, + { "envelope", 8 }, + { "manual", 6 }, + { "large-capacity", 14 }, + { "main", 4 }, + { "side", 4 }, + { "event-report-job-completed", 26 }, + { "electronic-mail", 15 }, + { "xp-setup-mandatory", 18 }, + { "xp-setup-optional", 17 }, + { "xp-setup-ok", 11 }, + { "xp-setup-incomplete", 19 }, + { "xp-list-glyph-fonts", 19 }, + { "xp-list-internal-printer-fonts", 30 }, + { "0", 1 }, + { "01", 2 }, + { "02", 2 }, + { "03", 2 }, + { "012", 3 }, + { "013", 3 }, + { "023", 3 }, + { "0123", 4 } +}; diff --git a/Xprint/Util.c b/Xprint/Util.c new file mode 100644 index 000000000..efc196f82 --- /dev/null +++ b/Xprint/Util.c @@ -0,0 +1,360 @@ +/* $Xorg: Util.c,v 1.3 2000/08/17 19:48:06 cpqbld Exp $ */ +/* +(c) Copyright 1996 Hewlett-Packard Company +(c) Copyright 1996 International Business Machines Corp. +(c) Copyright 1996 Sun Microsystems, Inc. +(c) Copyright 1996 Novell, Inc. +(c) Copyright 1996 Digital Equipment Corp. +(c) Copyright 1996 Fujitsu Limited +(c) Copyright 1996 Hitachi, Ltd. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the names of the copyright holders shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from said +copyright holders. +*/ +#include "Xos.h" /* for unistd.h and string.h */ +#include <stdio.h> +#include <sys/wait.h> +#include <sys/stat.h> +#include "dixstruct.h" +#include "scrnintstr.h" +#include "misc.h" + +#define _XP_PRINT_SERVER_ +#include "extensions/Print.h" +#include "extensions/Printstr.h" +#undef _XP_PRINT_SERVER_ + +#define IN_FILE_STRING "%(InFile)%" +#define OUT_FILE_STRING "%(OutFile)%" + +/* + * ReplaceAnyString returns a string combining the input strings. + * It replaces all occurances of 'target' with the supplied + * 'replacement'. + * The original input string will generally be freed, + * and the caller is responsible for freeing whatever string is returned. + */ +char * +ReplaceAnyString( + char *string, + char *target, + char *replacement) +{ + char *pKeyString; + + if(replacement != (char *)NULL) + { + while((pKeyString = strstr(string, target)) != (char *)NULL) + { + char *newString; + + newString = (char *)xalloc(strlen(string) + strlen(replacement) - + strlen(target) + 1); + strncpy(newString, string, pKeyString - string); + newString[pKeyString - string] = '\0'; + strcat(newString, replacement); + strcat(newString, pKeyString + strlen(target)); + xfree(string); + string = newString; + } + } + + return string; +} + +/* + * ReplaceFileString returns a string combining the input strings. + * It replaces all occurances of IN_FILE_STRING with the supplied + * inFileName, and all occurances of OUT_FILE_STRING with the + * supplied outFileName. The original input string will generally be freed, + * and the caller is responsible for freeing whatever string is returned. + */ +char * +ReplaceFileString(string, inFileName, outFileName) + char *string; + char *inFileName; + char *outFileName; +{ + char *pKeyString, + *pInFileString = IN_FILE_STRING, + *pOutFileString = OUT_FILE_STRING; + + if(inFileName != (char *)NULL) + { + while((pKeyString = strstr(string, pInFileString)) != + (char *)NULL) + { + char *newString; + + newString = (char *)xalloc(strlen(string) + + strlen(inFileName) + 1); + strncpy(newString, string, pKeyString - string); + newString[pKeyString - string] = '\0'; + strcat(newString, inFileName); + strcat(newString, pKeyString + strlen(pInFileString)); + xfree(string); + string = newString; + } + } + + if(outFileName != (char *)NULL) + { + while((pKeyString = strstr(string, pOutFileString)) != + (char *)NULL) + { + char *newString; + + newString = (char *)xalloc(strlen(string) + + strlen(outFileName) + 1); + strncpy(newString, string, pKeyString - string); + newString[pKeyString - string] = '\0'; + strcat(newString, outFileName); + strcat(newString, pKeyString + strlen(pOutFileString)); + xfree(string); + string = newString; + } + } + return string; +} + +/* + * ExecCommand takes two character pointers - the command to execute, + * and the "argv" style NULL-terminated vector of arguments for the command. + * We wait for the command to terminate before continuing to ensure that + * we don't delete the job file before the spooler has made a copy. + */ +void +ExecCommand(pCommand, argVector) + char *pCommand; + char **argVector; +{ + pid_t childPid; + int status; + + if((childPid = fork()) == 0) + { + execv(pCommand, argVector); + } + else + { + (void) waitpid(childPid, &status, 0); + } + return; +} + +/* + * TransferBytes reads numBytes of data from pSrcFile and writes them + * to pDstFile. It returns the number of bytes actually transfered, + * which will be numBytes if it's successful. Neither pSrcFile nor + * pDstFile are rewound or their pointers otherwise modified prior to + * beginning the transfer. + */ +int +TransferBytes(pSrcFile, pDstFile, numBytes) + FILE *pSrcFile, + *pDstFile; + int numBytes; +{ + char buf[10240]; + int bytesWritten = 0, bytesToXfer; + + for(bytesToXfer = min(sizeof(buf)*sizeof(char), numBytes); + bytesToXfer > 0; + bytesToXfer = min(sizeof(buf)*sizeof(char), numBytes - bytesWritten)) + { + if(fread((void *)buf, (size_t) 1, bytesToXfer, pSrcFile) < bytesToXfer) + return bytesWritten; + if(fwrite((void *)buf, (size_t) 1, bytesToXfer, pDstFile) < bytesToXfer) + return bytesWritten; + bytesWritten += bytesToXfer; + } + return bytesWritten; +} + +/* + * CopyContentsAndDelete - does the work of copying and deleting the + * pre, no, and post raster files as well as the raster file itself. + */ +Bool +CopyContentsAndDelete(ppSrcFile, pSrcFileName, pDstFile) + FILE **ppSrcFile, + *pDstFile; + char **pSrcFileName; +{ + struct stat statBuf; + + if(stat(*pSrcFileName, &statBuf) < 0) + return FALSE; + rewind(*ppSrcFile); + if(TransferBytes(*ppSrcFile, pDstFile, + (int)statBuf.st_size) != (int)statBuf.st_size) + return FALSE; + fclose(*ppSrcFile); + *ppSrcFile = (FILE *)NULL; + unlink(*pSrcFileName); + xfree(*pSrcFileName); + *pSrcFileName = (char *)NULL; + + return TRUE; +} + + +#define QUADPAD(x) ((((x)+3)>>2)<<2) + +int +XpSendDocumentData( + ClientPtr client, + FILE *fp, + int fileLen, + int maxBufSize) +{ + xPrintGetDocumentDataReply *pRep; + int bytesWritten, bytesToWrite; + int result = Success; + + if(client->clientGone) + return Success; + + pRep = (xPrintGetDocumentDataReply *)xalloc(sz_xPrintGetDocumentDataReply+ + QUADPAD(maxBufSize)); + + for(bytesToWrite = min(maxBufSize, fileLen), + bytesWritten = 0; + bytesToWrite > 0; + bytesToWrite = min(maxBufSize, fileLen - bytesWritten)) + { + pRep->type = X_Reply; + pRep->sequenceNumber = client->sequence; + pRep->length = (QUADPAD(bytesToWrite)) >> 2; + pRep->dataLen = bytesToWrite; + + if(fread((void *)(pRep + 1), (size_t) 1, bytesToWrite, fp) < + bytesToWrite) + { + result = BadAlloc; /* XXX poor error choice? */ + pRep->statusCode = 2; /* XXX Is this the right value??? */ + } + else + pRep->statusCode = 0; /* XXX Ignored??? */ + + pRep->finishedFlag = FALSE; + + if (client->swapped) { + int n; + long l; + + swaps(&pRep->sequenceNumber, n); + swapl(&pRep->length, l); + swapl(&pRep->statusCode, l); /* XXX Why are these longs??? */ + swapl(&pRep->finishedFlag, l); /* XXX Why are these longs??? */ + swapl(&pRep->dataLen, l); + } + + (void)WriteToClient(client, + sz_xPrintGetDocumentDataReply + bytesToWrite, + (char *)pRep); + bytesWritten += bytesToWrite; + } + + xfree(pRep); + return result; +} + +/* + * XpFinishDocData - send a DocumentData reply with the "finishedFlag" + * field set to TRUE. This routine should be called from the EndJob + * function of a driver after the driver has sent all required + * document data (presumably via XpSendDocumentData). + */ +int +XpFinishDocData( + ClientPtr client) +{ + xPrintGetDocumentDataReply rep; + + if(client->clientGone) + return Success; + + rep.type = X_Reply; + rep.sequenceNumber = client->sequence; + rep.length = 0; + rep.dataLen = 0; + rep.finishedFlag = TRUE; + rep.statusCode = 0; + + if (client->swapped) { + int n; + long l; + + swaps(&rep.sequenceNumber, n); + swapl(&rep.length, l); + swapl(&rep.statusCode, l); /* XXX Why are these longs??? */ + swapl(&rep.finishedFlag, l); /* XXX Why are these longs??? */ + swapl(&rep.dataLen, l); + } + + (void)WriteToClient(client, sz_xPrintGetDocumentDataReply, (char *)&rep); + return Success; +} + +static +char *XpDirName(char *fname) +{ + char *fn, *ptr; + + fn = (char *)xalloc(strlen(fname) + 1); + if (fn) { + strcpy(fn, fname); + ptr = strrchr(fn, '/'); + if (!ptr) { + ptr = fn; + *ptr++ = '.'; + } else if (ptr == fn) + ptr++; + *ptr = '\0'; + } + return fn; +} + +Bool +XpOpenTmpFile( + char *mode, + char **fname, + FILE **stream) +{ + char *fn = NULL; + + /* note that there is a small race condition here... */ + if (!(*fname = tempnam(NULL, NULL)) || + !(fn = XpDirName(*fname)) || + access(fn, W_OK) || + !(*stream = fopen(*fname, mode))) + { + xfree(fn); + xfree(*fname); + *fname = NULL; + *stream = NULL; + return FALSE; + } + xfree(fn); + return TRUE; +} diff --git a/Xprint/ValTree.c b/Xprint/ValTree.c new file mode 100644 index 000000000..73aa27a36 --- /dev/null +++ b/Xprint/ValTree.c @@ -0,0 +1,187 @@ +/* $Xorg: ValTree.c,v 1.3 2000/08/17 19:48:06 cpqbld Exp $ */ +/* +(c) Copyright 1996 Hewlett-Packard Company +(c) Copyright 1996 International Business Machines Corp. +(c) Copyright 1996 Sun Microsystems, Inc. +(c) Copyright 1996 Novell, Inc. +(c) Copyright 1996 Digital Equipment Corp. +(c) Copyright 1996 Fujitsu Limited +(c) Copyright 1996 Hitachi, Ltd. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the names of the copyright holders shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from said +copyright holders. +*/ +#include "X.h" +#include "scrnintstr.h" +#include "validate.h" +#include "windowstr.h" +#include "mi.h" +#include "regionstr.h" +#include "mivalidate.h" + +/* + * XpValidateTree - a validateTree routine which ignores overlapping + * top-level windows when computing the clip lists for such windows. + * This can be used by any driver which maintains a separate memory + * store for each top-level window (with its respective children). + * If the pParent is not the root window, then miValidateTree + * is used unmodified. + * + * The strategy if pParent is the root is to save off the + * current values of pParent->firstChild and pParent->lastChild, + * replacing both with the single child of interest. We save off + * pChild->prevSib and pChild->nextSib, and replace them with NullWindow. + * We save off pParent->clipList, and replace it with + * pParent->winSize - pChild->winSize. We then call miValidateTree + * to do the needed ComputeClips on the pChild's heirarchy. + * pParent's clipList is then recomputed based on the sizes + * of its children, and the saved pointers are restored. + * The trees associated with the siblings of pChild must be descended + * and cleaned of any marks (i.e. the valdata pointer freed, and set to NULL), + * and pParent' AfterValidate structure's exposed field must be updated. + */ +/*ARGSUSED*/ +int +XpValidateTree (pParent, pChild, kind) + WindowPtr pParent; /* Parent to validate */ + WindowPtr pChild; /* First child of pParent that was + * affected */ + VTKind kind; /* What kind of configuration caused call */ +{ + RegionRec origPrntClip; /* orig clipList for parent */ + RegionRec childClip; /* The new borderClip for the current + * child */ + RegionRec tmpPrntClip; /* parent clipList - child borderClip */ + RegionRec exposed; /* For intermediate calculations */ + register ScreenPtr pScreen; + register WindowPtr pWin; + Bool overlap; + int viewvals; + Bool forward; + + WindowPtr origFirstChild, origLastChild, origPrevSib, origNextSib; + + /* + * If we're validating something other than a top-level window, + * then just invoke miValidateTree. + */ + if(pParent->parent != NullWindow) + return miValidateTree(pParent, pChild, kind); + + /* + * If it's a stack change of top levels then it's a no-op for + * this scheme, so we just clean up any marks on windows and return. + */ + if(kind == VTStack) + { + CleanMarks(pParent); + return 1; + } + + pScreen = pParent->drawable.pScreen; + if (pChild == NullWindow) + pChild = pParent->firstChild; + + /* Save off the existing window heirarchy */ + origFirstChild = pParent->firstChild; + origLastChild = pParent->lastChild; + origPrevSib = pChild->prevSib; + origNextSib = pChild->nextSib; + pParent->firstChild = pChild; + pParent->lastChild = pChild; + pChild->prevSib = NullWindow; + pChild->nextSib = NullWindow; + + /* + * Set pParent's clipList to be its winSize minus the pChild's + * borderSize. + */ + origPrntClip = pParent->clipList; + REGION_INIT(pScreen, &tmpPrntClip, NullBox, 0); + REGION_SUBRACT(pScreen, &tmpPrntClip, &pParent->winSize, + &pChild->borderSize); + pParent->clipList = tmpPrntClip; + + /* + * Call miValidateTree on the pruned tree. + */ + (void) miValidateTree(pParent, pChild, kind); + + /* Restore the saved heirarchy */ + pChild->prevSib = origPrevSib; + pChild->nextSib = origNextSib; + pParent->firstChild = origFirstChild; + pParent->lastChild = origLastChild; + + /* + * Compute pParent's clipList by taking its winSize and subracting + * the borderSize of each of its children. + */ + for(pWin = pParent->firstChild, + REGION_COPY(pScreen, &pParent->clipList, &pParent->winSize); + pWin != NullWindow; + pWin = pWin->nextSib) + { + REGION_SUBTRACT(pScreen, &pParent->clipList, &pParent->clipList, + &pWin->borderSize); + } + + /* + * Compute pParent's AfterValidate structure by subracting the original + * clipList from the newly computed clipList. + */ + REGION_INIT(pScreen, &pParent->valdata->after.exposed, NullBox, 0); + REGION_SUBTRACT(pScreen, &pParent->valdata->after.exposed, + &pParent->clipList, &origPrntClip); + + /* + * Remove the marks from all but pParent and pChild's heirarchy. + * i.e. from all of pChild's siblings and their children. + */ + for(pWin = pParent->firstChild; pWin != NullWindow; pWin = pWin->nextSib) + { + WindowPtr pCurChild = pWin; + + if(pCurChild == pChild) + continue; + + while (1) + { + if(pCurChild->valdata) + { + xfree(pCurChild->valdata); + pCurChild->valdata = (ValidatePtr)NULL; + } + + if (pCurChild->firstChild) + { + pCurChild = pCurChild->firstChild; + continue; + } + while (!pCurChild->nextSib && (pCurChild != pWin)) + pCurChild = pCurChild->parent; + if (pCurChild == pWin) + break; + pCurChild = pCurChild->nextSib; + } + } +} diff --git a/Xprint/attributes.c b/Xprint/attributes.c new file mode 100644 index 000000000..7348d6402 --- /dev/null +++ b/Xprint/attributes.c @@ -0,0 +1,1575 @@ +/* $Xorg: attributes.c,v 1.3 2000/08/17 19:48:07 cpqbld Exp $ */ +/* +(c) Copyright 1996 Hewlett-Packard Company +(c) Copyright 1996 International Business Machines Corp. +(c) Copyright 1996 Sun Microsystems, Inc. +(c) Copyright 1996 Novell, Inc. +(c) Copyright 1996 Digital Equipment Corp. +(c) Copyright 1996 Fujitsu Limited +(c) Copyright 1996 Hitachi, Ltd. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the names of the copyright holders shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from said +copyright holders. +*/ +/******************************************************************* +** +** ********************************************************* +** * +** * File: attributes.c +** * +** * Contents: +** * Implementation of the attribute store for Xp. +** * +** * Copyright: Copyright 1995 Hewlett-Packard Company +** * +** ********************************************************* +** +********************************************************************/ + +#include <Xproto.h> +#include <string.h> +#include <stdlib.h> +#include <sys/wait.h> +#include <pwd.h> + +#include <scrnintstr.h> + +#define _XP_PRINT_SERVER_ +#include "extensions/Printstr.h" +#undef _XP_PRINT_SERVER_ + +#include "Xrm.c" + +static XrmDatabase CopyDb(XrmDatabase inDb); + +extern XrmDatabase XpSpoolerGetServerAttributes(); + +static int attrGeneration = 0; + +typedef struct { + XrmDatabase *pDb; + char *qualifier; + char *modelId; +} DbEnumStruct; + +typedef struct { + char *stringDb; + int nextPos; + int space; +} StringDbStruct; + +typedef struct _printerAttrs { + struct _printerAttrs *next; + char *name; + char *qualifier; + XrmDatabase printerAttrs; + XrmDatabase docAttrs; + XrmDatabase jobAttrs; +} PrAttrs, *PrAttrPtr; + +static PrAttrPtr attrList = (PrAttrPtr)NULL; + +typedef struct _systemAttrs { + XrmDatabase doc; + XrmDatabase job; + XrmDatabase printers; + XrmDatabase server; +} SysAttrs, *SysAttrsPtr; + +SysAttrs systemAttributes; + +/* + * attrCtxtPrivIndex hold the attribute store's context private index. + * This index is allocated at the time the attribute store is initialized. + */ +static int attrCtxtPrivIndex; + +/* + * The ContextAttrs structure descibes the context private space reserved + * by the attribute store. + */ +typedef struct _contextAttrs { + XrmDatabase printerAttrs; + XrmDatabase docAttrs; + XrmDatabase jobAttrs; + XrmDatabase pageAttrs; +} ContextAttrs, *ContextAttrPtr; + +/* + * XPDIR is relative to (i.e. is a subdir of) XPRINTDIR/$LANG. + */ +static const char XPDIR[] = "/print"; +/* + * The following files/directories define or are within subdirectories of the + * above-defined XPDIR. + */ +static const char XPPRINTERATTRFILE[] = "/attributes/printer"; +static const char XPJOBATTRFILE[] = "/attributes/job"; +static const char XPDOCATTRFILE[] = "/attributes/document"; +static const char XPMODELDIR[] = "/models"; + +static char NULL_STRING[] = "\0"; + +/* + * XpGetConfigDir returns a string containing the path name of the print + * server configuration directory. If the useLocale parameter is False + * the it returns the path to the "/C" directory. If the useLocale + * parameter is True it returns the path to the directory associated with + * $LANG. It makes no attempt to ensure that the directory actually exists. + */ +char * +XpGetConfigDir(useLocale) + Bool useLocale; +{ + char *dirName, *langName, *langDir, *configDir; + Bool freeLangDir = False; + + if(useLocale == False) langDir = "/C"; + else + { + if((langName = getenv("LANG")) == (char *)NULL) + return (char *)NULL; + else + { + if(strcmp(langName, "C") == 0) + return (char *)NULL; + langDir = (char *)xalloc(strlen(langName) + 2); + sprintf(langDir, "/%s", langName); + freeLangDir = True; + } + } + + /* + * If the XPCONFIGDIR environment variable is not set, then use the + * compile-time constant XPRINTDIR. XPRINTDIR is passed in on the + * compile command line, and is defined in $(TOP)/config/cf/Project.tmpl. + */ + if((configDir = getenv("XPCONFIGDIR")) == (char *)NULL) + configDir = XPRINTDIR; + + dirName = (char *)xalloc(strlen(configDir) + strlen(XPDIR) + + strlen(langDir) + 1); + sprintf(dirName, "%s%s%s", configDir, langDir, XPDIR); + + if(freeLangDir == True) + xfree(langDir); + + return dirName; +} + +/* + * GetMergedDatabase reads and merges xrmdb files from the top-level printer + * config directory, and from the directory associated with the current + * locale (if other than the top-level). + */ +static XrmDatabase +GetMergedDatabase(attrName) + char *attrName; +{ + char *dirName, *fileName; + XrmDatabase db; + + if((dirName = XpGetConfigDir(False)) == (char *)NULL) + return (XrmDatabase)NULL; + if((fileName = (char *)xalloc(strlen(dirName) + strlen(attrName) + 1)) == + (char *)NULL) + return (XrmDatabase)NULL; + sprintf(fileName, "%s%s", dirName, attrName); + db = XrmGetFileDatabase(fileName); + xfree(fileName); + xfree(dirName); + + if((dirName = XpGetConfigDir(True)) == (char *)NULL) + return db; + if((fileName = (char *)xalloc(strlen(dirName) + strlen(attrName) + 1)) == + (char *)NULL) + return db; + sprintf(fileName, "%s%s", dirName, attrName); + (void)XrmCombineFileDatabase(fileName, &db, True); + xfree(fileName); + xfree(dirName); + + return db; +} + +/* + * BuildSystemAttributes reads the on-disk configuration files for printers, + * initial job, and initial document attributes. The resulting xrm + * databases are then dissected as needed for each printer. + * It also allocates a contextPrivate space for the attributes, + * reserving space to store pointers to the attribute stores for + * the context. + */ +static void +BuildSystemAttributes() +{ + if(systemAttributes.printers != (XrmDatabase)NULL) + XrmDestroyDatabase(systemAttributes.printers); + systemAttributes.printers = GetMergedDatabase(XPPRINTERATTRFILE); + if(systemAttributes.job != (XrmDatabase)NULL) + XrmDestroyDatabase(systemAttributes.job); + systemAttributes.job = GetMergedDatabase(XPJOBATTRFILE); + if(systemAttributes.doc != (XrmDatabase)NULL) + XrmDestroyDatabase(systemAttributes.doc); + systemAttributes.doc = GetMergedDatabase(XPDOCATTRFILE); + if(systemAttributes.server != (XrmDatabase)NULL) + XrmDestroyDatabase(systemAttributes.server); + systemAttributes.server = XpSpoolerGetServerAttributes(); + return; +} + +/* + * AddDbEntry is called by XrmEnumerateDatabase, and adds the supplied + * database entry to the database pointed to within the "DbEnumStruct" + * passed as the client_data (aka "closure"). + */ +static Bool +AddDbEntry(sourceDB, bindings, quarks, type, value, client_data) + XrmDatabase *sourceDB; + XrmBindingList bindings; + XrmQuarkList quarks; + XrmRepresentation *type; + XrmValue *value; + XPointer client_data; +{ + DbEnumStruct *pEnumStruct = (DbEnumStruct *)client_data; + XrmName xrm_name[5]; + XrmClass xrm_class[5]; + XrmBinding xrm_bind[3]; + XrmValue realVal; + XrmRepresentation rep_type; + + xrm_name[0] = XrmStringToQuark (pEnumStruct->qualifier); + xrm_class[0] = XrmStringToQuark (pEnumStruct->modelId); + + for(;*quarks; quarks++) + xrm_name[1] = xrm_class[1] = *quarks; + + xrm_name[2] = (XrmQuark)NULL; + xrm_class[2] = (XrmQuark)NULL; + + if(XrmQGetResource (*sourceDB, xrm_name, xrm_class, &rep_type, &realVal)) + { + xrm_bind[0] = XrmBindLoosely; + + xrm_name[0] = xrm_name[1]; + xrm_name[1] = NULLQUARK; + + XrmQPutStringResource(pEnumStruct->pDb, xrm_bind, xrm_name, + (char *)realVal.addr); + } + + return FALSE; +} + +/* + * BuildPrinterAttrs - builds and returns an XrmDatabase for the printer + * of the specified name/qualifier, if we have enough information. + * If we don't have a model-config + * file, then just enumerate the systemAttributes->printers database, + * otherwise read in the model-config database and merge into it the + * systemAttributes->printers database. This database is then enumerated + * with the printer qualifier (and the model name as class if we have it), and + * the resulting elements are stored into the database for this particular + * printer. + */ +static XrmDatabase +BuildPrinterAttrs(printerName, qualifierName) + char *printerName; + char *qualifierName; +{ + XrmDatabase printerDB = (XrmDatabase)NULL; + + if(systemAttributes.printers != (XrmDatabase)NULL) + { + char *dirName, *fileName; + XrmDatabase modelDB = (XrmDatabase)NULL; + XrmName xrm_name[5], xrm_class[2]; + XrmRepresentation rep_type; + XrmValue value; + DbEnumStruct enumStruct; + Bool freeModelDB = False; + /* + * Build the initial db based on the model-config files + */ + xrm_name[0] = XrmStringToQuark (qualifierName); + xrm_name[1] = XrmStringToQuark ("xp-model-identifier"); + xrm_name[2] = (XrmQuark)NULL; + XrmQGetResource (systemAttributes.printers, xrm_name, xrm_name, + &rep_type, &value); + + if(value.addr != (XPointer)NULL) + { + fileName = (char *)xalloc(strlen(XPMODELDIR) + + strlen((char *)value.addr) + + strlen("model-config") + 3); + sprintf(fileName, "%s/%s/%s", XPMODELDIR, value.addr, + "model-config"); + modelDB = GetMergedDatabase(fileName); + xfree(fileName); + if(modelDB != (XrmDatabase)NULL) + { + XrmDatabase tempDB = (XrmDatabase)NULL; + /* + * have to make a temp copy because MergeDatabase destroys + * the "source" database. Merge in the printers DB + */ + tempDB = CopyDb(systemAttributes.printers); + XrmMergeDatabases(tempDB, &modelDB); + freeModelDB = True; + } + } + + /* + * Check to see if we knew the name AND found a database file + */ + if(modelDB == (XrmDatabase)NULL) + modelDB = systemAttributes.printers; + + xrm_name[0] = XrmStringToQuark (qualifierName); + xrm_name[1] = (XrmQuark)NULL; + xrm_class[0] = XrmStringToQuark((char *)value.addr); + xrm_class[1] = (XrmQuark)NULL; + enumStruct.pDb = &printerDB; + enumStruct.qualifier = (char *)qualifierName; + enumStruct.modelId = (char *)value.addr; + XrmEnumerateDatabase(modelDB, xrm_name, xrm_class, XrmEnumAllLevels, + AddDbEntry, (XPointer) &enumStruct); + + if(freeModelDB == True) XrmDestroyDatabase(modelDB); + } + XrmPutStringResource(&printerDB, "*printer-name", printerName); + XrmPutStringResource(&printerDB, "*qualifier", qualifierName); + return printerDB; +} + +/* + * BuildABase - builds an XrmDatabase by enumerating the supplied sourceBase + * database for elements relevant for the printer named by printerName, + * and deriving a class for printerName from the model declared in the + * systemAttributes.printers database. If no model is defined for this + * printer then the printerName is used as the class as well. + * + * This is used to build the initial value document and initial value + * job attribute databases for each printer by searching the system + * level doc and job databases. + */ +static XrmDatabase +BuildABase(printerName, qualifierName, sourceBase) + char *printerName; + char *qualifierName; + XrmDatabase sourceBase; +{ + XrmDatabase builtDB = (XrmDatabase)NULL; + + if(sourceBase != (XrmDatabase)NULL) + { + XrmName xrm_name[5], xrm_class[2]; + XrmRepresentation rep_type; + XrmValue value; + DbEnumStruct enumStruct; + + /* + * Retrieve the model name for use as the class. + */ + xrm_name[0] = XrmStringToQuark (printerName); + xrm_name[1] = XrmStringToQuark ("xp-model-identifier"); + xrm_name[2] = (XrmQuark)NULL; + XrmQGetResource (systemAttributes.printers, xrm_name, xrm_name, + &rep_type, &value); + /* + * if we have a model name then use it as the class, otherwise + * just use the printer name as the class as well as the name. + */ + if(value.addr != (XPointer)NULL) + xrm_class[0] = XrmStringToQuark((char *)value.addr); + else + xrm_class[0] = xrm_name[0]; + xrm_class[1] = (XrmQuark)NULL; + + xrm_name[1] = (XrmQuark)NULL; + + enumStruct.pDb = &builtDB; + enumStruct.qualifier = (char *)qualifierName; + enumStruct.modelId = (char *)value.addr; + XrmEnumerateDatabase(sourceBase, xrm_name, xrm_class, XrmEnumAllLevels, + AddDbEntry, (XPointer) &enumStruct); + } + + XrmPutStringResource(&builtDB, "*qualifier", qualifierName); + + return builtDB; +} + +/* + * FreeAttrList is called upon server recycle, and frees the printer + * databases stored in the global attrList. + */ +static void +FreeAttrList() +{ + PrAttrPtr pAttr, pNext; + + for(pAttr = attrList, pNext = attrList; + pAttr != (PrAttrPtr)NULL; + pAttr = pNext) + { + pNext = pAttr->next; + if(pAttr->printerAttrs != (XrmDatabase)NULL) + XrmDestroyDatabase(pAttr->printerAttrs); + if(pAttr->docAttrs != (XrmDatabase)NULL) + XrmDestroyDatabase(pAttr->docAttrs); + if(pAttr->jobAttrs != (XrmDatabase)NULL) + XrmDestroyDatabase(pAttr->jobAttrs); + xfree(pAttr->name); + xfree(pAttr->qualifier); + xfree(pAttr); + } + attrList = (PrAttrPtr)NULL; +} + +/* + * XpRehashAttributes - frees the per-printer attribute list and + * calls BuildSystemAttributes to rebuild the overall attribute + * store. It is expected that a caller of this will follow it + * by calling XpBuildAttributeStore for a new list of printers. + */ +int +XpRehashAttributes() +{ + if(attrList != (PrAttrPtr)NULL) + FreeAttrList(); + BuildSystemAttributes(); + return Success; +} + +/* + * XpBuildAttributeStore - creates the attribute database associated + * with the specified printer. The first time this is called it + * calls BuildSystemAttributes to create the system-level databases. + */ +void +XpBuildAttributeStore(printerName, qualifierName) + char *printerName; + char *qualifierName; +{ + PrAttrPtr pAttr; + + if((pAttr = (PrAttrPtr)xalloc(sizeof(PrAttrs))) == (PrAttrPtr)NULL) + return; + + if(attrGeneration != serverGeneration) + { + if(attrList != (PrAttrPtr)NULL) + FreeAttrList(); + attrCtxtPrivIndex = XpAllocateContextPrivateIndex(); + XpAllocateContextPrivate(attrCtxtPrivIndex, sizeof(ContextAttrs)); + BuildSystemAttributes(); + + attrGeneration = serverGeneration; + } + + if(attrList == (PrAttrPtr)NULL) + { + pAttr->next = (PrAttrPtr)NULL; + attrList = pAttr; + } + else + { + pAttr->next = attrList; + attrList = pAttr; + } + + pAttr->name = strdup(printerName); + pAttr->qualifier = strdup(qualifierName); + pAttr->printerAttrs = BuildPrinterAttrs(printerName, qualifierName); + pAttr->docAttrs = BuildABase(printerName, qualifierName, + systemAttributes.doc); + pAttr->jobAttrs = BuildABase(printerName, qualifierName, + systemAttributes.job); +} + + +static Bool +StoreEntry(sourceDB, bindings, quarks, type, value, client_data) + XrmDatabase *sourceDB; + XrmBindingList bindings; + XrmQuarkList quarks; + XrmRepresentation *type; + XrmValue *value; + XPointer client_data; +{ + XrmDatabase *outDb = (XrmDatabase *)client_data; + + XrmQPutStringResource(outDb, bindings, quarks, (char *)value->addr); + + return FALSE; +} + +/* + * XpCopyDb - makes a copy of the specified XrmDatabase and returns + * the copy. + */ +static XrmDatabase +CopyDb(inDb) + XrmDatabase inDb; +{ + XrmDatabase outDb = (XrmDatabase)NULL; + XrmQuark empty = NULLQUARK; + + (void)XrmEnumerateDatabase(inDb, &empty, &empty, XrmEnumAllLevels, + StoreEntry, (XPointer) &outDb); + return outDb; +} + +/* + * XpInitAttributes - initializes the attribute store for the specified + * context. It does this by making copies of the printer, doc, and job + * attributes databases for the printer associated with the context. + */ +void +XpInitAttributes( pContext ) + XpContextPtr pContext; +{ + ContextAttrPtr pCtxtAttrs; + PrAttrPtr pPrAttr = attrList; + + /* Initialize all the pointers to NULL */ + pCtxtAttrs = (ContextAttrPtr)pContext->devPrivates[attrCtxtPrivIndex].ptr; + (void)memset((void *)pCtxtAttrs, 0, (size_t) sizeof(ContextAttrs)); + + for(pPrAttr = attrList; pPrAttr != (PrAttrPtr)NULL; pPrAttr = pPrAttr->next) + if(!strcmp(pPrAttr->name, pContext->printerName)) break; + + if(pPrAttr != (PrAttrPtr)NULL) + { + pCtxtAttrs->printerAttrs = CopyDb(pPrAttr->printerAttrs); + pCtxtAttrs->docAttrs = CopyDb(pPrAttr->docAttrs); + pCtxtAttrs->jobAttrs = CopyDb(pPrAttr->jobAttrs); + } +} + +void +XpDestroyAttributes( pContext ) + XpContextPtr pContext; +{ + ContextAttrPtr pCtxtAttrs; + + pCtxtAttrs = (ContextAttrPtr)pContext->devPrivates[attrCtxtPrivIndex].ptr; + + if(pCtxtAttrs->printerAttrs != (XrmDatabase)NULL) + XrmDestroyDatabase(pCtxtAttrs->printerAttrs); + if(pCtxtAttrs->docAttrs != (XrmDatabase)NULL) + XrmDestroyDatabase(pCtxtAttrs->docAttrs); + if(pCtxtAttrs->jobAttrs != (XrmDatabase)NULL) + XrmDestroyDatabase(pCtxtAttrs->jobAttrs); + if(pCtxtAttrs->pageAttrs != (XrmDatabase)NULL) + XrmDestroyDatabase(pCtxtAttrs->pageAttrs); +} + +/* + * XpGetOneAttribute returns the string value of the specified attribute + * in the specified class for the specified print context. If the attribute + * doesn't exist in the database for this context, or if the class database + * doesn't exist for this context, then NULL is returned. The caller must + * not free the returned string, as the returned pointer points into the + * database. This function can also return a value from the server attributes, + * in which case the pContext parameter is ignored. + */ +char * +XpGetOneAttribute( pContext, class, attributeName ) + XpContextPtr pContext; + XPAttributes class; + char *attributeName; +{ + ContextAttrPtr pCtxtAttrs; + XrmDatabase db = (XrmDatabase)NULL; + char *retVal; + XrmName xrm_name[3]; + XrmRepresentation rep_type; + XrmValue value; + + if(class == XPServerAttr) + { + if(systemAttributes.server == (XrmDatabase)NULL) + return NULL_STRING; + + xrm_name[0] = XrmStringToQuark (attributeName); + xrm_name[1] = (XrmQuark)NULL; + XrmQGetResource(systemAttributes.server, xrm_name, xrm_name, + &rep_type, &value); + + if(value.addr == (char *)NULL) + return NULL_STRING; + return (char *)value.addr; + } + else + { + pCtxtAttrs=(ContextAttrPtr)pContext->devPrivates[attrCtxtPrivIndex].ptr; + switch(class) + { + case XPPrinterAttr: + db = pCtxtAttrs->printerAttrs; + break; + case XPDocAttr: + db = pCtxtAttrs->docAttrs; + break; + case XPJobAttr: + db = pCtxtAttrs->jobAttrs; + break; + case XPPageAttr: + db = pCtxtAttrs->pageAttrs; + break; + default: + break; + } + } + if(db == (XrmDatabase)NULL) + return NULL_STRING; + + xrm_name[0] = XrmStringToQuark ("qualifier"); + xrm_name[1] = (XrmQuark)NULL; + XrmQGetResource(db, xrm_name, xrm_name, &rep_type, &value); + + xrm_name[0] = XrmStringToQuark (value.addr); + xrm_name[1] = XrmStringToQuark (attributeName); + xrm_name[2] = (XrmQuark)NULL; + if(XrmQGetResource(db, xrm_name, xrm_name, &rep_type, &value)) + return (char *)value.addr; + else + return NULL_STRING; +} + +/* + * XpPutOneAttribute updates one attribute for the specified + * context and class. This function is intended for use by the attribute + * validation module which updates the XrmDatabases directly. This + * function does not recognize XPServerAttr. + */ +void +XpPutOneAttribute( pContext, class, attributeName, value ) + +XpContextPtr pContext; +XPAttributes class; +const char* attributeName; +const char* value; +{ + ContextAttrPtr pCtxtAttrs; + XrmDatabase db; + XrmBinding bindings[1]; + XrmQuark quarks[2]; + + pCtxtAttrs = (ContextAttrPtr)pContext->devPrivates[attrCtxtPrivIndex].ptr; + switch(class) + { + case XPPrinterAttr: + db = pCtxtAttrs->printerAttrs; + break; + case XPDocAttr: + db = pCtxtAttrs->docAttrs; + break; + case XPJobAttr: + db = pCtxtAttrs->jobAttrs; + break; + case XPPageAttr: + db = pCtxtAttrs->pageAttrs; + break; + default: + return; + } + bindings[0] = XrmBindLoosely; + quarks[0] = XrmStringToQuark(attributeName); + quarks[1] = (XrmQuark)NULL; + XrmQPutStringResource(&db, bindings, quarks, value ? value : ""); +} + + + +/******************************************************************************* + * + * The following routines: ExpandSpace, PutString, PutByte, and AppendEntry + * form the functional core of the GetAttributes routine. Xrm does not + * supply a routine to form a string database from an XrmDatabase, except + * by writing the database to a file. This code avoids the file system + * overhead, but is a bit clunky in its memory management. + * + ******************************************************************************/ + +/* + * ExpandSpace expands the memory allocated for the string database in + * the StringDbStruct passed in, and updates the "space" field of the + * struct to indicate the new amount of space available. + */ +static Bool +ExpandSpace(pStr) + StringDbStruct *pStr; +{ + char *newSpace; + + if((newSpace = (char *)xrealloc(pStr->stringDb, pStr->nextPos + pStr->space + + 1024)) == (char *)NULL) + return False; + pStr->space += 1024; + pStr->stringDb = newSpace; + return True; +} + +/* + * PutString puts the contents of a null-terminated string into the string + * database in the StringDbStruct passed in. If there is insufficient room + * for the string, ExpandSpace is called, and the nextPos and space fields + * are updated. + */ +static void +PutString(pStr, pString) + StringDbStruct *pStr; + char *pString; +{ + int len = strlen(pString); + + if(len >= pStr->space) + if(!ExpandSpace(pStr)) + return; + strcpy(&pStr->stringDb[pStr->nextPos], pString); + pStr->nextPos += len; + pStr->space -= len; +} + +/* + * PutByte puts a single byte value in to the string database in the passed-in + * StringDbStruct. ExpandSpace is called if there is insufficient room for + * the byte, and the nextPos and space fields are updated. + */ +static void +PutByte(pStr, byte) + StringDbStruct *pStr; + char byte; +{ + if(pStr->space <= 1) + if(!ExpandSpace(pStr)) + return; + pStr->stringDb[pStr->nextPos] = byte; + pStr->nextPos++; + pStr->space--; +} + +/* + * AppendEntry is called by XrmEnumerateDatabase, and serves to append + * a database entry onto a string database. The passed-in "closure" + * struct contains a pointer to the string, and a count of the remaining + * bytes. If there are insufficient remaining bytes then the struct + * is realloced, and the count of the space remaining is updated. + * Database elements of types other than String are ignored! + * This code is based directly on that in "DumpEntry" in Xrm.c. + */ +static Bool +AppendEntry(db, bindings, quarks, type, value, data) + XrmDatabase *db; + XrmBindingList bindings; + XrmQuarkList quarks; + XrmRepresentation *type; + XrmValuePtr value; + XPointer data; +{ + StringDbStruct *pEnumStr = (StringDbStruct *)data; + Bool firstNameSeen; + unsigned int i; + char *s, c; + + if (*type != XrmQString) + return; + + for (firstNameSeen = False; *quarks; bindings++, quarks++) { + if (*bindings == XrmBindLoosely) { + PutString(pEnumStr, "*"); + } else if (firstNameSeen) { + PutString(pEnumStr, "."); + } + firstNameSeen = True; + PutString(pEnumStr, XrmQuarkToString(*quarks)); + } + s = value->addr; + i = value->size; + PutString(pEnumStr, ":\t"); + if(i) i--; + + if (i && (*s == ' ' || *s == '\t')) + PutByte(pEnumStr, '\\'); /* preserve leading whitespace */ + + while (i--) { + c = *s++; + if (c == '\n') { + if (i) + PutString(pEnumStr, "\\n\\\n"); + else + PutString(pEnumStr, "\\n"); + } else if (c == '\\') + PutString(pEnumStr, "\\\\"); + else if ((c < ' ' && c != '\t') || + ((unsigned char)c >= 0x7f && (unsigned char)c < 0xa0)) + { + char temp[4]; + (void) sprintf(temp, "\\%03o", (unsigned char)c); + PutString(pEnumStr, temp); + } + else + PutByte(pEnumStr, c); + } + PutByte(pEnumStr, '\n'); + pEnumStr->stringDb[pEnumStr->nextPos] = (char)'\0'; + return False; +} + +/* + * XpGetAttributes returns a string database version of the Xrm database + * for the specified context and class. This function can also return the + * contents of the server attributes, in which case the pContext parameter + * is ignored. + * + * The caller is responsible for freeing the returned string, + * unlike XpGetOneAttribute, where the caller must not free the string. + */ +char * +XpGetAttributes( pContext, class ) + XpContextPtr pContext; + XPAttributes class; +{ + ContextAttrPtr pCtxtAttrs; + XrmDatabase db = (XrmDatabase)NULL; + char *retVal; + StringDbStruct enumStruct; + XrmQuark empty = NULLQUARK; + + if(class == XPServerAttr) + db = systemAttributes.server; + else + { + pCtxtAttrs=(ContextAttrPtr)pContext->devPrivates[attrCtxtPrivIndex].ptr; + switch(class) + { + case XPServerAttr: + db = systemAttributes.server; + break; + case XPPrinterAttr: + db = pCtxtAttrs->printerAttrs; + break; + case XPDocAttr: + db = pCtxtAttrs->docAttrs; + break; + case XPJobAttr: + db = pCtxtAttrs->jobAttrs; + break; + case XPPageAttr: + db = pCtxtAttrs->pageAttrs; + break; + default: + break; + } + } + if(db == (XrmDatabase)NULL) + { + char *retval = (char *)xalloc(1); + retval[0] = (char)'\0'; + return retval; + } + + if((enumStruct.stringDb = (char *)xalloc(1024)) == (char *)NULL) + return (char *)NULL; + enumStruct.stringDb[0] = (char)'\0'; + enumStruct.nextPos = 0; + enumStruct.space = 1024; + (void)XrmEnumerateDatabase(db, &empty, &empty, XrmEnumAllLevels, + AppendEntry, (XPointer) &enumStruct); + + return enumStruct.stringDb; +} + +int +XpAugmentAttributes( pContext, class, attributes ) + XpContextPtr pContext; + XPAttributes class; + char *attributes; +{ + XrmDatabase db; + ContextAttrPtr pCtxtAttrs; + + db = XrmGetStringDatabase(attributes); + if(db == (XrmDatabase)NULL) return BadAlloc; + + pCtxtAttrs = (ContextAttrPtr)pContext->devPrivates[attrCtxtPrivIndex].ptr; + switch(class) + { + case XPPrinterAttr: + XrmMergeDatabases(db, &pCtxtAttrs->printerAttrs); + break; + case XPDocAttr: + XrmMergeDatabases(db, &pCtxtAttrs->docAttrs); + break; + case XPJobAttr: + XrmMergeDatabases(db, &pCtxtAttrs->jobAttrs); + break; + case XPPageAttr: + XrmMergeDatabases(db, &pCtxtAttrs->pageAttrs); + break; + default: + break; + } + return Success; +} + +/* + * XpSetAttributes - sets the attribute stores for a specified context. + */ +int +XpSetAttributes( pContext, class, attributes ) + XpContextPtr pContext; + XPAttributes class; + char *attributes; +{ + XrmDatabase db; + ContextAttrPtr pCtxtAttrs; + + db = XrmGetStringDatabase(attributes); + if(db == (XrmDatabase)NULL) return BadAlloc; + + pCtxtAttrs=(ContextAttrPtr)pContext->devPrivates[attrCtxtPrivIndex].ptr; + switch(class) + { + case XPPrinterAttr: + if(pCtxtAttrs->printerAttrs != (XrmDatabase)NULL) + XrmDestroyDatabase(pCtxtAttrs->printerAttrs); + pCtxtAttrs->printerAttrs = db; + break; + case XPDocAttr: + if(pCtxtAttrs->docAttrs != (XrmDatabase)NULL) + XrmDestroyDatabase(pCtxtAttrs->docAttrs); + pCtxtAttrs->docAttrs = db; + break; + case XPJobAttr: + if(pCtxtAttrs->jobAttrs != (XrmDatabase)NULL) + XrmDestroyDatabase(pCtxtAttrs->jobAttrs); + pCtxtAttrs->jobAttrs = db; + break; + case XPPageAttr: + if(pCtxtAttrs->pageAttrs != (XrmDatabase)NULL) + XrmDestroyDatabase(pCtxtAttrs->pageAttrs); + pCtxtAttrs->pageAttrs = db; + break; + default: + break; + } + return Success; +} + +void +XpAddPrinterAttribute(printerName, printerQualifier, attributeName, + attributeValue) + char *printerName; + char *printerQualifier; + char *attributeName; + char *attributeValue; +{ + PrAttrPtr pAttr; + + for(pAttr = attrList; pAttr != (PrAttrPtr)NULL; pAttr = pAttr->next) + { + if(!strcmp(printerQualifier, pAttr->qualifier)) + { + XrmPutStringResource(&pAttr->printerAttrs, attributeName, + attributeValue); + break; + } + } +} + +const char * +XpGetPrinterAttribute(const char *printerName, + const char *attribute) +{ + PrAttrPtr pAttr; + XrmValue value; + char *type; + + for(pAttr = attrList; pAttr != (PrAttrPtr)NULL; pAttr = pAttr->next) + { + if(!strcmp(printerName, pAttr->qualifier)) + { + char *attrStr; + + attrStr = (char *)xalloc(strlen(printerName) + strlen(attribute) + + 2); + sprintf(attrStr, "%s.%s", printerName, attribute); + XrmGetResource(pAttr->printerAttrs, attrStr, attrStr, + &type, &value); + xfree(attrStr); + break; + } + } + if(value.addr != (XPointer)NULL && strlen(value.addr) != 0) + return value.addr; + else + return ""; +} + +/******************************************************************************* + * + * The following routines are not attribute routines, but are rather + * spooler interface functions. They should presumably move to + * a SpoolerIf.c of some similarly named file. + * + ******************************************************************************/ +#include <locale.h> + +static char serverAttrStr[] = "*document-attributes-supported: copy-count\n\ +*job-attributes-supported: job-name job-owner\ + notification-profile xp-spooler-command-options\n\ +*multiple-documents-supported: False"; + +XrmDatabase +XpSpoolerGetServerAttributes() +{ + char *totalAttrs, *localeName; + XrmDatabase db; + + localeName = setlocale(LC_CTYPE, (char *)NULL); + if(!localeName || strlen(localeName) == 0) + localeName = "C"; + + if((totalAttrs = (char *)xalloc(strlen(serverAttrStr) + strlen(localeName) + + 11)) == (char *)NULL) + return (XrmDatabase)NULL; + sprintf(totalAttrs, "%s\n%s\t%s", serverAttrStr, "*locale:", localeName); + + db = XrmGetStringDatabase(totalAttrs); + xfree(totalAttrs); + return db; +} + +/* + * ExecuteCommand takes two pointers - the command to execute, + * and the "argv" style NULL-terminated vector of arguments for the command. + * We wait for the command to terminate before continuing to ensure that + * we don't delete the job file before the spooler has made a copy. + */ +static void +ExecCommand(pCommand, argVector) + char *pCommand; + char **argVector; +{ + pid_t childPid; + int status; + + if((childPid = fork()) == 0) + { + /* return BadAlloc? */ + if (execv(pCommand, argVector) == -1) { + FatalError("unable to exec '%s'", pCommand); + } + } + else + { + (void) waitpid(childPid, &status, 0); + } + return; +} + +/* + * SendFileToCommand takes three character pointers - the file name, + * the command to execute, + * and the "argv" style NULL-terminated vector of arguments for the command. + * The command is exec'd, and the file contents are sent to the command + * via stdin. + * + * WARNING: This function will try to adopt the userId of the supplied + * user name prior to exec'ing the supplied command. + */ +static void +SendFileToCommand( + char *fileName, + char *pCommand, + char **argVector, + char *userName) +{ + pid_t childPid; + int pipefd[2]; + int status; + struct stat statBuf; + FILE *fp, *outPipe; + + if(pipe(pipefd)) + return; + + if(stat(fileName, &statBuf) < 0 || (int)statBuf.st_size == 0) + { + close(pipefd[0]); + close(pipefd[1]); + return; + } + + fp = fopen(fileName, "r"); + if(fp == (FILE *)NULL) + { + close(pipefd[0]); + close(pipefd[1]); + return; + } + + if((childPid = fork()) == 0) + { + close(pipefd[1]); + close(0); + dup(pipefd[0]); + close(pipefd[0]); + + /* + * If a user name is specified, try to set our uid to match that + * user name. This is to allow e.g. a banner page to show the + * name of the printing user rather than the user who started + * the print server. + */ + if(userName) + { + uid_t myUid; + + if((myUid = geteuid()) == (uid_t)0) + { + struct passwd *pPasswd; + + if((pPasswd = getpwnam(userName))) + { + setuid((uid_t)pPasswd->pw_uid); + } + } + } + /* return BadAlloc? */ + if (execv(pCommand, argVector) == -1) { + FatalError("unable to exec '%s'", pCommand); + } + } + else + { + int res; + + (void) close(pipefd[0]); + + outPipe = fdopen(pipefd[1], "w"); + (void) TransferBytes(fp, outPipe, (int)statBuf.st_size); + + (void) fclose(outPipe); + (void) fclose(fp); + + (void) waitpid(childPid, &status, 0); + } + return; +} + +/* + * ReplaceAllKeywords causes all the predefined keywords (e.g. %options%) + * to be replaced with the appropriate values derived from the attribute + * store for the supplied print context. The ReplaceAnyString utility + * routine is used to perform the actual replacements. + */ +extern char *ReplaceAnyString(char *, char *, char *); + +static char * +ReplaceAllKeywords( + XpContextPtr pContext, + char *command) +{ + char *cmdOpt; + + cmdOpt = XpGetOneAttribute(pContext, XPPrinterAttr, + "xp-spooler-printer-name"); + if(cmdOpt != (char *)NULL && strlen(cmdOpt) != 0) + command = ReplaceAnyString(command, "%printer-name%", cmdOpt); + else + command = ReplaceAnyString(command, "%printer-name%", + pContext->printerName); + + cmdOpt = XpGetOneAttribute(pContext, XPDocAttr, "copy-count"); + if(cmdOpt != (char *)NULL && strlen(cmdOpt) != 0) + command = ReplaceAnyString(command, "%copy-count%", cmdOpt); + else + command = ReplaceAnyString(command, "%copy-count%", "1"); + + cmdOpt = XpGetOneAttribute(pContext, XPJobAttr, "job-name"); + if(cmdOpt != (char *)NULL && strlen(cmdOpt) != 0) + command = ReplaceAnyString(command, "%job-name%", cmdOpt); + else + command = ReplaceAnyString(command, "%job-name%", ""); + + cmdOpt = XpGetOneAttribute(pContext, XPJobAttr, "job-owner"); + if(cmdOpt != (char *)NULL && strlen(cmdOpt) != 0) + command = ReplaceAnyString(command, "%job-owner%", cmdOpt); + else + command = ReplaceAnyString(command, "%job-owner%", ""); + + cmdOpt = XpGetOneAttribute(pContext, XPJobAttr, + "xp-spooler-command-options"); + if(cmdOpt != (char *)NULL && strlen(cmdOpt) != 0) + command = ReplaceAnyString(command, "%options%", cmdOpt); + else + command = ReplaceAnyString(command, "%options%", ""); + + return command; +} + +#if defined(CSRG_BASED) || defined(linux) || (defined(sun) && !defined(SVR4)) || (defined(SVR4) && !defined(sun) && !defined(USL)) +#define iswspace(c) (isascii(c) && isspace(toascii(c))) +#endif + +/* + * GetToken - takes in a string and returns a malloc'd copy of the + * first non-white-space sequence of characters in the string. + * It returns the number of _bytes_ (NOT characters) parsed through + * the inStr to get to the end of the returned token. + */ +static int +GetToken( + char *inStr, + char **outStr) +{ + size_t mbCurMax = MB_CUR_MAX; + wchar_t curChar; + int i, numBytes, byteLen = strlen(inStr); + char *tok; + + /* + * read through any leading white space. + */ + for(i = 0, numBytes = 0; i < byteLen; i += numBytes) + { + numBytes = mbtowc(&curChar, &inStr[i], mbCurMax); + if(!iswspace(curChar)) + break; + } + tok = inStr + i; + + /* + * find the end of the token. + */ + byteLen = strlen(tok); + for(i = 0, numBytes = 0; i < byteLen; i += numBytes) + { + numBytes = mbtowc(&curChar, &tok[i], mbCurMax); + if(iswspace(curChar)) + break; + } + + if((*outStr = (char *)xalloc(i + 1)) == (char *)NULL) + return 0; + strncpy(*outStr, tok, i); + (*outStr)[i] = (char)'\0'; + return (tok + i) - inStr; +} + +static void +FreeVector( + char **vector) +{ + int i; + + if(vector == (char **)NULL) return; + + for(i = 0; vector[i] != (char *)NULL; i++) + xfree(vector[i]); + xfree(vector); +} + + +/* + * AddVector appends the pAddition arg vector to the pTarget arg vector. + * If the pTarget cannot be realloc'd, then pTarget is set to NULL. + */ +static void +AddVector( + char ***pTarget, + char **pAddition) +{ + int numTarget, numAdd, i; + + for(numTarget = 0; (*pTarget)[numTarget] != (char *)NULL; numTarget++) + ; + for(numAdd = 0; pAddition[numAdd] != (char *)NULL; numAdd++) + ; + + *pTarget = (char **)xrealloc((void *)*pTarget, (numTarget + numAdd + 1) * + sizeof(char *)); + if(*pTarget == (char **)NULL) + return; + for(i = 0; i < numAdd; i++) + (*pTarget)[numTarget + i] = pAddition[i]; + + (*pTarget)[numTarget + numAdd] = (char *)NULL; +} + +static char ** +BuildArgVector( + char *argString, + XpContextPtr pContext) +{ + char **pVector; + char *curTok; + int numChars, i; + static int beenHere = 0; /* prevent recursion on embedded %options% + */ + + pVector = (char **)xalloc(sizeof(char *)); + pVector[0] = (char *)NULL; + for(i = 0; (numChars = GetToken(argString, &curTok)) != 0; + i++, argString += numChars) + { + if(beenHere || strcmp(curTok, "%options%")) + { + if(curTok[0] == (char)'\0') + { + xfree(curTok); + } + else + { + pVector = (char **)xrealloc((void *)pVector, + (i + 2)*sizeof(char *)); + if(pVector == (char **)NULL) + return (char **)NULL; + pVector[i] = curTok; + pVector[i + 1] = (char *)NULL; + } + } + else if(!beenHere) + { + char **optionsVec; + + curTok = ReplaceAllKeywords(pContext, curTok); + beenHere = 1; + optionsVec = BuildArgVector(curTok, pContext); + xfree(curTok); + beenHere = 0; + AddVector(&pVector, optionsVec); + xfree(optionsVec); + } + } + if(numChars == 0 && curTok != (char *)NULL) + xfree(curTok); + return pVector; +} + +/* + * VectorizeCommand takes a string and breaks it into a command name and + * an array of character pointers suitable for handing to execv. The + * array is NULL-terminated. + * The returned char * is the command name, and should be freed when no + * longer needed. The array elements returned in the pVector parameter + * should be individually freed, and the array itself should also be + * freed when no longer needed. + */ +static char * +VectorizeCommand( + char *command, + char ***pVector, + XpContextPtr pContext) +{ + char *cmdName, *curTok; + int i, numChars; + + if(command == (char *)NULL) + return (char *)NULL; + + numChars = GetToken(command, &cmdName); + + if(cmdName == (char *)NULL) + return (char *)NULL; + + *pVector = BuildArgVector(command, pContext); + + return cmdName; +} + +#ifdef hpux +static char DEFAULT_SPOOL_COMMAND[] = "/usr/bin/lp -d %printer-name% -o raw -n %copy-count% -t %job-name% %options%"; +#else +static char DEFAULT_SPOOL_COMMAND[] = "/usr/bin/lp -d %printer-name% -n %copy-count% -t %job-name% %options%"; +#endif + +int +XpSubmitJob(fileName, pContext) + char *fileName; + XpContextPtr pContext; +{ + char **vector, *cmdNam, *cmdOpt, *command, *userName; + int i; + + command = XpGetOneAttribute(pContext, XPPrinterAttr, "xp-spooler-command"); + if(command == (char *)NULL || strlen(command) == 0) + command = strdup(DEFAULT_SPOOL_COMMAND); + else + command = strdup(command); + if(command == (char *)NULL) + return BadAlloc; + + cmdNam = VectorizeCommand(command, &vector, pContext); + xfree(command); + + if(cmdNam == (char *)NULL) + return BadAlloc; + + for(i = 0; vector[i] != (char *)NULL; i++) + { + vector[i] = ReplaceAllKeywords(pContext, vector[i]); + if(vector[i] == (char *)NULL) + { + xfree(cmdNam); + for(i = 0; vector[i] != (char *)NULL; i++) + xfree(vector[i]); + xfree(vector); + return BadAlloc; + } + } + + userName = XpGetOneAttribute(pContext, XPJobAttr, "job-owner"); + if(userName != (char *)NULL && strlen(userName) == 0) + userName = (char *)NULL; + + SendFileToCommand(fileName, cmdNam, vector, userName); + + FreeVector(vector); + xfree(cmdNam); +} + +/* + * SearchInputTrays() + * + * Given a tray, return the medium in the tray. Conversely, given a + * medium, return a tray in which it can be found. In either case, + * return NULL if the given tray or medium cannot be found. + */ +#define TRAY 0 +#define MEDIUM 1 + +static char * +SearchInputTrays(XpContextPtr pCon, + int which, + char *val) +{ + char *inputTraysMedium, tray[80], medium[80], *copy; + char *pS, *pE, *pLast; + + inputTraysMedium = XpGetOneAttribute( pCon, XPPrinterAttr, + "input-trays-medium" ); + + copy = strdup( inputTraysMedium ); + pS = copy; + pLast = copy + strlen( copy ); + + while( pS < pLast ) + { + while( *pS && *pS != '{' ) + pS++; + + pE = ++pS; + while( *pE && *pE != '}' ) + pE++; + *pE = '\0'; + + sscanf( pS, "%s %s", tray, medium ); + + if( which == MEDIUM && !strcmp( val, medium ) ) + { + xfree( copy ); + return strdup( tray ); + } + + if( which == TRAY && !strcmp( val, tray ) ) + { + xfree( copy ); + return strdup( medium ); + } + + pS = pE + 1; + } + + xfree( copy ); + return strdup( NULL_STRING ); +} + +/* + * XpGetTrayMediumFromContext() + * + * Given a print context, hit the input-trays-medium, + * default-input-tray and default-medium attributes to find the + * appropriate tray to use, and the medium in that tray. + */ +void +XpGetTrayMediumFromContext(XpContextPtr pCon, + char **medium, + char **tray) +{ + char *defMedium, *defTray; + char *t, *m; + char *pS, *pE, *pLast; + + defMedium = XpGetOneAttribute( pCon, XPPageAttr, + "default-medium" ); + if( *defMedium == '\0' ) + defMedium = XpGetOneAttribute( pCon, XPDocAttr, + "default-medium" ); + + defTray = XpGetOneAttribute( pCon, XPPageAttr, + "default-input-tray" ); + if( *defTray == '\0' ) + defTray = XpGetOneAttribute( pCon, XPDocAttr, + "default-input-tray" ); + + /* + * First, check to see if the default tray has the default medium + * installed. This is the ideal case. + */ + m = SearchInputTrays( pCon, TRAY, defTray ); + if( !strcmp( m, defMedium ) ) + { + xfree( m ); + *tray = strdup( defTray ); + *medium = strdup( defMedium ); + return; + } + + /* + * If the default tray doesn't have the default medium, search for + * a tray which has the default medium. + */ + t = SearchInputTrays( pCon, MEDIUM, defMedium ); + if( t ) + { + *tray = t; + *medium = strdup( defMedium ); + return; + } + + /* + * If all else fails, just return the default tray, and whatever + * medium happens to be there. Note that we simply return + * whatever is in the attribute store. Any further correction is + * left up to the DDX driver. + */ + *tray = strdup( defTray ); + *medium = m; + xfree( t ); +} diff --git a/Xprint/attributes.h b/Xprint/attributes.h new file mode 100644 index 000000000..59ccb9c63 --- /dev/null +++ b/Xprint/attributes.h @@ -0,0 +1,78 @@ +/* $Xorg: attributes.h,v 1.4 2001/03/14 18:42:44 pookie Exp $ */ +/* +(c) Copyright 1996 Hewlett-Packard Company +(c) Copyright 1996 International Business Machines Corp. +(c) Copyright 1996 Sun Microsystems, Inc. +(c) Copyright 1996 Novell, Inc. +(c) Copyright 1996 Digital Equipment Corp. +(c) Copyright 1996 Fujitsu Limited +(c) Copyright 1996 Hitachi, Ltd. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the names of the copyright holders shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from said +copyright holders. +*/ + +#include "Oid.h" + +/* + * attributes.c + */ +void XpInitAttributes(XpContextPtr pContext); +char *XpGetOneAttribute(XpContextPtr pContext, + XPAttributes class, + char *attributeName); +void XpPutOneAttribute(XpContextPtr pContext, + XPAttributes class, + const char* attributeName, + const char* value); +char *XpGetAttributes(XpContextPtr pContext, + XPAttributes class); +int XpAugmentAttributes(XpContextPtr pContext, + XPAttributes class, + char *attributes); +int XpSetAttributes(XpContextPtr pContext, + XPAttributes class, + char *attributes); +const char *XpGetPrinterAttribute(const char *printerName, + const char *attribute); +void XpGetTrayMediumFromContext(XpContextPtr pCon, + char **medium, + char **tray); + +/* + * mediaSizes.c + */ +int XpGetResolution(XpContextPtr pContext); +XpOid XpGetContentOrientation(XpContextPtr pContext); +XpOid XpGetAvailableCompression(XpContextPtr pContext); +XpOid XpGetPlex(XpContextPtr pContext); +XpOid XpGetPageSize(XpContextPtr pContext, + XpOid* pTray, + const XpOidMediumSS* msss); +void XpGetMediumMillimeters(XpOid page_size, + float *width, + float *height); +void XpGetMediumDimensions(XpContextPtr pContext, + unsigned short *width, + unsigned short *height); +void XpGetReproductionArea(XpContextPtr pContext, + xRectangle *pRect); diff --git a/Xprint/ddxInit.c b/Xprint/ddxInit.c new file mode 100644 index 000000000..3f8cefbe8 --- /dev/null +++ b/Xprint/ddxInit.c @@ -0,0 +1,364 @@ +/* $Xorg: ddxInit.c,v 1.3 2000/08/17 19:48:07 cpqbld Exp $ */ +/* +(c) Copyright 1996 Hewlett-Packard Company +(c) Copyright 1996 International Business Machines Corp. +(c) Copyright 1996 Sun Microsystems, Inc. +(c) Copyright 1996 Novell, Inc. +(c) Copyright 1996 Digital Equipment Corp. +(c) Copyright 1996 Fujitsu Limited +(c) Copyright 1996 Hitachi, Ltd. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the names of the copyright holders shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from said +copyright holders. +*/ + +#include "X.h" +#include "Xproto.h" +#include "screenint.h" +#include "input.h" +#include "misc.h" +#include "scrnintstr.h" +#include "windowstr.h" +#include "servermd.h" +#include "Xos.h" + +static void Exit(); +void _XpVoidNoop(); + +/*- + *----------------------------------------------------------------------- + * InitOutput -- + * If this is built as a print-only server, then we must supply + * an InitOutput routine. If a normal server's real ddx InitOutput + * is used, then it should call PrinterInitOutput if it so desires. + * The ddx-level hook is needed to allow the printer stuff to + * create additional screens. An extension can't reliably do + * this for two reasons: + * + * 1) If InitOutput doesn't create any screens, then main() + * exits before calling InitExtensions(). + * + * 2) Other extensions may rely on knowing about all screens + * when they initialize, and we can't guarantee the order + * of extension initialization. + * + * Results: + * ScreenInfo filled in, and PrinterInitOutput is called to create + * the screens associated with printers. + * + * Side Effects: + * None + * + *----------------------------------------------------------------------- + */ + +void +InitOutput(pScreenInfo, argc, argv) + ScreenInfo *pScreenInfo; + int argc; + char **argv; +{ + int i; + + pScreenInfo->imageByteOrder = IMAGE_BYTE_ORDER; + pScreenInfo->bitmapScanlineUnit = BITMAP_SCANLINE_UNIT; + pScreenInfo->bitmapScanlinePad = BITMAP_SCANLINE_PAD; + pScreenInfo->bitmapBitOrder = BITMAP_BIT_ORDER; + + pScreenInfo->numPixmapFormats = 0; /* get them in PrinterInitOutput */ + screenInfo.numVideoScreens = 0; +#ifdef PRINT_ONLY_SERVER + PrinterInitOutput(pScreenInfo, argc, argv); +#endif +} + +static void +BellProc(volume, pDev) + int volume; + DeviceIntPtr pDev; +{ + return; +} + +static void +KeyControlProc(pDev, ctrl) + DeviceIntPtr pDev; + KeybdCtrl *ctrl; +{ + return; +} + +static KeySym printKeyMap[256]; +static CARD8 printModMap[256]; + +static int +KeyboardProc(pKbd, what, argc, argv) + DevicePtr pKbd; + int what; + int argc; + char *argv[]; +{ + KeySymsRec keySyms; + + keySyms.minKeyCode = 8; + keySyms.maxKeyCode = 8; + keySyms.mapWidth = 1; + keySyms.map = printKeyMap; + + switch(what) + { + case DEVICE_INIT: + InitKeyboardDeviceStruct(pKbd, &keySyms, printModMap, + (BellProcPtr)BellProc, + KeyControlProc); + break; + case DEVICE_ON: + break; + case DEVICE_OFF: + break; + case DEVICE_CLOSE: + break; + } + return Success; +} + +#include "../mi/mipointer.h" +static int +PointerProc(pPtr, what, argc, argv) + DevicePtr pPtr; + int what; + int argc; + char *argv[]; +{ +#define NUM_BUTTONS 1 + CARD8 map[NUM_BUTTONS]; + + switch(what) + { + case DEVICE_INIT: + { + map[0] = 0; + InitPointerDeviceStruct(pPtr, map, NUM_BUTTONS, + miPointerGetMotionEvents, + (PtrCtrlProcPtr)_XpVoidNoop, + miPointerGetMotionBufferSize()); + break; + } + case DEVICE_ON: + break; + case DEVICE_OFF: + break; + case DEVICE_CLOSE: + break; + } + return Success; +} + +void +InitInput(argc, argv) + int argc; + char **argv; +{ + DevicePtr ptr, kbd; + + ptr = AddInputDevice((DeviceProc)PointerProc, TRUE); + kbd = AddInputDevice((DeviceProc)KeyboardProc, TRUE); + RegisterPointerDevice(ptr); + RegisterKeyboardDevice(kbd); + return; +} + + +Bool +LegalModifier(key, dev) + unsigned int key; + DevicePtr dev; +{ + return TRUE; +} + +void +ProcessInputEvents() +{ +} + +#ifdef DDXOSINIT +void +OsVendorInit() +{ +} +#endif + +#ifdef DDXTIME +CARD32 +GetTimeInMillis() +{ + struct timeval tp; + + X_GETTIMEOFDAY(&tp); + return(tp.tv_sec * 1000) + (tp.tv_usec / 1000); +} +#endif + +/**************************************** +* ddxUseMsg() +* +* Called my usemsg from os/utils/c +* +*****************************************/ + +void ddxUseMsg() +{ + /* Right now, let's just do nothing */ +} + +static void Exit (code) + int code; +{ + exit (code); +} + +void AbortDDX () +{ +} + +void ddxGiveUp() /* Called by GiveUp() */ +{ +} + +int +ddxProcessArgument (argc, argv, i) + int argc; + char *argv[]; + int i; + +{ +#ifdef PRINT_ONLY_SERVER + return XprintOptions(argc, argv, i) - i; +#else + return(0); +#endif +} + +#ifdef XINPUT + +#include "XI.h" +#include "XIproto.h" + +extern int BadDevice; + +ChangePointerDevice (old_dev, new_dev, x, y) + DeviceIntPtr old_dev; + DeviceIntPtr new_dev; + unsigned char x,y; +{ + return (BadDevice); +} + +int +ChangeDeviceControl (client, dev, control) + register ClientPtr client; + DeviceIntPtr dev; + xDeviceCtl *control; +{ + return BadMatch; +} + +OpenInputDevice (dev, client, status) + DeviceIntPtr dev; + ClientPtr client; + int *status; +{ + return; +} + +AddOtherInputDevices () +{ + return; +} + +CloseInputDevice (dev, client) + DeviceIntPtr dev; + ClientPtr client; +{ + return; +} + +ChangeKeyboardDevice (old_dev, new_dev) + DeviceIntPtr old_dev; + DeviceIntPtr new_dev; +{ + return (Success); +} + +SetDeviceMode (client, dev, mode) + register ClientPtr client; + DeviceIntPtr dev; + int mode; +{ + return BadMatch; +} + +SetDeviceValuators (client, dev, valuators, first_valuator, num_valuators) + register ClientPtr client; + DeviceIntPtr dev; + int *valuators; + int first_valuator; + int num_valuators; +{ + return BadMatch; +} + + +#endif /* XINPUT */ + +#ifdef XTESTEXT1 + +void +XTestJumpPointer(x, y, dev) + int x, y, dev; +{ + return; +} + +void +XTestGetPointerPos(x, y) +{ + return; +} + +void +XTestGenerateEvent(dev, keycode, keystate, x, y) + int dev, keycode, keystate, x, y; +{ + return; +} + +#endif /* XTESTEXT1 */ + +#ifdef AIXV3 +/* + * This is just to get the server to link on AIX, where some bits + * that should be in os/ are instead in hw/ibm. + */ +int SelectWaitTime = 10000; /* usec */ +#endif diff --git a/Xprint/mediaSizes.c b/Xprint/mediaSizes.c new file mode 100644 index 000000000..eaff20a88 --- /dev/null +++ b/Xprint/mediaSizes.c @@ -0,0 +1,777 @@ +/* $Xorg: mediaSizes.c,v 1.4 2001/03/14 18:44:37 pookie Exp $ */ +/* +(c) Copyright 1996 Hewlett-Packard Company +(c) Copyright 1996 International Business Machines Corp. +(c) Copyright 1996 Sun Microsystems, Inc. +(c) Copyright 1996 Novell, Inc. +(c) Copyright 1996 Digital Equipment Corp. +(c) Copyright 1996 Fujitsu Limited +(c) Copyright 1996 Hitachi, Ltd. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the names of the copyright holders shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from said +copyright holders. +*/ +/******************************************************************* +** +** ********************************************************* +** * +** * File: mediaSizes.c +** * +** * Contents: +** * Routines to return the sizes associated +** * with particular media and particular printers. +** * +** * Created: 2/19/96 +** * +** * Copyright: Copyright 1993,1995 Hewlett-Packard Company +** * +** ********************************************************* +** +********************************************************************/ + +#include <unistd.h> +#include <stdlib.h> +#include <stdio.h> +#include <ctype.h> +#include <string.h> +#include <locale.h> + +#include "X.h" +#include "dixstruct.h" +#include "screenint.h" +#include "misc.h" +#include "scrnintstr.h" +#include "fontstruct.h" + +#define _XP_PRINT_SERVER_ +#include "Printstr.h" +#undef _XP_PRINT_SERVER_ + +#include "DiPrint.h" +#include "AttrValid.h" + +extern XpContextPtr XpContextOfClient(); + +typedef struct { + XpOid page_size; + float width; + float height; +} PageDimensionsRec; + +static PageDimensionsRec PageDimensions[] = +{ + {xpoid_val_medium_size_na_letter, 215.9, 279.4}, + {xpoid_val_medium_size_na_legal, 215.9, 355.6}, + {xpoid_val_medium_size_executive, 184.15, 266.7}, + {xpoid_val_medium_size_folio, 210.82, 330.2}, + {xpoid_val_medium_size_invoice, 139.7, 215.9}, + {xpoid_val_medium_size_ledger, 279.4, 431.8}, + {xpoid_val_medium_size_quarto, 215.9, 275.082}, + {xpoid_val_medium_size_a, 215.9, 279.4}, + {xpoid_val_medium_size_b, 279.4, 431.8}, + {xpoid_val_medium_size_c, 431.8, 558.8}, + {xpoid_val_medium_size_d, 558.8, 863.6}, + {xpoid_val_medium_size_e, 863.6, 1117.6}, + {xpoid_val_medium_size_na_6x9_envelope, 152.4, 228.6}, + {xpoid_val_medium_size_na_10x15_envelope, 254, 381}, + {xpoid_val_medium_size_monarch_envelope, 98.298, 190.5}, + {xpoid_val_medium_size_na_10x13_envelope, 254, 330.2}, + {xpoid_val_medium_size_na_9x12_envelope, 228.6, 304.8}, + {xpoid_val_medium_size_na_number_10_envelope, 104.775, 241.3}, + {xpoid_val_medium_size_na_7x9_envelope, 177.8, 228.6}, + {xpoid_val_medium_size_na_9x11_envelope, 228.6, 279.4}, + {xpoid_val_medium_size_na_10x14_envelope, 254, 355.6}, + {xpoid_val_medium_size_na_number_9_envelope, 98.425, 225.425}, + {xpoid_val_medium_size_iso_a0, 841, 1189}, + {xpoid_val_medium_size_iso_a1, 594, 841}, + {xpoid_val_medium_size_iso_a2, 420, 594}, + {xpoid_val_medium_size_iso_a3, 297, 420}, + {xpoid_val_medium_size_iso_a4, 210, 297}, + {xpoid_val_medium_size_iso_a5, 148, 210}, + {xpoid_val_medium_size_iso_a6, 105, 148}, + {xpoid_val_medium_size_iso_a7, 74, 105}, + {xpoid_val_medium_size_iso_a8, 52, 74}, + {xpoid_val_medium_size_iso_a9, 37, 52}, + {xpoid_val_medium_size_iso_a10, 26, 37}, + {xpoid_val_medium_size_iso_b0, 1000, 1414}, + {xpoid_val_medium_size_iso_b1, 707, 1000}, + {xpoid_val_medium_size_iso_b2, 500, 707}, + {xpoid_val_medium_size_iso_b3, 353, 500}, + {xpoid_val_medium_size_iso_b4, 250, 353}, + {xpoid_val_medium_size_iso_b5, 176, 250}, + {xpoid_val_medium_size_iso_b6, 125, 176}, + {xpoid_val_medium_size_iso_b7, 88, 125}, + {xpoid_val_medium_size_iso_b8, 62, 88}, + {xpoid_val_medium_size_iso_b9, 44, 62}, + {xpoid_val_medium_size_iso_b10, 31, 44}, + {xpoid_val_medium_size_jis_b0, 1030, 1456}, + {xpoid_val_medium_size_jis_b1, 728, 1030}, + {xpoid_val_medium_size_jis_b2, 515, 728}, + {xpoid_val_medium_size_jis_b3, 364, 515}, + {xpoid_val_medium_size_jis_b4, 257, 364}, + {xpoid_val_medium_size_jis_b5, 182, 257}, + {xpoid_val_medium_size_jis_b6, 128, 182}, + {xpoid_val_medium_size_jis_b7, 91, 128}, + {xpoid_val_medium_size_jis_b8, 64, 91}, + {xpoid_val_medium_size_jis_b9, 45, 64}, + {xpoid_val_medium_size_jis_b10, 32, 45}, + {xpoid_val_medium_size_iso_c3, 324, 458}, + {xpoid_val_medium_size_iso_c4, 229, 324}, + {xpoid_val_medium_size_iso_c5, 162, 229}, + {xpoid_val_medium_size_iso_c6, 114, 162}, + {xpoid_val_medium_size_iso_designated_long, 110, 220} +}; + +/* + * XpGetResolution returns an integer representing the printer resolution + * in dots-per-inch for the specified print context. + * + * Note: This routine assumes the values found in the passed context's + * attributes pools have been validated. + */ +int +XpGetResolution( + XpContextPtr pContext) +{ + unsigned long resolution; + + resolution = XpGetCardAttr(pContext, XPPageAttr, + xpoid_att_default_printer_resolution, + (XpOidCardList*)NULL); + if(0 == resolution) + resolution = XpGetCardAttr(pContext, XPDocAttr, + xpoid_att_default_printer_resolution, + (XpOidCardList*)NULL); + if(0 == resolution) + { + XpOidCardList* resolutions_supported; + /* + * default-printer-resolution not specified; default to 1st entry + * in printer-resolutions-supported. + */ + resolutions_supported = + XpGetCardListAttr(pContext, XPPrinterAttr, + xpoid_att_printer_resolutions_supported, + (XpOidCardList*)NULL); + resolution = XpOidCardListGetCard(resolutions_supported, 0); + XpOidCardListDelete(resolutions_supported); + } + return (int)resolution; +} + +/* + * XpGetContentOrientation determines the content-orientation as + * determined by the passed context. The page and document pools are + * queried in turn for a specified content-orientation attribute. If none + * is found the first content-orientation in the + * content-orientations-supported printer attribute is taken as the + * default. + * + * Note: This routine assumes the values found in the passed context's + * attributes pools have been validated. + */ +XpOid +XpGetContentOrientation( + XpContextPtr pContext) +{ + XpOid orientation; + + orientation = XpGetOidAttr(pContext, XPPageAttr, + xpoid_att_content_orientation, + (XpOidList*)NULL); + if(xpoid_none == orientation) + orientation = XpGetOidAttr(pContext, XPDocAttr, + xpoid_att_content_orientation, + (XpOidList*)NULL); + if(xpoid_none == orientation) + { + XpOidList* content_orientations_supported; + + content_orientations_supported = + XpGetListAttr(pContext, XPPrinterAttr, + xpoid_att_content_orientations_supported, + (XpOidList*)NULL); + orientation = XpOidListGetOid(content_orientations_supported, 0); + XpOidListDelete(content_orientations_supported); + } + return orientation; +} + +/* + * XpGetAvailableCompression determines the available-compression as + * determined by the passed context. The page and document pools are + * queried in turn for a specified content-orientation attribute. If none + * is found the first available-compression in the + * avaiable-compressions-supported printer attribute is taken as the + * default. + * + * Note: This routine assumes the values found in the passed context's + * attributes pools have been validated. + */ +XpOid +XpGetAvailableCompression( + XpContextPtr pContext) +{ + XpOid compression; + + compression = XpGetOidAttr(pContext, XPPageAttr, + xpoid_att_available_compression, + (XpOidList*)NULL); + if(xpoid_none == compression) + compression = XpGetOidAttr(pContext, XPDocAttr, + xpoid_att_available_compression, + (XpOidList*)NULL); + if(xpoid_none == compression) + { + XpOidList* available_compressions_supported; + + available_compressions_supported = + XpGetListAttr(pContext, XPPrinterAttr, + xpoid_att_available_compressions_supported, + (XpOidList*)NULL); + compression = XpOidListGetOid(available_compressions_supported, 0); + XpOidListDelete(available_compressions_supported); + } + return compression; +} + +/* + * XpGetPlex determines the plex as determined by the passed context. The page + * and document pools are queried in turn for a specified plex attribute. If + * none is found the first plex in the plexes-supported printer attribute is + * taken as the default. + * + * Note: This routine assumes the values found in the passed context's + * attributes pools have been validated. + */ +XpOid +XpGetPlex( + XpContextPtr pContext) +{ + XpOid plex; + + plex = XpGetOidAttr(pContext, XPPageAttr, xpoid_att_plex, + (XpOidList*)NULL); + if(xpoid_none == plex) + plex = XpGetOidAttr(pContext, XPDocAttr, xpoid_att_plex, + (XpOidList*)NULL); + if(xpoid_none == plex) + { + XpOidList* plexes_supported; + + plexes_supported = + XpGetListAttr(pContext, XPPrinterAttr, + xpoid_att_plexes_supported, + (XpOidList*)NULL); + plex = XpOidListGetOid(plexes_supported, 0); + XpOidListDelete(plexes_supported); + } + return plex; +} + +/* + * XpGetPageSize returns the XpOid of the current page size (medium names + * are page sizes in this implementation) as indicated by the passed + * context. + * + * The relevant input-tray is returned in pTray. This parm must not be + * NULL. If the input-tray is not indicated or irrelevant, xpoid_none + * will be returned. + * + * This function optionally takes a XpOidMediumSS representation of the + * medium-source-sizes-supported attribute in order to avoid parsing the + * string value twice for calling functions that need to parse m-s-s-s + * anyway (e.g. XpGetReproductionArea). If the caller has no other reason + * to parse medium-source-sizes-supported, it is recommended that NULL be + * passed. This function will obtain medium-source-sizes-supported if it + * needs to. + * + * Note: This routine assumes the values found in the passed context's + * attributes pools have been validated. + */ +XpOid +XpGetPageSize(XpContextPtr pContext, + XpOid* pTray, + const XpOidMediumSS* msss) +{ + XpOid medium; + /* + * check to see if default-medium is specified + */ + medium = XpGetOidAttr(pContext, XPPageAttr, xpoid_att_default_medium, + (const XpOidList*)NULL); + if(medium == xpoid_none) + { + /* + * default-medium not in page pool; try the document pool + */ + medium = XpGetOidAttr(pContext, XPDocAttr, xpoid_att_default_medium, + (const XpOidList*)NULL); + } + if(medium == xpoid_none) + { + /* + * default-medium not specified; try default-input-tray + */ + *pTray = XpGetOidAttr(pContext, XPPageAttr, + xpoid_att_default_input_tray, + (const XpOidList*)NULL); + if(*pTray == xpoid_none) + { + /* + * default-input-tray not in page pool; try the document pool + */ + *pTray = XpGetOidAttr(pContext, XPDocAttr, + xpoid_att_default_input_tray, + (const XpOidList*)NULL); + } + if(*pTray != xpoid_none) + { + /* + * default-input-tray found; get corresponding medium from + * input-trays-medium + */ + XpOidTrayMediumList* input_trays_medium; + int i; + + input_trays_medium = + XpGetTrayMediumListAttr(pContext, XPPrinterAttr, + xpoid_att_input_trays_medium, + (const XpOidList*)NULL, + (const XpOidMediumSS*)NULL); + for(i = 0; i < XpOidTrayMediumListCount(input_trays_medium); i++) + { + if(*pTray == XpOidTrayMediumListTray(input_trays_medium, i)) + { + medium = XpOidTrayMediumListMedium(input_trays_medium, i); + break; + } + } + XpOidTrayMediumListDelete(input_trays_medium); + } + } + else + *pTray = xpoid_none; + + if(medium == xpoid_none) + { + XpOidMediumSS* local_msss = (XpOidMediumSS*)NULL; + int i_mss, i_ds; + XpOidMediumDiscreteSizeList* ds_list; + /* + * no medium specified; use 1st page size found in + * medium-source-sizes-supported + */ + if((XpOidMediumSS*)NULL == msss) + msss = local_msss = + XpGetMediumSSAttr(pContext, XPPrinterAttr, + xpoid_att_medium_source_sizes_supported, + (const XpOidList*)NULL, + (const XpOidList*)NULL); + for(i_mss = 0; + i_mss < XpOidMediumSSCount(msss) && xpoid_none == medium; + i_mss++) + { + if(XpOidMediumSS_DISCRETE == (msss->mss)[i_mss].mstag + && + xpoid_none != (msss->mss)[i_mss].input_tray) + { + ds_list = (msss->mss)[i_mss].ms.discrete; + for(i_ds = 0; i_ds < ds_list->count; i_ds++) + { + if(xpoid_none != (ds_list->list)[i_ds].page_size) + { + medium = (ds_list->list)[i_ds].page_size; + break; + } + } + } + } + XpOidMediumSSDelete(local_msss); + } + return medium; +} + +/* + * XpGetMediumMillimeters returns into the supplied float pointers the + * width and height in millimeters of the passed page size identifier. + */ +void +XpGetMediumMillimeters( + XpOid page_size, + float *width, /* return */ + float *height) /* return */ +{ + int i; + + *width = *height = 0; + for(i = 0; i < XpNumber(PageDimensions); i++) + { + if(page_size == PageDimensions[i].page_size) + { + *width = PageDimensions[i].width; + *height = PageDimensions[i].height; + return; + } + } +} + +/* + * Converts a millimeter specification into pixels given a resolution in + * DPI. + */ +static float +MmToPixels(float mm, int resolution) +{ + float f; + + f = mm * resolution; + f /= 25.4; + return f; +} + +/* + * XpGetMediumDimensions returns into the supplied short pointers the + * width and height in pixels of the medium associated with the specified + * print context. It obtains the page size associated with the current + * medium by calling XpGetPageSize. It passes XpGetMediumMillimeters the + * page size, and converts the returned millimeter dimensions into pixels + * using the resolution returned by XpGetResolution. + * + * Note: This routine assumes the values found in the passed context's + * attributes pools have been validated. + */ +void +XpGetMediumDimensions( + XpContextPtr pContext, + unsigned short *width, /* return */ + unsigned short *height) /* return */ +{ + XpOid page_size; + XpOid tray; + XpOid orientation; + + int resolution; + float w_mm, h_mm; + + page_size = XpGetPageSize(pContext, &tray, (XpOidMediumSS*)NULL); + if(page_size == xpoid_none) + { + /* + * fail-safe: if the pools have been validated, this defaulting logic + * isn't needed. + */ + page_size = xpoid_val_medium_size_na_letter; + } + XpGetMediumMillimeters(page_size, &w_mm, &h_mm); + resolution = XpGetResolution(pContext); + orientation = XpGetContentOrientation(pContext); + switch(orientation) + { + case xpoid_val_content_orientation_landscape: + case xpoid_val_content_orientation_reverse_landscape: + /* + * transpose width and height + */ + *height = MmToPixels(w_mm, resolution); + *width = MmToPixels(h_mm, resolution); + break; + + default: + *width = MmToPixels(w_mm, resolution); + *height = MmToPixels(h_mm, resolution); + break; + } +} + +/* + * XRectangleFromXpOidArea converts an XpOidArea area specification + * into an XRectangle. The passed resolution is used to convert from + * millimeters (XpOidArea) into pixels (XRectangle). + */ +static void +XRectangleFromXpOidArea( + xRectangle *pRect, + const XpOidArea* repro, + int resolution, + XpOid orientation) +{ + switch(orientation) + { + case xpoid_val_content_orientation_landscape: + case xpoid_val_content_orientation_reverse_landscape: + /* + * transpose x and y, width and height + */ + pRect->y = MmToPixels(repro->minimum_x, resolution); + pRect->x = MmToPixels(repro->minimum_y, resolution); + pRect->height = + MmToPixels(repro->maximum_x - repro->minimum_x, resolution); + pRect->width = + MmToPixels(repro->maximum_y - repro->minimum_y, resolution); + break; + + default: + pRect->x = MmToPixels(repro->minimum_x, resolution); + pRect->y = MmToPixels(repro->minimum_y, resolution); + pRect->width = + MmToPixels(repro->maximum_x - repro->minimum_x, resolution); + pRect->height = + MmToPixels(repro->maximum_y - repro->minimum_y, resolution); + break; + } +} + +/* + * XpGetReproductionArea queries the current pool attribute values in + * order to determine the reproduction area for the currently selected + * medium. + * + * First the current page size (equivalent to current medium) and tray + * (if specified) is retrieved via XpGetPageSize. The value of the + * medium-source-sizes-supported attribute is interrogated until a matching + * entry for the current page size and tray is found. The reproduction + * area defined for the current entry is converted into an XRectangle + * using XRectangleFromXpOidArea and returned to the caller. + * + * Note: This routine assumes the values found in the passed context's + * attributes pools have been validated. + */ +void +XpGetReproductionArea(XpContextPtr pContext, + xRectangle *pRect) +{ + XpOid page_size; + XpOid tray; + XpOidMediumSS* msss; + int i_mss, i_ds; + XpOidMediumDiscreteSizeList* ds_list; + XpOidArea* repro; + BOOL done; + int resolution; + XpOid orientation; + /* + * find the appropriate assured reproduction area for the current + * tray and page size in the medium-source-sizes-supported attribute. + */ + msss = XpGetMediumSSAttr(pContext, XPPrinterAttr, + xpoid_att_medium_source_sizes_supported, + (const XpOidList*)NULL, + (const XpOidList*)NULL); + page_size = XpGetPageSize(pContext, &tray, msss); + resolution = XpGetResolution(pContext); + orientation = XpGetContentOrientation(pContext); + + memset(pRect, 0, sizeof(xRectangle)); + + if(xpoid_none == tray) + { + /* + * no tray specified; use 1st matching page size + */ + for(i_mss = 0, done = xFalse; + i_mss < XpOidMediumSSCount(msss) && !done; + i_mss++) + { + if(XpOidMediumSS_DISCRETE == (msss->mss)[i_mss].mstag + && + xpoid_none != (msss->mss)[i_mss].input_tray) + { + ds_list = (msss->mss)[i_mss].ms.discrete; + for(i_ds = 0; i_ds < ds_list->count; i_ds++) + { + if(page_size == (ds_list->list)[i_ds].page_size) + { + repro = + &(ds_list->list)[i_ds].assured_reproduction_area; + XRectangleFromXpOidArea(pRect, repro, + resolution, orientation); + done = xTrue; + break; + } + } + } + } + } + else + { + /* + * tray && page size specified; find matching entry + */ + for(i_mss = 0, done = xFalse; + i_mss < XpOidMediumSSCount(msss) && !done; + i_mss++) + { + if(XpOidMediumSS_DISCRETE == (msss->mss)[i_mss].mstag + && + xpoid_none != (msss->mss)[i_mss].input_tray + && + (tray == (msss->mss)[i_mss].input_tray + || + xpoid_unspecified == (msss->mss)[i_mss].input_tray) + ) + { + ds_list = (msss->mss)[i_mss].ms.discrete; + for(i_ds = 0; i_ds < ds_list->count; i_ds++) + { + if(page_size == (ds_list->list)[i_ds].page_size) + { + repro = + &(ds_list->list)[i_ds].assured_reproduction_area; + XRectangleFromXpOidArea(pRect, repro, + resolution, orientation); + if(xpoid_unspecified != (msss->mss)[i_mss].input_tray) + { + /* + * exact match on tray takes precendence over + * unspecified tray entry in m-s-s-s + */ + done = xTrue; + } + break; + } + } + } + } + } + XpOidMediumSSDelete(msss); +} + +/* + * XpGetMaxWidthHeightRes returns into the supplied width and height + * unsigned short pointers the dimensions in millimeters of the largest + * supported media for a specific printer. It looks at the + * medium-source-sizes-supported attribute (if it exists) to determine + * the list of possible media, and calls XpGetMediumMillimeters to get the + * dimensions for each medium. If the m-s-s-s attribute is not defined, + * then the dimensions for the na-letter medium is returned. + * + * This function also returns the largest resolution in DPI defined in + * printer-resolutions-supported. If printer-resolutions-supported is not + * specified, the default is obtained from the passed XpValidatePoolsRec. + * + * The passed XpValidatePoolsRec is also used to determine valid values + * when parsing attribute values. + */ +void +XpGetMaxWidthHeightRes( + const char *printer_name, + const XpValidatePoolsRec* vpr, + float *width, + float *height, + int* resolution) +{ + const char* value; + const char* attr_str; + XpOidMediumSS* pool_msss; + const XpOidMediumSS* msss; + int i_mss, i_ds; + XpOidMediumDiscreteSizeList* ds_list; + float w, h; + XpOidCardList* pool_resolutions_supported; + const XpOidCardList* resolutions_supported; + int i; + int res; + /* + * get the max medium width and height + */ + attr_str = XpOidString(xpoid_att_medium_source_sizes_supported); + value = XpGetPrinterAttribute(printer_name, attr_str); + pool_msss = XpOidMediumSSNew(value, + vpr->valid_input_trays, + vpr->valid_medium_sizes); + if(0 == XpOidMediumSSCount(pool_msss)) + msss = XpGetDefaultMediumSS(); + else + msss = pool_msss; + *width = *height = 0; + for(i_mss = 0; i_mss < XpOidMediumSSCount(msss); i_mss++) + { + if(XpOidMediumSS_DISCRETE == (msss->mss)[i_mss].mstag + && + xpoid_none != (msss->mss)[i_mss].input_tray) + { + ds_list = (msss->mss)[i_mss].ms.discrete; + for(i_ds = 0; i_ds < ds_list->count; i_ds++) + { + if(xpoid_none != (ds_list->list)[i_ds].page_size) + { + XpGetMediumMillimeters((ds_list->list)[i_ds].page_size, + &w, &h); + if(w > *width) *width = w; + if(h > *height) *height = h; + } + } + } + } + XpOidMediumSSDelete(pool_msss); + /* + * get the maximum resolution + */ + attr_str = XpOidString(xpoid_att_printer_resolutions_supported); + value = XpGetPrinterAttribute(printer_name, attr_str); + pool_resolutions_supported = + XpOidCardListNew(value, vpr->valid_printer_resolutions_supported); + if(0 == XpOidCardListCount(pool_resolutions_supported)) + resolutions_supported = vpr->default_printer_resolutions_supported; + else + resolutions_supported = pool_resolutions_supported; + *resolution = 0; + for(i = 0; i < XpOidCardListCount(resolutions_supported); i++) + { + res = XpOidCardListGetCard(resolutions_supported, i); + if(res > *resolution) *resolution = res; + } + XpOidCardListDelete(pool_resolutions_supported); +} + +FontResolutionPtr +XpGetClientResolutions(client, num) + ClientPtr client; + int *num; +{ + static struct _FontResolution res; + int resolution = XpGetResolution(XpContextOfClient(client)); + + res.x_resolution = resolution; + res.y_resolution = resolution; + + res.point_size = 120; + + *num = 1; + + return &res; +} + + +void XpSetFontResFunc(client) + ClientPtr client; +{ + client->fontResFunc = XpGetClientResolutions; +} + + +void XpUnsetFontResFunc(client) + ClientPtr client; +{ + client->fontResFunc = NULL; +} diff --git a/Xprint/pcl/Pcl.h b/Xprint/pcl/Pcl.h new file mode 100644 index 000000000..0f744eafe --- /dev/null +++ b/Xprint/pcl/Pcl.h @@ -0,0 +1,580 @@ +/* $Xorg: Pcl.h,v 1.3 2000/08/17 19:48:07 cpqbld Exp $ */ +/******************************************************************* +** +** ********************************************************* +** * +** * File: Pcl.h +** * +** * Contents: defines and includes for the Pcl driver +** * for a printing X server. +** * +** * Created: 1/30/95 +** * +** ********************************************************* +** +********************************************************************/ +/* +(c) Copyright 1996 Hewlett-Packard Company +(c) Copyright 1996 International Business Machines Corp. +(c) Copyright 1996 Sun Microsystems, Inc. +(c) Copyright 1996 Novell, Inc. +(c) Copyright 1996 Digital Equipment Corp. +(c) Copyright 1996 Fujitsu Limited +(c) Copyright 1996 Hitachi, Ltd. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the names of the copyright holders shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from said +copyright holders. +*/ + +#ifndef _PCL_H_ +#define _PCL_H_ + +#include <stdio.h> +#include "scrnintstr.h" + +/* +#include "X.h" +#include "Xproto.h" +#include "Xatom.h" +#include "misc.h" +#include "screenint.h" +#include "colormapst.h" +#include "windowstr.h" +#include "propertyst.h" +#include "servermd.h" */ /* needed for IMAGE_BUFSIZE */ + +#include "PclDef.h" +#include "Pclmap.h" +#include "PclSFonts.h" + +#define _XP_PRINT_SERVER_ +#include "Print.h" +#include "extensions/Printstr.h" +#undef _XP_PRINT_SERVER_ + +#include "miscstruct.h" +#include "fontstruct.h" +#include "dixfontstr.h" +#include "gcstruct.h" + +/* + * Some sleazes to force the XrmDB stuff into the server + */ +typedef char *XPointer; +#define Status int +#define True 1 +#define False 0 +#include "misc.h" +#include <Xfuncproto.h> +#include "../Xresource.h" + +/****** + * externally visible variables from PclInit.c + ******/ +extern int PclScreenPrivateIndex, PclWindowPrivateIndex; +extern int PclContextPrivateIndex; +extern int PclPixmapPrivateIndex; +extern int PclGCPrivateIndex; + +/* + * This structure defines a mapping from an X colormap ID to a list of + * print contexts which use the colormap. + */ +typedef struct _pclcontextlist { + XpContextPtr context; + struct _pclcontextlist *next; +} PclContextList, *PclContextListPtr; + +typedef struct _pclcmaptocontexts { + long colormapId; + PclContextListPtr contexts; + struct _pclcmaptocontexts *next; +} PclCmapToContexts; + +typedef struct { + PclCmapToContexts *colormaps; + CloseScreenProcPtr CloseScreen; +} PclScreenPrivRec, *PclScreenPrivPtr; + +/* + * This structure defines a mapping from an X colormap ID to a PCL + * palette ID. + */ +typedef struct _palettemap { + long colormapId; + int paletteId; + int downloaded; + struct _palettemap *next; +} PclPaletteMap, *PclPaletteMapPtr; + +typedef struct { + char *jobFileName; + FILE *pJobFile; + char *pageFileName; + FILE *pPageFile; + GC lastGC; + unsigned char *dash; + int validGC; + ClientPtr getDocClient; + int getDocBufSize; + PclSoftFontInfoPtr pSoftFontInfo; + PclPaletteMapPtr palettes; + int currentPalette; + int nextPaletteId; + PclPaletteMap staticGrayPalette; + PclPaletteMap trueColorPalette; + PclPaletteMap specialTrueColorPalette; + unsigned char *ctbl; + int ctbldim; + int isRaw; +#ifdef XP_PCL_LJ3 + unsigned int fcount; + unsigned int fcount_max; + char *figures; +#endif /* XP_PCL_LJ3 */ +} PclContextPrivRec, *PclContextPrivPtr; + +typedef struct { + int validContext; + XpContextPtr context; +} PclWindowPrivRec, *PclWindowPrivPtr; + +typedef struct { + unsigned freeCompClip; + RegionPtr pCompositeClip; + unsigned long stippleFg, stippleBg; +} PclGCPrivRec, *PclGCPrivPtr; + +typedef struct { + XpContextPtr context; + char *tempFileName; + FILE *tempFile; + GC lastGC; + int validGC; +} PclPixmapPrivRec, *PclPixmapPrivPtr; + +/****** + * Defined functions + ******/ +#define SEND_PCL(f,c) fwrite( c, sizeof( char ), strlen( c ), f ) +#define SEND_PCL_COUNT(f,c,n) fwrite( c, sizeof( char ), n, f ) + +#ifndef XP_PCL_LJ3 +#define SAVE_PCL(f,p,c) SEND_PCL(f,c) +#define SAVE_PCL_COUNT(f,p,c,n) SEND_PCL_COUNT(f,c,n) +#define MACRO_START(f,p) SEND_PCL(f, "\033&f1Y\033&f0X") +#define MACRO_END(f) SEND_PCL(f, "\033&f1X") +#else +#define SAVE_PCL(f,p,c) PclSpoolFigs(p, c, strlen(c)) +#define SAVE_PCL_COUNT(f,p,c,n) PclSpoolFigs(p, c, n) +#define MACRO_START(f,p) p->fcount = 0 +#define MACRO_END(f) /* do nothing */ +#endif /* XP_PCL_LJ3 */ + +#define MIN(a,b) (((a)<(b))?(a):(b)) +#define MAX(a,b) (((a)>(b))?(a):(b)) + +/****** + * Functions in PclArc.c + ******/ +extern void PclPolyArc( + DrawablePtr pDrawable, + GCPtr pGC, + int nArcs, + xArc *pArcs); +extern void PclPolyFillArc( + DrawablePtr pDrawable, + GCPtr pGC, + int nArcs, + xArc *pArcs); + +/****** + * Functions in PclArea.c + ******/ +extern void PclPutImage( + DrawablePtr pDrawable, + GCPtr pGC, + int depth, + int x, + int y, + int w, + int h, + int leftPad, + int format, + char *pImage); +extern RegionPtr PclCopyArea( + DrawablePtr pSrc, + DrawablePtr pDst, + GCPtr pGC, + int srcx, + int srcy, + int width, + int height, + int dstx, + int dsty); +RegionPtr PclCopyPlane( + DrawablePtr pSrc, + DrawablePtr pDst, + GCPtr pGC, + int srcx, + int srcy, + int width, + int height, + int dstx, + int dsty, + unsigned long plane); + + +/****** + * Functions in PclAttr.c + ******/ +extern char *PclGetAttributes( + XpContextPtr pCon, + XPAttributes pool ); +extern char *PclGetOneAttribute( + XpContextPtr pCon, + XPAttributes pool, + char *attr ); +extern int PclAugmentAttributes( + XpContextPtr pCon, + XPAttributes pool, + char *attrs ); +extern int PclSetAttributes( + XpContextPtr pCon, + XPAttributes pool, + char *attrs ); + +/****** + * Functions in PclColor.c + ******/ +extern Bool PclCreateDefColormap(ScreenPtr pScreen); +extern Bool PclCreateColormap(ColormapPtr pColor); +extern void PclDestroyColormap(ColormapPtr pColor); +extern void PclInstallColormap(ColormapPtr pColor); +extern void PclUninstallColormap(ColormapPtr pColor); +extern int PclListInstalledColormaps(ScreenPtr pScreen, + XID *pCmapList); +extern void PclStoreColors(ColormapPtr pColor, + int ndef, + xColorItem *pdefs); +extern void PclResolveColor(unsigned short *pRed, + unsigned short *pGreen, + unsigned short *pBlue, + VisualPtr pVisual); +extern int PclUpdateColormap(DrawablePtr pDrawable, + XpContextPtr pCon, + GCPtr gc, + FILE *outFile); + +/****** + * Functions in PclCursor.c + ******/ +extern void PclConstrainCursor( + ScreenPtr pScreen, + BoxPtr pBox); +extern void PclCursorLimits( + ScreenPtr pScreen, + CursorPtr pCursor, + BoxPtr pHotBox, + BoxPtr pTopLeftbox); +extern Bool PclDisplayCursor( + ScreenPtr pScreen, + CursorPtr pCursor); +extern Bool PclRealizeCursor( + ScreenPtr pScreen, + CursorPtr pCursor); +extern Bool PclUnrealizeCursor( + ScreenPtr pScreen, + CursorPtr pCursor); +extern void PclRecolorCursor( + ScreenPtr pScreen, + CursorPtr pCursor, + Bool displayed); +extern Bool PclSetCursorPosition( + ScreenPtr pScreen, + int x, + int y, + Bool generateEvent); + +/****** + * Functions in PclGC.c + ******/ +extern Bool PclCreateGC(GCPtr pGC); +extern void PclDestroyGC(GCPtr pGC); +extern int PclUpdateDrawableGC( + GCPtr pGC, + DrawablePtr pDrawable, + FILE **outFile); +extern void PclValidateGC( + GCPtr pGC, + Mask changes, + DrawablePtr pDrawable); +extern void PclSetDrawablePrivateStuff( + DrawablePtr pDrawable, + GC gc ); +extern int PclGetDrawablePrivateStuff( + DrawablePtr pDrawable, + GC *gc, + unsigned long *valid, + FILE **file ); + +/****** + * Functions in PclInit.c + ******/ +extern Bool InitializePclDriver( + int ndx, + ScreenPtr pScreen, + int argc, + char **argv); +static Bool PclDestroyContext( XpContextPtr pCon ); +extern XpContextPtr PclGetContextFromWindow( WindowPtr win ); + +/****** + * Functions in PclLine.c + ******/ +extern void PclPolyLine( + DrawablePtr pDrawable, + GCPtr pGC, + int mode, + int nPoints, + xPoint *pPoints); +extern void PclPolySegment( + DrawablePtr pDrawable, + GCPtr pGC, + int nSegments, + xSegment *pSegments); + +/****** + * Functions in PclMisc.c + ******/ +extern void PclQueryBestSize( + int class, + short *pwidth, + short *pheight, + ScreenPtr pScreen); +extern char *GetPropString(WindowPtr pWin, char *propName); +extern int SystemCmd(char *cmdStr); +extern int PclGetMediumDimensions( + XpContextPtr pCon, + CARD16 *pWidth, + CARD16 *pHeight); +extern int PclGetReproducibleArea( + XpContextPtr pCon, + xRectangle *pRect); + +/****** + * Functions in PclPixel.c + ******/ +extern void PclPolyPoint( + DrawablePtr pDrawable, + GCPtr pGC, + int mode, + int nPoints, + xPoint *pPoints); +extern void PclPushPixels( + GCPtr pGC, + PixmapPtr pBitmap, + DrawablePtr pDrawable, + int width, + int height, + int x, + int y); + +/****** + * Functions in PclPixmap.c + ******/ +extern PixmapPtr PclCreatePixmap( + ScreenPtr pScreen, + int width, + int height, + int depth); +extern Bool PclDestroyPixmap(PixmapPtr pPixmap); + +/****** + * Functions in PclPolygon.c + ******/ +extern void PclPolyRectangle( + DrawablePtr pDrawable, + GCPtr pGC, + int nRects, + xRectangle *pRects); +extern void PclFillPolygon( + DrawablePtr pDrawable, + GCPtr pGC, + int shape, + int mode, + int nPoints, + DDXPointPtr pPoints); +extern void PclPolyFillRect( + DrawablePtr pDrawable, + GCPtr pGC, + int nRects, + xRectangle *pRects); + +/****** + * Functions in PclSpans.c + ******/ +extern void PclFillSpans( + DrawablePtr pDrawable, + GCPtr pGC, + int nSpans, + DDXPointPtr pPoints, + int *pWidths, + int fSorted); +extern void PclSetSpans( + DrawablePtr pDrawable, + GCPtr pGC, + char *pSrc, + DDXPointPtr pPoints, + int *pWidths, + int nSpans, + int fSorted); + +/****** + * Functions in PclText.c + ******/ +extern int PclPolyText8( + DrawablePtr pDrawable, + GCPtr pGC, + int x, + int y, + int count, + char *string); +extern int PclPolyText16( + DrawablePtr pDrawable, + GCPtr pGC, + int x, + int y, + int count, + unsigned short *string); +extern void PclImageText8( + DrawablePtr pDrawable, + GCPtr pGC, + int x, + int y, + int count, + char *string); +extern void PclImageText16( + DrawablePtr pDrawable, + GCPtr pGC, + int x, + int y, + int count, + unsigned short *string); +extern void PclImageGlyphBlt( + DrawablePtr pDrawable, + GCPtr pGC, + int x, + int y, + unsigned int nGlyphs, + CharInfoPtr *pCharInfo, + pointer pGlyphBase); +extern void PclPolyGlyphBlt( + DrawablePtr pDrawable, + GCPtr pGC, + int x, + int y, + unsigned int nGlyphs, + CharInfoPtr *pCharInfo, + pointer pGlyphBase); + +/****** + * Functions in PclWindow.c + ******/ +extern Bool PclCreateWindow(register WindowPtr pWin); +extern Bool PclDestroyWindow(WindowPtr pWin); +extern Bool PclMapWindow(WindowPtr pWindow); +extern Bool PclPositionWindow( + register WindowPtr pWin, + int x, + int y); +extern Bool PclUnmapWindow(WindowPtr pWindow); +extern Bool PclUnmapWindow(WindowPtr pWindow); +extern void PclCopyWindow( + WindowPtr pWin, + DDXPointRec ptOldOrg, + RegionPtr prgnSrc); +extern Bool PclChangeWindowAttributes( + register WindowPtr pWin, + register unsigned long mask); +extern void PclPaintWindow( + WindowPtr pWin, + RegionPtr pRegion, + int what); + +/****** + * Functions in PclFonts.c + ******/ +extern Bool PclRealizeFont( + ScreenPtr pscr, + FontPtr pFont); +extern Bool PclUnrealizeFont( + ScreenPtr pscr, + FontPtr pFont); + +/****** + * Functions in PclPrint.c + ******/ +extern int PclStartJob( + XpContextPtr pCon, + Bool sendClientData, + ClientPtr client); +extern int PclEndJob( + XpContextPtr pCon, + Bool cancel); +extern int PclStartPage( + XpContextPtr pCon, + WindowPtr pWin); +extern int PclEndPage( + XpContextPtr pCon, + WindowPtr pWin); +extern int PclStartDoc(XpContextPtr pCon, + XPDocumentType type); +extern int PclEndDoc( + XpContextPtr pCon, + Bool cancel); +extern int PclDocumentData( + XpContextPtr pCon, + DrawablePtr pDraw, + char *pData, + int len_data, + char *pFmt, + int len_fmt, + char *pOpt, + int len_opt, + ClientPtr client); +extern int PclGetDocumentData( + XpContextPtr pCon, + ClientPtr client, + int maxBufferSize); + + +#endif /* _PCL_H_ */ + + + + + + + + + diff --git a/Xprint/pcl/PclArc.c b/Xprint/pcl/PclArc.c new file mode 100644 index 000000000..ffdf32907 --- /dev/null +++ b/Xprint/pcl/PclArc.c @@ -0,0 +1,264 @@ +/* $Xorg: PclArc.c,v 1.3 2000/08/17 19:48:07 cpqbld Exp $ */ +/******************************************************************* +** +** ********************************************************* +** * +** * File: PclArc.c +** * +** * Contents: +** * Arc-drawing code for the PCL DDX driver +** * +** * Created: 10/23/95 +** * +** ********************************************************* +** +********************************************************************/ +/* +(c) Copyright 1996 Hewlett-Packard Company +(c) Copyright 1996 International Business Machines Corp. +(c) Copyright 1996 Sun Microsystems, Inc. +(c) Copyright 1996 Novell, Inc. +(c) Copyright 1996 Digital Equipment Corp. +(c) Copyright 1996 Fujitsu Limited +(c) Copyright 1996 Hitachi, Ltd. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the names of the copyright holders shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from said +copyright holders. +*/ + +#include <stdio.h> +#include <math.h> +#include <errno.h> + +#include "Pcl.h" +#include "gcstruct.h" +#include "windowstr.h" + +static void +PclDoArc( pDrawable, pGC, nArcs, pArcs, DoIt ) + DrawablePtr pDrawable; + GCPtr pGC; + int nArcs; + xArc *pArcs; + void (*DoIt)(); +{ + char t[80]; + FILE *outFile; + int nbox, i; + BoxPtr pbox; + BoxRec r; + RegionPtr drawRegion, region, transClip; + short fudge; + int xoffset, yoffset; + XpContextPtr pCon; + PclContextPrivPtr pConPriv; + xRectangle repro; + + if( PclUpdateDrawableGC( pGC, pDrawable, &outFile ) == FALSE ) + return; + + fudge = 3 * pGC->lineWidth; + + pCon = PclGetContextFromWindow( (WindowPtr) pDrawable ); + pConPriv = (PclContextPrivPtr) + pCon->devPrivates[PclContextPrivateIndex].ptr; + XpGetReproductionArea( pCon, &repro ); + + /* + * Generate the PCL code to draw the collection of arcs, by + * defining it as a macro which uses the HP-GL/2 arc drawing + * function. + */ + + xoffset = pDrawable->x; + yoffset = pDrawable->y; + + for( i = 0; i < nArcs; i++ ) + { + xArc Arc = pArcs[i]; + double b, X, Y, ratio; + double angle1; + + MACRO_START( outFile, pConPriv ); + SAVE_PCL( outFile, pConPriv, "\033%0B" ); + + /* Calculate the start of the arc */ + if( ( Arc.angle1 / 64 ) % 360 == 90 ) + { + X = 0; + Y = -Arc.height / 2.0; + } + else if( ( Arc.angle1 / 64 ) % 360 == 270 ) + { + X = 0; + Y = Arc.height / 2.0; + } + else + { + /* Convert the angle to radians */ + angle1 = ( Arc.angle1 / 64.0 ) * 3.141592654 / 180.0; + + b = (Arc.height / 2.0); + X = b * cos( angle1 ); + Y = -b * sin( angle1 ); + } + + /* Change the coordinate system to scale the ellipse */ + ratio = (double)Arc.height / (double)Arc.width; + + sprintf( t, "SC%.2f,%.2f,%d,%d;", + (repro.x - Arc.width / 2 - xoffset - Arc.x) * ratio, + (repro.x - Arc.width / 2 - xoffset - Arc.x + + repro.width) * ratio, + repro.y - Arc.height / 2 - yoffset - Arc.y + repro.height, + repro.y - Arc.height / 2 - yoffset - Arc.y); + SAVE_PCL( outFile, pConPriv, t ); + + DoIt( outFile, pConPriv, X, Y, Arc ); + + /* Build the bounding box */ + r.x1 = -Arc.width / 2 - fudge; + r.y1 = -Arc.height / 2 - fudge; + r.x2 = Arc.width / 2 + fudge; + r.y2 = Arc.height / 2 + fudge; + drawRegion = miRegionCreate( &r, 0 ); + + SAVE_PCL( outFile, pConPriv, "\033%0A" ); + MACRO_END( outFile ); + + /* + * Intersect the bounding box with the clip region. + */ + region = miRegionCreate( NULL, 0 ); + transClip = miRegionCreate( NULL, 0 ); + miRegionCopy( transClip, + ((PclGCPrivPtr)pGC->devPrivates[PclGCPrivateIndex].ptr) + ->pCompositeClip ); + miTranslateRegion( transClip, -(xoffset + Arc.x + Arc.width / 2), + -(yoffset + Arc.y + Arc.height / 2) ); + miIntersect( region, drawRegion, transClip ); + + /* + * For each rectangle in the clip region, set the HP-GL/2 "input + * window" and render the collection of arcs to it. + */ + pbox = REGION_RECTS( region ); + nbox = REGION_NUM_RECTS( region ); + + PclSendData(outFile, pConPriv, pbox, nbox, ratio); + + /* + * Restore the coordinate system + */ + sprintf( t, "\033%%0BSC%d,%d,%d,%d;\033%%0A", repro.x, + repro.x + repro.width, repro.y + repro.height, + repro.y ); + SEND_PCL( outFile, t ); + + /* + * Clean up the temporary regions + */ + miRegionDestroy( drawRegion ); + miRegionDestroy( region ); + miRegionDestroy( transClip ); + } +} + +/* + * Draw a simple non-filled arc, centered on the origin and starting + * at the given point. + */ +static void +DrawArc(FILE *outFile, + PclContextPrivPtr pConPriv, + double X, + double Y, + xArc A) +{ + char t[80]; + + sprintf( t, "PU%d,%d;PD;AA0,0,%.2f;", (int)X, (int)Y, + (float)A.angle2 / -64.0 ); + SAVE_PCL(outFile, pConPriv, t); +} + +void +PclPolyArc( pDrawable, pGC, nArcs, pArcs ) + DrawablePtr pDrawable; + GCPtr pGC; + int nArcs; + xArc *pArcs; +{ + PclDoArc( pDrawable, pGC, nArcs, pArcs, DrawArc ); +} + +/* + * Draw a filled wedge, from the origin, to the given point, through + * the appropriate angle, and back to the origin. + */ +static void +DoWedge(FILE *outFile, + PclContextPrivPtr pConPriv, + double X, + double Y, + xArc A) +{ + char t[80]; + + sprintf( t, "PU0,0;WG%.2f,%.2f,%.2f;", sqrt( X * X + Y * Y ), + (float)A.angle1 / -64.0, + (float)A.angle2 / -64.0 ); + SAVE_PCL(outFile, pConPriv, t); +} + +static void +DoChord(FILE *outFile, + PclContextPrivPtr pConPriv, + double X, + double Y, + xArc A) +{ + char t[80]; + + sprintf( t, "PU%d,%d;PM0;AA0,0,%.2f;PA%d,%d;PM2;FP;", (int)X, (int)Y, + (float)A.angle2 / -64.0 , (int)X, (int)Y ); + SAVE_PCL(outFile, pConPriv, t); +} + + +void +PclPolyFillArc( pDrawable, pGC, nArcs, pArcs ) + DrawablePtr pDrawable; + GCPtr pGC; + int nArcs; + xArc *pArcs; +{ + switch( pGC->arcMode ) + { + case ArcChord: + PclDoArc( pDrawable, pGC, nArcs, pArcs, DoChord ); + break; + case ArcPieSlice: + PclDoArc( pDrawable, pGC, nArcs, pArcs, DoWedge ); + break; + } +} diff --git a/Xprint/pcl/PclArea.c b/Xprint/pcl/PclArea.c new file mode 100644 index 000000000..da3107d5a --- /dev/null +++ b/Xprint/pcl/PclArea.c @@ -0,0 +1,487 @@ +/* $Xorg: PclArea.c,v 1.3 2000/08/17 19:48:07 cpqbld Exp $ */ +/******************************************************************* +** +** ********************************************************* +** * +** * File: PclArea.c +** * +** * Contents: +** * Image and Area functions for the PCL DDX driver +** * +** * Created: 10/23/95 +** * +** ********************************************************* +** +********************************************************************/ +/* +(c) Copyright 1996 Hewlett-Packard Company +(c) Copyright 1996 International Business Machines Corp. +(c) Copyright 1996 Sun Microsystems, Inc. +(c) Copyright 1996 Novell, Inc. +(c) Copyright 1996 Digital Equipment Corp. +(c) Copyright 1996 Fujitsu Limited +(c) Copyright 1996 Hitachi, Ltd. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the names of the copyright holders shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from said +copyright holders. +*/ + +#include <stdio.h> +#include <sys/types.h> +#include <sys/stat.h> +#include "Pcl.h" +#include "pixmapstr.h" +#include "region.h" + +#include "cfb.h" + +void +PclPutImage(DrawablePtr pDrawable, + GCPtr pGC, + int depth, + int x, + int y, + int w, + int h, + int leftPad, + int format, + char *pImage) +{ + PixmapPtr pPixmap; + unsigned long oldFg, oldBg; + XID gcv[3]; + unsigned long oldPlanemask; + unsigned long i; + long bytesPer; + + if( ( w == 0 ) || ( h == 0 ) ) + return; + + if( format != XYPixmap ) + { + pPixmap = GetScratchPixmapHeader( pDrawable->pScreen, + w+leftPad, h, depth, + BitsPerPixel( depth ), + PixmapBytePad( w + leftPad, + depth ), (pointer)pImage ); + if( !pPixmap ) + return; + + if( format == ZPixmap ) + (void)(*pGC->ops->CopyArea)( (DrawablePtr)pPixmap, pDrawable, pGC, + leftPad, 0, w, h, x, y ); + else + (void)(*pGC->ops->CopyPlane)( (DrawablePtr)pPixmap, pDrawable, pGC, + leftPad, 0, w, h, x, y, 1 ); + FreeScratchPixmapHeader( pPixmap ); + } + else + { + pPixmap = GetScratchPixmapHeader( pDrawable->pScreen, + w+leftPad, h, depth, + BitsPerPixel( depth ), + PixmapBytePad( w + leftPad, + depth ), (pointer)pImage ); + + if( !pPixmap ) + return; + + depth = pGC->depth; + oldPlanemask = pGC->planemask; + oldFg = pGC->fgPixel; + oldBg = pGC->bgPixel; + gcv[0] = ~0L; + gcv[1] = 0; + DoChangeGC( pGC, GCForeground | GCBackground, gcv, 0 ); + bytesPer = (long)h * BitmapBytePad( w + leftPad ); + + for( i = 1 << (depth-1); i != 0; i >>= 1, pImage += bytesPer ) + { + if( i & oldPlanemask ) + { + extern void cfbPutImage(), cfb32PutImage(); + gcv[0] = i; + DoChangeGC( pGC, GCPlaneMask, gcv, 0 ); + ValidateGC( pDrawable, pGC ); + if (pPixmap->drawable.depth <= 8 ) + cfbPutImage( (DrawablePtr)pPixmap, pGC, 1, x, y, w, h, + leftPad, XYBitmap, pImage ); + else if (pPixmap->drawable.depth <= 32 ) + cfb32PutImage( (DrawablePtr)pPixmap, pGC, 1, x, y, w, h, + leftPad, XYBitmap, pImage ); + } + } + gcv[0] = oldPlanemask; + gcv[1] = oldFg; + gcv[2] = oldBg; + DoChangeGC( pGC, GCPlaneMask | GCForeground | GCBackground, + gcv, 0 ); + + PclCopyArea( (DrawablePtr)pPixmap, pDrawable, pGC, leftPad, + 0, w, h, x, y ); + FreeScratchPixmapHeader( pPixmap ); + } +} + +/* + * PclMonoPixmapFragment() + * + * Given a 1-bit-deep pixmap, send the appropriate part of it to the + * output file as a PCL raster graphics command. + */ +static void +PclMonoPixmapFragment(FILE *outFile, + PixmapPtr pix, + short x1, + short y1, + short x2, + short y2, + short dstx, + short dsty) +{ + char *bits, t[80], *row; + int h, w, i; + + /* + * Create a storage area large enough to hold the entire pixmap, + * then use mfbGetImage to get the appropriate bits. + */ + h = y2 - y1; + w = BitmapBytePad( x2 - x1 ); + + bits = (char *)xalloc( h * w ); + mfbGetImage( (DrawablePtr)pix, x1, y1, x2 - x1, h, + XYPixmap, ~0, bits ); + + /* + * Move the cursor to the appropriate place on the page. We have + * to jump into HP-GL/2 to do this correctly, then go back to PCL + * for the actual drawing. + */ + sprintf( t, "\033%%0BPU%d,%d;\033%%1A", dstx, dsty ); + SEND_PCL( outFile, t ); + + /* + * Now, wrap the raster in the appropriate PCL code. Right now, + * it's going to go down the wire without any compression. That + * will have to be good enough for the sample implementation. + */ + sprintf( t, "\033*t300R\033*r%dT\033*r%dS\033*r1A\033*b0M", + h, x2 - x1 ); + SEND_PCL( outFile, t ); + + sprintf( t, "\033*b%dW", w ); + for( row = bits, i = 0; i <= h; i++, row += w ) + { + SEND_PCL( outFile, t ); + SEND_PCL_COUNT( outFile, row, w ); + } + + SEND_PCL( outFile, "\033*rC" ); + + /* + * Clean things up a bit + */ + xfree( bits ); +} + +static void +PclColorPixmapFragment(FILE *outFile, + PixmapPtr pix, + short x1, + short y1, + short x2, + short y2, + short dstx, + short dsty) +{ + char *bits, t[80], *row; + int h, w, i; + extern void cfbGetImage(), cfb32GetImage(); + + /* + * Create a storage area large enough to hold the entire pixmap, + * then use cfbGetImage to get the appropriate bits. + */ + h = y2 - y1; + w = PixmapBytePad( x2 - x1, pix->drawable.depth ); + + bits = (char *)xalloc( h * w ); + if (pix->drawable.depth <= 8) + cfbGetImage( (DrawablePtr)pix, x1, y1, x2 - x1, h, + ZPixmap, ~0, bits ); + else if (pix->drawable.depth <= 32) + cfb32GetImage( (DrawablePtr)pix, x1, y1, x2 - x1, h, + ZPixmap, ~0, bits ); + + /* + * Move the cursor to the appropriate place on the page. We have + * to jump into HP-GL/2 to do this correctly, then go back to PCL + * for the actual drawing. + */ + sprintf( t, "\033%%0BPU%d,%d;\033%%1A", dstx, dsty ); + SEND_PCL( outFile, t ); + + /* + * Now, wrap the raster in the appropriate PCL code. Right now, + * it's going to go down the wire without any compression. That + * will have to be good enough for the sample implementation. + */ + sprintf( t, "\033*t300R\033*r%dt%ds1A\033*b0M", + h, x2 - x1 ); + SEND_PCL( outFile, t ); + + sprintf( t, "\033*b%dW", w ); + for( row = bits, i = 0; i < h; i++, row += w ) + { + SEND_PCL( outFile, t ); + SEND_PCL_COUNT( outFile, row, w ); + } + + SEND_PCL( outFile, "\033*rC" ); + + /* + * Clean things up a bit + */ + xfree( bits ); +} + +RegionPtr +PclCopyArea(DrawablePtr pSrc, + DrawablePtr pDst, + GCPtr pGC, + int srcx, + int srcy, + int width, + int height, + int dstx, + int dsty) +{ + PixmapPtr pixSrc = (PixmapPtr)pSrc; + char t[80]; + FILE *srcFile, *dstFile; + GC srcGC, dstGC; + unsigned long valid; + struct stat statBuf; + XpContextPtr pCon; + xRectangle repro; + PclPixmapPrivPtr pPriv; + RegionPtr drawRegion, region, whole, ret; + BoxRec box; + BoxPtr prect; + int nrect; + void (*doFragment)(FILE *, PixmapPtr, short, short, short, short, + short, short ); + extern RegionPtr mfbCopyArea(), cfbCopyArea(), cfb32CopyArea(); + + /* + * Since we don't store any information on a per-window basis, we + * can't copy from a window. + */ + if( pSrc->type == DRAWABLE_WINDOW ) + return NULL; + + /* + * If we're copying from a pixmap to a pixmap, we just use the + * mfb/cfb code to do the work. + */ + if( pDst->type == DRAWABLE_PIXMAP ) + { + if( pSrc->depth == 1 ) + return mfbCopyArea( pSrc, pDst, pGC, srcx, srcy, width, + height, dstx, dsty ); + else if( pSrc->depth <= 8 ) + return cfbCopyArea( pSrc, pDst, pGC, srcx, srcy, width, + height, dstx, dsty ); + else if( pSrc->depth <= 32 ) + return cfb32CopyArea( pSrc, pDst, pGC, srcx, srcy, width, + height, dstx, dsty ); + } + +/* + PclGetDrawablePrivateStuff( pSrc, &srcGC, &valid, &srcFile ); +*/ + PclGetDrawablePrivateStuff( pDst, &dstGC, &valid, &dstFile ); + + /* + * If we're copying to a window, we have to do some actual + * drawing, instead of just handing it off to mfb or cfb. Start + * by determining the region that will be drawn. + */ + box.x1 = srcx; + box.y1 = srcy; + box.x2 = srcx + width; + box.y2 = srcy + height; + drawRegion = miRegionCreate( &box, 0 ); + miTranslateRegion( drawRegion, dstx, dsty ); + + region = miRegionCreate( NULL, 0 ); + miIntersect( region, drawRegion, + ((PclGCPrivPtr) + (pGC->devPrivates[PclGCPrivateIndex].ptr)) + ->pCompositeClip ); + + /* + * Now select the operation to be performed on each box in the + * region. + */ + if( pSrc->depth == 1 ) + doFragment = PclMonoPixmapFragment; + else + doFragment = PclColorPixmapFragment; + + /* + * Actually draw each section of the bitmap. + */ + nrect = REGION_NUM_RECTS( region ); + prect = REGION_RECTS( region ); + + while( nrect ) + { + (*doFragment)( dstFile, (PixmapPtr)pSrc, prect->x1 - dstx, + prect->y1 - dsty, prect->x2 - dstx, + prect->y2 - dsty, prect->x1, prect->y1 ); + + nrect--; + prect++; + } + + /* + * Update the destination's GC to the source's GC. + */ +/* + PclSetDrawablePrivateGC( pDst, srcGC ); +*/ + + /* + * Determine the region that needs to be returned. This is the + * region of the source that falls outside the boundary of the + * pixmap. + */ + box.x1 = 0; + box.y1 = 0; + box.x2 = pixSrc->drawable.width; + box.y2 = pixSrc->drawable.height; + whole = miRegionCreate( &box, 0 ); + ret = miRegionCreate( NULL, 0 ); + + miTranslateRegion( drawRegion, -dstx, -dsty ); + miSubtract( ret, drawRegion, whole ); + + /* + * Clean up the regions + */ + miRegionDestroy( drawRegion ); + miRegionDestroy( region ); + miRegionDestroy( whole ); + + if( miRegionNotEmpty( ret ) ) + return ret; + else + { + miRegionDestroy( ret ); + return NULL; + } +} + +RegionPtr +PclCopyPlane(DrawablePtr pSrc, + DrawablePtr pDst, + GCPtr pGC, + int srcx, + int srcy, + int width, + int height, + int dstx, + int dsty, + unsigned long plane) +{ + RegionPtr reg; + GCPtr scratchGC; + PixmapPtr scratchPix; + extern RegionPtr mfbCopyPlane(), cfbCopyPlane(), cfb32CopyPlane(); + + /* + * Since we don't store PCL on a per-window basis, there's no good + * way to copy from a window. + */ + if( pSrc->type == DRAWABLE_WINDOW ) + return NULL; + + /* + * Copying from a pixmap to a pixmap is already implemented by + * mfb/cfb. + */ + if( pSrc->type == DRAWABLE_PIXMAP && + pDst->type == DRAWABLE_PIXMAP ) + { + if( pDst->depth == 1 ) + return mfbCopyPlane( pSrc, pDst, pGC, srcx, srcy, width, + height, dstx, dsty, plane ); + else if( pDst->depth <= 8 ) + return cfbCopyPlane( pSrc, pDst, pGC, srcx, srcy, width, + height, dstx, dsty, plane ); + else if( pDst->depth <= 32 ) + return cfb32CopyPlane( pSrc, pDst, pGC, srcx, srcy, width, + height, dstx, dsty, plane ); + } + + /* + * We can use the mfb/cfbCopyPlane function to do the work of grabbing + * the plane and converting it to the desired visual. Once that's + * done, we already know how to do a CopyArea. + */ + scratchPix = (*pDst->pScreen->CreatePixmap)( pDst->pScreen, width, + height, pDst->depth ); + + scratchGC = GetScratchGC( pDst->depth, pDst->pScreen ); + CopyGC( pGC, scratchGC, ~0L ); + + if( pDst->depth == 1 ) + { + mfbValidateGC( scratchGC, ~0L, (DrawablePtr)scratchPix ); + mfbCopyPlane( pSrc, (DrawablePtr)scratchPix, scratchGC, + srcx, srcy, width, height, 0, 0, plane ); + } + else if( pDst->depth <= 8 ) + { + cfbValidateGC( scratchGC, ~0L, (DrawablePtr)scratchPix ); + cfbCopyPlane( pSrc, (DrawablePtr)scratchPix, scratchGC, + srcx, srcy, width, height, 0, 0, plane ); + } + else if( pDst->depth <= 32 ) + { + cfb32ValidateGC( scratchGC, ~0L, (DrawablePtr)scratchPix ); + cfb32CopyPlane( pSrc, (DrawablePtr)scratchPix, scratchGC, + srcx, srcy, width, height, 0, 0, plane ); + } + + reg = PclCopyArea( (DrawablePtr)scratchPix, pDst, pGC, 0, 0, width, + height, dstx, dsty ); + + FreeScratchGC( scratchGC ); + + (*pDst->pScreen->DestroyPixmap)( scratchPix ); + + return reg; +} + diff --git a/Xprint/pcl/PclAttVal.c b/Xprint/pcl/PclAttVal.c new file mode 100644 index 000000000..88fcf23b5 --- /dev/null +++ b/Xprint/pcl/PclAttVal.c @@ -0,0 +1,203 @@ +/* + * $Xorg: PclAttVal.c,v 1.3 2000/08/17 19:48:07 cpqbld Exp $ + */ +/* +(c) Copyright 1996 Hewlett-Packard Company +(c) Copyright 1996 International Business Machines Corp. +(c) Copyright 1996 Sun Microsystems, Inc. +(c) Copyright 1996 Novell, Inc. +(c) Copyright 1996 Digital Equipment Corp. +(c) Copyright 1996 Fujitsu Limited +(c) Copyright 1996 Hitachi, Ltd. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the names of the copyright holders shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from said +copyright holders. +*/ + +#include "Pcl.h" +#include "AttrValid.h" + +/* + * define valid values and defaults for Printer pool + */ +static XpOid ValidContentOrientationsOids[] = { + xpoid_val_content_orientation_portrait, + xpoid_val_content_orientation_landscape, + xpoid_val_content_orientation_reverse_portrait, + xpoid_val_content_orientation_reverse_landscape +}; +static XpOidList ValidContentOrientations = { + ValidContentOrientationsOids, XpNumber(ValidContentOrientationsOids) +}; + +static XpOid DefaultContentOrientationsOids[] = { + xpoid_val_content_orientation_portrait, + xpoid_val_content_orientation_landscape +}; +static XpOidList DefaultContentOrientations = { + DefaultContentOrientationsOids, XpNumber(DefaultContentOrientationsOids) +}; + +static XpOid ValidPlexesOids[] = { + xpoid_val_plex_simplex, xpoid_val_plex_duplex, xpoid_val_plex_tumble +}; +static XpOidList ValidPlexes = { + ValidPlexesOids, XpNumber(ValidPlexesOids) +}; + +static XpOid DefaultPlexesOids[] = { + xpoid_val_plex_simplex +}; +static XpOidList DefaultPlexes = { + DefaultPlexesOids, XpNumber(DefaultPlexesOids) +}; + +static unsigned long ValidPrinterResolutionsCards[] = { + 300 +}; +static XpOidCardList ValidPrinterResolutions = { + ValidPrinterResolutionsCards, XpNumber(ValidPrinterResolutionsCards) +}; + +static unsigned long DefaultPrinterResolutionsCards[] = { + 300 +}; +static XpOidCardList DefaultPrinterResolutions = { + DefaultPrinterResolutionsCards, XpNumber(DefaultPrinterResolutionsCards) +}; + +static XpOid ValidListfontsModesOids[] = { + xpoid_val_xp_list_internal_printer_fonts, xpoid_val_xp_list_glyph_fonts +}; +static XpOidList ValidListfontsModes = { + ValidListfontsModesOids, XpNumber(ValidListfontsModesOids) +}; + +static XpOid DefaultListfontsModesOids[] = { + xpoid_val_xp_list_glyph_fonts +}; +static XpOidList DefaultListfontsModes = { + DefaultListfontsModesOids, XpNumber(DefaultListfontsModesOids) +}; + +static XpOid ValidSetupProvisoOids[] = { + xpoid_val_xp_setup_mandatory, xpoid_val_xp_setup_optional +}; +static XpOidList ValidSetupProviso = { + + + ValidSetupProvisoOids, XpNumber(ValidSetupProvisoOids) +}; + +static XpOidDocFmt ValidDocFormatsSupportedFmts[] = { + { "PCL", "5", NULL }, +}; +static XpOidDocFmtList ValidDocFormatsSupported = { + ValidDocFormatsSupportedFmts, XpNumber(ValidDocFormatsSupportedFmts) +}; + +static XpOidDocFmt DefaultDocFormatsSupportedFmts[] = { + { "PCL", "5", NULL } +}; +static XpOidDocFmtList DefaultDocFormatsSupported = { + DefaultDocFormatsSupportedFmts, XpNumber(DefaultDocFormatsSupportedFmts) +}; + +static XpOidDocFmt ValidEmbeddedFormatsSupportedFmts[] = { + { "HPGL", "2", NULL }, +}; +static XpOidDocFmtList ValidEmbeddedFormatsSupported = { + ValidEmbeddedFormatsSupportedFmts, XpNumber(ValidEmbeddedFormatsSupportedFmts) +}; + +static XpOidDocFmt DefaultEmbeddedFormatsSupportedFmts[] = { + { "HPGL", "2", NULL } +}; +static XpOidDocFmtList DefaultEmbeddedFormatsSupported = { + DefaultEmbeddedFormatsSupportedFmts, XpNumber(DefaultEmbeddedFormatsSupportedFmts) +}; + +static XpOidDocFmt ValidRawFormatsSupportedFmts[] = { + { "PCL", "5", NULL }, + { "Postscript", "2", NULL }, + { "ASCII", NULL, NULL } + +}; +static XpOidDocFmtList ValidRawFormatsSupported = { + ValidRawFormatsSupportedFmts, XpNumber(ValidRawFormatsSupportedFmts) +}; + +static XpOidDocFmt DefaultRawFormatsSupportedFmts[] = { + { "PCL", "5", NULL } +}; +static XpOidDocFmtList DefaultRawFormatsSupported = { + DefaultRawFormatsSupportedFmts, XpNumber(DefaultRawFormatsSupportedFmts) +}; + +static XpOid ValidInputTraysOids[] = { + xpoid_val_input_tray_manual, + xpoid_val_input_tray_main, + xpoid_val_input_tray_envelope, + xpoid_val_input_tray_large_capacity, + xpoid_val_input_tray_bottom +}; +static XpOidList ValidInputTrays = { + ValidInputTraysOids, XpNumber(ValidInputTraysOids) +}; + +static XpOid ValidMediumSizesOids[] = { + xpoid_val_medium_size_iso_a3, + xpoid_val_medium_size_iso_a4, + xpoid_val_medium_size_na_letter, + xpoid_val_medium_size_na_legal, + xpoid_val_medium_size_executive, + xpoid_val_medium_size_ledger, + xpoid_val_medium_size_iso_c5, + xpoid_val_medium_size_iso_designated_long, + xpoid_val_medium_size_na_number_10_envelope, + xpoid_val_medium_size_monarch_envelope, + xpoid_val_medium_size_jis_b5, +}; +static XpOidList ValidMediumSizes = { + ValidMediumSizesOids, XpNumber(ValidMediumSizesOids) +}; + +static XpOidDocFmt DefaultDocumentFormat = { + "PCL", "5", NULL +}; + + +/* + * init struct for XpValidate*Pool + */ +XpValidatePoolsRec PclValidatePoolsRec = { + &ValidContentOrientations, &DefaultContentOrientations, + &ValidDocFormatsSupported, &DefaultDocFormatsSupported, + &ValidInputTrays, &ValidMediumSizes, + &ValidPlexes, &DefaultPlexes, + &ValidPrinterResolutions, &DefaultPrinterResolutions, + &ValidEmbeddedFormatsSupported, &DefaultEmbeddedFormatsSupported, + &ValidListfontsModes, &DefaultListfontsModes, + &ValidRawFormatsSupported, &DefaultRawFormatsSupported, + &ValidSetupProviso, + &DefaultDocumentFormat +}; diff --git a/Xprint/pcl/PclAttr.c b/Xprint/pcl/PclAttr.c new file mode 100644 index 000000000..2612a821f --- /dev/null +++ b/Xprint/pcl/PclAttr.c @@ -0,0 +1,83 @@ +/* $Xorg: PclAttr.c,v 1.3 2000/08/17 19:48:07 cpqbld Exp $ */ +/******************************************************************* +** +** ********************************************************* +** * +** * File: PclAttr.c +** * +** * Contents: +** * Attribute-handling functions for the PCL driver +** * +** * Created: 2/2/96 +** * +** ********************************************************* +** +********************************************************************/ +/* +(c) Copyright 1996 Hewlett-Packard Company +(c) Copyright 1996 International Business Machines Corp. +(c) Copyright 1996 Sun Microsystems, Inc. +(c) Copyright 1996 Novell, Inc. +(c) Copyright 1996 Digital Equipment Corp. +(c) Copyright 1996 Fujitsu Limited +(c) Copyright 1996 Hitachi, Ltd. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the names of the copyright holders shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from said +copyright holders. +*/ + +#include "Pcl.h" +#include "attributes.h" + +char * +PclGetAttributes( + XpContextPtr pCon, + XPAttributes pool ) +{ + return XpGetAttributes( pCon, pool ); +} + +char * +PclGetOneAttribute( + XpContextPtr pCon, + XPAttributes pool, + char *attr ) +{ + return XpGetOneAttribute( pCon, pool, attr ); +} +int +PclAugmentAttributes( + XpContextPtr pCon, + XPAttributes pool, + char *attrs ) +{ + return XpAugmentAttributes( pCon, pool, attrs ); +} + +int +PclSetAttributes( + XpContextPtr pCon, + XPAttributes pool, + char *attrs ) +{ + return XpSetAttributes( pCon, pool, attrs ); +} diff --git a/Xprint/pcl/PclColor.c b/Xprint/pcl/PclColor.c new file mode 100644 index 000000000..cd3d2cc12 --- /dev/null +++ b/Xprint/pcl/PclColor.c @@ -0,0 +1,860 @@ +/* $Xorg: PclColor.c,v 1.3 2000/08/17 19:48:07 cpqbld Exp $ */ +/******************************************************************* +** +** ********************************************************* +** * +** * File: PclColorInit.c +** * +** * Contents: +** * Colormap handing code of Pcl driver for the +** * print server. +** * +** * Created: 4/8/96 +** * +** ********************************************************* +** +********************************************************************/ +/* +(c) Copyright 1996 Hewlett-Packard Company +(c) Copyright 1996 International Business Machines Corp. +(c) Copyright 1996 Sun Microsystems, Inc. +(c) Copyright 1996 Novell, Inc. +(c) Copyright 1996 Digital Equipment Corp. +(c) Copyright 1996 Fujitsu Limited +(c) Copyright 1996 Hitachi, Ltd. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the names of the copyright holders shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from said +copyright holders. +*/ + +#include <stdio.h> +#include <string.h> +#include <stdlib.h> +#include <sys/wait.h> +#include <unistd.h> +#include <math.h> + +#include "colormapst.h" +#include "windowstr.h" +#include "resource.h" + +#include "Pcl.h" + +PclPaletteMapPtr PclFindPaletteMap(PclContextPrivPtr cPriv, + ColormapPtr cmap, + GCPtr gc); + +unsigned char *PclReadMap(char *, int *); + +void PclLookUp( ColormapPtr cmap, + PclContextPrivPtr cPriv, + unsigned short *r, + unsigned short *g, + unsigned short *b); + +static void lookup(unsigned char *src, + unsigned char *dst, + int num, + unsigned char *map, + int dim); +static void trilinear(unsigned char *p, + unsigned char *out, + unsigned char *d, + int dim, + unsigned char def); + + +/* + * This seems to be (and is) a duplication of effort; one would think + * that cfbCreateDefColormap would be sufficient. It almost is. The + * only change made in this function is that the black and white pixels + * are allocated with three separate variables for red, green and blue + * values, instead of the single variable in cfbCreateDefColormap. The + * single variable leads to the one value being corrected by + * ResolveColor three times, which leads to incorrect colors. + */ + +Bool +PclCreateDefColormap(ScreenPtr pScreen) +{ + unsigned short wp_red = ~0, wp_green = ~0, wp_blue = ~0; + unsigned short bp_red = 0, bp_green = 0, bp_blue = 0; + VisualPtr pVisual; + ColormapPtr cmap; + Pixel wp, bp; + + for (pVisual = pScreen->visuals; + pVisual->vid != pScreen->rootVisual; + pVisual++) + ; + + if (CreateColormap(pScreen->defColormap, pScreen, pVisual, &cmap, + (pVisual->class & DynamicClass) ? AllocNone : AllocAll, + 0) + != Success) + return FALSE; + wp = pScreen->whitePixel; + bp = pScreen->blackPixel; + if ((AllocColor(cmap, &wp_red, &wp_green, &wp_blue, &wp, 0) != + Success) || + (AllocColor(cmap, &bp_red, &bp_green, &bp_blue, &bp, 0) != + Success)) + return FALSE; + + pScreen->whitePixel = wp; + pScreen->blackPixel = bp; + + (*pScreen->InstallColormap)(cmap); + return TRUE; +} + +/* + * Add colormap to list of colormaps on screen + */ +Bool +PclCreateColormap(ColormapPtr pColor) +{ + PclCmapToContexts *new; + PclScreenPrivPtr sPriv; + + sPriv = (PclScreenPrivPtr)pColor->pScreen + ->devPrivates[PclScreenPrivateIndex].ptr; + + /* + * Use existing code to initialize the values in the colormap + */ + cfbInitializeColormap( pColor ); + + /* + * Set up the mapping between the color map and the context + */ + new = (PclCmapToContexts *)xalloc( sizeof( PclCmapToContexts ) ); + + if( new ) + { + new->colormapId = pColor->mid; + new->contexts = NULL; + new->next = sPriv->colormaps; + sPriv->colormaps = new; + + return TRUE; + } + else + return FALSE; +} + +void +PclDestroyColormap(ColormapPtr pColor) +{ + PclScreenPrivPtr sPriv; + PclCmapToContexts *pCmap, *tCmap; + PclContextListPtr con, tCon; + PclContextPrivPtr cPriv; + PclPaletteMapPtr pPal; + char t[80]; + + /* + * At DestroyContext time, colormaps may be destroyed twice, so if the + * pointer is NULL, just crash out. + */ + if( !pColor ) + return; + + /* + * Find the colormap <-> contexts mapping + */ + sPriv = (PclScreenPrivPtr)pColor->pScreen + ->devPrivates[PclScreenPrivateIndex].ptr; + pCmap = sPriv->colormaps; + while( pCmap ) + { + if( pCmap->colormapId == pColor->mid ) + break; + tCmap = pCmap; + pCmap = pCmap->next; + } + + /* + * For each context, delete the palette in the printer and + * free the mapping. + */ + if( pCmap ) + { + con = pCmap->contexts; + while( con ) + { + cPriv = con->context->devPrivates[PclContextPrivateIndex].ptr; + + pPal = cPriv->palettes; + while( pPal ) + { + if( pPal->colormapId == pColor->mid ) + break; + pPal = pPal->next; + } + + if( cPriv->pPageFile ) + { + sprintf( t, "\033&p%dI\033*p2C", pPal->paletteId ); + SEND_PCL( cPriv->pPageFile, t ); + } + + tCon = con; + con = con->next; + xfree( tCon ); + } + + /* + * Delete the colormap<->contexts mapping + */ + if( sPriv->colormaps == pCmap ) + /* Delete from the front */ + sPriv->colormaps = pCmap->next; + else + /* Delete from the middle */ + tCmap->next = pCmap->next; + free( pCmap ); + } +} + +void +PclInstallColormap(ColormapPtr pColor) +{ +} + +void +PclUninstallColormap(ColormapPtr pColor) +{ +} + +int +PclListInstalledColormaps(ScreenPtr pScreen, + XID *pCmapList) +{ + return 0; +} + +void +PclStoreColors(ColormapPtr pColor, + int ndef, + xColorItem *pdefs) +{ + PclCmapToContexts *p; + PclScreenPrivPtr sPriv; + PclContextListPtr con; + PclContextPrivPtr cPriv; + PclPaletteMapPtr pMap; + char t[80], t2[30]; + int i; + + sPriv = (PclScreenPrivPtr)pColor->pScreen + ->devPrivates[PclScreenPrivateIndex].ptr; + p = sPriv->colormaps; + while( p ) + { + if( p->colormapId == pColor->mid ) + break; + p = p->next; + } + + if( p ) + { + con = p->contexts; + while( con ) + { + /* + * For each context, get the palette ID and update the + * appropriate palette. + */ + cPriv = con->context + ->devPrivates[PclContextPrivateIndex].ptr; + pMap = PclFindPaletteMap( cPriv, pColor, NULL ); + + /* + * Update the palette + */ + sprintf( t, "\033&p%dS", pMap->paletteId ); + SEND_PCL( cPriv->pPageFile, t ); + + if( pColor->class == PseudoColor ) + { + unsigned short r, g, b; + unsigned int pID; + for( i = 0; i < ndef; i++ ) + { + pID = pdefs[i].pixel; + if ( pColor->red[i].fShared ) + { + r = pColor->red[pID].co.shco.red->color; + g = pColor->red[pID].co.shco.green->color; + b = pColor->red[pID].co.shco.blue->color; + } + else + { + r = pColor->red[pID].co.local.red; + g = pColor->red[pID].co.local.green; + b = pColor->red[pID].co.local.blue; + } + + if( pdefs[i].flags & DoRed ) + r = pdefs[i].red; + if( pdefs[i].flags & DoGreen ) + g = pdefs[i].green; + if( pdefs[i].flags & DoBlue ) + b = pdefs[i].blue; + PclLookUp(pColor, cPriv, &r, &g, &b); + sprintf( t, "\033*v%ua%ub%uc%dI", r, g, b, pID); + SEND_PCL( cPriv->pPageFile, t ); + } + } + + sprintf( t, "\033&p%dS", cPriv->currentPalette ); + SEND_PCL( cPriv->pPageFile, t ); + + con = con->next; + } + } +} + +void +PclResolveColor(unsigned short *pRed, + unsigned short *pGreen, + unsigned short *pBlue, + VisualPtr pVisual) +{ + /* + * We need to map the X color range of [0,65535] to the PCL color + * range of [0,32767]. + */ + *pRed >>= 1; + *pGreen >>= 1; + *pBlue >>= 1; +} + +PclPaletteMapPtr +PclFindPaletteMap(PclContextPrivPtr cPriv, + ColormapPtr cmap, + GCPtr gc) +{ + PclPaletteMapPtr p = cPriv->palettes, new; + + /* + * If the colormap is static, grab one of the special palettes. If we come + * into this from StoreColors, there will be no GC, but by definition we're + * looking at a dynamic color map, so the special colors will not be + * needed. + */ + if( gc ) + { + if( cmap->pVisual->class == StaticGray ) + return &( cPriv->staticGrayPalette ); + else if( cmap->pVisual->class == TrueColor ) + { + if( gc->fillStyle == FillTiled && !( gc->tileIsPixel ) ) + return &( cPriv->specialTrueColorPalette ); + else + return &( cPriv->trueColorPalette ); + } + } + + + /* Look for the colormap ID <-> palette ID mapping */ + while( p ) + { + if( p->colormapId == cmap->mid ) + return p; + p = p->next; + } + + /* If the colormap isn't already there, make an entry for it */ + new = (PclPaletteMapPtr)xalloc( sizeof( PclPaletteMap ) ); + new->colormapId = cmap->mid; + new->paletteId = cPriv->nextPaletteId++; + new->downloaded = 0; + new->next = cPriv->palettes; + cPriv->palettes = new; + return new; +} + +int +PclUpdateColormap(DrawablePtr pDrawable, + XpContextPtr pCon, + GCPtr gc, + FILE *outFile) +{ + PclScreenPrivPtr sPriv; + + PclContextPrivPtr cPriv; + PclPaletteMapPtr pMap; + PclCmapToContexts *pCmap, *tCmap; + PclContextListPtr new; + char t[80]; + Colormap c; + ColormapPtr cmap; + WindowPtr win = (WindowPtr)pDrawable; + unsigned short r, g, b, rr, gg, bb; + int i; + + cPriv = pCon->devPrivates[PclContextPrivateIndex].ptr; + + c = wColormap( win ); + cmap = (ColormapPtr)LookupIDByType( c, RT_COLORMAP ); + pMap = PclFindPaletteMap( cPriv, cmap, gc ); + + if( cPriv->currentPalette == pMap->paletteId ) + /* + * If the requested colormap is already active, nothing needs to + * be done. + */ + return; + + /* + * Now we activate the palette in the printer + */ + sprintf( t, "\033&p%dS", pMap->paletteId ); + SEND_PCL( outFile, t ); + cPriv->currentPalette = pMap->paletteId; + + if( pMap->downloaded == 0 ) + /* + * If the requested colormap has not been downloaded to the + * printer, we need to do that before activating it. + */ + { + /* + * Add the colormap to the screen-level colormap<->context mapping. + */ + sPriv = (PclScreenPrivPtr)cmap->pScreen + ->devPrivates[PclScreenPrivateIndex].ptr; + pCmap = sPriv->colormaps; + while( pCmap ) + { + if( pCmap->colormapId == cmap->mid ) + break; + tCmap = pCmap; + pCmap = pCmap->next; + } + new = (PclContextListPtr)xalloc( sizeof( PclContextList ) ); + new->context = pCon; + new->next = pCmap->contexts; + pCmap->contexts = new; + + /* + * XXX Download the colormap + */ + if( cmap->class == StaticGray ) + { +#ifdef XP_PCL_COLOR + sprintf( t, "\033*v18W%c%c%c%c%c%c", 0, 1, 1, 1, 1, 1 ); + SEND_PCL_COUNT( cPriv->pPageFile, t, 12 ); + + /* Send the white reference point... */ + sprintf( t, "%c%c%c%c%c%c", 0x7f, 0xff, 0x7f, 0xff, + 0x7f, 0xff ); + SEND_PCL_COUNT( cPriv->pPageFile, t, 6 ); + + /* ... and the black reference point */ + sprintf( t, "%c%c%c%c%c%c", 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 ); + SEND_PCL_COUNT( cPriv->pPageFile, t, 6 ); + + /* Now program the two colors */ + sprintf( t, "\033*v0a0b0c%dI", cmap->pScreen->blackPixel ); + SEND_PCL( cPriv->pPageFile, t ); + sprintf( t, "\033*v32767a32767b32767c%dI", + cmap->pScreen->whitePixel ); + SEND_PCL( cPriv->pPageFile, t ); +#endif /* XP_PCL_COLOR */ + } + else if( cmap->class == PseudoColor ) + { + sprintf( t, + "\033*v18W%c%c%c%c%c%c", + 0, 1, cmap->pVisual->nplanes, 16, 16, 16 ); + SEND_PCL_COUNT( cPriv->pPageFile, t, 12 ); + + /* Send the white reference point... */ + if ( cPriv->ctbl != NULL ) + sprintf( t, "%c%c%c%c%c%c", 0x00, 0xff, 0x00, 0xff, + 0x00, 0xff ); + else + sprintf( t, "%c%c%c%c%c%c", 0x7f, 0xff, 0x7f, 0xff, + 0x7f, 0xff ); + SEND_PCL_COUNT( cPriv->pPageFile, t, 6 ); + + /* ... and the black reference point */ + sprintf( t, "%c%c%c%c%c%c", 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 ); + SEND_PCL_COUNT( cPriv->pPageFile, t, 6 ); + + for(i = 0; i < cmap->pVisual->ColormapEntries; i++ ) + { + if( cmap->red[i].fShared ) + { + r = cmap->red[i].co.shco.red->color; + g = cmap->red[i].co.shco.green->color; + b = cmap->red[i].co.shco.blue->color; + } + else + { + r = cmap->red[i].co.local.red; + g = cmap->red[i].co.local.green; + b = cmap->red[i].co.local.blue; + } + PclLookUp(cmap, cPriv, &r, &g, &b); + sprintf( t, "\033*v%ua%ub%uc%dI", r, g, b, i ); + SEND_PCL( outFile, t ); + } + } + else if( cmap->class == TrueColor ) + { + unsigned short lim; + + if( gc->fillStyle == FillTiled && !( gc->tileIsPixel ) ) + { + if( cPriv->ctbl != NULL ) + { + /* Send the "special" colormap for 24-bit fills */ + sprintf( t, "\033*v18W%c%c%c%c%c%c", 0, 1, + 8, + cmap->pVisual->bitsPerRGBValue, + cmap->pVisual->bitsPerRGBValue, + cmap->pVisual->bitsPerRGBValue ); + SEND_PCL_COUNT( cPriv->pPageFile, t, 12 ); + + /* Send the white reference point... */ + sprintf( t, "%c%c%c%c%c%c", + 0x00, 0xff, + 0x00, 0xff, + 0x00, 0xff ); + SEND_PCL_COUNT( cPriv->pPageFile, t, 6 ); + + /* ... and the black reference point */ + sprintf( t, "%c%c%c%c%c%c", + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00 ); + SEND_PCL_COUNT( cPriv->pPageFile, t, 6 ); + + /* Now send the color entries, RRRGGGBB */ + i=0; + for( r = 0; r < 8; r++ ) + for( g = 0; g < 8; g ++ ) + for( b = 0; b < 4; b++ ) + { + rr = (r * 0xff)/7; + gg = (g * 0xff)/7; + bb = (b * 0xff)/3; + PclLookUp(cmap, cPriv, &rr, &gg, &bb); + sprintf( t, "\033*v%ua%ub%uc%dI", + rr, gg, bb, i ); + SEND_PCL( outFile, t ); + i++; + } + } + else + { + /* Send the "special" colormap for 24-bit fills */ + sprintf( t, "\033*v18W%c%c%c%c%c%c", 0, 1, + 8, + cmap->pVisual->bitsPerRGBValue, + cmap->pVisual->bitsPerRGBValue, + cmap->pVisual->bitsPerRGBValue ); + SEND_PCL_COUNT( cPriv->pPageFile, t, 12 ); + + /* Send the white reference point... */ + sprintf( t, "%c%c%c%c%c%c", + 0x00, 0x07, + 0x00, 0x07, + 0x00, 0x03 ); + SEND_PCL_COUNT( cPriv->pPageFile, t, 6 ); + + /* ... and the black reference point */ + sprintf( t, "%c%c%c%c%c%c", + 0x00, 0x00, + 0x00, 0x00, + 0x00, 0x00 ); + SEND_PCL_COUNT( cPriv->pPageFile, t, 6 ); + + /* Now send the color entries, RRRGGGBB */ + i=0; + for( r = 0; r < 8; r++ ) + for( g = 0; g < 8; g ++ ) + for( b = 0; b < 4; b++ ) + { + sprintf( t, "\033*v%ua%ub%uc%dI", + r, g, b, i ); + SEND_PCL( outFile, t ); + i++; + } + } + + } + else + { + lim = (1 << cmap->pVisual->bitsPerRGBValue) - 1; + + /* Send the "special" colormap for 24-bit fills */ + sprintf( t, "\033*v18W%c%c%c%c%c%c", 0, 3, + cmap->pVisual->nplanes, + cmap->pVisual->bitsPerRGBValue, + cmap->pVisual->bitsPerRGBValue, + cmap->pVisual->bitsPerRGBValue ); + SEND_PCL_COUNT( cPriv->pPageFile, t, 12 ); + + /* Send the white reference point... */ + sprintf( t, "%c%c%c%c%c%c", + (lim >> 8) & 0xff, lim & 0xff, + (lim >> 8) & 0xff, lim & 0xff, + (lim >> 8) & 0xff, lim & 0xff); + SEND_PCL_COUNT( cPriv->pPageFile, t, 6 ); + + /* ... and the black reference point */ + sprintf( t, "%c%c%c%c%c%c", 0x00, 0x00, 0x00, 0x00, + 0x00, 0x00 ); + SEND_PCL_COUNT( cPriv->pPageFile, t, 6 ); + } + + } + pMap->downloaded = 1; + } + +} + +void PclLookUp( + ColormapPtr cmap, + PclContextPrivPtr cPriv, + unsigned short *r, + unsigned short *g, + unsigned short *b +) +{ + unsigned char cdata[3]; + + if( cmap->class == PseudoColor ) + { + if( cPriv->ctbl != NULL ) + { + cdata[0] = *r >> 8; + cdata[1] = *g >> 8; + cdata[2] = *b >> 8; + lookup(cdata, cdata, 1, cPriv->ctbl, cPriv->ctbldim); + *r = cdata[0]; + *g = cdata[1]; + *b = cdata[2]; + } + else + { + *r >>= 1; + *g >>= 1; + *b >>= 1; + } + } + else if( cmap->class == TrueColor ) + { + if( cPriv->ctbl != NULL ) + { + cdata[0] = *r; + cdata[1] = *g; + cdata[2] = *b; + lookup(cdata, cdata, 1, cPriv->ctbl, cPriv->ctbldim); + *r = cdata[0]; + *g = cdata[1]; + *b = cdata[2]; + } + } + return; +} + +unsigned char *PclReadMap(char *name, int *dim) +{ + FILE *fp; + unsigned char *data; + long size; + + if ((fp=fopen(name, "r")) == NULL) { + return(NULL); + } + + fseek(fp, 0, SEEK_END); + size = ftell(fp); + + /* Could do this with a lookup table, if the constraint is that the + 3 map dimensions must be equal. */ + switch (size) { + case 8*8*8*3: + *dim = 8; + break; + case 16*16*16*3: + *dim = 16; + break; + case 17*17*17*3: + *dim = 17; + break; + case 65*65*65*3: + *dim = 65; + break; + default: + fclose(fp); + return(NULL); + } + + if ((data = (unsigned char *) xalloc(sizeof(char) * size)) == NULL) { + fclose(fp); + return(NULL); + } + + fseek(fp, 0, SEEK_SET); + + if (fread(data, sizeof(char), size, fp) != size) { + fclose(fp); + free(data); + return(NULL); + } + + fclose(fp); + return(data); +} + +/************************************************************************ + * + * Here is the mapper. + * + ************************************************************************/ + +#define SCL(x) ((x)*(dim-1)/255) +/* Interleaved-map lookup */ +static void lookup(unsigned char *src, unsigned char *dst, int num, unsigned char *map, int dim) +{ + int i; + unsigned char *p1, *p2, *p3; + int shift, offset; + +#define _INTERPOLATE +#ifndef _INTERPOLATE + for (i=0; i<num; i++) { + p1 = map + (SCL(src[0])*dim*dim + SCL(src[1])*dim + SCL(src[2])) * 3; + *dst++ = *p1++; + *dst++ = *p1++; + *dst++ = *p1++; + src += 3; + } +#else + for (i=0; i<num; i++) { + trilinear(src, dst, map, dim, 128); + src += 3; + dst += 3; + } +#endif +} + +/* + * C code from the article + * "Tri-linear Interpolation" + * by Steve Hill, sah@ukc.ac.uk + * in "Graphics Gems IV", Academic Press, 1994 + * + * Fri Feb 16 14:12:43 PST 1996 + * Modified to use for 8-bit color mapping -- A. Fitzhugh, + * HP Labs, Printing Technology Department + */ + +/* linear interpolation from l (when a=0) to h (when a=1)*/ +/* (equal to (a*h)+((1-a)*l) */ +#define LERP(a,l,h) ((l)+((((h)-(l))*(a))>>8)) + +static void trilinear(unsigned char *p, unsigned char *out, unsigned char *d, int dim, unsigned char def) +{ +#define DENS(X, Y, Z, ch) d[((X*dim+Y)*dim+Z)*3+ch] + + int x0, y0, z0, + x1, y1, z1, + i; + unsigned char *dp, + fx, fy, fz, + d000, d001, d010, d011, + d100, d101, d110, d111, + dx00, dx01, dx10, dx11, + dxy0, dxy1, dxyz; + float scale; + + scale = 255.0 / (dim-1); + + x0 = p[0] / scale; + y0 = p[1] / scale; + z0 = p[2] / scale; + + /* Fractions should range from 0-1.0 (fixed point 8-256) */ + fx = (((int) (p[0] - x0 * scale)) << 8) / 255; + fy = (((int) (p[1] - y0 * scale)) << 8) / 255; + fz = (((int) (p[2] - z0 * scale)) << 8) / 255; + + x1 = x0 + 1; + y1 = y0 + 1; + z1 = z0 + 1; + + for (i=0; i<3; i++) { + + if (x0 >= 0 && x1 < dim && + y0 >= 0 && y1 < dim && + z0 >= 0 && z1 < dim) { + dp = &DENS(x0, y0, z0, i); + d000 = dp[0]; + d100 = dp[3]; + dp += dim*3; + d010 = dp[0]; + d110 = dp[3]; + dp += dim*dim*3; + d011 = dp[0]; + d111 = dp[3]; + dp -= dim*3; + d001 = dp[0]; + d101 = dp[3]; + } else { +# define INRANGE(X, Y, Z) \ + ((X) >= 0 && (X) < dim && \ + (Y) >= 0 && (Y) < dim && \ + (Z) >= 0 && (Z) < dim) + + d000 = INRANGE(x0, y0, z0) ? DENS(x0, y0, z0, i) : def; + d001 = INRANGE(x0, y0, z1) ? DENS(x0, y0, z1, i) : def; + d010 = INRANGE(x0, y1, z0) ? DENS(x0, y1, z0, i) : def; + d011 = INRANGE(x0, y1, z1) ? DENS(x0, y1, z1, i) : def; + + d100 = INRANGE(x1, y0, z0) ? DENS(x1, y0, z0, i) : def; + d101 = INRANGE(x1, y0, z1) ? DENS(x1, y0, z1, i) : def; + d110 = INRANGE(x1, y1, z0) ? DENS(x1, y1, z0, i) : def; + d111 = INRANGE(x1, y1, z1) ? DENS(x1, y1, z1, i) : def; + } + + dx00 = LERP(fx, d000, d100); + dx01 = LERP(fx, d001, d101); + dx10 = LERP(fx, d010, d110); + dx11 = LERP(fx, d011, d111); + + dxy0 = LERP(fy, dx00, dx10); + dxy1 = LERP(fy, dx01, dx11); + + out[i] = LERP(fz, dxy0, dxy1); + } +} + diff --git a/Xprint/pcl/PclCursor.c b/Xprint/pcl/PclCursor.c new file mode 100644 index 000000000..88a76f6bf --- /dev/null +++ b/Xprint/pcl/PclCursor.c @@ -0,0 +1,110 @@ +/* $Xorg: PclCursor.c,v 1.3 2000/08/17 19:48:08 cpqbld Exp $ */ +/******************************************************************* +** +** ********************************************************* +** * +** * File: PclCursor.c +** * +** * Contents: +** * Cursor-handling code for the PCL DDX driver +** * +** * Created: 1/18/96 +** * +** ********************************************************* +** +********************************************************************/ +/* +(c) Copyright 1996 Hewlett-Packard Company +(c) Copyright 1996 International Business Machines Corp. +(c) Copyright 1996 Sun Microsystems, Inc. +(c) Copyright 1996 Novell, Inc. +(c) Copyright 1996 Digital Equipment Corp. +(c) Copyright 1996 Fujitsu Limited +(c) Copyright 1996 Hitachi, Ltd. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the names of the copyright holders shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from said +copyright holders. +*/ + +#include <stdio.h> + +#include "Pcl.h" +#include "gcstruct.h" +#include "windowstr.h" + +void +PclConstrainCursor( pScreen, pBox ) + ScreenPtr pScreen; + BoxPtr pBox; +{ +} + +void +PclCursorLimits( pScreen, pCursor, pHotBox, pTopLeftBox ) + ScreenPtr pScreen; + CursorPtr pCursor; + BoxPtr pHotBox; + BoxPtr pTopLeftBox; +{ +} + +Bool +PclDisplayCursor( pScreen, pCursor ) + ScreenPtr pScreen; + CursorPtr pCursor; +{ + return True; +} + +Bool +PclRealizeCursor( pScreen, pCursor ) + ScreenPtr pScreen; + CursorPtr pCursor; +{ + return True; +} + +Bool +PclUnrealizeCursor( pScreen, pCursor ) + ScreenPtr pScreen; + CursorPtr pCursor; +{ + return True; +} + +void +PclRecolorCursor( pScreen, pCursor, displayed ) + ScreenPtr pScreen; + CursorPtr pCursor; + Bool displayed; +{ +} + +Bool +PclSetCursorPosition( pScreen, x, y, generateEvent ) + ScreenPtr pScreen; + int x; + int y; + Bool generateEvent; +{ + return True; +} diff --git a/Xprint/pcl/PclDef.h b/Xprint/pcl/PclDef.h new file mode 100644 index 000000000..2638748b2 --- /dev/null +++ b/Xprint/pcl/PclDef.h @@ -0,0 +1,64 @@ +/* $Xorg: PclDef.h,v 1.3 2000/08/17 19:48:08 cpqbld Exp $ */ +/******************************************************************* +** +** ********************************************************* +** * +** * File: PclDef.h +** * +** * Contents: extran defines and includes for the Pcl driver +** * for a printing X server. +** * +** * Created: 7/31/95 +** * +** ********************************************************* +** +********************************************************************/ +/* +(c) Copyright 1996 Hewlett-Packard Company +(c) Copyright 1996 International Business Machines Corp. +(c) Copyright 1996 Sun Microsystems, Inc. +(c) Copyright 1996 Novell, Inc. +(c) Copyright 1996 Digital Equipment Corp. +(c) Copyright 1996 Fujitsu Limited +(c) Copyright 1996 Hitachi, Ltd. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the names of the copyright holders shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from said +copyright holders. +*/ + +#ifndef _PCLDEF_H_ +#define _PCLDEF_H_ + +#define DT_PRINT_JOB_HEADER "DT_PRINT_JOB_HEADER" +#define DT_PRINT_JOB_TRAILER "DT_PRINT_JOB_TRAILER" +#define DT_PRINT_JOB_COMMAND "DT_PRINT_JOB_COMMAND" +#define DT_PRINT_JOB_EXEC_COMMAND "DT_PRINT_JOB_EXEC_COMMAND" +#define DT_PRINT_JOB_EXEC_OPTIONS "DT_PRINT_JOB_EXEC_OPTION" +#define DT_PRINT_PAGE_HEADER "DT_PRINT_PAGE_HEADER" +#define DT_PRINT_PAGE_TRAILER "DT_PRINT_PAGE_TRAILER" +#define DT_PRINT_PAGE_COMMAND "DT_PRINT_PAGE_COMMAND" + +#define DT_IN_FILE_STRING "%(InFile)%" +#define DT_OUT_FILE_STRING "%(OutFile)%" +#define DT_ALLOWED_COMMANDS_FILE "printCommands" + +#endif /* _PCLDEF_H_ */ diff --git a/Xprint/pcl/PclFonts.c b/Xprint/pcl/PclFonts.c new file mode 100644 index 000000000..ef4554a12 --- /dev/null +++ b/Xprint/pcl/PclFonts.c @@ -0,0 +1,69 @@ +/* $Xorg: PclFonts.c,v 1.3 2000/08/17 19:48:08 cpqbld Exp $ */ +/******************************************************************* +** +** ********************************************************* +** * +** * File: PclFonts.c +** * +** * Contents: +** * Font code for Pcl driver. +** * +** * Created: 2/03/95 +** * +** ********************************************************* +** +********************************************************************/ +/* +(c) Copyright 1996 Hewlett-Packard Company +(c) Copyright 1996 International Business Machines Corp. +(c) Copyright 1996 Sun Microsystems, Inc. +(c) Copyright 1996 Novell, Inc. +(c) Copyright 1996 Digital Equipment Corp. +(c) Copyright 1996 Fujitsu Limited +(c) Copyright 1996 Hitachi, Ltd. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the names of the copyright holders shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from said +copyright holders. +*/ + +#include "miscstruct.h" +#include "fontstruct.h" +#include "dixfontstr.h" +#include "scrnintstr.h" + +#include "Pcl.h" + +Bool +PclRealizeFont( + ScreenPtr pscr, + FontPtr pFont) +{ + return TRUE; +} + +Bool +PclUnrealizeFont( + ScreenPtr pscr, + FontPtr pFont) +{ + return TRUE; +} diff --git a/Xprint/pcl/PclGC.c b/Xprint/pcl/PclGC.c new file mode 100644 index 000000000..7f0039e1f --- /dev/null +++ b/Xprint/pcl/PclGC.c @@ -0,0 +1,1064 @@ +/* $Xorg: PclGC.c,v 1.4 2000/08/17 19:48:08 cpqbld Exp $ */ +/******************************************************************* +** +** ********************************************************* +** * +** * File: PclGC.c +** * +** * Contents: +** * Graphics Context handling for the PCL driver +** * +** * Created: 10/11/95 +** * +** ********************************************************* +** +********************************************************************/ +/* +(c) Copyright 1996 Hewlett-Packard Company +(c) Copyright 1996 International Business Machines Corp. +(c) Copyright 1996 Sun Microsystems, Inc. +(c) Copyright 1996 Novell, Inc. +(c) Copyright 1996 Digital Equipment Corp. +(c) Copyright 1996 Fujitsu Limited +(c) Copyright 1996 Hitachi, Ltd. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the names of the copyright holders shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from said +copyright holders. +*/ + +#include "gcstruct.h" + +#include "Pcl.h" +#include "pixmapstr.h" +#include "colormapst.h" +#include "windowstr.h" +#include "migc.h" +#include "scrnintstr.h" +#include "resource.h" + +static GCOps PclGCOps = +{ + PclFillSpans, + PclSetSpans, + PclPutImage, + PclCopyArea, + PclCopyPlane, + PclPolyPoint, + PclPolyLine, + PclPolySegment, + PclPolyRectangle, + PclPolyArc, + PclFillPolygon, + PclPolyFillRect, + PclPolyFillArc, + PclPolyText8, + PclPolyText16, + PclImageText8, + PclImageText16, + PclImageGlyphBlt, + PclPolyGlyphBlt, + PclPushPixels +#ifdef NEED_LINEHELPER + ,NULL +#endif +} +; + + +static GCFuncs PclGCFuncs = +{ + PclValidateGC, + miChangeGC, + miCopyGC, + PclDestroyGC, + miChangeClip, + miDestroyClip, + miCopyClip, +} +; + +Bool +PclCreateGC( pGC ) + GCPtr pGC; +{ + PclGCPrivPtr pPriv = pGC->devPrivates[PclGCPrivateIndex].ptr; + + if( pGC->depth == 1 ) + { + if( mfbCreateGC( pGC ) == FALSE ) + return FALSE; + } + else if( pGC->depth <= 32 ) + { +#if PSZ == 8 + if( cfbCreateGC( pGC ) == FALSE ) +#else + if( cfb32CreateGC( pGC ) == FALSE ) +#endif + return FALSE; + } + else + return FALSE; + + pGC->clientClip = NULL; + pGC->clientClipType = CT_NONE; + + pGC->ops = &PclGCOps; + pGC->funcs = &PclGCFuncs; + + pPriv->pCompositeClip = NULL; + pPriv->freeCompClip = FALSE; + + return TRUE; +} + +void +PclDestroyGC(GCPtr pGC) +{ + PclGCPrivPtr pPriv = pGC->devPrivates[PclGCPrivateIndex].ptr; + extern int mfbGCPrivateIndex; + + /* Handle the mfb and cfb, which share a GC private struct */ + miRegisterGCPrivateIndex( mfbGCPrivateIndex ); + miDestroyGC( pGC ); + + if( pPriv->freeCompClip == TRUE ) + REGION_DESTROY( pGC->pScreen, pPriv->pCompositeClip ); +} + + +int +PclGetDrawablePrivateStuff( pDrawable, gc, valid, file ) + DrawablePtr pDrawable; + GC *gc; + unsigned long *valid; + FILE **file; +{ + XpContextPtr pCon; + PclPixmapPrivPtr pPriv; + PclContextPrivPtr cPriv; + + switch( pDrawable->type ) + { + case DRAWABLE_PIXMAP: + /* + * If we ever get here, something is wrong. + */ + return FALSE; + + case DRAWABLE_WINDOW: + pCon = PclGetContextFromWindow( (WindowPtr)pDrawable ); + + if( pCon == NULL ) + return FALSE; + else + { + cPriv = pCon->devPrivates[PclContextPrivateIndex].ptr; + *gc = cPriv->lastGC; + *valid = cPriv->validGC; + *file = cPriv->pPageFile; + return TRUE; + } + + default: + return FALSE; + } +} + +void +PclSetDrawablePrivateGC( pDrawable, gc ) + DrawablePtr pDrawable; + GC gc; +{ + PixmapPtr pix; + XpContextPtr pCon; + PclPixmapPrivPtr pixPriv; + PclContextPrivPtr pPriv; + int i; + + switch( pDrawable->type ) + { + case DRAWABLE_PIXMAP: + pix = (PixmapPtr)pDrawable; + pixPriv = pix->devPrivates[PclPixmapPrivateIndex].ptr; + + pixPriv->lastGC = gc; + pixPriv->validGC = 1; + break; + + case DRAWABLE_WINDOW: + pCon = PclGetContextFromWindow( (WindowPtr)pDrawable ); + pPriv = ((PclContextPrivPtr) + (pCon->devPrivates[PclContextPrivateIndex].ptr)); + + pPriv->validGC = 1; + pPriv->lastGC = gc; + + /* + * Store the dash list separately, to avoid having it freed + * out from under us. + */ + if( pPriv->dash != NULL ) + xfree( pPriv->dash ); + if( gc.numInDashList != 0 ) + { + pPriv->dash = (unsigned char *)xalloc( sizeof( unsigned char ) + * gc.numInDashList ); + for( i = 0; i < gc.numInDashList; i++ ) + pPriv->dash[i] = gc.dash[i]; + } + else + pPriv->dash = NULL; + + + /* + * Store the dash list separately, to avoid having it freed + * out from under us. + */ + if( pPriv->dash != NULL ) + xfree( pPriv->dash ); + if( gc.numInDashList != 0 ) + { + pPriv->dash = (unsigned char *)xalloc( sizeof( unsigned char ) + * gc.numInDashList ); + for( i = 0; i < gc.numInDashList; i++ ) + pPriv->dash[i] = gc.dash[i]; + } + else + pPriv->dash = NULL; + + break; + } +} + +static void +PclSendPattern(char *bits, + int sz, + int depth, + int h, + int w, + int patNum, + FILE *outFile) +{ + char t[80], *row, *mod; + int w2; + int i, j; + + SEND_PCL( outFile, "\033%0A" ); + + if( depth == 1 ) + { + /* Each row must be word-aligned */ + w2 = ( w / 8 ) + ( ( w%8 ) ? 1 : 0 ); +/* + if( w2 % 2 ) + w2++; +*/ + + sprintf( t, "\033*c%dg%dW", patNum, h * w2 + 8 ); + SEND_PCL( outFile, t ); + + sprintf( t, "%c%c%c%c%c%c%c%c", 0, 0, 1, 0, h>>8, h&0xff, w>>8, + w&0xff ); + SEND_PCL_COUNT( outFile, t, 8 ); + + for( row = bits, i = 0; i < h; i++, row += BitmapBytePad( w ) ) + SEND_PCL_COUNT( outFile, row, w2 ); + } + else if( depth == 8 ) + { + w2 = ( w % 2 ) ? w + 1 : w; + + sprintf( t, "\033*c%dg%dW", patNum, h * w2 + 8 ); + SEND_PCL( outFile, t ); + + sprintf( t, "%c%c%c%c%c%c%c%c", 1, 0, 8, 0, h>>8, h&0xff, + w>>8, w&0xff ); + SEND_PCL_COUNT( outFile, t, 8 ); + + for( row = bits, i = 0; i < h; i++, + row += PixmapBytePad( w, 8 ) ) + SEND_PCL_COUNT( outFile, row, w2 ); + } + else + { + w2 = ( w % 2 ) ? w + 1 : w; + + sprintf( t, "\033*c%dg%dW", patNum, h * w2 + 8 ); + SEND_PCL( outFile, t ); + + sprintf( t, "%c%c%c%c%c%c%c%c", 1, 0, 8, 0, h>>8, h&0xff, + w>>8, w&0xff ); + SEND_PCL_COUNT( outFile, t, 8 ); + + mod = (char *)xalloc( w2 ); + + for( row = bits, i = 0; i < h; i++, + row += PixmapBytePad( w, 24 ) ) + { + char r, g, b; + for( j = 0; j < w2; j++ ) { + r = ((row[j*4+1] >> 5) & 0x7) << 5; + g = ((row[j*4+2] >> 5) & 0x7) << 2; + b = ((row[j*4+3] >> 6) & 0x3); + mod[j] = r | g | b; + } + SEND_PCL_COUNT( outFile, mod, w2 ); + } + + xfree( mod ); + } + + SEND_PCL( outFile, "\033%0B" ); +} + +int +PclUpdateDrawableGC( pGC, pDrawable, outFile ) + GCPtr pGC; + DrawablePtr pDrawable; + FILE **outFile; +{ + Mask drawableMask, changeMask = 0; + GC dGC; + unsigned long valid; + int i; + XpContextPtr pCon; + PclContextPrivPtr cPriv; + Colormap c; + ColormapPtr cmap; + PclGCPrivPtr gcPriv = (PclGCPrivPtr) + (pGC->devPrivates[PclGCPrivateIndex].ptr); + + if( !PclGetDrawablePrivateStuff( pDrawable, &dGC, &valid, outFile ) ) + return FALSE; + + pCon = PclGetContextFromWindow( (WindowPtr)pDrawable ); + cPriv = pCon->devPrivates[PclContextPrivateIndex].ptr; + + /* + * Here's where we update the colormap. Since there can be + * different colormaps installed on each window, we need to check + * before each drawing request that the correct palette is active in + * the printer. This is as good a place as any. + */ + if( !PclUpdateColormap( pDrawable, pCon, pGC, *outFile ) ) + return FALSE; + + /* + * If the drawable's last GC is NULL, this means that this is + * the first time the drawable is being used. Therefore, we need + * to emit PCL for all the GC fields. + */ + if( valid == 0 ) + changeMask = ~0; + + /* + * If we have two different GC structures, there is no alternative + * but to scan through them both to determine the changeMask. + */ + else + { + if( dGC.alu != pGC->alu ) + changeMask |= GCFunction; + if( dGC.fgPixel != pGC->fgPixel ) + changeMask |= GCForeground; + if( dGC.bgPixel != pGC->bgPixel ) + changeMask |= GCBackground; + if( dGC.lineWidth != pGC->lineWidth ) + changeMask |= GCLineWidth; + if( dGC.lineStyle != pGC->lineStyle ) + changeMask |= GCLineStyle; + if( dGC.capStyle != pGC->capStyle ) + changeMask |= GCCapStyle; + if( dGC.joinStyle != pGC->joinStyle ) + changeMask |= GCJoinStyle; + if( dGC.fillStyle != pGC->fillStyle ) + changeMask |= GCFillStyle; + if( dGC.tile.pixmap != pGC->tile.pixmap ) + changeMask |= GCTile; + if( dGC.stipple != pGC->stipple ) + changeMask |= GCStipple; + if( dGC.patOrg.x != pGC->patOrg.x ) + changeMask |= GCTileStipXOrigin; + if( dGC.patOrg.y != pGC->patOrg.y ) + changeMask |= GCTileStipYOrigin; + + if( dGC.numInDashList == pGC->numInDashList ) + for( i = 0; i < dGC.numInDashList; i++ ) + if( cPriv->dash[i] != pGC->dash[i] ) + { + changeMask |= GCDashList; + break; + } + else + changeMask |= GCDashList; + } + + /* + * Once the changeMask has been determined, we scan it and emit + * the appropriate PCL code to set the drawing attributes. + */ + + /* Must be in HP-GL/2 mode to set attributes */ + SEND_PCL( *outFile, "\033%0B" ); + + if( changeMask & GCFunction ) + { +#ifdef XP_PCL_COLOR + + if( pGC->alu == GXclear ) + SEND_PCL( *outFile, "SP0;" ); + else + SEND_PCL( *outFile, "SP1;" ); +#else + if( pGC->alu == GXclear ) + SEND_PCL( *outFile, "SP0;" ); + else + SEND_PCL( *outFile, "SP1;" ); +#endif /* XP_PCL_COLOR */ + } + +#if 0 + if( changeMask & GCFunction ) + { + int rop = -1; + char t[10]; + + switch( pGC->alu ) + { + case GXclear: + rop = 1; + break; + case GXand: + rop = 136; + break; + case GXandReverse: + rop = 68; + break; + case GXcopy: + rop = 204; + break; + case GXandInverted: + rop = 34; + break; + case GXnoop: + rop = 170; + break; + case GXxor: + rop = 238; + break; + case GXor: + rop = 238; + break; + case GXnor: + rop = 17; + break; + case GXequiv: + rop = 153; + break; + case GXinvert: + rop = 85; + break; + case GXorReverse: + rop = 221; + break; + case GXcopyInverted: + rop = 51; + break; + case GXorInverted: + rop = 187; + break; + case GXnand: + rop = 119; + break; + case GXset: + rop = 0; + break; + } + if( rop != -1 ) + { + sprintf( t, "MC1,%d;", rop ); + SEND_PCL( *outFile, t ); +#endif + + if( changeMask & GCForeground ) + switch( pGC->fgPixel ) + { + case 1: + SEND_PCL( *outFile, "SP1;" ); + break; + default: + SEND_PCL( *outFile, "SP0;" ); + break; + } + + if( changeMask & GCForeground ) + { + char t[40]; + +#ifdef XP_PCL_COLOR + c = wColormap( ((WindowPtr)pDrawable) ); + cmap = (ColormapPtr)LookupIDByType( c, RT_COLORMAP ); + + if( cmap->class == TrueColor ) + { + if( pGC->fillStyle != FillTiled || pGC->tileIsPixel ) { + unsigned short r, g, b; + + r = (pGC->fgPixel & cmap->pVisual->redMask) + >> (cmap->pVisual->offsetRed ); + g = (pGC->fgPixel & cmap->pVisual->greenMask) + >> (cmap->pVisual->offsetGreen); + b = (pGC->fgPixel & cmap->pVisual->blueMask) + >> (cmap->pVisual->offsetBlue); + + PclLookUp(cmap, cPriv, &r, &g, &b); + sprintf( t, "\033%%0A\033*v%ua%ub%uc0I\033%%0B", r, g, b); + SEND_PCL( *outFile, t ); + } + } + else /* PseudoColor or StaticGray */ + { + sprintf( t, "SP%d;", pGC->fgPixel ); + SEND_PCL( *outFile, t ); + } +#else + ScreenPtr screen; + screen = pDrawable->pScreen; + if ( pGC->fgPixel == screen->whitePixel ) + SEND_PCL( *outFile, "SP0;"); + else + SEND_PCL( *outFile, "SP1;"); +#endif /* XP_PCL_COLOR */ + } + + if( changeMask & GCJoinStyle ) + switch( pGC->joinStyle ) + { + case JoinMiter: + SEND_PCL( *outFile, "LA2,1;" ); + break; + case JoinRound: + SEND_PCL( *outFile, "LA2,4;" ); + break; + case JoinBevel: + SEND_PCL( *outFile, "LA2,5;" ); + break; + } + + if( changeMask & GCCapStyle ) + switch( pGC->capStyle ) + { + case CapNotLast: + case CapButt: + SEND_PCL( *outFile, "LA1,1;" ); + break; + case CapRound: + SEND_PCL( *outFile, "LA1,4;" ); + break; + case CapProjecting: + SEND_PCL( *outFile, "LA1,2;" ); + break; + } + + if( changeMask & GCLineWidth ) + { + float penWidth, pixelsPerMM; + ScreenPtr screen; + char temp[30]; + + if( pGC->lineWidth == 0 || pGC->lineWidth == 1 ) + /* A pen width of 0.0 mm gives a one-pixel-wide line */ + penWidth = 0.0; + else + { + screen = pDrawable->pScreen; + pixelsPerMM = (float)screen->width / (float)screen->mmWidth; + + penWidth = pGC->lineWidth / pixelsPerMM; + } + sprintf( temp, "PW%g;", penWidth ); + SEND_PCL( *outFile, temp ); + } + + if( changeMask & GCLineStyle ) + { + int i, num = pGC->numInDashList; + double total; + char t[30]; + + switch( pGC->lineStyle ) + { + case LineSolid: + SEND_PCL( *outFile, "LT;" ); + break; + case LineOnOffDash: + /* + * Calculate the pattern length of the dashes, in pixels, + * then convert to mm + */ + for( i = 0, total = 0.0; i < 20 && i < num; i++ ) + total += pGC->dash[i]; + if( num % 2 ) + for( i = num; i < 20 && i < num + num; i++ ) + total += pGC->dash[i-num]; + + total *= ( (double)pDrawable->pScreen->mmWidth / + (double)pDrawable->pScreen->width ); + + sprintf( t, "LT8,%f,1;", total ); + SEND_PCL( *outFile, t ); + break; + } + } + + + if( changeMask & GCFillStyle ) + switch( pGC->fillStyle ) + { + case FillSolid: + SEND_PCL( *outFile, "FT1;TR0;CF;" ); + break; + case FillTiled: + SEND_PCL( *outFile, "FT22,100;TR0;CF2,0;" ); + break; + case FillOpaqueStippled: + SEND_PCL( *outFile, "FT22,101;TR0;CF2,0;" ); + if( pGC->fgPixel != gcPriv->stippleFg || + pGC->bgPixel != gcPriv->stippleBg ) + changeMask |= GCStipple; + break; + case FillStippled: + SEND_PCL( *outFile, "FT22,102;TR1;CF2,0;" ); + break; + } + + if( changeMask & GCTile && !pGC->tileIsPixel ) + { + char t[80], *bits, *row, *mod; + int h, w, w2, sz; + int i, j; + + h = pGC->tile.pixmap->drawable.height; + w = pGC->tile.pixmap->drawable.width; + + if( pGC->tile.pixmap->drawable.depth == 1 ) + { + sz = h * BitmapBytePad( w ); + + bits = (char *)xalloc( sz ); + mfbGetImage(pGC->tile.pixmap, 0, 0, w, h, XYPixmap, ~0, bits); + PclSendPattern( bits, sz, 1, h, w, 100, *outFile ); + xfree( bits ); + } + else if( pGC->tile.pixmap->drawable.depth == 8 ) + { + sz = h * PixmapBytePad( w, 8 ); + bits = (char *)xalloc( sz ); + cfbGetImage(pGC->tile.pixmap, 0, 0, w, h, ZPixmap, ~0, bits); + PclSendPattern( bits, sz, 8, h, w, 100, *outFile ); + xfree( bits ); + } +#if PSZ == 32 + else + { + sz = h * PixmapBytePad( w, 24 ); + + bits = (char *)xalloc( sz ); + cfb32GetImage(pGC->tile.pixmap, 0, 0, w, h, ZPixmap, ~0, bits); + PclSendPattern( bits, sz, 24, h, w, 100, *outFile ); + xfree( bits ); + } +#endif + } + + if( changeMask & ( GCTileStipXOrigin | GCTileStipYOrigin ) ) + { + char t[30]; + + sprintf( t, "AC%d,%d;", pGC->patOrg.x, pGC->patOrg.y ); + SEND_PCL( *outFile, t ); + } + + /* + * We have to resend the stipple pattern either when the stipple itself + * changes, or if we're in FillOpaqueStippled mode and either the + * foreground or the background color changes. + */ + if( changeMask & GCStipple || + ( pGC->fillStyle == FillOpaqueStippled && + ( pGC->fgPixel != gcPriv->stippleFg || + pGC->bgPixel != gcPriv->stippleBg ) ) ) + { + int h, w, i, sz, w2; + char *bits, *row, t[30]; + PixmapPtr scratchPix; + GCPtr scratchGC; + + if( pGC->stipple != NULL ) + { + SEND_PCL( *outFile, "\033%0A" ); + + h = pGC->stipple->drawable.height; + w = pGC->stipple->drawable.width; + sz = h * BitmapBytePad( w ); + + bits = (char *)xalloc( sz ); + mfbGetImage( pGC->stipple, 0, 0, w, h, XYPixmap, ~0, bits ); + + w2 = ( w / 8 ) + ( ( w%8 ) ? 1 : 0 ); + /* + * XXX The PCL docs say that I need to word-align each + * XXX row, but I get garbage when I do... + */ + /* + if( w2 % 2 ) + w2++; + */ + + sprintf( t, "\033*c102g%dW", h * w2 + 8 ); + SEND_PCL( *outFile, t ); + + sprintf( t, "%c%c%c%c%c%c%c%c", 0, 0, 1, 0, h>>8, h&0xff, w>>8, + w&0xff ); + SEND_PCL_COUNT( *outFile, t, 8 ); + + for( row = bits, i = 0; i < h; i++, row += BitmapBytePad( w ) ) + SEND_PCL_COUNT( *outFile, row, w2 ); + + SEND_PCL( *outFile, "\033%0B" ); + + xfree( bits ); + + /* + * Also do the opaque stipple, as a tile + */ + if( pGC->depth != 1 ) + sz = h * PixmapBytePad( w, pGC->depth ); + bits = (char *)xalloc( sz ); + + scratchPix = + (*pGC->pScreen->CreatePixmap)( pGC->pScreen, + w, h, pGC->depth ); + scratchGC = GetScratchGC( pGC->depth, pGC->pScreen ); + CopyGC( pGC, scratchGC, ~0L ); + + if( pGC->depth == 1 ) + { + mfbValidateGC( scratchGC, ~0L, + (DrawablePtr)scratchPix ); + mfbCopyPlane( pGC->stipple, + (DrawablePtr)scratchPix, scratchGC, 0, + 0, w, h, 0, 0, 1 ); + mfbGetImage( scratchPix, 0, 0, w, h, XYPixmap, ~0, + bits ); + } + else if( pGC->depth <= 32 ) + { +#if PSZ == 8 + cfbValidateGC( scratchGC, ~0L, + (DrawablePtr)scratchPix ); + cfbCopyPlane( pGC->stipple, + (DrawablePtr)scratchPix, scratchGC, 0, + 0, w, h, 0, 0, 1 ); + cfbGetImage( scratchPix, 0, 0, w, h, ZPixmap, ~0, + bits ); +#else + cfb32ValidateGC( scratchGC, ~0L, + (DrawablePtr)scratchPix ); + cfb32CopyPlane( pGC->stipple, + (DrawablePtr)scratchPix, scratchGC, 0, + 0, w, h, 0, 0, 1 ); + cfb32GetImage( scratchPix, 0, 0, w, h, ZPixmap, ~0, + bits ); +#endif + } + PclSendPattern( bits, sz, pGC->depth, h, w, 101, *outFile ); + FreeScratchGC( scratchGC ); + (*pGC->pScreen->DestroyPixmap)( scratchPix ); + xfree( bits ); + } + } + + if( changeMask & ( GCTileStipXOrigin | GCTileStipYOrigin ) ) + { + char t[30]; + + sprintf( t, "AC%d,%d;", pGC->patOrg.x, pGC->patOrg.y ); + SEND_PCL( *outFile, t ); + } + + if( changeMask & GCDashList ) + { + int num = pGC->numInDashList; + double total; + char dashes[20]; + char t[100], t2[20]; + + /* Make up the doubled dash list, if necessary */ + for( i = 0; i < 20 && i < num; i++ ) + dashes[i] = pGC->dash[i]; + + if( num % 2 ) + { + for( i = num; i < 20 && i < num + num; i++ ) + dashes[i] = dashes[i-num]; + if( ( num *= 2 ) > 20 ) + num = 20; + } + + /* Add up dash lengths to get percentage */ + for( i = 0, total = 0; i < num; i++ ) + total += dashes[i]; + + /* Build up the HP-GL/2 for the dash list */ + strcpy( t, "UL8" ); + for( i = 0; i < num; i++ ) + { + sprintf( t2, ",%d", + (int)( ( (double)dashes[i] / total * 100.0 ) + 0.5 ) ); + strcat( t, t2 ); + } + strcat( t, ";" ); + SEND_PCL( *outFile, t ); + } + + + /* Go back to PCL mode */ + SEND_PCL( *outFile, "\033%0A" ); + + /* + * Update the drawable's private information, which includes + * erasing the drawable's private changeMask, since all the + * changes have been made. + */ + if( changeMask ) + PclSetDrawablePrivateGC( pDrawable, *pGC ); + + return TRUE; +} + +/* + * PclComputeCompositeClip() + * + * I'd like to use the miComputeCompositeClip function, but it sticks + * things into the mi GC privates, where the PCL driver can't get at + * it. So, rather than mess around with the mi code, I ripped it out + * and made the appropriate changes here. + */ + + +void +PclComputeCompositeClip(pGC, pDrawable) + GCPtr pGC; + DrawablePtr pDrawable; +{ + ScreenPtr pScreen = pGC->pScreen; + PclGCPrivPtr devPriv = (PclGCPrivPtr) + (pGC->devPrivates[PclGCPrivateIndex].ptr); + + if (pDrawable->type == DRAWABLE_WINDOW) + { + WindowPtr pWin = (WindowPtr) pDrawable; + RegionPtr pregWin; + Bool freeTmpClip, freeCompClip; + + if (pGC->subWindowMode == IncludeInferiors) + { + pregWin = NotClippedByChildren(pWin); + freeTmpClip = TRUE; + } + else + { + pregWin = &pWin->clipList; + freeTmpClip = FALSE; + } + freeCompClip = devPriv->freeCompClip; + + /* + * if there is no client clip, we can get by with just keeping the + * pointer we got, and remembering whether or not should destroy (or + * maybe re-use) it later. this way, we avoid unnecessary copying of + * regions. (this wins especially if many clients clip by children + * and have no client clip.) + */ + if (pGC->clientClipType == CT_NONE) + { + if (freeCompClip) + REGION_DESTROY(pScreen, devPriv->pCompositeClip); + devPriv->pCompositeClip = pregWin; + devPriv->freeCompClip = freeTmpClip; + } + else + { + /* + * we need one 'real' region to put into the composite clip. if + * pregWin the current composite clip are real, we can get rid of + * one. if pregWin is real and the current composite clip isn't, + * use pregWin for the composite clip. if the current composite + * clip is real and pregWin isn't, use the current composite + * clip. if neither is real, create a new region. + */ + + REGION_TRANSLATE(pScreen, pGC->clientClip, + pDrawable->x + pGC->clipOrg.x, + pDrawable->y + pGC->clipOrg.y); + + if (freeCompClip) + { + REGION_INTERSECT(pGC->pScreen, devPriv->pCompositeClip, + pregWin, pGC->clientClip); + if (freeTmpClip) + REGION_DESTROY(pScreen, pregWin); + } + else if (freeTmpClip) + { + REGION_INTERSECT(pScreen, pregWin, pregWin, pGC->clientClip); + devPriv->pCompositeClip = pregWin; + } + else + { + devPriv->pCompositeClip = REGION_CREATE(pScreen, NullBox, 0); + REGION_INTERSECT(pScreen, devPriv->pCompositeClip, + pregWin, pGC->clientClip); + } + devPriv->freeCompClip = TRUE; + REGION_TRANSLATE(pScreen, pGC->clientClip, + -(pDrawable->x + pGC->clipOrg.x), + -(pDrawable->y + pGC->clipOrg.y)); + } + } /* end of composite clip for a window */ + else + { + BoxRec pixbounds; + + /* XXX should we translate by drawable.x/y here ? */ + pixbounds.x1 = 0; + pixbounds.y1 = 0; + pixbounds.x2 = pDrawable->width; + pixbounds.y2 = pDrawable->height; + + if (devPriv->freeCompClip) + { + REGION_RESET(pScreen, devPriv->pCompositeClip, &pixbounds); + } + else + { + devPriv->freeCompClip = TRUE; + devPriv->pCompositeClip = REGION_CREATE(pScreen, &pixbounds, 1); + } + + if (pGC->clientClipType == CT_REGION) + { + REGION_TRANSLATE(pScreen, devPriv->pCompositeClip, + -pGC->clipOrg.x, -pGC->clipOrg.y); + REGION_INTERSECT(pScreen, devPriv->pCompositeClip, + devPriv->pCompositeClip, pGC->clientClip); + REGION_TRANSLATE(pScreen, devPriv->pCompositeClip, + pGC->clipOrg.x, pGC->clipOrg.y); + } + } /* end of composite clip for pixmap */ +} + +/* + * PclValidateGC() + * + * Unlike many screen GCValidate routines, this function should not need + * to mess with setting the drawing functions. Different drawing + * functions are usually needed to optimize such things as drawing + * wide or dashed lines; this functionality will be handled primarily + * by the printer itself, while the necessary PCL code to set the + * attributes will be done in PclUpdateDrawableGC(). + */ + +/*ARGSUSED*/ +void +PclValidateGC( pGC, changes, pDrawable ) + GCPtr pGC; + Mask changes; + DrawablePtr pDrawable; +{ + XpContextPtr pCon; + PclContextPrivPtr pConPriv; + extern int mfbGCPrivateIndex; + extern int cfbGCPrivateIndex; + + /* + * Pixmaps should be handled by their respective validation + * functions. + */ + if( pDrawable->type == DRAWABLE_PIXMAP ) + { + if( pDrawable->depth == 1 ) + { + miRegisterGCPrivateIndex( mfbGCPrivateIndex ); + mfbValidateGC( pGC, ~0, pDrawable ); + } + else if( pDrawable->depth <= 32 ) + { +#if PSZ == 8 + miRegisterGCPrivateIndex( cfbGCPrivateIndex ); + cfbValidateGC( pGC, ~0, pDrawable ); +#else + miRegisterGCPrivateIndex( cfbGCPrivateIndex ); + cfb32ValidateGC( pGC, ~0, pDrawable ); +#endif + } + return; + } + + /* + * Reset the drawing operations + */ + pGC->ops = &PclGCOps; + + /* + * Validate the information, and correct it if necessary. + */ + + /* + * If necessary, compute the composite clip region. (Code ripped + * from migc.c) + */ + if ((changes & (GCClipXOrigin|GCClipYOrigin|GCClipMask|GCSubwindowMode)) || + (pDrawable->serialNumber != (pGC->serialNumber & DRAWABLE_SERIAL_BITS)) + ) + { + PclComputeCompositeClip(pGC, pDrawable); + } + + /* + * PCL does not directly support the DoubleDash line style, nor is + * there an easy way to simulate it, so we'll just change it to a + * LineOnOffDash, which is supported by PCL. + */ + if( ( changes & GCLineStyle ) && ( pGC->lineStyle == LineDoubleDash ) ) + pGC->lineStyle = LineOnOffDash; + + /* + * Update the drawable's changeMask to reflect the changes made to the GC. + */ +/* + PclSetDrawablePrivateGC( pDrawable, *pGC, changes ); +*/ +} + diff --git a/Xprint/pcl/PclInit.c b/Xprint/pcl/PclInit.c new file mode 100644 index 000000000..791a33dfe --- /dev/null +++ b/Xprint/pcl/PclInit.c @@ -0,0 +1,658 @@ +/* $Xorg: PclInit.c,v 1.3 2000/08/17 19:48:08 cpqbld Exp $ */ +/******************************************************************* +** +** ********************************************************* +** * +** * File: PclInit.c +** * +** * Contents: +** * Initialization code of Pcl driver for the print server. +** * +** * Created: 1/30/95 +** * +** ********************************************************* +** +********************************************************************/ +/* +(c) Copyright 1996 Hewlett-Packard Company +(c) Copyright 1996 International Business Machines Corp. +(c) Copyright 1996 Sun Microsystems, Inc. +(c) Copyright 1996 Novell, Inc. +(c) Copyright 1996 Digital Equipment Corp. +(c) Copyright 1996 Fujitsu Limited +(c) Copyright 1996 Hitachi, Ltd. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the names of the copyright holders shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from said +copyright holders. +*/ + +/* +(c) Copyright 1996 Hewlett-Packard Company +(c) Copyright 1996 International Business Machines Corp. +(c) Copyright 1996 Sun Microsystems, Inc. +(c) Copyright 1996 Novell, Inc. +(c) Copyright 1996 Digital Equipment Corp. +(c) Copyright 1996 Fujitsu Limited +(c) Copyright 1996 Hitachi, Ltd. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the names of the copyright holders shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from said +copyright holders. +*/ + +#include <stdio.h> +#include <string.h> +#include <sys/wait.h> + +#include "Pcl.h" +#include "AttrValid.h" + +#include "cfb.h" + +#include "attributes.h" +#include "windowstr.h" + +#define MODELDIRNAME "/models" +extern char *XpGetConfigDir(); + +static void AllocatePclPrivates( + ScreenPtr pScreen); +static int PclInitContext(XpContextPtr pCon); + +extern Bool _XpBoolNoop(); +extern void _XpVoidNoop(); + +extern unsigned char *PclReadMap(char *, int *); + +int PclScreenPrivateIndex; +int PclContextPrivateIndex; +int PclPixmapPrivateIndex; +int PclWindowPrivateIndex; +int PclGCPrivateIndex; + +#ifdef XP_PCL_COLOR +/* + * The supported visuals on this screen + */ +static VisualRec Visuals[] = +{ + { 1, StaticGray, 1, 2, 1, 0, 0, 0, 0, 0, 0 }, + { 2, PseudoColor, 8, 256, 8, 0, 0, 0, 0, 0, 0 }, + { 3, TrueColor, 8, 256, 24, 0xFF0000, 0xFF00, 0xFF, 16, 8, 0 } +}; + +/* + * The supported depths on this screen + */ +static DepthRec Depths[] = +{ + { 1, 1, NULL }, + { 8, 1, NULL }, + { 24, 1, NULL } +}; +#else +/* + * The supported visuals on this screen + */ +static VisualRec Visuals[] = +{ + { 1, StaticGray, 1, 2, 1, 0, 0, 0, 0, 0, 0} +}; + +/* + * The supported depths on this screen + */ +static DepthRec Depths[] = +{ + { 1, 1, NULL } +}; +#endif /* XP_PCL_COLOR */ + + +#define NUM_VISUALS(visuals) (sizeof(visuals) / sizeof(VisualRec)) +#define NUM_DEPTHS(depths) (sizeof(depths) / sizeof(DepthRec)) + +Bool +PclCloseScreen(int index, + ScreenPtr pScreen) +{ + Bool status = Success; + PclScreenPrivPtr pPriv = pScreen->devPrivates[PclScreenPrivateIndex].ptr; + +/* + if( pPriv->CloseScreen != (Bool (*)())NULL ) + { + pScreen->CloseScreen = pPriv->CloseScreen; + status = pScreen->CloseScreen( index, pScreen ); + pScreen->CloseScreen = PclCloseScreen; + } +*/ + + /* + * Finish cleaning up cfb (code taken from cfbCloseScreen) + */ +#ifdef XP_PCL_COLOR +#ifdef CFB_NEED_SCREEN_PRIVATE + xfree( pScreen->devPrivates[cfbScreenPrivateIndex].ptr ); +#else + xfree( pScreen->devPrivate ); +#endif +#endif + + xfree( pPriv ); + + return status; +} + +Bool +InitializePclDriver(ndx, pScreen, argc, argv) + int ndx; + ScreenPtr pScreen; + int argc; + char **argv; +{ + int maxRes, xRes, yRes, maxWidth, maxHeight, maxDim, numBytes; + int i; + PclScreenPrivPtr pPriv; + char **printerNames; + int numPrinters; + + /* + * Register this driver's InitContext function with the print + * extension. This is a bit sleazy, as the extension hasn't yet + * been initialized, but the extensionneeds to know this, and this + * seems the best time to provide the information. + */ +#ifdef XP_PCL_COLOR + XpRegisterInitFunc( pScreen, "XP-PCL-COLOR", PclInitContext ); +#elif XP_PCL_MONO + XpRegisterInitFunc( pScreen, "XP-PCL-MONO", PclInitContext ); +#else + XpRegisterInitFunc( pScreen, "XP-PCL-LJ3", PclInitContext ); +#endif /* XP_PCL_MONO */ + + /* + * Create and fill in the devPrivate for the PCL driver. + */ + AllocatePclPrivates(pScreen); + + pPriv = + (PclScreenPrivPtr)pScreen->devPrivates[PclScreenPrivateIndex].ptr; + + maxDim = MAX( pScreen->height, pScreen->width ); + xRes = pScreen->width / ( pScreen->mmWidth / 25.4 ); + yRes = pScreen->height / ( pScreen->mmHeight / 25.4 ); + maxRes = MAX( xRes, yRes ); + +#ifdef XP_PCL_COLOR + cfbScreenInit( pScreen, NULL, maxDim, maxDim, maxRes, maxRes, + maxRes ); + /* + * Clean up the fields that we stomp (code taken from cfbCloseScreen) + */ + for( i = 0; i < pScreen->numDepths; i++ ) + xfree( pScreen->allowedDepths[i].vids ); + xfree( pScreen->allowedDepths ); + xfree( pScreen->visuals ); +#else + mfbScreenInit( pScreen, NULL, maxDim, maxDim, maxRes, maxRes, + maxRes ); +#endif /* XP_PCL_COLOR */ + + pScreen->defColormap = FakeClientID(0); + pScreen->blackPixel = 1; + pScreen->whitePixel = 0; + +/* + pPriv->CloseScreen = pScreen->CloseScreen; +*/ + pScreen->CloseScreen = PclCloseScreen; + + pScreen->QueryBestSize = (QueryBestSizeProcPtr)PclQueryBestSize; + pScreen->SaveScreen = _XpBoolNoop; + pScreen->GetImage = _XpVoidNoop; + pScreen->GetSpans = _XpVoidNoop; + pScreen->CreateWindow = PclCreateWindow; + pScreen->DestroyWindow = PclDestroyWindow; +/* + pScreen->PositionWindow = PclPositionWindow; +*/ + pScreen->ChangeWindowAttributes = PclChangeWindowAttributes; +/* + pScreen->RealizeWindow = PclMapWindow; + pScreen->UnrealizeWindow = PclUnmapWindow; +*/ + pScreen->PaintWindowBackground = PclPaintWindow; + pScreen->PaintWindowBorder = PclPaintWindow; + pScreen->CopyWindow = PclCopyWindow; /* XXX Hard routine to write! */ + + pScreen->CreatePixmap = PclCreatePixmap; + pScreen->DestroyPixmap = PclDestroyPixmap; + pScreen->RealizeFont = PclRealizeFont; + pScreen->UnrealizeFont = PclUnrealizeFont; + pScreen->CreateGC = PclCreateGC; + + pScreen->CreateColormap = PclCreateColormap; + pScreen->DestroyColormap = PclDestroyColormap; + pScreen->InstallColormap = (InstallColormapProcPtr)NoopDDA; + pScreen->UninstallColormap = (UninstallColormapProcPtr)NoopDDA; + pScreen->ListInstalledColormaps = PclListInstalledColormaps; + pScreen->StoreColors = PclStoreColors; +/* + pScreen->ResolveColor = PclResolveColor; +*/ + + pScreen->BitmapToRegion = mfbPixmapToRegion; + + pScreen->ConstrainCursor = PclConstrainCursor; + pScreen->CursorLimits = PclCursorLimits; + pScreen->DisplayCursor = PclDisplayCursor; + pScreen->RealizeCursor = PclRealizeCursor; + pScreen->UnrealizeCursor = PclUnrealizeCursor; + pScreen->RecolorCursor = PclRecolorCursor; + pScreen->SetCursorPosition = PclSetCursorPosition; + + pScreen->visuals = Visuals; + pScreen->numVisuals = NUM_VISUALS( Visuals ); + pScreen->allowedDepths = Depths; + pScreen->numDepths = NUM_DEPTHS( Depths ); + + for( i = 0; i < NUM_DEPTHS( Depths ); i++ ) + { + pScreen->allowedDepths[i].vids = + (VisualID *)xalloc( sizeof(VisualID ) ); + pScreen->allowedDepths[i].vids[0] = i + 1; + } + +#ifdef XP_PCL_COLOR + pScreen->rootVisual = 2; + pScreen->rootDepth = 8; +#else + pScreen->rootVisual = 1; + pScreen->rootDepth = 1; +#endif /* XP_PCL_COLOR */ + + pPriv->colormaps = NULL; + PclCreateDefColormap( pScreen ); + + return TRUE; +} + +static void +AllocatePclPrivates( + ScreenPtr pScreen) +{ + static int PclGeneration = -1; + + if(PclGeneration != serverGeneration) + { + PclScreenPrivateIndex = AllocateScreenPrivateIndex(); + + PclWindowPrivateIndex = AllocateWindowPrivateIndex(); + AllocateWindowPrivate( pScreen, PclWindowPrivateIndex, + sizeof( PclWindowPrivRec ) ); + + PclContextPrivateIndex = XpAllocateContextPrivateIndex(); + XpAllocateContextPrivate( PclContextPrivateIndex, + sizeof( PclContextPrivRec ) ); + + PclGCPrivateIndex = AllocateGCPrivateIndex(); + AllocateGCPrivate( pScreen, PclGCPrivateIndex, + sizeof( PclGCPrivRec ) ); + + PclPixmapPrivateIndex = AllocatePixmapPrivateIndex(); + AllocatePixmapPrivate( pScreen, PclPixmapPrivateIndex, + sizeof( PclPixmapPrivRec ) ); + + PclGeneration = serverGeneration; + } + + pScreen->devPrivates[PclScreenPrivateIndex].ptr = (pointer)xalloc( + sizeof(PclScreenPrivRec)); +} + +/* + * PclInitContext + * + * Establish the appropriate values for a PrintContext used with the PCL + * driver. + */ + +static char DOC_ATT_SUPP[]="document-attributes-supported"; +static char DOC_ATT_VAL[]="document-format"; +static char JOB_ATT_SUPP[]="job-attributes-supported"; +static char JOB_ATT_VAL[]=""; +static char PAGE_ATT_SUPP[]="xp-page-attributes-supported"; +static char PAGE_ATT_VAL[]="content-orientation default-printer-resolution \ +default-input-tray default-medium plex"; + +static int +PclInitContext( pCon ) + XpContextPtr pCon; +{ + XpDriverFuncsPtr pFuncs; + PclContextPrivPtr pConPriv; + char *server, *attrStr; + char *modelID; + char *configDir; + char *pathName; + extern XpValidatePoolsRec PclValidatePoolsRec; + int i, j; + float width, height; + XpOidMediumDiscreteSizeList* ds_list; + XpOidArea* repro; + XpOid page_size; + XpOidMediumSS* m; + + /* + * Initialize the attribute store for this printer. + */ + XpInitAttributes( pCon ); + + /* + * Initialize the function pointers + */ + pFuncs = &( pCon->funcs ); + pFuncs->StartJob = PclStartJob; + pFuncs->EndJob = PclEndJob; + pFuncs->StartDoc = (int (*)())PclStartDoc; + pFuncs->EndDoc = PclEndDoc; + pFuncs->StartPage = PclStartPage; + pFuncs->EndPage = PclEndPage; + pFuncs->PutDocumentData = PclDocumentData; + pFuncs->GetDocumentData = PclGetDocumentData; + pFuncs->GetAttributes = (char *(*)())PclGetAttributes; + pFuncs->SetAttributes = (int (*)())PclSetAttributes; + pFuncs->AugmentAttributes = (int (*)())PclAugmentAttributes; + pFuncs->GetOneAttribute = (char *(*)())PclGetOneAttribute; + pFuncs->DestroyContext = PclDestroyContext; + pFuncs->GetMediumDimensions = PclGetMediumDimensions; + pFuncs->GetReproducibleArea = PclGetReproducibleArea; + + + /* + * Set up the context privates + */ + pConPriv = + (PclContextPrivPtr)pCon->devPrivates[PclContextPrivateIndex].ptr; + + pConPriv->jobFileName = (char *)NULL; + pConPriv->pageFileName = (char *)NULL; + pConPriv->pJobFile = (FILE *)NULL; + pConPriv->pPageFile = (FILE *)NULL; + pConPriv->dash = NULL; + pConPriv->validGC = 0; + + pConPriv->getDocClient = (ClientPtr)NULL; + pConPriv->getDocBufSize = 0; + modelID = XpGetOneAttribute(pCon, XPPrinterAttr, "xp-model-identifier"); + if ( (configDir = XpGetConfigDir(False)) != (char *) NULL ) { + pathName = (char *)xalloc(strlen(configDir) + strlen(MODELDIRNAME) + + strlen(modelID) + strlen("color.map") + 4); + if (pathName) { + sprintf(pathName, "%s/%s/%s/%s", configDir, MODELDIRNAME, modelID, + "color.map"); + pConPriv->ctbl = PclReadMap(pathName, &pConPriv->ctbldim); + xfree(pathName); + + } else + pConPriv->ctbl = NULL; + } else + pConPriv->ctbl = NULL; + +#ifdef XP_PCL_LJ3 + /* + * Initialize the spooling buffer for saving the figures temporary + * (LaserJet IIIs printers don't support the macro function which + * includes some HP-GL/2 commands.) + */ + pConPriv->fcount = 0; + if ( !(pConPriv->figures = (char *)xalloc(1024)) ) + pConPriv->fcount_max = 0; + else + pConPriv->fcount_max = 1024; +#endif /* XP_PCL_LJ3 */ + + /* + * document-attributes-supported + */ + server = XpGetOneAttribute( pCon, XPServerAttr, DOC_ATT_SUPP ); + if( ( attrStr = (char *)xalloc(strlen(server) + strlen(DOC_ATT_SUPP) + + strlen(DOC_ATT_VAL) + + strlen(PAGE_ATT_VAL) + 6 ) ) + == (char *)NULL ) + return BadAlloc; + sprintf( attrStr, "*%s:\t%s %s %s", DOC_ATT_SUPP, server, + DOC_ATT_VAL, PAGE_ATT_VAL ); + XpAugmentAttributes( pCon, XPPrinterAttr, attrStr ); + xfree( attrStr ); + + /* + * job-attributes-supported + */ + server = XpGetOneAttribute( pCon, XPServerAttr, JOB_ATT_SUPP ); + if( ( attrStr = (char *)xalloc(strlen(server) + strlen(JOB_ATT_SUPP) + + strlen(JOB_ATT_VAL) + 4 ) ) + == (char *)NULL ) + return BadAlloc; + sprintf( attrStr, "*%s:\t%s %s", JOB_ATT_SUPP, server, JOB_ATT_VAL ); + XpAugmentAttributes( pCon, XPPrinterAttr, attrStr ); + xfree( attrStr ); + + /* + * xp-page-attributes-supported + */ + server = XpGetOneAttribute( pCon, XPServerAttr, PAGE_ATT_SUPP ); + if( ( attrStr = (char *)xalloc(strlen(server) + strlen(PAGE_ATT_SUPP) + + strlen(PAGE_ATT_VAL) + 4 ) ) + == (char *)NULL ) + return BadAlloc; + sprintf( attrStr, "*%s:\t%s %s", PAGE_ATT_SUPP, server, PAGE_ATT_VAL ); + XpAugmentAttributes( pCon, XPPrinterAttr, attrStr ); + xfree( attrStr ); + + /* + * Validate the attribute pools + */ + XpValidateAttributePool( pCon, XPPrinterAttr, &PclValidatePoolsRec ); + + /* + * Munge the reproducible areas to reflect the fact that PCL will not let + * me move the right or left margins closer than .25" to the edge of the + * paper. + */ + m = XpGetMediumSSAttr( pCon, XPPrinterAttr, + xpoid_att_medium_source_sizes_supported, + (const XpOidList*) NULL, + (const XpOidList*) NULL ); + for( i = 0; i < XpOidMediumSSCount( m ); i++ ) + { + if( XpOidMediumSS_DISCRETE == (m->mss)[i].mstag ) + { + ds_list = (m->mss)[i].ms.discrete; + for( j = 0; j < ds_list->count; j++ ) + { + repro = &(ds_list->list)[j].assured_reproduction_area; + page_size = (ds_list->list)[j].page_size; + XpGetMediumMillimeters( page_size, &width, &height ); + + if( repro->minimum_x < 6.35 ) + repro->minimum_x = 6.35; + if( width - repro->maximum_x < 6.35 ) + repro->maximum_x = width - 6.35; + } + } + } + XpPutMediumSSAttr( pCon, XPPrinterAttr, + xpoid_att_medium_source_sizes_supported, m ); + XpOidMediumSSDelete( m ); + + /* + * Finish validating the attribute pools + */ + + XpValidateAttributePool( pCon, XPDocAttr, &PclValidatePoolsRec ); + XpValidateAttributePool( pCon, XPJobAttr, &PclValidatePoolsRec ); + XpValidateAttributePool( pCon, XPPageAttr, &PclValidatePoolsRec ); + + /* + * Clear out the colormap storage + */ + pConPriv->palettes = NULL; + + return Success; +} + +static Bool +PclDestroyContext( pCon ) + XpContextPtr pCon; +{ + PclContextPrivPtr pConPriv = (PclContextPrivPtr) + pCon->devPrivates[PclContextPrivateIndex].ptr; + PclPaletteMapPtr p, t; + PclCmapToContexts *pCmap; + ScreenPtr screen; + PclScreenPrivPtr sPriv; + PclContextListPtr con, prevCon, temp; + + + /* + * Clean up the temporary files + */ + if( pConPriv->pPageFile != (FILE *)NULL ) + { + fclose( pConPriv->pPageFile ); + pConPriv->pPageFile = (FILE *)NULL; + } + if( pConPriv->pageFileName != (char *)NULL ) + { + unlink( pConPriv->pageFileName ); + xfree( pConPriv->pageFileName ); + pConPriv->pageFileName = (char *)NULL; + } + + if( pConPriv->pJobFile != (FILE *)NULL ) + { + fclose( pConPriv->pJobFile ); + pConPriv->pJobFile = NULL; + } + if( pConPriv->jobFileName != (char *)NULL ) + { + unlink( pConPriv->jobFileName ); + xfree( pConPriv->jobFileName ); + pConPriv->jobFileName = (char *)NULL; + } + + xfree( pConPriv->dash ); + xfree(pConPriv->ctbl); + pConPriv->ctbl = NULL; +#ifdef XP_PCL_LJ3 + xfree( pConPriv->figures ); +#endif /* XP_PCL_LJ3 */ + + /* + * Destroy the colormap<->palette mappings + */ + p = pConPriv->palettes; + while( p ) + { + t = p; + p = p->next; + xfree( t ); + } + pConPriv->palettes = NULL; + + /* + * Remove the context from the screen-level colormap<->contexts mappings + */ + screen = screenInfo.screens[pCon->screenNum]; + sPriv = (PclScreenPrivPtr)screen->devPrivates[PclScreenPrivateIndex].ptr; + pCmap = sPriv->colormaps; + while( pCmap ) + { + con = pCmap->contexts; + prevCon = NULL; + + while( con ) + { + if( con->context->contextID == pCon->contextID ) + { + if( prevCon ) + { + temp = con; + prevCon->next = con = con->next; + } + else + { + temp = pCmap->contexts; + pCmap->contexts = con = con->next; + } + xfree( temp ); + } + else + con = con->next; + } + + pCmap = pCmap->next; + } + + XpDestroyAttributes(pCon); + + return Success; +} + +XpContextPtr +PclGetContextFromWindow( win ) + WindowPtr win; +{ + PclWindowPrivPtr pPriv; + + while( win ) + { + pPriv = + (PclWindowPrivPtr)win->devPrivates[PclWindowPrivateIndex].ptr; + if( pPriv->validContext ) + return pPriv->context; + + win = win->parent; + } + + return NULL; +} diff --git a/Xprint/pcl/PclLine.c b/Xprint/pcl/PclLine.c new file mode 100644 index 000000000..271bdfb16 --- /dev/null +++ b/Xprint/pcl/PclLine.c @@ -0,0 +1,314 @@ +/* $Xorg: PclLine.c,v 1.3 2000/08/17 19:48:08 cpqbld Exp $ */ +/******************************************************************* +** +** ********************************************************* +** * +** * File: PclLine.c +** * +** * Contents: +** * Line drawing routines for the PCL driver +** * +** * Created: 10/11/95 +** * +** ********************************************************* +** +********************************************************************/ +/* +(c) Copyright 1996 Hewlett-Packard Company +(c) Copyright 1996 International Business Machines Corp. +(c) Copyright 1996 Sun Microsystems, Inc. +(c) Copyright 1996 Novell, Inc. +(c) Copyright 1996 Digital Equipment Corp. +(c) Copyright 1996 Fujitsu Limited +(c) Copyright 1996 Hitachi, Ltd. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the names of the copyright holders shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from said +copyright holders. +*/ + +#include "Pcl.h" +#include "gcstruct.h" +#include "windowstr.h" + +/* + * PclPolyLine() + * PclPolySegment() + * + * Generates PCL code to draw a polyline, or a collection of distinct + * line segments, clipped by the current clip region. Since PCL + * supports clipping to a rectangle, and the clip region is + * represented as a collection of visible rectangles, we can draw and + * clip the line by repeatedly drawing the complete line, clipped to + * each rectangle in the clip region. + * + * Since each box in the clipping region generates approximately 30 + * bytes of PCL code, we have to have a way to avoid having a large + * number of boxes. The worst problem the case where the clipping + * region is a collection of one-pixel-high boxes, perhaps arising + * from a bitmap clip mask, or a region defined by a non-rectangular + * polygon. + * + * To alleviate this problem, we create a second clipping region, + * which consists of the union of the bounding boxes of each line + * segment. (Each bounding box is also increased by some amount + * related to the current line width to allow for non-zero-width + * lines, and for the various end and join styles.) This region is + * intersected with the "real" clipping region to get the region used + * to actually clip the polyline. This should result in a significant + * reduction in the number of clip rectangles, as the region-handling + * code should consolidate many of the fragments of one-pixel-high + * rectangles into larger rectangles. + */ + +void +PclPolyLine( pDrawable, pGC, mode, nPoints, pPoints ) + DrawablePtr pDrawable; + GCPtr pGC; + int mode; + int nPoints; + xPoint *pPoints; +{ + char t[80], window[80]; + FILE *outFile; + int xoffset, yoffset; + int nbox; + BoxPtr pbox; + xRectangle *drawRects, *r; + RegionPtr drawRegion, region; + short fudge; + int i; + XpContextPtr pCon; + PclContextPrivPtr pConPriv; + + if( PclUpdateDrawableGC( pGC, pDrawable, &outFile ) == FALSE ) + return; + + pCon = PclGetContextFromWindow( (WindowPtr) pDrawable ); + pConPriv = (PclContextPrivPtr) + pCon->devPrivates[PclContextPrivateIndex].ptr; + + /* + * Allocate the storage required to deal with the clipping + * regions. + */ + region = miRegionCreate( NULL, 0 ); + drawRects = (xRectangle *) + xalloc( ( nPoints - 1 ) * sizeof( xRectangle ) ); + + /* + * Calculate the "fudge factor" based on the line width. + * Multiplying by three seems to be a good first guess. + * XXX I need to think of a way to test this. + */ + fudge = 3 * pGC->lineWidth + 1; + + /* + * Generate the PCL code to draw the polyline, by defining it as a + * macro which uses the HP-GL/2 line drawing function. + */ + + MACRO_START( outFile, pConPriv ); + SAVE_PCL( outFile, pConPriv, "\033%0B" ); + + sprintf( t, "PU%d,%dPD\n", pPoints[0].x + pDrawable->x, + pPoints[0].y + pDrawable->y ); + SAVE_PCL( outFile, pConPriv, t ); /* Move to the start of the polyline */ + + switch( mode ) + { + case CoordModeOrigin: + xoffset = pDrawable->x; + yoffset = pDrawable->y; + SAVE_PCL( outFile, pConPriv, "PA" ); + break; + case CoordModePrevious: + xoffset = yoffset = 0; + SAVE_PCL( outFile, pConPriv, "PR" ); + break; + } + + /* + * Build the "drawing region" as we build the PCL to draw the + * line. + */ + for(i = 1, r = drawRects; i < nPoints; i++, r++ ) + { + if( i != 1 ) + SAVE_PCL( outFile, pConPriv, "," ); + + sprintf( t, "%d,%d", pPoints[i].x + xoffset, + pPoints[i].y + yoffset ); + SAVE_PCL( outFile, pConPriv, t ); + + r->x = MIN( pPoints[i-1].x, pPoints[i].x ) + xoffset - fudge; + r->y = MIN( pPoints[i-1].y, pPoints[i].y ) + yoffset - fudge; + r->width = abs( pPoints[i-1].x - pPoints[i].x ) + 2 * fudge; + r->height = abs( pPoints[i-1].y - pPoints[i].y ) + 2 * fudge; + } + SAVE_PCL( outFile, pConPriv, ";\033%0A" ); /* End the macro */ + MACRO_END( outFile ); + + /* + * Convert the collection of rectangles into a proper region, then + * intersect it with the clip region. + */ + drawRegion = miRectsToRegion( nPoints - 1, drawRects, CT_UNSORTED ); + if( mode == CoordModePrevious ) + miTranslateRegion( drawRegion, pPoints[0].x, pPoints[0].y ); + miIntersect( region, drawRegion, + ((PclGCPrivPtr)pGC->devPrivates[PclGCPrivateIndex].ptr) + ->pCompositeClip ); + + /* + * For each rectangle in the clip region, set the HP-GL/2 "input + * window" and render the entire polyline to it. + */ + pbox = REGION_RECTS( region ); + nbox = REGION_NUM_RECTS( region ); + + PclSendData(outFile, pConPriv, pbox, nbox, 1.0); + + /* + * Clean up the temporary regions + */ + miRegionDestroy( drawRegion ); + miRegionDestroy( region ); + xfree( drawRects ); +} + +void +PclPolySegment( pDrawable, pGC, nSegments, pSegments ) + DrawablePtr pDrawable; + GCPtr pGC; + int nSegments; + xSegment *pSegments; +{ + FILE *outFile, *dummy; + char t[80]; + int xoffset, yoffset; + int nbox, i; + unsigned long valid; + BoxPtr pbox; + xRectangle *drawRects, *r; + RegionPtr drawRegion, region; + short fudge; + XpContextPtr pCon; + PclContextPrivPtr pConPriv; + GC cacheGC; + + + if( PclUpdateDrawableGC( pGC, pDrawable, &outFile ) == FALSE ) + return; + + pCon = PclGetContextFromWindow( (WindowPtr) pDrawable ); + pConPriv = (PclContextPrivPtr) + pCon->devPrivates[PclContextPrivateIndex].ptr; + + /* + * Allocate the storage for the temporary regions. + */ + region = miRegionCreate( NULL, 0 ); + drawRects = (xRectangle *) + xalloc( nSegments * sizeof( xRectangle ) ); + + /* + * Calculate the fudge factor, based on the line width + */ + fudge = pGC->lineWidth * 3 + 1; + + /* + * Turn off line joining. + */ + SEND_PCL( outFile, "\033%0BLA2,6;\033%0A" ); + + /* + * Generate the PCL code to draw the segments, by defining them as + * a macro which uses the HP-GL/2 line drawing function. + * + * XXX I wonder if this should be implemented using the Encoded + * XXX Polyline function. Since I'm only sending it once, it's not + * XXX necessarily too important. + */ + + MACRO_START( outFile, pConPriv ); + SAVE_PCL( outFile, pConPriv, "\033%0B" ); + + xoffset = pDrawable->x; + yoffset = pDrawable->y; + + for( i = 0, r = drawRects; i < nSegments; i++, r++ ) + { + r->x = MIN( pSegments[i].x1, pSegments[i].x2 ) + xoffset; + r->y = MIN( pSegments[i].y1, pSegments[i].y2 ) + yoffset; + r->width = abs( pSegments[i].x1 - pSegments[i].x2 ); + r->height = abs( pSegments[i].y1 - pSegments[i].y2 ); + + sprintf( t, "PU%d,%d;PD%d,%d;", pSegments[i].x1 + xoffset, + pSegments[i].y1 + yoffset, pSegments[i].x2 + + xoffset, pSegments[i].y2 + yoffset ); + SAVE_PCL( outFile, pConPriv, t ); + + r->x -= fudge; + r->y -= fudge; + r->width += 2 * fudge; + r->height += 2 * fudge; + } + SAVE_PCL( outFile, pConPriv, "\033%0A" ); + MACRO_END ( outFile ); + + /* + * Convert the collection of rectangles into a proper region, then + * intersect it with the clip region. + */ + drawRegion = miRectsToRegion( nSegments, drawRects, CT_UNSORTED ); + miIntersect( region, drawRegion, + ((PclGCPrivPtr)pGC->devPrivates[PclGCPrivateIndex].ptr) + ->pCompositeClip ); + + /* + * For each rectangle in the clip region, set the HP-GL/2 "input + * window" and render the entire set of segments to it. + */ + pbox = REGION_RECTS( region ); + nbox = REGION_NUM_RECTS( region ); + + PclSendData(outFile, pConPriv, pbox, nbox, 1.0); + + /* + * Now we need to reset the line join mode to whatever it was at before. + * The easiest way is to force the cached GC's joinstyle to be different + * from the current GC's joinstyle, then re-update the GC. This way, we + * don't have to duplicate code unnecessarily. + */ + PclGetDrawablePrivateStuff( pDrawable, &cacheGC, &valid, &dummy ); + cacheGC.joinStyle = !cacheGC.joinStyle; + PclSetDrawablePrivateGC( pDrawable, cacheGC ); + PclUpdateDrawableGC( pGC, pDrawable, &outFile ); + + /* + * Clean up + */ + miRegionDestroy( drawRegion ); + miRegionDestroy( region ); + xfree( drawRects ); +} + diff --git a/Xprint/pcl/PclMisc.c b/Xprint/pcl/PclMisc.c new file mode 100644 index 000000000..867393a46 --- /dev/null +++ b/Xprint/pcl/PclMisc.c @@ -0,0 +1,293 @@ +/* $Xorg: PclMisc.c,v 1.3 2000/08/17 19:48:08 cpqbld Exp $ */ +/******************************************************************* +** +** ********************************************************* +** * +** * File: PclMisc.c +** * +** * Contents: +** * Miscellaneous code for Pcl driver. +** * +** * Created: 2/01/95 +** * +** ********************************************************* +** +********************************************************************/ +/* +(c) Copyright 1996 Hewlett-Packard Company +(c) Copyright 1996 International Business Machines Corp. +(c) Copyright 1996 Sun Microsystems, Inc. +(c) Copyright 1996 Novell, Inc. +(c) Copyright 1996 Digital Equipment Corp. +(c) Copyright 1996 Fujitsu Limited +(c) Copyright 1996 Hitachi, Ltd. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the names of the copyright holders shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from said +copyright holders. +*/ + +#include "Xos.h" /* for SIGCLD on pre-POSIX systems */ +#include <stdio.h> +#include "Pcl.h" + +#include "cursor.h" +#include "resource.h" + +#include "windowstr.h" +#include "propertyst.h" + + +/*ARGSUSED*/ +void +PclQueryBestSize( + int type, + short *pwidth, + short *pheight, + ScreenPtr pScreen) +{ + unsigned width, highBit; + + switch(type) + { + case CursorShape: + *pwidth = 0; + *pheight = 0; + break; + case TileShape: + case StippleShape: + width = *pwidth; + if (!width) break; + /* Return the nearest power of two >= what they gave us */ + highBit = 0x80000000; + /* Find the highest 1 bit in the given width */ + while(!(highBit & width)) + highBit >>= 1; + /* If greater than that then return the next power of two */ + if((highBit - 1) & width) + highBit <<= 1; + *pwidth = highBit; + /* height is a don't-care */ + break; + } +} + +/* + * GetPropString searches the window heirarchy from pWin up looking for + * a property by the name of propName. If found, returns the property's + * value. If not, it returns NULL. + */ +char * +GetPropString( + WindowPtr pWin, + char *propName) +{ + Atom atom; + PropertyPtr pProp = (PropertyPtr)NULL; + char *retVal; + + atom = MakeAtom(propName, strlen(propName), FALSE); + if(atom != BAD_RESOURCE) + { + WindowPtr pPropWin; + int n; + + /* + * The atom has been defined, but it might only exist as a + * property on an unrelated window. + */ + for(pPropWin = pWin; pPropWin != (WindowPtr)NULL; + pPropWin = pPropWin->parent) + { + for(pProp = (PropertyPtr)(wUserProps(pPropWin)); + pProp != (PropertyPtr)NULL; + pProp = pProp->next) + { + if (pProp->propertyName == atom) + break; + } + if(pProp != (PropertyPtr)NULL) + break; + } + if(pProp == (PropertyPtr)NULL) + return (char *)NULL; + + n = (pProp->format/8) * pProp->size; /* size (bytes) of prop */ + retVal = (char *)xalloc(n + 1); + (void)memcpy((void *)retVal, (void *)pProp->data, n); + retVal[n] = '\0'; + + return retVal; + } + + return (char *)NULL; +} + +#include <signal.h> + +/* ARGSUSED */ +static void SigchldHndlr ( + int dummy) +{ + int status, w; + struct sigaction act; + sigfillset(&act.sa_mask); + act.sa_flags = 0; + act.sa_handler = SigchldHndlr; + + w = wait (&status); + + /* + * Is this really necessary? + */ + sigaction(SIGCHLD, &act, (struct sigaction *)NULL); +} + +/* + * SystemCmd provides a wrapper for the 'system' library call. The call + * appears to be sensitive to the handling of SIGCHLD, so this wrapper + * sets the status to SIG_DFL, and then resets the established handler + * after system returns. + */ +int +SystemCmd(char *cmdStr) +{ + int status; + struct sigaction newAct, oldAct; + sigfillset(&newAct.sa_mask); + newAct.sa_flags = 0; + newAct.sa_handler = SIG_DFL; + sigfillset(&oldAct.sa_mask); + oldAct.sa_flags = 0; + oldAct.sa_handler = SigchldHndlr; + + /* + * get the old handler, and set the action to IGN + */ + sigaction(SIGCHLD, &newAct, &oldAct); + + status = system (cmdStr); + + sigaction(SIGCHLD, &oldAct, (struct sigaction *)NULL); + return status; +} + + +/* + * PclGetMediumDimensions is installed in the GetMediumDimensions field + * of each Pcl-initialized context. + */ +int +PclGetMediumDimensions(XpContextPtr pCon, + CARD16 *width, + CARD16 *height) +{ + XpGetMediumDimensions(pCon, width, height); + return Success; +} + +/* + * PclGetReproducibleArea is installed in the GetReproducibleArea field + * of each Pcl-initialized context. + */ +int +PclGetReproducibleArea(XpContextPtr pCon, + xRectangle *pRect) +{ + XpGetReproductionArea(pCon, pRect); + return Success; +} + +#ifdef XP_PCL_LJ3 +/* + * PclSpoolFigs spooled the rendering PCL/HP-GL2 commands into the + * temporary buffer pointed by figures pointer in pcl private context. + * LaserJet IIIs printers don't support the macro function which + * includes some HP-GL/2 commands. + */ +void +PclSpoolFigs(PclContextPrivPtr pConPriv, char *t, int n) +{ +char *ptr; + + ptr = pConPriv->figures; + while ( ( pConPriv->fcount + n) > pConPriv->fcount_max ) { + ptr = (char *)xrealloc(ptr, 1024 + pConPriv->fcount_max); + if ( !ptr ) + return; + pConPriv->figures = ptr; + pConPriv->fcount_max += 1024; + } + ptr += pConPriv->fcount; + pConPriv->fcount += n; + memcpy(ptr, t, n); +} +#endif /* XP_PCL_LJ3 */ + +/* + * PclSendData: + * For XP-PCL-COLOR/XP-PCL-MONO, it executes the macro stored before + * in the clipped area. + * For XP-PCL-LJ3, it draws the spooled figures in the clipped area. + */ +PclSendData( + FILE *outFile, + PclContextPrivPtr pConPriv, + BoxPtr pbox, + int nbox, + double ratio +) +{ +char *ptr; +int n; +char t[80]; + +#ifdef XP_PCL_LJ3 + ptr = pConPriv->figures; + n = pConPriv->fcount; +#else + ptr = "\033&f3X"; + n = 5; +#endif /* XP_PCL_LJ3 */ + + while( nbox ) + { + /* + * Set the HP-GL/2 input window to the current + * rectangle in the clip region, then send the code to + * execute the macro defined above. + */ + if (ratio == 1.0) + sprintf( t, "\033%%0BIW%d,%d,%d,%d;\033%%0A", + pbox->x1, pbox->y1, + pbox->x2, pbox->y2 ); + else + sprintf( t, "\033%%0BIW%g,%d,%g,%d;\033%%0A", + ratio * pbox->x1, pbox->y1, + ratio * pbox->x2, pbox->y2 ); + + SEND_PCL( outFile, t ); + SEND_PCL_COUNT( outFile, ptr, n); + + nbox--; + pbox++; + } +} diff --git a/Xprint/pcl/PclPixel.c b/Xprint/pcl/PclPixel.c new file mode 100644 index 000000000..23ec464e5 --- /dev/null +++ b/Xprint/pcl/PclPixel.c @@ -0,0 +1,154 @@ +/* $Xorg: PclPixel.c,v 1.3 2000/08/17 19:48:08 cpqbld Exp $ */ +/******************************************************************* +** +** ********************************************************* +** * +** * File: PclPixel.c +** * +** * Contents: +** * Pixel-drawing code for the PCL DDX driver +** * +** * Created: 10/23/95 +** * +** ********************************************************* +** +********************************************************************/ +/* +(c) Copyright 1996 Hewlett-Packard Company +(c) Copyright 1996 International Business Machines Corp. +(c) Copyright 1996 Sun Microsystems, Inc. +(c) Copyright 1996 Novell, Inc. +(c) Copyright 1996 Digital Equipment Corp. +(c) Copyright 1996 Fujitsu Limited +(c) Copyright 1996 Hitachi, Ltd. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the names of the copyright holders shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from said +copyright holders. +*/ + +#include <stdio.h> + +#include "windowstr.h" +#include "gcstruct.h" + +#include "Pcl.h" + +void +PclPolyPoint( pDrawable, pGC, mode, nPoints, pPoints ) + DrawablePtr pDrawable; + GCPtr pGC; + int mode; + int nPoints; + xPoint *pPoints; +{ + char t[80], *command; + FILE *outFile; + int xoffset, yoffset; + BoxRec box; + int xloc, yloc, i; + XpContextPtr pCon; + PclContextPrivPtr cPriv; + PclPixmapPrivPtr pPriv; + + if( PclUpdateDrawableGC( pGC, pDrawable, &outFile ) == FALSE ) + return; + + xoffset = pDrawable->x; + yoffset = pDrawable->y; + + /* + * Enter HP-GL/2 and change the line style to one in which only + * the vertices of the specified polyline are drawn. We must also + * temporarily change the line width so that only a single pixel + * is drawn. Then move to the first possible location. + */ + xloc = pPoints[0].x + pDrawable->x; + yloc = pPoints[0].y + pDrawable->y; + + sprintf( t, "\27%0BPW0,0;LT0;PU;PA%d,%d", xloc, yloc ); + SEND_PCL( outFile, t ); + + /* + * Check each point against the clip region. If it is outside the + * region, don't send the PCL to the printer. + */ + + for( i = 0; i < nPoints; i++ ) + { + if( miPointInRegion( pGC->clientClip, xloc, yloc, &box ) ) + { + sprintf( t, ",%d,%d", xloc, yloc ); + SEND_PCL( outFile, t ); + } + + if( mode == CoordModeOrigin ) + { + xloc = pPoints[i+1].x + xoffset; + yloc = pPoints[i+1].y + yoffset; + } + else + { + xloc += pPoints[i+1].x; + yloc += pPoints[i+1].y; + } + } + + /* + * Change the line style and width back to what they were before + * this routine was called. No, this isn't pretty... + */ + if( pDrawable->type == DRAWABLE_WINDOW ) + { + pCon = PclGetContextFromWindow( (WindowPtr)pDrawable ); + cPriv = pCon->devPrivates[PclContextPrivateIndex].ptr; +/* + cPriv->changeMask = GCLineWidth | GCLineStyle; +*/ + } + else + { + pPriv = + ((PixmapPtr)pDrawable)->devPrivates[PclPixmapPrivateIndex].ptr; +/* + pPriv->changeMask = GCLineWidth | GCLineStyle; +*/ + } + + PclUpdateDrawableGC( pGC, pDrawable, &outFile ); + + /* + * Go back to PCL + */ + SEND_PCL( outFile, "\27%0A" ); +} + +void +PclPushPixels( pGC, pBitmap, pDrawable, width, height, x, y ) + GCPtr pGC; + PixmapPtr pBitmap; + DrawablePtr pDrawable; + int width; + int height; + int x; + int y; +{ +} diff --git a/Xprint/pcl/PclPixmap.c b/Xprint/pcl/PclPixmap.c new file mode 100644 index 000000000..fe8d169b1 --- /dev/null +++ b/Xprint/pcl/PclPixmap.c @@ -0,0 +1,80 @@ +/* $Xorg: PclPixmap.c,v 1.3 2000/08/17 19:48:08 cpqbld Exp $ */ +/******************************************************************* +** +** ********************************************************* +** * +** * File: PclPixmap.c +** * +** * Contents: +** * Pixmap handling code for the PCL DDX driver +** * +** * Created: 2/19/96 +** * +** ********************************************************* +** +********************************************************************/ +/* +(c) Copyright 1996 Hewlett-Packard Company +(c) Copyright 1996 International Business Machines Corp. +(c) Copyright 1996 Sun Microsystems, Inc. +(c) Copyright 1996 Novell, Inc. +(c) Copyright 1996 Digital Equipment Corp. +(c) Copyright 1996 Fujitsu Limited +(c) Copyright 1996 Hitachi, Ltd. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the names of the copyright holders shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from said +copyright holders. +*/ + +#include "Pcl.h" +/*#include "cfb.h"*/ +/* #include "mfb.h" */ +#include "pixmapstr.h" + +PixmapPtr +PclCreatePixmap(ScreenPtr pScreen, + int width, + int height, + int depth) +{ +extern PixmapPtr mfbCreatePixmap(), cfbCreatePixmap(), cfb32CreatePixmap(); + + if( depth == 1 ) + return mfbCreatePixmap( pScreen, width, height, depth ); + else if( depth <= 8 ) + return cfbCreatePixmap( pScreen, width, height, depth ); + else if( depth <= 32 ) + return cfb32CreatePixmap( pScreen, width, height, depth ); +} + + +Bool +PclDestroyPixmap(PixmapPtr pPixmap) +{ +extern Bool mfbDestroyPixmap(), cfbDestroyPixmap(), cfb32DestroyPixmap(); + if( pPixmap->drawable.depth == 1 ) + return mfbDestroyPixmap( pPixmap ); + else if( pPixmap->drawable.depth <= 8 ) + return cfbDestroyPixmap( pPixmap ); + else if( pPixmap->drawable.depth <= 32 ) + return cfb32DestroyPixmap( pPixmap ); +} diff --git a/Xprint/pcl/PclPolygon.c b/Xprint/pcl/PclPolygon.c new file mode 100644 index 000000000..badbdf18a --- /dev/null +++ b/Xprint/pcl/PclPolygon.c @@ -0,0 +1,354 @@ +/* $Xorg: PclPolygon.c,v 1.3 2000/08/17 19:48:08 cpqbld Exp $ */ +/******************************************************************* +** +** ********************************************************* +** * +** * File: PclPolygon.c +** * +** * Contents: +** * Draws Polygons and Rectangles for the PCL DDX +** * +** * Created: 10/23/95 +** * +** ********************************************************* +** +********************************************************************/ +/* +(c) Copyright 1996 Hewlett-Packard Company +(c) Copyright 1996 International Business Machines Corp. +(c) Copyright 1996 Sun Microsystems, Inc. +(c) Copyright 1996 Novell, Inc. +(c) Copyright 1996 Digital Equipment Corp. +(c) Copyright 1996 Fujitsu Limited +(c) Copyright 1996 Hitachi, Ltd. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the names of the copyright holders shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from said +copyright holders. +*/ + + +#include "Pcl.h" +#include "gcstruct.h" +#include "windowstr.h" + +void +PclPolyRectangle( pDrawable, pGC, nRects, pRects ) + DrawablePtr pDrawable; + GCPtr pGC; + int nRects; + xRectangle *pRects; +{ + char t[80]; + FILE *outFile; + int nbox, i; + BoxPtr pbox; + xRectangle *drawRects, *r; + RegionPtr drawRegion, region; + short fudge; + int xoffset, yoffset; + XpContextPtr pCon; + PclContextPrivPtr pConPriv; + + if( PclUpdateDrawableGC( pGC, pDrawable, &outFile ) == FALSE ) + return; + + pCon = PclGetContextFromWindow( (WindowPtr) pDrawable ); + pConPriv = (PclContextPrivPtr) + pCon->devPrivates[PclContextPrivateIndex].ptr; + + /* + * Allocate the storage required to deal with the clipping + * regions. + */ + region = miRegionCreate( NULL, 0 ); + drawRects = (xRectangle *)xalloc( nRects * sizeof( xRectangle ) ); + + fudge = 3 * pGC->lineWidth + 1; + + /* + * Generate the PCL code to draw the rectangles, by defining them + * as a macro which uses the HP-GL/2 rectangle drawing function. + */ + MACRO_START( outFile, pConPriv ); + SAVE_PCL( outFile, pConPriv, "\033%0B" ); + + xoffset = pDrawable->x; + yoffset = pDrawable->y; + + for( i = 0, r = drawRects; i < nRects; i++, r++ ) + { + xRectangle rect = pRects[i]; + + /* Draw the rectangle */ + sprintf( t, "PU%d,%d;ER%d,%d;", rect.x + xoffset, + rect.y + yoffset, rect.width, rect.height ); + SAVE_PCL( outFile, pConPriv, t ); + + /* Build the bounding box */ + r->x = MIN( rect.x, rect.x + rect.width ) + xoffset - + fudge; + r->y = MIN( rect.y, rect.y + rect.height ) + yoffset - + fudge; + r->width = rect.width + 2 * fudge; + r->height = rect.height + 2 * fudge; + } + SAVE_PCL( outFile, pConPriv, ";\033%0A" ); /* End the macro */ + MACRO_END( outFile ); + + /* + * Convert the collection of rectangles to a proper region, then + * intersect it with the clip region. + */ + drawRegion = miRectsToRegion( nRects, drawRects, CT_UNSORTED ); + + miIntersect( region, drawRegion, + ((PclGCPrivPtr)pGC->devPrivates[PclGCPrivateIndex].ptr) + ->pCompositeClip ); + + /* + * For each rectangle in the clip region, set the HP-GL/2 "input + * window" and render the set of rectangles to it. + */ + pbox = REGION_RECTS( region ); + nbox = REGION_NUM_RECTS( region ); + + PclSendData(outFile, pConPriv, pbox, nbox, 1.0); + + /* + * Clean up the temporary regions + */ + miRegionDestroy( drawRegion ); + miRegionDestroy( region ); + xfree( drawRects ); +} + +void +PclFillPolygon( pDrawable, pGC, shape, mode, nPoints, pPoints ) + DrawablePtr pDrawable; + GCPtr pGC; + int shape; + int mode; + int nPoints; + DDXPointPtr pPoints; +{ + char t[80]; + FILE *outFile; + int nbox, i; + BoxPtr pbox; + BoxRec box; + xRectangle *drawRects, *r; + RegionPtr drawRegion, region; + int xoffset, yoffset; + int xtop, xbottom, yleft, yright; + int fillRule; + XpContextPtr pCon; + PclContextPrivPtr pConPriv; + char *command; + + if( PclUpdateDrawableGC( pGC, pDrawable, &outFile ) == FALSE ) + return; + + pCon = PclGetContextFromWindow( (WindowPtr) pDrawable ); + pConPriv = (PclContextPrivPtr) + pCon->devPrivates[PclContextPrivateIndex].ptr; + + /* + * Generate the PCL code to draw the filled polygon, by defining + * it as a macro which uses the HP-GL/2 polygon drawing function. + */ + MACRO_START( outFile, pConPriv ); + SAVE_PCL( outFile, pConPriv, "\033%0B" ); + + if( mode == CoordModeOrigin ) + { + xoffset = pDrawable->x; + yoffset = pDrawable->y; + command = "PA"; + } + else + { + xoffset = yoffset = 0; + command = "PR"; + } + + /* Begin the polygon */ + sprintf( t, "PU%d,%d;PM0;%s", pPoints[0].x + xoffset, pPoints[0].y + + yoffset, command ); + SAVE_PCL( outFile, pConPriv, t ); + + /* Seed the bounding box */ + xtop = xbottom = pPoints[0].x + xoffset; + yleft = yright = pPoints[0].y + yoffset; + + /* Add the rest of the points to the polygon */ + for( i = 1; i < nPoints; i++ ) + { + if( i != 1 ) + SAVE_PCL( outFile, pConPriv, "," ); + + sprintf( t, "%d,%d", pPoints[i].x + xoffset, pPoints[i].y + + yoffset ); + SAVE_PCL( outFile, pConPriv, t ); + + /* Update the bounding box */ + xtop = MIN( xtop, pPoints[i].x + xoffset ); + xbottom = MAX( xbottom, pPoints[i].x + xoffset ); + yleft = MIN( yleft, pPoints[i].y + yoffset ); + yright = MAX( yright, pPoints[i].y + yoffset ); + } + + /* Close the polygon and the macro */ + + if( pGC->fillRule == EvenOddRule ) + fillRule = 0; + else + fillRule = 1; + + sprintf( t, ";PM2;FP%d;\033%%0A", fillRule ); + SAVE_PCL( outFile, pConPriv, t ); + MACRO_END ( outFile ); + + /* + * Build the bounding region from the bounding box of the polygon + */ + box.x1 = xtop; + box.y1 = yleft; + box.x2 = xbottom; + box.y2 = yright; + drawRegion = miRegionCreate( &box, 0 ); + + if( mode == CoordModePrevious ) + miTranslateRegion( drawRegion, pPoints[0].x, pPoints[0].y ); + + region = miRegionCreate( NULL, 0 ); + + miIntersect( region, drawRegion, + ((PclGCPrivPtr)pGC->devPrivates[PclGCPrivateIndex].ptr) + ->pCompositeClip ); + + /* + * For each rectangle in the clip region, set the HP-GL/2 "input + * window" and render the polygon to it. + */ + pbox = REGION_RECTS( region ); + nbox = REGION_NUM_RECTS( region ); + + PclSendData(outFile, pConPriv, pbox, nbox, 1.0); + + /* + * Clean up the temporary regions + */ + miRegionDestroy( drawRegion ); + miRegionDestroy( region ); +} + +void +PclPolyFillRect( pDrawable, pGC, nRects, pRects ) + DrawablePtr pDrawable; + GCPtr pGC; + int nRects; + xRectangle *pRects; +{ + char t[80]; + FILE *outFile; + int nbox, i; + BoxPtr pbox; + xRectangle *drawRects, *r; + RegionPtr drawRegion, region; + int xoffset, yoffset; + short fudge; + XpContextPtr pCon; + PclContextPrivPtr pConPriv; + + if( PclUpdateDrawableGC( pGC, pDrawable, &outFile ) == FALSE ) + return; + + pCon = PclGetContextFromWindow( (WindowPtr) pDrawable ); + pConPriv = (PclContextPrivPtr) + pCon->devPrivates[PclContextPrivateIndex].ptr; + + /* + * Allocate the storage required to deal with the clipping + * regions. + */ + region = miRegionCreate( NULL, 0 ); + drawRects = (xRectangle *)xalloc( nRects * sizeof( xRectangle ) ); + + + fudge = 3 * pGC->lineWidth + 1; + + /* + * Generate the PCL code to draw the filled rectangles, by + * defining them as a macro which uses the HP-GL/2 rectangle + * drawing function. + */ + MACRO_START( outFile, pConPriv ); + SAVE_PCL( outFile, pConPriv, "\033%0B" ); + + xoffset = pDrawable->x; + yoffset = pDrawable->y; + + for( i = 0, r = drawRects; i < nRects; i++, r++ ) + { + xRectangle rect = pRects[i]; + + /* Draw the rectangle */ + sprintf( t, "PU%d,%d;RR%d,%d;", rect.x + xoffset, rect.y + + yoffset, rect.width, rect.height ); + SAVE_PCL( outFile, pConPriv, t ); + + /* Build the bounding box */ + r->x = MIN( rect.x, rect.x + rect.width ) + xoffset - fudge; + r->y = MIN( rect.y, rect.y + rect.height ) + yoffset - + fudge; + r->width = rect.width + 2 * fudge; + r->height = rect.height + 2 * fudge; + } + SAVE_PCL( outFile, pConPriv, ";\033%0A" ); /* End the macro */ + MACRO_END( outFile ); + + /* + * Convert the collection of rectangles to a proper region, then + * intersect it with the clip region. + */ + drawRegion = miRectsToRegion( nRects, drawRects, CT_UNSORTED ); + miIntersect( region, drawRegion, + ((PclGCPrivPtr)pGC->devPrivates[PclGCPrivateIndex].ptr) + ->pCompositeClip ); + + /* + * For each rectangle in the clip region, set the HP-GL/2 "input + * window" and render the set of rectangles to it. + */ + pbox = REGION_RECTS( region ); + nbox = REGION_NUM_RECTS( region ); + + PclSendData(outFile, pConPriv, pbox, nbox, 1.0); + + /* + * Clean up the temporary regions + */ + miRegionDestroy( drawRegion ); + miRegionDestroy( region ); + xfree( drawRects ); +} + diff --git a/Xprint/pcl/PclPrint.c b/Xprint/pcl/PclPrint.c new file mode 100644 index 000000000..2bfd92d15 --- /dev/null +++ b/Xprint/pcl/PclPrint.c @@ -0,0 +1,718 @@ +/* $Xorg: PclPrint.c,v 1.3 2000/08/17 19:48:08 cpqbld Exp $ */ +/******************************************************************* +** +** ********************************************************* +** * +** * File: PclPrint.c +** * +** * Contents: Print extension code of Pcl driver +** * +** * Created: 2/03/95 +** * +** ********************************************************* +** +********************************************************************/ +/* +(c) Copyright 1996 Hewlett-Packard Company +(c) Copyright 1996 International Business Machines Corp. +(c) Copyright 1996 Sun Microsystems, Inc. +(c) Copyright 1996 Novell, Inc. +(c) Copyright 1996 Digital Equipment Corp. +(c) Copyright 1996 Fujitsu Limited +(c) Copyright 1996 Hitachi, Ltd. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the names of the copyright holders shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from said +copyright holders. +*/ + +#include <stdio.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/wait.h> +#include <unistd.h> +#include <X11/Xprotostr.h> + +#define NEED_EVENTS +#include "Xproto.h" +#undef NEED_EVENTS + +#include "Pcl.h" + +#include "windowstr.h" +#include "attributes.h" +#include "AttrValid.h" +#include "Oid.h" + +extern PclSoftFontInfoPtr PclCreateSoftFontInfo(); +extern void PclDestroySoftFontInfo(PclSoftFontInfoPtr); + +int +PclStartJob( pCon, sendClientData, client ) + XpContextPtr pCon; + Bool sendClientData; + ClientPtr client; + +{ + PclContextPrivPtr pConPriv = + (PclContextPrivPtr)pCon->devPrivates[PclContextPrivateIndex].ptr; + char *jobHeader; + char s[40]; + PclPaletteMap *pal; + + /* + * Check for existing page file, and delete it if it exists. + */ + if(pConPriv->pageFileName != (char *)NULL) + { + if(pConPriv->pPageFile != (FILE *)NULL) + { + fclose(pConPriv->pPageFile); + pConPriv->pPageFile = (FILE *)NULL; + } + unlink(pConPriv->pageFileName); + xfree(pConPriv->pageFileName); + pConPriv->pageFileName = (char *)NULL; + } + + /* + * Create a temporary file to store the printer output. + */ + if (!XpOpenTmpFile("w+", &pConPriv->jobFileName, &pConPriv->pJobFile)) + return BadAlloc; + + /* + * Create/Initialize the SoftFontInfo structure + */ + pConPriv->pSoftFontInfo = PclCreateSoftFontInfo(); + + /* + * Set up the colormap handling + */ + pConPriv->palettes = NULL; + pConPriv->nextPaletteId = 4; + pConPriv->currentPalette = 0; + + pal = &( pConPriv->staticGrayPalette ); + pal->paletteId = 1; + pal->downloaded = 0; + + pal = &( pConPriv->trueColorPalette ); + pal->paletteId = 2; + pal->downloaded = 0; + + pal = &( pConPriv->specialTrueColorPalette ); + pal->paletteId = 3; + pal->downloaded = 0; + + return Success; +} + +int +PclEndJob( pCon, cancel ) + XpContextPtr pCon; + Bool cancel; +{ + PclContextPrivPtr priv = (PclContextPrivPtr) + pCon->devPrivates[PclContextPrivateIndex].ptr; + +#ifdef CCP_DEBUG + FILE *xpoutput; +#endif + FILE *fp; + int retVal; + char *fileName, *trailer; + struct stat statBuf; + int n; + PclPaletteMapPtr p, t; + + trailer = "\033%-12345X@PJL RESET\n"; + + if( cancel == True ) + { + if( priv->getDocClient != (ClientPtr)NULL ) { + XpFinishDocData( priv->getDocClient ); + + priv->getDocClient == NULL; + priv->getDocBufSize = 0; + } + + return Success; + } + + if( priv->getDocClient != (ClientPtr)NULL && priv->getDocBufSize > 0 ) + { + /* + * We need to stash the trailer information somewhere... + */ + if (!XpOpenTmpFile("w+", &fileName, &fp)) + return BadAlloc; + +#ifndef XP_PCL_LJ3 + SEND_PCL( fp, trailer ); + rewind( fp ); + + retVal = XpSendDocumentData( priv->getDocClient, fp, + strlen( trailer ), + priv->getDocBufSize ); +#endif /* XP_PCL_LJ3 */ + + fclose( fp ); + unlink( fileName ); + xfree( fileName ); + + if( priv->getDocClient != (ClientPtr)NULL ) { + XpFinishDocData( priv->getDocClient ); + + priv->getDocClient == NULL; + priv->getDocBufSize = 0; + } + + return retVal; + } + +#ifndef XP_PCL_LJ3 + SEND_PCL( priv->pJobFile, trailer ); +#endif /* XP_PCL_LJ3 */ + + /* + * Submit the job to the spooler + */ + fflush( priv->pJobFile ); + + /* + * Dump the job file to another output file, for testing + * purposes. + */ + rewind( priv->pJobFile ); + n = stat( priv->jobFileName, &statBuf ); + +#ifdef CCP_DEBUG + unlink( "/users/prince/XpOutput" ); + xpoutput = fopen( "/users/prince/XpOutput", "w" ); + + rewind( priv->pJobFile ); + n = TransferBytes( priv->pJobFile, xpoutput, + (int)statBuf.st_size ); + fclose( xpoutput ); +#endif + + XpSubmitJob( priv->jobFileName, pCon ); + fclose( priv->pJobFile ); + unlink( priv->jobFileName ); + xfree( priv->jobFileName ); + priv->jobFileName = NULL; + + PclDestroySoftFontInfo(priv->pSoftFontInfo); + priv->pSoftFontInfo = (PclSoftFontInfoPtr) NULL; + + /* + * Clear out the colormap cache + */ + p = priv->palettes; + while( p ) + { + p->downloaded = 0; + p = p->next; + } + + return Success; +} + +/* StartPage + * + * If page file exists + * close page file + * set page file pointer = NULL + * unlink page file + * Create a new page file + * Send the page header information to the page file + * ClearArea the window and all descendant windows + */ +int +PclStartPage( pCon, pWin ) + XpContextPtr pCon; + WindowPtr pWin; +{ + register WindowPtr pChild; + PclContextPrivPtr pConPriv = (PclContextPrivPtr) + pCon->devPrivates[PclContextPrivateIndex].ptr; + PclWindowPrivPtr pWinPriv = + (PclWindowPrivPtr)pWin->devPrivates[PclWindowPrivateIndex].ptr; + xRectangle repro; + char t[80]; + XpOid orient, plex, tray, medium; + unsigned short wid, ht; + int dir, plexNum, num; + xEvent event; + + /* + * Put a pointer to the context in the window private structure + */ + pWinPriv->validContext = 1; + pWinPriv->context = pCon; + + /* + * Clear out the old page file, if necessary + */ + if(pConPriv->pPageFile != (FILE *)NULL) + { + fclose(pConPriv->pPageFile); + pConPriv->pPageFile = (FILE *)NULL; + } + if(pConPriv->pageFileName != (char *)NULL) + { + unlink(pConPriv->pageFileName); + pConPriv->pageFileName = (char *)NULL; + } + + /* + * Make up a new page file. + */ + if (!XpOpenTmpFile("w+", &pConPriv->pageFileName, &pConPriv->pPageFile)) + return BadAlloc; + + /* + * Reset the GC cached in the context private struct. + */ + pConPriv->validGC = 0; + + /* + * Set the page orientation + */ + orient = XpGetContentOrientation( pCon ); + switch( orient ) + { + case xpoid_val_content_orientation_landscape: + dir = 1; + break; + case xpoid_val_content_orientation_reverse_portrait: + dir = 2; + break; + case xpoid_val_content_orientation_reverse_landscape: + dir = 3; + break; + case xpoid_val_content_orientation_portrait: + default: + dir = 0; + break; + } + sprintf( t, "\033&l%dO", dir ); + SEND_PCL( pConPriv->pPageFile, t ); + + /* + * Set the duplexing method. Since PCL wants to think of it in + * terms of the "binding edge," and the attribute store thinks in + * "duplex/tumble," this is a little complicated. + * + * Actually, this has no bearing on the output, since the HP1600C + * will only print on one side of the paper, and ignore all + * requests to enable duplexing. But, in an attempt to keep this + * driver somewhat generic, we'll enable it anyway. + */ + plex = XpGetPlex( pCon ); + + if( plex == xpoid_val_plex_duplex ) + { + if( dir == 0 || dir == 2 ) + plexNum = 1; + else + plexNum = 2; + } + else if( plex == xpoid_val_plex_tumble ) + { + if( dir == 0 || dir == 2 ) + plexNum = 2; + else + plexNum = 1; + } + else + plexNum = 0; + sprintf( t, "\033&l%dS", plexNum ); + SEND_PCL( pConPriv->pPageFile, t ); + + /* + * Set the input tray or medium. If XpGetPageSize gives us a valid medium, + * we can just send that to the printer, and let the printer handle the + * details. Otherwise, we select the tray returned from XpGetPageSize, + * which will be either a tray that should contain the correct medium + * (possibly with operator intervention), or the default tray from the + * config files. + */ + medium = XpGetPageSize( pCon, &tray, NULL ); + if( medium != xpoid_none ) + { + switch( medium ) + { + case xpoid_val_medium_size_na_legal: + num = 3; + break; + case xpoid_val_medium_size_iso_a3: + num = 27; + break; + case xpoid_val_medium_size_iso_a4: + num = 26; + break; + case xpoid_val_medium_size_executive: + num = 1; + break; + case xpoid_val_medium_size_ledger: + num = 6; + break; + case xpoid_val_medium_size_monarch_envelope: + num = 80; + break; + case xpoid_val_medium_size_na_number_10_envelope: + num = 81; + break; + case xpoid_val_medium_size_iso_designated_long: + num = 90; + break; + case xpoid_val_medium_size_iso_c5: + num = 91; + break; + case xpoid_val_medium_size_iso_b5: + num = 100; + break; + case xpoid_val_medium_size_jis_b5: + num = 45; + break; + case xpoid_val_medium_size_na_letter: + default: + num = 2; + break; + } + sprintf( t, "\033&l%dA", num ); + SEND_PCL( pConPriv->pPageFile, t ); + } + else + { + switch( tray ) + { + case xpoid_val_input_tray_manual: + num = 2; + break; + case xpoid_val_input_tray_envelope: + num = 3; + break; + case xpoid_val_input_tray_large_capacity: + num = 5; + break; + case xpoid_val_input_tray_bottom: + num = 4; + break; + case xpoid_val_input_tray_main: + default: + num = 1; + break; + } + sprintf( t, "\033&l%dH", num ); + SEND_PCL( pConPriv->pPageFile, t ); + } + + /* + * Set the scaling factors so that the HP-GL/2 coordinate system + * matches the X coordinate system, both in axis orientation and + * in unit<->pixel conversion. + */ + XpGetReproductionArea( pCon, &repro ); + + sprintf( t, "\033&l0E\033*p%dx%dY", repro.x - 75, repro.y ); + SEND_PCL( pConPriv->pPageFile, t ); + + sprintf( t, "\033*c%dx%dY\033*c0T", (int)(repro.width / 300.0 * 720.0), + (int)(repro.height / 300.0 * 720.0) ); + SEND_PCL( pConPriv->pPageFile, t ); + + sprintf( t, "\033%%0BSC%d,%d,%d,%d;\033%%0A", repro.x, repro.x + + repro.width, repro.y + repro.height, repro.y ); + SEND_PCL( pConPriv->pPageFile, t ); + + return Success; +} + +/* + * When sending the generated PCL code back to the client, we send everything + * that we have generated so far for the job. After sending the data, we clean + * out the job file, to avoid repeatedly sending the same data. + */ + +static int +SendDocData( PclContextPrivPtr pPriv ) +{ + struct stat statBuf; + int ret; + + rewind( pPriv->pJobFile ); + if( stat( pPriv->jobFileName, &statBuf ) < 0 ) + return BadAlloc; + + ret = XpSendDocumentData( pPriv->getDocClient, pPriv->pJobFile, + (int)statBuf.st_size, pPriv->getDocBufSize ); + + /* + * Clean out the job file + */ + fclose( pPriv->pJobFile ); + unlink( pPriv->jobFileName ); + + xfree(pPriv->jobFileName); + + if (!XpOpenTmpFile("w+", &pPriv->jobFileName, &pPriv->pJobFile)) + return BadAlloc; + + return ret; +} + +/* + * EndPage: + * + * Write page trailer to page file + * Write page file to job file + */ +int +PclEndPage( pCon, pWin ) + XpContextPtr pCon; + WindowPtr pWin; +{ + PclContextPrivPtr pConPriv = (PclContextPrivPtr) + pCon->devPrivates[PclContextPrivateIndex].ptr; + PclWindowPrivPtr pWinPriv = + (PclWindowPrivPtr)pWin->devPrivates[PclWindowPrivateIndex].ptr; + + struct stat statBuf; + + /* + * Send the page trailer to the page file. + */ + SEND_PCL( pConPriv->pPageFile, "\014" ); + fflush( pConPriv->pPageFile ); + + /* + * Write the page file contents to the job file, or to the + * whatever client has called GetDocumentData. + * + * pWinPriv->pPageFile must first be set to the start of the page file. + */ + rewind(pConPriv->pPageFile); + if(stat(pConPriv->pageFileName, &statBuf) < 0) + return BadAlloc; + + if(TransferBytes(pConPriv->pPageFile, pConPriv->pJobFile, + (int)statBuf.st_size) != (int)statBuf.st_size) + return BadAlloc; + + if( pConPriv->getDocClient != (ClientPtr)NULL && + pConPriv->getDocBufSize > 0 ) + { + return SendDocData( pConPriv ); + } + + return Success; +} + +/* + * The PclStartDoc() and PclEndDoc() functions serve basically as NOOP + * placeholders. This driver doesn't deal with the notion of multiple + * documents per page. + */ + +int +PclStartDoc(XpContextPtr pCon, + XPDocumentType type) +{ + PclContextPrivPtr pConPriv = (PclContextPrivPtr) + pCon->devPrivates[PclContextPrivateIndex].ptr; + +#ifndef XP_PCL_LJ3 + /* + * Set the printer resolution for the page. Since we can only + * render color at 300dpi, we just hard-code this. + */ + SEND_PCL( pConPriv->pJobFile, + "\033%-12345X@PJL SET RESOLUTION = 300\r\n" ); +#endif /* XP_PCL_LJ3 */ + + /* + * Initialize HP-GL/2 + */ + SEND_PCL( pConPriv->pJobFile, "\033E\033%0BIN,SP1,TR0;\033%0A" ); + + /* + * Stash the type of the document (used by PutDocumentData operation) + */ + pConPriv->isRaw = (type == XPDocRaw); + + return Success; +} + +int +PclEndDoc( pCon, cancel ) + XpContextPtr pCon; + Bool cancel; +{ + /* + * XXX What should I do if I get cancel == TRUE? + */ + return Success; +} + +/* + * PclDocumentData() + * + * Hand any pre-generated PDL down to the spool files, formatting it + * as necessary to fit the given window. + * + */ + +#define DOC_PCL 1 +#define DOC_HPGL 2 + +int +PclDocumentData( pCon, pDraw, pData, len_data, pFmt, len_fmt, pOpt, len_opt, client) + XpContextPtr pCon; + DrawablePtr pDraw; + char *pData; + int len_data; + char *pFmt; + int len_fmt; + char *pOpt; + int len_opt; + ClientPtr client; +{ + int type; + PclContextPrivPtr pPriv = (PclContextPrivPtr) + pCon->devPrivates[PclContextPrivateIndex].ptr; + XpOidDocFmtList *formats; + XpOidDocFmt *f; + char t[80]; + xRectangle repro; + + /* + * Verify the input format + */ + formats = XpGetDocFmtListAttr( pCon, XPPrinterAttr, + (pPriv->isRaw) ? + xpoid_att_xp_raw_formats_supported : + xpoid_att_xp_embedded_formats_supported, + NULL ); + f = XpOidDocFmtNew( pFmt ); + if( !XpOidDocFmtListHasFmt( formats, f ) ) + { + XpOidDocFmtListDelete( formats ); + XpOidDocFmtDelete( f ); + return BadMatch; + } + XpOidDocFmtListDelete( formats ); + + if( !(pPriv->isRaw) ) + { + if( !strcmp( f->format, "PCL" ) ) + type = DOC_PCL; + else if( !strcmp( f->format, "HPGL" ) ) + type = DOC_HPGL; + else + { + XpOidDocFmtDelete( f ); + return BadMatch; + } + + switch( type ) + { + case DOC_HPGL: + /* + * Move the picture frame to the appropriate place on the page, + * then assume that the embedded code will scale it properly. + */ + sprintf( t, "\033&l0E\033*p%dx%dY", + pDraw->x - 75, + pDraw->y ); + SEND_PCL( pPriv->pPageFile, t ); + + sprintf( t, "\033*c%dx%dY\033*coT", + (int)( pDraw->width / 300.0 * 720.0 ), + (int)( pDraw->height / 300.0 * 720.0 ) ); + SEND_PCL( pPriv->pPageFile, t ); + break; + } + } + + + /* + * Send the data down the pipe + */ + SEND_PCL_COUNT( pPriv->pPageFile, pData, len_data ); + + /* + * If it's not a raw document, clean up the embedding + */ + if( !(pPriv->isRaw) ) + switch( type ) + { + case DOC_HPGL: + /* + * Reset the picture frame + */ + XpGetReproductionArea( pCon, &repro ); + + sprintf( t, "\033&l0E\033*p%dx%dY", repro.x - 75, repro.y ); + SEND_PCL( pPriv->pPageFile, t ); + + sprintf( t, "\033*c%dx%dY\033*c0T", + (int)(repro.width / 300.0 * 720.0), + (int)(repro.height / 300.0 * 720.0) ); + SEND_PCL( pPriv->pPageFile, t ); + + sprintf( t, "\033%%0BSC%d,%d,%d,%d;\033%%0A", repro.x, repro.x + + repro.width, repro.y + repro.height, repro.y ); + SEND_PCL( pPriv->pPageFile, t ); + break; + } + + XpOidDocFmtDelete( f ); + return Success; +} + +/* + * + * PclGetDocumentData() + * + * This function allows the driver to send the generated PCL back to + * the client. + * + * XXX This function is barely spec'ed, much less implemented! + */ + +int +PclGetDocumentData( pCon, client, maxBufferSize ) + XpContextPtr pCon; + ClientPtr client; + int maxBufferSize; +{ + PclContextPrivPtr pPriv = (PclContextPrivPtr) + pCon->devPrivates[PclContextPrivateIndex].ptr; + + pPriv->getDocClient = client; + pPriv->getDocBufSize = maxBufferSize; + + return Success; +} diff --git a/Xprint/pcl/PclSFonts.c b/Xprint/pcl/PclSFonts.c new file mode 100644 index 000000000..9f19a2387 --- /dev/null +++ b/Xprint/pcl/PclSFonts.c @@ -0,0 +1,431 @@ +/* $Xorg: PclSFonts.c,v 1.3 2000/08/17 19:48:08 cpqbld Exp $ */ +/******************************************************************* +** +** ********************************************************* +** * +** * File: PclSFonts.c +** * +** * Contents: +** * Send Soft Font Download data to the specified +** * file pointer. +** * +** * Created: 3/4/96 +** * +** ********************************************************* +** +********************************************************************/ +/* +(c) Copyright 1996 Hewlett-Packard Company +(c) Copyright 1996 International Business Machines Corp. +(c) Copyright 1996 Sun Microsystems, Inc. +(c) Copyright 1996 Novell, Inc. +(c) Copyright 1996 Digital Equipment Corp. +(c) Copyright 1996 Fujitsu Limited +(c) Copyright 1996 Hitachi, Ltd. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the names of the copyright holders shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from said +copyright holders. +*/ + + +#include <stdio.h> +#include "Pcl.h" + +static char tmp1; +static short tmp2; +#define Put1byte(fp, x) tmp1=x; fwrite((char *)&tmp1, 1, 1, fp) +#define Put2bytes(fp, x) tmp2=x; fwrite((char *)&tmp2, 2, 1, fp) + +#define ESC 0x1b +#define SYMBOL_SET 277 +#define MAX_CINDEX 255 + +static unsigned int PclDownloadChar(FILE *,PclCharDataPtr,unsigned short,unsigned char); +static unsigned int PclDownloadHeader(FILE *, PclFontDescPtr, unsigned short); + +#ifdef PCL_FONT_COMPRESS +static unsigned char *compress_bitmap_data(PclCharDataPtr, unsigned int *); +#endif /* PCL_FONT_COMPRESS */ + +/* -*- PclDownloadSoftFont8 -*- + * Send the Character Definition Command for 8-bit font + * **************************************************************************/ +void +PclDownloadSoftFont8( + FILE *fp, + PclSoftFontInfoPtr pSoftFontInfo, + PclFontHead8Ptr pfh, + PclCharDataPtr pcd, + unsigned char *code, + int flag +) +{ + /* + * Check whether the font header has already been downloaded. + * If not, download it. + */ + + if ( !pfh->fid ) { + pfh->fid = pSoftFontInfo->cur_max_fid++; + PclDownloadHeader(fp, &(pfh->fd), pfh->fid); + } + pfh->index[*code] = *code; + PclDownloadChar(fp, pcd, pfh->fid, pfh->index[*code]); + +} + +/* -*- PclDownloadSoftFont16 -*- + * Send the Character Definition Command for 16 bit font + * **************************************************************************/ +void +PclDownloadSoftFont16( + FILE *fp, + PclSoftFontInfoPtr pSoftFontInfo, + PclFontHead16Ptr pfh, + PclCharDataPtr pcd, + unsigned char row, + unsigned char col, + int flag +) +{ + /* + * Check whether the font header is already downloaded. + * If not, download it. + */ + + if ( !pfh->cur_cindex ) { + pfh->cur_fid = pSoftFontInfo->cur_max_fid++; + PclDownloadHeader(fp, &(pfh->fd), pfh->cur_fid); + } + pfh->index[row][col].fid = pfh->cur_fid; + pfh->index[row][col].cindex = pfh->cur_cindex++; + if ( pfh->cur_cindex > MAX_CINDEX ) + pfh->cur_cindex = 0; + + PclDownloadChar(fp, pcd, pfh->index[row][col].fid, pfh->index[row][col].cindex); +} + +/* -*- PclCreateSoftFontInfo -*- + * Create and Initialize the structure for storing the information + * of the downloaded soft font. + * **************************************************************************/ +PclSoftFontInfoPtr +PclCreateSoftFontInfo( +) +{ +PclSoftFontInfoPtr pSoftFontInfo; + + pSoftFontInfo = (PclSoftFontInfoPtr)xalloc(sizeof(PclSoftFontInfoRec)); + if ( pSoftFontInfo == (PclSoftFontInfoPtr) NULL) + return (PclSoftFontInfoPtr) NULL; + pSoftFontInfo->phead8 = (PclFontHead8Ptr)NULL; + pSoftFontInfo->phead16 = (PclFontHead16Ptr)NULL; + pSoftFontInfo->pinfont = (PclInternalFontPtr)NULL; + pSoftFontInfo->cur_max_fid = 1; + return pSoftFontInfo; +} + +/* -*- PclDestroySoftFontInfo -*- + * Destroy the soft font information structure + * **************************************************************************/ +void +PclDestroySoftFontInfo( PclSoftFontInfoPtr pSoftFontInfo ) +{ +PclFontHead8Ptr pfh8, pfh8_next; +PclFontHead16Ptr pfh16, pfh16_next; +PclInternalFontPtr pin, pin_next; +unsigned char nindex_row, nindex_col; +int i, j; + + if ( pSoftFontInfo == (PclSoftFontInfoPtr) NULL ) + return; + + pfh8 = pSoftFontInfo->phead8; + while (pfh8 != (PclFontHead8Ptr) NULL) { + xfree(pfh8->fontname); + xfree(pfh8->index); + pfh8_next = pfh8->next; + xfree(pfh8); + pfh8 = pfh8_next; + } + + pfh16 = pSoftFontInfo->phead16; + while (pfh16 != (PclFontHead16Ptr) NULL) { + xfree(pfh16->fontname); + nindex_col = pfh16->lastCol - pfh16->firstCol + 1; + nindex_row = pfh16->lastRow - pfh16->firstRow + 1; + for (i=0; i<nindex_row; i++) + xfree(pfh16->index[i]); + xfree(pfh16->index); + pfh16_next = pfh16->next; + xfree(pfh16); + pfh16 = pfh16_next; + } + + pin = pSoftFontInfo->pinfont; + while (pin != (PclInternalFontPtr) NULL) { + xfree(pin->fontname); + pin_next = pin->next; + xfree(pin); + pin = pin_next; + } + + xfree(pSoftFontInfo); +} + +/* -*- PclDownloadHeader -*- + * Send the Font Header Commnad. + * Format 0 : Font Header for Pcl Bitmapped Fonts + * Format 20 : Font Header for Resolution Specified Bitmapped Fonts + * **************************************************************************/ +static unsigned int +PclDownloadHeader( + FILE *fp, + PclFontDescPtr fd, + unsigned short fid +) +{ +int nbytes; + +#ifdef XP_PCL_LJ3 + nbytes = 64; +#else + nbytes = 68; +#endif /* XP_PCL_LJ3 */ + /* + * Font ID Command : Esc *c#D + * (Default = 0, Range = 0 - 32767) + */ + fprintf(fp, "%c*c%dD", ESC, fid); + + /* + * Font Header Commnad : Esc )s#W[font header data] + * (Default = 0, Range = 0 - 32767) + */ + fprintf(fp, "%c)s%dW", ESC, nbytes); + + Put2bytes(fp, nbytes); /* Font Description Size */ +#ifdef XP_PCL_LJ3 + Put1byte(fp, 0); /* Header Format */ +#else + Put1byte(fp, 20); /* Header Format */ +#endif /* XP_PCL_LJ3 */ + Put1byte(fp, 2); /* Font Type */ + Put2bytes(fp, 0); /* Style MSB */ + Put2bytes(fp, fd->ascent); /* BaseLine Position */ + Put2bytes(fp, fd->cellwidth); /* Cell Width */ + Put2bytes(fp, fd->cellheight); /* Cell Height */ + Put1byte(fp, 0); /* Orienation */ + Put1byte(fp, fd->spacing); /* Spacing */ + Put2bytes(fp, SYMBOL_SET); /* Symbol Set */ + Put2bytes(fp, fd->pitch*4); /* font pitch */ + Put2bytes(fp, fd->cellheight * 4); /* Height */ + Put2bytes(fp, 0); /* x-Height */ + Put1byte(fp, 0); /* width type (normal) */ + Put1byte(fp, 0); /* Style LSB */ + Put1byte(fp, 0); /* Stroke Weight */ + Put1byte(fp, 5); /* Typeface LSB */ + Put1byte(fp, 0); /* Typeface MSB */ + Put1byte(fp, 0); /* Serif Style */ + Put1byte(fp, 0); /* Quality */ + Put1byte(fp, 0); /* Placement */ + Put1byte(fp, 0); /* Underline Position */ + Put1byte(fp, 0); /* Underline Thickness */ + Put2bytes(fp, fd->cellheight*1.2); /* Text Height */ + Put2bytes(fp, fd->cellwidth * 4); /* Text Width */ + Put2bytes(fp, 0); /* First Code */ + Put2bytes(fp, 255); /* Last Code */ + Put1byte(fp, 0); /* Pitch Extend */ + Put1byte(fp, 0); /* Height Extend */ + Put2bytes(fp, 0); /* Cap Height */ + Put2bytes(fp, 0); /* Font Number 1 */ + Put2bytes(fp, 0); /* Font Number 2 */ + Put2bytes(fp, 0); /* Font Name */ + Put2bytes(fp, 0); /* Font Name */ + Put2bytes(fp, 0); /* Font Name */ + Put2bytes(fp, 0); /* Font Name */ + Put2bytes(fp, 0); /* Font Name */ + Put2bytes(fp, 0); /* Font Name */ + Put2bytes(fp, 0); /* Font Name */ + Put2bytes(fp, 0); /* Font Name */ + +#ifdef XP_PCL_LJ3 + return 64; +#else + Put2bytes(fp, 300); /* X Resolution */ + Put2bytes(fp, 300); /* Y Resolution */ + return 68; +#endif /* XP_PCL_LJ3 */ + +} + +/* -*- PclDownloadCharacter -*- + * Send the Character Definition Command. + * **************************************************************************/ +static unsigned int +PclDownloadChar( + FILE *fp, + PclCharDataPtr cd, + unsigned short fid, + unsigned char code +) +{ +unsigned int nbytes, n; +unsigned char *raster; + + /* + * Font ID Command : Esc *c#D + * (Default = 0, Range = 0 - 32767) + * Character Code Command : Esc *c#E + * (Default = 0, Range = 0 - 65535) + */ + fprintf(fp, "%c*c%dd%dE", ESC, fid, code); + + /* + * Character Definition Command : Esc (s#W[character descriptor and data] + * (Default = N/A, Range = 0 - 32767) + */ + + nbytes = n = cd->height * ((cd->width + 7) / 8); +#ifdef PCL_FONT_COMPRESS + raster = compress_bitmap_data(cd, &nbytes); +#else + raster = (unsigned char *)NULL; +#endif /* PCL_FONT_COMPRESS */ + fprintf(fp, "%c(s%dW", ESC, nbytes + 16); + + Put1byte(fp, 4); /* Format */ + Put1byte(fp, 0); /* Continuation */ + Put1byte(fp, 14); /* Descriptor Size */ + if (raster) { /* Class */ + Put1byte(fp, 2); + } else { + Put1byte(fp, 1); /* Class */ + } + Put2bytes(fp, 0); /* Orientation */ + Put2bytes(fp, cd->h_offset); /* left offset */ + Put2bytes(fp, cd->v_offset); /* top offset */ + Put2bytes(fp, cd->width); /* character width */ + Put2bytes(fp, cd->height); /* character height */ + Put2bytes(fp, cd->font_pitch*4); /* delta X */ + + /* + * Raster Character Data + */ + if (raster) { + fwrite(raster, nbytes, 1, fp); + xfree(raster); + } else + fwrite(cd->raster_top, nbytes, 1, fp); + + return n + 16; +} + + +#ifdef PCL_FONT_COMPRESS +/* -*- compress_bitmap_data -*- + * Compress Bitmap data + * **************************************************************************/ +static unsigned char * +compress_bitmap_data( + PclCharDataPtr cd, + unsigned int *nbytes +) +{ +unsigned int byte_width; +unsigned char *raster, *rptr_s, *rptr_e, *rptr_end; +unsigned char *tmp_s, *tmp_ptr; +unsigned char *p; +unsigned char cur, pixel; +unsigned int num; + +int i, j, k, w; + + byte_width = (cd->width + 7) / 8; + *nbytes = cd->height * byte_width; + + /* Create buffer for storing compress bitmap glyph */ + raster = (unsigned char *)xalloc(*nbytes); + rptr_s = raster; + rptr_e = raster; + rptr_end = raster + *nbytes; + + tmp_s = (unsigned char *)xalloc(cd->width * 8 + 2); + + p = cd->raster_top; + for (i=0; i<cd->height; i++) { + tmp_ptr = tmp_s; + *tmp_ptr++ = 0; + if ( (*p>>7)&0x1 == 1 ) { + *tmp_ptr++ = 0; + cur = 1; + } else { + cur = 0; + } + num = 0; + for (j=0, w=0; j<byte_width; j++, p++) { + for (k=0; k<8 && w<cd->width; k++, w++) { + pixel = (*p>>(7-k))&0x1; + if ( pixel == cur ) { + num++; + } else { + cur = pixel; + while (num > 255) { + *tmp_ptr++ = 255; + *tmp_ptr++ = 0; + num -= 255; + } + *tmp_ptr++ = num; + num = 1; + } + } + } + if ( pixel == cur ) { + while (num > 255) { + *tmp_ptr++ = 255; + *tmp_ptr++ = 0; + num -= 255; + } + *tmp_ptr++ = num&0xff; + } else + *tmp_ptr++ = num; + + if ( ((rptr_e - rptr_s) == (tmp_ptr - tmp_s)) && + !memcmp(rptr_s+1, tmp_s+1, (tmp_ptr - tmp_s) - 1) ) + *rptr_s += 1; + else { + if ( rptr_e + (tmp_ptr - tmp_s) > rptr_end ) { + xfree(raster); + xfree(tmp_s); + return (unsigned char *)NULL; + } + memcpy (rptr_e, tmp_s, tmp_ptr - tmp_s); + rptr_s = rptr_e; + rptr_e = rptr_s + (tmp_ptr - tmp_s); + } + } + xfree(tmp_s); + *nbytes = rptr_e - raster; + + return raster; +} +#endif /* PCL_FONT_COMPRESS */ diff --git a/Xprint/pcl/PclSFonts.h b/Xprint/pcl/PclSFonts.h new file mode 100644 index 000000000..5992c12af --- /dev/null +++ b/Xprint/pcl/PclSFonts.h @@ -0,0 +1,112 @@ +/* $Xorg: PclSFonts.h,v 1.3 2000/08/17 19:48:08 cpqbld Exp $ */ +#ifndef _PCLFONTS_H +#define _PCLFONTS_H + +/* -*-H-*- +****************************************************************************** +****************************************************************************** +* +* File: PclFonts.h +* Description: Send Soft Font Download data to the specified file pointer. +* +* +****************************************************************************** +****************************************************************************** +*/ +/* +(c) Copyright 1996 Hewlett-Packard Company +(c) Copyright 1996 International Business Machines Corp. +(c) Copyright 1996 Sun Microsystems, Inc. +(c) Copyright 1996 Novell, Inc. +(c) Copyright 1996 Digital Equipment Corp. +(c) Copyright 1996 Fujitsu Limited +(c) Copyright 1996 Hitachi, Ltd. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the names of the copyright holders shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from said +copyright holders. +*/ + + +typedef struct { + unsigned char fid; /* sfont font ID */ + unsigned char cindex; /* character indext */ +} PclFontMapRec, PclFontMapPtr; + +typedef struct { + int h_offset; + int v_offset; + unsigned int width; + unsigned int height; + int font_pitch; + unsigned char *raster_top; +} PclCharDataRec, *PclCharDataPtr; + +typedef struct { + unsigned char spacing; + unsigned int pitch; + unsigned int cellheight; + unsigned int cellwidth; + int ascent; + int descent; +} PclFontDescRec, *PclFontDescPtr; + +typedef struct _PclFontHead8Rec { + char *fontname; + PclFontDescRec fd; + unsigned short fid; + unsigned char *index; + struct _PclFontHead8Rec *next; +} PclFontHead8Rec, *PclFontHead8Ptr; + +typedef struct _PclFontHead16Rec { + char *fontname; + PclFontDescRec fd; + unsigned short cur_fid; + unsigned char cur_cindex; + PclFontMapRec **index; + unsigned short firstCol; + unsigned short lastCol; + unsigned short firstRow; + unsigned short lastRow; + struct _PclFontHead16Rec *next; +} PclFontHead16Rec, *PclFontHead16Ptr; + +typedef struct _PclInternalFontRec { + char *fontname; + float pitch; + float height; + char *pcl_font_name; + char *spacing; + struct _PclInternalFontRec *next; +} PclInternalFontRec, *PclInternalFontPtr; + +typedef struct { + PclFontHead8Ptr phead8; + PclFontHead16Ptr phead16; + PclInternalFontPtr pinfont; + unsigned char cur_max_fid; +} PclSoftFontInfoRec, *PclSoftFontInfoPtr; + +#define MONOSPACE 0 +#define PROPSPACE 1 + +#endif /* _PCLFONTS_H */ diff --git a/Xprint/pcl/PclSpans.c b/Xprint/pcl/PclSpans.c new file mode 100644 index 000000000..38d1b7b01 --- /dev/null +++ b/Xprint/pcl/PclSpans.c @@ -0,0 +1,136 @@ +/* $Xorg: PclSpans.c,v 1.3 2000/08/17 19:48:08 cpqbld Exp $ */ +/******************************************************************* +** +** ********************************************************* +** * +** * File: PclSpans.c +** * +** * Contents: +** * Code to set and fill spans in the PCL DDX +** * +** * Created: 10/23/95 +** * +** ********************************************************* +** +********************************************************************/ +/* +(c) Copyright 1996 Hewlett-Packard Company +(c) Copyright 1996 International Business Machines Corp. +(c) Copyright 1996 Sun Microsystems, Inc. +(c) Copyright 1996 Novell, Inc. +(c) Copyright 1996 Digital Equipment Corp. +(c) Copyright 1996 Fujitsu Limited +(c) Copyright 1996 Hitachi, Ltd. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the names of the copyright holders shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from said +copyright holders. +*/ + + +#include "Pcl.h" +#include "gcstruct.h" +#include "windowstr.h" + +void +PclFillSpans( pDrawable, pGC, nSpans, pPoints, pWidths, fSorted ) + DrawablePtr pDrawable; + GCPtr pGC; + int nSpans; + DDXPointPtr pPoints; + int *pWidths; + int fSorted; +{ + char t[80]; + FILE *outFile; + int xoffset, yoffset; + xRectangle *rects, *r; + RegionPtr fillRegion, region; + int i; + int nbox; + BoxPtr pbox; + + if( PclUpdateDrawableGC( pGC, pDrawable, &outFile ) == FALSE ) + return; + + /* + * Build a region out of the spans + */ + rects = (xRectangle *)xalloc( nSpans * sizeof( xRectangle ) ); + xoffset = pDrawable->x; + yoffset = pDrawable->y; + + for( i = 0, r = rects; i < nSpans; i++, r++ ) + { + r->x = pPoints[i].x + xoffset; + r->y = pPoints[i].y + yoffset; + r->width = pWidths[i]; + r->height = 1; + } + fillRegion = miRectsToRegion( nSpans, rects, ( fSorted ) ? + CT_YSORTED : CT_UNSORTED ); + + /* + * Intersect this region with the clip region. Whatever's left, + * should be filled. + */ + miIntersect( region, fillRegion, pGC->clientClip ); + + pbox = REGION_RECTS( region ); + nbox = REGION_NUM_RECTS( region ); + + /* Enter HP-GL/2 */ + SEND_PCL( outFile, "\27%0B" ); + + while( nbox ) + { + sprintf( t, "PU%d,%d;RR%d,%d;", pbox->x1, pbox->y1, + pbox->x2, pbox->y2 ); + SEND_PCL( outFile, t ); + + nbox--; + pbox++; + } + + /* Go back to PCL */ + SEND_PCL( outFile, "\27%0A" ); + + /* + * Clean up the temporary regions + */ + miRegionDestroy( fillRegion ); + miRegionDestroy( region ); + xfree( rects ); +} + +void +PclSetSpans( pDrawable, pGC, pSrc, pPoints, pWidths, nSpans, fSorted ) + DrawablePtr pDrawable; + GCPtr pGC; + char *pSrc; + DDXPointPtr pPoints; + int *pWidths; + int nSpans; + int fSorted; +{ +} + + diff --git a/Xprint/pcl/PclText.c b/Xprint/pcl/PclText.c new file mode 100644 index 000000000..d01baabfa --- /dev/null +++ b/Xprint/pcl/PclText.c @@ -0,0 +1,937 @@ +/* $Xorg: PclText.c,v 1.5 2001/03/06 16:28:48 pookie Exp $ */ +/******************************************************************* +** +** ********************************************************* +** * +** * File: PclText.c +** * +** * Contents: +** * Character-drawing routines for the PCL DDX +** * +** * Created: 10/23/95 +** * +** ********************************************************* +** +********************************************************************/ +/* +(c) Copyright 1996 Hewlett-Packard Company +(c) Copyright 1996 International Business Machines Corp. +(c) Copyright 1996 Sun Microsystems, Inc. +(c) Copyright 1996 Novell, Inc. +(c) Copyright 1996 Digital Equipment Corp. +(c) Copyright 1996 Fujitsu Limited +(c) Copyright 1996 Hitachi, Ltd. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the names of the copyright holders shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from said +copyright holders. +*/ + +#ifdef DO_TWO_BYTE_PCL +#include "iconv.h" +#endif /* DO_TWO_BYTE_PCL */ +#include "gcstruct.h" +#include "windowstr.h" + +#include "Pcl.h" +#include "migc.h" +#include "Xatom.h" + +#include "PclSFonts.h" + +static PclFontHead8Ptr makeFontHeader8 (FontPtr, PclSoftFontInfoPtr); +static PclFontHead16Ptr makeFontHeader16(FontPtr, PclSoftFontInfoPtr); +static PclInternalFontPtr makeInternalFont(FontPtr, PclSoftFontInfoPtr); +static void fillFontDescData(FontPtr, PclFontDescPtr, unsigned int); +static PclCharDataPtr fillCharDescData(PclCharDataPtr, CharInfoPtr); +static void output_text(FILE *, PclContextPrivPtr, unsigned char); +static char * getFontName(FontPtr); +static char isInternal(FontPtr); +static void selectInternalFont(FILE *, PclInternalFontPtr, int); +static void selectSize(FILE *, PclContextPrivPtr, PclInternalFontPtr); +static char t[80]; + +#ifdef DO_TWO_BYTE_PCL +static void code_conv(PclSoftFontInfoPtr, FontPtr, char *, char *); +#endif /* DO_TWO_BYTE_PCL */ + +#define ESC 0x1b +#define PER 0x25 +#define ETX 0x3 +#define ETX_ALT 0x2a +#define DOWNLOAD_FONT 0 +#define INTERNAL_FONT 1 + +int +PclPolyText8( pDrawable, pGC, x, y, count, string ) + DrawablePtr pDrawable; + GCPtr pGC; + int x; + int y; + int count; + char *string; +{ +XpContextPtr pCon; +PclContextPrivPtr pConPriv; +unsigned long n, i; +int w; +CharInfoPtr charinfo[255], *chinfo; + +FILE *outFile; +PclSoftFontInfoPtr pSoftFontInfo; +PclFontHead8Ptr pfh8 = (PclFontHead8Ptr)NULL; +PclInternalFontPtr pin = (PclInternalFontPtr)NULL; +PclCharDataRec cd; +unsigned char *p; +unsigned char last_fid; +int max_ascent, max_descent; + +int nbox; +BoxPtr pbox; +BoxRec box; +RegionPtr drawRegion, region; +char font_type; + + if( PclUpdateDrawableGC( pGC, pDrawable, &outFile ) == FALSE ) + return x; + + GetGlyphs(pGC->font, (unsigned long)count, (unsigned char *)string, + Linear8Bit, &n, charinfo); + if ( n == 0 ) + return x; + + pCon = PclGetContextFromWindow( (WindowPtr)pDrawable ); + pConPriv = (PclContextPrivPtr) + pCon->devPrivates[PclContextPrivateIndex].ptr; + pSoftFontInfo = pConPriv->pSoftFontInfo; + font_type = isInternal(pGC->font); + if ( font_type == DOWNLOAD_FONT ) { + /* + * Create Soft Font Header Information + */ + pfh8 = makeFontHeader8(pGC->font, pSoftFontInfo); + if (!pfh8) + return x; + + /* + * exec Soft Font Downloading + */ + p = (unsigned char *)string; + for (i=0, chinfo=charinfo; i<n; i++, p++, chinfo++) { + if ( !pfh8->index[*p] ) { + fillCharDescData(&cd, *chinfo); + PclDownloadSoftFont8(pConPriv->pJobFile, pSoftFontInfo, + pfh8, &cd, p); + xfree(cd.raster_top); + } + } + + /* + * print characters + */ + MACRO_START( outFile, pConPriv ); + sprintf(t, "\033%%0B;PU%d,%dPD;TD1;DT%c,1;", + x + pDrawable->x, y + pDrawable->y + pGC->font->info.fontAscent, + ETX); + SAVE_PCL( outFile, pConPriv, t ); + SAVE_PCL_COUNT( outFile, pConPriv, "FI0;SS;LB", 9 ); + + last_fid = 0; + w = 0; + max_ascent = charinfo[0]->metrics.ascent; + max_descent = charinfo[0]->metrics.descent; + p = (unsigned char *)string; + for (i=0, chinfo=charinfo; i<n; i++, p++, chinfo++) { + if ( last_fid != pfh8->fid ) { + sprintf(t, "%c;FI%d;SS;LB", ETX, pfh8->fid); + SAVE_PCL( outFile, pConPriv, t ); + + last_fid = pfh8->fid; + } + + output_text(outFile, pConPriv, pfh8->index[*p]); + + w += (*chinfo)->metrics.characterWidth; + max_ascent = MAX(max_ascent, (*chinfo)->metrics.ascent); + max_descent = MAX(max_descent, (*chinfo)->metrics.descent); + } + + sprintf(t, "%c", ETX); + SAVE_PCL_COUNT( outFile, pConPriv, t, 1 ); + sprintf(t, "TD0;\033%%1A"); + SAVE_PCL( outFile, pConPriv, t ); + MACRO_END( outFile ); + + } else { + char *internalFont; + int pixel_size; + int fid = 0; + + pin = makeInternalFont(pGC->font, pSoftFontInfo); + if (!pin) + return x; + + selectInternalFont(outFile, pin, fid); + + /* + * print characters + */ + MACRO_START( outFile, pConPriv ); + sprintf(t, "\033%%0B;PU%d,%dPD;TD1;DT%c,1;", + x + pDrawable->x, y + pDrawable->y + pGC->font->info.fontAscent, + ETX); + SAVE_PCL( outFile, pConPriv, t ); + selectSize(outFile, pConPriv, pin); + SAVE_PCL_COUNT( outFile, pConPriv, "FI0;SS;LB", 9 ); + + w = 0; + max_ascent = charinfo[0]->metrics.ascent; + max_descent = charinfo[0]->metrics.descent; + p = (unsigned char *)string; + for (i=0, chinfo=charinfo; i<n; i++, p++, chinfo++) { + output_text(outFile, pConPriv, *p); + + w += (*chinfo)->metrics.characterWidth; + max_ascent = MAX(max_ascent, (*chinfo)->metrics.ascent); + max_descent = MAX(max_descent, (*chinfo)->metrics.descent); + } + sprintf(t, "%c", ETX); + SAVE_PCL_COUNT( outFile, pConPriv, t, 1 ); + sprintf(t, "TD0;\033%%1A"); + SAVE_PCL( outFile, pConPriv, t ); + MACRO_END( outFile ); + } + + /* + * Convert the collection of rectangles into a proper region, then + * intersect it with the clip region. + */ + box.x1 = x + pDrawable->x; + box.y1 = y - max_ascent + pDrawable->y + pGC->font->info.fontAscent; + box.x2 = x + w + pDrawable->x; + box.y2 = y + max_descent + pDrawable->y + pGC->font->info.fontAscent; + + drawRegion = miRegionCreate( &box, 0 ); + region = miRegionCreate( NULL, 0 ); + miIntersect( region, drawRegion, + ((PclGCPrivPtr)pGC->devPrivates[PclGCPrivateIndex].ptr) + ->pCompositeClip ); + + /* + * For each rectangle in the clip region, set the HP-GL/2 "input + * window" and render the entire polyline to it. + */ + pbox = REGION_RECTS( region ); + nbox = REGION_NUM_RECTS( region ); + + PclSendData(outFile, pConPriv, pbox, nbox, 1.0); + + /* + * Clean up the temporary regions + */ + miRegionDestroy( drawRegion ); + miRegionDestroy( region ); + + return x+w; +} + +int +PclPolyText16( pDrawable, pGC, x, y, count, string ) + DrawablePtr pDrawable; + GCPtr pGC; + int x; + int y; + int count; + unsigned short *string; +{ +XpContextPtr pCon; +PclContextPrivPtr pConPriv; +unsigned long n, i; +int w; +CharInfoPtr charinfo[255], *chinfo; + +FILE *outFile; +PclSoftFontInfoPtr pSoftFontInfo; +PclFontHead16Ptr pfh16 = (PclFontHead16Ptr)NULL; +PclInternalFontPtr pin = (PclInternalFontPtr)NULL; +PclCharDataRec cd; +FontInfoPtr pfi; +unsigned char row, col; +char *p; +unsigned char last_fid; +int max_ascent, max_descent; +unsigned short def; + +int nbox; +BoxPtr pbox; +BoxRec box; +RegionPtr drawRegion, region; +char font_type; + + if( PclUpdateDrawableGC( pGC, pDrawable, &outFile ) == FALSE ) + return x; + + GetGlyphs(pGC->font, (unsigned long)count, (unsigned char *)string, + (FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit, + &n, charinfo); + + pCon = PclGetContextFromWindow( (WindowPtr)pDrawable ); + pConPriv = (PclContextPrivPtr) + pCon->devPrivates[PclContextPrivateIndex].ptr; + pSoftFontInfo = pConPriv->pSoftFontInfo; + + font_type = isInternal(pGC->font); + if ( font_type == DOWNLOAD_FONT ) { + /* + * Create Soft Font Header Information + */ + pfh16 = makeFontHeader16(pGC->font, pSoftFontInfo); + if (!pfh16) + return x; + + /* + * exec Soft Font Downloading + */ + pfi = (FontInfoRec *)&pGC->font->info; + p = (char *)string; + for (i=0, p=(char *)string, chinfo=charinfo; i<n; i++, p+=2, chinfo++) { + row = *p & 0xff; + col = *(p+1) & 0xff; + if ( (pfi->firstRow <= row) && (row <= pfi->lastRow) + && (pfi->firstCol <= col) && (col <= pfi->lastCol) ) { + row = row - pfi->firstRow; + col = col - pfi->firstCol; + } else { + def = pfi->defaultCh; + row = (def>>8)&0xff - pfi->firstRow; + col = def&0xff - pfi->firstCol; + } + if ( !pfh16->index[row][col].fid ) { + fillCharDescData(&cd, *chinfo); + PclDownloadSoftFont16(pConPriv->pJobFile, pSoftFontInfo, + pfh16, &cd, row, col); + xfree(cd.raster_top); + } + } + + /* + * print characters + */ + MACRO_START( outFile, pConPriv ); + sprintf(t, "\033%%0B;PU%d,%dPD;TD1;DT%c,1;", + x + pDrawable->x, y + pDrawable->y + pGC->font->info.fontAscent, + ETX); + SAVE_PCL( outFile, pConPriv, t ); + SAVE_PCL_COUNT( outFile, pConPriv, "FI0;SS;LB", 9 ); + + last_fid = 0; + + w = 0; + max_ascent = charinfo[0]->metrics.ascent; + max_descent = charinfo[0]->metrics.descent; + for (i=0, p=(char *)string, chinfo=charinfo; i<n; i++, p+=2, chinfo++) { + row = *p & 0xff; + col = *(p+1) & 0xff; + if ( (pfi->firstRow <= row) && (row <= pfi->lastRow) + && (pfi->firstCol <= col) && (col <= pfi->lastCol) ) { + row = row - pfi->firstRow; + col = col - pfi->firstCol; + } else { + def = pfi->defaultCh; + row = (def>>8)&0xff - pfi->firstRow; + col = def&0xff - pfi->firstCol; + } + if ( last_fid != pfh16->index[row][col].fid ) { + sprintf(t, "%cFI%d;SS;LB", + ETX, pfh16->index[row][col].fid); + SAVE_PCL( outFile, pConPriv, t ); + last_fid = pfh16->index[row][col].fid; + } + + output_text(outFile, pConPriv, pfh16->index[row][col].cindex); + + w += (*chinfo)->metrics.characterWidth; + max_ascent = MAX(max_ascent, (*chinfo)->metrics.ascent); + max_descent = MAX(max_descent, (*chinfo)->metrics.descent); + } + sprintf(t, "%c", ETX); + SAVE_PCL_COUNT( outFile, pConPriv, t, 1 ); + sprintf(t, "TD0;\033%%1A"); + SAVE_PCL( outFile, pConPriv, t ); + MACRO_END( outFile ); + + } else { +#ifdef DO_TWO_BYTE_PCL + char *internalFont; + int pixel_size; + int fid = 0; + + pin = makeInternalFont(pGC->font, pSoftFontInfo); + if (!pin) + return x; + + selectInternalFont(outFile, pin, fid); + fprintf(outFile, "%c&t31P", ESC); + + /* + * print characters + */ + MACRO_START( outFile, pConPriv ); + sprintf(t, "\033%%0B;PU%d,%dPD;TD1;DT%c,1;", + x + pDrawable->x, y + pDrawable->y + pGC->font->info.fontAscent, + ETX); + SAVE_PCL( outFile, pConPriv, t ); + sprintf(t, "TD0;\033%%1A"); + SAVE_PCL( outFile, pConPriv, t ); + + w = 0; + last_fid = 0; + max_ascent = charinfo[0]->metrics.ascent; + max_descent = charinfo[0]->metrics.descent; + for (i=0, p=(char *)string, chinfo=charinfo; i<n; i++, p+=2, chinfo++) { + char tobuf[3]; + code_conv(pSoftFontInfo, pGC->font, (char *)p, tobuf); + fprintf(outFile, "%c%c", tobuf[0], tobuf[1]); + + w += (*chinfo)->metrics.characterWidth; + max_ascent = MAX(max_ascent, (*chinfo)->metrics.ascent); + max_descent = MAX(max_descent, (*chinfo)->metrics.descent); + } + MACRO_END( outFile ); +#else + return x; +#endif /* DO_TWO_BYTE_PCL */ + } + + /* + * Convert the collection of rectangles into a proper region, then + * intersect it with the clip region. + */ + box.x1 = x + pDrawable->x; + box.y1 = y - max_ascent + pDrawable->y + pGC->font->info.fontAscent; + box.x2 = x + w + pDrawable->x; + box.y2 = y + max_descent + pDrawable->y + pGC->font->info.fontAscent; + + drawRegion = miRegionCreate( &box, 0 ); + region = miRegionCreate( NULL, 0 ); + miIntersect( region, drawRegion, + ((PclGCPrivPtr)pGC->devPrivates[PclGCPrivateIndex].ptr) + ->pCompositeClip ); + + /* + * For each rectangle in the clip region, set the HP-GL/2 "input + * window" and render the entire polyline to it. + */ + pbox = REGION_RECTS( region ); + nbox = REGION_NUM_RECTS( region ); + + PclSendData(outFile, pConPriv, pbox, nbox, 1.0); + + /* + * Clean up the temporary regions + */ + miRegionDestroy( drawRegion ); + miRegionDestroy( region ); + + return x+w; +} + +void +PclImageText8( pDrawable, pGC, x, y, count, string ) + DrawablePtr pDrawable; + GCPtr pGC; + int x, y; + int count; + char *string; +{ +} + +void +PclImageText16( pDrawable, pGC, x, y, count, string ) + DrawablePtr pDrawable; + GCPtr pGC; + int x; + int y; + int count; + unsigned short *string; +{ +} + +void +PclImageGlyphBlt( pDrawable, pGC, x, y, nGlyphs, pCharInfo, pGlyphBase ) + DrawablePtr pDrawable; + GCPtr pGC; + int x, y; + unsigned int nGlyphs; + CharInfoPtr *pCharInfo; + pointer pGlyphBase; +{ +} + +void +PclPolyGlyphBlt( pDrawable, pGC, x, y, nGlyphs, pCharInfo, pGlyphBase ) + DrawablePtr pDrawable; + GCPtr pGC; + int x, y; + unsigned int nGlyphs; + CharInfoPtr *pCharInfo; + pointer pGlyphBase; +{ +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +static PclFontHead8Ptr +makeFontHeader8(FontPtr pfont, PclSoftFontInfoPtr pSoftFontInfo) +{ +PclFontHead8Ptr phead8 = pSoftFontInfo->phead8; +PclFontHead8Ptr pfh8 = phead8; +PclFontHead8Ptr prev = (PclFontHead8Ptr)NULL; +FontInfoPtr pfi; +char *fontname; +unsigned char nindex; +int i, j; +unsigned long n; +CharInfoPtr charinfo[1]; +unsigned int space_width; + + if (pSoftFontInfo == (PclSoftFontInfoPtr) NULL) + return (PclFontHead8Ptr)NULL; + + /* + * Verify it has already been created, if so, return it. + */ + if ( (fontname = getFontName(pfont)) == (char *)NULL) + return (PclFontHead8Ptr)NULL; + + while (pfh8 != (PclFontHead8Ptr) NULL) { + if (!strcmp(pfh8->fontname, fontname)) + return pfh8; + prev = pfh8; + pfh8 = pfh8->next; + } + + /* + * Create Font Header Information + */ + pfh8 = (PclFontHead8Ptr)xalloc(sizeof(PclFontHead8Rec)); + if (pfh8 == (PclFontHead8Ptr)NULL) + return (PclFontHead8Ptr)NULL; + + pfi = (FontInfoRec *)&pfont->info; + GetGlyphs(pfont, 1, (unsigned char *)&pfi->defaultCh, + Linear8Bit, &n, charinfo); + if ( n ) + space_width = charinfo[0]->metrics.characterWidth; + else + space_width = FONTMAXBOUNDS(pfont,characterWidth); + + fillFontDescData(pfont, &(pfh8->fd), space_width); + pfh8->fid = 0; + pfh8->fontname = (char *)xalloc(strlen(fontname) + 1); + if (pfh8->fontname == (char *)NULL) { + xfree(pfh8); + return (PclFontHead8Ptr) NULL; + } + strcpy(pfh8->fontname, fontname); + + nindex = 0xff; + pfh8->index = (unsigned char *)xalloc(nindex); + if ( pfh8->index == (unsigned char *) NULL ) { + xfree(pfh8->fontname); + xfree(pfh8); + return (PclFontHead8Ptr) NULL; + } + + for (i=0; i<=nindex; i++) + pfh8->index[i] = 0x0; + + pfh8->next = (PclFontHead8Ptr)NULL; + + if ( prev == (PclFontHead8Ptr) NULL) + pSoftFontInfo->phead8 = pfh8; + else + prev->next = pfh8; + + return pfh8; +} + +static PclFontHead16Ptr +makeFontHeader16(FontPtr pfont, PclSoftFontInfoPtr pSoftFontInfo) +{ +PclFontHead16Ptr phead16 = pSoftFontInfo->phead16; +PclFontHead16Ptr pfh16 = phead16; +PclFontHead16Ptr prev = (PclFontHead16Ptr)NULL; +PclFontMapRec ** index; +FontInfoPtr pfi; +char *fontname; +unsigned char nindex_row, nindex_col; +int i, j; +unsigned long n; +CharInfoPtr charinfo[1]; +unsigned int space_width; + + if (pSoftFontInfo == (PclSoftFontInfoPtr) NULL) + return (PclFontHead16Ptr)NULL; + + /* + * Verify it has already been created, if so, return it. + */ + if ( (fontname = getFontName(pfont)) == (char *)NULL) + return (PclFontHead16Ptr)NULL; + + while (pfh16 != (PclFontHead16Ptr) NULL) { + if (!strcmp(pfh16->fontname, fontname)) + return pfh16; + prev = pfh16; + pfh16 = pfh16->next; + } + + /* + * Create Font Header Information + */ + pfh16 = (PclFontHead16Ptr)xalloc(sizeof(PclFontHead16Rec)); + if (pfh16 == (PclFontHead16Ptr)NULL) + return (PclFontHead16Ptr)NULL; + + pfi = (FontInfoRec *)&pfont->info; + GetGlyphs(pfont, 1, (unsigned char *)&pfi->defaultCh, + (FONTLASTROW(pfont) == 0) ? Linear16Bit : TwoD16Bit, + &n, charinfo); + + if ( n ) + space_width = charinfo[0]->metrics.characterWidth; + else + space_width = FONTMAXBOUNDS(pfont,characterWidth); + + fillFontDescData(pfont, &(pfh16->fd), space_width); + pfh16->cur_fid = 0; + pfh16->cur_cindex = 0; + pfh16->fontname = (char *)xalloc(strlen(fontname) + 1); + if (pfh16->fontname == (char *)NULL) { + xfree(pfh16); + return (PclFontHead16Ptr) NULL; + } + strcpy(pfh16->fontname, fontname); + + pfi = (FontInfoRec *)&pfont->info; + nindex_col = pfi->lastCol - pfi->firstCol + 1; + nindex_row = pfi->lastRow - pfi->firstRow + 1; + index = (PclFontMapRec **)xalloc(sizeof(PclFontMapRec *)*nindex_row); + if (index == (PclFontMapRec **)NULL) { + xfree(pfh16->fontname); + xfree(pfh16); + return (PclFontHead16Ptr) NULL; + } + for (i=0; i<nindex_row; i++) { + index[i] = (PclFontMapRec *)xalloc(sizeof(PclFontMapRec)*nindex_col); + if (index[i] == (PclFontMapRec *)NULL) { + for(j=0; j<i; j++) + xfree(index[j]); + xfree(pfh16->fontname); + xfree(pfh16); + return (PclFontHead16Ptr) NULL; + } + for (j=0; j<=nindex_col; j++) + index[i][j].fid = 0x0; + } + + pfh16->index = index; + pfh16->firstCol = pfi->firstCol; + pfh16->lastCol = pfi->lastCol; + pfh16->firstRow = pfi->firstRow; + pfh16->lastRow = pfi->lastRow; + pfh16->next = (PclFontHead16Ptr)NULL; + + if ( prev == (PclFontHead16Ptr) NULL) + pSoftFontInfo->phead16 = pfh16; + else + prev->next = pfh16; + + return pfh16; +} + +static PclInternalFontPtr +makeInternalFont(FontPtr pfont, PclSoftFontInfoPtr pSoftFontInfo) +{ +PclInternalFontPtr pinfont = pSoftFontInfo->pinfont; +PclInternalFontPtr pin = pinfont; +PclInternalFontPtr prev = (PclInternalFontPtr)NULL; +FontPropPtr props; +FontInfoPtr pfi; +char *fontname; +Atom xa_pcl_font_name, xa_res, xa_ave_width, xa_spacing; +int res, width; +int mask; +int i; + + if (pSoftFontInfo == (PclSoftFontInfoPtr) NULL) + return (PclInternalFontPtr)NULL; + + /* + * Verify it has already been created, if so, return it. + */ + if ( (fontname = getFontName(pfont)) == (char *)NULL) + return (PclInternalFontPtr)NULL; + + while (pin != (PclInternalFontPtr) NULL) { + if (!strcmp(pin->fontname, fontname)) + return pin; + prev = pin; + pin = pin->next; + } + + /* + * Create Internal Font Information + */ + pin = (PclInternalFontPtr)xalloc(sizeof(PclInternalFontRec)); + if (pin == (PclInternalFontPtr)NULL) + return (PclInternalFontPtr)NULL; + + pin->fontname = (char *)xalloc(strlen(fontname) + 1); + if (pin->fontname == (char *)NULL) { + xfree(pin); + return (PclInternalFontPtr) NULL; + } + strcpy(pin->fontname, fontname); + + xa_pcl_font_name = MakeAtom("PCL_FONT_NAME", strlen("PCL_FONT_NAME"), TRUE); + xa_res = MakeAtom("RESOLUTION_X", strlen("RESOLUTION_X"), TRUE); + xa_ave_width = MakeAtom("AVERAGE_WIDTH", strlen("AVERAGE_WIDTH"), TRUE); + xa_spacing = MakeAtom("SPACING", strlen("SPACING"), TRUE); + pfi = (FontInfoRec *)&pfont->info; + props = pfi->props; + + mask = 0; + for (i=0; i<pfi->nprops; i++, props++) { + if ( props->name == xa_pcl_font_name ) { + pin->pcl_font_name = NameForAtom(props->value); + mask |= 0x1; + } else if ( props->name == XA_POINT_SIZE ) { + pin->height = (float) props->value / 10.0; + mask |= 0x2; + } else if ( props->name == xa_res ) { + res = (int) props->value; + mask |= 0x4; + } else if ( props->name == xa_ave_width ) { + width = (int) props->value / 10; + mask |= 0x8; + } else if ( props->name == xa_spacing ) { + pin->spacing = NameForAtom(props->value); + mask |= 0x10; + } + } + if ( mask != 0x1f ) { + xfree(pin->fontname); + xfree(pin); + return (PclInternalFontPtr) NULL; + } + + if ( *pin->spacing != 'P' || *pin->spacing != 'p' ) + pin->pitch = (float) 300.0 / width; /* Hard-Code: Resolution is 300 */ + + pin->next = (PclInternalFontPtr)NULL; + if ( prev == (PclInternalFontPtr) NULL) + pSoftFontInfo->pinfont = pin; + else + prev->next = pin; + + return pin; +} + +static void +fillFontDescData(FontPtr pfont, PclFontDescPtr pfd, unsigned int space) +{ +FontInfoPtr pfi; + + pfi = (FontInfoRec *)&pfont->info; + + if ( (pfi->maxbounds.leftSideBearing == pfi->minbounds.leftSideBearing) + && (pfi->maxbounds.rightSideBearing == pfi->minbounds.rightSideBearing) + && (pfi->maxbounds.characterWidth == pfi->minbounds.characterWidth) + && (pfi->maxbounds.ascent == pfi->minbounds.ascent) + && (pfi->maxbounds.descent == pfi->minbounds.descent) + ) + pfd->spacing = MONOSPACE; + else + pfd->spacing = PROPSPACE; + + pfd->pitch = space; + pfd->cellheight = FONTMAXBOUNDS(pfont,ascent) + + FONTMAXBOUNDS(pfont,descent); + pfd->cellwidth = FONTMAXBOUNDS(pfont,rightSideBearing) + - FONTMINBOUNDS(pfont,leftSideBearing); + pfd->ascent = FONTMAXBOUNDS(pfont,ascent); /*FONTASCENT(pfont);*/ + pfd->descent = FONTMAXBOUNDS(pfont,descent); /*FONTDESCENT(pfont);*/ +} + +static PclCharDataPtr +fillCharDescData(PclCharDataPtr pcd, CharInfoPtr pci) +{ +unsigned int byte_width; +unsigned char *p; +register int nbyGlyphWidth; +unsigned char *pglyph, *pg; +int i, j; + + pcd->h_offset = pci->metrics.leftSideBearing; + pcd->v_offset = pci->metrics.ascent; + pcd->width = pci->metrics.rightSideBearing + - pci->metrics.leftSideBearing; + pcd->height = pci->metrics.ascent + pci->metrics.descent; + pcd->font_pitch = pci->metrics.characterWidth; + + byte_width = (pcd->width + 7)/8; + pcd->raster_top = (unsigned char *)xalloc(byte_width * pcd->height); + if (pcd->raster_top == (unsigned char *)NULL) + return (PclCharDataPtr)NULL; + + p = pcd->raster_top; + nbyGlyphWidth = GLYPHWIDTHBYTESPADDED(pci); + pglyph = FONTGLYPHBITS(pglyphBase, pci); + for (i=0; i<pcd->height; i++) { + pg = pglyph + nbyGlyphWidth * i; + for (j=0; j<byte_width; j++) + *p++ = *pg++; + } + return pcd; +} + +static void +output_text(FILE *outFile, + PclContextPrivPtr pConPriv, + unsigned char index) +{ + if ( index == ETX ) { + sprintf(t, "%c;DT%c,1;LB%c%c;DT%c,1;LB", + ETX, ETX_ALT, ETX, ETX_ALT, ETX); + SAVE_PCL( outFile, pConPriv, t ); + } else { + sprintf(t, "%c", index); + SAVE_PCL_COUNT( outFile, pConPriv, t, 1 ); + } +} + +static char * +getFontName(FontPtr pfont) +{ +int i; +FontInfoPtr pfi; +FontPropPtr props; +char *fontname; + + pfi = (FontInfoRec *)&pfont->info; + props = pfi->props; + fontname = (char *) NULL; + for (i=0; i<pfi->nprops; i++, props++) { + if ( props->name == XA_FONT ) { + fontname = (char *)NameForAtom(props->value); + break; + } + } + return fontname; +} + +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ +/* Internal Font Selection */ +/* * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * * */ + +static char +isInternal(FontPtr pfont) +{ +int i; +FontInfoPtr pfi; +FontPropPtr props; +Atom dest; + + dest = MakeAtom("PRINTER_RESIDENT_FONT", strlen("PRINTER_RESIDENT_FONT"), TRUE); + + pfi = (FontInfoRec *)&pfont->info; + props = pfi->props; + for (i=0; i<pfi->nprops; i++, props++) { + if ( props->name == dest && props->value == 2 ) + return INTERNAL_FONT; + } + return DOWNLOAD_FONT; +} + +static void +selectInternalFont(FILE *outFile, PclInternalFontPtr pin, int fid) +{ + fprintf(outFile, "%c*c%dD", ESC, fid); + if ( *pin->spacing == 'P' || *pin->spacing == 'p' ) + fprintf(outFile, pin->pcl_font_name, pin->height); + else + fprintf(outFile, pin->pcl_font_name, pin->pitch); + fprintf(outFile, "%c*c6F", ESC); +} + +static void +selectSize(FILE *outFile, + PclContextPrivPtr pConPriv, + PclInternalFontPtr pin) +{ + if ( *pin->spacing == 'P' || *pin->spacing == 'p' ) { + sprintf(t, "SD4,%f;", pin->height); + SAVE_PCL( outFile, pConPriv, t ); + } else { + sprintf(t, "SD3,%f;", pin->pitch); + SAVE_PCL( outFile, pConPriv, t ); + } + return; +} + +#ifdef DO_TWO_BYTE_PCL +static void +code_conv( + PclSoftFontInfoPtr pSoftFontInfo, + FontPtr pfont, + char *from, + char *to +) +{ +iconv_t cd; +char frombuf[9], *fromptr; +size_t inbyte = 5, outbyte=2; + + fromptr = frombuf; + frombuf[0] = 0x1b; /* Esc */ + frombuf[1] = 0x24; /* $ */ + frombuf[2] = 0x42; /* B */ + frombuf[3] = *from; + frombuf[4] = *(from+1); + frombuf[5] = 0x1b; /* Esc */ + frombuf[6] = 0x28; /* ( */ + frombuf[7] = 0x4a; /* J */ + frombuf[8] = 0x0; + if ((cd = iconv_open("sjis", "jis")) == (iconv_t)(-1)) { + *to = (unsigned char)NULL; + return; + } + + if ( iconv(cd, &fromptr, &inbyte, &to, &outbyte) == -1 ) + *to = (unsigned char)NULL; + + iconv_close(cd); + return; +} +#endif /* DO_TWO_BYTE_PCL */ diff --git a/Xprint/pcl/PclWindow.c b/Xprint/pcl/PclWindow.c new file mode 100644 index 000000000..7c830b897 --- /dev/null +++ b/Xprint/pcl/PclWindow.c @@ -0,0 +1,450 @@ +/* $Xorg: PclWindow.c,v 1.3 2000/08/17 19:48:08 cpqbld Exp $ */ +/******************************************************************* +** +** ********************************************************* +** * +** * File: PclWindow.c +** * +** * Contents: +** * Window code for Pcl driver. +** * +** * Created: 2/02/95 +** * +** ********************************************************* +** +********************************************************************/ +/* +(c) Copyright 1996 Hewlett-Packard Company +(c) Copyright 1996 International Business Machines Corp. +(c) Copyright 1996 Sun Microsystems, Inc. +(c) Copyright 1996 Novell, Inc. +(c) Copyright 1996 Digital Equipment Corp. +(c) Copyright 1996 Fujitsu Limited +(c) Copyright 1996 Hitachi, Ltd. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the names of the copyright holders shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from said +copyright holders. +*/ + + +#include <stdio.h> +#include <string.h> +#include <sys/wait.h> + +#include "mistruct.h" +#include "regionstr.h" +#include "windowstr.h" +#include "gcstruct.h" + +#include "Pcl.h" + +extern WindowPtr *WindowTable; + +/* + * The following list of strings defines the properties which will be + * placed on the screen's root window if the property was defined in + * the start-up configuration resource database. + */ +static /* const */ char *propStrings[] = { + DT_PRINT_JOB_HEADER, + DT_PRINT_JOB_TRAILER, + DT_PRINT_JOB_COMMAND, /* old-obsolete */ + DT_PRINT_JOB_EXEC_COMMAND, + DT_PRINT_JOB_EXEC_OPTIONS, + DT_PRINT_PAGE_HEADER, + DT_PRINT_PAGE_TRAILER, + DT_PRINT_PAGE_COMMAND, + (char *)NULL +}; + + +/* + * PclCreateWindow - watch for the creation of the root window. + * When it's created, register the screen with the print extension, + * and put the default command/header properties on it. + */ +/*ARGSUSED*/ + +Bool +PclCreateWindow( + register WindowPtr pWin) +{ + PclWindowPrivPtr pPriv; + +#if 0 + Bool status = Success; + ScreenPtr pScreen = pWin->drawable.pScreen; + PclScreenPrivPtr pScreenPriv = (PclScreenPrivPtr) + pScreen->devPrivates[PclScreenPrivateIndex].ptr; + PclWindowPrivPtr pWinPriv = (PclWindowPrivPtr) + pWin->devPrivates[PclWindowPrivateIndex].ptr; + + /* + * Initialize this window's private struct. + */ + pWinPriv->jobFileName = (char *)NULL; + pWinPriv->pJobFile = (FILE *)NULL; + pWinPriv->pageFileName = (char *)NULL; + pWinPriv->pPageFile = (FILE *)NULL; + + if(pWin->parent == (WindowPtr)NULL) /* root window? */ + { + Atom propName; /* type = XA_STRING */ + char *propVal; + int i; + XrmDatabase rmdb = pScreenPriv->resDB; + + /* + * Put the defaults spec'd in the config files in properties on this + * screen's root window. + */ + for(i = 0; propStrings[i] != (char *)NULL; i++) + { + if((propVal = _DtPrintGetPrinterResource(pWin, rmdb, + propStrings[i])) != + (char *)NULL) + { + propName = MakeAtom(propStrings[i], strlen(propStrings[i]), + TRUE); + ChangeWindowProperty(pWin, propName, XA_STRING, 8, + PropModeReplace, strlen(propVal), + (pointer)propVal, FALSE); + xfree(propVal); + } + } + } + + return status; +#endif + + /* + * Invalidate the window's private print context. + */ + pPriv = (PclWindowPrivPtr)pWin->devPrivates[PclWindowPrivateIndex].ptr; + pPriv->validContext = 0; + + return TRUE; +} + + +/*ARGSUSED*/ +Bool PclMapWindow( + WindowPtr pWindow) +{ + return TRUE; +} + +/*ARGSUSED*/ +Bool +PclPositionWindow( + register WindowPtr pWin, + int x, + int y) +{ + return TRUE; +} + +/*ARGSUSED*/ +Bool +PclUnmapWindow( + WindowPtr pWindow) +{ + return TRUE; +} + +/*ARGSUSED*/ +void +PclCopyWindow( + WindowPtr pWin, + DDXPointRec ptOldOrg, + RegionPtr prgnSrc) +{ +} + +/*ARGSUSED*/ +Bool +PclChangeWindowAttributes( + register WindowPtr pWin, + register unsigned long mask) +{ + if( pWin->backingStore != NotUseful ) + { + pWin->backingStore = NotUseful; + mask |= CWBackingStore; + } + + return TRUE; +} + + +/* + * This function is largely ripped from miPaintWindow, but modified so + * that the background is not painted to the root window, and so that + * the backing store is not referenced. + */ +void +PclPaintWindow( + WindowPtr pWin, + RegionPtr pRegion, + int what) +{ + int status; + WindowPtr pRoot; + +#define FUNCTION 0 +#define FOREGROUND 1 +#define TILE 2 +#define FILLSTYLE 3 +#define ABSX 4 +#define ABSY 5 +#define CLIPMASK 6 +#define SUBWINDOW 7 +#define COUNT_BITS 8 + + pointer gcval[7]; + pointer newValues [COUNT_BITS]; + + BITS32 gcmask, index, mask; + RegionRec prgnWin; + DDXPointRec oldCorner; + BoxRec box; + WindowPtr pBgWin; + GCPtr pGC; + register int i; + register BoxPtr pbox; + register ScreenPtr pScreen = pWin->drawable.pScreen; + register xRectangle *prect; + int numRects; + + gcmask = 0; + + /* + * We don't want to paint a window that has no place to put the + * PCL output. + */ + if( PclGetContextFromWindow( pWin ) == (XpContextPtr)NULL ) + return; + + if (what == PW_BACKGROUND) + { + switch (pWin->backgroundState) { + case None: + return; + case ParentRelative: + (*pWin->parent->drawable.pScreen->PaintWindowBackground) + (pWin->parent, pRegion, what); + return; + case BackgroundPixel: + newValues[FOREGROUND] = (pointer)pWin->background.pixel; + newValues[FILLSTYLE] = (pointer)FillSolid; + gcmask |= GCForeground | GCFillStyle; + break; + case BackgroundPixmap: + newValues[TILE] = (pointer)pWin->background.pixmap; + newValues[FILLSTYLE] = (pointer)FillTiled; + gcmask |= GCTile | GCFillStyle | GCTileStipXOrigin | + GCTileStipYOrigin; + break; + } + } + else + { + if (pWin->borderIsPixel) + { + newValues[FOREGROUND] = (pointer)pWin->border.pixel; + newValues[FILLSTYLE] = (pointer)FillSolid; + gcmask |= GCForeground | GCFillStyle; + } + else + { + newValues[TILE] = (pointer)pWin->border.pixmap; + newValues[FILLSTYLE] = (pointer)FillTiled; + gcmask |= GCTile | GCFillStyle | GCTileStipXOrigin + | GCTileStipYOrigin; + } + } + + prect = (xRectangle *)ALLOCATE_LOCAL(REGION_NUM_RECTS(pRegion) * + sizeof(xRectangle)); + if (!prect) + return; + + newValues[FUNCTION] = (pointer)GXcopy; + gcmask |= GCFunction | GCClipMask; + + i = pScreen->myNum; + pRoot = WindowTable[i]; + + pBgWin = pWin; + if (what == PW_BORDER) + { + while (pBgWin->backgroundState == ParentRelative) + pBgWin = pBgWin->parent; + } + + pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen); + if (!pGC) + { + DEALLOCATE_LOCAL(prect); + return; + } + /* + * mash the clip list so we can paint the border by + * mangling the window in place, pretending it + * spans the entire screen + */ + if (what == PW_BORDER) + { + prgnWin = pWin->clipList; + oldCorner.x = pWin->drawable.x; + oldCorner.y = pWin->drawable.y; + pWin->drawable.x = pWin->drawable.y = 0; + box.x1 = 0; + box.y1 = 0; + box.x2 = pScreen->width; + box.y2 = pScreen->height; + REGION_INIT(pScreen, &pWin->clipList, &box, 1); + pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER; + newValues[ABSX] = (pointer)(long)pBgWin->drawable.x; + newValues[ABSY] = (pointer)(long)pBgWin->drawable.y; + } + else + { + newValues[ABSX] = (pointer)0; + newValues[ABSY] = (pointer)0; + } + +/* + * XXX Backing store is turned off for the PCL driver + + if (pWin->backStorage) + (*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, + GuaranteeVisBack); + */ + + mask = gcmask; + gcmask = 0; + i = 0; + while (mask) { + index = lowbit (mask); + mask &= ~index; + switch (index) { + case GCFunction: + if ((pointer)(long) pGC->alu != newValues[FUNCTION]) { + gcmask |= index; + gcval[i++] = newValues[FUNCTION]; + } + break; + case GCTileStipXOrigin: + if ((pointer)(long) pGC->patOrg.x != newValues[ABSX]) { + gcmask |= index; + gcval[i++] = newValues[ABSX]; + } + break; + case GCTileStipYOrigin: + if ((pointer)(long) pGC->patOrg.y != newValues[ABSY]) { + gcmask |= index; + gcval[i++] = newValues[ABSY]; + } + break; + case GCClipMask: + if ((pointer) pGC->clientClipType != (pointer)CT_NONE) { + gcmask |= index; + gcval[i++] = (pointer)CT_NONE; + } + break; + case GCSubwindowMode: + if ((pointer) pGC->subWindowMode != newValues[SUBWINDOW]) { + gcmask |= index; + gcval[i++] = newValues[SUBWINDOW]; + } + break; + case GCTile: + if (pGC->tileIsPixel || + (pointer) pGC->tile.pixmap != newValues[TILE]) + { + gcmask |= index; + gcval[i++] = newValues[TILE]; + } + break; + case GCFillStyle: + if ((pointer) pGC->fillStyle != newValues[FILLSTYLE]) { + gcmask |= index; + gcval[i++] = newValues[FILLSTYLE]; + } + break; + case GCForeground: + if ((pointer) pGC->fgPixel != newValues[FOREGROUND]) { + gcmask |= index; + gcval[i++] = newValues[FOREGROUND]; + } + break; + } + } + + if (gcmask) + DoChangeGC(pGC, gcmask, (XID *)gcval, 1); + + if (pWin->drawable.serialNumber != pGC->serialNumber) + ValidateGC((DrawablePtr)pWin, pGC); + + numRects = REGION_NUM_RECTS(pRegion); + pbox = REGION_RECTS(pRegion); + for (i= numRects; --i >= 0; pbox++, prect++) + { + prect->x = pbox->x1 - pWin->drawable.x; + prect->y = pbox->y1 - pWin->drawable.y; + prect->width = pbox->x2 - pbox->x1; + prect->height = pbox->y2 - pbox->y1; + } + prect -= numRects; + (*pGC->ops->PolyFillRect)((DrawablePtr)pWin, pGC, numRects, prect); + DEALLOCATE_LOCAL(prect); + +/* + * XXX Backing store is turned off for the PCL driver + + if (pWin->backStorage) + (*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, + GuaranteeNothing); + */ + + if (what == PW_BORDER) + { + REGION_UNINIT(pScreen, &pWin->clipList); + pWin->clipList = prgnWin; + pWin->drawable.x = oldCorner.x; + pWin->drawable.y = oldCorner.y; + pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER; + } + FreeScratchGC(pGC); + +} + +/*ARGSUSED*/ +Bool +PclDestroyWindow( + WindowPtr pWin) +{ + return TRUE; +} + diff --git a/Xprint/pcl/Pclmap.h b/Xprint/pcl/Pclmap.h new file mode 100644 index 000000000..ecec35776 --- /dev/null +++ b/Xprint/pcl/Pclmap.h @@ -0,0 +1,195 @@ +/* $Xorg: Pclmap.h,v 1.3 2000/08/17 19:48:08 cpqbld Exp $ */ +/* +(c) Copyright 1996 Hewlett-Packard Company +(c) Copyright 1996 International Business Machines Corp. +(c) Copyright 1996 Sun Microsystems, Inc. +(c) Copyright 1996 Novell, Inc. +(c) Copyright 1996 Digital Equipment Corp. +(c) Copyright 1996 Fujitsu Limited +(c) Copyright 1996 Hitachi, Ltd. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the names of the copyright holders shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from said +copyright holders. +*/ + +#ifndef _PCLMAP_H_ +#define _PCLMAP_H_ + +#ifdef XP_PCL_COLOR +#if (defined(__STDC__) && !defined(UNIXCPP)) || defined(ANSICPP) +#define NAME(subname) PclCr##subname +#define CATNAME(prefix,subname) prefix##Color##subname +#else +#define NAME(subname) PclCr/**/subname +#define CATNAME(prefix,subname) prefix/**/Color/**/subname +#endif +#endif /* XP_PCL_COLOR */ + +#ifdef XP_PCL_MONO +#if (defined(__STDC__) && !defined(UNIXCPP)) || defined(ANSICPP) +#define NAME(subname) PclMn##subname +#define CATNAME(prefix,subname) prefix##Mono##subname +#else +#define NAME(subname) PclMn/**/subname +#define CATNAME(prefix,subname) prefix/**/Mono/**/subname +#endif +#endif /* XP_PCL_MONO */ + +#ifdef XP_PCL_LJ3 +#if (defined(__STDC__) && !defined(UNIXCPP)) || defined(ANSICPP) +#define NAME(subname) PclLj3##subname +#define CATNAME(prefix,subname) prefix##Lj3##subname +#else +#define NAME(subname) PclLj3/**/subname +#define CATNAME(prefix,subname) prefix/**/Lj3/**/subname +#endif +#endif /* XP_PCL_LJ3 */ + +/* PclInit.c */ +#define InitializePclDriver CATNAME(Initialize, PclDriver) +#define PclCloseScreen NAME(CloseScreen) +#define PclGetContextFromWindow NAME(GetContextFromWindow) +#define PclScreenPrivateIndex NAME(ScreenPrivateIndex) +#define PclWindowPrivateIndex NAME(WindowPrivateIndex) +#define PclContextPrivateIndex NAME(ContextPrivateIndex) +#define PclPixmapPrivateIndex NAME(PixmapPrivateIndex) +#define PclGCPrivateIndex NAME(GCPrivateIndex) + +/* PclPrint.c */ +#define PclStartJob NAME(StartJob) +#define PclEndJob NAME(EndJob) +#define PclStartPage NAME(StartPage) +#define PclEndPage NAME(EndPage) +#define PclStartDoc NAME(StartDoc) +#define PclEndDoc NAME(EndDoc) +#define PclDocumentData NAME(DocumentData) +#define PclGetDocumentData NAME(GetDocumentData) + +/* PclWindow.c */ +#define PclCreateWindow NAME(CreateWindow) +#define PclMapWindow NAME(MapWindow) +#define PclPositionWindow NAME(PositionWindow) +#define PclUnmapWindow NAME(UnmapWindow) +#define PclCopyWindow NAME(CopyWindow) +#define PclChangeWindowAttributes NAME(ChangeWindowAttributes) +#define PclPaintWindow NAME(PaintWindow) +#define PclDestroyWindow NAME(DestroyWindow) + +/* PclGC.c */ +#define PclCreateGC NAME(CreateGC) +#define PclDestroyGC NAME(DestroyGC) +#define PclGetDrawablePrivateStuff NAME(GetDrawablePrivateStuff) +#define PclSetDrawablePrivateGC NAME(SetDrawablePrivateGC) +#define PclSendPattern NAME(SendPattern) +#define PclUpdateDrawableGC NAME(UpdateDrawableGC) +#define PclComputeCompositeClip NAME(ComputeCompositeClip) +#define PclValidateGC NAME(ValidateGC) + +/* PclAttr.c */ +#define PclGetAttributes NAME(GetAttributes) +#define PclGetOneAttribute NAME(GetOneAttribute) +#define PclAugmentAttributes NAME(AugmentAttributes) +#define PclSetAttributes NAME(SetAttributes) + +/* PclColor.c */ +#define PclLookUp NAME(LookUp) +#define PclCreateDefColormap NAME(CreateDefColormap) +#define PclCreateColormap NAME(CreateColormap) +#define PclDestroyColormap NAME(DestroyColormap) +#define PclInstallColormap NAME(InstallColormap) +#define PclUninstallColormap NAME(UninstallColormap) +#define PclListInstalledColormaps NAME(ListInstalledColormaps) +#define PclStoreColors NAME(StoreColors) +#define PclResolveColor NAME(ResolveColor) +#define PclFindPaletteMap NAME(FindPaletteMap) +#define PclUpdateColormap NAME(UpdateColormap) +#define PclReadMap NAME(ReadMap) + +/* PclPixmap.c */ +#define PclCreatePixmap NAME(CreatePixmap) +#define PclDestroyPixmap NAME(DestroyPixmap) + +/* PclArc.c */ +#define PclDoArc NAME(DoArc) +#define PclPolyArc NAME(PolyArc) +#define PclPolyFillArc NAME(PolyFillArc) + +/* PclArea.c */ +#define PclPutImage NAME(PutImage) +#define PclCopyArea NAME(CopyArea) +#define PclCopyPlane NAME(CopyPlane) + +/* PclLine */ +#define PclPolyLine NAME(PolyLine) +#define PclPolySegment NAME(PolySegment) + +/* PclPixel.c */ +#define PclPolyPoint NAME(PolyPoint) +#define PclPushPixels NAME(PushPixels) + +/* PclPolygon.c */ +#define PclPolyRectangle NAME(PolyRectangle) +#define PclFillPolygon NAME(FillPolygon) +#define PclPolyFillRect NAME(PolyFillRect) + +/* PclSpans.c */ +#define PclFillSpans NAME(FillSpans) +#define PclSetSpans NAME(SetSpans) + +/* PclText.c */ +#define PclPolyText8 NAME(PolyText8) +#define PclPolyText16 NAME(PolyText16) +#define PclImageText8 NAME(ImageText8) +#define PclImageText16 NAME(ImageText16) +#define PclImageGlyphBlt NAME(ImageGlyphBlt) +#define PclPolyGlyphBlt NAME(PolyGlyphBlt) +#define PclPolyGlyphBlt NAME(PolyGlyphBlt) + +/* PclFonts.c */ +#define PclRealizeFont NAME(RealizeFont) +#define PclUnrealizeFont NAME(UnrealizeFont) + +/* PclSFonts.c */ +#define PclDownloadSoftFont8 NAME(DownloadSoftFont8) +#define PclDownloadSoftFont16 NAME(DownloadSoftFont16) +#define PclCreateSoftFontInfo NAME(CreateSoftFontInfo) +#define PclDestroySoftFontInfo NAME(DestroySoftFontInfo) + +/* PclMisc.c */ +#define PclQueryBestSize NAME(QueryBestSize) +#define GetPropString NAME(GetPropString) +#define SystemCmd NAME(SystemCmd) +#define PclGetMediumDimensions NAME(GetMediumDimensions) +#define PclGetReproducibleArea NAME(GetReproducibleArea) +#define PclSpoolFigs NAME(SpoolFigs) +#define PclSendData NAME(SendData) + +/* PclCursor.c */ +#define PclConstrainCursor NAME(ConstrainCursor) +#define PclCursorLimits NAME(CursorLimits) +#define PclDisplayCursor NAME(DisplayCursor) +#define PclRealizeCursor NAME(RealizeCursor) +#define PclUnrealizeCursor NAME(UnrealizeCursor) +#define PclRecolorCursor NAME(RecolorCursor) +#define PclSetCursorPosition NAME(SetCursorPosition) + +#endif /* _PCLMAP_H_ */ diff --git a/Xprint/ps/Ps.h b/Xprint/ps/Ps.h new file mode 100644 index 000000000..942e8f9f8 --- /dev/null +++ b/Xprint/ps/Ps.h @@ -0,0 +1,520 @@ +/* $Xorg: Ps.h,v 1.5 2001/02/09 02:04:35 xorgcvs Exp $ */ +/* + +Copyright 1996, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ +/* + * (c) Copyright 1996 Hewlett-Packard Company + * (c) Copyright 1996 International Business Machines Corp. + * (c) Copyright 1996 Sun Microsystems, Inc. + * (c) Copyright 1996 Novell, Inc. + * (c) Copyright 1996 Digital Equipment Corp. + * (c) Copyright 1996 Fujitsu Limited + * (c) Copyright 1996 Hitachi, Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the names of the copyright holders + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in this Software without prior written authorization + * from said copyright holders. + */ + +/******************************************************************* +** +** ********************************************************* +** * +** * File: Ps.h +** * +** * Contents: defines and includes for the Ps driver +** * for a printing X server. +** * +** * Created By: Roger Helmendach (Liberty Systems) +** * +** * Copyright: Copyright 1996 The Open Group, Inc. +** * +** ********************************************************* +** +********************************************************************/ + +#ifndef _PS_H_ +#define _PS_H_ + +#include <stdio.h> + +#ifdef abs +#undef abs /* this is because of a non-Spec1170ness in misc.h */ +#endif +#include <stdlib.h> +#include "scrnintstr.h" +#include "dix.h" + +/* +#include "X.h" +#include "Xproto.h" +#include "Xatom.h" +#include "misc.h" +#include "screenint.h" +#include "colormapst.h" +#include "windowstr.h" +#include "propertyst.h" +#include "servermd.h"*/ /* needed for IMAGE_BUFSIZE */ + +#include "PsDef.h" +#include "psout.h" + +#define _XP_PRINT_SERVER_ +#include "Print.h" +#include "extensions/Printstr.h" +#undef _XP_PRINT_SERVER_ + +#include "miscstruct.h" +#include "fontstruct.h" +#include "dixfontstr.h" +#include "gcstruct.h" + +/* + * Some sleazes to force the XrmDB stuff into the server + */ +typedef char *XPointer; +#define Status int +#define True 1 +#define False 0 +#include "misc.h" +#include <Xfuncproto.h> +#include "../Xresource.h" + +/* + * Public index variables from PsInit.c + */ + +extern int PsScreenPrivateIndex; +extern int PsWindowPrivateIndex; +extern int PsContextPrivateIndex; +extern int PsPixmapPrivateIndex; +extern int PsGCPrivateIndex; + +/* + * Display list structures + */ + +#define DPY_BLOCKSIZE 4096 + +typedef struct +{ + int mode; + int nPoints; + xPoint *pPoints; +} PsPolyPointsRec; + +typedef struct +{ + int nSegments; + xSegment *pSegments; +} PsSegmentsRec; + +typedef struct +{ + int nRects; + xRectangle *pRects; +} PsRectanglesRec; + +typedef struct +{ + int nArcs; + xArc *pArcs; +} PsArcsRec; + +typedef struct +{ + int x; + int y; + int count; + char *string; +} PsText8Rec; + +typedef struct +{ + int x; + int y; + int count; + unsigned short *string; +} PsText16Rec; + +typedef struct +{ + int depth; + int x; + int y; + int w; + int h; + int leftPad; + int format; + int res; /* image resolution */ + char *pData; +} PsImageRec; + +typedef struct +{ + int x; + int y; + int w; + int h; +} PsFrameRec; + +typedef enum +{ + PolyPointCmd, + PolyLineCmd, + PolySegmentCmd, + PolyRectangleCmd, + FillPolygonCmd, + PolyFillRectCmd, + PolyArcCmd, + PolyFillArcCmd, + Text8Cmd, + Text16Cmd, + TextI8Cmd, + TextI16Cmd, + PutImageCmd, + BeginFrameCmd, + EndFrameCmd +} DisplayElmType; + +typedef struct _DisplayElmRec +{ + DisplayElmType type; + GCPtr gc; + union + { + PsPolyPointsRec polyPts; + PsSegmentsRec segments; + PsRectanglesRec rects; + PsArcsRec arcs; + PsText8Rec text8; + PsText16Rec text16; + PsImageRec image; + PsFrameRec frame; + } c; +} DisplayElmRec; + +typedef DisplayElmRec *DisplayElmPtr; + +typedef struct _DisplayListRec +{ + struct _DisplayListRec *next; + int nelms; + DisplayElmRec elms[DPY_BLOCKSIZE]; +} DisplayListRec; + +typedef DisplayListRec *DisplayListPtr; + +/* + * Private structures + */ + +typedef struct +{ + XrmDatabase resDB; + ColormapPtr CMap; + Bool (*DestroyWindow)(); +} PsScreenPrivRec, *PsScreenPrivPtr; + +typedef struct +{ + char *jobFileName; + FILE *pJobFile; + GC lastGC; + unsigned char *dash; + int validGC; + ClientPtr getDocClient; + int getDocBufSize; + PsOutPtr pPsOut; +} PsContextPrivRec, *PsContextPrivPtr; + +typedef struct +{ + int validContext; + XpContextPtr context; +} PsWindowPrivRec, *PsWindowPrivPtr; + +typedef struct +{ + unsigned freeCompClip; + RegionPtr pCompositeClip; +} PsGCPrivRec, *PsGCPrivPtr; + +typedef struct +{ + XpContextPtr context; + GC lastGC; + int validGC; + DisplayListPtr dispList; +} PsPixmapPrivRec, *PsPixmapPrivPtr; + +/* + * Macro functions + */ + +#define SEND_PS(f,c) fwrite( c, sizeof( char ), strlen( c ), f ) +#define MIN(a,b) (((a)<(b))?(a):(b)) +#define MAX(a,b) (((a)>(b))?(a):(b)) + +/* + * Functions in PsInit.c + */ + +extern Bool InitializePsDriver(int ndx, ScreenPtr pScreen, int argc, + char **argv); +static Bool PsDestroyContext(XpContextPtr pCon); +extern XpContextPtr PsGetContextFromWindow(WindowPtr win); + +/* + * Functions in PsPrint.c + */ + +extern int PsStartJob(XpContextPtr pCon, Bool sendClientData, ClientPtr client); +extern int PsEndJob(XpContextPtr pCon, Bool cancel); +extern int PsStartPage(XpContextPtr pCon, WindowPtr pWin); +extern int PsEndPage(XpContextPtr pCon, WindowPtr pWin); +extern int PsStartDoc(XpContextPtr pCon, XPDocumentType type); +extern int PsEndDoc(XpContextPtr pCon, Bool cancel); +extern int PsDocumentData(XpContextPtr pCon, DrawablePtr pDraw, char *pData, + int len_data, char *pFmt, int len_fmt, char *pOpt, int len_opt, + ClientPtr client); +extern int PsGetDocumentData(XpContextPtr pCon, ClientPtr client, + int maxBufferSize); + +/* + * Functions in PsGC.c + */ + +extern Bool PsCreateGC(GCPtr pGC); +static int PsGetDrawablePrivateStuff(DrawablePtr pDrawable, GC *gc, + unsigned long *valid, PsOutPtr *psOut, + ColormapPtr *cMap); +extern int PsUpdateDrawableGC(GCPtr pGC, DrawablePtr pDrawable, + PsOutPtr *psOut, ColormapPtr *cMap); +extern void PsValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable); +extern void PsChangeGC(GCPtr pGC, unsigned long changes); +extern void PsCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst); +extern void PsDestroyGC(GCPtr pGC); +extern void PsChangeClip(GCPtr pGC, int type, pointer pValue, int nrects); +extern void PsDestroyClip(GCPtr pGC); +extern void PsCopyClip(GCPtr pgcDst, GCPtr pgcSrc); + +extern GCPtr PsCreateAndCopyGC(DrawablePtr pDrawable, GCPtr pSrc); + +/* + * Functions in PsMisc.c + */ + +extern void PsQueryBestSize(int type, short *pwidth, short *pheight, + ScreenPtr pScreen); +extern Bool PsCloseScreen(int index, ScreenPtr pScreen); +extern void PsLineAttrs(PsOutPtr psOut, GCPtr pGC, ColormapPtr cMap); +extern int PsGetMediumDimensions( + XpContextPtr pCon, + CARD16 *pWidth, + CARD16 *pHeight); +extern int PsGetReproducibleArea( + XpContextPtr pCon, + xRectangle *pRect); +extern int PsSetImageResolution( + XpContextPtr pCon, + int imageRes, + Bool *status); + +/* + * Functions in PsSpans.c + */ + +extern void PsFillSpans(DrawablePtr pDrawable, GCPtr pGC, int nSpans, + DDXPointPtr pPoints, int *pWidths, int fSorted); +extern void PsSetSpans(DrawablePtr pDrawable, GCPtr pGC, char *pSrc, + DDXPointPtr pPoints, int *pWidths, int nSpans, + int fSorted); + +/* + * Functions in PsArea.c + */ + +extern void PsPutScaledImage(DrawablePtr pDrawable, GCPtr pGC, int depth, + int x, int y, int w, int h, int leftPad, int format, + int imageRes, char *pImage); +extern void PsPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth, + int x, int y, int w, int h, int leftPad, int format, + char *pImage); +extern RegionPtr PsCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, + int srcx, int srcy, int width, int height, + int dstx, int dsty); +extern RegionPtr PsCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, + int srcx, int srcy, int width, int height, + int dstx, int dsty, unsigned long plane); + +/* + * Functions in PsPixel.c + */ + +extern void PsPolyPoint(DrawablePtr pDrawable, GCPtr pGC, int mode, + int nPoints, xPoint *pPoints); +extern void PsPushPixels(GCPtr pGC, PixmapPtr pBitmap, DrawablePtr pDrawable, + int width, int height, int x, int y); + +/* + * Functions in PsLine.c + */ + +extern void PsPolyLine(DrawablePtr pDrawable, GCPtr pGC, int mode, + int nPoints, xPoint *pPoints); +extern void PsPolySegment(DrawablePtr pDrawable, GCPtr pGC, int nSegments, + xSegment *pSegments); + +/* + * Functions in PsPolygon.c + */ + +extern void PsPolyRectangle(DrawablePtr pDrawable, GCPtr pGC, int nRects, + xRectangle *pRects); +extern void PsFillPolygon(DrawablePtr pDrawable, GCPtr pGC, int shape, + int mode, int nPoints, DDXPointPtr pPoints); +extern void PsPolyFillRect(DrawablePtr pDrawable, GCPtr pGC, int nRects, + xRectangle *pRects); + +/* + * Functions in PsPolygon.c + */ + +extern void PsPolyArc(DrawablePtr pDrawable, GCPtr pGC, int nArcs, + xArc *pArcs); +extern void PsPolyFillArc(DrawablePtr pDrawable, GCPtr pGC, int nArcs, + xArc *pArcs); + +/* + * Functions in PsText.c + */ + +extern int PsPolyText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y, + int count, char *string); +extern int PsPolyText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y, + int count, unsigned short *string); +extern void PsImageText8(DrawablePtr pDrawable, GCPtr pGC, int x, int y, + int count, char *string); +extern void PsImageText16(DrawablePtr pDrawable, GCPtr pGC, int x, int y, + int count, unsigned short *string); +extern void PsImageGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y, + unsigned int nGlyphs, CharInfoPtr *pCharInfo, + pointer pGlyphBase); +extern void PsPolyGlyphBlt(DrawablePtr pDrawable, GCPtr pGC, int x, int y, + unsigned int nGlyphs, CharInfoPtr *pCharInfo, + pointer pGlyphBase); + +/* + * Functions in PsWindow.c + */ + +extern Bool PsCreateWindow(WindowPtr pWin); +extern Bool PsMapWindow(WindowPtr pWin); +extern Bool PsPositionWindow(WindowPtr pWin, int x, int y); +extern Bool PsUnmapWindow(WindowPtr pWin); +extern void PsCopyWindow(WindowPtr pWin, DDXPointRec ptOldOrg, + RegionPtr prgnSrc); +extern Bool PsChangeWindowAttributes(WindowPtr pWin, unsigned long mask); +extern void PsPaintWindow(WindowPtr pWin, RegionPtr pRegion, int what); +extern Bool PsDestroyWindow(WindowPtr pWin); + +/* + * Functions in PsFonts.c + */ + +extern Bool PsRealizeFont(ScreenPtr pscr, FontPtr pFont); +extern Bool PsUnrealizeFont(ScreenPtr pscr, FontPtr pFont); +extern char *PsGetFontName(FontPtr pFont); +extern int PsGetFontSize(FontPtr pFont, float *mtx); +extern char *PsGetPSFontName(FontPtr pFont); +extern int PsIsISOLatin1Encoding(FontPtr pFont); + +/* + * Functions in PsAttr.c + */ + +extern char *PsGetAttributes(XpContextPtr pCon, XPAttributes pool); +extern char *PsGetOneAttribute(XpContextPtr pCon, XPAttributes pool, + char *attr); +extern int PsAugmentAttributes(XpContextPtr pCon, XPAttributes pool, + char *attrs); +extern int PsSetAttributes(XpContextPtr pCon, XPAttributes pool, char *attrs); + +/* + * Functions in PsColor.c + */ + +extern Bool PsCreateColormap(ColormapPtr pColor); +extern void PsDestroyColormap(ColormapPtr pColor); +extern void PsInstallColormap(ColormapPtr pColor); +extern void PsUninstallColormap(ColormapPtr pColor); +extern int PsListInstalledColormaps(ScreenPtr pScreen, XID *pCmapList); +extern void PsStoreColors(ColormapPtr pColor, int ndef, xColorItem *pdefs); +extern void PsResolveColor(unsigned short *pRed, unsigned short *pGreen, + unsigned short *pBlue, VisualPtr pVisual); +extern int PsGetPixelColor(ColormapPtr cMap, int pixval); +extern void PsSetFillColor(DrawablePtr pDrawable, GCPtr pGC, PsOutPtr psOut, + ColormapPtr cMap); + +/* + * Functions in PsPixmap.c + */ + +extern PixmapPtr PsCreatePixmap(ScreenPtr pScreen, int width, int height, + int depth); +extern Bool PsDestroyPixmap(PixmapPtr pPixmap); +extern DisplayListPtr PsGetFreeDisplayBlock(PsPixmapPrivPtr priv); +extern void PsReplayPixmap(PixmapPtr pix, DrawablePtr pDrawable); +extern int PsCloneDisplayElm(PixmapPtr dst, + DisplayElmPtr elm, DisplayElmPtr newElm, + int xoff, int yoff); +extern void PsCopyDisplayList(PixmapPtr src, PixmapPtr dst, int xoff, + int yoff, int x, int y, int w, int h); +extern PsElmPtr PsCreateFillElementList(PixmapPtr pix, int *nElms); +extern PsElmPtr PsCloneFillElementList(int nElms, PsElmPtr elms); +extern void PsDestroyFillElementList(int nElms, PsElmPtr elms); + +#endif /* _PS_H_ */ diff --git a/Xprint/ps/PsArc.c b/Xprint/ps/PsArc.c new file mode 100644 index 000000000..76804bb18 --- /dev/null +++ b/Xprint/ps/PsArc.c @@ -0,0 +1,178 @@ +/* $Xorg: PsArc.c,v 1.4 2001/02/09 02:04:35 xorgcvs Exp $ */ +/* + +Copyright 1996, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ +/* + * (c) Copyright 1996 Hewlett-Packard Company + * (c) Copyright 1996 International Business Machines Corp. + * (c) Copyright 1996 Sun Microsystems, Inc. + * (c) Copyright 1996 Novell, Inc. + * (c) Copyright 1996 Digital Equipment Corp. + * (c) Copyright 1996 Fujitsu Limited + * (c) Copyright 1996 Hitachi, Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the names of the copyright holders + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in this Software without prior written authorization + * from said copyright holders. + */ + +/******************************************************************* +** +** ********************************************************* +** * +** * File: PsArc.c +** * +** * Contents: Arc-drawing code for the PS DDX driver +** * +** * Created By: Roger Helmendach (Liberty Systems) +** * +** * Copyright: Copyright 1996 The Open Group, Inc. +** * +** ********************************************************* +** +********************************************************************/ + +#include <stdio.h> + +#include "Ps.h" +#include "gcstruct.h" +#include "windowstr.h" + +void +PsPolyArc( + DrawablePtr pDrawable, + GCPtr pGC, + int nArcs, + xArc *pArcs) +{ + if( pDrawable->type==DRAWABLE_PIXMAP ) + { + DisplayElmPtr elm; + PixmapPtr pix = (PixmapPtr)pDrawable; + PsPixmapPrivPtr priv = (PsPixmapPrivPtr)pix->devPrivate.ptr; + DisplayListPtr disp; + GCPtr gc; + + if ((gc = PsCreateAndCopyGC(pDrawable, pGC)) == NULL) return; + + disp = PsGetFreeDisplayBlock(priv); + + elm = &disp->elms[disp->nelms]; + elm->type = PolyArcCmd; + elm->gc = gc; + elm->c.arcs.nArcs = nArcs; + elm->c.arcs.pArcs = (xArc *)xalloc(nArcs*sizeof(xArc)); + memcpy(elm->c.arcs.pArcs, pArcs, nArcs*sizeof(xArc)); + disp->nelms += 1; + } + else + { + int i; + PsOutPtr psOut; + ColormapPtr cMap; + + if( PsUpdateDrawableGC(pGC, pDrawable, &psOut, &cMap)==FALSE ) return; + PsOut_Offset(psOut, pDrawable->x, pDrawable->y); + PsOut_Color(psOut, PsGetPixelColor(cMap, pGC->fgPixel)); + PsLineAttrs(psOut, pGC, cMap); + for( i=0 ; i<nArcs ; i++ ) + { + PsOut_DrawArc(psOut, (int)pArcs[i].x, (int)pArcs[i].y, + (int)pArcs[i].width, (int)pArcs[i].height, + (float)pArcs[i].angle1/64., + (float)pArcs[i].angle2/64.); + } + } +} + +void +PsPolyFillArc( + DrawablePtr pDrawable, + GCPtr pGC, + int nArcs, + xArc *pArcs) +{ + if( pDrawable->type==DRAWABLE_PIXMAP ) + { + DisplayElmPtr elm; + PixmapPtr pix = (PixmapPtr)pDrawable; + PsPixmapPrivPtr priv = (PsPixmapPrivPtr)pix->devPrivate.ptr; + DisplayListPtr disp; + GCPtr gc; + + if ((gc = PsCreateAndCopyGC(pDrawable, pGC)) == NULL) return; + + disp = PsGetFreeDisplayBlock(priv); + + elm = &disp->elms[disp->nelms]; + elm->type = PolyFillArcCmd; + elm->gc = gc; + elm->c.arcs.nArcs = nArcs; + elm->c.arcs.pArcs = (xArc *)xalloc(nArcs*sizeof(xArc)); + memcpy(elm->c.arcs.pArcs, pArcs, nArcs*sizeof(xArc)); + disp->nelms += 1; + } + else + { + int i; + PsOutPtr psOut; + PsArcEnum styl; + ColormapPtr cMap; + + if( PsUpdateDrawableGC(pGC, pDrawable, &psOut, &cMap)==FALSE ) return; + PsOut_Offset(psOut, pDrawable->x, pDrawable->y); + PsSetFillColor(pDrawable, pGC, psOut, cMap); + PsLineAttrs(psOut, pGC, cMap); + if( pGC->arcMode==ArcChord ) styl = PsChord; + else styl = PsPieSlice; + for( i=0 ; i<nArcs ; i++ ) + { + PsOut_FillArc(psOut, (int)pArcs[i].x, (int)pArcs[i].y, + (int)pArcs[i].width, (int)pArcs[i].height, + (float)pArcs[i].angle1/64., + (float)pArcs[i].angle2/64., styl); + } + } +} diff --git a/Xprint/ps/PsArea.c b/Xprint/ps/PsArea.c new file mode 100644 index 000000000..134686a87 --- /dev/null +++ b/Xprint/ps/PsArea.c @@ -0,0 +1,464 @@ +/* $Xorg: PsArea.c,v 1.6 2001/03/14 18:27:44 pookie Exp $ */ +/* + +Copyright 1996, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ +/* + * (c) Copyright 1996 Hewlett-Packard Company + * (c) Copyright 1996 International Business Machines Corp. + * (c) Copyright 1996, 2000 Sun Microsystems, Inc. + * (c) Copyright 1996 Novell, Inc. + * (c) Copyright 1996 Digital Equipment Corp. + * (c) Copyright 1996 Fujitsu Limited + * (c) Copyright 1996 Hitachi, Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the names of the copyright holders + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in this Software without prior written authorization + * from said copyright holders. + */ + +/******************************************************************* +** +** ********************************************************* +** * +** * File: PsArea.c +** * +** * Contents: Image and Area functions for the PS DDX driver +** * +** * Created By: Roger Helmendach (Liberty Systems) +** * +** * Copyright: Copyright 1996 The Open Group, Inc. +** * +** ********************************************************* +** +********************************************************************/ + +#include "Ps.h" +#include "gcstruct.h" +#include "windowstr.h" + +void +PsPutScaledImage(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, + int w, int h, int leftPad, int format, int imageRes, char *pImage) +{ + if( pDrawable->type==DRAWABLE_PIXMAP ) + { + int size = PixmapBytePad(w, depth)*h; + DisplayElmPtr elm; + PixmapPtr pix = (PixmapPtr)pDrawable; + PsPixmapPrivPtr priv = (PsPixmapPrivPtr)pix->devPrivate.ptr; + DisplayListPtr disp; + GCPtr gc; + + if ((gc = PsCreateAndCopyGC(pDrawable, pGC)) == NULL) return; + + disp = PsGetFreeDisplayBlock(priv); + elm = &disp->elms[disp->nelms]; + elm->type = PutImageCmd; + elm->gc = gc; + elm->c.image.depth = depth; + elm->c.image.x = x; + elm->c.image.y = y; + elm->c.image.w = w; + elm->c.image.h = h; + elm->c.image.leftPad = leftPad; + elm->c.image.format = format; + elm->c.image.res = imageRes; + elm->c.image.pData = (char *)xalloc(size); + memcpy(elm->c.image.pData, pImage, size); + disp->nelms += 1; + } + else + { + int i, j; + int r, c; + int swap; + char *pt; + PsOutPtr psOut; + ColormapPtr cMap; + int pageRes, sw, sh; + + if( PsUpdateDrawableGC(pGC, pDrawable, &psOut, &cMap)==FALSE ) return; + if (!imageRes) { + sw = w; + sh = h; + } else { + pageRes = XpGetResolution(XpGetPrintContext(requestingClient)); + sw = (float)w * (float)pageRes / (float)imageRes + 0.5; + sh = (float)h * (float)pageRes / (float)imageRes + 0.5; + } + PsOut_Offset(psOut, pDrawable->x, pDrawable->y); + pt = (char *)(&i); i = 1; if( pt[0]=='\001' ) swap = 1; else swap = 0; + + if( depth==24 ) + { + PsOut_BeginImage(psOut, 0, 0, x, y, w, h, sw, sh, 3); + if( format==XYPixmap ) + { + int rowsiz = PixmapBytePad(w, depth); + char *planes[3]; + planes[0] = pImage; + planes[1] = &pImage[rowsiz*h]; + planes[2] = &pImage[rowsiz*h*2]; + for( r=0 ; r<h ; r++ ) + { + char *pt[3]; + for( i=0 ; i<3 ; i++ ) pt[i] = &planes[i][rowsiz*r]; + for( c=0 ; c<w ; c++ ) + { + for( i=0 ; i<3 ; i++ ) + { PsOut_OutImageBytes(psOut, 1, &pt[i][c]); pt[i]++; } + } + } + } + else if( format==ZPixmap ) + { + int rowsiz = PixmapBytePad(w, depth); + for( r=0 ; r<h ; r++ ) + { + char *pt = &pImage[rowsiz*r]; + for( c=0 ; c<w ; c++,pt+=4 ) + { + if( swap ) + { + char tmp[4]; + tmp[0] = pt[3]; tmp[1] = pt[2]; tmp[2] = pt[1]; tmp[3] = pt[0]; + PsOut_OutImageBytes(psOut, 3, &tmp[1]); + } + else + PsOut_OutImageBytes(psOut, 3, &pt[1]); + } + } + } + else goto error; + PsOut_EndImage(psOut); + } + else if( depth==8 ) + { + int rowsiz = PixmapBytePad(w, depth); + PsOut_BeginImage(psOut, 0, 0, x, y, w, h, sw, sh, 3); + for( r=0 ; r<h ; r++ ) + { + char *pt = &pImage[rowsiz*r]; + for( c=0 ; c<w ; c++,pt++ ) + { + int val = PsGetPixelColor(cMap, (int)(*pt)&0xFF); + char *ipt = (char *)&val; + if( swap ) + { + char tmp[4]; + tmp[0] = ipt[3]; tmp[1] = ipt[2]; tmp[2] = ipt[1]; tmp[3] = ipt[0]; + PsOut_OutImageBytes(psOut, 3, &tmp[1]); + } + else + PsOut_OutImageBytes(psOut, 3, &ipt[1]); + } + } + PsOut_EndImage(psOut); + } + else if( depth==1 ) + { + { + int rowsiz = BitmapBytePad(w); + int psrsiz = (w+7)/8; + PsOut_BeginImage(psOut, PsGetPixelColor(cMap, pGC->bgPixel), + PsGetPixelColor(cMap, pGC->fgPixel), + x, y, w, h, sw, sh, 1); + for( r=0 ; r<h ; r++ ) + { + char *pt = &pImage[rowsiz*r]; + for( i=0 ; i<psrsiz ; i++ ) + { + int iv_, iv = (int)pt[i]&0xFF; + char c; + if( swap ) + { for( j=0,iv_=0 ; j<8 ; j++ ) iv_ |= (((iv>>j)&1)<<(7-j)); } + else + iv_ = iv; + c = iv_; + PsOut_OutImageBytes(psOut, 1, &c); + } + } + PsOut_EndImage(psOut); + } + } + } +error: + return; +} + +void +PsPutScaledImageIM(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, + int w, int h, int leftPad, int format, int imageRes, char *pImage) +{ + if( pDrawable->type==DRAWABLE_PIXMAP ) + { + int size = PixmapBytePad(w, depth)*h; + DisplayElmPtr elm; + PixmapPtr pix = (PixmapPtr)pDrawable; + PsPixmapPrivPtr priv = (PsPixmapPrivPtr)pix->devPrivate.ptr; + DisplayListPtr disp; + GCPtr gc; + + if ((gc = PsCreateAndCopyGC(pDrawable, pGC)) == NULL) return; + + disp = PsGetFreeDisplayBlock(priv); + elm = &disp->elms[disp->nelms]; + elm->type = PutImageCmd; + elm->gc = gc; + elm->c.image.depth = depth; + elm->c.image.x = x; + elm->c.image.y = y; + elm->c.image.w = w; + elm->c.image.h = h; + elm->c.image.leftPad = leftPad; + elm->c.image.format = format; + elm->c.image.res = imageRes; + elm->c.image.pData = (char *)xalloc(size); + memcpy(elm->c.image.pData, pImage, size); + disp->nelms += 1; + } + else + { + int i, j; + int r, c; + int swap; + char *pt; + PsOutPtr psOut; + ColormapPtr cMap; + int pageRes, sw, sh; +#ifdef BM_CACHE + long cache_id = 0; +#endif + + if( PsUpdateDrawableGC(pGC, pDrawable, &psOut, &cMap)==FALSE ) return; + if (!imageRes) { + sw = w; + sh = h; + } else { + pageRes = XpGetResolution(XpGetPrintContext(requestingClient)); + sw = (float)w * (float)pageRes / (float)imageRes + 0.5; + sh = (float)h * (float)pageRes / (float)imageRes + 0.5; + } + PsOut_Offset(psOut, pDrawable->x, pDrawable->y); + pt = (char *)(&i); i = 1; if( pt[0]=='\001' ) swap = 1; else swap = 0; + +#ifdef BM_CACHE + cache_id = PsBmIsImageCached(w, h, pImage); + + if(!cache_id) + { + cache_id = PsBmPutImageInCache(w, h, pImage); + + if(!cache_id) + return; + + PsOut_BeginImageCache(psOut, cache_id); +#endif + if( depth==24 ) + { + PsOut_BeginImageIM(psOut, 0, 0, x, y, w, h, sw, sh, 3); + if( format==XYPixmap ) + { + int rowsiz = PixmapBytePad(w, depth); + char *planes[3]; + planes[0] = pImage; + planes[1] = &pImage[rowsiz*h]; + planes[2] = &pImage[rowsiz*h*2]; + for( r=0 ; r<h ; r++ ) + { + char *pt[3]; + for( i=0 ; i<3 ; i++ ) pt[i] = &planes[i][rowsiz*r]; + for( c=0 ; c<w ; c++ ) + { + for( i=0 ; i<3 ; i++ ) + { PsOut_OutImageBytes(psOut, 1, &pt[i][c]); pt[i]++; } + } + } + } + else if( format==ZPixmap ) + { + int rowsiz = PixmapBytePad(w, depth); + for( r=0 ; r<h ; r++ ) + { + char *pt = &pImage[rowsiz*r]; + for( c=0 ; c<w ; c++,pt+=4 ) + { + if( swap ) + { + char tmp[4]; + tmp[0] = pt[3]; tmp[1] = pt[2]; tmp[2] = pt[1]; tmp[3] = pt[0]; + PsOut_OutImageBytes(psOut, 3, &tmp[1]); + } + else + PsOut_OutImageBytes(psOut, 3, &pt[1]); + } + } + } + else goto error; + PsOut_EndImage(psOut); + } + else if( depth==8 ) + { + int rowsiz = PixmapBytePad(w, depth); + PsOut_BeginImageIM(psOut, 0, 0, x, y, w, h, sw, sh, 3); + for( r=0 ; r<h ; r++ ) + { + char *pt = &pImage[rowsiz*r]; + for( c=0 ; c<w ; c++,pt++ ) + { + int val = PsGetPixelColor(cMap, (int)(*pt)&0xFF); + char *ipt = (char *)&val; + if( swap ) + { + char tmp[4]; + tmp[0] = ipt[3]; tmp[1] = ipt[2]; tmp[2] = ipt[1]; tmp[3] = ipt[0]; + PsOut_OutImageBytes(psOut, 3, &tmp[1]); + } + else + PsOut_OutImageBytes(psOut, 3, &ipt[1]); + } + } + PsOut_EndImage(psOut); + } + else if( depth==1 ) + { + { + int rowsiz = BitmapBytePad(w); + int psrsiz = (w+7)/8; + PsOut_BeginImageIM(psOut, PsGetPixelColor(cMap, pGC->bgPixel), + PsGetPixelColor(cMap, pGC->fgPixel), + x, y, w, h, sw, sh, 1); + for( r=0 ; r<h ; r++ ) + { + char *pt = &pImage[rowsiz*r]; + for( i=0 ; i<psrsiz ; i++ ) + { + int iv_, iv = (int)pt[i]&0xFF; + char c; + if( swap ) + { for( j=0,iv_=0 ; j<8 ; j++ ) iv_ |= (((iv>>j)&1)<<(7-j)); } + else + iv_ = iv; + c = iv_; + PsOut_OutImageBytes(psOut, 1, &c); + } + } + PsOut_EndImage(psOut); + } + } +#ifdef BM_CACHE + PsOut_EndImageCache(psOut); + } + PsOut_ImageCache(psOut, x, y, cache_id, PsGetPixelColor(cMap, pGC->bgPixel), + PsGetPixelColor(cMap, pGC->fgPixel)); +#endif + } +error: + return; +} +void +PsPutImage(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, + int w, int h, int leftPad, int format, char *pImage) +{ + XpContextPtr pcon; + if (requestingClient && (pcon = XpGetPrintContext(requestingClient))) + PsPutScaledImage(pDrawable, pGC, depth, x, y, w, h, leftPad, format, + pcon->imageRes, pImage); +} +void +PsPutImageMask(DrawablePtr pDrawable, GCPtr pGC, int depth, int x, int y, + int w, int h, int leftPad, int format, char *pImage) +{ + XpContextPtr pcon; + if (requestingClient && (pcon = XpGetPrintContext(requestingClient))) + PsPutScaledImageIM(pDrawable, pGC, depth, x, y, w, h, leftPad, format, + pcon->imageRes, pImage); +} + +RegionPtr +PsCopyArea(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, int srcx, int srcy, + int width, int height, int dstx, int dsty) +{ + PixmapPtr src = (PixmapPtr)pSrc; + PixmapPtr dst = (PixmapPtr)pDst; + + if( pSrc->type!=DRAWABLE_PIXMAP ) return NULL; + if( pDst->type!=DRAWABLE_PIXMAP ) + { + PsOutPtr psOut; + ColormapPtr cMap; + if( PsUpdateDrawableGC(pGC, pDst, &psOut, &cMap)==FALSE ) return NULL; + PsOut_Offset(psOut, pDst->x, pDst->y); + PsOut_BeginFrame(psOut, dstx-srcx, dsty-srcy, dstx, dsty, width, height); + PsReplayPixmap(src, pDst); + PsOut_EndFrame(psOut); + } + else PsCopyDisplayList(src, dst, dstx-srcx, dsty-srcy, dstx, dsty, + width, height); + return NULL; +} + +RegionPtr +PsCopyPlane(DrawablePtr pSrc, DrawablePtr pDst, GCPtr pGC, int srcx, int srcy, + int width, int height, int dstx, int dsty, unsigned long plane) +{ + PixmapPtr src = (PixmapPtr)pSrc; + PixmapPtr dst = (PixmapPtr)pDst; + + if( pSrc->type!=DRAWABLE_PIXMAP ) return NULL; + if( pDst->type!=DRAWABLE_PIXMAP ) + { + PsOutPtr psOut; + ColormapPtr cMap; + if( PsUpdateDrawableGC(pGC, pDst, &psOut, &cMap)==FALSE ) return NULL; + PsOut_Offset(psOut, pDst->x, pDst->y); + PsOut_BeginFrame(psOut, dstx-srcx, dsty-srcy, dstx, dsty, width, height); + PsReplayPixmap(src, pDst); + PsOut_EndFrame(psOut); + } + else PsCopyDisplayList(src, dst, dstx-srcx, dsty-srcy, dstx, dsty, + width, height); + return NULL; +} diff --git a/Xprint/ps/PsAttVal.c b/Xprint/ps/PsAttVal.c new file mode 100644 index 000000000..83133e53a --- /dev/null +++ b/Xprint/ps/PsAttVal.c @@ -0,0 +1,202 @@ +/* + * $Xorg: PsAttVal.c,v 1.5 2001/03/13 18:45:31 pookie Exp $ + */ +/* +(c) Copyright 1996 Hewlett-Packard Company +(c) Copyright 1996 International Business Machines Corp. +(c) Copyright 1996 Sun Microsystems, Inc. +(c) Copyright 1996 Novell, Inc. +(c) Copyright 1996 Digital Equipment Corp. +(c) Copyright 1996 Fujitsu Limited +(c) Copyright 1996 Hitachi, Ltd. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the names of the copyright holders shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from said +copyright holders. +*/ + +#include "Ps.h" +#include "AttrValid.h" + +/* + * define valid values and defaults for Printer pool + */ +static XpOid ValidContentOrientationsOids[] = { + xpoid_val_content_orientation_portrait, + xpoid_val_content_orientation_landscape, + xpoid_val_content_orientation_reverse_portrait, + xpoid_val_content_orientation_reverse_landscape +}; +static XpOidList ValidContentOrientations = { + ValidContentOrientationsOids, XpNumber(ValidContentOrientationsOids) +}; + +static XpOid DefaultContentOrientationsOids[] = { + xpoid_val_content_orientation_portrait, + xpoid_val_content_orientation_landscape +}; +static XpOidList DefaultContentOrientations = { + DefaultContentOrientationsOids, XpNumber(DefaultContentOrientationsOids) +}; + +static XpOid ValidPlexesOids[] = { + xpoid_val_plex_simplex, xpoid_val_plex_duplex, xpoid_val_plex_tumble +}; +static XpOidList ValidPlexes = { + ValidPlexesOids, XpNumber(ValidPlexesOids) +}; + +static XpOid DefaultPlexesOids[] = { + xpoid_val_plex_simplex +}; +static XpOidList DefaultPlexes = { + DefaultPlexesOids, XpNumber(DefaultPlexesOids) +}; + +static unsigned long ValidPrinterResolutionsCards[] = { + 300, + 600, + 720, + 940, + 1200, + 1440, + 2400 +}; +static XpOidCardList ValidPrinterResolutions = { + ValidPrinterResolutionsCards, XpNumber(ValidPrinterResolutionsCards) +}; + +static unsigned long DefaultPrinterResolutionsCards[] = { + 300 +}; +static XpOidCardList DefaultPrinterResolutions = { + DefaultPrinterResolutionsCards, XpNumber(DefaultPrinterResolutionsCards) +}; + +static XpOid ValidListfontsModesOids[] = { + xpoid_val_xp_list_internal_printer_fonts, xpoid_val_xp_list_glyph_fonts +}; +static XpOidList ValidListfontsModes = { + ValidListfontsModesOids, XpNumber(ValidListfontsModesOids) +}; + +static XpOid DefaultListfontsModesOids[] = { + xpoid_val_xp_list_glyph_fonts +}; +static XpOidList DefaultListfontsModes = { + DefaultListfontsModesOids, XpNumber(DefaultListfontsModesOids) +}; + +static XpOid ValidSetupProvisoOids[] = { + xpoid_val_xp_setup_mandatory, xpoid_val_xp_setup_optional +}; +static XpOidList ValidSetupProviso = { + + + ValidSetupProvisoOids, XpNumber(ValidSetupProvisoOids) +}; + +static XpOidDocFmt ValidDocFormatsSupportedFmts[] = { + { "Postscript", "2", NULL } +}; +static XpOidDocFmtList ValidDocFormatsSupported = { + ValidDocFormatsSupportedFmts, XpNumber(ValidDocFormatsSupportedFmts) +}; + +static XpOidDocFmt DefaultDocFormatsSupportedFmts[] = { + { "Postscript", "2", NULL } +}; +static XpOidDocFmtList DefaultDocFormatsSupported = { + DefaultDocFormatsSupportedFmts, XpNumber(DefaultDocFormatsSupportedFmts) +}; + +static XpOidDocFmt ValidEmbeddedFormatsSupportedFmts[] = { + { "Postscript", "2", NULL } +}; +static XpOidDocFmtList ValidEmbeddedFormatsSupported = { + ValidEmbeddedFormatsSupportedFmts, XpNumber(ValidEmbeddedFormatsSupportedFmts) +}; + +static XpOidDocFmt DefaultEmbeddedFormatsSupportedFmts[] = { + { "Postscript", "2", NULL } +}; +static XpOidDocFmtList DefaultEmbeddedFormatsSupported = { + DefaultEmbeddedFormatsSupportedFmts, XpNumber(DefaultEmbeddedFormatsSupportedFmts) +}; + +static XpOidDocFmt ValidRawFormatsSupportedFmts[] = { + { "Postscript", "2", NULL } + +}; +static XpOidDocFmtList ValidRawFormatsSupported = { + ValidRawFormatsSupportedFmts, XpNumber(ValidRawFormatsSupportedFmts) +}; + +static XpOidDocFmt DefaultRawFormatsSupportedFmts[] = { + { "Postscript", "2", NULL } +}; +static XpOidDocFmtList DefaultRawFormatsSupported = { + DefaultRawFormatsSupportedFmts, XpNumber(DefaultRawFormatsSupportedFmts) +}; + +static XpOid ValidInputTraysOids[] = { + xpoid_val_input_tray_manual, + xpoid_val_input_tray_main, + xpoid_val_input_tray_envelope, + xpoid_val_input_tray_large_capacity, + xpoid_val_input_tray_bottom +}; +static XpOidList ValidInputTrays = { + ValidInputTraysOids, XpNumber(ValidInputTraysOids) +}; + +static XpOid ValidMediumSizesOids[] = { + xpoid_val_medium_size_iso_a4, + xpoid_val_medium_size_na_letter, + xpoid_val_medium_size_na_legal, + xpoid_val_medium_size_executive, + xpoid_val_medium_size_iso_designated_long, + xpoid_val_medium_size_na_number_10_envelope +}; +static XpOidList ValidMediumSizes = { + ValidMediumSizesOids, XpNumber(ValidMediumSizesOids) +}; + +static XpOidDocFmt DefaultDocumentFormat = { + "Postscript", "2", NULL +}; + + +/* + * init struct for XpValidate*Pool + */ +XpValidatePoolsRec PsValidatePoolsRec = { + &ValidContentOrientations, &DefaultContentOrientations, + &ValidDocFormatsSupported, &DefaultDocFormatsSupported, + &ValidInputTrays, &ValidMediumSizes, + &ValidPlexes, &DefaultPlexes, + &ValidPrinterResolutions, &DefaultPrinterResolutions, + &ValidEmbeddedFormatsSupported, &DefaultEmbeddedFormatsSupported, + &ValidListfontsModes, &DefaultListfontsModes, + &ValidRawFormatsSupported, &DefaultRawFormatsSupported, + &ValidSetupProviso, + &DefaultDocumentFormat +}; diff --git a/Xprint/ps/PsAttr.c b/Xprint/ps/PsAttr.c new file mode 100644 index 000000000..8a5bee9e3 --- /dev/null +++ b/Xprint/ps/PsAttr.c @@ -0,0 +1,113 @@ +/* $Xorg: PsAttr.c,v 1.4 2001/02/09 02:04:35 xorgcvs Exp $ */ +/* + +Copyright 1996, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ +/* + * (c) Copyright 1996 Hewlett-Packard Company + * (c) Copyright 1996 International Business Machines Corp. + * (c) Copyright 1996 Sun Microsystems, Inc. + * (c) Copyright 1996 Novell, Inc. + * (c) Copyright 1996 Digital Equipment Corp. + * (c) Copyright 1996 Fujitsu Limited + * (c) Copyright 1996 Hitachi, Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the names of the copyright holders + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in this Software without prior written authorization + * from said copyright holders. + */ + +/******************************************************************* +** +** ********************************************************* +** * +** * File: PsAttr.c +** * +** * Contents: Attribute-handling functions for the PS driver +** * +** * Created By: Roger Helmendach (Liberty Systems) +** * +** * Copyright: Copyright 1996 The Open Group, Inc. +** * +** ********************************************************* +** +********************************************************************/ + +#include "Ps.h" +#include "attributes.h" + +char * +PsGetAttributes( + XpContextPtr pCon, + XPAttributes pool) +{ + return XpGetAttributes(pCon, pool); +} + +char * +PsGetOneAttribute( + XpContextPtr pCon, + XPAttributes pool, + char *attr) +{ + return XpGetOneAttribute(pCon, pool, attr); +} + +int +PsAugmentAttributes( + XpContextPtr pCon, + XPAttributes pool, + char *attrs) +{ + return XpAugmentAttributes(pCon, pool, attrs); +} + +int +PsSetAttributes( + XpContextPtr pCon, + XPAttributes pool, + char *attrs) +{ + return XpSetAttributes(pCon, pool, attrs); +} diff --git a/Xprint/ps/PsCache.c b/Xprint/ps/PsCache.c new file mode 100644 index 000000000..8c9f4a926 --- /dev/null +++ b/Xprint/ps/PsCache.c @@ -0,0 +1,324 @@ +/* + +Copyright 1996, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ +/* + * (c) Copyright 1996 Hewlett-Packard Company + * (c) Copyright 1996 International Business Machines Corp. + * (c) Copyright 1996, 2000 Sun Microsystems, Inc. All Rights Reserved. + * (c) Copyright 1996 Novell, Inc. + * (c) Copyright 1996 Digital Equipment Corp. + * (c) Copyright 1996 Fujitsu Limited + * (c) Copyright 1996 Hitachi, Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the names of the copyright holders + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in this Software without prior written authorization + * from said copyright holders. + */ + +/******************************************************************* +** +** ********************************************************* +** * +** * File: PsCache.c +** * +** * Contents: Character-caching routines +** * +** * Created By: Jay Hobson (Sun MicroSystems) +** * +** * Copyright: Copyright 1996 The Open Group, Inc. +** * +** ********************************************************* +** +********************************************************************/ + +#include "Ps.h" +#include "gcstruct.h" +#include "windowstr.h" +#include "fntfil.h" +#include "fntfilst.h" + +#define GET 0 +#define RESET 1 + +struct bm_cache_list { + struct bm_cache_list *next; + struct bm_cache_list *prev; + int height; + long id; + char *pBuffer; +}; + +struct bm_cache_head { + struct bm_cache_list *head; + int width; + struct bm_cache_head *next; + struct bm_cache_head *prev; +}; + +static struct bm_cache_head *bm_cache = NULL; + +static long +PsBmUniqueId(int func) +{ + static long unique_id = 0; + + if(func == RESET) + { + unique_id = 0; + return 0; + } + else + return ++unique_id; +} + +int +PsBmIsImageCached( + int gWidth, + int gHeight, + char *pBuffer) +{ + int return_val = 0; + struct bm_cache_head *pList = bm_cache; + + while(pList != NULL && !return_val) + { + if(pList->width == gWidth) + { + struct bm_cache_list *pItem = pList->head; + + while(pItem != NULL) + { + if(pItem->height == gHeight) + { + int length = 4*(gWidth/32+(gWidth%32!=0))*gHeight; + + if(!memcmp(pItem->pBuffer, pBuffer, sizeof(char)*length)) + { + return_val = pItem->id; + break; + } + } + else if(pItem->height > gHeight) + break; + + pItem = pItem->next; + } + } + else if(pList->width > gWidth) + break; + + pList = pList->next; + } + return return_val; +} + +int +PsBmPutImageInCache( + int gWidth, + int gHeight, + char *pBuffer) +{ + int return_val = 0; + struct bm_cache_head *pList = bm_cache; + struct bm_cache_list *pNew; + int length = 4*(gWidth/32+(gWidth%32!=0))*gHeight; + + if(gWidth == 1 && gHeight == 1 && pBuffer[0] == 0) + return return_val; + + pNew = (struct bm_cache_list *)malloc(sizeof(struct bm_cache_list)); + pNew->next = NULL; + pNew->prev = NULL; + pNew->height = gHeight; + pNew->id = PsBmUniqueId(GET); + pNew->pBuffer = (char *)malloc(sizeof(char)*length); + + memcpy(pNew->pBuffer, pBuffer, length); + + while(pList != NULL) + { + if(pList->width == gWidth) + { + struct bm_cache_list *pItem = pList->head; + + while(pItem != NULL) + { + if(pItem->height >= gHeight) + { + pNew->next = pItem; + pNew->prev = pItem->prev; + if(pItem->prev != NULL) + pItem->prev->next = pNew; + else + pList->head = pNew; + pItem->prev = pNew; + + return_val = pNew->id; + + break; + } + else if(pItem->next == NULL) + { + pNew->prev = pItem; + pItem->next = pNew; + + return_val = pNew->id; + + break; + } + + pItem = pItem->next; + } + + break; + } + + pList = pList->next; + } + + if(pList == NULL) + { + struct bm_cache_head *pNewList; + + pNewList = (struct bm_cache_head *)malloc(sizeof(struct bm_cache_head)); + + pNewList->next = NULL; + pNewList->prev = NULL; + pNewList->width = gWidth; + pNewList->head = pNew; + + if(bm_cache == NULL) + { + bm_cache = pNewList; + return_val = pNew->id; + } + else + { + pList = bm_cache; + + while(pList != NULL) + { + if(pList->width > gWidth) + { + pNewList->next = pList; + pNewList->prev = pList->prev; + + if(pList->prev != NULL) + pList->prev->next = pNewList; + else + bm_cache = pNewList; + pList->prev = pNewList; + + return_val = pNew->id; + + break; + } + else if(pList->next == NULL) + { + pNewList->prev = pList; + pList->next = pNewList; + + return_val = pNew->id; + + break; + } + + pList = pList->next; + } + } + } + + return return_val; +} + + +static void +PsBmClearImageCacheItem( + struct bm_cache_list *pItem) +{ + if(pItem != NULL) + { + if(pItem->pBuffer != NULL) + free(pItem->pBuffer); + pItem->pBuffer = NULL; + + if(pItem->next) + PsBmClearImageCacheItem(pItem->next); + pItem->next = NULL; + + free(pItem); + pItem = NULL; + } +} + +static void +PsBmClearImageCacheList( + struct bm_cache_head *pList) +{ + if(pList != NULL) + { + if(pList->head) + PsBmClearImageCacheItem(pList->head); + pList->head = NULL; + + if(pList->next) + PsBmClearImageCacheList(pList->next); + pList->next = NULL; + + free(pList); + pList = NULL; + } +} + +void +PsBmClearImageCache() +{ + PsBmClearImageCacheList(bm_cache); + + bm_cache = NULL; + + PsBmUniqueId(RESET); +} + diff --git a/Xprint/ps/PsColor.c b/Xprint/ps/PsColor.c new file mode 100644 index 000000000..9c76904d6 --- /dev/null +++ b/Xprint/ps/PsColor.c @@ -0,0 +1,223 @@ +/* $Xorg: PsColor.c,v 1.4 2001/02/09 02:04:36 xorgcvs Exp $ */ +/* + +Copyright 1996, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ +/* + * (c) Copyright 1996 Hewlett-Packard Company + * (c) Copyright 1996 International Business Machines Corp. + * (c) Copyright 1996 Sun Microsystems, Inc. + * (c) Copyright 1996 Novell, Inc. + * (c) Copyright 1996 Digital Equipment Corp. + * (c) Copyright 1996 Fujitsu Limited + * (c) Copyright 1996 Hitachi, Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the names of the copyright holders + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in this Software without prior written authorization + * from said copyright holders. + */ + +/******************************************************************* +** +** ********************************************************* +** * +** * File: PsColor.c +** * +** * Contents: Color routines for the PS driver +** * +** * Created By: Roger Helmendach (Liberty Systems) +** * +** * Copyright: Copyright 1996 The Open Group, Inc. +** * +** ********************************************************* +** +********************************************************************/ + +#include "Ps.h" +#include "gcstruct.h" +#include "windowstr.h" +#include "colormapst.h" + +Bool +PsCreateColormap(ColormapPtr pColor) +{ + int i; + unsigned short rgb; + VisualPtr pVisual = pColor->pVisual; + Pixel pix; + + if( pVisual->class==TrueColor ) + { + for( i=0 ; i<pVisual->ColormapEntries ; i++ ) + { + rgb = (i<<8)|i; + + pColor->red[i].fShared = FALSE; + pColor->red[i].co.local.red = rgb; + pColor->red[i].co.local.green = 0; + pColor->red[i].co.local.blue = 0; + + pColor->green[i].fShared = FALSE; + pColor->green[i].co.local.red = 0; + pColor->green[i].co.local.green = rgb; + pColor->green[i].co.local.blue = 0; + + pColor->blue[i].fShared = FALSE; + pColor->blue[i].co.local.red = 0; + pColor->blue[i].co.local.green = 0; + pColor->blue[i].co.local.blue = rgb; + } + } + return TRUE; +} + +void +PsDestroyColormap(ColormapPtr pColor) +{ +} + +void +PsInstallColormap(ColormapPtr pColor) +{ + PsScreenPrivPtr pPriv = + (PsScreenPrivPtr)pColor->pScreen->devPrivates[PsScreenPrivateIndex].ptr; + pPriv->CMap = pColor; +} + +void +PsUninstallColormap(ColormapPtr pColor) +{ +} + +int +PsListInstalledColormaps( + ScreenPtr pScreen, + XID *pCmapList) +{ + return 0; +} + +void +PsStoreColors( + ColormapPtr pColor, + int ndef, + xColorItem *pdefs) +{ + int i; + for( i=0 ; i<ndef ; i++ ) + { + if( pdefs[i].flags&DoRed ) + pColor->red[pdefs[i].pixel].co.local.red = pdefs[i].red; + if( pdefs[i].flags&DoGreen ) + pColor->red[pdefs[i].pixel].co.local.green = pdefs[i].green; + if( pdefs[i].flags&DoBlue ) + pColor->red[pdefs[i].pixel].co.local.blue = pdefs[i].blue; + } +} + +void +PsResolveColor( + unsigned short *pRed, + unsigned short *pGreen, + unsigned short *pBlue, + VisualPtr pVisual) +{ +} + +int +PsGetPixelColor(ColormapPtr cMap, int pixval) +{ + int r, g, b; + if( cMap->pVisual->class==TrueColor ) return(pixval); + if( pixval<0 || pixval>255 ) return(0); + r = cMap->red[pixval].co.local.red>>8; + g = cMap->red[pixval].co.local.green>>8; + b = cMap->red[pixval].co.local.blue>>8; + return((r<<16)|(g<<8)|b); +} + +void +PsSetFillColor(DrawablePtr pDrawable, GCPtr pGC, PsOutPtr psOut, + ColormapPtr cMap) +{ + switch(pGC->fillStyle) + { + case FillSolid: + PsOut_Color(psOut, PsGetPixelColor(cMap, pGC->fgPixel)); + break; + case FillTiled: + if( !PsOut_BeginPattern(psOut, pGC->tile.pixmap, + pGC->tile.pixmap->drawable.width, + pGC->tile.pixmap->drawable.height, PsTile, 0, 0) ) + { + PsReplayPixmap(pGC->tile.pixmap, pDrawable); + PsOut_EndPattern(psOut); + } + PsOut_SetPattern(psOut, pGC->tile.pixmap, PsTile); + break; + case FillStippled: + if( !PsOut_BeginPattern(psOut, pGC->stipple, + pGC->stipple->drawable.width, + pGC->stipple->drawable.height, PsStip, 0, + PsGetPixelColor(cMap, pGC->fgPixel)) ) + { + PsReplayPixmap(pGC->stipple, pDrawable); + PsOut_EndPattern(psOut); + } + PsOut_SetPattern(psOut, pGC->stipple, PsStip); + break; + case FillOpaqueStippled: + if( !PsOut_BeginPattern(psOut, pGC->stipple, + pGC->stipple->drawable.width, + pGC->stipple->drawable.height, PsOpStip, + PsGetPixelColor(cMap, pGC->bgPixel), + PsGetPixelColor(cMap, pGC->fgPixel)) ) + { + PsReplayPixmap(pGC->stipple, pDrawable); + PsOut_EndPattern(psOut); + } + PsOut_SetPattern(psOut, pGC->stipple, PsOpStip); + break; + } +} diff --git a/Xprint/ps/PsDef.h b/Xprint/ps/PsDef.h new file mode 100644 index 000000000..ec648c442 --- /dev/null +++ b/Xprint/ps/PsDef.h @@ -0,0 +1,93 @@ +/* $Xorg: PsDef.h,v 1.4 2001/02/09 02:04:36 xorgcvs Exp $ */ +/* + +Copyright 1996, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ +/* + * (c) Copyright 1996 Hewlett-Packard Company + * (c) Copyright 1996 International Business Machines Corp. + * (c) Copyright 1996 Sun Microsystems, Inc. + * (c) Copyright 1996 Novell, Inc. + * (c) Copyright 1996 Digital Equipment Corp. + * (c) Copyright 1996 Fujitsu Limited + * (c) Copyright 1996 Hitachi, Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the names of the copyright holders + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in this Software without prior written authorization + * from said copyright holders. + */ + +/******************************************************************* +** +** ********************************************************* +** * +** * File: PsDef.h +** * +** * Contents: extran defines and includes for the Ps driver +** * for a printing X server. +** * +** * Created By: Roger Helmendach (Liberty Systems) +** * +** * Copyright: Copyright 1996 The Open Group, Inc. +** * +** ********************************************************* +** +********************************************************************/ +#ifndef _PSDEF_H_ +#define _PSDEF_H_ + +#define DT_PRINT_JOB_HEADER "DT_PRINT_JOB_HEADER" +#define DT_PRINT_JOB_TRAILER "DT_PRINT_JOB_TRAILER" +#define DT_PRINT_JOB_COMMAND "DT_PRINT_JOB_COMMAND" +#define DT_PRINT_JOB_EXEC_COMMAND "DT_PRINT_JOB_EXEC_COMMAND" +#define DT_PRINT_JOB_EXEC_OPTIONS "DT_PRINT_JOB_EXEC_OPTION" +#define DT_PRINT_PAGE_HEADER "DT_PRINT_PAGE_HEADER" +#define DT_PRINT_PAGE_TRAILER "DT_PRINT_PAGE_TRAILER" +#define DT_PRINT_PAGE_COMMAND "DT_PRINT_PAGE_COMMAND" + +#define DT_IN_FILE_STRING "%(InFile)%" +#define DT_OUT_FILE_STRING "%(OutFile)%" +#define DT_ALLOWED_COMMANDS_FILE "printCommands" + +#endif /* _PSDEF_H_ */ diff --git a/Xprint/ps/PsFonts.c b/Xprint/ps/PsFonts.c new file mode 100644 index 000000000..1a4692692 --- /dev/null +++ b/Xprint/ps/PsFonts.c @@ -0,0 +1,185 @@ +/* $Xorg: PsFonts.c,v 1.6 2001/03/06 16:30:15 pookie Exp $ */ +/* + +Copyright 1996, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ +/* + * (c) Copyright 1996 Hewlett-Packard Company + * (c) Copyright 1996 International Business Machines Corp. + * (c) Copyright 1996 Sun Microsystems, Inc. + * (c) Copyright 1996 Novell, Inc. + * (c) Copyright 1996 Digital Equipment Corp. + * (c) Copyright 1996 Fujitsu Limited + * (c) Copyright 1996 Hitachi, Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the names of the copyright holders + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in this Software without prior written authorization + * from said copyright holders. + */ + +/******************************************************************* +** +** ********************************************************* +** * +** * File: PsFonts.c +** * +** * Contents: Font code for PS driver. +** * +** * Created By: Roger Helmendach (Liberty Systems) +** * +** * Copyright: Copyright 1996 The Open Group, Inc. +** * +** ********************************************************* +** +********************************************************************/ + +#include "miscstruct.h" +#include "fontstruct.h" +#include "dixfontstr.h" +#include "scrnintstr.h" +#include "fontxlfd.h" + +#include "Ps.h" + +Bool +PsRealizeFont( + ScreenPtr pscr, + FontPtr pFont) +{ + return TRUE; +} + +Bool +PsUnrealizeFont( + ScreenPtr pscr, + FontPtr pFont) +{ + return TRUE; +} + +char * +PsGetFontName(FontPtr pFont) +{ + int i; + int nprops = pFont->info.nprops; + FontPropPtr props = pFont->info.props; + Atom name = MakeAtom("FONT", 4, True); + Atom value = (Atom)0; + + for( i=0 ; i<nprops ; i++ ) + { + if( props[i].name==name ) + { value = props[i].value; break; } + } + if( !value ) return (char *)0; + return NameForAtom(value); +} + +int +PsGetFontSize(FontPtr pFont, float *mtx) +{ + FontScalableRec vals; + char *name = PsGetFontName(pFont); + int value = 0; + + FontParseXLFDName(name, &vals, FONT_XLFD_REPLACE_NONE); + if( vals.values_supplied&PIXELSIZE_ARRAY ) + { + int i; + for( i=0 ; i<4 ; i++ ) + mtx[i] = (float)vals.pixel_matrix[i]; + } + else + { + value = vals.pixel; + if( !value ) value = 20; + } + return value; +} + +char * +PsGetPSFontName(FontPtr pFont) +{ + int i; + int nprops = pFont->info.nprops; + FontPropPtr props = pFont->info.props; + Atom name = MakeAtom("PRINTER_RESIDENT_FONT", 21, True); + Atom value = (Atom)0; + + for( i=0 ; i<nprops ; i++ ) + { + if( props[i].name==name ) + { value = props[i].value; break; } + } + if( !value ) return (char *)0; + return NameForAtom(value); +} + +int +PsIsISOLatin1Encoding(FontPtr pFont) +{ + int i; + int nprops = pFont->info.nprops; + FontPropPtr props = pFont->info.props; + Atom reg = MakeAtom("CHARSET_REGISTRY", 16, True); + Atom enc = MakeAtom("CHARSET_ENCODING", 16, True); + Atom rv = 0, ev = 0; + char *rp = 0; + char *ep = 0; + + for( i=0 ; i<nprops ; i++ ) + { + if( props[i].name==reg ) rv = props[i].value; + if( props[i].name==enc ) ev = props[i].value; + } + if( rv ) rp = NameForAtom(rv); + if( ev ) ep = NameForAtom(ev); + if( (!rp) || (!ep) ) return(0); + if( (char)tolower(rp[0])!='i' || + (char)tolower(rp[1])!='s' || + (char)tolower(rp[2])!='o' || + memcmp(&rp[3], "8859", 4)!=0 || + ep[0]!='1' ) return(0); + return(1); +} diff --git a/Xprint/ps/PsGC.c b/Xprint/ps/PsGC.c new file mode 100644 index 000000000..c6e352279 --- /dev/null +++ b/Xprint/ps/PsGC.c @@ -0,0 +1,380 @@ +/* $Xorg: PsGC.c,v 1.4 2001/02/09 02:04:36 xorgcvs Exp $ */ +/* + +Copyright 1996, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ +/* + * (c) Copyright 1996 Hewlett-Packard Company + * (c) Copyright 1996 International Business Machines Corp. + * (c) Copyright 1996 Sun Microsystems, Inc. + * (c) Copyright 1996 Novell, Inc. + * (c) Copyright 1996 Digital Equipment Corp. + * (c) Copyright 1996 Fujitsu Limited + * (c) Copyright 1996 Hitachi, Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the names of the copyright holders + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in this Software without prior written authorization + * from said copyright holders. + */ + +/******************************************************************* +** +** ********************************************************* +** * +** * File: PsGC.c +** * +** * Contents: Graphics Context handling for the PS driver +** * +** * Created By: Roger Helmendach (Liberty Systems) +** * +** * Copyright: Copyright 1996 The Open Group, Inc. +** * +** ********************************************************* +** +********************************************************************/ + +#include "Ps.h" +#include "gcstruct.h" +#include "pixmapstr.h" +#include "windowstr.h" +#include "migc.h" +#include "scrnintstr.h" + +static GCOps PsGCOps = +{ + PsFillSpans, + PsSetSpans, + PsPutImage, + PsCopyArea, + PsCopyPlane, + PsPolyPoint, + PsPolyLine, + PsPolySegment, + PsPolyRectangle, + PsPolyArc, + PsFillPolygon, + PsPolyFillRect, + PsPolyFillArc, + PsPolyText8, + PsPolyText16, + PsImageText8, + PsImageText16, + PsImageGlyphBlt, + PsPolyGlyphBlt, + PsPushPixels +#ifdef NEED_LINEHELPER + ,NULL +#endif +}; + + +static GCFuncs PsGCFuncs = +{ + PsValidateGC, + PsChangeGC, + PsCopyGC, + PsDestroyGC, + PsChangeClip, + PsDestroyClip, + PsCopyClip +}; + +Bool +PsCreateGC(pGC) + GCPtr pGC; +{ + pGC->clientClip = NULL; + pGC->clientClipType = CT_NONE; + + pGC->ops = &PsGCOps; + pGC->funcs = &PsGCFuncs; + + pGC->clientClip = (pointer)xalloc(sizeof(PsClipRec)); + memset(pGC->clientClip, 0, sizeof(PsClipRec)); + return TRUE; +} + +static int +PsGetDrawablePrivateStuff( + DrawablePtr pDrawable, + GC *gc, + unsigned long *valid, + PsOutPtr *psOut, + ColormapPtr *cMap) +{ + XpContextPtr pCon; + PsPixmapPrivPtr pPriv; + PsContextPrivPtr cPriv; + PsScreenPrivPtr sPriv; + + switch(pDrawable->type) + { + case DRAWABLE_PIXMAP: + return FALSE; + case DRAWABLE_WINDOW: + pCon = PsGetContextFromWindow((WindowPtr)pDrawable); + if( pCon==NULL ) return FALSE; + else + { + cPriv = pCon->devPrivates[PsContextPrivateIndex].ptr; + sPriv = (PsScreenPrivPtr) + pDrawable->pScreen->devPrivates[PsScreenPrivateIndex].ptr; + *gc = cPriv->lastGC; + *valid = cPriv->validGC; + *psOut = cPriv->pPsOut; + *cMap = sPriv->CMap; + return TRUE; + } + default: + return FALSE; + } +} + +int +PsUpdateDrawableGC( + GCPtr pGC, + DrawablePtr pDrawable, + PsOutPtr *psOut, + ColormapPtr *cMap) +{ + GC dGC; + unsigned long valid; + int i; + PsContextPrivPtr cPriv; + BoxPtr boxes; + + if (!PsGetDrawablePrivateStuff(pDrawable, &dGC, &valid, psOut, cMap)) + return FALSE; + + switch (pDrawable->type) { + + case DRAWABLE_PIXMAP: + /* we don't support pixmaps yet! */ + return FALSE; + break; + case DRAWABLE_WINDOW: + if( pGC ) + { + RegionPtr pReg; + WindowPtr pWin = (WindowPtr)pDrawable; + Bool freeClip; + PsClipPtr clp = (PsClipPtr)pGC->clientClip; + if( clp->outterClips ) + { xfree(clp->outterClips); clp->outterClips = 0; } + clp->nOutterClips = 0; + if( pGC->subWindowMode==IncludeInferiors ) + { + pReg = NotClippedByChildren(pWin); + freeClip = TRUE; + } + else + { + pReg = &pWin->clipList; + freeClip = FALSE; + } + + if( pReg->data ) + { + boxes = (BoxPtr)((char *)pReg->data+sizeof(long)*2); + clp->nOutterClips = pReg->data->numRects; + clp->outterClips = + (PsRectPtr)xalloc(clp->nOutterClips*sizeof(PsRectRec)); + for( i=0 ; i<clp->nOutterClips ; i++ ) + { + clp->outterClips[i].x = boxes[i].x1; + clp->outterClips[i].y = boxes[i].y1; + clp->outterClips[i].w = (boxes[i].x2-boxes[i].x1)+1; + clp->outterClips[i].h = (boxes[i].y2-boxes[i].y1)+1; + } + } + + if( freeClip ) (*pGC->pScreen->RegionDestroy)(pReg); + PsOut_Offset(*psOut, pDrawable->x, pDrawable->y); + PsOut_Clip(*psOut, pGC->clientClipType, (PsClipPtr)pGC->clientClip); + } + cPriv = ( PsGetContextFromWindow( (WindowPtr)pDrawable ) ) + ->devPrivates[PsContextPrivateIndex].ptr; + break; + } + return TRUE; +} + +void +PsValidateGC(GCPtr pGC, unsigned long changes, DrawablePtr pDrawable) +{ + pGC->ops = &PsGCOps; +} + +void +PsChangeGC(GCPtr pGC, unsigned long changes) +{ +} + +void +PsCopyGC(GCPtr pGCSrc, unsigned long mask, GCPtr pGCDst) +{ +} + +void +PsDestroyGC(GCPtr pGC) +{ + PsDestroyClip(pGC); + xfree(pGC->clientClip); +} + +void +PsChangeClip(GCPtr pGC, int type, pointer pValue, int nrects) +{ + int i; + PsClipPtr clp = (PsClipPtr)pGC->clientClip; + RegionPtr rgn; + BoxPtr boxes; + xRectangle *rects; + + PsDestroyClip(pGC); + pGC->clientClipType = type; + switch(type) + { + case CT_NONE: break; + case CT_PIXMAP: + clp->elms = PsCreateFillElementList((PixmapPtr)pValue, &clp->nElms); + (*pGC->pScreen->DestroyPixmap)((PixmapPtr)pValue); + break; + case CT_REGION: + rgn = (RegionPtr)pValue; + boxes = (BoxPtr)((char *)rgn->data+sizeof(long)*2); + clp->nRects = rgn->data->numRects; + clp->rects = (PsRectPtr)xalloc(clp->nRects*sizeof(PsRectRec)); + for( i=0 ; i<clp->nRects ; i++ ) + { + clp->rects[i].x = boxes[i].x1; + clp->rects[i].y = boxes[i].y1; + clp->rects[i].w = (boxes[i].x2-boxes[i].x1)+1; + clp->rects[i].h = (boxes[i].y2-boxes[i].y1)+1; + } + (*pGC->pScreen->RegionDestroy)((RegionPtr)pValue); + break; + case CT_UNSORTED: + case CT_YSORTED: + case CT_YXSORTED: + case CT_YXBANDED: + rects = (xRectangle *)pValue; + clp->nRects = nrects; + clp->rects = (PsRectPtr)xalloc(clp->nRects*sizeof(PsRectRec)); + for( i=0 ; i<clp->nRects ; i++ ) + { + clp->rects[i].x = rects[i].x; + clp->rects[i].y = rects[i].y; + clp->rects[i].w = rects[i].width; + clp->rects[i].h = rects[i].height; + } + xfree(pValue); + break; + } +} + +void +PsDestroyClip(GCPtr pGC) +{ + PsClipPtr clp = (PsClipPtr)pGC->clientClip; + + if( clp->rects ) xfree(clp->rects); + if( clp->outterClips ) xfree(clp->outterClips); + clp->rects = (PsRectPtr)0; + clp->outterClips = (PsRectPtr)0; + clp->nRects = 0; + clp->nOutterClips = 0; + if( clp->elms ) PsDestroyFillElementList(clp->nElms, clp->elms); + clp->elms = (PsElmPtr)0; + clp->nElms = 0; + pGC->clientClipType = CT_NONE; +} + +void +PsCopyClip(GCPtr pDst, GCPtr pSrc) +{ + PsClipPtr src = (PsClipPtr)pSrc->clientClip; + PsClipPtr dst = (PsClipPtr)pDst->clientClip; + + PsDestroyClip(pDst); + pDst->clientClipType = pSrc->clientClipType; + *dst = *src; + if( src->rects ) + { + dst->rects = (PsRectPtr)xalloc(src->nRects*sizeof(PsRectRec)); + memcpy(dst->rects, src->rects, src->nRects*sizeof(PsRectRec)); + } + if( src->elms ) + dst->elms = PsCloneFillElementList(src->nElms, src->elms); +} + + +GCPtr +PsCreateAndCopyGC(DrawablePtr pDrawable, GCPtr pSrc) +{ + GCPtr pDst; + + if ((pDst = + CreateScratchGC(pDrawable->pScreen, pDrawable->depth)) == NULL) + { + return NULL; + } + + if (CopyGC(pSrc, pDst, + GCFunction | GCPlaneMask | GCForeground | GCBackground | + GCLineWidth | GCLineStyle | GCCapStyle | GCJoinStyle | + GCFillStyle | GCFillRule | GCTile | GCStipple | + GCTileStipXOrigin | GCTileStipYOrigin | GCFont | + GCSubwindowMode | GCGraphicsExposures | GCClipXOrigin | + GCClipYOrigin | GCClipMask | GCDashOffset | GCDashList | + GCArcMode) != Success) + { + (void)FreeGC(pDst, (GContext)0); + + return NULL; + } + + return pDst; +} + diff --git a/Xprint/ps/PsInit.c b/Xprint/ps/PsInit.c new file mode 100644 index 000000000..72c83448e --- /dev/null +++ b/Xprint/ps/PsInit.c @@ -0,0 +1,413 @@ +/* $Xorg: PsInit.c,v 1.4 2001/02/09 02:04:36 xorgcvs Exp $ */ +/* + +Copyright 1996, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ +/* + * (c) Copyright 1996 Hewlett-Packard Company + * (c) Copyright 1996 International Business Machines Corp. + * (c) Copyright 1996 Sun Microsystems, Inc. + * (c) Copyright 1996 Novell, Inc. + * (c) Copyright 1996 Digital Equipment Corp. + * (c) Copyright 1996 Fujitsu Limited + * (c) Copyright 1996 Hitachi, Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the names of the copyright holders + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in this Software without prior written authorization + * from said copyright holders. + */ + +/******************************************************************* +** +** ********************************************************* +** * +** * File: PsInit.c +** * +** * Contents: Initialization code of Ps driver for the print server. +** * +** * Created By: Roger Helmendach (Liberty Systems) +** * +** * Copyright: Copyright 1996 The Open Group, Inc. +** * +** ********************************************************* +** +********************************************************************/ + +#include <stdio.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/wait.h> + +#include "Ps.h" +#include "AttrValid.h" +#include "../../mfb/mfb.h" + +#include "windowstr.h" + +static void AllocatePsPrivates(ScreenPtr pScreen); +static int PsInitContext(XpContextPtr pCon); + +extern Bool _XpBoolNoop(); +extern void _XpVoidNoop(); +extern Bool cfbCreateDefColormap(ScreenPtr pScreen); + +int PsScreenPrivateIndex; +int PsContextPrivateIndex; +int PsPixmapPrivateIndex; +int PsWindowPrivateIndex; +int PsGCPrivateIndex; + +Bool +InitializePsDriver(ndx, pScreen, argc, argv) + int ndx; + ScreenPtr pScreen; + int argc; + char **argv; +{ + int maxXres, maxYres, maxWidth, maxHeight; + int maxRes, maxDim, numBytes; + PsScreenPrivPtr pPriv; + char **printerNames; + int numPrinters; + int nVisuals; + int nDepths; + VisualPtr visuals; + DepthPtr depths; + +/* + * Register this driver's InitContext function with the print + * extension. + */ + XpRegisterInitFunc(pScreen, "XP-POSTSCRIPT", PsInitContext); + +/* + * Create and fill in the devPrivate for the PS driver. + */ + AllocatePsPrivates(pScreen); + + pPriv = (PsScreenPrivPtr)pScreen->devPrivates[PsScreenPrivateIndex].ptr; +/*pPriv->resDB = rmdb;*/ + + pScreen->defColormap = (Colormap) FakeClientID(0); + pScreen->blackPixel = 1; + pScreen->whitePixel = 0; + pScreen->QueryBestSize = (QueryBestSizeProcPtr)PsQueryBestSize; + pScreen->SaveScreen = _XpBoolNoop; + pScreen->GetImage = _XpVoidNoop; + pScreen->GetSpans = _XpVoidNoop; + pScreen->CreateWindow = PsCreateWindow; + pScreen->DestroyWindow = PsDestroyWindow; + pScreen->PositionWindow = PsPositionWindow; + pScreen->ChangeWindowAttributes = PsChangeWindowAttributes; + pScreen->RealizeWindow = PsMapWindow; + pScreen->UnrealizeWindow = PsUnmapWindow; + pScreen->PaintWindowBackground = PsPaintWindow; + pScreen->PaintWindowBorder = PsPaintWindow; + pScreen->CloseScreen = PsCloseScreen; + pScreen->CopyWindow = PsCopyWindow; + /* XXX Hard routine to write! */ + +/* + * These two are going to be VERY different... + */ + pScreen->CreatePixmap = PsCreatePixmap; + pScreen->DestroyPixmap = PsDestroyPixmap; + pScreen->RealizeFont = PsRealizeFont; + pScreen->UnrealizeFont = PsUnrealizeFont; + pScreen->CreateGC = PsCreateGC; + pScreen->CreateColormap = PsCreateColormap; + pScreen->DestroyColormap = PsDestroyColormap; + pScreen->InstallColormap = PsInstallColormap; + pScreen->UninstallColormap = PsUninstallColormap; + pScreen->ListInstalledColormaps = PsListInstalledColormaps; + pScreen->StoreColors = PsStoreColors; + pScreen->ResolveColor = PsResolveColor; + /* Will BitmapToRegion make any difference at all? */ + pScreen->BitmapToRegion = mfbPixmapToRegion; + + nVisuals = 2; + nDepths = 2; + visuals = (VisualPtr)xalloc(nVisuals*sizeof(VisualRec)); + depths = (DepthPtr) xalloc(nDepths*sizeof(DepthRec)); + + visuals[0].vid = FakeClientID(0); + visuals[0].class = TrueColor; + visuals[0].bitsPerRGBValue = 8; + visuals[0].ColormapEntries = 256; + visuals[0].nplanes = 24; + visuals[0].redMask = 0x00FF0000; + visuals[0].greenMask = 0x0000FF00; + visuals[0].blueMask = 0x000000FF; + visuals[0].offsetRed = 16; + visuals[0].offsetGreen = 8; + visuals[0].offsetBlue = 0; + + visuals[1].vid = FakeClientID(0); + visuals[1].class = PseudoColor; + visuals[1].bitsPerRGBValue = 0; + visuals[1].ColormapEntries = 256; + visuals[1].nplanes = 8; + visuals[1].redMask = 0x0; + visuals[1].greenMask = 0x0; + visuals[1].blueMask = 0x0; + visuals[1].offsetRed = 0x0; + visuals[1].offsetGreen = 0x0; + visuals[1].offsetBlue = 0x0; + + depths[0].depth = 24; + depths[0].numVids = 1; + depths[0].vids = &visuals[0].vid; + + depths[1].depth = 8; + depths[1].numVids = 1; + depths[1].vids = &visuals[1].vid; + +/* THE FOLLOWING CAUSES SERVER DEFAULT VISUAL TO BE 24 BIT */ +/* miScreenInit(pScreen, (pointer)0, + pScreen->width, pScreen->height, + pScreen->width / (pScreen->mmWidth / 25.40), + pScreen->height / (pScreen->mmHeight / 25.40), + 0, 24, nDepths, + depths, visuals[1].vid, nVisuals, visuals, (miBSFuncPtr)0); */ + +/* THE FOLLOWING CAUSES SERVER DEFAULT VISUAL TO BE 8 BIT */ + miScreenInit(pScreen, (pointer)0, + pScreen->width, pScreen->height, + (int) (pScreen->width / (pScreen->mmWidth / 25.40)), + (int) (pScreen->height / (pScreen->mmHeight / 25.40)), + 0, 8, nDepths, + depths, visuals[1].vid, nVisuals, visuals, (miBSFuncPtr)0); + + if( cfbCreateDefColormap(pScreen)==FALSE ) return FALSE; + +/*scalingScreenInit(pScreen);*/ + + return TRUE; +} + +static void +AllocatePsPrivates(ScreenPtr pScreen) +{ + static int PsGeneration = -1; + + if(PsGeneration != serverGeneration) + { + PsScreenPrivateIndex = AllocateScreenPrivateIndex(); + + PsWindowPrivateIndex = AllocateWindowPrivateIndex(); + AllocateWindowPrivate(pScreen, PsWindowPrivateIndex, + sizeof(PsWindowPrivRec)); + + PsContextPrivateIndex = XpAllocateContextPrivateIndex(); + XpAllocateContextPrivate(PsContextPrivateIndex, + sizeof(PsContextPrivRec)); + + PsGCPrivateIndex = AllocateGCPrivateIndex(); + AllocateGCPrivate(pScreen, PsGCPrivateIndex, + sizeof(PsGCPrivRec)); + + PsPixmapPrivateIndex = AllocatePixmapPrivateIndex(); + AllocatePixmapPrivate(pScreen, PsPixmapPrivateIndex, + sizeof(PsPixmapPrivRec)); + + PsGeneration = serverGeneration; + } + pScreen->devPrivates[PsScreenPrivateIndex].ptr = + (pointer)xalloc(sizeof(PsScreenPrivRec)); +} + +/* + * PsInitContext + * + * Establish the appropriate values for a PrintContext used with the PS + * driver. + */ + +static char DOC_ATT_SUPP[]="document-attributes-supported"; +static char DOC_ATT_VAL[]="document-format"; +static char JOB_ATT_SUPP[]="job-attributes-supported"; +static char JOB_ATT_VAL[]=""; +static char PAGE_ATT_SUPP[]="xp-page-attributes-supported"; +static char PAGE_ATT_VAL[]="content-orientation default-printer-resolution \ +default-input-tray default-medium plex"; + +static int +PsInitContext(pCon) + XpContextPtr pCon; +{ + XpDriverFuncsPtr pFuncs; + PsContextPrivPtr pConPriv; + char *server, *attrStr; + extern XpValidatePoolsRec PsValidatePoolsRec; + + /* + * Initialize the attribute store for this printer. + */ + XpInitAttributes(pCon); + + /* + * Initialize the function pointers + */ + pFuncs = &(pCon->funcs); + pFuncs->StartJob = PsStartJob; + pFuncs->EndJob = PsEndJob; + pFuncs->StartDoc = PsStartDoc; + pFuncs->EndDoc = PsEndDoc; + pFuncs->StartPage = PsStartPage; + pFuncs->EndPage = PsEndPage; + pFuncs->PutDocumentData = PsDocumentData; + pFuncs->GetDocumentData = PsGetDocumentData; + pFuncs->GetAttributes = (char *(*)())PsGetAttributes; + pFuncs->SetAttributes = (int (*)())PsSetAttributes; + pFuncs->AugmentAttributes = (int (*)())PsAugmentAttributes; + pFuncs->GetOneAttribute = (char *(*)())PsGetOneAttribute; + pFuncs->DestroyContext = PsDestroyContext; + pFuncs->GetMediumDimensions = PsGetMediumDimensions; + pFuncs->GetReproducibleArea = PsGetReproducibleArea; + pFuncs->SetImageResolution = PsSetImageResolution; + + /* + * Set up the context privates + */ + pConPriv = + (PsContextPrivPtr)pCon->devPrivates[PsContextPrivateIndex].ptr; + + pConPriv->jobFileName = (char *)NULL; + pConPriv->pJobFile = (FILE *)NULL; + + pConPriv->getDocClient = (ClientPtr)NULL; + pConPriv->getDocBufSize = 0; + + /* + * document-attributes-supported + */ + server = XpGetOneAttribute( pCon, XPServerAttr, DOC_ATT_SUPP ); + if ((attrStr = (char *) xalloc(strlen(server) + + strlen(DOC_ATT_SUPP) + strlen(DOC_ATT_VAL) + + strlen(PAGE_ATT_VAL) + 6)) == NULL) + { + return BadAlloc; + } + sprintf(attrStr, "*%s:\t%s %s %s", + DOC_ATT_SUPP, server, DOC_ATT_VAL, PAGE_ATT_VAL); + XpAugmentAttributes( pCon, XPPrinterAttr, attrStr); + xfree(attrStr); + + /* + * job-attributes-supported + */ + server = XpGetOneAttribute( pCon, XPServerAttr, JOB_ATT_SUPP ); + if ((attrStr = (char *) xalloc(strlen(server) + strlen(JOB_ATT_SUPP) + + strlen(JOB_ATT_VAL) + 4)) == NULL) + { + return BadAlloc; + } + sprintf(attrStr, "*%s:\t%s %s", JOB_ATT_SUPP, server, JOB_ATT_VAL); + XpAugmentAttributes(pCon, XPPrinterAttr, attrStr); + xfree(attrStr); + + /* + * xp-page-attributes-supported + */ + server = XpGetOneAttribute( pCon, XPServerAttr, PAGE_ATT_SUPP ); + if ((attrStr = (char *) xalloc(strlen(server) + strlen(PAGE_ATT_SUPP) + + strlen(PAGE_ATT_VAL) + 4)) == NULL) + { + return BadAlloc; + } + sprintf(attrStr, "*%s:\t%s %s", PAGE_ATT_SUPP, server, PAGE_ATT_VAL); + XpAugmentAttributes(pCon, XPPrinterAttr, attrStr); + xfree(attrStr); + + /* + * Validate the attribute pools + */ + XpValidateAttributePool(pCon, XPPrinterAttr, &PsValidatePoolsRec); + XpValidateAttributePool(pCon, XPDocAttr, &PsValidatePoolsRec); + XpValidateAttributePool(pCon, XPJobAttr, &PsValidatePoolsRec); + XpValidateAttributePool(pCon, XPPageAttr, &PsValidatePoolsRec); + + return Success; +} + +static Bool +PsDestroyContext(pCon) + XpContextPtr pCon; +{ + PsContextPrivPtr pConPriv = + (PsContextPrivPtr)pCon->devPrivates[PsContextPrivateIndex].ptr; + + if( pConPriv->pJobFile!=(FILE *)NULL ) + { + fclose(pConPriv->pJobFile); + pConPriv->pJobFile = NULL; + } + if( pConPriv->jobFileName!=(char *)NULL ) + { + unlink(pConPriv->jobFileName); + xfree(pConPriv->jobFileName); + pConPriv->jobFileName = (char *)NULL; + } + +/*### free up visuals/depths ###*/ + + return Success; +} + +XpContextPtr +PsGetContextFromWindow(win) + WindowPtr win; +{ + PsWindowPrivPtr pPriv; + + while( win ) + { + pPriv = (PsWindowPrivPtr)win->devPrivates[PsWindowPrivateIndex].ptr; + if( pPriv->validContext ) return pPriv->context; + win = win->parent; + } + + return NULL; +} diff --git a/Xprint/ps/PsLine.c b/Xprint/ps/PsLine.c new file mode 100644 index 000000000..23e105804 --- /dev/null +++ b/Xprint/ps/PsLine.c @@ -0,0 +1,188 @@ +/* $Xorg: PsLine.c,v 1.4 2001/02/09 02:04:36 xorgcvs Exp $ */ +/* + +Copyright 1996, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ +/* + * (c) Copyright 1996 Hewlett-Packard Company + * (c) Copyright 1996 International Business Machines Corp. + * (c) Copyright 1996 Sun Microsystems, Inc. + * (c) Copyright 1996 Novell, Inc. + * (c) Copyright 1996 Digital Equipment Corp. + * (c) Copyright 1996 Fujitsu Limited + * (c) Copyright 1996 Hitachi, Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the names of the copyright holders + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in this Software without prior written authorization + * from said copyright holders. + */ + +/******************************************************************* +** +** ********************************************************* +** * +** * File: PsLine.c +** * +** * Contents: Line drawing routines for the PS driver +** * +** * Created By: Roger Helmendach (Liberty Systems) +** * +** * Copyright: Copyright 1996 The Open Group, Inc. +** * +** ********************************************************* +** +********************************************************************/ + +#include "Ps.h" +#include "gcstruct.h" +#include "windowstr.h" + +void +PsPolyLine( + DrawablePtr pDrawable, + GCPtr pGC, + int mode, + int nPoints, + xPoint *pPoints) +{ + if( pDrawable->type==DRAWABLE_PIXMAP ) + { + DisplayElmPtr elm; + PixmapPtr pix = (PixmapPtr)pDrawable; + PsPixmapPrivPtr priv = (PsPixmapPrivPtr)pix->devPrivate.ptr; + DisplayListPtr disp; + GCPtr gc; + + if ((gc = PsCreateAndCopyGC(pDrawable, pGC)) == NULL) return; + + disp = PsGetFreeDisplayBlock(priv); + + elm = &disp->elms[disp->nelms]; + elm->type = PolyLineCmd; + elm->gc = gc; + elm->c.polyPts.mode = mode; + elm->c.polyPts.nPoints = nPoints; + elm->c.polyPts.pPoints = (xPoint *)xalloc(nPoints*sizeof(xPoint)); + memcpy(elm->c.polyPts.pPoints, pPoints, nPoints*sizeof(xPoint)); + disp->nelms += 1; + } + else + { + int i; + PsOutPtr psOut; + PsPointPtr pts; + ColormapPtr cMap; + + if( PsUpdateDrawableGC(pGC, pDrawable, &psOut, &cMap)==FALSE ) return; + PsOut_Offset(psOut, pDrawable->x, pDrawable->y); + PsOut_Color(psOut, PsGetPixelColor(cMap, pGC->fgPixel)); + PsLineAttrs(psOut, pGC, cMap); + pts = (PsPointPtr)xalloc(sizeof(PsPointRec)*nPoints); + if( mode==CoordModeOrigin ) + { + for( i=0 ; i<nPoints ; i++ ) + { pts[i].x = pPoints[i].x; pts[i].y = pPoints[i].y; } + } + else + { + pts[0].x = pPoints[0].x; pts[0].y = pPoints[0].y; + for( i=1 ; i<nPoints ; i++ ) + { + pts[i].x = pts[i-1].x+pPoints[i].x; + pts[i].y = pts[i-1].y+pPoints[i].y; + } + } + PsOut_Lines(psOut, nPoints, pts); + xfree(pts); + } +} + +void +PsPolySegment( + DrawablePtr pDrawable, + GCPtr pGC, + int nSegments, + xSegment *pSegments) +{ + if( pDrawable->type==DRAWABLE_PIXMAP ) + { + DisplayElmPtr elm; + PixmapPtr pix = (PixmapPtr)pDrawable; + PsPixmapPrivPtr priv = (PsPixmapPrivPtr)pix->devPrivate.ptr; + DisplayListPtr disp; + GCPtr gc; + + if ((gc = PsCreateAndCopyGC(pDrawable, pGC)) == NULL) return; + + disp = PsGetFreeDisplayBlock(priv); + + elm = &disp->elms[disp->nelms]; + elm->type = PolySegmentCmd; + elm->gc = gc; + elm->c.segments.nSegments = nSegments; + elm->c.segments.pSegments = (xSegment *)xalloc(nSegments*sizeof(xSegment)); + memcpy(elm->c.segments.pSegments, pSegments, nSegments*sizeof(xSegment)); + disp->nelms += 1; + } + else + { + int i; + PsOutPtr psOut; + PsPointRec pts[2]; + ColormapPtr cMap; + + if( PsUpdateDrawableGC(pGC, pDrawable, &psOut, &cMap)==FALSE ) return; + PsOut_Offset(psOut, pDrawable->x, pDrawable->y); + PsOut_Color(psOut, PsGetPixelColor(cMap, pGC->fgPixel)); + PsLineAttrs(psOut, pGC, cMap); + for( i=0 ; i<nSegments ; i++ ) + { + pts[0].x = pSegments[i].x1; + pts[0].y = pSegments[i].y1; + pts[1].x = pSegments[i].x2; + pts[1].y = pSegments[i].y2; + PsOut_Lines(psOut, 2, pts); + } + } +} diff --git a/Xprint/ps/PsMisc.c b/Xprint/ps/PsMisc.c new file mode 100644 index 000000000..86d862ce1 --- /dev/null +++ b/Xprint/ps/PsMisc.c @@ -0,0 +1,320 @@ +/* $Xorg: PsMisc.c,v 1.4 2001/02/09 02:04:36 xorgcvs Exp $ */ +/* + +Copyright 1996, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ +/* + * (c) Copyright 1996 Hewlett-Packard Company + * (c) Copyright 1996 International Business Machines Corp. + * (c) Copyright 1996 Sun Microsystems, Inc. + * (c) Copyright 1996 Novell, Inc. + * (c) Copyright 1996 Digital Equipment Corp. + * (c) Copyright 1996 Fujitsu Limited + * (c) Copyright 1996 Hitachi, Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the names of the copyright holders + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in this Software without prior written authorization + * from said copyright holders. + */ + +/******************************************************************* +** +** ********************************************************* +** * +** * File: PsMisc.c +** * +** * Contents: Miscellaneous code for Ps driver. +** * +** * Created By: Roger Helmendach (Liberty Systems) +** * +** * Copyright: Copyright 1996 The Open Group, Inc. +** * +** ********************************************************* +** +********************************************************************/ + +#include "Xos.h" /* for SIGCLD on pre-POSIX systems */ +#include <stdio.h> +#include "Ps.h" + +#include "cursor.h" +#include "resource.h" + +#include "windowstr.h" +#include "propertyst.h" + + +/*ARGSUSED*/ +void +PsQueryBestSize( + int type, + short *pwidth, + short *pheight, + ScreenPtr pScreen) +{ + unsigned width, highBit; + + switch(type) + { + case CursorShape: + *pwidth = 0; + *pheight = 0; + break; + case TileShape: + case StippleShape: + width = *pwidth; + if (!width) break; + /* Return the nearest power of two >= what they gave us */ + highBit = 0x80000000; + /* Find the highest 1 bit in the given width */ + while(!(highBit & width)) + highBit >>= 1; + /* If greater than that then return the next power of two */ + if((highBit - 1) & width) + highBit <<= 1; + *pwidth = highBit; + /* height is a don't-care */ + break; + } +} + +/* + * PsGetMediumDimensions is installed in the GetMediumDimensions field + * of each Ps-initialized context. + */ +int +PsGetMediumDimensions(XpContextPtr pCon, CARD16 *width, CARD16 *height) +{ + XpGetMediumDimensions(pCon, width, height); + return Success; +} + +/* + * PsGetReproducibleArea is installed in the GetReproducibleArea field + * of each Ps-initialized context. + */ +int +PsGetReproducibleArea(XpContextPtr pCon, xRectangle *pRect) +{ + XpGetReproductionArea(pCon, pRect); + return Success; +} + +/* + * PsSetImageResolution is installed in the SetImageResolution field + * of each Ps-initialized context. + */ +int +PsSetImageResolution(XpContextPtr pCon, int imageRes, Bool *status) +{ + pCon->imageRes = imageRes; + *status = True; + return Success; +} + +/* + * GetPropString searches the window heirarchy from pWin up looking for + * a property by the name of propName. If found, returns the property's + * value. If not, it returns NULL. + */ +/* +char * +GetPropString( + WindowPtr pWin, + char *propName) +{ + Atom atom; + PropertyPtr pProp = (PropertyPtr)NULL; + char *retVal; + + atom = MakeAtom(propName, strlen(propName), FALSE); + if(atom != BAD_RESOURCE) + { + WindowPtr pPropWin; + int n; +*/ + + /* + * The atom has been defined, but it might only exist as a + * property on an unrelated window. + */ +/* + for(pPropWin = pWin; pPropWin != (WindowPtr)NULL; + pPropWin = pPropWin->parent) + { + for(pProp = (PropertyPtr)(wUserProps(pPropWin)); + pProp != (PropertyPtr)NULL; + pProp = pProp->next) + { + if (pProp->propertyName == atom) + break; + } + if(pProp != (PropertyPtr)NULL) + break; + } + if(pProp == (PropertyPtr)NULL) + return (char *)NULL; + + n = (pProp->format/8) * pProp->size; *//* size (bytes) of prop */ +/* + retVal = (char *)xalloc(n + 1); + (void)memcpy((void *)retVal, (void *)pProp->data, n); + retVal[n] = '\0'; + + return retVal; + } + + return (char *)NULL; +} + +#include <signal.h> + +*/ +/* ARGSUSED */ +/* +static void SigchldHndlr (int dummy) +{ + int status, w; + struct sigaction act; + sigfillset(&act.sa_mask); + act.sa_flags = 0; + act.sa_handler = SigchldHndlr; + + w = wait (&status); + +*/ + /* + * Is this really necessary? + */ +/* + sigaction(SIGCHLD, &act, (struct sigaction *)NULL); +} +*/ + +/* + * SystemCmd provides a wrapper for the 'system' library call. The call + * appears to be sensitive to the handling of SIGCHLD, so this wrapper + * sets the status to SIG_DFL, and then resets the established handler + * after system returns. + */ +/* +int +SystemCmd(char *cmdStr) +{ + int status; + struct sigaction newAct, oldAct; + sigfillset(&newAct.sa_mask); + newAct.sa_flags = 0; + newAct.sa_handler = SIG_DFL; + sigfillset(&oldAct.sa_mask); + oldAct.sa_flags = 0; + oldAct.sa_handler = SigchldHndlr; + +*/ + /* + * get the old handler, and set the action to IGN + */ +/* + sigaction(SIGCHLD, &newAct, &oldAct); + + status = system (cmdStr); + + sigaction(SIGCHLD, &oldAct, (struct sigaction *)NULL); + return status; +} +*/ + +Bool +PsCloseScreen( + int index, + ScreenPtr pScreen) +{ + return TRUE; +} + +void +PsLineAttrs( + PsOutPtr psOut, + GCPtr pGC, + ColormapPtr cMap) +{ + int i; + int nDsh; + int dshOff; + int *dsh; + PsCapEnum cap; + PsJoinEnum join; + + switch(pGC->capStyle) { + case CapButt: cap = PsCButt; break; + case CapRound: cap = PsCRound; break; + case CapProjecting: cap = PsCSquare; break; + default: cap = PsCButt; break; } + switch(pGC->joinStyle) { + case JoinMiter: join = PsJMiter; break; + case JoinRound: join = PsJRound; break; + case JoinBevel: join = PsJBevel; break; + default: join = PsJBevel; break; } + if( pGC->lineStyle==LineSolid ) { nDsh = dshOff = 0; dsh = (int *)0; } + else + { + nDsh = pGC->numInDashList; + dshOff = pGC->dashOffset; + if( !nDsh ) dsh = (int *)0; + else + { + dsh = (int *)xalloc(sizeof(int)*nDsh); + for( i=0 ; i<nDsh ; i++ ) dsh[i] = (int)pGC->dash[i]&0xFF; + } + } + + if( pGC->lineStyle!=LineDoubleDash ) + PsOut_LineAttrs(psOut, (int)pGC->lineWidth, + cap, join, nDsh, dsh, dshOff, -1); + else + PsOut_LineAttrs(psOut, (int)pGC->lineWidth, + cap, join, nDsh, dsh, dshOff, + PsGetPixelColor(cMap, pGC->bgPixel)); + if( nDsh && dsh ) xfree(dsh); +} diff --git a/Xprint/ps/PsPixel.c b/Xprint/ps/PsPixel.c new file mode 100644 index 000000000..c2c360d2e --- /dev/null +++ b/Xprint/ps/PsPixel.c @@ -0,0 +1,153 @@ +/* $Xorg: PsPixel.c,v 1.4 2001/02/09 02:04:36 xorgcvs Exp $ */ +/* + +Copyright 1996, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ +/* + * (c) Copyright 1996 Hewlett-Packard Company + * (c) Copyright 1996 International Business Machines Corp. + * (c) Copyright 1996 Sun Microsystems, Inc. + * (c) Copyright 1996 Novell, Inc. + * (c) Copyright 1996 Digital Equipment Corp. + * (c) Copyright 1996 Fujitsu Limited + * (c) Copyright 1996 Hitachi, Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the names of the copyright holders + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in this Software without prior written authorization + * from said copyright holders. + */ + +/******************************************************************* +** +** ********************************************************* +** * +** * File: PsPixel.c +** * +** * Contents: Pixel-drawing code for the PS DDX driver +** * +** * Created By: Roger Helmendach (Liberty Systems) +** * +** * Copyright: Copyright 1995 The Open Group, Inc. +** * +** ********************************************************* +** +********************************************************************/ + +#include <stdio.h> + +#include "windowstr.h" +#include "gcstruct.h" + +#include "Ps.h" + +void +PsPolyPoint( + DrawablePtr pDrawable, + GCPtr pGC, + int mode, + int nPoints, + xPoint *pPoints) +{ + if( pDrawable->type==DRAWABLE_PIXMAP ) + { + DisplayElmPtr elm; + PixmapPtr pix = (PixmapPtr)pDrawable; + PsPixmapPrivPtr priv = (PsPixmapPrivPtr)pix->devPrivate.ptr; + DisplayListPtr disp; + GCPtr gc; + + if ((gc = PsCreateAndCopyGC(pDrawable, pGC)) == NULL) return; + + disp = PsGetFreeDisplayBlock(priv); + + elm = &disp->elms[disp->nelms]; + elm->type = PolyPointCmd; + elm->gc = gc; + elm->c.polyPts.mode = mode; + elm->c.polyPts.nPoints = nPoints; + elm->c.polyPts.pPoints = (xPoint *)xalloc(nPoints*sizeof(xPoint)); + memcpy(elm->c.polyPts.pPoints, pPoints, nPoints*sizeof(xPoint)); + disp->nelms += 1; + } + else + { + int i; + PsOutPtr psOut; + PsPointPtr pts; + ColormapPtr cMap; + + if( PsUpdateDrawableGC(pGC, pDrawable, &psOut, &cMap)==FALSE ) return; + PsOut_Offset(psOut, pDrawable->x, pDrawable->y); + PsOut_Color(psOut, PsGetPixelColor(cMap, pGC->fgPixel)); + pts = (PsPointPtr)xalloc(sizeof(PsPointRec)*nPoints); + if( mode==CoordModeOrigin ) + { + for( i=0 ; i<nPoints ; i++ ) + { pts[i].x = pPoints[i].x; pts[i].y = pPoints[i].y; } + } + else + { + pts[0].x = pPoints[0].x; pts[0].y = pPoints[0].y; + for( i=1 ; i<nPoints ; i++ ) + { + pts[i].x = pts[i-1].x+pPoints[i].x; + pts[i].y = pts[i-1].y+pPoints[i].y; + } + } + PsOut_Points(psOut, nPoints, pts); + xfree(pts); + } +} + +void +PsPushPixels( + GCPtr pGC, + PixmapPtr pBitmap, + DrawablePtr pDrawable, + int width, + int height, + int x, + int y) +{ +} diff --git a/Xprint/ps/PsPixmap.c b/Xprint/ps/PsPixmap.c new file mode 100644 index 000000000..2c3e43245 --- /dev/null +++ b/Xprint/ps/PsPixmap.c @@ -0,0 +1,597 @@ +/* $Xorg: PsPixmap.c,v 1.4 2001/02/09 02:04:36 xorgcvs Exp $ */ +/* + +Copyright 1996, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ +/* + * (c) Copyright 1996 Hewlett-Packard Company + * (c) Copyright 1996 International Business Machines Corp. + * (c) Copyright 1996 Sun Microsystems, Inc. + * (c) Copyright 1996 Novell, Inc. + * (c) Copyright 1996 Digital Equipment Corp. + * (c) Copyright 1996 Fujitsu Limited + * (c) Copyright 1996 Hitachi, Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the names of the copyright holders + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in this Software without prior written authorization + * from said copyright holders. + */ + +/******************************************************************* +** +** ********************************************************* +** * +** * File: PsPixmap.c +** * +** * Contents: Pixmap functions for the PS DDX driver +** * +** * Created By: Roger Helmendach (Liberty Systems) +** * +** * Copyright: Copyright 1995 The Open Group, Inc. +** * +** ********************************************************* +** +********************************************************************/ + +#include "windowstr.h" +#include "gcstruct.h" + +#include "Ps.h" + +#define BitsPerPixel(d) (\ + (1 << PixmapWidthPaddingInfo[d].padBytesLog2) * 8 / \ + (PixmapWidthPaddingInfo[d].padRoundUp+1)) + +PixmapPtr +PsCreatePixmap( + ScreenPtr pScreen, + int width, + int height, + int depth) +{ + PixmapPtr pPixmap; + + pPixmap = (PixmapPtr)xalloc(sizeof(PixmapRec)); + if( !pPixmap) return NullPixmap; + pPixmap->drawable.type = DRAWABLE_PIXMAP; + pPixmap->drawable.class = 0; + pPixmap->drawable.pScreen = pScreen; + pPixmap->drawable.depth = depth; + pPixmap->drawable.bitsPerPixel = BitsPerPixel(depth); + pPixmap->drawable.id = 0; + pPixmap->drawable.serialNumber = NEXT_SERIAL_NUMBER; + pPixmap->drawable.x = 0; + pPixmap->drawable.y = 0; + pPixmap->drawable.width = width; + pPixmap->drawable.height = height; + pPixmap->devKind = 0; + pPixmap->refcnt = 1; + + pPixmap->devPrivate.ptr = (PsPixmapPrivPtr)xalloc(sizeof(PsPixmapPrivRec)); + if( !pPixmap->devPrivate.ptr ) + { xfree(pPixmap); return NullPixmap; } + memset(pPixmap->devPrivate.ptr, 0, sizeof(PsPixmapPrivRec)); + return pPixmap; +} + +Bool +PsDestroyPixmap(PixmapPtr pPixmap) +{ + PsPixmapPrivPtr priv = (PsPixmapPrivPtr)pPixmap->devPrivate.ptr; + DisplayListPtr disp = priv->dispList; + + if( --pPixmap->refcnt ) return TRUE; + while( disp ) + { + int i; + DisplayListPtr oldDisp = disp; + disp = disp->next; + for( i=0 ; i<oldDisp->nelms ; i++ ) + { + DisplayElmPtr elm = &oldDisp->elms[i]; + + switch(elm->type) + { + case PolyPointCmd: + case PolyLineCmd: + if( elm->c.polyPts.pPoints ) xfree(elm->c.polyPts.pPoints); + break; + case PolySegmentCmd: + if( elm->c.segments.pSegments ) xfree(elm->c.segments.pSegments); + break; + case PolyRectangleCmd: + if( elm->c.rects.pRects ) xfree(elm->c.rects.pRects); + break; + case FillPolygonCmd: + if( elm->c.polyPts.pPoints ) xfree(elm->c.polyPts.pPoints); + break; + case PolyFillRectCmd: + if( elm->c.rects.pRects ) xfree(elm->c.rects.pRects); + break; + case PolyArcCmd: + if( elm->c.arcs.pArcs ) xfree(elm->c.arcs.pArcs); + break; + case PolyFillArcCmd: + if( elm->c.arcs.pArcs ) xfree(elm->c.arcs.pArcs); + break; + case Text8Cmd: + case TextI8Cmd: + if( elm->c.text8.string ) xfree(elm->c.text8.string); + break; + case Text16Cmd: + case TextI16Cmd: + if( elm->c.text16.string ) xfree(elm->c.text16.string); + break; + case PutImageCmd: + if( elm->c.image.pData ) xfree(elm->c.image.pData); + break; + case BeginFrameCmd: + break; + case EndFrameCmd: + break; + } + + if (elm->type != BeginFrameCmd && elm->type != EndFrameCmd) { + (void) FreeGC(elm->gc, (GContext) 0); + } + } + xfree(oldDisp); + } + xfree(priv); + xfree(pPixmap); + return TRUE; +} + +DisplayListPtr +PsGetFreeDisplayBlock(PsPixmapPrivPtr priv) +{ + DisplayListPtr disp = priv->dispList; + + for(; disp ; disp=disp->next ) + { + if( disp->nelms>=DPY_BLOCKSIZE && disp->next ) continue; + if( disp->nelms<DPY_BLOCKSIZE ) return(disp); + disp->next = (DisplayListPtr)xalloc(sizeof(DisplayListRec)); + disp->next->next = (DisplayListPtr)0; + disp->next->nelms = 0; + } + disp = (DisplayListPtr)xalloc(sizeof(DisplayListRec)); + disp->next = (DisplayListPtr)0; + disp->nelms = 0; + priv->dispList = disp; + return(disp); +} + +void +PsReplay(DisplayElmPtr elm, DrawablePtr pDrawable) +{ + switch(elm->type) + { + case PolyPointCmd: + PsPolyPoint(pDrawable, elm->gc, elm->c.polyPts.mode, + elm->c.polyPts.nPoints, elm->c.polyPts.pPoints); + break; + case PolyLineCmd: + PsPolyLine(pDrawable, elm->gc, elm->c.polyPts.mode, + elm->c.polyPts.nPoints, elm->c.polyPts.pPoints); + break; + case PolySegmentCmd: + PsPolySegment(pDrawable, elm->gc, elm->c.segments.nSegments, + elm->c.segments.pSegments); + break; + case PolyRectangleCmd: + PsPolyRectangle(pDrawable, elm->gc, elm->c.rects.nRects, + elm->c.rects.pRects); + break; + case FillPolygonCmd: + PsFillPolygon(pDrawable, elm->gc, 0, elm->c.polyPts.mode, + elm->c.polyPts.nPoints, elm->c.polyPts.pPoints); + break; + case PolyFillRectCmd: + PsPolyFillRect(pDrawable, elm->gc, elm->c.rects.nRects, + elm->c.rects.pRects); + break; + case PolyArcCmd: + PsPolyArc(pDrawable, elm->gc, elm->c.arcs.nArcs, elm->c.arcs.pArcs); + break; + case PolyFillArcCmd: + PsPolyFillArc(pDrawable, elm->gc, elm->c.arcs.nArcs, elm->c.arcs.pArcs); + break; + case Text8Cmd: + PsPolyText8(pDrawable, elm->gc, elm->c.text8.x, elm->c.text8.y, + elm->c.text8.count, elm->c.text8.string); + break; + case Text16Cmd: + PsPolyText16(pDrawable, elm->gc, elm->c.text16.x, elm->c.text16.y, + elm->c.text16.count, elm->c.text16.string); + break; + case TextI8Cmd: + PsImageText8(pDrawable, elm->gc, elm->c.text8.x, elm->c.text8.y, + elm->c.text8.count, elm->c.text8.string); + break; + case TextI16Cmd: + PsImageText16(pDrawable, elm->gc, elm->c.text16.x, elm->c.text16.y, + elm->c.text16.count, elm->c.text16.string); + break; + case PutImageCmd: + PsPutScaledImage(pDrawable, elm->gc, elm->c.image.depth, + elm->c.image.x, elm->c.image.y, + elm->c.image.w, elm->c.image.h, elm->c.image.leftPad, + elm->c.image.format, elm->c.image.res, + elm->c.image.pData); + break; + case BeginFrameCmd: + { + PsOutPtr psOut; + ColormapPtr cMap; + if( PsUpdateDrawableGC(NULL, pDrawable, &psOut, &cMap)==FALSE ) return; + PsOut_BeginFrame(psOut, 0, 0, elm->c.frame.x, elm->c.frame.y, + elm->c.frame.w, elm->c.frame.h); + } + break; + case EndFrameCmd: + { + PsOutPtr psOut; + ColormapPtr cMap; + if( PsUpdateDrawableGC(NULL, pDrawable, &psOut, &cMap)==FALSE ) return; + PsOut_EndFrame(psOut); + } + break; + } +} + +void +PsReplayPixmap(PixmapPtr pix, DrawablePtr pDrawable) +{ + PsPixmapPrivPtr priv = (PsPixmapPrivPtr)pix->devPrivate.ptr; + DisplayListPtr disp = priv->dispList; + DisplayElmPtr elm; + + for(; disp ; disp=disp->next ) + { + int i; + for( i=0,elm=disp->elms ; i<disp->nelms ; i++,elm++ ) + PsReplay(elm, pDrawable); + } +} + +int +PsCloneDisplayElm(PixmapPtr dst, DisplayElmPtr elm, DisplayElmPtr newElm, + int xoff, int yoff) +{ + int i; + int size; + int status = 0; + + *newElm = *elm; + + /* I think this is the correct return value */ + if ((newElm->gc = PsCreateAndCopyGC(&dst->drawable, elm->gc)) == NULL) { + return 1; + } + + switch(elm->type) + { + case PolyPointCmd: + case PolyLineCmd: + newElm->c.polyPts.pPoints = + (xPoint *)xalloc(elm->c.polyPts.nPoints*sizeof(xPoint)); + for( i=0 ; i<elm->c.polyPts.nPoints ; i++ ) + { + newElm->c.polyPts.pPoints[i].x = elm->c.polyPts.pPoints[i].x+xoff; + newElm->c.polyPts.pPoints[i].y = elm->c.polyPts.pPoints[i].y+yoff; + } + break; + case PolySegmentCmd: + newElm->c.segments.pSegments = + (xSegment *)xalloc(elm->c.segments.nSegments*sizeof(xSegment)); + for( i=0 ; i<elm->c.segments.nSegments ; i++ ) + { + newElm->c.segments.pSegments[i].x1 = + elm->c.segments.pSegments[i].x1+xoff; + newElm->c.segments.pSegments[i].y1 = + elm->c.segments.pSegments[i].y1+yoff; + newElm->c.segments.pSegments[i].x2 = + elm->c.segments.pSegments[i].x2+xoff; + newElm->c.segments.pSegments[i].y2 = + elm->c.segments.pSegments[i].y2+yoff; + } + break; + case PolyRectangleCmd: + newElm->c.rects.pRects = + (xRectangle *)xalloc(elm->c.rects.nRects*sizeof(xRectangle)); + for( i=0 ; i<elm->c.rects.nRects ; i++ ) + { + newElm->c.rects.pRects[i].x = elm->c.rects.pRects[i].x+xoff; + newElm->c.rects.pRects[i].y = elm->c.rects.pRects[i].y+yoff; + newElm->c.rects.pRects[i].width = elm->c.rects.pRects[i].width; + newElm->c.rects.pRects[i].height = elm->c.rects.pRects[i].height; + } + break; + case FillPolygonCmd: + newElm->c.polyPts.pPoints = + (xPoint *)xalloc(elm->c.polyPts.nPoints*sizeof(xPoint)); + for( i=0 ; i<elm->c.polyPts.nPoints ; i++ ) + { + newElm->c.polyPts.pPoints[i].x = elm->c.polyPts.pPoints[i].x+xoff; + newElm->c.polyPts.pPoints[i].y = elm->c.polyPts.pPoints[i].y+yoff; + } + break; + case PolyFillRectCmd: + newElm->c.rects.pRects = + (xRectangle *)xalloc(elm->c.rects.nRects*sizeof(xRectangle)); + for( i=0 ; i<elm->c.rects.nRects ; i++ ) + { + newElm->c.rects.pRects[i].x = elm->c.rects.pRects[i].x+xoff; + newElm->c.rects.pRects[i].y = elm->c.rects.pRects[i].y+yoff; + newElm->c.rects.pRects[i].width = elm->c.rects.pRects[i].width; + newElm->c.rects.pRects[i].height = elm->c.rects.pRects[i].height; + } + break; + case PolyArcCmd: + newElm->c.arcs.pArcs = + (xArc *)xalloc(elm->c.arcs.nArcs*sizeof(xArc)); + for( i=0 ; i<elm->c.arcs.nArcs ; i++ ) + { + newElm->c.arcs.pArcs[i].x = elm->c.arcs.pArcs[i].x+xoff; + newElm->c.arcs.pArcs[i].y = elm->c.arcs.pArcs[i].y+yoff; + newElm->c.arcs.pArcs[i].width = elm->c.arcs.pArcs[i].width; + newElm->c.arcs.pArcs[i].height = elm->c.arcs.pArcs[i].height; + newElm->c.arcs.pArcs[i].angle1 = elm->c.arcs.pArcs[i].angle1; + newElm->c.arcs.pArcs[i].angle2 = elm->c.arcs.pArcs[i].angle2; + } + break; + case PolyFillArcCmd: + newElm->c.arcs.pArcs = + (xArc *)xalloc(elm->c.arcs.nArcs*sizeof(xArc)); + for( i=0 ; i<elm->c.arcs.nArcs ; i++ ) + { + newElm->c.arcs.pArcs[i].x = elm->c.arcs.pArcs[i].x+xoff; + newElm->c.arcs.pArcs[i].y = elm->c.arcs.pArcs[i].y+yoff; + newElm->c.arcs.pArcs[i].width = elm->c.arcs.pArcs[i].width; + newElm->c.arcs.pArcs[i].height = elm->c.arcs.pArcs[i].height; + newElm->c.arcs.pArcs[i].angle1 = elm->c.arcs.pArcs[i].angle1; + newElm->c.arcs.pArcs[i].angle2 = elm->c.arcs.pArcs[i].angle2; + } + break; + case Text8Cmd: + case TextI8Cmd: + newElm->c.text8.string = (char *)xalloc(elm->c.text8.count); + memcpy(newElm->c.text8.string, elm->c.text8.string, elm->c.text8.count); + newElm->c.text8.x += xoff; + newElm->c.text8.y += yoff; + break; + case Text16Cmd: + case TextI16Cmd: + newElm->c.text16.string = + (unsigned short *)xalloc(elm->c.text16.count*sizeof(unsigned short)); + memcpy(newElm->c.text16.string, elm->c.text16.string, + elm->c.text16.count*sizeof(unsigned short)); + newElm->c.text16.x += xoff; + newElm->c.text16.y += yoff; + break; + case PutImageCmd: + size = PixmapBytePad(elm->c.image.w, elm->c.image.depth)*elm->c.image.h; + newElm->c.image.pData = (char *)xalloc(size); + memcpy(newElm->c.image.pData, elm->c.image.pData, size); + newElm->c.image.x += xoff; + newElm->c.image.y += yoff; + break; + case BeginFrameCmd: + case EndFrameCmd: + status = 1; + break; + } + return(status); +} + +void +PsCopyDisplayList(PixmapPtr src, PixmapPtr dst, int xoff, int yoff, + int x, int y, int w, int h) +{ + PsPixmapPrivPtr sPriv = (PsPixmapPrivPtr)src->devPrivate.ptr; + PsPixmapPrivPtr dPriv = (PsPixmapPrivPtr)dst->devPrivate.ptr; + DisplayListPtr sDisp; + DisplayListPtr dDisp = PsGetFreeDisplayBlock(dPriv); + DisplayElmPtr elm = &dDisp->elms[dDisp->nelms]; + + elm->type = BeginFrameCmd; + elm->c.frame.x = x; + elm->c.frame.y = y; + elm->c.frame.w = w; + elm->c.frame.h = h; + dDisp->nelms += 1; + + sDisp = sPriv->dispList; + for(; sDisp ; sDisp=sDisp->next ) + { + int i; + for( i=0,elm=sDisp->elms ; i<sDisp->nelms ; i++,elm++ ) + { + dDisp = PsGetFreeDisplayBlock(dPriv); + if (PsCloneDisplayElm(dst, elm, &dDisp->elms[dDisp->nelms], + xoff, yoff)==0) + { + dDisp->nelms += 1; + } + } + } + + dDisp = PsGetFreeDisplayBlock(dPriv); + elm = &dDisp->elms[dDisp->nelms]; + elm->type = EndFrameCmd; + dDisp->nelms += 1; +} + +PsElmPtr +PsCreateFillElementList(PixmapPtr pix, int *nElms) +{ + PsElmPtr elms = (PsElmPtr)0; + PsPixmapPrivPtr priv = (PsPixmapPrivPtr)pix->devPrivate.ptr; + DisplayListPtr disp = priv->dispList; + PsArcEnum styl; + + *nElms = 0; + for(; disp ; disp=disp->next ) + { + int i; + DisplayElmPtr elm = disp->elms; + + for( i=0 ; i<disp->nelms ; i++,elm++ ) + { + if( !elm->gc->fgPixel ) continue; + switch(elm->type) + { + case FillPolygonCmd: + *nElms += 1; + break; + case PolyFillRectCmd: + *nElms += elm->c.rects.nRects; + break; + case PolyFillArcCmd: + *nElms += elm->c.arcs.nArcs; + break; + } + } + } + + if( (*nElms) ) + { + elms = (PsElmPtr)xalloc((*nElms)*sizeof(PsElmRec)); + if( elms ) + { + disp = priv->dispList; + *nElms = 0; + for(; disp ; disp=disp->next ) + { + int i, k; + DisplayElmPtr elm = disp->elms; + + for( i=0 ; i<disp->nelms ; i++,elm++ ) + { + if( !elm->gc->fgPixel ) continue; + switch(elm->type) + { + case FillPolygonCmd: + elms[*nElms].type = PSOUT_POINTS; + elms[*nElms].nPoints = elm->c.polyPts.nPoints; + elms[*nElms].c.points = + (PsPointPtr)xalloc(elms[*nElms].nPoints*sizeof(PsPointRec)); + for( k=0 ; k<elms[*nElms].nPoints ; k++ ) + { + elms[*nElms].c.points[k].x = elm->c.polyPts.pPoints[k].x; + elms[*nElms].c.points[k].y = elm->c.polyPts.pPoints[k].y; + } + *nElms += 1; + break; + case PolyFillRectCmd: + for( k=0 ; k<elm->c.rects.nRects ; k++ ) + { + elms[*nElms].type = PSOUT_RECT; + elms[*nElms].nPoints = 0; + elms[*nElms].c.rect.x = elm->c.rects.pRects[k].x; + elms[*nElms].c.rect.y = elm->c.rects.pRects[k].y; + elms[*nElms].c.rect.w = elm->c.rects.pRects[k].width; + elms[*nElms].c.rect.h = elm->c.rects.pRects[k].height; + *nElms += 1; + } + break; + case PolyFillArcCmd: + if( elm->gc->arcMode==ArcChord ) styl = PsChord; + else styl = PsPieSlice; + for( k=0 ; k<elm->c.rects.nRects ; k++ ) + { + elms[*nElms].type = PSOUT_ARC; + elms[*nElms].nPoints = 0; + elms[*nElms].c.arc.x = elm->c.arcs.pArcs[k].x; + elms[*nElms].c.arc.y = elm->c.arcs.pArcs[k].y; + elms[*nElms].c.arc.w = elm->c.arcs.pArcs[k].width; + elms[*nElms].c.arc.h = elm->c.arcs.pArcs[k].height; + elms[*nElms].c.arc.a1 = elm->c.arcs.pArcs[k].angle1; + elms[*nElms].c.arc.a2 = elm->c.arcs.pArcs[k].angle2; + elms[*nElms].c.arc.style = styl; + *nElms += 1; + } + break; + } + } + } + } + } + return(elms); +} + +PsElmPtr +PsCloneFillElementList(int nElms, PsElmPtr elms) +{ + int i; + PsElmPtr newElms; + + newElms = (PsElmPtr)xalloc(nElms*sizeof(PsElmRec)); + if( !newElms ) return(newElms); + for( i=0 ; i<nElms ; i++ ) + { + newElms[i] = elms[i]; + + if( elms[i].type==PSOUT_POINTS ) + { + newElms[i].c.points = + (PsPointPtr)xalloc(elms[i].nPoints*sizeof(PsElmRec)); + memcpy(newElms[i].c.points, elms[i].c.points, + elms[i].nPoints*sizeof(PsPointRec)); + } + } + return(newElms); +} + +void +PsDestroyFillElementList(int nElms, PsElmPtr elms) +{ + int i; + + for( i=0 ; i<nElms ; i++ ) + { if( elms[i].type==PSOUT_POINTS ) xfree(elms[i].c.points); } + + xfree(elms); +} diff --git a/Xprint/ps/PsPolygon.c b/Xprint/ps/PsPolygon.c new file mode 100644 index 000000000..e1f0b9003 --- /dev/null +++ b/Xprint/ps/PsPolygon.c @@ -0,0 +1,232 @@ +/* $Xorg: PsPolygon.c,v 1.4 2001/02/09 02:04:36 xorgcvs Exp $ */ +/* + +Copyright 1996, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ +/* + * (c) Copyright 1996 Hewlett-Packard Company + * (c) Copyright 1996 International Business Machines Corp. + * (c) Copyright 1996 Sun Microsystems, Inc. + * (c) Copyright 1996 Novell, Inc. + * (c) Copyright 1996 Digital Equipment Corp. + * (c) Copyright 1996 Fujitsu Limited + * (c) Copyright 1996 Hitachi, Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the names of the copyright holders + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in this Software without prior written authorization + * from said copyright holders. + */ + +/******************************************************************* +** +** ********************************************************* +** * +** * File: PsPolygon.c +** * +** * Contents: Draws Polygons and Rectangles for the PS DDX +** * +** * Created By: Roger Helmendach (Liberty Systems) +** * +** * Copyright: Copyright 1996 The Open Group, Inc. +** * +** ********************************************************* +** +********************************************************************/ + +#include "Ps.h" +#include "gcstruct.h" +#include "windowstr.h" + +void +PsPolyRectangle( + DrawablePtr pDrawable, + GCPtr pGC, + int nRects, + xRectangle *pRects) +{ + if( pDrawable->type==DRAWABLE_PIXMAP ) + { + DisplayElmPtr elm; + PixmapPtr pix = (PixmapPtr)pDrawable; + PsPixmapPrivPtr priv = (PsPixmapPrivPtr)pix->devPrivate.ptr; + DisplayListPtr disp; + GCPtr gc; + + if ((gc = PsCreateAndCopyGC(pDrawable, pGC)) == NULL) return; + + disp = PsGetFreeDisplayBlock(priv); + + elm = &disp->elms[disp->nelms]; + elm->type = PolyRectangleCmd; + elm->gc = gc; + elm->c.rects.nRects = nRects; + elm->c.rects.pRects = (xRectangle *)xalloc(nRects*sizeof(xRectangle)); + memcpy(elm->c.rects.pRects, pRects, nRects*sizeof(xRectangle)); + disp->nelms += 1; + } + else + { + int i; + PsOutPtr psOut; + ColormapPtr cMap; + + if( PsUpdateDrawableGC(pGC, pDrawable, &psOut, &cMap)==FALSE ) return; + PsOut_Offset(psOut, pDrawable->x, pDrawable->y); + PsOut_Color(psOut, PsGetPixelColor(cMap, pGC->fgPixel)); + PsLineAttrs(psOut, pGC, cMap); + for( i=0 ; i<nRects ; i++ ) + { + PsOut_DrawRect(psOut, (int)pRects[i].x, (int)pRects[i].y, + (int)pRects[i].width, (int)pRects[i].height); + } + } +} + +void +PsFillPolygon( + DrawablePtr pDrawable, + GCPtr pGC, + int shape, + int mode, + int nPoints, + DDXPointPtr pPoints) +{ + if( pDrawable->type==DRAWABLE_PIXMAP ) + { + DisplayElmPtr elm; + PixmapPtr pix = (PixmapPtr)pDrawable; + PsPixmapPrivPtr priv = (PsPixmapPrivPtr)pix->devPrivate.ptr; + DisplayListPtr disp; + GCPtr gc; + + if ((gc = PsCreateAndCopyGC(pDrawable, pGC)) == NULL) return; + + disp = PsGetFreeDisplayBlock(priv); + + elm = &disp->elms[disp->nelms]; + elm->type = FillPolygonCmd; + elm->gc = gc; + elm->c.polyPts.mode = mode; + elm->c.polyPts.nPoints = nPoints; + elm->c.polyPts.pPoints = (xPoint *)xalloc(nPoints*sizeof(xPoint)); + memcpy(elm->c.polyPts.pPoints, pPoints, nPoints*sizeof(xPoint)); + disp->nelms += 1; + } + else + { + int i; + PsOutPtr psOut; + PsPointPtr pts; + PsRuleEnum rule; + ColormapPtr cMap; + + if( PsUpdateDrawableGC(pGC, pDrawable, &psOut, &cMap)==FALSE ) return; + PsOut_Offset(psOut, pDrawable->x, pDrawable->y); + PsSetFillColor(pDrawable, pGC, psOut, cMap); + if( pGC->fillRule==EvenOddRule ) rule = PsEvenOdd; + else rule = PsNZWinding; + PsOut_FillRule(psOut, rule); + pts = (PsPointPtr)xalloc(sizeof(PsPointRec)*nPoints); + if( mode==CoordModeOrigin ) + { + for( i=0 ; i<nPoints ; i++ ) + { pts[i].x = pPoints[i].x; pts[i].y = pPoints[i].y; } + } + else + { + pts[0].x = pPoints[i].x; pts[0].y = pPoints[i].y; + for( i=1 ; i<nPoints ; i++ ) + { + pts[i].x = pts[i-1].x+pPoints[i].x; + pts[i].y = pts[i-1].y+pPoints[i].y; + } + } + PsOut_Polygon(psOut, nPoints, pts); + xfree(pts); + } +} + +void +PsPolyFillRect( + DrawablePtr pDrawable, + GCPtr pGC, + int nRects, + xRectangle *pRects) +{ + if( pDrawable->type==DRAWABLE_PIXMAP ) + { + DisplayElmPtr elm; + PixmapPtr pix = (PixmapPtr)pDrawable; + PsPixmapPrivPtr priv = (PsPixmapPrivPtr)pix->devPrivate.ptr; + DisplayListPtr disp; + GCPtr gc; + + if ((gc = PsCreateAndCopyGC(pDrawable, pGC)) == NULL) return; + + disp = PsGetFreeDisplayBlock(priv); + + elm = &disp->elms[disp->nelms]; + elm->type = PolyFillRectCmd; + elm->gc = gc; + elm->c.rects.nRects = nRects; + elm->c.rects.pRects = (xRectangle *)xalloc(nRects*sizeof(xRectangle)); + memcpy(elm->c.rects.pRects, pRects, nRects*sizeof(xRectangle)); + disp->nelms += 1; + } + else + { + int i; + PsOutPtr psOut; + ColormapPtr cMap; + + if( PsUpdateDrawableGC(pGC, pDrawable, &psOut, &cMap)==FALSE ) return; + PsOut_Offset(psOut, pDrawable->x, pDrawable->y); + PsSetFillColor(pDrawable, pGC, psOut, cMap); + for( i=0 ; i<nRects ; i++ ) + { + PsOut_FillRect(psOut, (int)pRects[i].x, (int)pRects[i].y, + (int)pRects[i].width, (int)pRects[i].height); + } + } +} diff --git a/Xprint/ps/PsPrint.c b/Xprint/ps/PsPrint.c new file mode 100644 index 000000000..49ed97583 --- /dev/null +++ b/Xprint/ps/PsPrint.c @@ -0,0 +1,434 @@ +/* $Xorg: PsPrint.c,v 1.7 2001/03/14 18:28:18 pookie Exp $ */ +/* + +Copyright 1996, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ +/* + * (c) Copyright 1996 Hewlett-Packard Company + * (c) Copyright 1996 International Business Machines Corp. + * (c) Copyright 1996, 2000 Sun Microsystems, Inc. All rights reserved. + * (c) Copyright 1996 Novell, Inc. + * (c) Copyright 1996 Digital Equipment Corp. + * (c) Copyright 1996 Fujitsu Limited + * (c) Copyright 1996 Hitachi, Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the names of the copyright holders + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in this Software without prior written authorization + * from said copyright holders. + */ + +/******************************************************************* +** +** ********************************************************* +** * +** * File: PsPrint.c +** * +** * Contents: Print extension code of Ps driver +** * +** * Created By: Roger Helmendach (Liberty Systems) +** * +** * Copyright: Copyright 1996 The Open Group, Inc. +** * +** ********************************************************* +** +********************************************************************/ + +#include <stdio.h> +#include <string.h> +#include <sys/types.h> +#include <sys/stat.h> +#include <sys/wait.h> +#include <unistd.h> +#include <errno.h> +#include <X11/Xprotostr.h> + +#define NEED_EVENTS +#include "Xproto.h" +#undef NEED_EVENTS + +#include "Ps.h" + +#include "windowstr.h" +#include "attributes.h" +#include "Oid.h" + +/* static utility function to get document/page attributes */ +static void +S_GetPageAttributes(XpContextPtr pCon,int *iorient,int *icount, int *iplex, + int *ires, unsigned short *iwd, unsigned short *iht) +{ + char *count; + XpOid orient, plex; + /* + * Get the orientation + */ + orient = XpGetContentOrientation(pCon); + switch (orient) { + case xpoid_val_content_orientation_landscape: + *iorient = 1; + break; + case xpoid_val_content_orientation_reverse_portrait: + *iorient = 2; + break; + case xpoid_val_content_orientation_reverse_landscape: + *iorient = 3; + break; + case xpoid_val_content_orientation_portrait: + default: + *iorient = 0; + break; + } + + /* + * Get the count + */ + count = XpGetOneAttribute(pCon, XPDocAttr, "copy-count"); + if( count ) + { + int ii = sscanf(count, "%d", icount); + if( ii!=1 ) *icount = 1; + } + else *icount = 1; + + /* + * Get the plex + */ + plex = XpGetPlex(pCon); + switch(plex) + { + case xpoid_val_plex_duplex: + *iplex = 1; + break; + case xpoid_val_plex_tumble: + *iplex = 2; + break; + default: + *iplex = 0; + break; + } + + /* + * Get the resolution and media size + */ + *ires = XpGetResolution(pCon); + XpGetMediumDimensions(pCon, iwd, iht); +} + + +int +PsStartJob( + XpContextPtr pCon, + Bool sendClientData, + ClientPtr client) +{ + PsContextPrivPtr pConPriv = + (PsContextPrivPtr)pCon->devPrivates[PsContextPrivateIndex].ptr; + + /* + * Create a temporary file to store the printer output. + */ + if (!XpOpenTmpFile("w", &pConPriv->jobFileName, &pConPriv->pJobFile)) + return BadAlloc; + + return Success; +} + + + +/* I thought about making this following code into a set of routines + or using a goto, or something, but in the end decided not to, + because the plain old listing here makes the logic clearer. */ +int +PsEndJob( + XpContextPtr pCon, + Bool cancel) +{ + int r; + struct stat buffer; + int error; + + PsContextPrivPtr priv = + (PsContextPrivPtr)pCon->devPrivates[PsContextPrivateIndex].ptr; + + if (cancel == True) { + if (priv->getDocClient != (ClientPtr) NULL) { + (void) XpFinishDocData( priv->getDocClient ); + + priv->getDocClient = NULL; + priv->getDocBufSize = 0; + } + + /* job is cancelled - do we really care if we're out of space? */ + (void) fclose(priv->pJobFile); + priv->pJobFile = NULL; + + unlink(priv->jobFileName); + xfree(priv->jobFileName); + priv->jobFileName = (char *)NULL; + + return Success; + } + + /* + * Append any trailing information here + */ + PsOut_EndFile(priv->pPsOut, 0); + + /* this is where we find out if we're out of space */ + error = (fclose(priv->pJobFile) == EOF); + priv->pJobFile = NULL; + + /* status to the client if we have ran out of space on the disk or + some other resource problem with the temporary file... */ + if (error) { + if (priv->getDocClient != (ClientPtr) NULL) { + (void) XpFinishDocData( priv->getDocClient ); + + priv->getDocClient = NULL; + priv->getDocBufSize = 0; + } + + unlink(priv->jobFileName); + xfree(priv->jobFileName); + priv->jobFileName = (char *)NULL; + + return BadAlloc; + } + + /* we have finished without incident & no cancel */ + + if (priv->getDocClient != NULL && priv->getDocBufSize > 0) { + FILE *file; + + file = fopen(priv->jobFileName, "r"); + if (!file || (fstat(fileno(file), &buffer) < 0)) + r = BadAlloc; + else + r = XpSendDocumentData(priv->getDocClient, file, buffer.st_size, + priv->getDocBufSize); + if (file) + fclose(file); + + (void) XpFinishDocData(priv->getDocClient); + + priv->getDocClient = NULL; + priv->getDocBufSize = 0; + } + else { + XpSubmitJob(priv->jobFileName, pCon); + + r = Success; + } + + unlink(priv->jobFileName); + xfree(priv->jobFileName); + priv->jobFileName = (char *)NULL; + +#ifdef BM_CACHE + PsBmClearImageCache(); +#endif + + return r; +} + +/* StartPage + */ +int +PsStartPage( + XpContextPtr pCon, + WindowPtr pWin) +{ + int iorient, iplex, icount, ires; + unsigned short iwd, iht; + register WindowPtr pChild; + PsContextPrivPtr pConPriv = + (PsContextPrivPtr)pCon->devPrivates[PsContextPrivateIndex].ptr; + PsWindowPrivPtr pWinPriv = + (PsWindowPrivPtr)pWin->devPrivates[PsWindowPrivateIndex].ptr; + char s[80]; + xEvent event; + +/* + * Put a pointer to the context in the window private structure + */ + pWinPriv->validContext = 1; + pWinPriv->context = pCon; + + /* get page level attributes */ + S_GetPageAttributes(pCon,&iorient,&icount,&iplex,&ires,&iwd,&iht); + /* + * Start the page + */ + if (pConPriv->pPsOut == NULL) { + pConPriv->pPsOut = PsOut_BeginFile(pConPriv->pJobFile, + iorient, icount, iplex, ires, + (int)iwd, (int)iht, False); + } + PsOut_BeginPage(pConPriv->pPsOut, iorient, icount, iplex, ires, + (int)iwd, (int)iht); + + return Success; +} + + +/* + * EndPage: + * + * Write page trailer to page file + * Write page file to job file + */ +int +PsEndPage( + XpContextPtr pCon, + WindowPtr pWin) +{ + PsWindowPrivPtr pWinPriv = + (PsWindowPrivPtr)pWin->devPrivates[PsWindowPrivateIndex].ptr; + PsContextPrivPtr pConPriv = + (PsContextPrivPtr)pCon->devPrivates[PsContextPrivateIndex].ptr; + + PsOut_EndPage(pConPriv->pPsOut); + + pWinPriv->validContext = 0; + pWinPriv->context = NULL; + + /* status to the client if we have ran out of space on the disk or + some other resource problem with the temporary file... */ +/* if (ferror(pConPriv->pJobFile)) return BadAlloc; */ + + return Success; +} + +/* + * The PsStartDoc() and PsEndDoc() functions serve basically as NOOP + * placeholders. This driver doesn't deal with the notion of multiple + * documents per page. + */ + +int +PsStartDoc(XpContextPtr pCon, XPDocumentType type) +{ + int iorient, iplex, icount, ires; + unsigned short iwd, iht; + PsContextPrivPtr pConPriv = + (PsContextPrivPtr)pCon->devPrivates[PsContextPrivateIndex].ptr; + + /* get document level attributes */ + S_GetPageAttributes(pCon,&iorient,&icount,&iplex,&ires,&iwd,&iht); + + pConPriv->pPsOut = PsOut_BeginFile(pConPriv->pJobFile, + iorient, icount, iplex, ires, + (int)iwd, (int)iht, (type == XPDocRaw)); + + return Success; +} + +int +PsEndDoc( + XpContextPtr pCon, + Bool cancel) +{ + return Success; +} + +/* + * PsDocumentData() + * + * Hand any pre-generated PDL down to the spool files, formatting it + * as necessary to fit the given window. + */ + +int +PsDocumentData( + XpContextPtr pCon, + DrawablePtr pDraw, + char *pData, + int len_data, + char *pFmt, + int len_fmt, + char *pOpt, + int len_opt, + ClientPtr client) +{ + PsContextPrivPtr cPriv; + PsOutPtr psOut; + + if (len_fmt != 12 || !strcmp(pFmt, "PostScript 2") || len_opt) + return BadValue; + cPriv = pCon->devPrivates[PsContextPrivateIndex].ptr; + psOut = cPriv->pPsOut; + + if (pDraw) + PsOut_BeginFrame(psOut, 0, 0, pDraw->x, pDraw->y, + pDraw->width, pDraw->height); + PsOut_RawData(psOut, pData, len_data); + if (pDraw) + PsOut_EndFrame(psOut); + + return Success; +} + +/* + * + * PsGetDocumentData() + * + * This function allows the driver to send the generated PS back to + * the client. + */ + +int +PsGetDocumentData( + XpContextPtr pCon, + ClientPtr client, + int maxBufferSize) +{ + PsContextPrivPtr pPriv = (PsContextPrivPtr) + pCon->devPrivates[PsContextPrivateIndex].ptr; + + pPriv->getDocClient = client; + pPriv->getDocBufSize = maxBufferSize; + + return Success; +} + diff --git a/Xprint/ps/PsSpans.c b/Xprint/ps/PsSpans.c new file mode 100644 index 000000000..4d8fb3459 --- /dev/null +++ b/Xprint/ps/PsSpans.c @@ -0,0 +1,162 @@ +/* $Xorg: PsSpans.c,v 1.4 2001/02/09 02:04:36 xorgcvs Exp $ */ +/* + +Copyright 1996, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ +/* + * (c) Copyright 1996 Hewlett-Packard Company + * (c) Copyright 1996 International Business Machines Corp. + * (c) Copyright 1996 Sun Microsystems, Inc. + * (c) Copyright 1996 Novell, Inc. + * (c) Copyright 1996 Digital Equipment Corp. + * (c) Copyright 1996 Fujitsu Limited + * (c) Copyright 1996 Hitachi, Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the names of the copyright holders + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in this Software without prior written authorization + * from said copyright holders. + */ + +/******************************************************************* +** +** ********************************************************* +** * +** * File: PsSpans.c +** * +** * Contents: Code to set and fill spans in the PS DDX +** * +** * Created By: Roger Helmendach (Liberty Systems) +** * +** * Copyright: Copyright 1996 The Open Group, Inc. +** * +** ********************************************************* +** +********************************************************************/ + +#include "Ps.h" +#include "gcstruct.h" +#include "windowstr.h" + +void +PsFillSpans( + DrawablePtr pDrawable, + GCPtr pGC, + int nSpans, + DDXPointPtr pPoints, + int *pWidths, + int fSorted) +{ + char t[80]; + PsOutPtr psOut; + int xoffset, yoffset; + xRectangle *rects, *r; + RegionPtr fillRegion, region; + int i; + int nbox; + BoxPtr pbox; + ColormapPtr cMap; + + if( PsUpdateDrawableGC(pGC, pDrawable, &psOut, &cMap)==FALSE ) return; + + /* + * Build a region out of the spans + */ + rects = (xRectangle *)xalloc(nSpans*sizeof(xRectangle)); + xoffset = pDrawable->x; + yoffset = pDrawable->y; + + for( i = 0, r = rects; i < nSpans; i++, r++ ) + { + r->x = pPoints[i].x + xoffset; + r->y = pPoints[i].y + yoffset; + r->width = pWidths[i]; + r->height = 1; + } + fillRegion = miRectsToRegion(nSpans, rects, + (fSorted)?CT_YSORTED:CT_UNSORTED); + + /* + * Intersect this region with the clip region. Whatever's left, + * should be filled. + */ +/*miIntersect(region, fillRegion, pGC->clientClip);*/ + + pbox = REGION_RECTS(region); + nbox = REGION_NUM_RECTS(region); + + /* Enter HP-GL/2 */ + /*###SEND_PCL( outFile, "\27%0B" );*/ + + while( nbox ) + { +/*### + sprintf( t, "PU%d,%d;RR%d,%d;", pbox->x1, pbox->y1, pbox->x2, pbox->y2); + SEND_PCL( outFile, t ); +*/ + nbox--; + pbox++; + } + + /* Go back to PCL */ + /*###SEND_PCL( outFile, "\27%0A" );*/ + + /* + * Clean up the temporary regions + */ + miRegionDestroy(fillRegion); + miRegionDestroy(region); + xfree(rects); +} + +void +PsSetSpans( + DrawablePtr pDrawable, + GCPtr pGC, + char *pSrc, + DDXPointPtr pPoints, + int *pWidths, + int nSpans, + int fSorted) +{ +} diff --git a/Xprint/ps/PsText.c b/Xprint/ps/PsText.c new file mode 100644 index 000000000..618d0a163 --- /dev/null +++ b/Xprint/ps/PsText.c @@ -0,0 +1,478 @@ +/* $Xorg: PsText.c,v 1.7 2001/02/09 02:04:36 xorgcvs Exp $ */ +/* + +Copyright 1996, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ +/* + * (c) Copyright 1996 Hewlett-Packard Company + * (c) Copyright 1996 International Business Machines Corp. + * (c) Copyright 1996 Sun Microsystems, Inc. + * (c) Copyright 1996 Novell, Inc. + * (c) Copyright 1996 Digital Equipment Corp. + * (c) Copyright 1996 Fujitsu Limited + * (c) Copyright 1996 Hitachi, Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the names of the copyright holders + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in this Software without prior written authorization + * from said copyright holders. + */ + +/******************************************************************* +** +** ********************************************************* +** * +** * File: PsText.c +** * +** * Contents: Character-drawing routines for the PS DDX +** * +** * Created By: Roger Helmendach (Liberty Systems) +** * +** * Copyright: Copyright 1996 The Open Group, Inc. +** * +** ********************************************************* +** +********************************************************************/ + +#include "Ps.h" +#include "gcstruct.h" +#include "windowstr.h" +#include "fntfil.h" +#include "fntfilst.h" +#include <sys/stat.h> + +static int readFontName(char *fileName, char *file_name, char *dlfnam) +{ + FILE *file; + struct stat statb; + int count, i, status; + char buf[256]; + char *front, *end, *fn; + + file = fopen(fileName, "r"); + if(file) + { + if (fstat (fileno(file), &statb) == -1) + return 0; + while(fgets(buf, 255, file)) + { + if((fn = strstr(buf, " -"))) + { + strcpy(file_name, buf); + file_name[fn - buf - 4] = '\0'; + fn++; + if((front = strstr(fn, "normal-"))) + { + fn[front - fn] = '\0'; + if(strstr(dlfnam, fn)) + { + fclose(file); + return 1; + } + } + } + } + } + file_name[0] = '\0'; + fclose(file); + return 0; +} + +int +PsPolyText8( + DrawablePtr pDrawable, + GCPtr pGC, + int x, + int y, + int count, + char *string) +{ + if( pDrawable->type==DRAWABLE_PIXMAP ) + { + DisplayElmPtr elm; + PixmapPtr pix = (PixmapPtr)pDrawable; + PsPixmapPrivPtr priv = (PsPixmapPrivPtr)pix->devPrivate.ptr; + DisplayListPtr disp; + GCPtr gc; + + if ((gc = PsCreateAndCopyGC(pDrawable, pGC)) == NULL) return x; + + disp = PsGetFreeDisplayBlock(priv); + + elm = &disp->elms[disp->nelms]; + elm->type = Text8Cmd; + elm->gc = gc; + elm->c.text8.x = x; + elm->c.text8.y = y; + elm->c.text8.count = count; + elm->c.text8.string = (char *)xalloc(count); + memcpy(elm->c.text8.string, string, count); + disp->nelms += 1; + } + else + { + char *fnam, ffname[512], *dlfnam; + FontDirectoryPtr dir; + char file_name[MAXFONTNAMELEN]; + + dir = pGC->font->fpe->private; + sprintf(ffname, "%s%s", dir->directory, "fonts.dir"); + + fnam = PsGetPSFontName(pGC->font); + if(!fnam){ + if(!(dlfnam = PsGetFontName(pGC->font))) + return x; + /* If Type1 font, try to download to printer first */ + if(strstr(ffname, "Type1") && readFontName(ffname, file_name, dlfnam)) + { + int iso; + int siz; + float mtx[4]; + PsOutPtr psOut; + ColormapPtr cMap; + + if( PsUpdateDrawableGC(pGC, pDrawable, &psOut, &cMap)==FALSE ) + return x; + sprintf(ffname, "%s%s%s", dir->directory, file_name, ".pfa"); + PsOut_DownloadType1(psOut, file_name, ffname); + PsOut_Offset(psOut, pDrawable->x, pDrawable->y); + PsOut_Color(psOut, PsGetPixelColor(cMap, pGC->fgPixel)); + siz = PsGetFontSize(pGC->font, mtx); + iso = PsIsISOLatin1Encoding(pGC->font); + if( !siz ) PsOut_TextAttrsMtx(psOut, file_name, mtx, 1); + else PsOut_TextAttrs(psOut, file_name, siz, 1); + PsOut_Text(psOut, x, y, string, count, -1); + return x; + } + { + unsigned long n, i; + int w; + CharInfoPtr charinfo[255]; + + GetGlyphs(pGC->font, (unsigned long)count, + (unsigned char *)string, Linear8Bit,&n, charinfo); + w = 0; + for (i=0; i < n; i++) w += charinfo[i]->metrics.characterWidth; + if (n != 0) + PsPolyGlyphBlt(pDrawable, pGC, x, y, n, + charinfo, FONTGLYPHS(pGC->font)); + x += w; + } + }else{ + int iso; + int siz; + float mtx[4]; + PsOutPtr psOut; + ColormapPtr cMap; + + if( PsUpdateDrawableGC(pGC, pDrawable, &psOut, &cMap)==FALSE ) return x; + PsOut_Offset(psOut, pDrawable->x, pDrawable->y); + PsOut_Color(psOut, PsGetPixelColor(cMap, pGC->fgPixel)); + siz = PsGetFontSize(pGC->font, mtx); + iso = PsIsISOLatin1Encoding(pGC->font); + if( !siz ) PsOut_TextAttrsMtx(psOut, fnam, mtx, iso); + else PsOut_TextAttrs(psOut, fnam, siz, iso); + PsOut_Text(psOut, x, y, string, count, -1); + } + } + return x; +} + +int +PsPolyText16( + DrawablePtr pDrawable, + GCPtr pGC, + int x, + int y, + int count, + unsigned short *string) +{ + if( pDrawable->type==DRAWABLE_PIXMAP ) + { + DisplayElmPtr elm; + PixmapPtr pix = (PixmapPtr)pDrawable; + PsPixmapPrivPtr priv = (PsPixmapPrivPtr)pix->devPrivate.ptr; + DisplayListPtr disp; + GCPtr gc; + + if ((gc = PsCreateAndCopyGC(pDrawable, pGC)) == NULL) return x; + + disp = PsGetFreeDisplayBlock(priv); + + elm = &disp->elms[disp->nelms]; + elm->type = Text16Cmd; + elm->gc = gc; + elm->c.text16.x = x; + elm->c.text16.y = y; + elm->c.text16.count = count; + elm->c.text16.string = + (unsigned short *)xalloc(count*sizeof(unsigned short)); + memcpy(elm->c.text16.string, string, count*sizeof(unsigned short)); + disp->nelms += 1; + } + else + { + unsigned long n, i; + int w; + CharInfoPtr charinfo[255]; /* encoding only has 1 byte for count */ + + GetGlyphs(pGC->font, (unsigned long)count, (unsigned char *)string, + (FONTLASTROW(pGC->font) == 0) ? Linear16Bit : TwoD16Bit, + &n, charinfo); + w = 0; + for (i=0; i < n; i++) w += charinfo[i]->metrics.characterWidth; + if (n != 0) + PsPolyGlyphBlt(pDrawable, pGC, x, y, n, charinfo, FONTGLYPHS(pGC->font)); + x += w; + } + return x; +} + +void +PsImageText8( + DrawablePtr pDrawable, + GCPtr pGC, + int x, + int y, + int count, + char *string) +{ + if( pDrawable->type==DRAWABLE_PIXMAP ) + { + DisplayElmPtr elm; + PixmapPtr pix = (PixmapPtr)pDrawable; + PsPixmapPrivPtr priv = (PsPixmapPrivPtr)pix->devPrivate.ptr; + DisplayListPtr disp; + GCPtr gc; + + if ((gc = PsCreateAndCopyGC(pDrawable, pGC)) == NULL) return; + + disp = PsGetFreeDisplayBlock(priv); + + elm = &disp->elms[disp->nelms]; + elm->type = TextI8Cmd; + elm->gc = gc; + elm->c.text8.x = x; + elm->c.text8.y = y; + elm->c.text8.count = count; + elm->c.text8.string = (char *)xalloc(count); + memcpy(elm->c.text8.string, string, count); + disp->nelms += 1; + } + else + { + int iso; + int siz; + float mtx[4]; + char *fnam; + PsOutPtr psOut; + ColormapPtr cMap; + + if( PsUpdateDrawableGC(pGC, pDrawable, &psOut, &cMap)==FALSE ) return; + PsOut_Offset(psOut, pDrawable->x, pDrawable->y); + PsOut_Color(psOut, PsGetPixelColor(cMap, pGC->fgPixel)); + fnam = PsGetPSFontName(pGC->font); + if( !fnam ) fnam = "Times-Roman"; + siz = PsGetFontSize(pGC->font, mtx); + iso = PsIsISOLatin1Encoding(pGC->font); + if( !siz ) PsOut_TextAttrsMtx(psOut, fnam, mtx, iso); + else PsOut_TextAttrs(psOut, fnam, siz, iso); + PsOut_Text(psOut, x, y, string, count, PsGetPixelColor(cMap, pGC->bgPixel)); + } +} + +void +PsImageText16( + DrawablePtr pDrawable, + GCPtr pGC, + int x, + int y, + int count, + unsigned short *string) +{ + if( pDrawable->type==DRAWABLE_PIXMAP ) + { + DisplayElmPtr elm; + PixmapPtr pix = (PixmapPtr)pDrawable; + PsPixmapPrivPtr priv = (PsPixmapPrivPtr)pix->devPrivate.ptr; + DisplayListPtr disp; + GCPtr gc; + + if ((gc = PsCreateAndCopyGC(pDrawable, pGC)) == NULL) return; + + disp = PsGetFreeDisplayBlock(priv); + + elm = &disp->elms[disp->nelms]; + elm->type = TextI16Cmd; + elm->gc = gc; + elm->c.text16.x = x; + elm->c.text16.y = y; + elm->c.text16.count = count; + elm->c.text16.string = + (unsigned short *)xalloc(count*sizeof(unsigned short)); + memcpy(elm->c.text16.string, string, count*sizeof(unsigned short)); + disp->nelms += 1; + } + else + { + int i; + char *str; + if( !count ) return; + str = (char *)xalloc(count); + for( i=0 ; i<count ; i++ ) str[i] = string[i]; + PsImageText8(pDrawable, pGC, x, y, count, str); + free(str); + } +} + +void +PsImageGlyphBlt( + DrawablePtr pDrawable, + GCPtr pGC, + int x, + int y, + unsigned int nGlyphs, + CharInfoPtr *pCharInfo, + pointer pGlyphBase) +{ + /* NOT TO BE IMPLEMENTED */ +} + +void +PsPolyGlyphBlt( + DrawablePtr pDrawable, + GCPtr pGC, + int x, + int y, + unsigned int nGlyphs, + CharInfoPtr *pCharInfo, + pointer pGlyphBase) +{ + int width, height; + PixmapPtr pPixmap; + int nbyLine; /* bytes per line of padded pixmap */ + FontPtr pfont; + GCPtr pGCtmp; + register int i; + register int j; + unsigned char *pbits; /* buffer for PutImage */ + register unsigned char *pb; /* temp pointer into buffer */ + register CharInfoPtr pci; /* currect char info */ + register unsigned char *pglyph; /* pointer bits in glyph */ + int gWidth, gHeight; /* width and height of glyph */ + register int nbyGlyphWidth; /* bytes per scanline of glyph */ + int nbyPadGlyph; /* server padded line of glyph */ + int w, tmpx; + XID gcvals[3]; + + pfont = pGC->font; + width = FONTMAXBOUNDS(pfont,rightSideBearing) - + FONTMINBOUNDS(pfont,leftSideBearing); + height = FONTMAXBOUNDS(pfont,ascent) + + FONTMAXBOUNDS(pfont,descent); + + if ((width == 0) || (height == 0) ) + return; + { + int i; + w = 0; + for (i=0; i < nGlyphs; i++) w += pCharInfo[i]->metrics.characterWidth; + } + pGCtmp = GetScratchGC(1, pDrawable->pScreen); + if (!pGCtmp) + { + (*pDrawable->pScreen->DestroyPixmap)(pPixmap); + return; + } + + gcvals[0] = GXcopy; + gcvals[1] = pGC->fgPixel; + gcvals[2] = pGC->bgPixel; + + DoChangeGC(pGCtmp, GCFunction|GCForeground|GCBackground, gcvals, 0); + + + nbyLine = BitmapBytePad(width); + pbits = (unsigned char *)ALLOCATE_LOCAL(height*nbyLine); + if (!pbits){ + PsDestroyPixmap(pPixmap); + return; + } + tmpx = 0; + while(nGlyphs--) + { + pci = *pCharInfo++; + pglyph = FONTGLYPHBITS(pGlyphBase, pci); + gWidth = GLYPHWIDTHPIXELS(pci); + gHeight = GLYPHHEIGHTPIXELS(pci); + if (gWidth && gHeight) + { + nbyGlyphWidth = GLYPHWIDTHBYTESPADDED(pci); + nbyPadGlyph = BitmapBytePad(gWidth); + + if (nbyGlyphWidth == nbyPadGlyph +#if GLYPHPADBYTES != 4 + && (((int) pglyph) & 3) == 0 +#endif + ) + { + pb = pglyph; + } + else + { + for (i=0, pb = pbits; i<gHeight; i++, pb = pbits+(i*nbyPadGlyph)) + for (j = 0; j < nbyGlyphWidth; j++) + *pb++ = *pglyph++; + pb = pbits; + } + + PsPutImageMask((DrawablePtr)pDrawable, pGCtmp, + 1, x + pci->metrics.leftSideBearing, + y - pci->metrics.ascent, gWidth, gHeight, + 0, XYBitmap, (char *)pb); + x += pci->metrics.characterWidth; + } + } + DEALLOCATE_LOCAL(pbits); + FreeScratchGC(pGCtmp); +} diff --git a/Xprint/ps/PsWindow.c b/Xprint/ps/PsWindow.c new file mode 100644 index 000000000..3a9a7ed2a --- /dev/null +++ b/Xprint/ps/PsWindow.c @@ -0,0 +1,458 @@ +/* $Xorg: PsWindow.c,v 1.4 2001/02/09 02:04:36 xorgcvs Exp $ */ +/* + +Copyright 1996, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ +/* + * (c) Copyright 1996 Hewlett-Packard Company + * (c) Copyright 1996 International Business Machines Corp. + * (c) Copyright 1996 Sun Microsystems, Inc. + * (c) Copyright 1996 Novell, Inc. + * (c) Copyright 1996 Digital Equipment Corp. + * (c) Copyright 1996 Fujitsu Limited + * (c) Copyright 1996 Hitachi, Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the names of the copyright holders + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in this Software without prior written authorization + * from said copyright holders. + */ + +/******************************************************************* +** +** ********************************************************* +** * +** * File: PsWindow.c +** * +** * Contents: Window code for PS driver. +** * +** * Created By: Roger Helmendach (Liberty Systems) +** * +** * Copyright: Copyright 1996 The Open Group, Inc. +** * +** ********************************************************* +** +********************************************************************/ + +#include <stdio.h> +#include <string.h> +#include <sys/wait.h> + +#include "mistruct.h" +#include "regionstr.h" +#include "windowstr.h" +#include "gcstruct.h" + +#include "Ps.h" + +extern WindowPtr *WindowTable; + +/* + * The following list of strings defines the properties which will be + * placed on the screen's root window if the property was defined in + * the start-up configuration resource database. + */ +static char *propStrings[] = { + DT_PRINT_JOB_HEADER, + DT_PRINT_JOB_TRAILER, + DT_PRINT_JOB_COMMAND, + DT_PRINT_JOB_EXEC_COMMAND, + DT_PRINT_JOB_EXEC_OPTIONS, + DT_PRINT_PAGE_HEADER, + DT_PRINT_PAGE_TRAILER, + DT_PRINT_PAGE_COMMAND, + (char *)NULL +}; + + +/* + * PsCreateWindow - watch for the creation of the root window. + * When it's created, register the screen with the print extension, + * and put the default command/header properties on it. + */ +/*ARGSUSED*/ + +Bool +PsCreateWindow(WindowPtr pWin) +{ + PsWindowPrivPtr pPriv; + +#if 0 + Bool status = Success; + ScreenPtr pScreen = pWin->drawable.pScreen; + PsScreenPrivPtr pScreenPriv = (PsScreenPrivPtr) + pScreen->devPrivates[PsScreenPrivateIndex].ptr; + PsWindowPrivPtr pWinPriv = (PsWindowPrivPtr) + pWin->devPrivates[PsWindowPrivateIndex].ptr; + + /* + * Initialize this window's private struct. + */ + pWinPriv->jobFileName = (char *)NULL; + pWinPriv->pJobFile = (FILE *)NULL; + pWinPriv->pageFileName = (char *)NULL; + pWinPriv->pPageFile = (FILE *)NULL; + + if(pWin->parent == (WindowPtr)NULL) /* root window? */ + { + Atom propName; /* type = XA_STRING */ + char *propVal; + int i; + XrmDatabase rmdb = pScreenPriv->resDB; + + /* + * Put the defaults spec'd in the config files in properties on this + * screen's root window. + */ + for(i = 0; propStrings[i] != (char *)NULL; i++) + { + if((propVal = _DtPrintGetPrinterResource(pWin, rmdb, + propStrings[i])) != + (char *)NULL) + { + propName = MakeAtom(propStrings[i], strlen(propStrings[i]), + TRUE); + ChangeWindowProperty(pWin, propName, XA_STRING, 8, + PropModeReplace, strlen(propVal), + (pointer)propVal, FALSE); + xfree(propVal); + } + } + } + + return status; +#endif + + pPriv = (PsWindowPrivPtr)pWin->devPrivates[PsWindowPrivateIndex].ptr; + pPriv->validContext = 0; + + return TRUE; +} + + +/*ARGSUSED*/ +Bool PsMapWindow(WindowPtr pWindow) +{ + return TRUE; +} + +/*ARGSUSED*/ +Bool +PsPositionWindow( + WindowPtr pWin, + int x, + int y) +{ + return TRUE; +} + +/*ARGSUSED*/ +Bool +PsUnmapWindow(WindowPtr pWindow) +{ + return TRUE; +} + +/*ARGSUSED*/ +void +PsCopyWindow( + WindowPtr pWin, + DDXPointRec ptOldOrg, + RegionPtr prgnSrc) +{ +} + +/*ARGSUSED*/ +Bool +PsChangeWindowAttributes( + WindowPtr pWin, + unsigned long mask) +{ + return TRUE; +} + + +void +PsPaintWindow( + WindowPtr pWin, + RegionPtr pRegion, + int what) +{ + int status; + WindowPtr pRoot; + +#define FUNCTION 0 +#define FOREGROUND 1 +#define TILE 2 +#define FILLSTYLE 3 +#define ABSX 4 +#define ABSY 5 +#define CLIPMASK 6 +#define SUBWINDOW 7 +#define COUNT_BITS 8 + + pointer gcval[7]; + pointer newValues [COUNT_BITS]; + + BITS32 gcmask, index, mask; + RegionRec prgnWin; + DDXPointRec oldCorner; + BoxRec box; + WindowPtr pBgWin; + GCPtr pGC; + register int i; + register BoxPtr pbox; + register ScreenPtr pScreen = pWin->drawable.pScreen; + register xRectangle *prect; + int numRects; + + gcmask = 0; + + /* + * We don't want to paint a window that has no place to put the + * PS output. + */ + if( PsGetContextFromWindow(pWin)==(XpContextPtr)NULL ) return; + + if( what==PW_BACKGROUND ) + { + switch(pWin->backgroundState) + { + case None: return; + case ParentRelative: + (*pWin->parent->drawable.pScreen->PaintWindowBackground) + (pWin->parent, pRegion, what); + return; + case BackgroundPixel: + newValues[FOREGROUND] = (pointer)pWin->background.pixel; + newValues[FILLSTYLE] = (pointer)FillSolid; + gcmask |= GCForeground | GCFillStyle; + break; + case BackgroundPixmap: + newValues[TILE] = (pointer)pWin->background.pixmap; + newValues[FILLSTYLE] = (pointer)FillTiled; + gcmask |= GCTile | GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin; + break; + } + } + else + { + if( pWin->borderIsPixel ) + { + newValues[FOREGROUND] = (pointer)pWin->border.pixel; + newValues[FILLSTYLE] = (pointer)FillSolid; + gcmask |= GCForeground | GCFillStyle; + } + else + { + newValues[TILE] = (pointer)pWin->border.pixmap; + newValues[FILLSTYLE] = (pointer)FillTiled; + gcmask |= GCTile | GCFillStyle | GCTileStipXOrigin | GCTileStipYOrigin; + } + } + + prect = (xRectangle *)ALLOCATE_LOCAL(REGION_NUM_RECTS(pRegion) * + sizeof(xRectangle)); + if( !prect ) return; + + newValues[FUNCTION] = (pointer)GXcopy; + gcmask |= GCFunction | GCClipMask; + + i = pScreen->myNum; + pRoot = WindowTable[i]; + + pBgWin = pWin; + if (what == PW_BORDER) + { + while( pBgWin->backgroundState==ParentRelative ) pBgWin = pBgWin->parent; + } + + pGC = GetScratchGC(pWin->drawable.depth, pWin->drawable.pScreen); + if( !pGC ) + { + DEALLOCATE_LOCAL(prect); + return; + } + /* + * mash the clip list so we can paint the border by + * mangling the window in place, pretending it + * spans the entire screen + */ + if( what==PW_BORDER ) + { + prgnWin = pWin->clipList; + oldCorner.x = pWin->drawable.x; + oldCorner.y = pWin->drawable.y; + pWin->drawable.x = pWin->drawable.y = 0; + box.x1 = 0; + box.y1 = 0; + box.x2 = pScreen->width; + box.y2 = pScreen->height; + REGION_INIT(pScreen, &pWin->clipList, &box, 1); + pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER; + newValues[ABSX] = (pointer)(long)pBgWin->drawable.x; + newValues[ABSY] = (pointer)(long)pBgWin->drawable.y; + } + else + { + newValues[ABSX] = (pointer)0; + newValues[ABSY] = (pointer)0; + } + +/* + * XXX Backing store is turned off for the PS driver + + if( pWin->backStorage ) + (*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, GuaranteeVisBack); + */ + + mask = gcmask; + gcmask = 0; + i = 0; + while( mask ) + { + index = lowbit (mask); + mask &= ~index; + switch(index) + { + case GCFunction: + if( (pointer)(long)pGC->alu!=newValues[FUNCTION] ) + { + gcmask |= index; + gcval[i++] = newValues[FUNCTION]; + } + break; + case GCTileStipXOrigin: + if( (pointer)(long)pGC->patOrg.x!=newValues[ABSX] ) + { + gcmask |= index; + gcval[i++] = newValues[ABSX]; + } + break; + case GCTileStipYOrigin: + if( (pointer)(long)pGC->patOrg.y!=newValues[ABSY] ) + { + gcmask |= index; + gcval[i++] = newValues[ABSY]; + } + break; + case GCClipMask: + if( (pointer)pGC->clientClipType!=(pointer)CT_NONE ) + { + gcmask |= index; + gcval[i++] = (pointer)CT_NONE; + } + break; + case GCSubwindowMode: + if( (pointer)pGC->subWindowMode!=newValues[SUBWINDOW] ) + { + gcmask |= index; + gcval[i++] = newValues[SUBWINDOW]; + } + break; + case GCTile: + if( pGC->tileIsPixel || (pointer)pGC->tile.pixmap!=newValues[TILE] ) + { + gcmask |= index; + gcval[i++] = newValues[TILE]; + } + break; + case GCFillStyle: + if( (pointer)pGC->fillStyle!=newValues[FILLSTYLE] ) + { + gcmask |= index; + gcval[i++] = newValues[FILLSTYLE]; + } + break; + case GCForeground: + if( (pointer)pGC->fgPixel!=newValues[FOREGROUND] ) + { + gcmask |= index; + gcval[i++] = newValues[FOREGROUND]; + } + break; + } + } + + if( gcmask ) DoChangeGC(pGC, gcmask, (XID *)gcval, 1); + + if( pWin->drawable.serialNumber!=pGC->serialNumber ) + ValidateGC((DrawablePtr)pWin, pGC); + + numRects = REGION_NUM_RECTS(pRegion); + pbox = REGION_RECTS(pRegion); + for( i=numRects ; --i >= 0 ; pbox++,prect++ ) + { + prect->x = pbox->x1 - pWin->drawable.x; + prect->y = pbox->y1 - pWin->drawable.y; + prect->width = pbox->x2 - pbox->x1; + prect->height = pbox->y2 - pbox->y1; + } + prect -= numRects; + (*pGC->ops->PolyFillRect)((DrawablePtr)pWin, pGC, numRects, prect); + DEALLOCATE_LOCAL(prect); + +/* + * XXX Backing store is turned off for the PS driver + + if( pWin->backStorage ) + (*pWin->drawable.pScreen->DrawGuarantee) (pWin, pGC, GuaranteeNothing); + */ + + if( what==PW_BORDER ) + { + REGION_UNINIT(pScreen, &pWin->clipList); + pWin->clipList = prgnWin; + pWin->drawable.x = oldCorner.x; + pWin->drawable.y = oldCorner.y; + pWin->drawable.serialNumber = NEXT_SERIAL_NUMBER; + } + FreeScratchGC(pGC); +} + +/*ARGSUSED*/ +Bool +PsDestroyWindow(WindowPtr pWin) +{ + return TRUE; +} diff --git a/Xprint/ps/psout.c b/Xprint/ps/psout.c new file mode 100644 index 000000000..d4a64eacb --- /dev/null +++ b/Xprint/ps/psout.c @@ -0,0 +1,1623 @@ +/* $Xorg: psout.c,v 1.9 2001/03/26 15:25:12 coskrey Exp $ */ +/* + +Copyright 1996, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ +/* + * (c) Copyright 1996 Hewlett-Packard Company + * (c) Copyright 1996 International Business Machines Corp. + * (c) Copyright 1996, 2000 Sun Microsystems, Inc. All Rights Reserved. + * (c) Copyright 1996 Novell, Inc. + * (c) Copyright 1996 Digital Equipment Corp. + * (c) Copyright 1996 Fujitsu Limited + * (c) Copyright 1996 Hitachi, Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the names of the copyright holders + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in this Software without prior written authorization + * from said copyright holders. + */ + +/******************************************************************* +** +** ********************************************************* +** * +** * File: psout.c +** * +** * Contents: Code to output PostScript to file +** * +** * Created By: Roger Helmendach (Liberty Systems) +** * +** * Copyright: Copyright 1996 The Open Group, Inc. +** * +** ********************************************************* +** +********************************************************************/ + +#include <stdlib.h> +#include "os.h" +#include "psout.h" + +PsElmPtr PsCloneFillElementList(int nElms, PsElmPtr elms); + +typedef void *voidPtr; + +typedef struct PsPatRec_ +{ + PsFillEnum type; + voidPtr tag; +} PsPatRec; + +typedef PsPatRec *PsPatPtr; + +typedef struct PsOutRec_ +{ + FILE *Fp; + char Buf[256]; + int CurColor; + int LineWidth; + PsCapEnum LineCap; + PsJoinEnum LineJoin; + int NDashes; + int *Dashes; + int DashOffset; + int LineBClr; + PsRuleEnum FillRule; + char *FontName; + int FontSize; + float FontMtx[4]; + int ImageFormat; + int RevImage; + int NPatterns; + int MxPatterns; + PsPatPtr Patterns; + int ClipType; + PsClipRec Clip; + int InFrame; + int XOff; + int YOff; + + PsFillEnum InTile; + int ImgSkip; + int ImgBClr; + int ImgFClr; + int ImgX; + int ImgY; + int ImgW; + int ImgH; + int SclW; + int SclH; + + int NDownloads; + int MxDownloads; + char **Downloads; + Bool isRaw; + + int start_image; +} PsOutRec; + +/* + * Standard definitions + */ + +static char *S_StandardDefs = "\ +/d{def}bind def\ +/b{bind}bind d\ +/bd{b d}b d\ +/x{exch}bd\ +/xd{x d}bd\ +/dp{dup}bd\ +/t{true}bd\ +/f{false}bd\ +/p{pop}bd\ +/r{roll}bd\ +/c{copy}bd\ +/i{index}bd\ +/rp{repeat}bd\ +/n{newpath}bd\ +/w{setlinewidth}bd\ +/lc{setlinecap}bd\ +/lj{setlinejoin}bd\ +/sml{setmiterlimit}bd\ +/ds{setdash}bd\ +/ie{ifelse}bd\ +/len{length}bd\ +/m{moveto}bd\ +/l{lineto}bd\ +/rl{rlineto}bd\ +/a{arc}bd\ +/an{arcn}bd\ +/st{stroke}bd\ +/fl{fill}bd\ +/ef{eofill}bd\ +/sp{showpage}bd\ +/cp{closepath}bd\ +/clp{clippath}bd\ +/cl{clip}bd\ +/pb{pathbbox}bd\ +/tr{translate}bd\ +/rt{rotate}bd\ +/dv{div}bd\ +/ml{mul}bd\ +/ad{add}bd\ +/ng{neg}bd\ +/scl{scale}bd\ +/sc{setrgbcolor}bd\ +/g{setgray}bd\ +/gs{gsave}bd\ +/gr{grestore}bd\ +/sv{save}bd\ +/rs{restore}bd\ +/mx{matrix}bd\ +/cm{currentmatrix}bd\ +/sm{setmatrix}bd\ +/ccm{concatmatrix}bd\ +/cc{concat}bd\ +/ff{findfont}bd\ +/mf{makefont}bd\ +/sf{setfont}bd\ +/cft{currentfont}bd\ +/fd{FontDirectory}bd\ +/sh{show}bd\ +/stw{stringwidth}bd\ +/ci{colorimage}bd\ +/ig{image}bd\ +/im{imagemask}bd\ +/cf{currentfile}bd\ +/rh{readhexstring}bd\ +/str{string}bd\ +/al{aload}bd\ +/wh{where}bd\ +/kn{known}bd\ +/stp{stopped}bd\ +/bg{begin}bd\ +/ed{end}bd\ +/fa{forall}bd\ +/pi{putinterval}bd\ +/mk{mark}bd\ +/ctm{cleartomark}bd\ +/df{definefont}bd\ +/cd{currentdict}bd\ +/db{20 dict dp bg}bd\ +/de{ed}bd\ +/languagelevel wh{p languagelevel}{1}ie\ + 1 eq{/makepattern{p}bd/setpattern{p}bd/setpagedevice{p}bd}if\ +/mp{makepattern}bd\ +/spt{setpattern}bd\ +/spd{setpagedevice}bd\ +"; + +/* + * Composite definitions + * + * + * XYr - Return X/Y dpi for device + * + * XYr <xdpi> <ydpi> + * + * Cs - Coordinate setup (for origin upper left) + * + * <orient(0,1,2,3)> Cs + * + * P - Draw a point + * + * <x> <y> P + * + * R - Add rectangle to path + * + * <x> <y> <w> <h> R + * + * Ac - Add arc to path + * + * <x> <y> <w> <h> <ang1> <ang2> Ac + * + * An - Add arc to path (counterclockwise) + * + * <x> <y> <w> <h> <ang1> <ang2> An + * + * Tf - Set font + * + * <font_name> <size> <iso> Tf + * + * Tfm - Set font with matrix + * + * <font_name> <matrix> <iso> Tfm + * + * T - Draw text + * + * <text> <x> <y> T + * + * Tb - Draw text with background color + * + * <text> <x> <y> <bg_red> <bg_green> <bg_blue> Tb + * + * Im1 - Image 1 bit monochrome imagemask + * + * <x> <y> <w> <h> <sw> <sh> Im1 + * + * Im24 - Image 24 bit RGB color + * + * <x> <y> <w> <h> <sw> <sh> Im24 + * + * Im1t - Image 1 bit monochrome imagemask (in tile) + * + * <data> <x> <y> <w> <h> <sw> <sh> Im1t + * + * Im24t - Image 24 bit RGB color (in tile) + * + * <data> <x> <y> <w> <h> <sw> <sh> Im24t + */ + +static char *S_CompositeDefs = "\ +/XYr{/currentpagedevice wh\ + {p currentpagedevice dp /HWResolution kn\ + {/HWResolution get al p}{p 300 300}ie}{300 300}ie}bd\ +/Cs{dp 0 eq{0 pHt tr XYr -1 x dv 72 ml x 1 x dv 72 ml x scl}if\ + dp 1 eq{90 rt XYr -1 x dv 72 ml x 1 x dv 72 ml x scl}if\ + dp 2 eq{pWd 0 tr XYr 1 x dv 72 ml x -1 x dv 72 ml x scl}if\ + 3 eq{pHt pWd tr 90 rt XYr 1 x dv 72 ml x -1 x dv 72 ml x scl}if}bd\ +/P{gs 1 w [] 0 ds 2 c m .1 ad x .1 ad x l st gr}bd\ +/R{4 2 r m 1 i 0 rl 0 x rl ng 0 rl cp}bd\ +/Ac{mx_ cm p 6 -2 r tr 4 2 r ng scl 0 0 .5 5 3 r a mx_ sm}bd\ +/An{mx_ cm p 6 -2 r tr 4 2 r ng scl 0 0 .5 5 3 r an mx_ sm}bd\ +/ISO{dp len dict bg{1 i/FID ne{d}{p p}ie}fa\ + /Encoding ISOLatin1Encoding d cd ed df}bd\ +/iN{dp len str cvs dp len x 1 i 3 ad str 2 c c p x p dp 3 -1 r(ISO)pi}bd\ +/Tp{{x dp iN dp fd x kn{x p dp/f_ x d ff}{dp/f_ x d x ff ISO}ie x}\ + {x dp/f_ x d ff x}ie}bd\ +/Tf{Tp[x 0 0 2 i ng 0 0] dp/fm_ x d mf sf}bd\ +/Tfm{Tp 1 -1 tm1_ scl tm2_ ccm dp/fm_ x d mf sf}bd\ +/T{m sh}bd\ +/Tb{gs sc f_ ff sf cft/FontMatrix get 3 get\ + cft/FontBBox get dp 1 get x 3 get 2 i ml 3 1 r ml\ + 0 0 m 4 i stw p 4 i 4 i m fm_ cc\ + 0 2 i rl dp 0 rl 0 2 i ng rl 0 3 i rl ng 0 rl cp fl p p\ + gr T}bd\ +/Im1{6 4 r tr scl t [3 i 0 0 5 i 0 0]{cf str1 rh p} im}bd\ +/Im1rev{6 4 r tr scl f [3 i 0 0 5 i 0 0]{cf str1 rh p} im}bd\ +/Im24{gs 6 4 r tr scl 8 [3 i 0 0 5 i 0 0]{cf str3 rh p} f 3 ci}bd\ +/Im1t{6 4 r tr scl t [3 i 0 0 5 i 0 0]{} im}bd\ +/Im24t{gs 6 4 r tr scl 8 [3 i 0 0 5 i 0 0]{} f 3 ci}bd\ +/ck2{/currentpagedevice wh \ +{p dp currentpagedevice dp 3 -1 r kn \ +{x get al p 3 -1 r eq 3 1 r eq and } \ +{p p p p t}ie} \ +{p p p t}ie}bd \ +/ck1{/currentpagedevice wh \ +{p dp currentpagedevice dp 3 -1 r kn \ +{x get eq} {p p p t}ie} \ +{p p t}ie}bd \ +/mtx{scl t [3 i 0 0 5 i 0 0]}bd \ +"; + +int pagenum = 0; +char *pg_orient[] = {"Portrait","Landscape","Reverse Portrait","Reverse Landscape"}; +/* + * Setup definitions + */ + +static char *S_SetupDefs = "\ + /mx_ mx d\ + /im_ mx d\ + /tm1_ mx d\ + /tm2_ mx d\ + /str3 3 str d\ + /str1 1 str d\ +"; + +/******************************************************************* + * PRIVATE FUNCTIONS * + *******************************************************************/ + +static void +S_Flush(PsOutPtr self) +{ + if( self->Buf[0] ) + { + if( self->Buf[strlen(self->Buf)-1]!='\n' ) strcat(self->Buf, "\n"); + + if (!ferror(self->Fp)) { + (void) fputs(self->Buf, self->Fp); + } + + self->Buf[0] = '\0'; + } +} + +static void +S_Comment(PsOutPtr self, char *comment) +{ + S_Flush(self); + strcpy(self->Buf, comment); + S_Flush(self); +} + +static void +S_OutDefs(PsOutPtr self, char *defs) +{ + int i, k=0; + S_Flush(self); + memset(self->Buf, 0, 256); + for( i=0 ; defs[i]!='\0' ;) + { + if( k>70 && (i==0 || (i && defs[i-1]!='/')) && + (defs[i]==' ' || defs[i]=='/' || defs[i]=='{') ) + { + S_Flush(self); + k = 0; + memset(self->Buf, 0, 256); + } + if( k && self->Buf[k-1]==' ' && defs[i]==' ' ) { i++; continue; } + self->Buf[k] = defs[i]; + k++; i++; + } + S_Flush(self); +} + +static void +S_OutNum(PsOutPtr self, float num) +{ + int i; + char buf[64]; + sprintf(buf, "%.3f", num); + for( i=strlen(buf)-1 ; buf[i]=='0' ; i-- ); buf[i+1] = '\0'; + if( buf[strlen(buf)-1]=='.' ) buf[strlen(buf)-1] = '\0'; + if( self->Buf[0] ) strcat(self->Buf, " "); + strcat(self->Buf, buf); + if( strlen(self->Buf)>70 ) S_Flush(self); +} + +static void +S_OutStr(PsOutPtr self, char *txt, int txtl) +{ + int i, k; + char buf[512]; + for( i=0,k=0 ; i<txtl ; i++ ) + { + if( (txt[i]>=' ' && txt[i]<='~') && + txt[i]!='(' && txt[i]!=')' && txt[i]!='\\' ) + { buf[k] = txt[i]; k++; continue; } + buf[k] = '\\'; k++; + sprintf(&buf[k], "%03o", txt[i]&0xFF); + k += 3; + } + strcat(self->Buf, "("); + i = strlen(self->Buf); + memcpy(&self->Buf[i], buf, k); + self->Buf[i+k] = '\0'; + strcat(self->Buf, ")"); + if( strlen(self->Buf)>70 ) S_Flush(self); +} + +static void +S_OutTok(PsOutPtr self, char *tok, int cr) +{ + if( self->Buf[0] ) strcat(self->Buf, " "); + strcat(self->Buf, tok); + if( cr ) S_Flush(self); +} + +static void +S_Color(PsOutPtr self, int clr) +{ + int ir, ig, ib; + ir = clr>>16; ig = (clr>>8)&0xFF; ib = clr&0xFF; + if( ir==ig && ig==ib ) + { S_OutNum(self, (float)ir/255.); S_OutTok(self, "g", 1); } + else + { + S_OutNum(self, (float)ir/255.); + S_OutNum(self, (float)ig/255.); + S_OutNum(self, (float)ib/255.); + S_OutTok(self, "sc", 1); + } +} + +static void +S_SetPageDevice(PsOutPtr self, int orient, int count, int plex, int res, + int wd, int ht, int isPage) +{ + float fwd = ((float)wd/(float)res)*72.; + float fht = ((float)ht/(float)res)*72.; + + S_OutTok(self, "/pWd", 0); + S_OutNum(self, fwd); + S_OutTok(self, "d /pHt", 0); + S_OutNum(self, fht); + S_OutTok(self, "d", 1); + + /* + * if these are page attributes, have PostScript check to see if they + * have changed. If not, don't do setpagedevice, since it will cause + * a page flush and screw up duplex printing. Having PostScript check + * means we don't have to keep track ourselves. + */ + if(isPage) { + S_OutNum(self, (float) orient); + S_OutTok(self, "/Orientation ck1", 0); + S_OutTok(self, "pWd pHt /PageSize ck2 and not {", 1); + } + S_OutTok(self, "{db", 0); + + S_OutTok(self, "/Orientation", 0); + S_OutNum(self, (float) orient); + S_OutTok(self, " d ", 0); + S_OutTok(self, "/PageSize [pWd pHt] d", 0); + + S_OutTok(self, " de spd", 0); + /* + * save a flag to show if we failed to set orientation... determined + * by both/either Orientation and/or PageSize, use this + * later to set/not set orientation using Cs command. + */ + S_OutTok(self,"}stp /orientationFailed x d", 1); + /* + * if these are page attributes, have PostScript check to see if they + * have changed. If not, don't do setpagedevice, since it will cause + * a page flush and screw up duplex printing. Having PostScript check + * means we don't have to keep track ourselves. + */ + if(isPage) + { + S_OutTok(self,"}if",1); + + S_OutTok(self, (plex==0)?"f":"t", 0); + S_OutTok(self, "/Duplex ck1 ", 0); + + S_OutTok(self, (plex==2)?"t":"f", 0); + S_OutTok(self, "/Tumble ck1 and ", 0); + + + S_OutNum(self, (float)res); + S_OutNum(self, (float)res); + S_OutTok(self, " /HWResolution ck2 and", 0); + + if( count>1 ) + { + S_OutNum(self, (float)count); + S_OutTok(self, " /NumCopies", 0); + S_OutTok(self, " ck1 and ", 0); + } + S_OutTok(self," not {",1); + } + S_OutTok(self, "{db", 0); + + S_OutTok(self, "/Duplex ", 0); + S_OutTok(self, (plex==0)?"f":"t", 0); + S_OutTok(self, " d ", 0); + + S_OutTok(self, "/Tumble ", 0); + S_OutTok(self, (plex==2)?"t":"f", 0); + S_OutTok(self, " d ", 0); + + S_OutTok(self, " /HWResolution [", 0); + S_OutNum(self, (float)res); + S_OutNum(self, (float)res); + S_OutTok(self, "] d ", 0); + + if( count>1 ) + { + S_OutTok(self, " /NumCopies", 0); + S_OutNum(self, (float)count); + S_OutTok(self, " d ", 0); + } + S_OutTok(self, " de spd}stp p", 1); + + if(isPage) + { + S_OutTok(self, "}if", 1); + } +} + +/******************************************************************* + * PUBLIC FUNCTIONS * + *******************************************************************/ + +FILE * +PsOut_ChangeFile(PsOutPtr self, FILE *fp) +{ + FILE *nfp; + + nfp = self->Fp; + + self->Fp = fp; + + return nfp; +} + +PsOutPtr +PsOut_BeginFile(FILE *fp, int orient, int count, int plex, int res, + int wd, int ht, Bool raw) +{ + int i; +/* + * Get ready to output PostScript header + */ + PsOutPtr psout; + psout = (PsOutPtr)xalloc(sizeof(PsOutRec)); + memset(psout, 0, sizeof(PsOutRec)); + psout->Fp = fp; + psout->isRaw = raw; + pagenum = 0; + + if (!raw) { +/* + * Output PostScript header + */ + S_Comment(psout, "%!PS-Adobe-3.0 EPSF-3.0"); + S_Comment(psout, "%%Creator: The Open Group PostScript Print Server"); + /*### BoundingBox ###*/ + S_Comment(psout, "%%EndComments"); + S_Comment(psout, "%%BeginProlog"); + S_Comment(psout, "%%BeginProcSet: XServer_PS_Functions"); + S_OutDefs(psout, S_StandardDefs); + S_OutDefs(psout, S_CompositeDefs); + S_Comment(psout, "%%EndProcSet"); + S_Comment(psout, "%%EndProlog"); + S_Comment(psout, "%%BeginSetup"); + /* set document level page attributes */ + S_SetPageDevice(psout, orient, count, plex, res, wd, ht, 0); + S_Comment(psout, "%%Pages: atend"); + S_OutDefs(psout, S_SetupDefs); + S_Comment(psout, "%%EndSetup"); + } +/* + * Initialize the structure + */ + psout->CurColor = 0xFFFFFFFF; + psout->LineWidth = 1; + psout->LineCap = PsCButt; + psout->LineJoin = PsJMiter; + psout->NDashes = 0; + psout->Dashes = (int *)0; + psout->FontName = (char *)0; + psout->FontSize = 0; + psout->start_image = 0; + for( i=0 ; i<4 ; i++ ) psout->FontMtx[i] = 0.; + psout->ImageFormat = 0; + return(psout); +} + +void +PsOut_EndFile(PsOutPtr self, int closeFile) +{ + char coms[50]; + int i; + + if (!self->isRaw) { + S_Comment(self,"%%Trailer"); + sprintf(coms,"%%%%Pages: %d",pagenum); + S_Comment(self, coms); + S_Comment(self, "%%EOF"); + } + if( self->NDashes && self->Dashes ) xfree(self->Dashes); + if( self->FontName ) xfree(self->FontName); + if( self->Patterns ) xfree(self->Patterns); + if( self->Clip.rects ) xfree(self->Clip.rects); + if( closeFile ) fclose(self->Fp); + for( i=0 ; i<self->NDownloads ; i++ ) xfree(self->Downloads[i]); + if( self->Downloads ) xfree(self->Downloads); + pagenum = 0; /* reset page num back to 0 */ + xfree(self); +} + +void +PsOut_BeginPage(PsOutPtr self, int orient, int count, int plex, int res, + int wd, int ht) +{ + char coms[50]; + +/*** comment for pagenumbers *****/ + + S_Comment(self,"%%PageHeader"); + pagenum++; + sprintf(coms,"%%%%Page: %d %d",pagenum,pagenum); + S_Comment(self, coms); + sprintf(coms,"%%%%PageOrientation: %s",pg_orient[orient]); + S_Comment(self, coms); + +/*** end comment *****************/ + + /* set page level page attributes */ + S_SetPageDevice(self, orient, count, plex, res, wd, ht, 1); + + S_OutTok(self, "gs ", 0); + /* + * check to see if we set orientation already; if it wasn't set, + * use Cs to set orientation here. + */ + S_OutNum(self, (float)orient); + S_OutTok(self, "orientationFailed { ", 0); + S_OutNum(self, (float)orient); + S_OutTok(self, " } { 0 }ie Cs 100 sml gs", 1); +} + +void +PsOut_EndPage(PsOutPtr self) +{ + S_OutTok(self, "gr gr sp", 1); + + /* did grestore: mark attributes 'dirty' so they will be re-sent */ + PsOut_DirtyAttributes(self); + +/*** comment for pagenumbers *****/ + + S_Comment(self,"%%PageTrailer"); + +/*** end comment *****************/ +} + +void +PsOut_DirtyAttributes(PsOutPtr self) +{ + int i; + self->CurColor = 0xFFFFFFFF; + self->LineWidth = -1; + self->LineCap = (PsCapEnum)-1; + self->LineJoin = (PsJoinEnum)-1; + self->NDashes = -1; + self->FontSize = -1; + for( i=0 ; i<4 ; i++ ) self->FontMtx[i] = -1.; + if( self->Dashes ) { xfree(self->Dashes); self->Dashes = (int *)0; } + if( self->FontName ) { xfree(self->FontName); self->FontName = (char *)0; } +} + +void +PsOut_Comment(PsOutPtr self, char *comment) +{ + S_Comment(self, comment); +} + +void +PsOut_Offset(PsOutPtr self, int x, int y) +{ + self->XOff = x; + self->YOff = y; +} + +void +PsOut_Clip(PsOutPtr self, int clpTyp, PsClipPtr clpinf) +{ + int i, k; + int changed = 0; + int xo = self->XOff; + int yo = self->YOff; + + if( self->InTile ) return; + if( self->InFrame ) xo = yo = 0; + if( clpTyp!=self->ClipType ) changed = 1; + else + { + if( clpinf->nRects!=self->Clip.nRects ) changed = 1; + else + { + if( clpinf->nOutterClips!=self->Clip.nOutterClips ) changed = 1; + else + { + for( i=0 ; i<clpinf->nOutterClips ; i++ ) + { + if( memcmp(&clpinf->outterClips[i], &self->Clip.outterClips[i], + sizeof(PsRectRec))!=0 ) break; + } + if( i<clpinf->nOutterClips ) changed = 1; + else + { + for( i=0 ; i<clpinf->nRects ; i++ ) + { + if( memcmp(&clpinf->rects[i], &self->Clip.rects[i], + sizeof(PsRectRec))!=0 ) { changed = 1; break; } + } + } + } + } + if( clpinf->nElms!=self->Clip.nElms ) changed = 1; + else + { + for( i=0 ; i<clpinf->nElms ; i++ ) + { + if( clpinf->elms[i].type!=PSOUT_POINTS ) + { + if( memcmp(&clpinf->elms[i], &self->Clip.elms[i], + sizeof(PsElmRec))!=0 ) { changed = 1; break; } + } + else + { + if( clpinf->elms[i].type!=self->Clip.elms[i].type || + clpinf->elms[i].nPoints!=self->Clip.elms[i].nPoints ) + { changed = 1; break; } + else + { + for( k=0 ; k<clpinf->elms[i].nPoints ; k++ ) + { + if( memcmp(&clpinf->elms[i].c.points[k], + &self->Clip.elms[i].c.points[k], sizeof(PsPointRec)) ) + { changed = 1; break; } + } + if( changed ) break; + } + } + } + } + } + + if( self->Clip.rects ) xfree(self->Clip.rects); + if( self->Clip.outterClips ) xfree(self->Clip.outterClips); + if( self->Clip.elms ) + PsDestroyFillElementList(self->Clip.nElms, self->Clip.elms); + self->ClipType = clpTyp; + self->Clip.nRects = clpinf->nRects; + self->Clip.nElms = clpinf->nElms; + self->Clip.nOutterClips = clpinf->nOutterClips; + if( clpinf->nRects ) + { + self->Clip.rects = (PsRectPtr)xalloc(clpinf->nRects*sizeof(PsRectRec)); + memcpy(self->Clip.rects, clpinf->rects, clpinf->nRects*sizeof(PsRectRec)); + } + else self->Clip.rects = 0; + if( clpinf->nOutterClips ) + { + self->Clip.outterClips = (PsRectPtr)xalloc(clpinf->nOutterClips* + sizeof(PsRectRec)); + memcpy(self->Clip.outterClips, clpinf->outterClips, + clpinf->nOutterClips*sizeof(PsRectRec)); + } + else self->Clip.outterClips = 0; + if( clpinf->nElms ) + self->Clip.elms = PsCloneFillElementList(clpinf->nElms, clpinf->elms); + else self->Clip.elms = 0; + + PsOut_DirtyAttributes(self); + S_OutTok(self, "gr gs", 1); + if( self->Clip.nOutterClips ) + { + for( i=0 ; i<self->Clip.nOutterClips ; i++ ) + { + S_OutNum(self, (float)(self->Clip.outterClips[i].x)); + S_OutNum(self, (float)(self->Clip.outterClips[i].y)); + S_OutNum(self, (float)self->Clip.outterClips[i].w); + S_OutNum(self, (float)self->Clip.outterClips[i].h); + S_OutTok(self, "R", 1); + } + S_OutTok(self, "cl n", 1); + } + if( self->Clip.nRects ) + { + for( i=0 ; i<self->Clip.nRects ; i++ ) + { + S_OutNum(self, (float)(self->Clip.rects[i].x+xo)); + S_OutNum(self, (float)(self->Clip.rects[i].y+yo)); + S_OutNum(self, (float)self->Clip.rects[i].w); + S_OutNum(self, (float)self->Clip.rects[i].h); + S_OutTok(self, "R", 1); + } + S_OutTok(self, "cl n", 1); + } + if( self->Clip.nElms ) + { + PsElmPtr elm = self->Clip.elms; + for( i=0 ; i<self->Clip.nElms ; i++,elm++ ) + { + switch(elm->type) + { + case PSOUT_POINTS: + for( k=0 ; k<elm->nPoints ; k++ ) + { + S_OutNum(self, (float)elm->c.points[k].x+xo); + S_OutNum(self, (float)elm->c.points[k].y+yo); + if( k==0 ) S_OutTok(self, "m", 0); + else S_OutTok(self, "l", 0); + } + S_OutTok(self, "cp", 1); + break; + case PSOUT_RECT: + S_OutNum(self, (float)elm->c.rect.x+xo); + S_OutNum(self, (float)elm->c.rect.y+yo); + S_OutNum(self, (float)elm->c.rect.w); + S_OutNum(self, (float)elm->c.rect.h); + S_OutTok(self, "R", 1); + break; + case PSOUT_ARC: + if( elm->c.arc.style==PsPieSlice ) + { + S_OutNum(self, (float)elm->c.arc.x+xo+(float)elm->c.arc.w/2.); + S_OutNum(self, (float)elm->c.arc.y+yo+(float)elm->c.arc.h/2.); + S_OutTok(self, "m", 0); + } + S_OutNum(self, (float)elm->c.arc.x+xo+(float)elm->c.arc.w/2.); + S_OutNum(self, (float)elm->c.arc.y+yo+(float)elm->c.arc.h/2.); + S_OutNum(self, (float)elm->c.arc.w); + S_OutNum(self, (float)elm->c.arc.h); + S_OutNum(self, (float)elm->c.arc.a1/64.); + S_OutNum(self, (float)elm->c.arc.a1/64.+(float)elm->c.arc.a2/64.); + if( elm->c.arc.a2<0 ) S_OutTok(self, "An cp", 1); + else S_OutTok(self, "Ac cp", 1); + break; + } + } + S_OutTok(self, "cl n", 1); + } +} + +void +PsOut_Color(PsOutPtr self, int clr) +{ + if( clr==self->CurColor || self->InTile>=PsStip ) return; + self->CurColor = clr; + S_Color(self, clr); +} + +void +PsOut_FillRule(PsOutPtr self, PsRuleEnum rule) +{ + self->FillRule = rule; +} + +void +PsOut_LineAttrs(PsOutPtr self, int wd, PsCapEnum cap, PsJoinEnum join, + int nDsh, int *dsh, int dshOff, int bclr) +{ + int i; + int same = 1; + + if( wd!=self->LineWidth && wd>=0 ) + { + if( wd==0 ) wd = 1; + self->LineWidth = wd; + S_OutNum(self, (float)wd); S_OutTok(self, "w", 1); + } + if( cap!=self->LineCap ) + { + self->LineCap = cap; + S_OutNum(self, (float)cap); S_OutTok(self, "lc", 1); + } + if( join!=self->LineJoin ) + { + self->LineJoin = join; + S_OutNum(self, (float)join); S_OutTok(self, "lj", 1); + } + if( nDsh!=self->NDashes ) same = 0; + else if( dshOff!=self->DashOffset ) same = 0; + else if( nDsh ) + { + for( i=0 ; i<nDsh ; i++ ) + { if( dsh[i]!=self->Dashes[i] ) break; } + if( i<nDsh ) same = 0; + } + if( !same ) + { + if( self->NDashes && self->Dashes ) + { xfree(self->Dashes); self->Dashes = (int *)0; } + self->NDashes = nDsh; + self->DashOffset = dshOff; + if( nDsh ) self->Dashes = (int *)xalloc(sizeof(int)*nDsh); + S_OutTok(self, "[", 0); + for( i=0 ; i<nDsh ; i++ ) + { + self->Dashes[i] = dsh[i]; + S_OutNum(self, (float)dsh[i]); + } + S_OutTok(self, "]", 0); + S_OutNum(self, (float)dshOff); + S_OutTok(self, "ds", 1); + } + + if( nDsh ) self->LineBClr = bclr; else bclr = -1; +} + +void +PsOut_TextAttrs(PsOutPtr self, char *fnam, int siz, int iso) +{ + int i; + char buf[256]; + if( self->FontName && strcmp(fnam, self->FontName)==0 && + siz==self->FontSize ) return; + if( self->FontName ) xfree(self->FontName); + self->FontName = (char *)xalloc(strlen(fnam)+1); + strcpy(self->FontName, fnam); + self->FontSize = siz; + for( i=0 ; i<4 ; i++ ) self->FontMtx[i] = -1.; + strcpy(buf, "/"); strcat(buf, fnam); + S_OutTok(self, buf, 0); + S_OutNum(self, (float)siz); + if( iso ) S_OutTok(self, "t", 0); + else S_OutTok(self, "f", 0); + S_OutTok(self, "Tf", 1); +} + +void +PsOut_TextAttrsMtx(PsOutPtr self, char *fnam, float *mtx, int iso) +{ + int i; + char buf[256]; + if( self->FontName && strcmp(fnam, self->FontName)==0 && + mtx[0]==self->FontMtx[0] && mtx[1]==self->FontMtx[1] && + mtx[2]==self->FontMtx[2] && mtx[3]==self->FontMtx[3] ) return; + if( self->FontName ) xfree(self->FontName); + self->FontName = (char *)xalloc(strlen(fnam)+1); + strcpy(self->FontName, fnam); + for( i=0 ; i<4 ; i++ ) self->FontMtx[i] = mtx[i]; + self->FontSize = -1; + strcpy(buf, "/"); strcat(buf, fnam); strcat(buf, " ["); + S_OutTok(self, buf, 0); + for( i=0 ; i<4 ; i++ ) S_OutNum(self, mtx[i]); + S_OutTok(self, "0 0]", 0); + if( iso ) S_OutTok(self, "t", 0); + else S_OutTok(self, "f", 0); + S_OutTok(self, "Tfm", 1); +} + +void +PsOut_Polygon(PsOutPtr self, int nPts, PsPointPtr pts) +{ + int i; + int xo = self->XOff; + int yo = self->YOff; + + if( self->InFrame || self->InTile ) xo = yo = 0; + if( nPts<=2 ) return; + for( i=0 ; i<nPts ; i++ ) + { + S_OutNum(self, (float)(pts[i].x+xo)); + S_OutNum(self, (float)(pts[i].y+yo)); + if( i==0 ) S_OutTok(self, "m", 0); + else S_OutTok(self, "l", 0); + } + if( self->FillRule==PsEvenOdd ) S_OutTok(self, "cp ef", 1); + else S_OutTok(self, "cp fl", 1); +} + +void +PsOut_FillRect(PsOutPtr self, int x, int y, int w, int h) +{ + int xo = self->XOff; + int yo = self->YOff; + + if( self->InFrame || self->InTile ) xo = yo = 0; + x += xo; y += yo; + S_OutNum(self, (float)x); + S_OutNum(self, (float)y); + S_OutNum(self, (float)w); + S_OutNum(self, (float)h); + S_OutTok(self, "R fl", 1); +} + +void +PsOut_FillArc(PsOutPtr self, int x, int y, int w, int h, + float ang1, float ang2, PsArcEnum style) +{ + int xo = self->XOff; + int yo = self->YOff; + + if( self->InFrame || self->InTile ) xo = yo = 0; + x += xo; y += yo; + if( style==PsPieSlice ) + { + S_OutNum(self, (float)x+(float)w/2.); + S_OutNum(self, (float)y+(float)h/2.); + S_OutTok(self, "m", 0); + } + S_OutNum(self, (float)x+(float)w/2.); + S_OutNum(self, (float)y+(float)h/2.); + S_OutNum(self, (float)w); + S_OutNum(self, (float)h); + S_OutNum(self, ang1); + S_OutNum(self, ang1+ang2); + if( ang2<0 ) S_OutTok(self, "An cp fl", 1); + else S_OutTok(self, "Ac cp fl", 1); +} + +void +PsOut_Lines(PsOutPtr self, int nPts, PsPointPtr pts) +{ + int i; + int xo = self->XOff; + int yo = self->YOff; + + if( self->InFrame || self->InTile ) xo = yo = 0; + if( nPts<1 ) return; + for( i=0 ; i<nPts ; i++ ) + { + S_OutNum(self, (float)(pts[i].x+xo)); + S_OutNum(self, (float)(pts[i].y+yo)); + if( i==0 ) S_OutTok(self, "m", 0); + else S_OutTok(self, "l", 0); + } + if( self->LineBClr>=0 ) + { + S_OutTok(self, "gs", 0); + S_Color(self, self->LineBClr); + S_OutTok(self, "[] 0 ds st gr", 0); + } + S_OutTok(self, "st", 1); +} + +void +PsOut_Points(PsOutPtr self, int nPts, PsPointPtr pts) +{ + int i; + int xo = self->XOff; + int yo = self->YOff; + + if( self->InFrame || self->InTile ) xo = yo = 0; + if( nPts<1 ) return; + for( i=0 ; i<nPts ; i++ ) + { + S_OutNum(self, (float)(pts[i].x+xo)); + S_OutNum(self, (float)(pts[i].y+yo)); + S_OutTok(self, "P", 1); + } +} + +void +PsOut_DrawRect(PsOutPtr self, int x, int y, int w, int h) +{ + int xo = self->XOff; + int yo = self->YOff; + + if( self->InFrame || self->InTile ) xo = yo = 0; + x += xo; y += yo; + S_OutNum(self, (float)x); + S_OutNum(self, (float)y); + S_OutNum(self, (float)w); + S_OutNum(self, (float)h); + S_OutTok(self, "R", 0); + if( self->LineBClr>=0 ) + { + S_OutTok(self, "gs", 0); + S_Color(self, self->LineBClr); + S_OutTok(self, "[] 0 ds st gr", 0); + } + S_OutTok(self, "st", 1); +} + +void +PsOut_DrawArc(PsOutPtr self, int x, int y, int w, int h, + float ang1, float ang2) +{ + int xo = self->XOff; + int yo = self->YOff; + + if( self->InFrame || self->InTile ) xo = yo = 0; + x += xo; y += yo; + S_OutNum(self, (float)x+(float)w/2.); + S_OutNum(self, (float)y+(float)h/2.); + S_OutNum(self, (float)w); + S_OutNum(self, (float)h); + S_OutNum(self, ang1); + S_OutNum(self, ang1+ang2); + if( ang2<0 ) S_OutTok(self, "An", 0); + else S_OutTok(self, "Ac", 0); + if( self->LineBClr>=0 ) + { + S_OutTok(self, "gs", 0); + S_Color(self, self->LineBClr); + S_OutTok(self, "[] 0 ds st gr", 0); + } + S_OutTok(self, "st", 1); +} + +void +PsOut_Text(PsOutPtr self, int x, int y, char *text, int textl, int bclr) +{ + int xo = self->XOff; + int yo = self->YOff; + + if( self->InFrame || self->InTile ) xo = yo = 0; + x += xo; y += yo; + S_OutStr(self, text, textl); + S_OutNum(self, (float)x); + S_OutNum(self, (float)y); + if( bclr<0 ) S_OutTok(self, "T", 1); + else + { + int ir = bclr>>16; + int ig = (bclr>>8)&0xFF; + int ib = bclr&0xFF; + S_OutNum(self, (float)ir/255.); + S_OutNum(self, (float)ig/255.); + S_OutNum(self, (float)ib/255.); + S_OutTok(self, "Tb", 1); + } +} + +#ifdef BM_CACHE +void /* new */ +PsOut_ImageCache(PsOutPtr self, int x, int y, long cache_id, int bclr, int fclr) +{ + char cacheID[10]; + int xo = self->XOff; + int yo = self->YOff; + + if( self->InFrame || self->InTile ) xo = yo = 0; + x += xo; y += yo; + sprintf(cacheID, "c%di", cache_id); + + S_OutNum(self, (float)x); + S_OutNum(self, (float)y); + + if( fclr==0xFFFFFF ) + { + int ir, ig, ib; + ir = bclr>>16; ig = (bclr>>8)&0xFF; ib = bclr&0xFF; + if( ir==ig && ig==ib ) + S_OutNum(self, (float)ir/255.); + else + S_OutNum(self, (float)0); + self->RevImage = 1; + } + else + { + int ir, ig, ib; + ir = fclr>>16; ig = (fclr>>8)&0xFF; ib = fclr&0xFF; + if( ir==ig && ig==ib ) + S_OutNum(self, (float)ir/255.); + else + S_OutNum(self, (float)0); + } + + S_OutTok(self, cacheID, 1); +} /* new */ + +void /* new */ +PsOut_BeginImageCache(PsOutPtr self, long cache_id) +{ + char cacheID[10]; + + sprintf(cacheID, "/c%di {", cache_id); + + S_OutTok(self, cacheID, 0); +} /* new */ + +void /* new */ +PsOut_EndImageCache(PsOutPtr self) +{ + S_OutTok(self, "}bd", 1); +} /* new */ +#endif + +void +PsOut_BeginImage(PsOutPtr self, int bclr, int fclr, int x, int y, + int w, int h, int sw, int sh, int format) +{ + int savClr = self->CurColor; + int xo = self->XOff; + int yo = self->YOff; + + if( self->InFrame || self->InTile ) xo = yo = 0; + x += xo; y += yo; + if( self->InTile ) + { + if( self->InTile>=PsStip && format!=1 ) { self->ImgSkip = 1; return; } + self->ImgBClr = bclr; self->ImgFClr = fclr; + self->ImgX = x; self->ImgY = y; + self->ImgW = w; self->ImgH = h; + self->SclW = sw; self->SclH = sh; + S_OutTok(self, "<", 0); + self->ImageFormat = format; + self->RevImage = 0; + if( self->InTile==PsTile && format==1 && fclr==0xFFFFFF ) + self->RevImage = 1; + return; + } + + self->RevImage = 0; + if( format==1 ) + { + S_OutTok(self, "gs", 0); + if( fclr==0xFFFFFF ) + { + PsOut_Color(self, fclr); + PsOut_FillRect(self, x, y, sw, sh); + PsOut_Color(self, bclr); + self->RevImage = 1; + } + else + { + PsOut_Color(self, bclr); + PsOut_FillRect(self, x, y, sw, sh); + PsOut_Color(self, fclr); + } + } + S_OutNum(self, (float)x); + S_OutNum(self, (float)y); + S_OutNum(self, (float)w); + S_OutNum(self, (float)h); + S_OutNum(self, (float)sw); + S_OutNum(self, (float)sh); + if( format==1 ) { + if(self->RevImage) + S_OutTok(self, "Im1rev", 1); + else + S_OutTok(self, "Im1", 1); + } + else S_OutTok(self, "Im24", 1); + self->ImageFormat = format; + self->CurColor = savClr; +} + +void +PsOut_BeginImageIM(PsOutPtr self, int bclr, int fclr, int x, int y, + int w, int h, int sw, int sh, int format) +{ + int savClr = self->CurColor; + int xo = self->XOff; + int yo = self->YOff; + + if( self->InFrame || self->InTile ) xo = yo = 0; + x += xo; y += yo; + if( self->InTile ) + { + if( self->InTile>=PsStip && format!=1 ) { self->ImgSkip = 1; return; } + self->ImgBClr = bclr; self->ImgFClr = fclr; + self->ImgX = x; self->ImgY = y; + self->ImgW = w; self->ImgH = h; + self->SclW = sw; self->SclH = sh; + S_OutTok(self, "<", 0); + self->ImageFormat = format; + self->RevImage = 0; + if( self->InTile==PsTile && format==1 && fclr==0xFFFFFF ) + self->RevImage = 1; + return; + } + + self->RevImage = 0; + if( format==1 ) + { + S_OutTok(self, "gs", 0); +#ifdef BM_CACHE + S_OutTok(self, "g", 1); +#else + if( fclr==0xFFFFFF ) + { + PsOut_Color(self, bclr); + self->RevImage = 1; + } + else + { + PsOut_Color(self, fclr); + } +#endif + } + +#ifdef BM_CACHE + S_OutTok(self, "tr", 0); /* new */ +#else + S_OutNum(self, (float)x); + S_OutNum(self, (float)y); +#endif + S_OutNum(self, (float)w); + S_OutNum(self, (float)h); + S_OutNum(self, (float)sw); + S_OutNum(self, (float)sh); +#ifdef BM_CACHE + S_OutTok(self, "mtx", 1); /* new */ + S_OutTok(self, "<", 0); /* new */ + self->start_image = 1; +#else + if( format==1 ){ + if(self->RevImage) + S_OutTok(self, "Im1rev", 1); + else + S_OutTok(self, "Im1", 1); + } + else S_OutTok(self, "Im24", 1); +#endif + self->ImageFormat = format; + self->CurColor = savClr; +} + +void +PsOut_EndImage(PsOutPtr self) +{ + if( self->ImgSkip ) { self->ImgSkip = 0; return; } + if( self->InTile ) + { + S_OutTok(self, ">", 1); + if( self->ImageFormat==1 && self->InTile==PsTile ) + { + if( self->ImgFClr==0xFFFFFF ) + { + PsOut_Color(self, self->ImgFClr); + PsOut_FillRect(self, self->ImgX, self->ImgY, self->SclW, self->SclH); + PsOut_Color(self, self->ImgBClr); + } + else + { + PsOut_Color(self, self->ImgBClr); + PsOut_FillRect(self, self->ImgX, self->ImgY, self->SclW, self->SclH); + PsOut_Color(self, self->ImgFClr); + } + } + S_OutNum(self, (float)self->ImgX); + S_OutNum(self, (float)self->ImgY); + S_OutNum(self, (float)self->ImgW); + S_OutNum(self, (float)self->ImgH); + S_OutNum(self, (float)self->SclW); + S_OutNum(self, (float)self->SclH); + if( self->ImageFormat==1 ) S_OutTok(self, "Im1t", 1); + else S_OutTok(self, "Im24t", 1); + self->ImageFormat = 0; + self->RevImage = 0; + return; + } + +#ifdef BM_CACHE + if(self->start_image) + S_OutTok(self, "> im", 1); /* new */ +#endif + self->ImageFormat = 0; + self->RevImage = 0; + S_Flush(self); +#ifdef BM_CACHE + if(self->start_image) + { + self->start_image = 0; + S_OutTok(self, "gr", 0); + } + else + S_OutTok(self, "gr", 1); +#else + S_OutTok(self, "gr", 1); +#endif +} + +void +PsOut_OutImageBytes(PsOutPtr self, int nBytes, char *bytes) +{ + int i; + char buf[5]; + + if( (!self->ImageFormat) || self->ImgSkip ) return; + for( i=0 ; i<nBytes ; i++ ) + { + if( self->RevImage ) sprintf(buf, "%02x", (int)(bytes[i]^0xFF)&0xFF); + else sprintf(buf, "%02x", (int)bytes[i]&0xFF); + strcat(self->Buf, buf); + if( strlen(self->Buf)>70 ) S_Flush(self); + } +} + +void +PsOut_BeginFrame(PsOutPtr self, int xoff, int yoff, int x, int y, + int w, int h) +{ + int xo = self->XOff; + int yo = self->YOff; + + if( self->InFrame ) xo = yo = 0; + S_OutTok(self, "gs", 0); + S_OutNum(self, (float)(x+xo)); + S_OutNum(self, (float)(y+yo)); + S_OutNum(self, (float)w); + S_OutNum(self, (float)h); + S_OutTok(self, "R cl n", 0); + xoff += xo; yoff += yo; + if( xoff || yoff ) + { + S_OutNum(self, (float)xoff); + S_OutNum(self, (float)yoff); + S_OutTok(self, "tr", 0); + } + S_OutTok(self, "gs", 1); + self->InFrame += 1; +} + +void +PsOut_EndFrame(PsOutPtr self) +{ + self->InFrame -= 1; + if( self->InFrame<0 ) self->InFrame = 0; + S_OutTok(self, "gr gr", 1); + PsOut_DirtyAttributes(self); +} + +int +PsOut_BeginPattern(PsOutPtr self, void *tag, int w, int h, PsFillEnum type, + int bclr, int fclr) +{ + int i; + char key[64]; + + for( i=0 ; i<self->NPatterns ; i++ ) + { if( self->Patterns[i].tag==tag && self->Patterns[i].type==type ) break; } + if( i<self->NPatterns ) return(1); + if( (self->NPatterns+1)>self->MxPatterns ) + { + if( self->Patterns ) + { + self->MxPatterns *= 2; + self->Patterns = + (PsPatPtr)xrealloc(self->Patterns, sizeof(PsPatRec)*self->MxPatterns); + } + else + { + self->MxPatterns = 64; + self->Patterns = (PsPatPtr)xalloc(sizeof(PsPatRec)*self->MxPatterns); + } + } + self->Patterns[self->NPatterns].tag = tag; + self->Patterns[self->NPatterns].type = type; + sprintf(key, "/ %d", (int)tag); + switch(type) { + case PsTile: key[1] = 't'; break; + case PsStip: key[1] = 's'; break; + case PsOpStip: key[1] = 'o'; break; } + S_OutTok(self, key, 0); + S_OutTok(self, "db/PatternType 1 d/PaintType 1 d", 0); + S_OutTok(self, "/TilingType 1 d/BBox[0 0", 0); + S_OutNum(self, (float)w); + S_OutNum(self, (float)h); + S_OutTok(self, "]d/XStep", 0); + S_OutNum(self, (float)w); + S_OutTok(self, "d/YStep", 0); + S_OutNum(self, (float)h); + S_OutTok(self, "d/PaintProc{bg sv", 1); + if( type==PsOpStip ) + { + S_Color(self, bclr); + S_OutTok(self, "0 0", 0); + S_OutNum(self, (float)w); + S_OutNum(self, (float)h); + S_OutTok(self, "R fl", 1); + } + if( type!=PsTile ) S_Color(self, fclr); + self->NPatterns += 1; + self->InTile = type; + return(0); +} + +void +PsOut_EndPattern(PsOutPtr self) +{ + self->InTile = PsSolid; + S_OutTok(self, "rs ed}d de im_ mp d", 1); +} + +void +PsOut_SetPattern(PsOutPtr self, void *tag, PsFillEnum type) +{ + int i; + char key[64]; + + for( i=0 ; i<self->NPatterns ; i++ ) + { if( tag==self->Patterns[i].tag && type==self->Patterns[i].type ) break; } + if( i>=self->NPatterns ) return; + sprintf(key, " %d", (int)tag); + switch(type) { + case PsTile: key[0] = 't'; break; + case PsStip: key[0] = 's'; break; + case PsOpStip: key[0] = 'o'; break; } + S_OutTok(self, key, 0); + S_OutTok(self, "spt", 1); + self->CurColor = 0xFFFFFFFF; +} + +void +PsOut_RawData(PsOutPtr self, char *data, int len) +{ + S_Flush(self); + if (!ferror(self->Fp)) { + (void) fwrite(data, 1, len, self->Fp); + } +} + +void +PsOut_DownloadType1(PsOutPtr self, char *name, char *fname) +{ + int i; + int stt; + char buf[256]; + FILE *fp; + + for( i=0 ; i<self->NDownloads ; i++ ) + { if( strcmp(name, self->Downloads[i])==0 ) break; } + if( i<self->NDownloads ) return; + + if( (self->NDownloads+1)>self->MxDownloads ) + { + if( self->NDownloads ) + { + self->MxDownloads *= 2; + self->Downloads = (char **)xrealloc(self->Downloads, + self->MxDownloads*sizeof(char *)); + } + else + { + self->MxDownloads = 32; + self->Downloads = (char **)xalloc(self->MxDownloads*sizeof(char *)); + } + } + + self->Downloads[self->NDownloads] = (char *)xalloc(strlen(name)+1); + strcpy(self->Downloads[self->NDownloads], name); + self->NDownloads += 1; + + S_Flush(self); + sprintf(buf, "%%%%BeginFont: %s", name); + S_Comment(self, buf); + fp = fopen(fname, "r"); + if( !fp ) return; + fread(buf, 1, 1, fp); + fseek(fp, (long)0, 0); + if( (buf[0]&0xFF)==0x80 ) + { + int len; + + for(;;) + { + stt = fread(buf, 1, 2, fp); + if( stt!=2 || (buf[0]&0xFF)!=0x80 ) break; + if( (int)buf[1]<1 || (int)buf[1]>2 ) break; + stt = fread(buf, 1, 4, fp); + if( stt!=4 ) break; + len = ((buf[3]&0xFF)<<24)|((buf[2]&0xFF)<<16)| + ((buf[1]&0xFF)<<8)|(buf[0]&0xFF); + for(; len ;) + { + i = len<256 ? len : 256; + stt = fread(buf, 1, i, fp); + if( stt<=0 ) break; + if (!ferror(self->Fp)) { + (void) fwrite(buf, 1, stt, self->Fp); + } + if( stt<i ) break; + len -= i; + } + } + } + else + { + for(;;) + { + stt = fread(buf, 1, 256, fp); + if( stt<=0 ) break; + if (!ferror(self->Fp)) { + (void) fwrite(buf, 1, stt, self->Fp); + } + if( stt<256 ) break; + } + } + fclose(fp); + S_Flush(self); + S_Comment(self, "%%EndFont"); +} diff --git a/Xprint/ps/psout.h b/Xprint/ps/psout.h new file mode 100644 index 000000000..e8ca56458 --- /dev/null +++ b/Xprint/ps/psout.h @@ -0,0 +1,202 @@ +/* $Xorg: psout.h,v 1.6 2001/02/09 02:04:37 xorgcvs Exp $ */ +/* + +Copyright 1996, 1998 The Open Group + +Permission to use, copy, modify, distribute, and sell this software and its +documentation for any purpose is hereby granted without fee, provided that +the above copyright notice appear in all copies and that both that +copyright notice and this permission notice appear in supporting +documentation. + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN +AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the name of The Open Group shall not be +used in advertising or otherwise to promote the sale, use or other dealings +in this Software without prior written authorization from The Open Group. + +*/ +/* + * (c) Copyright 1996 Hewlett-Packard Company + * (c) Copyright 1996 International Business Machines Corp. + * (c) Copyright 1996 Sun Microsystems, Inc. + * (c) Copyright 1996 Novell, Inc. + * (c) Copyright 1996 Digital Equipment Corp. + * (c) Copyright 1996 Fujitsu Limited + * (c) Copyright 1996 Hitachi, Ltd. + * + * Permission is hereby granted, free of charge, to any person obtaining + * a copy of this software and associated documentation files (the + * "Software"), to deal in the Software without restriction, including + * without limitation the rights to use, copy, modify, merge, publish, + * distribute, sublicense, and/or sell copies of the Software, and to + * permit persons to whom the Software is furnished to do so, subject + * to the following conditions: + * + * The above copyright notice and this permission notice shall be included + * in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL + * THE COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF + * OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE + * SOFTWARE. + * + * Except as contained in this notice, the names of the copyright holders + * shall not be used in advertising or otherwise to promote the sale, use + * or other dealings in this Software without prior written authorization + * from said copyright holders. + */ + +/******************************************************************* +** +** ********************************************************* +** * +** * File: psout.h +** * +** * Contents: Include file for psout.c +** * +** * Created By: Roger Helmendach (Liberty Systems) +** * +** * Copyright: Copyright 1996 The Open Group, Inc. +** * +** ********************************************************* +** +********************************************************************/ + +#ifndef _psout_ +#define _psout_ + +#include <stdio.h> + +typedef enum PsCapEnum_ { PsCButt=0, PsCRound, PsCSquare } PsCapEnum; +typedef enum PsJoinEnum_ { PsJMiter=0, PsJRound, PsJBevel } PsJoinEnum; +typedef enum PsArcEnum_ { PsChord, PsPieSlice } PsArcEnum; +typedef enum PsRuleEnum_ { PsEvenOdd, PsNZWinding } PsRuleEnum; +typedef enum PsFillEnum_ { PsSolid=0, PsTile, PsStip, PsOpStip } PsFillEnum; + +typedef struct PsPointRec_ +{ + int x; + int y; +} PsPointRec; + +typedef PsPointRec *PsPointPtr; + +typedef struct PsRectRec_ +{ + int x; + int y; + int w; + int h; +} PsRectRec; + +typedef PsRectRec *PsRectPtr; + +typedef struct PsArcRec_ +{ + int x; + int y; + int w; + int h; + int a1; + int a2; + PsArcEnum style; +} PsArcRec; + +typedef PsArcRec *PsArcPtr; + +#define PSOUT_RECT 0 +#define PSOUT_ARC 1 +#define PSOUT_POINTS 2 + +typedef struct PsElmRec_ +{ + int type; + int nPoints; + union + { + PsRectRec rect; + PsArcRec arc; + PsPointPtr points; + } c; +} PsElmRec; + +typedef PsElmRec *PsElmPtr; + +typedef struct PsClipRec_ +{ + int nRects; + PsRectPtr rects; + int nElms; + PsElmPtr elms; + int nOutterClips; + PsRectPtr outterClips; +} PsClipRec; + +typedef PsClipRec *PsClipPtr; + +typedef struct PsOutRec_ *PsOutPtr; + +extern PsOutPtr PsOut_BeginFile(FILE *fp, int orient, int count, int plex, + int res, int wd, int ht, Bool raw); +extern void PsOut_EndFile(PsOutPtr self, int closeFile); +extern void PsOut_BeginPage(PsOutPtr self, int orient, int count, int plex, + int res, int wd, int ht); +extern void PsOut_EndPage(PsOutPtr self); +extern void PsOut_DirtyAttributes(PsOutPtr self); +extern void PsOut_Comment(PsOutPtr self, char *comment); +extern void PsOut_Offset(PsOutPtr self, int x, int y); + +extern void PsOut_Clip(PsOutPtr self, int clpTyp, PsClipPtr clpinf); + +extern void PsOut_Color(PsOutPtr self, int clr); +extern void PsOut_FillRule(PsOutPtr self, PsRuleEnum rule); +extern void PsOut_LineAttrs(PsOutPtr self, int wd, PsCapEnum cap, + PsJoinEnum join, int nDsh, int *dsh, int dshOff, + int bclr); +extern void PsOut_TextAttrs(PsOutPtr self, char *fnam, int siz, int iso); +extern void PsOut_TextAttrsMtx(PsOutPtr self, char *fnam, float *mtx, int iso); + +extern void PsOut_Polygon(PsOutPtr self, int nPts, PsPointPtr pts); +extern void PsOut_FillRect(PsOutPtr self, int x, int y, int w, int h); +extern void PsOut_FillArc(PsOutPtr self, int x, int y, int w, int h, + float ang1, float ang2, PsArcEnum style); + +extern void PsOut_Lines(PsOutPtr self, int nPts, PsPointPtr pts); +extern void PsOut_Points(PsOutPtr self, int nPts, PsPointPtr pts); +extern void PsOut_DrawRect(PsOutPtr self, int x, int y, int w, int h); +extern void PsOut_DrawArc(PsOutPtr self, int x, int y, int w, int h, + float ang1, float ang2); + +extern void PsOut_Text(PsOutPtr self, int x, int y, char *text, int textl, + int bclr); + +extern void PsOut_BeginImage(PsOutPtr self, int bclr, int fclr, int x, int y, + int w, int h, int sw, int sh, int format); +extern void PsOut_EndImage(PsOutPtr self); +extern void PsOut_OutImageBytes(PsOutPtr self, int nBytes, char *bytes); + +extern void PsOut_BeginFrame(PsOutPtr self, int xoff, int yoff, int x, int y, + int w, int h); +extern void PsOut_EndFrame(PsOutPtr self); + +extern int PsOut_BeginPattern(PsOutPtr self, void *tag, int w, int h, + PsFillEnum type, int bclr, int fclr); +extern void PsOut_EndPattern(PsOutPtr self); +extern void PsOut_SetPattern(PsOutPtr self, void *tag, PsFillEnum type); + +extern void PsOut_RawData(PsOutPtr self, char *data, int len); +extern void PsOut_DownloadType1(PsOutPtr self, char *name, char *fname); + +#endif diff --git a/Xprint/raster/Raster.c b/Xprint/raster/Raster.c new file mode 100644 index 000000000..db72b9b32 --- /dev/null +++ b/Xprint/raster/Raster.c @@ -0,0 +1,1585 @@ +/* $Xorg: Raster.c,v 1.4 2001/03/14 18:46:12 pookie Exp $ */ +/* +(c) Copyright 1996 Hewlett-Packard Company +(c) Copyright 1996 International Business Machines Corp. +(c) Copyright 1996 Sun Microsystems, Inc. +(c) Copyright 1996 Novell, Inc. +(c) Copyright 1996 Digital Equipment Corp. +(c) Copyright 1996 Fujitsu Limited +(c) Copyright 1996 Hitachi, Ltd. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the names of the copyright holders shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from said +copyright holders. +*/ +/******************************************************************* +** +** ********************************************************* +** * +** * File: printer/Raster.c +** * +** * Contents: +** * Raster driver for the print server. +** * +** * Copyright: Copyright 1993, 1995 Hewlett-Packard Company +** * +** ********************************************************* +** +********************************************************************/ + +#include <stdio.h> +#include <string.h> +#include <sys/stat.h> +#include <sys/wait.h> +#include <unistd.h> +#include <sys/types.h> +#include <sys/stat.h> +#include "X.h" +#include "Xos.h" /* for SIGCLD on pre-POSIX systems */ +#define NEED_EVENTS +#include "Xproto.h" +#undef NEED_EVENTS +#include "Xatom.h" +#include "misc.h" +#include "dixstruct.h" +#include "scrnintstr.h" +#include "screenint.h" +#include "colormapst.h" +#include "windowstr.h" +#include "propertyst.h" +#include "servermd.h" /* needed for IMAGE_BUFSIZE */ + +#define _XP_PRINT_SERVER_ +#include "extensions/Print.h" +#undef _XP_PRINT_SERVER_ +#include "Raster.h" + +#include "attributes.h" +#include "AttrValid.h" + +static void AllocateRasterPrivates( + ScreenPtr pScreen); +static Bool RasterChangeWindowAttributes( + WindowPtr pWin, + unsigned long mask); +static int StartJob( + XpContextPtr pCon, + Bool sendClientData); +static int StartPage( + XpContextPtr pCon, + WindowPtr pWin); +static int StartDoc( + XpContextPtr pCon); +static int EndDoc( + XpContextPtr pCon, + Bool cancel); +static int EndJob( + XpContextPtr pCon, + Bool cancel); +static int EndPage( + XpContextPtr pCon, + WindowPtr pWin, + Bool cancel); +static int DocumentData( + XpContextPtr pCon, + DrawablePtr pDraw, + char *pData, + int len_data, + char *pDoc_fmt, + int len_fmt, + char *pOptions, + int len_options, + ClientPtr client); +static int GetDocumentData( + XpContextPtr pContext, + ClientPtr client, + int maxBufferSize); +static void FreePageFiles( + RasterContextPrivPtr pWinPriv); +static int SystemCmd( + char *pCommand); +static Bool RasterCloseScreen( + int index, + ScreenPtr pScreen); +static int RasterInitContext(XpContextPtr pCon); +static Bool RasterDestroyContext(XpContextPtr pCon); +static char *RasterGetAttributes( + XpContextPtr pContext, + XPAttributes class); +static char *RasterGetOneAttribute(XpContextPtr pCon, + XPAttributes class, + char *attribute); +static void RasterSetAttributes(XpContextPtr pCon, + XPAttributes class, + char *attributes); +static void RasterAugmentAttributes(XpContextPtr pCon, + XPAttributes class, + char *attributes); +static int RasterMediumDimensions(XpContextPtr pCon, + CARD16 *width, + CARD16 *height); +static int RasterReproducibleArea(XpContextPtr pCon, + xRectangle *pRect); + +#define MAX(a,b) (((a) > (b)) ? (a) : (b)) +#define DOC_PCL 1 +#define DOC_RASTER 2 + +extern Bool _XpBoolNoop(); +extern void _XpVoidNoop(); +extern void XpDestroyAttributes(); +extern char *ReplaceFileString( + char *string, + char *inFileName, + char *outFileName); +extern char *XpGetConfigDir(); + +extern XpValidatePoolsRec RasterValidatePoolsRec; /* From RasterAttVal.c */ + +static int RasterScreenPrivateIndex, RasterContextPrivateIndex; +static int RasterGeneration = 0; +static char RASTER_DRIV_NAME[] = "XP-RASTER"; +static int doc_type = DOC_RASTER; + +#define ABSOLUTE_PCLCOMP_PATH1 "/usr/openwin/bin/pclcomp" +#define ABSOLUTE_PCLCOMP_PATH2 "/usr/X11/bin/pclcomp" + +static char *pcl3_output_cmds[] = { + "xpr -device ljet -rv -landscape < %(InFile)% | pclcomp -0 > %(OutFile)%", + "xpr -device ljet -rv -landscape < %(InFile)% | pclcomp -01 > %(OutFile)%", + "xpr -device ljet -rv -landscape < %(InFile)% | pclcomp -02 > %(OutFile)%", + "xpr -device ljet -rv -landscape < %(InFile)% | pclcomp -03 > %(OutFile)%", + "xpr -device ljet -rv -landscape < %(InFile)% | pclcomp -012 > %(OutFile)%", + "xpr -device ljet -rv -landscape < %(InFile)% | pclcomp -013 > %(OutFile)%", + "xpr -device ljet -rv -landscape < %(InFile)% | pclcomp -023 > %(OutFile)%", + "xpr -device ljet -rv -landscape < %(InFile)% | pclcomp -0123 > %(OutFile)%", + "xpr -device ljet -rv -landscape < %(InFile)% > %(OutFile)%", + "xpr -device ljet -rv < %(InFile)% | pclcomp -0 > %(OutFile)%", + "xpr -device ljet -rv < %(InFile)% | pclcomp -01 > %(OutFile)%", + "xpr -device ljet -rv < %(InFile)% | pclcomp -02 > %(OutFile)%", + "xpr -device ljet -rv < %(InFile)% | pclcomp -03 > %(OutFile)%", + "xpr -device ljet -rv < %(InFile)% | pclcomp -012 > %(OutFile)%", + "xpr -device ljet -rv < %(InFile)% | pclcomp -013 > %(OutFile)%", + "xpr -device ljet -rv < %(InFile)% | pclcomp -023 > %(OutFile)%", + "xpr -device ljet -rv < %(InFile)% | pclcomp -0123 > %(OutFile)%", + "xpr -device ljet -rv < %(InFile)% > %(OutFile)%"}; + +Bool +InitializeRasterDriver( + int ndx, + ScreenPtr pScreen, + int argc, + char **argv) +{ + char specifier[MAX_TOKEN_LEN]; + int xRes, yRes, maxWidth, maxHeight; + int maxRes, maxDim, numBytes; + RasterScreenPrivPtr pPriv; + XpDriverFuncsPtr pFuncs; + char **printerNames, *printDescFile; + int numPrinters; + + /* + * Register this driver's InitContext function with the print extension. + * This is a bit + * sleazy, as the extension hasn't yet been initialized, but the + * extension needs to know this, and this seems the best time to + * provide the information. + */ + XpRegisterInitFunc( pScreen, RASTER_DRIV_NAME, RasterInitContext ); + + /* + * Create and load the devPrivate for the printer layer. + */ + AllocateRasterPrivates(pScreen); + + pPriv = (RasterScreenPrivPtr) + pScreen->devPrivates[RasterScreenPrivateIndex].ptr; + + maxDim = MAX( pScreen->height, pScreen->width ); + numBytes = maxDim + BITMAP_SCANLINE_PAD - 1; /* pixels per row */ + numBytes *= maxDim; + numBytes /= 8; /* bytes per row */ + xRes = pScreen->width / (pScreen->mmWidth / 25.4); + yRes = pScreen->height / (pScreen->mmHeight / 25.4); + maxRes = MAX( xRes, yRes ); + + pPriv->pBits = (char *)xalloc(numBytes); + + /* + * Have to allocate maxDim X maxDim to allow for landscape mode. + */ + mfbScreenInit(pScreen, pPriv->pBits, maxDim, maxDim, maxRes, + maxRes, maxDim); + pScreen->blackPixel = 1; + pScreen->whitePixel = 0; + if(mfbCreateDefColormap(pScreen) == FALSE) + ; /* XXX what do I do if it fails? */ + + /* + cfbScreenInit(pScreen, pPriv->pBits, maxWidth, maxHeight, maxXres, + maxYres, maxWidth); + scalingScreenInit(pScreen); + */ + + pScreen->SaveScreen = _XpBoolNoop; + pPriv->ChangeWindowAttributes = pScreen->ChangeWindowAttributes; + pScreen->ChangeWindowAttributes = RasterChangeWindowAttributes; + pPriv->CloseScreen = pScreen->CloseScreen; + pScreen->CloseScreen = RasterCloseScreen; + + return TRUE; +} + +/* + * GetPropString searches the context's config database for a property + * by the name of propName. If found, it returns the property's + * value, otherwise it returns NULL unless the requested attribute + * is RASTER_PRINT_PAGE_COMMAND, in which case it returns a hard-coded + * default string to invoke xpr to produce a PostScript(tm) formatted + * raster. + */ + +static char * +GetPropString( + XpContextPtr pCon, + char *propName) +{ + RasterContextPrivPtr pConPriv = (RasterContextPrivPtr) + pCon->devPrivates[RasterContextPrivateIndex].ptr; + char *type; + XrmValue val; + struct stat status; + int pclcomp_exists = 0; + + if( XrmGetResource(pConPriv->config, propName, propName, &type, &val) == + True ) + return (char *)val.addr; + + if( !strcmp( propName, RASTER_PRINT_PAGE_COMMAND ) ) + if( doc_type == DOC_RASTER ) + return "xpr -device ps %(InFile)% > %(OutFile)%"; + else + { + XpOid orientation; + XpOid compression; + int pcl3_output_index = 0; + + orientation = XpGetContentOrientation(pCon); + compression = XpGetAvailableCompression(pCon); + + switch(orientation) { + case xpoid_val_content_orientation_landscape: + pcl3_output_index = 0; + break; + default: + pcl3_output_index += 9; + break; + } + + if(stat(ABSOLUTE_PCLCOMP_PATH1, &status) != -1) + pclcomp_exists = 1; + else if(stat(ABSOLUTE_PCLCOMP_PATH2, &status) != -1) + pclcomp_exists = 1; + + if(pclcomp_exists) + switch(compression) { + case xpoid_val_available_compressions_0: + pcl3_output_index += 0; + break; + case xpoid_val_available_compressions_01: + pcl3_output_index += 1; + break; + case xpoid_val_available_compressions_02: + pcl3_output_index += 2; + break; + case xpoid_val_available_compressions_03: + pcl3_output_index += 3; + break; + case xpoid_val_available_compressions_012: + pcl3_output_index += 4; + break; + case xpoid_val_available_compressions_013: + pcl3_output_index += 5; + break; + case xpoid_val_available_compressions_023: + pcl3_output_index += 6; + break; + default: + pcl3_output_index += 7; + break; + } + else + pcl3_output_index += 8; + + return pcl3_output_cmds[pcl3_output_index]; + } + else + return NULL; +} + +static void +SetDocumentType( + XpContextPtr pCon) +{ + XpOidList* attrs_supported; + + /* + * only validate attributes found in document-attributes-supported + */ + attrs_supported = + XpGetListAttr(pCon, XPPrinterAttr, + xpoid_att_document_attributes_supported, + (const XpOidList*)NULL); + + if(XpOidListHasOid(attrs_supported, xpoid_att_document_format)) + { + const char* value_in; + XpOidDocFmt *f; + + value_in = XpGetStringAttr(pCon, XPDocAttr, xpoid_att_document_format); + + f = XpOidDocFmtNew( value_in ); + + if( f != NULL ) + { + if( !strcmp( f->format, "PCL" ) ) + doc_type = DOC_PCL; + else + doc_type = DOC_RASTER; + + XpOidDocFmtDelete( f ); + } + } + + /* + * clean up + */ + XpOidListDelete(attrs_supported); +} + +static int +StartJob( + XpContextPtr pCon, + Bool sendClientData) +{ + RasterContextPrivPtr pConPriv = (RasterContextPrivPtr) + pCon->devPrivates[RasterContextPrivateIndex].ptr; + char *jobHeader; + + SetDocumentType( pCon ); + + /* + * Check for existing page file, and delete it if it exists. + */ + if(pConPriv->pageFileName != (char *)NULL) + { + if(pConPriv->pPageFile != (FILE *)NULL) + { + fclose(pConPriv->pPageFile); + pConPriv->pPageFile = (FILE *)NULL; + } + unlink(pConPriv->pageFileName); + Xfree(pConPriv->pageFileName); + pConPriv->pageFileName = (char *)NULL; + } + + /* + * Create a temporary file to store the printer output. + */ + if(!sendClientData) + { + /* + * Create a temporary file to store the printer output. + */ + if (!XpOpenTmpFile("w", &pConPriv->jobFileName, &pConPriv->pJobFile)) + return BadAlloc; + } + + return Success; +} + +/* + * StartDoc and EndDoc are just no-ops in this implementation, since + * our view of the spooler really doesn't recognize documents. + */ + +static int +StartDoc( + XpContextPtr pCon) +{ + return Success; +} + +static int EndDoc( + XpContextPtr pCon, + Bool cancel) +{ + return Success; +} + +/* + * BuidArgVector takes a pointer to a comma-separated list of command + * options and splits it out into an array of argument pointers. The + * caller must not free the optionList after calling this function until + * the returned arg vector is no longer needed, at which time the arg + * vector should also be freed. + */ + +#define SEPARATOR_CHAR (char)',' + +static char ** +BuildArgVector( + char *optionList, + char **argVector, + int argCount) +{ + char *curArg, *lastChar, *endArg; + int optionLen; + + curArg = optionList; + lastChar = optionList + strlen(optionList); /* includes final NULL */ + + while(curArg != (char *)NULL && curArg < lastChar) + { + /* strip leading white space */ + while(curArg < lastChar && isascii((int)*curArg) && + isspace((int)*curArg)) + curArg++; + + if(curArg < lastChar) + { + argVector = (char **)Xrealloc(argVector, + sizeof(char *) * (argCount + 2)); + argVector[argCount] = curArg; + argVector[++argCount] = (char *)NULL; + + endArg = strchr(curArg, SEPARATOR_CHAR); + + /* Should I strip trailing white space ??? */ + + if(endArg != (char *)NULL) + { + *endArg = (char)'\0'; + curArg = endArg + 1; + } + else + curArg = (char *)NULL; + } + } + + return argVector; +} + +static int +EndJob( + XpContextPtr pCon, + Bool cancel) +{ + RasterContextPrivPtr pConPriv = (RasterContextPrivPtr) + pCon->devPrivates[RasterContextPrivateIndex].ptr; + + if( cancel == True ) + { + if(pConPriv->getDocClient != (ClientPtr)NULL) { + XpFinishDocData(pConPriv->getDocClient); + + pConPriv->getDocClient = (ClientPtr)NULL; + pConPriv->getDocBufSize = 0; + } + + if(pConPriv->jobFileName != (char *)NULL) + { + unlink(pConPriv->jobFileName); + Xfree(pConPriv->jobFileName); + pConPriv->jobFileName = (char *)NULL; + } + + return Success; + } + + if(pConPriv->getDocClient != (ClientPtr)NULL&&pConPriv->getDocBufSize > 0) + { + XpFinishDocData(pConPriv->getDocClient); + + pConPriv->getDocClient = (ClientPtr)NULL; + pConPriv->getDocBufSize = 0; + + return Success; + } + + if(pConPriv->pJobFile != (FILE *)NULL) + { + fclose(pConPriv->pJobFile); + pConPriv->pJobFile = (FILE *)NULL; + + if(pConPriv->jobFileName != (char *)NULL) + { + XpSubmitJob( pConPriv->jobFileName, pCon ); + unlink(pConPriv->jobFileName); + Xfree(pConPriv->jobFileName); + pConPriv->jobFileName = (char *)NULL; + } + } + + return Success; +} + +/* StartPage + * + * If page file exists + * close page file + * set page file pointer = NULL + * unlink page file + */ +static int +StartPage( + XpContextPtr pCon, + WindowPtr pWin) +{ + register WindowPtr pChild; + RasterContextPrivPtr pConPriv = (RasterContextPrivPtr) + pCon->devPrivates[RasterContextPrivateIndex].ptr; + unsigned short width, height; + xEvent event; + + if(pConPriv->pPageFile != (FILE *)NULL) + { + fclose(pConPriv->pPageFile); + pConPriv->pPageFile = (FILE *)NULL; + } + if(pConPriv->pageFileName != (char *)NULL) + { + unlink(pConPriv->pageFileName); + pConPriv->pageFileName = (char *)NULL; + } + + return Success; +} + +#include "X11/XWDFile.h" + + +#define lowbit(x) ((x) & (~(x) + 1)) + +/* + * Get the XWDColors of all pixels in colormap - returns # of colors + */ +static XWDColor * +Get_XWDColors( + ColormapPtr pCmap) +{ + int i, ncolors; + xrgb *prgbList; + Pixel *pPixels; + XWDColor *colors; + + ncolors = pCmap->pVisual->ColormapEntries; + if (!(colors = (XWDColor *) malloc (sizeof(XWDColor) * ncolors))) + return (XWDColor *) NULL; + if (!(prgbList = (xrgb*) malloc(sizeof(xrgb) * ncolors))) + { + Xfree(colors); + return (XWDColor *) NULL; + } + if (!(pPixels = (Pixel*) malloc(sizeof(Pixel) * ncolors))) + { + Xfree(colors); + Xfree(prgbList); + return (XWDColor *) NULL; + } + + if (pCmap->pVisual->class == DirectColor || + pCmap->pVisual->class == TrueColor) { + Pixel red, green, blue, red1, green1, blue1; + + red = green = blue = 0; + red1 = lowbit(pCmap->pVisual->redMask); + green1 = lowbit(pCmap->pVisual->greenMask); + blue1 = lowbit(pCmap->pVisual->blueMask); + for (i=0; i<ncolors; i++) { + colors[i].pixel = red|green|blue; + colors[i].pad = 0; + red += red1; + if (red > pCmap->pVisual->redMask) + red = 0; + green += green1; + if (green > pCmap->pVisual->greenMask) + green = 0; + blue += blue1; + if (blue > pCmap->pVisual->blueMask) + blue = 0; + } + } else { + for (i=0; i<ncolors; i++) { + colors[i].pixel = i; + colors[i].pad = 0; + } + } + + for(i = 0; i < ncolors; i++) + pPixels[i] = colors[i].pixel; + + QueryColors(pCmap, ncolors, pPixels, prgbList); + Xfree(pPixels); + + for(i = 0; i < ncolors; i++) + { + colors[i].red = prgbList[i].red; + colors[i].green = prgbList[i].green; + colors[i].blue = prgbList[i].blue; + } + Xfree(prgbList); + + return(colors); +} + +static +_swapshort ( + register char *bp, + register unsigned n) +{ + register char c; + register char *ep = bp + n; + + while (bp < ep) { + c = *bp; + *bp = *(bp + 1); + bp++; + *bp++ = c; + } +} + +static +_swaplong ( + register char *bp, + register unsigned n) +{ + register char c; + register char *ep = bp + n; + register char *sp; + + while (bp < ep) { + sp = bp + 3; + c = *sp; + *sp = *bp; + *bp++ = c; + sp = bp + 1; + c = *sp; + *sp = *bp; + *bp++ = c; + bp += 2; + } +} +static int +WriteWindowRaster( + WindowPtr pWin, + FILE *pRasterFile) +{ + long widthBytesLine, length; + int nlines, linesPerBuf, height, linesDone; + char *pBuf; + DrawablePtr pDraw = &pWin->drawable; + XWDFileHeader header; + int win_name_size; + int header_size; + int ncolors, i; + char *win_name; + VisualPtr pVisual; + ColormapPtr pCmap; + XWDColor *pColors; + unsigned long swaptest = 1; + + widthBytesLine = PixmapBytePad(pWin->drawable.width, pWin->drawable.depth); + length = widthBytesLine * pWin->drawable.height; + height = pWin->drawable.height; + + if(length <= 0) + return Success; + + if (widthBytesLine >= IMAGE_BUFSIZE) + linesPerBuf = 1; + else + { + linesPerBuf = IMAGE_BUFSIZE / widthBytesLine; + if (linesPerBuf > height) + linesPerBuf = height; + } + length = linesPerBuf * widthBytesLine; + if (linesPerBuf < height) + { + /* we have to make sure intermediate buffers don't need padding */ + while ((linesPerBuf > 1) && (length & 3)) + { + linesPerBuf--; + length -= widthBytesLine; + } + while (length & 3) + { + linesPerBuf++; + length += widthBytesLine; + } + } + if(!(pBuf = (char *) Xalloc(length))) + return (BadAlloc); + + /* + * Start of Xwd header code. + */ + + /* + * XXX - Should we use the real window name??? + */ + win_name = "xwdump"; + /* sizeof(char) is included for the null string terminator. */ + win_name_size = strlen(win_name) + sizeof(char); + + pCmap = (ColormapPtr)LookupIDByType(wColormap (pWin), RT_COLORMAP); + pVisual = pCmap->pVisual; + if((pColors = Get_XWDColors(pCmap)) == (XWDColor *)NULL) + { + Xfree(pBuf); + return (BadAlloc); + } + + /* + * Write out header information. + */ + header_size = sizeof(header) + win_name_size; + header.header_size = (CARD32) header_size; + header.file_version = (CARD32) XWD_FILE_VERSION; + header.pixmap_format = (CARD32) ZPixmap; /* Must match GetImage below */ + header.pixmap_depth = (CARD32) pDraw->depth; + header.pixmap_width = (CARD32) pDraw->width; + header.pixmap_height = (CARD32) pDraw->height; + header.xoffset = (CARD32) 0; + header.byte_order = (CARD32) screenInfo.imageByteOrder; + header.bitmap_unit = (CARD32) screenInfo.bitmapScanlineUnit; + header.bitmap_bit_order = (CARD32) screenInfo.bitmapBitOrder; + header.bitmap_pad = (CARD32) screenInfo.bitmapScanlinePad; + header.bits_per_pixel = (CARD32) pDraw->bitsPerPixel; + header.bytes_per_line = (CARD32) widthBytesLine; + header.visual_class = (CARD32) pVisual->class; + header.red_mask = (CARD32) pVisual->redMask; + header.green_mask = (CARD32) pVisual->greenMask; + header.blue_mask = (CARD32) pVisual->blueMask; + header.bits_per_rgb = (CARD32) pVisual->bitsPerRGBValue; + header.colormap_entries = (CARD32) pVisual->ColormapEntries; + header.ncolors = ncolors = (CARD32) pVisual->ColormapEntries; + header.window_width = (CARD32) pDraw->width; + header.window_height = (CARD32) pDraw->height; + header.window_x = 0; + header.window_y = 0; + header.window_bdrwidth = (CARD32) 0; + + if (*(char *) &swaptest) { + _swaplong((char *) &header, sizeof(header)); + for (i = 0; i < ncolors; i++) { + _swaplong((char *) &pColors[i].pixel, sizeof(long)); + _swapshort((char *) &pColors[i].red, 3 * sizeof(short)); + } + } + + (void) fwrite((char *)&header, sizeof(header), 1, pRasterFile); + (void) fwrite(win_name, win_name_size, 1, pRasterFile); + (void) fwrite((char *) pColors, sizeof(XWDColor), ncolors, pRasterFile); + + Xfree(pColors); + + /* + * End of Xwd header code. + */ + + linesDone = 0; + while(height - linesDone > 0) + { + nlines = min(linesPerBuf, height - linesDone); + (*pDraw->pScreen->GetImage) (pDraw, + 0, + linesDone, + pWin->drawable.width, + nlines, + ZPixmap, + ~0, + pBuf); + + if(fwrite(pBuf, sizeof(char), (size_t)(nlines * widthBytesLine), + pRasterFile) != + (size_t)(nlines * widthBytesLine)) + { + Xfree(pBuf); + return BadAlloc; + } + linesDone += nlines; + } + Xfree(pBuf); + return Success; +} + + +static int +SendPage( XpContextPtr pCon ) +{ + struct stat statBuf; + RasterContextPrivPtr pConPriv = (RasterContextPrivPtr) + pCon->devPrivates[RasterContextPrivateIndex].ptr; + + if(stat(pConPriv->pageFileName, &statBuf) < 0) + return BadAlloc; + + return XpSendDocumentData(pConPriv->getDocClient, + pConPriv->pPageFile, (int)statBuf.st_size, + pConPriv->getDocBufSize); +} + +/* + * EndPage: + * + * If page file doesn't exist: + * { + * Create page file + * Open page file + * Write page header to page file + * if(preRasterFile exists) + * copy preRasterFile contents to page file + * if(noRasterFile exists) + * write noRasterFile contents to page file + * else + * Create raster image file + * Open raster image file + * GetImage data + * Write Image data to raster image file + * invoke page_command on raster image file + * Write raster image file contents to page file + * Unlink tempPage file + * if(postRasterFile exists) + * write postRasterFile contents to page file + * Write page trailer to page file + * } + * Write page file to job file + */ +static int +EndPage( + XpContextPtr pCon, + WindowPtr pWin, + Bool cancel) +{ + RasterContextPrivPtr pConPriv = (RasterContextPrivPtr) + pCon->devPrivates[RasterContextPrivateIndex].ptr; + struct stat statBuf; + char *rasterFileName = (char *)NULL, *pCommand = (char *)NULL, + *pHeader = (char *)NULL, *pTrailer = (char *)NULL; + FILE *pRasterFile = (FILE *)NULL; + + if( cancel == True ) + return Success; + + if(pConPriv->pageFileName == (char *)NULL) + { + /* + * Open the page file. + */ + if (!XpOpenTmpFile("w+", &pConPriv->pageFileName, + &pConPriv->pPageFile)) + goto BAD_PAGE_ALLOC; + + /* + * Copy any pre-raster document data to the page file. + */ + if(pConPriv->pPreRasterFile != (FILE *)NULL) + { + if(CopyContentsAndDelete(&pConPriv->pPreRasterFile, + &pConPriv->preRasterFileName, + pConPriv->pPageFile) == FALSE) + goto BAD_PAGE_ALLOC; + } + + /* + * Copy either the no-raster document data, or the raster + * data itself to the page file. + * If the no-raster file exists, then we don't process the + * actual window raster bits. + */ + if(pConPriv->pNoRasterFile != (FILE *)NULL) + { + if(CopyContentsAndDelete(&pConPriv->pNoRasterFile, + &pConPriv->noRasterFileName, + pConPriv->pPageFile) == FALSE) + goto BAD_PAGE_ALLOC; + } + else + { + /* + * Open the raster image file. + */ + if (!XpOpenTmpFile("w", &rasterFileName, &pRasterFile)) + goto BAD_PAGE_ALLOC; + + /* + * Write the page image data to the raster image file. + */ + if(WriteWindowRaster(pWin, pRasterFile) != Success) + goto BAD_PAGE_ALLOC; + + /* + * Invoke the page_command on the raster image file. + */ + if((pCommand = GetPropString(pCon, RASTER_PRINT_PAGE_COMMAND)) != + (char *)NULL) + { + char *outFileName; + FILE *pOutFile; + + if (!XpOpenTmpFile("w", &outFileName, &pOutFile)) + goto BAD_PAGE_ALLOC; + fclose(pOutFile); + + pCommand = ReplaceFileString(strdup(pCommand), rasterFileName, + outFileName); + fclose(pRasterFile); + SystemCmd(pCommand); + free(pCommand); + /* + * Delete the unprocessed raster file. + */ + unlink(rasterFileName); + Xfree(rasterFileName); + rasterFileName = outFileName; + if((pRasterFile = fopen(rasterFileName, "r")) == (FILE *)NULL) + goto BAD_PAGE_ALLOC; + } + else + { + fclose(pRasterFile); + if((pRasterFile = fopen(rasterFileName, "r")) == (FILE *)NULL) + goto BAD_PAGE_ALLOC; + } + + /* + * Copy the raster image file contents to the page file. + * Note that pRasterFile must be set to the start of the + * raster file. + */ + if(CopyContentsAndDelete(&pRasterFile, + &rasterFileName, + pConPriv->pPageFile) == FALSE) + goto BAD_PAGE_ALLOC; + } + + /* + * Copy any post-raster document data to the page file. + */ + if(pConPriv->pPostRasterFile != (FILE *)NULL) + { + if(CopyContentsAndDelete(&pConPriv->pPostRasterFile, + &pConPriv->postRasterFileName, + pConPriv->pPageFile) == FALSE) + goto BAD_PAGE_ALLOC; + } + + } + + /* + * Write the page file contents to the job file or to the client + * performing GetDocumentData. + * pConPriv->pPageFile must first be set to the start of the page file. + */ + rewind(pConPriv->pPageFile); + if(stat(pConPriv->pageFileName, &statBuf) < 0) + goto BAD_PAGE_ALLOC; + + /* + * Send the page data to whatever client has called GetDocumentData. + */ + if(pConPriv->getDocClient != (ClientPtr)NULL&&pConPriv->getDocBufSize > 0) + { + int retval; + /* + * We should do something like the following: suspend the + * caller until we can gracefully write all the data in small + * chunks to the receiver, but for now we'll just call WriteToClient + * on the huge chunk + */ + retval = SendPage(pCon); + fclose(pConPriv->pPageFile); + pConPriv->pPageFile = (FILE *)NULL; + unlink(pConPriv->pageFileName); + free(pConPriv->pageFileName); + pConPriv->pageFileName = (char *)NULL; + return retval; + } + + if(pConPriv->pJobFile == (FILE *)NULL) + { + /* + * This shouldn't be necessary. I believe we only get here if + * someone calls "EndPage" prior to "StartJob". This error + * condition should probably be trapped at a higher level. + */ + + if(pConPriv->jobFileName != (char *)NULL) + Xfree(pConPriv->jobFileName); + /* + * Create a temporary file to store the printer output. + */ + if (!XpOpenTmpFile("w", &pConPriv->jobFileName, &pConPriv->pJobFile)) + goto BAD_PAGE_ALLOC; + } + + if(TransferBytes(pConPriv->pPageFile, pConPriv->pJobFile, + (int)statBuf.st_size) != (int)statBuf.st_size) + goto BAD_PAGE_ALLOC; + + fclose(pConPriv->pPageFile); + pConPriv->pPageFile = (FILE *)NULL; + unlink(pConPriv->pageFileName); + free(pConPriv->pageFileName); + pConPriv->pageFileName = (char *)NULL; + + return Success; + + BAD_PAGE_ALLOC: + + FreePageFiles(pConPriv); + + if(pRasterFile != (FILE *)NULL) + fclose(pRasterFile); + if(rasterFileName != (char *)NULL) + { + unlink(rasterFileName); + Xfree(rasterFileName); + } + return BadAlloc; +} + +static int +DocumentData( + XpContextPtr pCon, + DrawablePtr pDraw, + char *pData, + int len_data, + char *pDoc_fmt, + int len_fmt, + char *pOptions, + int len_options, + ClientPtr client) +{ + RasterContextPrivPtr pConPriv = (RasterContextPrivPtr) + pCon->devPrivates[RasterContextPrivateIndex].ptr; + char *preRasterStr = PRE_RASTER, *postRasterStr = POST_RASTER, + *noRasterStr = NO_RASTER; + + /* + * Check that options equals either PRE_RASTER or POST_RASTER. + */ + if(len_options == strlen(preRasterStr) && + strncmp(pOptions, preRasterStr, strlen(preRasterStr)) == 0) + { + if(pConPriv->pPreRasterFile == (FILE *)NULL) + { + if (!XpOpenTmpFile("w+", &pConPriv->preRasterFileName, + &pConPriv->pPreRasterFile)) + return BadAlloc; + } + if(fwrite(pData, sizeof(char), (size_t)len_data, + pConPriv->pPreRasterFile) != (size_t)len_data) + return BadAlloc; + fflush(pConPriv->pPreRasterFile); + } + else if(len_options == strlen(postRasterStr) && + strncmp(pOptions, postRasterStr, strlen(postRasterStr)) == 0) + { + if(pConPriv->pPostRasterFile == (FILE *)NULL) + { + if (!XpOpenTmpFile("w+", &pConPriv->postRasterFileName, + &pConPriv->pPostRasterFile)) + return BadAlloc; + } + if(fwrite(pData, sizeof(char), (size_t)len_data, + pConPriv->pPostRasterFile) != (size_t)len_data) + return BadAlloc; + fflush(pConPriv->pPostRasterFile); + } + else if(len_options == strlen(noRasterStr) && + strncmp(pOptions, noRasterStr, strlen(noRasterStr)) == 0) + { + if(pConPriv->pNoRasterFile == (FILE *)NULL) + { + if (!XpOpenTmpFile("w+", &pConPriv->noRasterFileName, + &pConPriv->pNoRasterFile)) + return BadAlloc; + } + if(fwrite(pData, sizeof(char), (size_t)len_data, + pConPriv->pNoRasterFile) != (size_t)len_data) + return BadAlloc; + fflush(pConPriv->pNoRasterFile); + } + else + return BadValue; + + return Success; +} + +/* + * GetDocumentData notes which client is requesting the document data for + * a particular context. The Raster driver's EndPage function causes the + * data to be written to the proper client. + */ +static int +GetDocumentData( + XpContextPtr pContext, + ClientPtr client, + int maxBufferSize) +{ + RasterContextPrivPtr pConPriv = (RasterContextPrivPtr) + pContext->devPrivates[RasterContextPrivateIndex].ptr; + + pConPriv->getDocClient = client; + pConPriv->getDocBufSize = maxBufferSize; + return Success; +} + +static void +AllocateRasterPrivates( + ScreenPtr pScreen) +{ + if(RasterGeneration != serverGeneration) + { + RasterScreenPrivateIndex = AllocateScreenPrivateIndex(); + RasterContextPrivateIndex = XpAllocateContextPrivateIndex(); + XpAllocateContextPrivate( RasterContextPrivateIndex, + sizeof( RasterContextPrivRec ) ); + + RasterGeneration = serverGeneration; + } + pScreen->devPrivates[RasterScreenPrivateIndex].ptr = (pointer)Xalloc( + sizeof(RasterScreenPrivRec)); +} + +/* + * RasterChangeWindowAttributes - Make sure that the window's backing + * store is turned on. + */ +static Bool +RasterChangeWindowAttributes( + WindowPtr pWin, + unsigned long mask) +{ + Bool status = Success; + ScreenPtr pScreen = pWin->drawable.pScreen; + RasterScreenPrivPtr pScreenPriv = (RasterScreenPrivPtr) + pScreen->devPrivates[RasterScreenPrivateIndex].ptr; + + if(pWin->backingStore == NotUseful) + { + pWin->backingStore = WhenMapped; + mask |= CWBackingStore; + } + + if(pScreenPriv->ChangeWindowAttributes != (Bool (*)())NULL) + { + pScreen->ChangeWindowAttributes = pScreenPriv->ChangeWindowAttributes; + status = pScreen->ChangeWindowAttributes(pWin, mask); + pScreen->ChangeWindowAttributes = RasterChangeWindowAttributes; + } + if(status != TRUE) + return status; +} + +/* + * RasterValidateDocFormats - Inspects the files available in the + * ddx-config/XP-RASTER directory to find the names of PDLs for which + * we have processing commands. These names are then intersected with + * the contents of the printer's document-formats-supported attribute, + * and the result is stored back into document-formats-supported. + * We have hard-coded knowledge of how to produce PS, so we always + * leave that in, if it's listed in document-formats-supported, + * even if we don't have a configuration file. If there is a + * configuration file for PS, then its contents will override our default. + */ +static void +RasterValidateDocFormats( + XpContextPtr pCon) +{ +} + +/* + * RasterValidateAttrs - Inspects and Corrects the attribute values + * in the specified context. + */ +static void +RasterValidateAttrs( + XpContextPtr pCon) +{ + RasterValidateDocFormats(pCon); + XpValidatePrinterPool(pCon, &RasterValidatePoolsRec); + XpValidateJobPool(pCon, &RasterValidatePoolsRec); + XpValidateDocumentPool(pCon, &RasterValidatePoolsRec); +} + +/* + * RasterInitContext - Establish the appropriate values for a + * PrintContext used with the Raster Driver. + */ +static char DOC_ATT_SUPP[]="document-attributes-supported:\tdefault-medium document-format"; +static char JOB_ATT_SUPP[]="job-attributes-supported:\t"; +static char DDX_DIR[]="ddx-config"; + +static int +RasterInitContext( + XpContextPtr pCon) +{ + char *configFileName, *val, *attrStr; + RasterContextPrivPtr pConPriv; + XpDriverFuncsPtr pFuncs; + + /* + * Initialize the attribute store for this printer. + */ + XpInitAttributes( pCon ); + + /* + * Validate the attributes + */ + RasterValidateAttrs( pCon ); + + + /* + * Initialize the function pointers + */ + pFuncs = &( pCon->funcs ); + pFuncs->StartJob = StartJob; + pFuncs->EndJob = EndJob; + pFuncs->StartDoc = StartDoc; + pFuncs->EndDoc = EndDoc; + pFuncs->StartPage = StartPage; + pFuncs->EndPage = EndPage; + pFuncs->PutDocumentData = DocumentData; + pFuncs->GetDocumentData = GetDocumentData; + pFuncs->DestroyContext = RasterDestroyContext; + pFuncs->GetAttributes = (char *(*)())RasterGetAttributes; + pFuncs->GetOneAttribute = (char *(*)())RasterGetOneAttribute; + pFuncs->SetAttributes = (int(*)())RasterSetAttributes; + pFuncs->AugmentAttributes = (int(*)())RasterAugmentAttributes; + pFuncs->GetMediumDimensions = (int(*)())RasterMediumDimensions; + pFuncs->GetReproducibleArea = (int(*)())RasterReproducibleArea; + + /* + * Set up the context privates + */ + pConPriv = (RasterContextPrivPtr) + pCon->devPrivates[RasterContextPrivateIndex].ptr; + + pConPriv->jobFileName = (char *)NULL; + pConPriv->pageFileName = (char *)NULL; + pConPriv->preRasterFileName = (char *)NULL; + pConPriv->postRasterFileName = (char *)NULL; + pConPriv->noRasterFileName = (char *)NULL; + pConPriv->pJobFile = (FILE *)NULL; + pConPriv->pPageFile = (FILE *)NULL; + pConPriv->pPreRasterFile = (FILE *)NULL; + pConPriv->pPostRasterFile = (FILE *)NULL; + pConPriv->pNoRasterFile = (FILE *)NULL; + + pConPriv->getDocClient = (ClientPtr)NULL; + pConPriv->getDocBufSize = 0; + + /* + * Get the configuration information for the context's printer + */ + configFileName = XpGetOneAttribute( pCon, XPPrinterAttr, + "xp-ddx-config-file-name" ); + if(configFileName && strlen(configFileName)) + { + if( configFileName[0] == '/' ) + pConPriv->config = XrmGetFileDatabase( configFileName ); + else + { + char *configDir, *configFilePath; + + configDir = XpGetConfigDir(FALSE); + configFilePath = (char *)malloc((strlen(configDir) + + strlen(DDX_DIR) + + strlen(RASTER_DRIV_NAME) + + strlen(configFileName) + + 4)* sizeof(char)); + sprintf(configFilePath, "%s/%s/%s/%s", configDir, DDX_DIR, + RASTER_DRIV_NAME, configFileName); + pConPriv->config = XrmGetFileDatabase(configFilePath); + free(configDir); + free(configFilePath); + } + } + else + pConPriv->config = (XrmDatabase)NULL; + + /* + * Add our own attribute initialization + */ + /* + * document-attributes-supported + */ + val = XpGetOneAttribute(pCon, XPServerAttr, "document-attributes-supported"); + if((attrStr = (char *)xalloc(strlen(val) + strlen(DOC_ATT_SUPP) + 4)) == + (char *)NULL) + return BadAlloc; + sprintf(attrStr, "*%s %s", DOC_ATT_SUPP, val); + XpAugmentAttributes(pCon, XPPrinterAttr, attrStr); + xfree(attrStr); + + /* + * job-attributes-supported + */ + val = XpGetOneAttribute(pCon, XPServerAttr, "job-attributes-supported"); + if((attrStr = (char *)xalloc(strlen(val) + strlen(JOB_ATT_SUPP) + 4)) == + (char *)NULL) + return BadAlloc; + sprintf(attrStr, "*%s %s", JOB_ATT_SUPP, val); + XpAugmentAttributes(pCon, XPPrinterAttr, attrStr); + xfree(attrStr); + + /* + * PageAttributesSupported + */ + XpAugmentAttributes(pCon, XPPrinterAttr, "*xp-page-attributes-supported:"); + + return Success; +} + + + +static Bool +RasterDestroyContext( + XpContextPtr pCon) +{ + RasterContextPrivPtr pConPriv = (RasterContextPrivPtr) + pCon->devPrivates[RasterContextPrivateIndex].ptr; + + /* + * Clean up the temporary files + */ + FreePageFiles( pConPriv ); + + if( pConPriv->pJobFile != (FILE *)NULL ) + { + fclose( pConPriv->pJobFile ); + pConPriv->pJobFile = (FILE *)NULL; + } + if( pConPriv->jobFileName != (char *)NULL ) + { + unlink( pConPriv->jobFileName ); + Xfree( pConPriv->jobFileName ); + } + if(pConPriv->config) + { + XrmDestroyDatabase(pConPriv->config); + pConPriv->config = (XrmDatabase)NULL; + } + + XpDestroyAttributes( pCon ); + return Success; +} + +static char * +RasterGetAttributes( + XpContextPtr pContext, + XPAttributes class) +{ + return XpGetAttributes( pContext, class ); +} + +static char * +RasterGetOneAttribute( + XpContextPtr pContext, + XPAttributes class, + char *attr) +{ + return XpGetOneAttribute( pContext, class, attr ); +} + +static void +RasterSetAttributes(XpContextPtr pCon, + XPAttributes class, + char *attributes) +{ + XpSetAttributes( pCon, class, attributes ); +} + +static void +RasterAugmentAttributes( + XpContextPtr pCon, + XPAttributes class, + char *attributes) +{ + XpAugmentAttributes( pCon, class, attributes ); +} + +static void +FreePageFiles( + RasterContextPrivPtr pConPriv) +{ + if(pConPriv->pPageFile != (FILE *)NULL) + { + fclose(pConPriv->pPageFile); + pConPriv->pPageFile = (FILE *)NULL; + } + if(pConPriv->pageFileName != (char *)NULL) + { + unlink(pConPriv->pageFileName); + Xfree(pConPriv->pageFileName); + pConPriv->pageFileName = (char *)NULL; + } + if(pConPriv->pPreRasterFile != (FILE *)NULL) + { + fclose(pConPriv->pPreRasterFile); + pConPriv->pPreRasterFile = (FILE *)NULL; + } + if(pConPriv->preRasterFileName != (char *)NULL) + { + unlink(pConPriv->preRasterFileName); + Xfree(pConPriv->preRasterFileName); + pConPriv->preRasterFileName = (char *)NULL; + } + if(pConPriv->pPostRasterFile != (FILE *)NULL) + { + fclose(pConPriv->pPostRasterFile); + pConPriv->pPostRasterFile = (FILE *)NULL; + } + if(pConPriv->postRasterFileName != (char *)NULL) + { + unlink(pConPriv->postRasterFileName); + Xfree(pConPriv->postRasterFileName); + pConPriv->postRasterFileName = (char *)NULL; + } + if(pConPriv->pNoRasterFile != (FILE *)NULL) + { + fclose(pConPriv->pNoRasterFile); + pConPriv->pNoRasterFile = (FILE *)NULL; + } + if(pConPriv->noRasterFileName != (char *)NULL) + { + unlink(pConPriv->noRasterFileName); + Xfree(pConPriv->noRasterFileName); + pConPriv->noRasterFileName = (char *)NULL; + } +} + +/* + * RasterCloseScreen - Call any wrapped CloseScreen function, + * and free the screen memory. + */ +static Bool +RasterCloseScreen( + int index, + ScreenPtr pScreen) +{ + Bool status = Success; + RasterScreenPrivPtr pScreenPriv = (RasterScreenPrivPtr) + pScreen->devPrivates[RasterScreenPrivateIndex].ptr; + + /* + * Call any wrapped CloseScreen proc. + */ + if(pScreenPriv->CloseScreen != (Bool (*)())NULL) + { + pScreen->CloseScreen = pScreenPriv->CloseScreen; + status = pScreen->CloseScreen(index, pScreen); + pScreen->CloseScreen = RasterCloseScreen; + } + + Xfree(pScreenPriv->pBits); + Xfree(pScreenPriv); + + return status; +} + +#include <signal.h> + +/* ARGSUSED */ +static void SigchldHndlr (int dummy) +{ + int status, w; + struct sigaction act; + sigfillset(&act.sa_mask); + act.sa_flags = 0; + act.sa_handler = SigchldHndlr; + + w = wait (&status); + + /* + * Is this really necessary? + */ + sigaction(SIGCHLD, &act, (struct sigaction *)NULL); +} + +/* + * SystemCmd provides a wrapper for the 'system' library call. The call + * appears to be sensitive to the handling of SIGCHLD, so this wrapper + * sets the status to SIG_DFL, and then resets the established handler + * after system returns. + */ +static int +SystemCmd(char *cmdStr) +{ + int status; + struct sigaction newAct, oldAct; + sigfillset(&newAct.sa_mask); + newAct.sa_flags = 0; + newAct.sa_handler = SIG_DFL; + sigfillset(&oldAct.sa_mask); + oldAct.sa_flags = 0; + oldAct.sa_handler = SigchldHndlr; + + /* + * get the old handler, and set the action to IGN + */ + sigaction(SIGCHLD, &newAct, &oldAct); + + status = system (cmdStr); + + sigaction(SIGCHLD, &oldAct, (struct sigaction *)NULL); + return status; +} + +/* + * RasterMediumDimensions is installed in the GetMediumDimensions field + * of each raster-initialized context. + */ +static int +RasterMediumDimensions(XpContextPtr pCon, + CARD16 *width, + CARD16 *height) +{ + XpGetMediumDimensions(pCon, width, height); + return Success; +} + +/* + * RasterReproducibleArea is installed in the GetReproducibleArea field + * of each raster-initialized context. + */ +static int +RasterReproducibleArea(XpContextPtr pCon, + xRectangle *pRect) +{ + XpGetReproductionArea(pCon, pRect); + return Success; +} diff --git a/Xprint/raster/Raster.h b/Xprint/raster/Raster.h new file mode 100644 index 000000000..b793f89a0 --- /dev/null +++ b/Xprint/raster/Raster.h @@ -0,0 +1,106 @@ +/* $Xorg: Raster.h,v 1.3 2000/08/17 19:48:12 cpqbld Exp $ */ +/* +(c) Copyright 1996 Hewlett-Packard Company +(c) Copyright 1996 International Business Machines Corp. +(c) Copyright 1996 Sun Microsystems, Inc. +(c) Copyright 1996 Novell, Inc. +(c) Copyright 1996 Digital Equipment Corp. +(c) Copyright 1996 Fujitsu Limited +(c) Copyright 1996 Hitachi, Ltd. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the names of the copyright holders shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from said +copyright holders. +*/ +/******************************************************************* +** +** ********************************************************* +** * +** * File: printer/Raster.h +** * +** * Contents: defines and includes for the raster layer +** * for a printing X server. +** * +** * Copyright: Copyright 1993 Hewlett-Packard Company +** * +** ********************************************************* +** +********************************************************************/ +#ifndef _RASTER_H_ +#define _RASTER_H_ + +/* + * Some sleazes to force the XrmDB stuff into the server + */ +typedef char *XPointer; +#define Status int +#define True 1 +#define False 0 +#include "misc.h" +#include <Xfuncproto.h> +#include "../Xresource.h" + +#define _XP_PRINT_SERVER_ +#include "extensions/Printstr.h" +#undef _XP_PRINT_SERVER_ + +#define MAX_TOKEN_LEN 512 + +#define RASTER_PRINT_PAGE_COMMAND "_XP_RASTER_PAGE_PROC_COMMAND" + +#define RASTER_IN_FILE_STRING "%(InFile)%" +#define RASTER_OUT_FILE_STRING "%(OutFile)%" + +#define RASTER_ALLOWED_COMMANDS_FILE "printCommands" + +/* + * Defines for the "options" in DtPrintDocumentData. + */ +#define PRE_RASTER "PRE-RASTER" +#define POST_RASTER "POST-RASTER" +#define NO_RASTER "NO-RASTER" + + +typedef struct { + char *pBits; + Bool (* CreateWindow)(); /* pWin */ + Bool (* ChangeWindowAttributes)(); /* pWin, mask */ + Bool (* DestroyWindow)(); /* pWin */ + Bool (* CloseScreen)(); /* index, pScreen */ +} RasterScreenPrivRec, *RasterScreenPrivPtr; + +typedef struct { + XrmDatabase config; + char *jobFileName; + FILE *pJobFile; + char *pageFileName; + FILE *pPageFile; + char *preRasterFileName; /* Pre-raster document data */ + FILE *pPreRasterFile; + char *noRasterFileName; /* Raster replacement document data */ + FILE *pNoRasterFile; + char *postRasterFileName; /* Post-raster document data */ + FILE *pPostRasterFile; + ClientPtr getDocClient; + int getDocBufSize; +} RasterContextPrivRec, *RasterContextPrivPtr; + +#endif /* _RASTER_H_ */ diff --git a/Xprint/raster/RasterAttVal.c b/Xprint/raster/RasterAttVal.c new file mode 100644 index 000000000..f76a890d3 --- /dev/null +++ b/Xprint/raster/RasterAttVal.c @@ -0,0 +1,265 @@ +/* $Xorg: RasterAttVal.c,v 1.4 2001/03/14 18:46:34 pookie Exp $ */ +/* +(c) Copyright 1996 Hewlett-Packard Company +(c) Copyright 1996 International Business Machines Corp. +(c) Copyright 1996 Sun Microsystems, Inc. +(c) Copyright 1996 Novell, Inc. +(c) Copyright 1996 Digital Equipment Corp. +(c) Copyright 1996 Fujitsu Limited +(c) Copyright 1996 Hitachi, Ltd. + +Permission is hereby granted, free of charge, to any person obtaining a copy +of this software and associated documentation files (the "Software"), to deal +in the Software without restriction, including without limitation the rights +to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +copies of the Software, and to permit persons to whom the Software is +furnished to do so, subject to the following conditions: + +The above copyright notice and this permission notice shall be included in +all copies or substantial portions of the Software. + +THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER +IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN +CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE. + +Except as contained in this notice, the names of the copyright holders shall +not be used in advertising or otherwise to promote the sale, use or other +dealings in this Software without prior written authorization from said +copyright holders. +*/ +#include <stdio.h> +#include "X.h" +#include "misc.h" +#include "dixstruct.h" +#include "scrnintstr.h" +#include "screenint.h" +#define _XP_PRINT_SERVER_ +#include "extensions/Print.h" +#undef _XP_PRINT_SERVER_ +#include "Raster.h" + +#include "attributes.h" +#include "AttrValid.h" + +/* + * define valid values and defaults for Printer pool + */ +static XpOid ValidContentOrientationsOids[] = { + xpoid_val_content_orientation_portrait, + xpoid_val_content_orientation_landscape +}; +static XpOidList ValidContentOrientations = { + ValidContentOrientationsOids, XpNumber(ValidContentOrientationsOids) +}; + +static XpOid DefaultContentOrientationsOids[] = { + xpoid_val_content_orientation_portrait, + xpoid_val_content_orientation_landscape +}; +static XpOidList DefaultContentOrientations = { + DefaultContentOrientationsOids, XpNumber(DefaultContentOrientationsOids) +}; + +static XpOid ValidPlexesOids[] = { + xpoid_val_plex_simplex +}; +static XpOidList ValidPlexes = { + ValidPlexesOids, XpNumber(ValidPlexesOids) +}; + +static XpOid DefaultPlexesOids[] = { + xpoid_val_plex_simplex +}; +static XpOidList DefaultPlexes = { + DefaultPlexesOids, XpNumber(DefaultPlexesOids) +}; + +static unsigned long ValidPrinterResolutionsCards[] = { + 150, 300, 600 +}; +static XpOidCardList ValidPrinterResolutions = { + ValidPrinterResolutionsCards, XpNumber(ValidPrinterResolutionsCards) +}; + +static unsigned long DefaultPrinterResolutionsCards[] = { + 300 +}; +static XpOidCardList DefaultPrinterResolutions = { + DefaultPrinterResolutionsCards, XpNumber(DefaultPrinterResolutionsCards) +}; + +static XpOid ValidListfontsModesOids[] = { + xpoid_val_xp_list_glyph_fonts +}; +static XpOidList ValidListfontsModes = { + ValidListfontsModesOids, XpNumber(ValidListfontsModesOids) +}; + +static XpOid DefaultListfontsModesOids[] = { + xpoid_val_xp_list_glyph_fonts +}; +static XpOidList DefaultListfontsModes = { + DefaultListfontsModesOids, XpNumber(DefaultListfontsModesOids) +}; + +static XpOid ValidSetupProvisoOids[] = { + xpoid_val_xp_setup_mandatory, xpoid_val_xp_setup_optional +}; +static XpOidList ValidSetupProviso = { + ValidSetupProvisoOids, XpNumber(ValidSetupProvisoOids) +}; + +static XpOidDocFmt ValidDocFormatsSupportedFmts[] = { + { "Postscript", "2", NULL }, + { "PCL", "3", NULL } +}; +static XpOidDocFmtList ValidDocFormatsSupported = { + ValidDocFormatsSupportedFmts, XpNumber(ValidDocFormatsSupportedFmts) +}; + +static XpOidDocFmt DefaultDocFormatsSupportedFmts[] = { + { "Postscript", "2", NULL } +}; +static XpOidDocFmtList DefaultDocFormatsSupported = { + DefaultDocFormatsSupportedFmts, XpNumber(DefaultDocFormatsSupportedFmts) +}; + +static XpOidDocFmtList ValidEmbeddedFormatsSupported = { + (XpOidDocFmt *)NULL, 0 +}; + +static XpOidDocFmtList DefaultEmbeddedFormatsSupported = { + (XpOidDocFmt *)NULL, 0 +}; + +static XpOidDocFmt ValidRawFormatsSupportedFmts[] = { + { "Postscript", "2", NULL }, + { "PCL", "3", NULL } +}; +static XpOidDocFmtList ValidRawFormatsSupported = { + ValidRawFormatsSupportedFmts, XpNumber(ValidRawFormatsSupportedFmts) +}; + +static XpOidDocFmt DefaultRawFormatsSupportedFmts[] = { + { "Postscript", "2", NULL } +}; +static XpOidDocFmtList DefaultRawFormatsSupported = { + DefaultRawFormatsSupportedFmts, XpNumber(DefaultRawFormatsSupportedFmts) +}; + +static XpOidList ValidInputTrays = { + (XpOid *)NULL, 0 +}; + +static XpOid ValidMediumSizesOids[] = { + xpoid_val_medium_size_iso_a0, + xpoid_val_medium_size_iso_a1, + xpoid_val_medium_size_iso_a2, + xpoid_val_medium_size_iso_a3, + xpoid_val_medium_size_iso_a4, + xpoid_val_medium_size_iso_a5, + xpoid_val_medium_size_iso_a6, + xpoid_val_medium_size_iso_a7, + xpoid_val_medium_size_iso_a8, + xpoid_val_medium_size_iso_a9, + xpoid_val_medium_size_iso_a10, + xpoid_val_medium_size_iso_b0, + xpoid_val_medium_size_iso_b1, + xpoid_val_medium_size_iso_b2, + xpoid_val_medium_size_iso_b3, + xpoid_val_medium_size_iso_b4, + xpoid_val_medium_size_iso_b5, + xpoid_val_medium_size_iso_b6, + xpoid_val_medium_size_iso_b7, + xpoid_val_medium_size_iso_b8, + xpoid_val_medium_size_iso_b9, + xpoid_val_medium_size_iso_b10, + xpoid_val_medium_size_na_letter, + xpoid_val_medium_size_na_legal, + xpoid_val_medium_size_executive, + xpoid_val_medium_size_folio, + xpoid_val_medium_size_invoice, + xpoid_val_medium_size_ledger, + xpoid_val_medium_size_quarto, + xpoid_val_medium_size_iso_c3, + xpoid_val_medium_size_iso_c4, + xpoid_val_medium_size_iso_c5, + xpoid_val_medium_size_iso_c6, + xpoid_val_medium_size_iso_designated_long, + xpoid_val_medium_size_na_10x13_envelope, + xpoid_val_medium_size_na_9x12_envelope, + xpoid_val_medium_size_na_number_10_envelope, + xpoid_val_medium_size_na_7x9_envelope, + xpoid_val_medium_size_na_9x11_envelope, + xpoid_val_medium_size_na_10x14_envelope, + xpoid_val_medium_size_na_number_9_envelope, + xpoid_val_medium_size_monarch_envelope, + xpoid_val_medium_size_a, + xpoid_val_medium_size_b, + xpoid_val_medium_size_c, + xpoid_val_medium_size_d, + xpoid_val_medium_size_e, + xpoid_val_medium_size_jis_b0, + xpoid_val_medium_size_jis_b1, + xpoid_val_medium_size_jis_b2, + xpoid_val_medium_size_jis_b3, + xpoid_val_medium_size_jis_b4, + xpoid_val_medium_size_jis_b5, + xpoid_val_medium_size_jis_b6, + xpoid_val_medium_size_jis_b7, + xpoid_val_medium_size_jis_b8, + xpoid_val_medium_size_jis_b9, + xpoid_val_medium_size_jis_b10 +}; +static XpOidList ValidMediumSizes = { + ValidMediumSizesOids, XpNumber(ValidMediumSizesOids) +}; + +static XpOidDocFmt DefaultDocumentFormat = { + "Postscript", "2", NULL +}; + +static XpOid ValidAvailableCompressionsOids[] = { + xpoid_val_available_compressions_0, + xpoid_val_available_compressions_01, + xpoid_val_available_compressions_02, + xpoid_val_available_compressions_03, + xpoid_val_available_compressions_012, + xpoid_val_available_compressions_013, + xpoid_val_available_compressions_023, + xpoid_val_available_compressions_0123 +}; + +static XpOidList ValidAvailableCompressions = { + ValidAvailableCompressionsOids, XpNumber(ValidAvailableCompressionsOids) +}; + +static XpOid DefaultAvailableCompressionsOids[] = { + xpoid_val_available_compressions_0123, + xpoid_val_available_compressions_0 +}; + +static XpOidList DefaultAvailableCompressions = { + DefaultAvailableCompressionsOids, XpNumber(DefaultAvailableCompressionsOids) +}; + + +/* + * init struct for XpValidate*Pool + */ +XpValidatePoolsRec RasterValidatePoolsRec = { + &ValidContentOrientations, &DefaultContentOrientations, + &ValidDocFormatsSupported, &DefaultDocFormatsSupported, + &ValidInputTrays, &ValidMediumSizes, + &ValidPlexes, &DefaultPlexes, + &ValidPrinterResolutions, &DefaultPrinterResolutions, + &ValidEmbeddedFormatsSupported, &DefaultEmbeddedFormatsSupported, + &ValidListfontsModes, &DefaultListfontsModes, + &ValidRawFormatsSupported, &DefaultRawFormatsSupported, + &ValidSetupProviso, + &DefaultDocumentFormat, + &ValidAvailableCompressions, &DefaultAvailableCompressions +}; |