#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"
#include "DiPrint.h"
#include "attributes.h"
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}
};
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;
resolutions_supported =
XpGetCardListAttr(pContext, XPPrinterAttr,
xpoid_att_printer_resolutions_supported,
(XpOidCardList*)NULL);
resolution = XpOidCardListGetCard(resolutions_supported, 0);
XpOidCardListDelete(resolutions_supported);
}
return (int)resolution;
}
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;
}
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;
}
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;
}
XpOid
XpGetPageSize(XpContextPtr pContext,
XpOid* pTray,
const XpOidMediumSS* msss)
{
XpOid medium;
medium = XpGetOidAttr(pContext, XPPageAttr, xpoid_att_default_medium,
(const XpOidList*)NULL);
if(medium == xpoid_none)
{
medium = XpGetOidAttr(pContext, XPDocAttr, xpoid_att_default_medium,
(const XpOidList*)NULL);
}
if(medium == xpoid_none)
{
*pTray = XpGetOidAttr(pContext, XPPageAttr,
xpoid_att_default_input_tray,
(const XpOidList*)NULL);
if(*pTray == xpoid_none)
{
*pTray = XpGetOidAttr(pContext, XPDocAttr,
xpoid_att_default_input_tray,
(const XpOidList*)NULL);
}
if(*pTray != xpoid_none)
{
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;
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;
}
void
XpGetMediumMillimeters(
XpOid page_size,
float *width,
float *height)
{
unsigned 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;
}
}
}
static float
MmToPixels(float mm, int resolution)
{
float f;
f = mm * resolution;
f /= 25.4;
return f;
}
void
XpGetMediumDimensions(
XpContextPtr pContext,
unsigned short *width,
unsigned short *height)
{
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)
{
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:
*height = MmToPixels(w_mm, resolution);
*width = MmToPixels(h_mm, resolution);
break;
default:
*width = MmToPixels(w_mm, resolution);
*height = MmToPixels(h_mm, resolution);
break;
}
}
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:
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;
}
}
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;
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)
{
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
{
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)
{
done = xTrue;
}
break;
}
}
}
}
}
XpOidMediumSSDelete(msss);
}
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;
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);
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(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(ClientPtr client)
{
client->fontResFunc = XpGetClientResolutions;
}
void XpUnsetFontResFunc(ClientPtr client)
{
client->fontResFunc = NULL;
}