home *** CD-ROM | disk | FTP | other *** search
- /* Copyright (C) 1989, 1990 Aladdin Enterprises and 1991 David Elworthy.
- All rights reserved.
- Distributed by Free Software Foundation, Inc.
-
- 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_arc.c */
- /* Archimedes-specific routines for Ghostscript */
- /* This includes the routines which are not associated with the device
- output, i.e. the icon bar and print/scan window management.
- (Previously some of this was in gdevarc and gdevarclow)
- */
- /* Read the header file for how to use it with different device drivers */
-
-
- #include "string_.h"
- #include "gx.h"
- #include "gp.h"
-
- #include <string.h>
- #include <time.h>
-
- #include "os.h"
- #include "win.h"
- #include "wimpc.h"
- #include "wimpio.h"
- #include "dbox.h"
- #include "event.h"
-
- #include "gp_arc.h"
-
- /*-------------------------------------------------------------------------------*/
-
- /* Globals */
- BOOL gp_arc_fast = FALSE;
- static gp_arc_menu_fn menu_fn = NULL;
- static void *menu_fn_handle = NULL;
-
- /* Forward references */
- static menu menu_maker(void *handle);
- static void menu_process(void *handle, char *hit);
- static void render_start(void *handle);
-
- /*-------------------------------------------------------------------------------*/
-
- /* Do platform-dependent initialization */
- void
- gp_init()
- {
- /* Set up the wimp environment */
- wimpc_init("GhostScript", "GS", 1, 0, WIMPIO_CREATE);
- w_baricon("(%s) run", render_start, NULL);
- w_register_drop("(%s) run", render_start, NULL);
- w_register_menu(menu_maker, menu_process, NULL);
- }
-
- /* Read the current date (in days since Jan. 1, 1980) */
- /* and time (in milliseconds since midnight). */
- /* Use the ANSI time routines, to set up a structure, find the difference with the current
- time, and get the answers from that. The structure pretends Jan 1 1980 was a Sunday. I don't
- know if it was, but it doesn't matter for doing the calculation, in the Archimedes implementation
- at least.
- *** SHOULD BE PATCHED UP AT SOME STAGE
- */
- void
- gp_get_clock(long *pdt)
- {
- struct tm jan_1_1980 =
- { 0, 0, 0, /* 00:00:00 */
- 1, 0, 80, /* Jan 1 1980 */
- 0, 1, 0
- };
-
- time_t now;
- long secs_since_1980;
-
- /* Find the time now */
- now = time(NULL);
- if (now == (time_t) -1)
- { perror("Ghostscript: gettimeofday failed:");
- exit(-1);
- }
-
- /* Find seconds since Jan 1 1980 */
- secs_since_1980 = (long)difftime(now, mktime(&jan_1_1980));
-
- /* Extract days */
- /* Truncation rounds it off */
- pdt[0] = secs_since_1980 / (60 * 60 * 24);
-
- /* Extract milliseconds */
- /* In fact, this is a really feeble approximation: just the seconds * 1000 */
- pdt[1] = (secs_since_1980 % (60 * 60 * 24)) * 1000;
- }
-
- /* ------ File name syntax ------ */
-
- /* Define the character used for separating file names in a list. */
- /* Not sure this is right */
- char gp_file_name_list_separator = ' ';
-
- char gp_scratch_file_name_template[] = "<GS$DIR>.tmp_XXXXX";
-
- /* Answer whether a file name contains a directory/device specification, */
- /* i.e. is absolute (not directory- or device-relative). */
- int
- gp_file_name_is_absolute(char *fname, uint len)
- { /* A file name is absolute unless it starts with a $ or contains a :. */
- /* return !( len >= 1 && (*fname == '$' || (strchr(fname, ':') != NULL)));*/
- return ( (len < 1) || (*fname != '$' && (strchr(fname, ':') == NULL)));
- }
-
- /* Answer the string to be used for combining a directory/device prefix */
- /* with a base file name. The file name is known to not be absolute. */
- char *
- gp_file_name_concat_string(char *prefix, uint plen, char *fname, uint len)
- { if ( plen > 0 && prefix[plen - 1] == '.' )
- return "";
- return ".";
- }
-
- /* ---------- File enumeration ---------------- */
-
- /* The file enumeration block records the directory and file names, and the
- number of the last matching file.
- These may not function correctly when there is a wild card in the directory
- name.
- */
-
- struct file_enum_s {
- int size;
- char *pattern; /* Allocated dynamically */
- int dirlen; /* Length of directory part */
- char *leaf; /* Leaf name of pattern */
- int next; /* Number of next entry to read (-1 = done) */
- gs_memory_procs mprocs; /* Memory allocation procedures */
- };
-
- /*
- * Begin an enumeration. pat is a C string that may contain *s or ?s.
- * The implementor should copy the string to a safe place.
- * If the operating system doesn't support correct, arbitrarily placed
- * *s and ?s, the implementation should modify the string so that it
- * will return a conservative superset of the request. E.g., if the OS
- * doesn't implement ? (single-character wild card), any consecutive
- * string of ?s should be interpreted as *. Note that \ can appear in
- * the pattern also, as a quoting character.
- */
-
- file_enum *
- gp_enumerate_files_init(char *pat, uint patlen, proc_alloc_t palloc, proc_free_t pfree)
- {
- char *pattern, *p, *q;
-
- /* Allocate control block */
- file_enum *pfen = (file_enum *)(*palloc)(1, sizeof(file_enum), "gp_enumerate_files");
- if (pfen == 0) return 0;
-
- /* Allocate space for pattern */
- pattern = (*palloc)(patlen + 1, 1, "gp_enumerate_files(pattern)");
- if ( pattern == 0 )
- {
- (*pfree)((char *)pfen, 1, sizeof(file_enum), "gp_enumerate_files_close");
- return 0;
- }
- pfen->size = patlen+1;
- pfen->mprocs.alloc = palloc;
- pfen->mprocs.free = pfree;
-
- /* Get the string into local format */
- for (p = pat, q = pattern ; p < pat+patlen && *p != 0; p++)
- {
- if (*p == '?') *q++ = '#';
- else if (*p != '\\') *q++ = *p;
- }
- *q = 0;
- pfen->pattern = pattern;
-
- /* Put a null at separator before leaf name, and note leaf address */
- p = strrchr(pattern, '.');
- if (p == NULL)
- pfen->leaf = pattern;
- else
- {
- *p++ = 0;
- pfen->leaf = p;
- }
- pfen->dirlen = strlen(pattern);
-
- /* Indicate first file is next to read */
- pfen->next = 0;
- return pfen;
- }
-
- /*
- * Return the next file name in the enumeration. The client passes in
- * a scratch string and a max length. If the name of the next file fits,
- * the procedure returns the length. If it doesn't fit, the procedure
- * returns max length +1. If there are no more files, the procedure
- * returns -1.
- */
- /* Enumerate the next file. */
- uint
- gp_enumerate_files_next(file_enum *pfen, char *ptr, uint maxlen)
- {
- os_gbpbstr regset;
- char *p = ptr;
-
- /* Check validity of control block */
- if (pfen == NULL) return -1;
-
- /* Check there are more files to read, and clean up if not */
- if (pfen->next == -1)
- {
- gp_enumerate_files_close(pfen);
- return -1;
- }
-
- /* Check we will have enough space for the directory part at least */
- if (pfen->dirlen+1 >= maxlen) return maxlen+1;
- strcpy(ptr, pfen->pattern);
- ptr += pfen->dirlen;
- *ptr++ = '.';
-
- /* Read next file */
- regset.action = 9;
- regset.file_handle = (int)(pfen->pattern);
- regset.data_addr = (void *)ptr;
- regset.number = 1;
- regset.seq_point = pfen->next;
- regset.buf_len = maxlen - pfen->dirlen - 1;
- regset.wild_fld = pfen->leaf;
- if (os_gbpb(®set) != NULL || regset.number == 0)
- {
- /* OS error - just give up */
- gp_enumerate_files_close(pfen);
- return -1;
- }
-
- /* Update next file number */
- pfen->next = regset.seq_point;
- return (strlen(p));
- }
-
- /*
- * Clean up a file enumeration. This is only called to abandon
- * an enumeration partway through: ...next should do it if there are
- * no more files to enumerate. This should deallocate the file_enum
- * structure and any subsidiary structures, strings, buffers, etc.
- */
- /* Clean up the file enumeration. */
- void
- gp_enumerate_files_close(file_enum *pfen)
- {
- proc_free_t pfree = pfen->mprocs.free;
- (*pfree)(pfen->pattern, pfen->size + 1, 1,
- "gp_enumerate_files_close(pattern)");
- (*pfree)((char *)pfen, 1, sizeof(file_enum), "gp_enumerate_files_close");
- }
-
-
- /*-----------------------------------------------------------------------*/
-
- /* The function hypot is in Unix math, but not in the ANSI library on the
- Archimedes. So I define it here. It doesn't check for overflow.
- If either argument is zero, the other one is returned; we first take the
- abs of it, to simulate squaring and then square rooting. */
- double hypot(double x, double y)
- {
- if (x == 0.0) return fabs(y);
- if (y == 0.0) return fabs(x);
- return sqrt(x*x + y*y);
- }
-
-
- /*-----------------------------------------------------------------------*/
-
- /* Menu code */
-
- /* Menu code - same menu is used for both icon bar and window */
- /* This is the code for handling the icon bar icon */
- static char *main_menu = ">Info,>Options,Fast,Show page,Quit";
- #define Menu_Info (1)
- #define Menu_Options (2)
- #define Menu_Fast (3)
- #define Menu_Page (4)
- #define Menu_Quit (5)
-
-
- static menu menu_maker(void *handle)
- {
- menu m = menu_new("GhostScript", main_menu);
- menu_setflags(m, Menu_Options, 0, (menu_fn == NULL));
- menu_setflags(m, Menu_Fast, gp_arc_fast, 0);
- return m;
- }
-
- static void menu_process(void *handle, char* hit)
- {
- switch (hit[0])
- {
- case Menu_Info:
- {
- dbox d;
- /* --- display info about the program in a dialogue box --- */
- d = dbox_new("ProgInfo");
- dbox_showstatic(d);
- dbox_fillin(d);
- dbox_dispose(&d);
- break;
- }
-
- case Menu_Options:
- if (menu_fn)
- {
- if (!(*menu_fn)(menu_fn_handle, hit))
- wread_fake_input("quit");
- }
- break;
-
- case Menu_Fast:
- gp_arc_fast = !gp_arc_fast;
- break;
-
- case Menu_Page:
- wread_fake_input("showpage");
- event_clear_current_menu();
- break;
-
- case Menu_Quit: /* Also remove page window if up */
- wread_fake_input("quit");
- event_clear_current_menu();
- break;
- }
- }
-
- void gp_arc_device_menu(gp_arc_menu_fn f, void *handle)
- {
- menu_fn = f;
- menu_fn_handle = handle;
- }
-
- /* This is called on a drop: it disables menus */
- static void render_start(void *handle)
- {
- event_clear_current_menu();
- }
-