⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 gvxprn.c

📁 GSview 4.6 PostScript previewer。Ghostscript在MS-Windows, OS/2 and Unix下的图形化接口
💻 C
📖 第 1 页 / 共 5 页
字号:
 * on gs_print_stdin_pipe.
 */
void print_write_fn(gpointer data, gint fd, GdkInputCondition condition)
{
    if (fd != gs_print_pipe_stdin[1]) {
	gs_addmess("print_write_fn: called with wrong source\n");
	return;
    }
    if (gs_print_file <=0) {
	gs_addmess("print_write_fn: gs_print_file is closed\n");
	return;
    }
    if (gs_print_pipe_stdin[1] == -1) {
	gs_addmess("print_write_fn: gs_print_pipe_stdin[1] is closed\n");
	return;
    }
    if (condition == GDK_INPUT_EXCEPTION) {
	/* complain */
	gs_addmess("print_write_fn: exception\n");
	close(gs_print_pipe_stdin[1]);
	gs_print_pipe_stdin[1] = -1;
	return;
    }
    else if (condition == GDK_INPUT_WRITE) {
        int pcdone;
	int bytes_written = 0;
	do {
	    if (gs_print_buffer_count == 0) {
		gs_print_buffer_count = read(gs_print_file,
			gs_print_buffer, gs_print_buffer_length);
	    }
	    if (gs_print_buffer_count == 0) {
		print_stop_stdin();
		close(gs_print_file);
		gs_print_file = -1;
	        if (gs_print_pipe_stdin[1] != -1) {
			close(gs_print_pipe_stdin[1]);
			gs_print_pipe_stdin[1] = -1;
		}
		break;
	    }
	    
	    bytes_written = write(gs_print_pipe_stdin[1], 
		gs_print_buffer+gs_print_buffer_index, gs_print_buffer_count);
	    if (bytes_written == -1) {
		break;	/* come back later */
	    }
	    else if (bytes_written == 0) {
		/* pipe probably closed */
		gs_addmess("print_write_fn: wrote 0 bytes to GS\n");
		print_check_zombie();
	    }
	    else {
		gs_print_buffer_count -= bytes_written;
		if (gs_print_buffer_count == 0)
		   gs_print_buffer_index = 0;
		else
		   gs_print_buffer_index += bytes_written;

		gs_print_bytes_done += bytes_written;
		pcdone = (int)(gs_print_bytes_done * 100 / gs_print_bytes_size);
		if (pcdone != gs_print_percent) {
		    gs_print_percent = pcdone;
		    percent_print_message(gs_print_percent);
		}
	    }

	} while (bytes_written > 0);
    }
    else {
	gs_addmessf("print_write_fn: unknown condition %d\n", condition);
    }
}

/* Asynchronous read of GS print stdout/stderr.
 * This is called from event loop when a read is possible 
 * on gs_print_stdout_pipe or gs_print_stderr_pipe.
 */
void print_read_stdout_fn(gpointer data, gint fd, GdkInputCondition condition)
{
    int is_stdout = (fd == gs_print_pipe_stdout[0]);
    int is_stderr = (fd == gs_print_pipe_stderr[0]);

    if (!is_stdout && !is_stderr) {
	gs_addmess("print_read_stdout_fn: called with wrong source\n");
	return;
    }

    if (condition == GDK_INPUT_EXCEPTION) {
	/* complain */
	gs_addmess("print_read_stdout_fn: exception\n");
	if (is_stdout)
	    print_stop_stdout();
	else
	    print_stop_stderr();
	return;
    }
    else if (condition == GDK_INPUT_READ) {
	char buf[256];
	int bytes_read = 0;
	do {
	    bytes_read = read(fd, buf, sizeof(buf));
	    if (bytes_read == -1) {
		if (errno == EAGAIN) {
		    break;	/* come back later */
		}
		else {
		    gs_addmessf("print_read_stdout_fn: read from GS failed, errno=%d\n", errno);
		}
	    }
	    else if (bytes_read == 0) {
		gs_addmessf("print_read_stdout_fn: read 0 bytes from GS %s\n",
			is_stdout ? "stdout" : "stderr");
		print_check_zombie();
	    }
	    else {
		add_print_message(buf, bytes_read);
	    }

	} while (bytes_read > 0);
    }
    else {
	gs_addmessf("print_read_stdout_fn: unknown condition %d\n", condition);
    }
}

