home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Crawly Crypt Collection 2
/
crawlyvol2.bin
/
apps
/
dtp
/
ghost
/
gs301src
/
atari
/
gp_atar1.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-09-17
|
19KB
|
777 lines
/* Copyright (C) 1989, 1992, 1993 Aladdin Enterprises. All rights reserved.
This file is part of Ghostscript.
Ghostscript is distributed in the hope that it will be useful, but
WITHOUT ANY WARRANTY. No author or distributor accepts responsibility
to anyone for the consequences of using it or for whether it serves any
particular purpose or works at all, unless he says so in writing. Refer
to the Ghostscript General Public License for full details.
Everyone is granted permission to copy, modify and redistribute
Ghostscript, but only under the conditions described in the Ghostscript
General Public License. A copy of this license is supposed to have been
given to you along with Ghostscript so you can know your rights and
responsibilities. It should be in a file named COPYING. Among other
things, the copyright notice and this notice must be preserved on all
copies. */
/* gp_atar1.c */
/*
* Atari-specific routines for Ghostscript. This file contains the
* standard suite of gp_* routines called by Ghostscript plus
* a few utility functions used by them.
*
* GEM initialization is performed in gp_init.
*/
#include "gp_atar1.h"
/* External routines */
extern FILE *popen(P2(const char *, const char *));
extern int pclose(P1(FILE *));
extern void gs_exit(P1(int exit_status)); /* from gsmain.c */
extern WINLIST *WinListAdd(); /* from gp_atar3.c */
extern WINLIST *WinListDelete(); /* from gp_atar3.c */
/* External Variables */
extern WINLIST *WList; /* from gp_atar2.c */
extern WINDOW conswin; /* from gp_atar2.c */
extern WINDOW aboutwin, reswin, pagewin; /* from gp_atar2.c */
extern WINDOW iconwin, devwin, sizwin, printwin;/* from gp_atar2.c */
extern EVENT Event; /* from gp_atar2.c */
/* Global Variables */
/* Virtual Workstation Structure. */
VWRK VWork = {
0, /* VdiHandle */
0, /* XRes */
0, /* YRes */
0, /* AspectRatio */
{0, 0, 0, 0}, /* full */
0, /* ColorBits */
0, /* MaxRGB */
0, /* TrueColor */
0, /* PaletteSize */
0, /* GSPalette */
0, /* Palette */
0, /* OldPalette */
0, /* ColorReg */
0, /* Character cell width */
0, /* Character cell height */
0, /* Character box width */
0 /* Character box height */
};
DOCUMENT document; /* Contains PS document information. */
/* Program State Structure. */
PSTATE State = {
0, /* ApId */
0, /* MultiTOS */
1, /* Windows */
0, /* TopWin */
0, /* PSHelp */
0, /* SelectPages */
FIRSTDEV, /* Device */
FIRSTDEV, /* LastDevice */
"", /* CurrentDir[] */
"", /* DirSpec[] */
"", /* FileSel[] */
"", /* Infile[] */
"", /* Outfile[] */
"", /* Command[] */
"", /* DevString[] */
1, /* PaletteCount */
0, /* Chunky8 */
0, /* Gdebug */
0, /* Debug8 */
0, /* Debug16 */
{0, 0, 0, 0, 0, 0, 0, 0}, /* pxy[] */
&Event, /* Event */
{0, 0, 0, 0, 0, 0, 0, 0}, /* Pobject[] */
&document /* Doc */
};
/* Gp_init does Atari-dependent initialization. It reads
* Atari-specific environment variables, initializes the
* AES, opens a virtual workstation, creates the windows,
* displays the menu, opens the console, and performs various
* other initializations.
*/
void
gp_init(void)
{
char *env, temp[MAXLEN];
char PrgName[] = " ST-GS"; /* CF */
int i, j, print_disable=0;
/* Check the GS_WIN environment variable to decide what to
* do about windows. Windows are used unless GS_WIN contains
* the string "off".
*/
if ((env = getenv("GS_WIN")) != NULL) {
if (!strcmp(env, "off") || !strcmp(env, "OFF")) {
State.Windows = 0;
}
}
if ((env = getenv("GS_DEVICE")) != NULL) {
for (i=0; (strcmp(env, devices[i])) && (i<DEVICES); ++i);
if (i < DEVICES) {
State.Device = i;
strcpy(State.DevString, devices[i]);
if (!strcmp(State.DevString, "stvdi")) {
print_disable = 1;
}
}
}
else {
strcpy(State.DevString, "stvdi");
print_disable = 1;
}
if (print_disable) {
objc_change(printobj, PR_PRN, 0,
printwin.canvas.g_x, printwin.canvas.g_y,
printwin.canvas.g_w, printwin.canvas.g_h,
(printobj[PR_PRN].ob_state |= DISABLED),
printwin.opened);
objc_change(printobj, PR_CEN, 0,
printwin.canvas.g_x, printwin.canvas.g_y,
printwin.canvas.g_w, printwin.canvas.g_h,
(printobj[PR_CEN].ob_state |= DISABLED),
printwin.opened);
objc_change(printobj, PR_OFILE, 0,
printwin.canvas.g_x, printwin.canvas.g_y,
printwin.canvas.g_w, printwin.canvas.g_h,
(printobj[PR_OFILE].ob_state |= DISABLED),
printwin.opened);
}
/* Find the current directory. */
getcwd(temp, MAXLEN);
unx2dos(temp, State.CurrentDir);
strcat(State.CurrentDir, "\\");
/* Initialize the AES and assign most of the VWork structure. */
GemInit(&VWork, &State);
if (State.Windows) {
LoadConfig(&VWork, &State);
}
/* Some environment variables override the values
* returned by the system.
*/
if ((env = getenv("GS_DISPLAY")) != NULL) {
if (!strcmp(env, "truecolor")) {
VWork.TrueColor = 1;
}
else if (!strcmp(env, "chunky8") || !strcmp(env, "CHUNKY8")) {
State.Chunky8 = 1;
}
}
if ((env = getenv("GS_DEBUG")) != NULL) {
if (!strcmp(env, "gdebug")) {
State.Gdebug = 1;
}
else if (!strcmp(env, "debug8")) {
State.Debug8 = 1;
VWork.ColorBits = 8;
VWork.TrueColor = 0;
}
else if (!strcmp(env, "debug16")) {
State.Debug16 = 1;
VWork.ColorBits = 16;
}
}
/* Check whether the current video hardware is supported. */
if (VWork.ColorBits != 1 && VWork.ColorBits != 2 &&
VWork.ColorBits != 4 && VWork.ColorBits != 8 &&
VWork.ColorBits != 16 && VWork.ColorBits != 24) {
eprintf1("stvdi_open: %d bit color is not supported.\n",
VWork.ColorBits);
gs_exit(-1);
}
VWork.MaxRGB = DITH_RGB(VWork.ColorBits) - 1;
/* Initialize the palette. */
if ((VWork.ColorBits > 1) && !VWork.TrueColor) {
InitPalette(&VWork, &State);
}
if (State.Gdebug) {
eprintf1("Color Bits = %ld\n", VWork.ColorBits);
eprintf1("True Color = %ld\n", VWork.TrueColor);
eprintf1("Max RGB = %ld\n", VWork.MaxRGB);
eprintf1("Palette Size = %ld\n", VWork.PaletteSize);
}
if (State.Windows) {
/* Initialization for GEM objects. */
/* Put pointers to all objects into an array. */
State.Pobject[0] = menuobj;
State.Pobject[1] = aboutobj;
State.Pobject[2] = resobj;
State.Pobject[3] = iconobj;
State.Pobject[4] = devobj;
State.Pobject[5] = sizobj;
State.Pobject[6] = printobj;
State.Pobject[7] = savemsg;
/* Fix object sizes for current resolution. */
AdjustObjects(&VWork);
for (j=0; j<NOBJS; j++) {
i=-1;
do {
++i;
rsrc_obfix(State.Pobject[j], i);
} while (!(State.Pobject[j][i].ob_flags & LASTOB));
}
/* Set the string pointers for the print dialog. */
printobj[PR_FSTR].ob_spec = (unsigned long) State.Infile;
printobj[PR_DSTR].ob_spec = (unsigned long) State.DevString;
if (!conswin.opened) {
WINTEXT *text = conswin.obj;
/* Display the menu and open the console window. */
RestoreBG(&VWork);
graf_mouse(M_OFF, 0L );
menu_bar(menuobj, 1);
if (State.MultiTOS) { /* CF */
menu_register(gl_apid, PrgName);
menu_ienable(menuobj, ICON, 0); /* use iconifier! */
}
/* Create the head of the window list. */
WList = WinListAdd(NULL, &conswin);
/* Open the console window. */
if (TextBuffRealloc(text, LINES) != NULL ) {
TextWinOpen(&conswin, &VWork, &State);
}
else {
eprintf("gp_init: No memory for the console text buffer!\n");
graf_mouse(M_ON, 0L);
gs_exit(-1);
}
graf_mouse(BUSY_BEE, 0L);
graf_mouse(M_ON, 0L);
}
}
}
int
GemInit(VWRK *vw, PSTATE *st)
{
int GemHandle;
int WorkOut[57];
int WorkIn[11] = {1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2};
/* Call appl_init() to initialize the aes before using any aes
* functions.
*/
if (st->Windows) {
if ((st->ApId = appl_init()) == -1) {
eprintf("stvdi_open: appl_init() failed!\n");
gs_exit(-1);
}
}
st->MultiTOS = (gl_ap_version >= 0x400); /* CF */
/* Open a virtual workstation. */
GemHandle = graf_handle(&vw->Wchar, &vw->Hchar, &vw->Wbox, &vw->Hbox);
vw->VdiHandle = GemHandle;
v_opnvwk(WorkIn, &VWork.VdiHandle, WorkOut);
if (vw->VdiHandle == 0) {
eprintf("stvdi_open: Could not open virtual screen workstation");
gs_exit(-1);
}
/* Get the screen resolution, aspect ratio, and palette size. */
vw->XRes = WorkOut[0];
vw->YRes = WorkOut[1];
vw->AspectRatio = (float) WorkOut[3] / WorkOut[4];
/* Get the number of color planes. */
vq_extnd(vw->VdiHandle, 1, WorkOut);
vw->ColorBits = WorkOut[4];
vw->TrueColor = (!WorkOut[5] || (vw->ColorBits >= 16));
/* Get the size of the root window. */
if (st->Windows) {
wind_get(0, WF_WORKXYWH,
&vw->full.g_x, &vw->full.g_y,
&vw->full.g_w, &vw->full.g_h);
}
return 0;
}
int
InitPalette(VWRK *vw, PSTATE *st)
{
int psize;
psize = (int)(pow(2, vw->ColorBits) + .5);
vw->PaletteSize = 3 * psize;
/* Set up the palette--a sequence of rgb values. */
if ((vw->Palette = (int *)gs_malloc((uint)vw->PaletteSize,
sizeof(int), "Palette")) == NULL) {
return_error(gs_error_VMerror);
}
if ((vw->OldPalette = (int *)gs_malloc((uint)vw->PaletteSize,
sizeof(int), "OldPalette")) == NULL) {
return_error(gs_error_VMerror);
}
if ((vw->ColorReg = (int *)gs_malloc((uint)psize,
sizeof(int), "ColorReg")) == NULL) {
return_error(gs_error_VMerror);
}
if (st->Debug8) {
int i;
vw->Palette[0] = 0;
vw->Palette[1] = 0;
vw->Palette[2] = 0;
for (i=3; i<vw->PaletteSize; i++) {
vw->Palette[i] = 1;
}
}
else {
/* Fill the array ColorReg. The value of ColorReg[i]
* will be the hardware color register which corresponds
* to the ith vdi color index.
*/
IndexToPixel((gx_color_index *)vw->ColorReg, psize);
GetPalette(VWork.Palette, &VWork); /* Get current palette. */
GetPalette(VWork.OldPalette, &VWork); /* Save for restoration. */
VWork.GSPalette = 1;
}
return 0;
}
int
AdjustObjects(VWRK *vw)
{
int ScreenWidth;
static char line1[] = "ST Ghostscript 2.6.1";
static char line2[] = "Tim Gallivan, 1994";
/* The icon and the banner bitmaps must be adjusted for the
* strange aspect ratio in ST medium (and perhaps other)
* resolutions.
*/
if (vw->AspectRatio < .6) {
iconobj[0].ob_height = 0x1800; /* 24 pixels high */
iconobj[1].ob_height = 0x1800;
iconblk[0].bi_pdata = (char *)HalfReaper;
iconblk[0].bi_hl = 24;
aboutobj[6].ob_height = 0x1b00; /* 27 pixels high */
bannerblk[0].bi_pdata = (char *)HalfBanner;
bannerblk[0].bi_hl = 27;
}
/* The About object must be changed to fit on the screen in
* low resolution. This is a major change to the object.
*/
ScreenWidth = vw->full.g_w / vw->Wchar;
if (ScreenWidth <= aboutobj[0].ob_width) {
aboutobj[0].ob_width = 28; aboutobj[0].ob_height = 15;
aboutobj[1].ob_y = 7;
aboutobj[2].ob_y = 9;
aboutobj[3].ob_x = 2; aboutobj[3].ob_y = 11;
aboutobj[4].ob_x = 2; aboutobj[4].ob_y = 13;
aboutobj[5].ob_state = SHADOWED;
aboutobj[5].ob_spec = 0xFF1111L;
aboutobj[5].ob_width = 24;
aboutobj[5].ob_height = 5;
aboutobj[6].ob_type = G_STRING;
aboutobj[6].ob_spec = UL line1;
aboutobj[6].ob_x = 2;
aboutobj[6].ob_y = 1;
aboutobj[6].ob_width = 20;
aboutobj[6].ob_height = 1;
aboutobj[7].ob_spec = UL line2;
aboutobj[7].ob_x = 3;
aboutobj[7].ob_y = 3;
aboutobj[7].ob_width = 18;
}
}
/* Gp_exit does Atari-dependent cleanup. It frees memory and AES
* resources, closes the virtual workstation, and calls appl_exit.
*/
#define EXITMSG "[3][Ghostscript Error %d!|See the console window\
|for more details.][Abort]"
void
gp_exit(int exit_status, int code)
{
WINLIST *wl = WList;
WINTEXT *text = conswin.obj;
char ErrorMsg[MAXLEN];
if (exit_status != 0 && State.Windows) {
graf_mouse(ARROW, 0L);
sprintf(ErrorMsg, EXITMSG, exit_status);
form_alert(1, ErrorMsg);
graf_mouse(BUSY_BEE, 0L);
}
/* Restore the palette and free the allocated memory. */
if (VWork.ColorBits > 1 && !VWork.TrueColor) {
if (VWork.GSPalette) {
SetPalette(VWork.OldPalette, &VWork);
gs_free((char *)VWork.Palette, VWork.PaletteSize,
sizeof(int), "Palette");
gs_free((char *)VWork.OldPalette, VWork.PaletteSize,
sizeof(int), "OldPalette");
gs_free((char *)VWork.ColorReg, VWork.PaletteSize / 3,
sizeof(int), "ColorReg");
VWork.GSPalette = 0;
}
}
/* Free the resources used by the aes. */
if (State.Windows) {
menu_bar(menuobj, 0);
/* Free the console character buffer. I probably should treat
* the console window the same as other text windows.
*/
gs_free((char *)text->buff, text->bsize, (COLUMNS+1), "charbuff");
/*
* Delete any scratch files for extracted pages and
* free any memory allocated for document page information.
*/
if (State.Doc->pageinf) {
char filename[MAXLEN], temp[10];
int i;
remove(PROLOG);
for (i=1; i <= State.Doc->maxpages; ++i) {
if (State.Doc->pageinf[i].extracted != 0) {
itoa(i, temp);
strcpy(filename, PAGE_PREFIX);
strcat(filename, temp);
strcat(filename, ".ps");
remove(filename);
}
}
gs_free((char *)State.Doc->pageinf, State.Doc->maxpages,
sizeof(PAGEINFO), "page info");
}
/* If memory was allocated for the page dialog, free it. */
if (pagewin.obj) {
DeletePageObj(&State, &pagewin);
}
/*
* Close and delete all open windows. Delete all window
* list entries.
*/
do {
if (!(wl->Win->iconified)) {
wind_close(wl->Win->handle);
}
wind_delete(wl->Win->handle);
}
while ((wl = WinListDelete(wl, wl->Win)));
}
/* Close the virtual workstation and call appl_exit */
if (VWork.VdiHandle > 0) {
v_clsvwk(VWork.VdiHandle);
}
if (State.Windows) {
graf_mouse(ARROW, 0L);
if (appl_exit() == 0) {
eprintf("stvdi_close: appl_exit() failed!\n");
exit_status = -1;
}
}
}
/* ------ Miscellaneous ------ */
/* Get the string corresponding to an OS error number. */
/* Unix systems support this so inconsistently that we don't attempt */
/* to figure out whether it's available. */
const char *
gp_strerror(int errnum)
{ return NULL;
}
/* ------ Date and time ------ */
/* Read the current date (in days since Jan. 1, 1980) */
/* and time (in milliseconds since midnight). */
void
gp_get_clock(long *pdt)
{ long secs_since_1980;
struct timeval tp;
time_t tsec;
struct tm *tm, *localtime(P1(const time_t *));
#if gettimeofday_no_timezone
{ if ( gettimeofday(&tp) == -1 )
{ lprintf("Ghostscript: gettimeofday failed!\n");
gs_exit(1);
}
secs_since_1980 = 0;
}
#else
{ struct timezone tzp;
if ( gettimeofday(&tp, &tzp) == -1 )
{ lprintf("Ghostscript: gettimeofday failed!\n");
gs_exit(1);
}
/*
* Don't adjust for timezone! That structure returns the
* kernel's notion of the timezone, which may be different
* from the one specified in the TZ environment variable.
* In particular, the tz_minuteswest value is documented to
* need adjustment according to the daylight savings time
* rules indicated by tz_dsttime. The latter indicates
* only the applicable rules and doesn't answer the
* question whether DST currently is in effect or not.
*/
/*secs_since_1980 = -(tzp.tz_minuteswest * 60);*/
secs_since_1980 = 0;
}
#endif
/* tp.tv_sec is #secs since Jan 1, 1970 */
/* subtract off number of seconds in 10 years */
/* leap seconds are not accounted for */
secs_since_1980 += tp.tv_sec - (long)(60 * 60 * 24 * 365.25 * 10);
/* adjust for daylight savings time - assume dst offset is 1 hour */
tsec = tp.tv_sec;
tm = localtime(&tsec);
if ( tm->tm_isdst )
secs_since_1980 += (60 * 60);
/* divide secs by #secs/day to get #days (integer division truncates) */
pdt[0] = secs_since_1980 / (60 * 60 * 24);
/* modulo + microsecs/1000 gives number of millisecs since midnight */
pdt[1] = (secs_since_1980 % (60 * 60 * 24)) * 1000;
/* Some Unix systems (e.g., Interactive 3.2 r3.0) return garbage */
/* in tp.tv_usec. Try to filter out the worst of it here. */
if ( tp.tv_usec >= 0 && tp.tv_usec < 1000000 )
pdt[1] += tp.tv_usec / 1000;
#ifdef DEBUG_CLOCK
printf("tp.tv_sec = %d tp.tv_usec = %d pdt[0] = %ld pdt[1] = %ld\n",
tp.tv_sec, tp.tv_usec, pdt[0], pdt[1]);
#endif
}
#if 0
/* Read the current date (in days since Jan. 1, 1980) */
/* and time (in milliseconds since midnight). */
void
gp_get_clock(long *pdt)
{ long secs_since_1970, secs_since_1980;
struct tm *tm, *localtime();
if ( (secs_since_1970 = time(NULL)) == 0 )
{ perror("Ghostscript: gettimeofday failed:");
gs_exit(-1);
}
/* secs_since_1970 is #secs since Jan 1, 1970 */
/* subtract off number of seconds in 10 years */
/* leap seconds are not accounted for */
secs_since_1980 = secs_since_1970 - (long)(60 * 60 * 24 * 365.25 * 10);
/* there is no time zone adjustment for the atari st */
/* adjust for daylight savings time - assume dst offset is 1 hour */
tm = localtime(&(secs_since_1970));
if ( tm->tm_isdst )
secs_since_1980 += (60 * 60);
/* divide secs by #secs/day to get #days (integer division truncates) */
pdt[0] = secs_since_1980 / (60 * 60 * 24);
/* modulo * 1000 gives number of millisecs since midnight */
pdt[1] = (secs_since_1980 % (60 * 60 * 24)) * 1000;
#ifdef DEBUG_CLOCK
printf("secs_since_1970 = %d usecs_since_1970 = %d pdt[0] = %ld\
pdt[1] = %ld\n", secs_since_1970, pdt[1], pdt[0], pdt[1]);
#endif
}
#endif
/* ------ Screen management ------ */
/* Get the environment variable that specifies the display to use. */
const char *
gp_getenv_display(void)
{ return getenv("DISPLAY");
}
/* ------ Check whether a file is the console. ------ */
int
gp_file_is_console(FILE *f)
{
if (!f) return 0;
if (fileno(f) >= 0 && fileno(f) <= 2) return 1;
return 0;
}
/* ------ Printer accessing ------ */
/* Open a file or a printing device. A null file name will cause
* output to be sent to "PRN:". If gp_open_printer returns
* a NULL, the file will be sent directly to the centronics port.
* This happens if fname = "CEN:" or if gp_open_scratch_file()
* fails. Usually, GS wants to interpret a NULL return value as
* an error, so this is slightly incompatible.
* "|command" opens an output pipe.
*/
FILE *
gp_open_printer(char *fname, int binary_mode)
{
if (!strcmp(fname, "CEN:")) { /* Direct Centronics printing. */
return NULL;
}
else {
return
(strlen(fname) == 0 ?
gp_open_scratch_file(gp_scratch_file_name_prefix, fname, "wb") :
fname[0] == '|' ?
popen(fname + 1, "wb") :
fopen(fname, "wb"));
}
}
/* Close the connection to the printer. */
void
gp_close_printer(FILE *pfile, const char *fname)
{ if ( fname[0] == '|' )
pclose(pfile);
else
fclose(pfile);
}