Esempio n. 1
0
static void print_flags(ms_MediaCode flags, const ms_Flag *user_flags)
{
  /* Non-standard flags first */
  if (user_flags != NULL) {
    while (user_flags->code != ms_none) {
      if (user_flags->code & flags) {
        eprintf1("%s", user_flags->name);
        flags &= ~user_flags->code;
      }
      user_flags++;
    }
  }

  /* Standard substrings */
  if (flags & MS_SMALL_FLAG) eprintf(MS_SMALL_STRING);
  if (flags & MS_BIG_FLAG  ) eprintf(MS_BIG_STRING);
  if (flags & MS_EXTRA_FLAG) eprintf(MS_EXTRA_STRING);
  flags &= ~(MS_SMALL_FLAG | MS_BIG_FLAG | MS_EXTRA_FLAG);

  /* Completeness check */
  if (flags & ~MS_TRANSVERSE_FLAG)
    eprintf1("0x%04X", (unsigned int)(flags & ~MS_TRANSVERSE_FLAG));

  /* Standard qualifier */
  if (flags & MS_TRANSVERSE_FLAG) eprintf("." MS_TRANSVERSE_STRING);

  return;
}
Esempio n. 2
0
static void eprn_flag_mismatch(const struct s_eprn_Device *eprn,
  bool no_match)
{
  if (eprn->fmr != NULL) (*eprn->fmr)(eprn, no_match);
  else {
    const char *epref = eprn->CUPS_messages? CUPS_ERRPREF: "";

    eprintf2("%s" ERRPREF "The %s does not support ",
      epref, eprn->cap->name);
    if (eprn->desired_flags == 0) eprintf("an empty set of media flags");
    else {
      eprintf("the \"");
      print_flags(eprn->desired_flags, eprn->flag_desc);
      eprintf("\" flag(s)");
    }
    eprintf1("\n%s  (ignoring presence or absence of \"", epref);
    {
      ms_MediaCode optional = MS_TRANSVERSE_FLAG;
      if (eprn->optional_flags != NULL) {
        const ms_MediaCode *of = eprn->optional_flags;
        while (*of != ms_none) optional |= *of++;
      }
      print_flags(optional, eprn->flag_desc);
    }
    eprintf("\") for ");
    if (no_match) eprintf("any"); else eprintf("this");
    eprintf(" page size.\n");
  }

  return;
}
Esempio n. 3
0
int gs_band_donor_band_full(void *opaque, uint nLines)
{
#ifdef DEBUG_PRINT
    eprintf1("gs_band_donor_band_full[%d]\n", nLines);
#endif
    return 0;
}
Esempio n. 4
0
/* Set the device mode */
void
pcfb_set_mode(int mode)
{
    int i, mode1;

    open_console();
    cur_mode = mode;
    mode1 = -1;
    if (mode == 0x10)
        mode = SW_ENH_CG640;
#ifdef SW_VGA12
    else if (mode == 0x12)
        mode = SW_VGA12;
#endif
    else if (mode == 0x03) {
#ifdef SW_VGA80x25
        mode = SW_VGA80x25;
        mode1 = SW_ENHC80x25;
#else
        mode = SW_ENHC80x25;
#endif
    } else {
        eprintf1("can not set to video mode %d\n", mode);
        exit(1);
    }
    i = ioctl(console_fd, mode, 0L);
    if (i == -1 && mode1 != -1)
        i = ioctl(console_fd, mode1, 0L);
    if (i == -1) {
        ega_close((gx_device *) NULL);
        eprintf("unable to set console mode\n");
        perror("pcfb_set_mode");
        exit(1);
    }
#ifdef VGA_IOPRIVL
    if (ioctl(console_fd, VGA_IOPRIVL, 1) == -1) {
        ega_close((gx_device *) NULL);
        eprintf("unable to get I/O privilege\n");
        perror("pcfb_set_mode");
        exit(1);
    }
#endif
    i = ioctl(console_fd, MAPCONS, 0L);
    if (i == -1) {
        ega_close((gx_device *) NULL);
        eprintf("unable to map console adaptor's display memory\n");
        perror("pcfb_set_mode");
        exit(1);
    }
    fb_addr = (fb_ptr) (i);
}
Esempio n. 5
0
int
clist_fopen(char *fname, const char *fmode, clist_file_ptr *pcf,
  gs_memory_t *mem, bool ok_to_compress)
{	if ( *fname == 0 )
	  { if ( fmode[0] == 'r' )
	      return_error(gs_error_invalidfileaccess);
	    *pcf =
	      (clist_file_ptr)gp_open_scratch_file(gp_scratch_file_name_prefix,
						   fname, fmode);
	  }
	else
	  *pcf = gp_fopen(fname, fmode);
	if ( *pcf == NULL )
	  { eprintf1("Could not open the scratch file %s.\n", fname);
	    return_error(gs_error_invalidfileaccess);
	  }
	return 0;
}
Esempio n. 6
0
static void
open_console()
{
    const char *dev;

    if (console_fd != -1)
        return;
    dev = getenv("GSDEVICE");
    if (dev == NULL || *dev == '\0')
        dev = "/dev/tty";
    console_fd = open(dev, 0);
    if (console_fd == -1) {
        ega_close((gx_device *) NULL);
        eprintf1("unable to map display '%s'\n", dev);
        perror("open_console");
        exit(1);
    }
}
Esempio n. 7
0
static void
rc_gsicc_link_cache_free(gs_memory_t * mem, void *ptr_in, client_name_t cname)
{
    /* Ending the entire cache.  The ref counts on all the links should be 0 */
    gsicc_link_cache_t *link_cache = (gsicc_link_cache_t * ) ptr_in;

    while (link_cache->head != NULL) {
        gsicc_remove_link(link_cache->head, mem);
        link_cache->num_links--;
    }
#ifdef DEBUG
    if (link_cache->num_links != 0) {
	eprintf1("num_links is %d, should be 0.\n", link_cache->num_links);
    }
#endif
    gs_free_object(mem->stable_memory, link_cache->lock, "rc_gsicc_link_cache_free(lock)");
    gs_free_object(mem->stable_memory, link_cache->wait, "rc_gsicc_link_cache_free(wait)");
    gs_free_object(mem->stable_memory, link_cache, "rc_gsicc_link_cache_free");
}
Esempio n. 8
0
/* Fill the page with the current color. */
int
gs_fillpage(gs_state * pgs)
{
    gx_device *dev = gs_currentdevice(pgs);
    int code;

    /* If we get here without a valid get_color_mapping_procs, fail */
    if (dev_proc(dev, get_color_mapping_procs) == NULL || 
        dev_proc(dev, get_color_mapping_procs) == gx_error_get_color_mapping_procs) {
	eprintf1("\n   *** Error: No get_color_mapping_procs for device: %s\n", dev->dname);
	return_error(gs_error_Fatal);
    }
    /* Processing a fill object operation */
    gs_set_object_tag(pgs, GS_PATH_TAG);

    gx_set_dev_color(pgs);

    code = (*dev_proc(dev, fillpage))(dev, (gs_imager_state *)pgs, pgs->dev_color);
    if (code < 0)
	return code;
    return (*dev_proc(dev, sync_output)) (dev);
}
Esempio n. 9
0
static void
rc_gsicc_link_cache_free(gs_memory_t * mem, void *ptr_in, client_name_t cname)
{
    /* Ending the entire cache.  The ref counts on all the links should be 0 */
    gsicc_link_cache_t *link_cache = (gsicc_link_cache_t * ) ptr_in;

    while (link_cache->head != NULL) {
        gsicc_remove_link(link_cache->head, mem);
        link_cache->num_links--;
    }
#ifdef DEBUG
    if (link_cache->num_links != 0) {
        eprintf1("num_links is %d, should be 0.\n", link_cache->num_links);
    }
#endif
    gx_semaphore_free(link_cache->wait);
    link_cache->wait = NULL;
    gx_monitor_free(link_cache->lock);
    link_cache->lock = NULL;
    if_debug2(gs_debug_flag_icc,"[icc] Removing link cache = 0x%x memory = 0x%x\n", link_cache,
        link_cache->memory);
    gs_free_object(mem->stable_memory, link_cache, "rc_gsicc_link_cache_free");
}
Esempio n. 10
0
/* Set up and start the render threads */
static int
clist_setup_render_threads(gx_device *dev, int y)
{
    gx_device_printer *pdev = (gx_device_printer *)dev;
    gx_device_clist *cldev = (gx_device_clist *)dev;
    gx_device_clist_common *cdev = (gx_device_clist_common *)cldev;
    gx_device_clist_reader *crdev = &cldev->reader;
    gs_memory_t *mem = cdev->bandlist_memory;
    gx_device *protodev;
    gs_c_param_list paramlist;
    int i, code, band;
    int band_count = cdev->nbands;
    char fmode[4];

    crdev->num_render_threads = pdev->num_render_threads_requested;

    if(gs_debug[':'] != 0)
	dprintf1("%% %d rendering threads requested.\n", pdev->num_render_threads_requested);

    if (crdev->num_render_threads > band_count)
	crdev->num_render_threads = band_count;	/* don't bother starting more threads than bands */

    /* Allocate and initialize an array of thread control structures */
    crdev->render_threads = (clist_render_thread_control_t *)
	      gs_alloc_byte_array(mem, crdev->num_render_threads,
	      sizeof(clist_render_thread_control_t), "clist_setup_render_threads" );
    /* fallback to non-threaded if allocation fails */
    if (crdev->render_threads == NULL) {
	eprintf(" VMerror prevented threads from starting.\n");
	return_error(gs_error_VMerror);
    }


    memset(crdev->render_threads, 0, crdev->num_render_threads *
	    sizeof(clist_render_thread_control_t));
    crdev->main_thread_data = cdev->data;		/* save data area */
    /* Based on the line number requested, decide the order of band rendering */
    /* Almost all devices go in increasing line order (except the bmp* devices ) */
    crdev->thread_lookahead_direction = (y < (cdev->height - 1)) ? 1 : -1;
    band = y / crdev->page_info.band_params.BandHeight;

    /* Close the files so we can open them in multiple threads */
    if ((code = cdev->page_info.io_procs->fclose(cdev->page_cfile, cdev->page_cfname, false)) < 0 ||
        (code = cdev->page_info.io_procs->fclose(cdev->page_bfile, cdev->page_bfname, false)) < 0) {
	gs_free_object(mem, crdev->render_threads, "clist_setup_render_threads");
	crdev->render_threads = NULL;
	eprintf("Closing clist files prevented threads from starting.\n");
        return_error(gs_error_unknownerror); /* shouldn't happen */
    }
    cdev->page_cfile = cdev->page_bfile = NULL;
    strcpy(fmode, "r");			/* read access for threads */
    strncat(fmode, gp_fmode_binary_suffix, 1);
    /* Find the prototype for this device (needed so we can copy from it) */
    for (i=0; (protodev = (gx_device *)gs_getdevice(i)) != NULL; i++)
	if (strcmp(protodev->dname, dev->dname) == 0)
	    break;
    if (protodev == NULL) {
	eprintf("Could not find prototype device. Rendering threads not started.\n");
	return gs_error_rangecheck;
    }

    gs_c_param_list_write(&paramlist, mem);
    if ((code = gs_getdeviceparams(dev, (gs_param_list *)&paramlist)) < 0) {
	eprintf1("Error getting device params, code=%d. Rendering threads not started.\n", code);
	return code;
    }

    /* Loop creating the devices and semaphores for each thread, then start them */
    for (i=0; (i < crdev->num_render_threads) && (band >= 0) && (band < band_count);
	    i++, band += crdev->thread_lookahead_direction) {
	gx_device *ndev;
	gx_device_clist *ncldev;
	gx_device_clist_common *ncdev;
	clist_render_thread_control_t *thread = &(crdev->render_threads[i]);

	/* Every thread will have a 'chunk allocator' to reduce the interaction
	 * with the 'base' allocator which has 'mutex' (locking) protection. 
	 * This improves performance of the threads.
	 */
	if ((code = gs_memory_chunk_wrap(&(thread->memory), mem )) < 0) {
	    eprintf1("chunk_wrap returned error code: %d\n", code);
	    break;
	}

        thread->band = -1;		/* a value that won't match any valid band */
	if ((code = gs_copydevice((gx_device **) &ndev, protodev, thread->memory)) < 0) {
	    code = 0;		/* even though we failed, no cleanup needed */
	    break;
	}
	ncldev = (gx_device_clist *)ndev;
	ncdev = (gx_device_clist_common *)ndev;
	gx_device_fill_in_procs(ndev);
	((gx_device_printer *)ncdev)->buffer_memory = ncdev->memory =
		ncdev->bandlist_memory = thread->memory;
	gs_c_param_list_read(&paramlist);
	ndev->PageCount = dev->PageCount;	/* copy to prevent mismatch error */
	if ((code = gs_putdeviceparams(ndev, (gs_param_list *)&paramlist)) < 0)
	    break;
	ncdev->page_uses_transparency = cdev->page_uses_transparency;
	/* gdev_prn_allocate_memory sets the clist for writing, creating new files.
	 * We need  to unlink those files and open the main thread's files, then
	 * reset the clist state for reading/rendering
	 */
	if ((code = gdev_prn_allocate_memory(ndev, NULL, ndev->width, ndev->height)) < 0)
	    break;
	thread->cdev = ndev;
	/* close and unlink the temp files just created */
	cdev->page_info.io_procs->fclose(ncdev->page_cfile, ncdev->page_cfname, true);
	cdev->page_info.io_procs->fclose(ncdev->page_bfile, ncdev->page_bfname, true);
	/* open the main thread's files for this thread */
	if ((code=cdev->page_info.io_procs->fopen(cdev->page_cfname, fmode, &ncdev->page_cfile,
			    thread->memory, thread->memory, true)) < 0 ||
	     (code=cdev->page_info.io_procs->fopen(cdev->page_bfname, fmode, &ncdev->page_bfile,
			    thread->memory, thread->memory, false)) < 0)
	    break;
	clist_render_init(ncldev);	/* Initialize clist device for reading */
	ncdev->page_bfile_end_pos = cdev->page_bfile_end_pos;

	/* create the buf device for this thread, and allocate the semaphores */
	if ((code = gdev_create_buf_device(cdev->buf_procs.create_buf_device,
				&(thread->bdev), cdev->target,
				band*crdev->page_band_height, NULL,
				thread->memory, clist_get_band_complexity(dev,y)) < 0)) 
	    break;
	if ((thread->sema_this = gx_semaphore_alloc(thread->memory)) == NULL ||
	    (thread->sema_group = gx_semaphore_alloc(thread->memory)) == NULL) {
	    code = gs_error_VMerror;
	    break;
	}
	/* Start thread 'i' to do band */
	if ((code = clist_start_render_thread(dev, i, band)) < 0)
	    break;
    }
    gs_c_param_list_release(&paramlist);
    /* If the code < 0, the last thread creation failed -- clean it up */
    if (code < 0) {
	/* the following relies on 'free' ignoring NULL pointers */
	gx_semaphore_free(crdev->render_threads[i].sema_group); 
	gx_semaphore_free(crdev->render_threads[i].sema_this); 
	if (crdev->render_threads[i].bdev != NULL)
	    cdev->buf_procs.destroy_buf_device(crdev->render_threads[i].bdev);
	if (crdev->render_threads[i].cdev != NULL) {
	    gx_device_clist_common *thread_cdev = (gx_device_clist_common *)crdev->render_threads[i].cdev;
	    
    	    /* Close the file handles, but don't delete (unlink) the files */
	    thread_cdev->page_info.io_procs->fclose(thread_cdev->page_bfile, thread_cdev->page_bfname, false);
	    thread_cdev->page_info.io_procs->fclose(thread_cdev->page_cfile, thread_cdev->page_cfname, false);
	    thread_cdev->do_not_open_or_close_bandfiles = true;	/* we already closed the files */

	    gdev_prn_free_memory((gx_device *)thread_cdev);
	    gs_free_object(crdev->render_threads[i].memory, thread_cdev,
	    "clist_setup_render_threads");
	}
	if (crdev->render_threads[i].memory != NULL)
	    gs_memory_chunk_release(crdev->render_threads[i].memory); 
    }
    /* If we weren't able to create at least one thread, punt	*/
    /* Although a single thread isn't any more efficient, the	*/
    /* machinery still works, so that's OK.			*/
    if (i == 0) {
	if (crdev->render_threads[0].memory != NULL)
	    gs_memory_chunk_release(crdev->render_threads[0].memory); 
	gs_free_object(mem, crdev->render_threads, "clist_setup_render_threads");
	crdev->render_threads = NULL;
	/* restore the file pointers */
	if (cdev->page_cfile == NULL) {
	    char fmode[4];

	    strcpy(fmode, "a+");	/* file already exists and we want to re-use it */
	    strncat(fmode, gp_fmode_binary_suffix, 1);
	    cdev->page_info.io_procs->fopen(cdev->page_cfname, fmode, &cdev->page_cfile,
				mem, cdev->bandlist_memory, true);
	    cdev->page_info.io_procs->fseek(cdev->page_cfile, 0, SEEK_SET, cdev->page_cfname);
	    cdev->page_info.io_procs->fopen(cdev->page_bfname, fmode, &cdev->page_bfile,
				mem, cdev->bandlist_memory, false);
	    cdev->page_info.io_procs->fseek(cdev->page_bfile, 0, SEEK_SET, cdev->page_bfname);
	}
	eprintf1("Rendering threads not started, code=%d.\n", code);
	return_error(code);
    }
    crdev->num_render_threads = i;
    crdev->curr_render_thread = 0;

    if(gs_debug[':'] != 0)
	dprintf1("%% Using %d rendering threads\n", i);

    return 0;
}
Esempio n. 11
0
int eprn_open_device(gx_device *device)
{
  eprn_Eprn *eprn = &((eprn_Device *)device)->eprn;
  const char *epref = eprn->CUPS_messages? CUPS_ERRPREF: "";
  int rc;

#ifdef EPRN_TRACE
  if_debug0(EPRN_TRACE_CHAR, "! eprn_open_device()...\n");
#endif

  /* Checks on page size and determination of derived values */
  if (eprn_set_page_layout((eprn_Device *)device) != 0)
    return_error(gs_error_rangecheck);

  /* Check the rendering parameters */
  if (eprn_check_colour_info(eprn->cap->colour_info, &eprn->colour_model,
      &device->HWResolution[0], &device->HWResolution[1],
      &eprn->black_levels, &eprn->non_black_levels) != 0) {
    gs_param_string str;

    eprintf1("%s" ERRPREF "The requested combination of colour model (",
      epref);
    str.size = 0;
    if (eprn_get_string(eprn->colour_model, eprn_colour_model_list, &str) != 0)
      assert(0); /* Bug. No harm on NDEBUG because I've just set the size. */
    errwrite(device->memory, (const char *)str.data, str.size * sizeof(str.data[0]));
    eprintf7("),\n"
      "%s  resolution (%gx%g ppi) and intensity levels (%d, %d) is\n"
      "%s  not supported by the %s.\n",
      epref, device->HWResolution[0], device->HWResolution[1],
      eprn->black_levels, eprn->non_black_levels, epref, eprn->cap->name);
    return_error(gs_error_rangecheck);
  }

  /* Initialization for colour rendering */
  if (device->color_info.num_components == 4) {
    /* Native colour space is 'DeviceCMYK' */
    set_dev_proc(device, map_rgb_color, NULL);

    if (eprn->intensity_rendering == eprn_IR_FloydSteinberg)
      set_dev_proc(device, map_cmyk_color, &eprn_map_cmyk_color_max);
    else if (device->color_info.max_gray > 1 || device->color_info.max_color > 1)
      set_dev_proc(device, map_cmyk_color, &eprn_map_cmyk_color_flex);
    else
      set_dev_proc(device, map_cmyk_color, &eprn_map_cmyk_color);

    if (eprn->intensity_rendering == eprn_IR_FloydSteinberg)
      set_dev_proc(device, map_rgb_color, &eprn_map_rgb_color_for_CMY_or_K_max);
    else if (device->color_info.max_gray > 1 || device->color_info.max_color > 1)
      set_dev_proc(device, map_rgb_color, &eprn_map_rgb_color_for_CMY_or_K_flex);
    else
      set_dev_proc(device, map_rgb_color, &eprn_map_rgb_color_for_CMY_or_K);

  }
  else {
    set_dev_proc(device, map_cmyk_color, NULL);

    if (eprn->colour_model == eprn_DeviceRGB) {
      if (eprn->intensity_rendering == eprn_IR_FloydSteinberg)
        set_dev_proc(device, map_rgb_color, &eprn_map_rgb_color_for_RGB_max);
      else if (device->color_info.max_color > 1)
        set_dev_proc(device, map_rgb_color, &eprn_map_rgb_color_for_RGB_flex);
      else
        set_dev_proc(device, map_rgb_color, &eprn_map_rgb_color_for_RGB);
    } else {
      if (eprn->intensity_rendering == eprn_IR_FloydSteinberg)
        set_dev_proc(device, map_rgb_color, &eprn_map_rgb_color_for_CMY_or_K_max);
      else if (device->color_info.max_gray > 1 || device->color_info.max_color > 1)
        set_dev_proc(device, map_rgb_color, &eprn_map_rgb_color_for_CMY_or_K_flex);
      else
        set_dev_proc(device, map_rgb_color, &eprn_map_rgb_color_for_CMY_or_K);
    }
  }
  eprn->output_planes = eprn_bits_for_levels(eprn->black_levels) +
    3 * eprn_bits_for_levels(eprn->non_black_levels);

#if !defined(GS_REVISION) || GS_REVISION >= 600
  /*  According to my understanding, the following call should be superfluous
      (because the colour mapping functions may not be called while the device
      is closed) and I am also not aware of any situation where it does make a
      difference. It shouldn't do any harm, though, and I feel safer with it :-)
  */
  gx_device_decache_colors(device);
#endif

#ifndef EPRN_NO_PAGECOUNTFILE
  /* Read the page count value */
  if (eprn->pagecount_file != NULL) {
    unsigned long count;
    if (pcf_getcount(eprn->pagecount_file, &count) == 0)
      device->PageCount = count;
       /* unsigned to signed. The C standard permits
          an implementation to generate an overflow indication if the value is
          too large. I consider this to mean that the type of 'PageCount' is
          inappropriate :-). Note that eprn does not use 'PageCount' for
          updating the file. */
    else {
      /* pcf_getcount() has issued an error message. */
      eprintf(
        "  No further attempts will be made to access the page count file.\n");
      gs_free(device->memory->non_gc_memory, eprn->pagecount_file, strlen(eprn->pagecount_file) + 1,
        sizeof(char), "eprn_open_device");
      eprn->pagecount_file = NULL;
    }
  }
#endif  /* !EPRN_NO_PAGECOUNTFILE */

  /* Open the "prn" device part */
  if ((rc = gdev_prn_open(device)) != 0) return rc;

  /* Just in case a previous open call failed in a derived device (note that
     'octets_per_line' is still the same as then): */
  if (eprn->scan_line.str != NULL)
    gs_free(device->memory->non_gc_memory, eprn->scan_line.str, eprn->octets_per_line, sizeof(eprn_Octet),
      "eprn_open_device");
  if (eprn->next_scan_line.str != NULL) {
    gs_free(device->memory->non_gc_memory, eprn->next_scan_line.str, eprn->octets_per_line, sizeof(eprn_Octet),
      "eprn_open_device");
    eprn->next_scan_line.str = NULL;
  }

  /* Calls which might depend on prn having been initialized */
  eprn->octets_per_line = gdev_prn_raster((gx_device_printer *)device);
  eprn->scan_line.str = (eprn_Octet *) gs_malloc(device->memory->non_gc_memory, eprn->octets_per_line,
    sizeof(eprn_Octet), "eprn_open_device");
  if (eprn->intensity_rendering == eprn_IR_FloydSteinberg) {
    eprn->next_scan_line.str = (eprn_Octet *) gs_malloc(device->memory->non_gc_memory, eprn->octets_per_line,
      sizeof(eprn_Octet), "eprn_open_device");
    if (eprn->next_scan_line.str == NULL && eprn->scan_line.str != NULL) {
      gs_free(device->memory->non_gc_memory, eprn->scan_line.str, eprn->octets_per_line, sizeof(eprn_Octet),
        "eprn_open_device");
      eprn->scan_line.str = NULL;
    }
  }
  if (eprn->scan_line.str == NULL) {
    eprintf1("%s" ERRPREF
      "Memory allocation failure from gs_malloc() in eprn_open_device().\n",
      epref);
    return_error(gs_error_VMerror);
  }

  return rc;
}
Esempio n. 12
0
int eprn_set_page_layout(eprn_Device *dev)
{
  bool
    no_match = true,
     /* Are the requested flags supported for some size? */
    landscape = dev->MediaSize[0] > dev->MediaSize[1];
     /* It's not documented, but 'MediaSize' is the requested "PageSize" page
        device parameter value and hence is to be interpreted in default (not
        default default!) user space. */
  const char *epref = dev->eprn.CUPS_messages? CUPS_ERRPREF: "";
  const eprn_CustomPageDescription
    *best_cmatch = NULL;        /* best custom page size match */
  eprn_Eprn
    *eprn = &dev->eprn;
  const eprn_PageDescription
    *best_cdmatch = NULL,     /* best custom page size match in discrete list*/
    *best_dmatch = NULL,        /* best discrete match */
    *pd;                        /* loop variable */
  float
    /* Page width and height in bp with w <= h (in a moment): */
    w = dev->MediaSize[0],
    h = dev->MediaSize[1],
    /* pixmap device space margins in bp (canonical order): */
    margins[4];
  int
    quarters;
  ms_MediaCode
    desired = eprn->desired_flags;

#ifdef EPRN_TRACE
  if_debug3(EPRN_TRACE_CHAR,
    "! eprn_set_page_layout(): PageSize = [%.0f %.0f], "
      "desired_flags = 0x%04X.\n",
    dev->MediaSize[0], dev->MediaSize[1], (unsigned int)desired);
#endif

  /* Ensure w <= h */
  if (w > h) {
    float temp;
    temp = w; w = h; h = temp;
    /* This has effectively split 'MediaSize[]' into 'w', 'h' and 'landscape'.
     */
  }

  /* Initialization of primary return value */
  eprn->code = ms_none;

  /* Put the LeadingEdge value into the desired flag pattern if it's set */
  if (eprn->leading_edge_set) {
    if (eprn->default_orientation % 2 == 0)     /* true on short edge first */
      desired &= ~MS_TRANSVERSE_FLAG;
    else
      desired |= MS_TRANSVERSE_FLAG;
  }

  /* Find best match in discrete sizes */
  if (eprn->media_overrides == NULL) pd = eprn->cap->sizes;
  else pd = eprn->media_overrides;
  while (pd->code != ms_none) {
    const ms_SizeDescription *ms = ms_find_size_from_code(pd->code);
    if (ms->dimen[0] > 0.0 /* ignore variable sizes */ &&
        fabs(w - ms->dimen[0])  <= 5.0 &&
        fabs(h - ms->dimen[1]) <= 5.0) {
       /* The size does match at 5 bp tolerance. This value has been chosen
          arbitrarily to be equal to PostScript's PageSize matching tolerance
          during media selection. The tolerance should really be that at which
          the printer in question distinguishes between sizes or smaller than
          that in order to at least prevent printing on unsupported sizes.
        */
      if (best_dmatch == NULL ||
          better_flag_match(desired, eprn->optional_flags, best_dmatch->code,
            pd->code))
        best_dmatch = pd;
      if (flag_match(desired, eprn->optional_flags, pd->code))
        no_match = false;
    }
    pd++;
  }

  /* Next find the best match among the custom size descriptions */
  if (eprn->cap->custom != NULL) {
    const eprn_CustomPageDescription *cp = eprn->cap->custom;

    /* First check whether the size is in the supported range */
    while (cp->width_max > 0.0) {
      if (cp->width_min  <= w && w <= cp->width_max &&
          cp->height_min <= h && h <= cp->height_max) {
        /* The size does match. */
        if (best_cmatch == NULL ||
            better_flag_match(desired, eprn->optional_flags, best_cmatch->code,
              cp->code))
          best_cmatch = cp;
        if (eprn->media_overrides == NULL &&
            flag_match(desired, eprn->optional_flags, cp->code))
          no_match = false;
      }
      cp++;
    }

    /* If we have read a media configuration file, the flags to be matched
       must be sought in 'media_overrides'. */
    if (best_cmatch != NULL && eprn->media_overrides != NULL) {
      for (pd = eprn->media_overrides; pd->code != ms_none; pd++) {
        if (ms_without_flags(pd->code) == ms_CustomPageSize) {
          if (best_cdmatch == NULL ||
              better_flag_match(desired, eprn->optional_flags,
                best_cdmatch->code, pd->code))
            best_cdmatch = pd;
          if (flag_match(desired, eprn->optional_flags, pd->code))
            no_match = false;
        }
      }
    }
  }

  /*  Now the 'best_*match' variables indicate for each of the categories of
      page descriptions to which extent the size is supported at all (non-NULL
      value) and what the best flag match in the category is. Here we now check
      for NULL values, i.e., size matches. */
  if (best_dmatch == NULL) {
    /* No discrete match */
    if (best_cmatch == NULL) {
      /* No match at all. */
      eprintf3("%s" ERRPREF
        "This document requests a page size of %.0f x %.0f bp.\n",
           epref, dev->MediaSize[0], dev->MediaSize[1]);
      if (eprn->cap->custom == NULL) {
        /* The printer does not support custom page sizes */
        if (eprn->media_overrides != NULL)
          eprintf1(
            "%s  The media configuration file does not contain an entry for "
              " this size.\n", epref);
        else
          eprintf2("%s  This size is not supported by the %s.\n",
            epref, eprn->cap->name);
      }
      else
        eprintf3(
          "%s  This size is not supported as a discrete size and it exceeds "
            "the\n"
          "%s  custom page size limits for the %s.\n",
          epref, epref, eprn->cap->name);
      return -1;
    }
    if (eprn->media_overrides != NULL && best_cdmatch == NULL) {
      eprintf6("%s" ERRPREF
        "This document requests a page size of %.0f x %.0f bp\n"
        "%s  but there is no entry for this size in the "
          "media configuration file\n"
        "%s  %s.\n",
        epref, dev->MediaSize[0], dev->MediaSize[1], epref, epref,
        eprn->media_file);
      return -1;
    }
  }
  /* Now we have: best_dmatch != NULL || best_cmatch != NULL &&
     (eprn->media_overrides == NULL || best_cdmatch != NULL). */

  /* Find a flag match among the size matches found so far */
  {
    ms_MediaCode custom_code = ms_none;
      /* best custom page size match (either from cmatch or dcmatch) */
    if (best_cmatch != NULL &&
        (eprn->media_overrides == NULL || best_cdmatch != NULL))
      custom_code = (eprn->media_overrides == NULL?
        best_cmatch->code: best_cdmatch->code);

    if (best_dmatch == NULL ||
        best_cmatch != NULL &&
          better_flag_match(desired, eprn->optional_flags, best_dmatch->code,
            custom_code)) {
      if (flag_match(desired, eprn->optional_flags, custom_code)) {
        if (eprn->media_overrides == NULL) {
          eprn->code = best_cmatch->code;
          margins[0] = best_cmatch->left;
          margins[1] = best_cmatch->bottom;
          margins[2] = best_cmatch->right;
          margins[3] = best_cmatch->top;
        }
        else {
          eprn->code = best_cdmatch->code;
          margins[0] = best_cdmatch->left;
          margins[1] = best_cdmatch->bottom;
          margins[2] = best_cdmatch->right;
          margins[3] = best_cdmatch->top;
        }
      }
    }
    else {
      if (flag_match(desired, eprn->optional_flags, best_dmatch->code)) {
        eprn->code = best_dmatch->code;
        margins[0] = best_dmatch->left;
        margins[1] = best_dmatch->bottom;
        margins[2] = best_dmatch->right;
        margins[3] = best_dmatch->top;
      }
    }
  }
  /* If we've found a match, 'code' is no longer 'ms_none'. */
  if (eprn->code == ms_none) {
    eprn_flag_mismatch(eprn, no_match);
    return -1;
  }

  /* Adapt the orientation of default default user space if not prescribed */
  if (!eprn->leading_edge_set) {
    if (eprn->code & MS_TRANSVERSE_FLAG) eprn->default_orientation = 3;
     /* This leads to 0 if landscape orientation is requested. */
    else eprn->default_orientation = 0;
  }

  /*
    Now 'eprn->default_orientation % 2' describes the sheet's orientation in
    pixmap device space. If this does not agree with the width and height
    values in the device instance, we'll have to adapt them.
    This is only necessary if there is a significant difference between width
    and height.
   */
  if (fabs(w - h) > 1 /* arbitrary */ &&
    (eprn->default_orientation % 2 == 0) !=
        (dev->width/dev->HWResolution[0] <= dev->height/dev->HWResolution[1])) {
    bool reallocate = false;

#ifdef EPRN_TRACE
    if_debug0(EPRN_TRACE_CHAR,
      "! eprn_set_page_layout(): width-height change is necessary.\n");
#endif

    /* Free old storage if the device is open */
    if (dev->is_open) {
#ifdef EPRN_TRACE
      if_debug0(EPRN_TRACE_CHAR, "! eprn_set_page_layout(): Device is open.\n");
#endif
      reallocate = true;
       /* One could try and call the allocation/reallocation routines of the
          prn device directly, but they are not available in older ghostscript
          versions and this method is safer anyway because it relies on a
          documented API. */
      gdev_prn_close((gx_device *)dev);         /* ignore the result */
    }

    /*  Now set width and height via gx_device_set_media_size(). This function
        sets 'MediaSize[]', 'width', and 'height' based on the assumption that
        default user space has a y axis which is vertical in pixmap device
        space. This may be wrong and we have to fix it. Because fixing
        'MediaSize[]' is simpler, gx_device_set_media_size() is called such
        that it gives the correct values for 'width' and 'height'. */
    if (eprn->default_orientation % 2 == 0) {
      /* portrait orientation of the sheet in pixmap device space */
      gx_device_set_media_size((gx_device *)dev, w, h);
      if (landscape) {
        dev->MediaSize[0] = h;
        dev->MediaSize[1] = w;
      }
    }
    else {
      /* landscape orientation in pixmap device space (transverse) */
      gx_device_set_media_size((gx_device *)dev, h, w);
      if (!landscape) {
        dev->MediaSize[0] = w;
        dev->MediaSize[1] = h;
      }
    }

    /* If the device is/was open, reallocate storage */
    if (reallocate) {
      int rc;

      rc = gdev_prn_open((gx_device *)dev);
      if (rc < 0) {
        eprintf2("%s" ERRPREF
          "Failure of gdev_prn_open(), code is %d.\n",
          epref, rc);
        return rc;
      }
    }
  }

  /* Increase the bottom margin for coloured modes except if it is exactly
     zero */
  if (eprn->colour_model != eprn_DeviceGray && margins[1] != 0.0)
    margins[1] += eprn->cap->bottom_increment;

  /* Number of +90-degree rotations needed for default user space: */
  quarters = eprn->default_orientation;
  if (landscape) quarters = (quarters + 1)%4;

  /* Store the top and left margins in the device structure for use by
     eprn_get_initial_matrix() and set the margins of the printable area if
     we may.
     gx_device_set_margins() (see gsdevice.c) copies the margins[] array to
     HWMargins[] which is presumably to be interpreted in default user space
     (see gs_initclip() in gspath.c), and if its second argument is true it
     also modifies the offset variable Margins[]. The first property means
     that gx_device_set_margins() can only be used if default user space and
     pixmap device space have the same "up" direction, and the second
     appropriates a parameter which is intended for the user.
  */
  if (eprn->keep_margins) {
    eprn->down_shift  = dev->HWMargins[3 - quarters];
    eprn->right_shift = dev->HWMargins[(4 - quarters)%4];
  }
  else {
    int j;

    eprn->down_shift  = margins[3];
    eprn->right_shift = margins[0];

    if (quarters != 0) {
       /* The "canonical margin order" for ghostscript is left, bottom, right,
          top. Hence for, e.g., a +90-degree rotation ('quarters' is 1) of
          default user space with respect to pixmap device space the left
          margin (index 0) in default user space is actually the bottom margin
          (index 1) in pixmap device space, the bottom margin is the right one,
          etc.
        */
      for (j = 0; j < 4; j++) dev->HWMargins[j] = margins[(j+quarters)%4];
      /* 'HWMargins[]' is in bp (see gxdevcli.h) */
    }
    else {
      /* Convert to inches */
      for (j = 0; j < 4; j++) margins[j] /= BP_PER_IN;

      gx_device_set_margins((gx_device *)dev, margins, false);
       /* Of course, I could set HWMargins[] directly also in this case. This
          way is however less prone to break on possible future incompatible
          changes to ghostscript and it covers the most frequent case (portrait
          and short edge first). */
    }
  }

  return 0;
}
Esempio n. 13
0
/* if filename is NULL, return 0 if spool queue is valid, non-zero if error */
int
pm_spool(char *filename, const char *queue)
{
    HSPL hspl;
    PDEVOPENSTRUC pdata;
    PSZ pszToken = "*";
    ULONG jobid;
    BOOL rc;
    char queue_name[256];
    char driver_name[256];
    char *buffer;
    FILE *f;
    int count;

    if (strlen(queue) != 0) {
	/* queue specified */
	strcpy(queue_name, queue + 8);	/* skip over \\spool\ */
    } else {
	/* get default queue */
	queue_name[0] = '\0';
    }
    if (pm_find_queue(queue_name, driver_name)) {
	/* error, list valid queue names */
	eprintf("Invalid queue name.  Use one of:\n");
	pm_find_queue(NULL, NULL);
	return 1;
    }
    if (!filename)
	return 0;		/* we were only asked to check the queue */


    if ((buffer = malloc(PRINT_BUF_SIZE)) == (char *)NULL) {
	eprintf("Out of memory in pm_spool\n");
	return 1;
    }
    if ((f = fopen(filename, "rb")) == (FILE *) NULL) {
	free(buffer);
	eprintf1("Can't open temporary file %s\n", filename);
	return 1;
    }
    /* Allocate memory for pdata */
    if (!DosAllocMem((PVOID) & pdata, sizeof(DEVOPENSTRUC),
		     (PAG_READ | PAG_WRITE | PAG_COMMIT))) {
	/* Initialize elements of pdata */
	pdata->pszLogAddress = queue_name;
	pdata->pszDriverName = driver_name;
	pdata->pdriv = NULL;
	pdata->pszDataType = "PM_Q_RAW";
	pdata->pszComment = "Ghostscript";
	pdata->pszQueueProcName = NULL;
	pdata->pszQueueProcParams = NULL;
	pdata->pszSpoolerParams = NULL;
	pdata->pszNetworkParams = NULL;

	hspl = SplQmOpen(pszToken, 4L, (PQMOPENDATA) pdata);
	if (hspl == SPL_ERROR) {
	    eprintf("SplQmOpen failed.\n");
	    DosFreeMem((PVOID) pdata);
	    free(buffer);
	    fclose(f);
	    return 1;		/* failed */
	}
	rc = SplQmStartDoc(hspl, "Ghostscript");
	if (!rc) {
	    eprintf("SplQmStartDoc failed.\n");
	    DosFreeMem((PVOID) pdata);
	    free(buffer);
	    fclose(f);
	    return 1;
	}
	/* loop, copying file to queue */
	while (rc && (count = fread(buffer, 1, PRINT_BUF_SIZE, f)) != 0) {
	    rc = SplQmWrite(hspl, count, buffer);
	    if (!rc)
		eprintf("SplQmWrite failed.\n");
	}
	free(buffer);
	fclose(f);

	if (!rc) {
	    eprintf("Aborting Spooling.\n");
	    SplQmAbort(hspl);
	} else {
	    SplQmEndDoc(hspl);
	    rc = SplQmClose(hspl);
	    if (!rc)
		eprintf("SplQmClose failed.\n");
	}
    } else
	rc = 0;			/* no memory */
    return !rc;
}
Esempio n. 14
0
/* returns 0 if OK, non-zero for error */
int
pm_find_queue(char *queue_name, char *driver_name)
{
    SPLERR splerr;
    USHORT jobCount;
    ULONG cbBuf;
    ULONG cTotal;
    ULONG cReturned;
    ULONG cbNeeded;
    ULONG ulLevel;
    ULONG i;
    PSZ pszComputerName;
    PBYTE pBuf;
    PPRQINFO3 prq;

    ulLevel = 3L;
    pszComputerName = (PSZ) NULL;
    splerr = SplEnumQueue(pszComputerName, ulLevel, pBuf, 0L,	/* cbBuf */
			  &cReturned, &cTotal,
			  &cbNeeded, NULL);
    if (splerr == ERROR_MORE_DATA || splerr == NERR_BufTooSmall) {
	if (!DosAllocMem((PVOID) & pBuf, cbNeeded,
			 PAG_READ | PAG_WRITE | PAG_COMMIT)) {
	    cbBuf = cbNeeded;
	    splerr = SplEnumQueue(pszComputerName, ulLevel, pBuf, cbBuf,
				  &cReturned, &cTotal,
				  &cbNeeded, NULL);
	    if (splerr == NO_ERROR) {
		/* Set pointer to point to the beginning of the buffer.           */
		prq = (PPRQINFO3) pBuf;

		/* cReturned has the count of the number of PRQINFO3 structures.  */
		for (i = 0; i < cReturned; i++) {
		    if (queue_name) {
			/* find queue name and return driver name */
			if (strlen(queue_name) == 0) {	/* use default queue */
			    if (prq->fsType & PRQ3_TYPE_APPDEFAULT)
				strcpy(queue_name, prq->pszName);
			}
			if (strcmp(prq->pszName, queue_name) == 0) {
			    char *p;

			    for (p = prq->pszDriverName; *p && (*p != '.'); p++)
				/* do nothing */ ;
			    *p = '\0';	/* truncate at '.' */
			    if (driver_name != NULL)
				strcpy(driver_name, prq->pszDriverName);
			    DosFreeMem((PVOID) pBuf);
			    return 0;
			}
		    } else {
			/* list queue details */
			if (prq->fsType & PRQ3_TYPE_APPDEFAULT)
			    eprintf1("  \042%s\042  (DEFAULT)\n", prq->pszName);
			else
			    eprintf1("  \042%s\042\n", prq->pszName);
		    }
		    prq++;
		}		/*endfor cReturned */
	    }
	    DosFreeMem((PVOID) pBuf);
	}
    }
    /* end if Q level given */ 
    else {
	/* If we are here we had a bad error code. Print it and some other info. */
	eprintf4("SplEnumQueue Error=%ld, Total=%ld, Returned=%ld, Needed=%ld\n",
		splerr, cTotal, cReturned, cbNeeded);
    }
    if (splerr)
	return splerr;
    if (queue_name)
	return -1;
    return 0;
}
Esempio n. 15
0
/* Write the actual file name at fname. */
FILE *
gp_open_scratch_file(const char *prefix, char *fname, const char *mode)
{
    UINT n;
    DWORD l;
    HANDLE hfile = INVALID_HANDLE_VALUE;
    int fd = -1;
    FILE *f = NULL;
    char sTempDir[_MAX_PATH];
    char sTempFileName[_MAX_PATH];

    memset(fname, 0, gp_file_name_sizeof);
    if (!gp_file_name_is_absolute(prefix, strlen(prefix))) {
	int plen = sizeof(sTempDir);

	if (gp_gettmpdir(sTempDir, &plen) != 0)
	    l = GetTempPath(sizeof(sTempDir), sTempDir);
	else
	    l = strlen(sTempDir);
    } else {
	strncpy(sTempDir, prefix, sizeof(sTempDir));
	prefix = "";
	l = strlen(sTempDir);
    }
    /* Fix the trailing terminator so GetTempFileName doesn't get confused */
    if (sTempDir[l-1] == '/')
	sTempDir[l-1] = '\\';		/* What Windoze prefers */

    if (l <= sizeof(sTempDir)) {
	n = GetTempFileName(sTempDir, prefix, 0, sTempFileName);
	if (n == 0) {
	    /* If 'prefix' is not a directory, it is a path prefix. */
	    int l = strlen(sTempDir), i;

	    for (i = l - 1; i > 0; i--) {
		uint slen = gs_file_name_check_separator(sTempDir + i, l, sTempDir + l);

		if (slen > 0) {
		    sTempDir[i] = 0;   
		    i += slen;
		    break;
		}
	    }
	    if (i > 0)
		n = GetTempFileName(sTempDir, sTempDir + i, 0, sTempFileName);
	}
	if (n != 0) {
	    hfile = CreateFile(sTempFileName, 
		GENERIC_READ | GENERIC_WRITE | DELETE,
		FILE_SHARE_READ | FILE_SHARE_WRITE, NULL, CREATE_ALWAYS,
		FILE_ATTRIBUTE_NORMAL /* | FILE_FLAG_DELETE_ON_CLOSE */, 
		NULL);
	    /*
	     * Can't apply FILE_FLAG_DELETE_ON_CLOSE due to 
	     * the logics of clist_fclose. Also note that
	     * gdev_prn_render_pages requires multiple temporary files
	     * to exist simultaneousely, so that keeping all them opened
	     * may exceed available CRTL file handles.
	     */
	}
    }
    if (hfile != INVALID_HANDLE_VALUE) {
	/* Associate a C file handle with an OS file handle. */
	fd = _open_osfhandle((long)hfile, 0);
	if (fd == -1)
	    CloseHandle(hfile);
	else {
	    /* Associate a C file stream with C file handle. */
	    f = fdopen(fd, mode);
	    if (f == NULL)
		_close(fd);
	}
    }
    if (f != NULL) {
	if ((strlen(sTempFileName) < gp_file_name_sizeof))
	    strncpy(fname, sTempFileName, gp_file_name_sizeof - 1);
	else {
	    /* The file name is too long. */
	    fclose(f);
	    f = NULL;
	}
    }
    if (f == NULL)
	eprintf1("**** Could not open temporary file '%s'\n", fname);
    return f;
}