void print_stop_stdin(void)
{
    if (gs_print_pipe_stdin_tag >=0) {
        gdk_input_remove(gs_print_pipe_stdin_tag);
	gs_print_pipe_stdin_tag = -1;
	if (debug & DEBUG_GENERAL)
	    gs_addmess("print_stop_stdin:\n");
    }
}

void print_start_stdin(void)
{
    if (gs_print_pipe_stdin_tag >=0)
	return;
    gs_print_pipe_stdin_tag = gdk_input_add(gs_print_pipe_stdin[1], 
	(GdkInputCondition)(GDK_INPUT_WRITE | GDK_INPUT_EXCEPTION),
	print_write_fn, 0);
    if (debug & DEBUG_GENERAL)
	gs_addmess("print_start_stdin:\n");
}

void print_stop_stdout(void)
{
    if (gs_print_pipe_stdout_tag >=0) {
        gdk_input_remove(gs_print_pipe_stdout_tag);
	gs_print_pipe_stdout_tag = -1;
	if (debug & DEBUG_GENERAL)
	    gs_addmess("print_stop_stdout:\n");
    }
}

void print_start_stdout(void)
{
    if (gs_print_pipe_stdout_tag >=0)
	return;
    gs_print_pipe_stdout_tag = gdk_input_add(gs_print_pipe_stdout[0], 
	(GdkInputCondition)(GDK_INPUT_READ | GDK_INPUT_EXCEPTION),
	print_read_stdout_fn, 0);
    if (debug & DEBUG_GENERAL)
	gs_addmess("print_start_stdout:\n");
}

void print_stop_stderr(void)
{
    if (gs_print_pipe_stderr_tag >=0) {
        gdk_input_remove(gs_print_pipe_stderr_tag);
	gs_print_pipe_stderr_tag = -1;
	if (debug & DEBUG_GENERAL)
	    gs_addmess("print_stop_stderr:\n");
    }
}

void print_start_stderr(void)
{
    if (gs_print_pipe_stderr_tag >=0)
	return;
    gs_print_pipe_stderr_tag = gdk_input_add(gs_print_pipe_stderr[0], 
	(GdkInputCondition)(GDK_INPUT_READ | GDK_INPUT_EXCEPTION),
	print_read_stdout_fn, 0);
    if (debug & DEBUG_GENERAL)
	gs_addmess("print_start_stderr:\n");
}


/* print will fork another process to run Ghostscript.
 * stdin will be obtained from main process
 * stdout/err will be written to a window owned by the main process.
 */
