home *** CD-ROM | disk | FTP | other *** search
/ APDL Public Domain 1 / APDL_PD1A.iso / printing / ghostscrip / source / _gs / c / gp_arc < prev    next >
Encoding:
Text File  |  1991-12-06  |  10.9 KB  |  362 lines

  1. /* Copyright (C) 1989, 1990 Aladdin Enterprises and 1991 David Elworthy.
  2.    All rights reserved.
  3.    Distributed by Free Software Foundation, Inc.
  4.  
  5. This file is part of Ghostscript.
  6.  
  7. Ghostscript is distributed in the hope that it will be useful, but
  8. WITHOUT ANY WARRANTY.  No author or distributor accepts responsibility
  9. to anyone for the consequences of using it or for whether it serves any
  10. particular purpose or works at all, unless he says so in writing.  Refer
  11. to the Ghostscript General Public License for full details.
  12.  
  13. Everyone is granted permission to copy, modify and redistribute
  14. Ghostscript, but only under the conditions described in the Ghostscript
  15. General Public License.  A copy of this license is supposed to have been
  16. given to you along with Ghostscript so you can know your rights and
  17. responsibilities.  It should be in a file named COPYING.  Among other
  18. things, the copyright notice and this notice must be preserved on all
  19. copies.  */
  20.  
  21. /* gp_arc.c */
  22. /* Archimedes-specific routines for Ghostscript */
  23. /* This includes the routines which are not associated with the device
  24.    output, i.e. the icon bar and print/scan window management.
  25.    (Previously some of this was in gdevarc and gdevarclow)
  26.  */
  27. /* Read the header file for how to use it with different device drivers */
  28.    
  29.  
  30. #include "string_.h"
  31. #include "gx.h"
  32. #include "gp.h"
  33.  
  34. #include <string.h>
  35. #include <time.h>
  36.  
  37. #include "os.h"
  38. #include "win.h"
  39. #include "wimpc.h"
  40. #include "wimpio.h"
  41. #include "dbox.h"
  42. #include "event.h"
  43.  
  44. #include "gp_arc.h"
  45.  
  46. /*-------------------------------------------------------------------------------*/
  47.  
  48. /* Globals */
  49. BOOL gp_arc_fast = FALSE;
  50. static gp_arc_menu_fn menu_fn = NULL;
  51. static void *menu_fn_handle = NULL;
  52.  
  53. /* Forward references */
  54. static menu menu_maker(void *handle);
  55. static void menu_process(void *handle, char *hit);
  56. static void render_start(void *handle);
  57.  
  58. /*-------------------------------------------------------------------------------*/
  59.  
  60. /* Do platform-dependent initialization */
  61. void
  62. gp_init()
  63. {
  64.     /* Set up the wimp environment */
  65.     wimpc_init("GhostScript", "GS", 1, 0, WIMPIO_CREATE);
  66.     w_baricon("(%s) run", render_start, NULL);
  67.     w_register_drop("(%s) run", render_start, NULL);
  68.     w_register_menu(menu_maker, menu_process, NULL);
  69. }
  70.  
  71. /* Read the current date (in days since Jan. 1, 1980) */
  72. /* and time (in milliseconds since midnight). */
  73. /* Use the ANSI time routines, to set up a structure, find the difference with the current
  74.    time, and get the answers from that. The structure pretends Jan 1 1980 was a Sunday. I don't
  75.    know if it was, but it doesn't matter for doing the calculation, in the Archimedes implementation
  76.    at least.
  77. *** SHOULD BE PATCHED UP AT SOME STAGE
  78. */
  79. void
  80. gp_get_clock(long *pdt)
  81. {
  82.         struct tm jan_1_1980 =
  83.           { 0, 0, 0,   /* 00:00:00 */
  84.             1, 0, 80,  /* Jan 1 1980 */
  85.             0, 1, 0
  86.           };
  87.  
  88.         time_t now;
  89.         long secs_since_1980;
  90.  
  91.         /* Find the time now */
  92.         now = time(NULL);
  93.         if (now == (time_t) -1)
  94.            {    perror("Ghostscript: gettimeofday failed:");
  95.                 exit(-1);
  96.            }
  97.  
  98.         /* Find seconds since Jan 1 1980 */
  99.         secs_since_1980 = (long)difftime(now, mktime(&jan_1_1980));
  100.  
  101.         /* Extract days */
  102.         /* Truncation rounds it off */
  103.         pdt[0] = secs_since_1980 / (60 * 60 * 24);
  104.  
  105.         /* Extract milliseconds */
  106.         /* In fact, this is a really feeble approximation: just the seconds * 1000 */
  107.         pdt[1] = (secs_since_1980 % (60 * 60 * 24)) * 1000;
  108. }
  109.  
  110. /* ------ File name syntax ------ */
  111.  
  112. /* Define the character used for separating file names in a list. */
  113. /* Not sure this is right */
  114. char gp_file_name_list_separator = ' ';
  115.  
  116. char gp_scratch_file_name_template[] = "<GS$DIR>.tmp_XXXXX";
  117.  
  118. /* Answer whether a file name contains a directory/device specification, */
  119. /* i.e. is absolute (not directory- or device-relative). */
  120. int
  121. gp_file_name_is_absolute(char *fname, uint len)
  122. {       /* A file name is absolute unless it starts with a $ or contains a :. */
  123. /*        return !( len >= 1 && (*fname == '$' || (strchr(fname, ':') != NULL)));*/
  124.         return ( (len < 1) || (*fname != '$' && (strchr(fname, ':') == NULL)));
  125. }
  126.  
  127. /* Answer the string to be used for combining a directory/device prefix */
  128. /* with a base file name.  The file name is known to not be absolute. */
  129. char *
  130. gp_file_name_concat_string(char *prefix, uint plen, char *fname, uint len)
  131. {       if ( plen > 0 && prefix[plen - 1] == '.' )
  132.                 return "";
  133.         return ".";
  134. }
  135.  
  136. /* ---------- File enumeration ---------------- */
  137.  
  138. /* The file enumeration block records the directory and file names, and the
  139.    number of the last matching file. 
  140.    These may not function correctly when there is a wild card in the directory
  141.    name.
  142. */
  143.  
  144. struct file_enum_s {
  145.     int  size;
  146.     char *pattern;   /* Allocated dynamically */
  147.     int  dirlen;     /* Length of directory part */
  148.     char *leaf;      /* Leaf name of pattern */
  149.     int  next;       /* Number of next entry to read (-1 = done) */
  150.     gs_memory_procs mprocs; /* Memory allocation procedures */
  151. };
  152.  
  153. /*
  154.  * Begin an enumeration.  pat is a C string that may contain *s or ?s.
  155.  * The implementor should copy the string to a safe place.
  156.  * If the operating system doesn't support correct, arbitrarily placed
  157.  * *s and ?s, the implementation should modify the string so that it
  158.  * will return a conservative superset of the request.  E.g., if the OS
  159.  * doesn't implement ? (single-character wild card), any consecutive
  160.  * string of ?s should be interpreted as *.  Note that \ can appear in
  161.  * the pattern also, as a quoting character.
  162.  */
  163.  
  164. file_enum *
  165. gp_enumerate_files_init(char *pat, uint patlen, proc_alloc_t palloc, proc_free_t pfree)
  166. {
  167.     char *pattern, *p, *q;
  168.  
  169.     /* Allocate control block */
  170.     file_enum *pfen = (file_enum *)(*palloc)(1, sizeof(file_enum), "gp_enumerate_files");
  171.     if (pfen == 0) return 0;
  172.  
  173.     /* Allocate space for pattern */
  174.     pattern = (*palloc)(patlen + 1, 1, "gp_enumerate_files(pattern)");
  175.     if ( pattern == 0 )
  176.     {
  177.         (*pfree)((char *)pfen, 1, sizeof(file_enum), "gp_enumerate_files_close");
  178.         return 0;
  179.     }
  180.     pfen->size = patlen+1;
  181.     pfen->mprocs.alloc = palloc;
  182.     pfen->mprocs.free = pfree;
  183.  
  184.     /* Get the string into local format */
  185.     for (p = pat, q = pattern ; p < pat+patlen && *p != 0; p++)
  186.     {
  187.         if (*p == '?') *q++ = '#';
  188.         else if (*p != '\\') *q++ = *p;
  189.     }
  190.     *q = 0;
  191.     pfen->pattern = pattern;
  192.  
  193.     /* Put a null at separator before leaf name, and note leaf address */
  194.     p = strrchr(pattern, '.');
  195.     if (p == NULL)
  196.         pfen->leaf = pattern;
  197.     else
  198.     {
  199.         *p++ = 0;
  200.         pfen->leaf = p;
  201.     }
  202.     pfen->dirlen = strlen(pattern);
  203.  
  204.     /* Indicate first file is next to read */
  205.     pfen->next = 0;
  206.     return pfen;
  207. }
  208.  
  209. /*
  210.  * Return the next file name in the enumeration.  The client passes in
  211.  * a scratch string and a max length.  If the name of the next file fits,
  212.  * the procedure returns the length.  If it doesn't fit, the procedure
  213.  * returns max length +1.  If there are no more files, the procedure
  214.  * returns -1.
  215.  */
  216. /* Enumerate the next file. */
  217. uint
  218. gp_enumerate_files_next(file_enum *pfen, char *ptr, uint maxlen)
  219. {
  220.     os_gbpbstr regset;
  221.     char *p = ptr;
  222.  
  223.     /* Check validity of control block */
  224.     if (pfen == NULL) return -1;
  225.  
  226.     /* Check there are more files to read, and clean up if not */
  227.     if (pfen->next == -1)
  228.     {
  229.         gp_enumerate_files_close(pfen);
  230.         return -1;
  231.     }
  232.  
  233.     /* Check we will have enough space for the directory part at least */
  234.     if (pfen->dirlen+1 >= maxlen) return maxlen+1;
  235.     strcpy(ptr, pfen->pattern);
  236.     ptr += pfen->dirlen;
  237.     *ptr++ = '.';
  238.  
  239.     /* Read next file */
  240.     regset.action = 9;
  241.     regset.file_handle = (int)(pfen->pattern);
  242.     regset.data_addr = (void *)ptr;
  243.     regset.number = 1;
  244.     regset.seq_point = pfen->next;
  245.     regset.buf_len = maxlen - pfen->dirlen - 1;
  246.     regset.wild_fld = pfen->leaf;
  247.     if (os_gbpb(®set) != NULL || regset.number == 0)
  248.     {
  249.         /* OS error - just give up */
  250.         gp_enumerate_files_close(pfen);
  251.         return -1;
  252.     }
  253.  
  254.     /* Update next file number */
  255.     pfen->next = regset.seq_point;
  256.     return (strlen(p));
  257. }
  258.  
  259. /*
  260.  * Clean up a file enumeration.  This is only called to abandon
  261.  * an enumeration partway through: ...next should do it if there are
  262.  * no more files to enumerate.  This should deallocate the file_enum
  263.  * structure and any subsidiary structures, strings, buffers, etc.
  264.  */
  265. /* Clean up the file enumeration. */
  266. void
  267. gp_enumerate_files_close(file_enum *pfen)
  268. {
  269.     proc_free_t pfree = pfen->mprocs.free;
  270.     (*pfree)(pfen->pattern, pfen->size + 1, 1,
  271.              "gp_enumerate_files_close(pattern)");
  272.     (*pfree)((char *)pfen, 1, sizeof(file_enum), "gp_enumerate_files_close");
  273. }
  274.  
  275.  
  276. /*-----------------------------------------------------------------------*/
  277.  
  278. /* The function hypot is in Unix math, but not in the ANSI library on the
  279.    Archimedes. So I define it here. It doesn't check for overflow.
  280.    If either argument is zero, the other one is returned; we first take the
  281.    abs of it, to simulate squaring and then square rooting. */
  282. double hypot(double x, double y)
  283. {
  284.     if (x == 0.0) return fabs(y);
  285.     if (y == 0.0) return fabs(x);
  286.     return sqrt(x*x + y*y);
  287. }
  288.  
  289.  
  290. /*-----------------------------------------------------------------------*/
  291.  
  292. /* Menu code */
  293.  
  294. /* Menu code - same menu is used for both icon bar and window */
  295. /* This is the code for handling the icon bar icon */
  296. static char *main_menu = ">Info,>Options,Fast,Show page,Quit";
  297. #define Menu_Info (1)
  298. #define Menu_Options (2)
  299. #define Menu_Fast (3)
  300. #define Menu_Page (4)
  301. #define Menu_Quit (5)
  302.  
  303.  
  304. static menu menu_maker(void *handle)
  305. {
  306.     menu m = menu_new("GhostScript", main_menu);
  307.     menu_setflags(m, Menu_Options, 0, (menu_fn == NULL));
  308.     menu_setflags(m, Menu_Fast, gp_arc_fast, 0);
  309.     return m;
  310. }
  311.  
  312. static void menu_process(void *handle, char* hit)
  313. {
  314.     switch (hit[0])
  315.     {
  316.         case Menu_Info:
  317.         {
  318.             dbox d;
  319.             /* --- display info about the program in a dialogue box --- */
  320.             d = dbox_new("ProgInfo");
  321.             dbox_showstatic(d);
  322.             dbox_fillin(d);
  323.             dbox_dispose(&d);
  324.             break;
  325.         }
  326.  
  327.         case Menu_Options:
  328.             if (menu_fn)
  329.             {
  330.                 if (!(*menu_fn)(menu_fn_handle, hit))
  331.                      wread_fake_input("quit");
  332.             }
  333.             break;
  334.  
  335.         case Menu_Fast:
  336.             gp_arc_fast = !gp_arc_fast;
  337.             break;
  338.  
  339.         case Menu_Page:
  340.             wread_fake_input("showpage");
  341.             event_clear_current_menu();
  342.             break;
  343.  
  344.         case Menu_Quit: /* Also remove page window if up */
  345.             wread_fake_input("quit");
  346.             event_clear_current_menu();
  347.             break;
  348.     }
  349. }
  350.  
  351. void gp_arc_device_menu(gp_arc_menu_fn f, void *handle)
  352. {
  353.     menu_fn     = f;
  354.     menu_fn_handle = handle;
  355. }
  356.  
  357. /* This is called on a drop: it disables menus */
  358. static void render_start(void *handle)
  359. {
  360.     event_clear_current_menu();
  361. }
  362.