void print_start_gs(void)
{
    char *nargv[10];
    char dash_string[] = "-";
    char dashc_string[] = "-c";
    char quit_string[] = "quit";

    gs_print_file = open(printer.psname, O_RDONLY);
    if (gs_print_file == -1) {
	print_stop_gs();
	return;
    }
    gs_print_bytes_size = lseek(gs_print_file, 0, SEEK_END);
    lseek(gs_print_file, 0, SEEK_SET);
    gs_print_bytes_done = 0;
    gs_print_percent = 0;
    gs_print_buffer_count = 0;
    gs_print_buffer_index = 0;
    gs_print_buffer_length = 4096;
    gs_print_buffer = (char *)malloc(gs_print_buffer_length);
    if (gs_print_buffer == NULL) {
	print_stop_gs();
	return;
    }

    /* redirect stdio of Ghostscript */
    if (pipe(gs_print_pipe_stdin)) {
	gs_addmessf("Could not open pipe for stdin, errno=%d\n", errno);
	print_stop_gs();
	return;
    }
    if (pipe(gs_print_pipe_stdout)) {
	gs_addmessf("Could not open pipe for stdout, errno=%d\n", errno);
	print_stop_gs();
	return;
    }
    if (pipe(gs_print_pipe_stderr)) {
	gs_addmessf("Could not open pipe for stderr, errno=%d\n", errno);
	print_stop_gs();
	return;
    }
    show_print_message();

    printer.pid = fork();
    if (printer.pid == 0) {
	char atopt[MAXSTR];
	strcpy(atopt, "@");
	strcat(atopt, printer.optname);
	/* child */
	close(gs_print_pipe_stdin[1]);	/* close write handle */
	dup2(gs_print_pipe_stdin[0], 0);/* duplicate and make it stdin */
	close(gs_print_pipe_stdin[0]);	/* close original read handle */

	close(gs_print_pipe_stdout[0]);
	dup2(gs_print_pipe_stdout[1], 1);/* duplicate and make it stdout */
	close(gs_print_pipe_stdout[1]);

	close(gs_print_pipe_stderr[0]);
	dup2(gs_print_pipe_stderr[1], 2);/* duplicate and make it stderr */
	close(gs_print_pipe_stderr[1]);

	/* replace with Ghostscript */
	/* start Ghostscript */
{
char buf[MAXSTR];
FILE *f = fopen(printer.optname, "r");
while (fgets(buf, sizeof(buf), f))
    fprintf(stdout, "option: %s", buf);
fclose(f);
}
	nargv[0] = option.gsexe;
	nargv[1] = atopt;
	nargv[2] = dash_string;	/* read stdin */
	nargv[3] = dashc_string;
	nargv[4] = quit_string;
	nargv[5] = NULL;
	if (debug & DEBUG_GENERAL)
	    fprintf(stdout, "child: starting gs for printing\n");
	if (execvp(nargv[0], nargv) == -1) {
	    int j;
	    int err = errno;
	    /* write to stdout, which will be captured by GSview */
	    fprintf(stdout, "Failed to start Ghostscript process\n");
	    for (j=0; nargv[j]; j++)
		fprintf(stdout, " %s", nargv[j]);
	    fputc('\n', stdout);
	    fprintf(stdout, "  errno=%d\n", err);
	    fflush(stdout);
	    /* If we used exit(), it would call the atexit function
	     * registered by gtk, and kill all the parent's windows.
	     * Instead we use _exit() which does not call atexit functions.
	     */
	    _exit(1);
	}
    }
    else {
	/* parent */
	int flags;

	close(gs_print_pipe_stdin[0]);	/* close read handle */
	gs_print_pipe_stdin[0] = -1;
	/* make pipe non blocking */
	flags = fcntl(gs_print_pipe_stdin[1], F_GETFL, 0);
	if (fcntl(gs_print_pipe_stdin[1], F_SETFL, flags | O_NONBLOCK)) {
	    gs_addmessf("Could not set stdin pipe to non-blocking, errno=%d\n", errno);
	    print_stop_gs();
	    return;
        }

	close(gs_print_pipe_stdout[1]);	/* close write handle */
	gs_print_pipe_stdout[1] = -1;
	/* make pipe non blocking */
	flags = fcntl(gs_print_pipe_stdout[0], F_GETFL, 0);
	if (fcntl(gs_print_pipe_stdout[0], F_SETFL, flags | O_NONBLOCK)) {
	    gs_addmessf("Could not set stdout pipe to non-blocking, errno=%d\n", errno);
	    print_stop_gs();
	    return;
        }
	print_start_stdout();

	close(gs_print_pipe_stderr[1]);	/* close write handle */
	gs_print_pipe_stdout[1] = -1;
	/* make pipe non blocking */
	flags = fcntl(gs_print_pipe_stderr[0], F_GETFL, 0);
	if (fcntl(gs_print_pipe_stderr[0], F_SETFL, flags | O_NONBLOCK)) {
	    gs_addmessf("Could not set stderr pipe to non-blocking, errno=%d\n", errno);
	    print_stop_gs();
	    return;
        }
	print_start_stderr();

	/* Trigger async write */ 
	print_start_stdin();

	if (debug & DEBUG_GENERAL)
	    gs_addmess("print_start_gs: parent\n");
    } 
}

/* print a range of pages using a Ghostscript device */
void
gsview_print(BOOL convert)
{
    if (psfile.name[0] == '\0') {
	gserror(IDS_NOTOPEN, NULL, MB_ICONEXCLAMATION, SOUND_NOTOPEN);
	return;
    }

    if (option.print_method == PRINT_GDI)
	option.print_method = PRINT_GS;
    
    nHelpTopic = convert ? IDS_TOPICCONVERT : IDS_TOPICPRINT;
    if (print_dialog_box(convert) != IDOK)
	    return;

    if (!convert)
	option.print_reverse = psfile.page_list.reverse;

    if (!gsview_cprint(printer.psname, printer.optname, convert)) {
	gs_addmess("gsview_print: gsview_cprint failed\n");
	return;
    }
    if (debug & DEBUG_GENERAL)
	gs_addmessf("gsview_print: optname=%s psname=%s\n", printer.optname, printer.psname);

    /* start GS print */
    print_start_gs();

    return;
}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -