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

📄 gvpm.c

📁 GSview 4.6 PostScript previewer。Ghostscript在MS-Windows, OS/2 and Unix下的图形化接口
💻 C
📖 第 1 页 / 共 5 页
字号:
/* Copyright (C) 1993-2002, Ghostgum Software Pty Ltd.  All rights reserved.
  
  This file is part of GSview.
  
  This program is distributed with NO WARRANTY OF ANY KIND.  No author
  or distributor accepts any responsibility for the consequences of using it,
  or for whether it serves any particular purpose or works at all, unless he
  or she says so in writing.  Refer to the GSview Free Public Licence 
  (the "Licence") for full details.
  
  Every copy of GSview must include a copy of the Licence, normally in a 
  plain ASCII text file named LICENCE.  The Licence grants you the right 
  to copy, modify and redistribute GSview, but only under certain conditions 
  described in the Licence.  Among other things, the Licence requires that 
  the copyright notice and this notice be preserved on all copies.
*/

/* gvpm.c */
/* Main routines for PM GSview */
#define INCL_WINSTDDRAG
#include "gvpm.h"
#ifdef __EMX__
#include "sys/ioctl.h"
#endif

#include <signal.h>
#include <setjmp.h>

char szAppName[MAXSTR] = GSVIEW_PRODUCT;  /* application name - for title bar */
int nHelpTopic;
char szWait[MAXSTR];
char szExePath[MAXSTR];
char szHelpName[MAXSTR];
char szFindText[MAXSTR];
char szIniFile[MAXSTR];
unsigned char szMMini[MAXSTR];
char previous_filename[MAXSTR];
char selectname[MAXSTR];
const char szScratch[] = "gv";	/* temporary filename prefix */
char *szSpoolPrefix = "\\\\spool\\";
HMTX hmutex_ps;
HAB hab;		/* Anchor Block */
HMQ hand_mq;		/* message queue */
ULONG os_version;
BOOL multithread;
HWND hwnd_frame;	/* main window */
HWND hwnd_bmp;		/* client area of main window */
HWND hwnd_image;	/* full screen popup or child window */
HWND hwnd_fullscreen;	/* full screen popup */
HWND hwnd_status;
HWND hwnd_button;
HWND hwnd_help;
HWND hwnd_modeless;	/* any modeless dialog box */
HWND hwnd_measure;		/* measure modeless dialog box */
HWND hptr_crosshair;
HWND hptr_hand;
HWND hwnd_menu;
HACCEL haccel;
HMODULE hlanguage;
POINTL buttonbar;
POINTL statusbar;
POINTL info_file;
POINTL info_page;
POINTL scroll_pos;
RECTL info_coord;
int on_link;			/* TRUE if we were or are over link */
int on_link_page;		/* page number of link target */
const char *on_link_action;	/* action of link target */
long gsbytes_size;		/* number of bytes for this page */
long gsbytes_done;		/* number of byte written */
BOOL fit_page_enabled = FALSE;	/* next WM_SIZE is allowed to resize window */
BOOL quitnow = FALSE;		/* Used to cause exit from nested message loops */

int percent_done;		/* percentage of document processed */
int percent_pending;		/* TRUE if WM_GSPERCENT is pending */

#define MAXARGS 64
int nargc;
char *nargv[MAXARGS];
GSVIEW_ARGS args;		/* Parsed arguments */
PSFILE psfile;		/* Postscript file structure */
BMAP bitmap;		/* Bitmap structure */
OPTIONS option;		/* GSview options (saved in INI file) */
DISPLAY display;	/* Display parameters */
PRINTER printer;	/* Printer GS parameters */
char last_files[4][MAXSTR];	/* last 4 files used */
int last_files_count;		/* number of files known */
HISTORY history;		/* history of pages displayed */
BOOL fullscreen = FALSE;

int page_skip = 5;		/* number of pages to skip in IDM_NEXTSKIP or IDM_PREVSKIP */
BOOL zoom = FALSE;		/* true if display zoomed */
BOOL print_silent = FALSE;	/* /P or /F command line option used */
BOOL print_exit = FALSE;	/* exit on completion of printing */
int print_count = 0;		/* number of current print jobs */
				/* It is safe to exit GSview when this is 0 */
int debug = 0;			/* /D command line option used */
struct sound_s sound[NUMSOUND] = {
	{"SoundOutputPage", IDS_SNDPAGE, ""},
	{"SoundNoPage", IDS_SNDNOPAGE, BEEP},
	{"SoundNoNumbering", IDS_SNDNONUMBER, ""},
	{"SoundNotOpen", IDS_SNDNOTOPEN, ""},
	{"SoundError", IDS_SNDERROR, BEEP},
	{"SoundStart", IDS_SNDSTART, ""},
	{"SoundExit", IDS_SNDEXIT, ""},
	{"SoundBusy", IDS_SNDBUSY, BEEP},
};
PFN_MciPlayFile pfnMciPlayFile;
USERMEDIA usermedia[IDM_USERSIZE13 - IDM_USERSIZE1 + 1];

/* button bar */
void delete_buttons(void);
struct button *buttonhead, *buttontail;
BOOL button_down;
struct button *button_current;
struct button *button_info;
POINTL button_shift;
POINTL button_size;

MRESULT EXPENTRY ClientWndProc(HWND, ULONG, MPARAM, MPARAM);
MRESULT EXPENTRY FrameWndProc(HWND, ULONG, MPARAM, MPARAM);
MRESULT EXPENTRY StatusWndProc(HWND, ULONG, MPARAM, MPARAM);
MRESULT EXPENTRY ButtonWndProc(HWND, ULONG, MPARAM, MPARAM);
PFNWP OldFrameWndProc;

BOOL scan_bitmap(BMAP *pbm);
HBITMAP make_bitmap(BMAP *, ULONG, ULONG, ULONG, ULONG, ULONG);
void cursorpos_paint(HPS hps);
void map_pt_to_pixel(float *x, float *y);
MRESULT DragOver(PDRAGINFO);
MRESULT Drop(PDRAGINFO);
void highlight_words(HPS ps, int first, int last);
BOOL text_marking = FALSE;
int text_mark_first = -1;
int text_mark_last = -1;
void highlight_links(HPS ps);
void info_link(void);

void
update_scroll_bars(void)
{
    /* Cause update of scroll bars etc. */
    SWP swp;
    WinQueryWindowPos(hwnd_image, &swp);
    WinSendMsg(hwnd_image, WM_SIZE, MPFROM2SHORT(swp.cx, swp.cy), MPFROM2SHORT(swp.cx, swp.cy));
}



/* Return TRUE if is OK to exit */
BOOL
query_close(void)
{
    /* tell GS DLL to unload */
    request_mutex();
    pending.unload = TRUE;
    pending.abort = TRUE;
    quitnow = TRUE;
    release_mutex();
    if (multithread)
        DosPostEventSem(display.event);	/* unblock display thread */
    return TRUE;
}

void
exit_func(void)
{
    psfile_free(&psfile);
    if (option.settings && !print_silent)
	write_profile();
    else
	write_profile_last_files();	/* always save MRU files */
    unload_zlib();
    unload_pstoedit();
    if (debug & DEBUG_MEM) {
	/* flush message queue of quit message */
        QMSG q_mess;		/* queue message */
	WinPeekMsg(hab, &q_mess, 0L, 0, 0, PM_REMOVE);
	WinPeekMsg(hab, &q_mess, 0L, 0, 0, PM_REMOVE);
	WinPeekMsg(hab, &q_mess, 0L, 0, 0, PM_REMOVE);
	WinPeekMsg(hab, &q_mess, 0L, 0, 0, PM_REMOVE);
	debug_memory_report();
    }
    language_free();
}


/* code to protect GSview against Ghostscript memory violations */
jmp_buf sig_env;

void
sig_handler(int code)
{
	signal(code, SIG_ACK); 
	longjmp(sig_env, 1);
}

void
gs_sig_process()
{
    if (setjmp(sig_env) == 0) {
	/* got here on direct call */
	signal(SIGSEGV, sig_handler);
	signal(SIGFPE, sig_handler);
        gs_process();	/* start Ghostscript */
    }
    else {
	/* got here by calling longjmp */
	pending.now = FALSE;
	delayed_message_box(IDS_SIGSEGV, 0);
    }
    signal(SIGFPE, SIG_DFL);	/* restore default handler */
    signal(SIGSEGV, SIG_DFL);	/* restore default handler */
}


/* Thread which loads Ghostscript DLL for display */
void 
gs_thread(void *arg)
{
HAB hab;
    hab = WinInitialize(0);
    while (!quitnow) {
	if (!pending.now)
	    wait_event();
	if (!quitnow)
	    gs_sig_process();
    }

    WinTerminate(hab);
    /* signal that we have finished */
    display.tid = 0;
}


int
main(int argc, char *argv[])
{
  QMSG q_mess;		/* queue message */
  APIRET rc = 0;

  hab = WinInitialize(0);	/* Get the Anchor Block */

  hand_mq = WinCreateMsgQueue(hab, 0); /* start a queue */

  rc = gsview_init(argc, argv);
/*
  atexit(exit_func);
*/

  if (!rc) {
	SWP swp;
	WinQueryWindowPos(hwnd_frame, &swp);
	if (print_silent) {
	    /* show minimized */
	    swp.fl &= (~SWP_MAXIMIZE);
	    swp.fl &= (~SWP_RESTORE);
	    swp.fl |= SWP_MINIMIZE | SWP_ACTIVATE | SWP_SHOW;;
	}
	else {
	    swp.fl |= SWP_ACTIVATE | SWP_SHOW;
	}
	WinSetWindowPos(hwnd_frame, HWND_TOP, swp.x, swp.y, swp.cx, swp.cy, swp.fl);
	haccel = WinQueryAccelTable(hab, hwnd_frame);
  }

  if (multithread) {
      /* start thread for displaying */
      display.tid = _beginthread(gs_thread, NULL, 131072, NULL);
  }

  play_sound(SOUND_START);
  info_wait(IDS_NOWAIT);
  if (gsview_changed())
      WinPostMsg(hwnd_bmp, WM_CLOSE, MPFROMLONG(0), MPFROMLONG(0));
  else if (!print_silent)
      /* before changing following line, please see gvcreg.cpp */
      registration_check();

  /* message loop */
  while (!rc && !quitnow && WinGetMsg(hab, &q_mess, 0L, 0, 0)) {
      WinDispatchMsg(hab, &q_mess);
      if (multithread) {
	  /* release other thread if needed */
	  if (pending.unload || pending.now || pending.next)
		DosPostEventSem(display.event);
      }
      else {
	  if (pending.now)
	    gs_sig_process();	/* start Ghostscript */
      }
  }

  if (WinIsWindow(hab, hwnd_frame))	/* don't play sound if closed using system menu */
      play_sound(SOUND_EXIT);
  if (multithread && display.tid) {
      int i = 100;	/* 10 seconds */
      pending.unload = TRUE;
      quitnow = TRUE;
      DosPostEventSem(display.event);	/* unblock display thread */
      while (i && display.tid) {
	  /* wait for thread to close */
	  DosSleep(100);
          DosPostEventSem(display.event);	/* unblock display thread */
	  i--;
	  peek_message();
      }
  }

  /* Shut down the application window and queue */
  if (hwnd_help)
      WinDestroyHelpInstance(hwnd_help);
  DosCloseMutexSem(hmutex_ps);
  WinDestroyWindow(hwnd_frame);
  hwnd_frame = (HWND)NULL;
  delete_buttons();
  WinDestroyMsgQueue(hand_mq);
  WinTerminate(hab);

  exit_func();

  return rc;
}

#define MAX_PAL_SIZE 256
void
make_palette(BMAP *pbm)
{
ULONG tbl[MAX_PAL_SIZE];
PRGB2 palptr = (PRGB2) ((PBYTE)(pbm->pbmi) + pbm->pbmi->cbFix);
RGB *old_palptr = (RGB *)palptr;
int palcount = pbm->palimportant;
int i;
BOOL old_bmp = (pbm->pbmi->cbFix == sizeof(BITMAPINFOHEADER));
    if (old_bmp) {
	for (i=0; i<palcount; i++) {
	    tbl[i] = (old_palptr->bRed<<16) + (old_palptr->bGreen<<8) + (old_palptr->bBlue);
	    old_palptr++;
	}
    }
    else {
	for (i=0; i<palcount; i++) {
	    tbl[i] = (palptr->bRed<<16) + (palptr->bGreen<<8) + (palptr->bBlue);
	    palptr++;
	}
    }
    if (display.hpal_exists)
	GpiDeletePalette(display.hpal);
    display.hpal = GpiCreatePalette(hab, 0L, LCOLF_CONSECRGB, palcount, tbl);
    display.hpal_exists = TRUE;
}


/* scan bitmap */
/* update bitmap structure */
/* return value is TRUE if bitmap dimension has changed */
BOOL
scan_bitmap(BMAP *pbm)
{
PBITMAPINFO2 pbmi;
PBITMAPINFO old_pbmi;
BOOL old_bmp;

    if (!pbm->pbmi)
	return TRUE;

    pbmi = pbm->pbmi;
    old_pbmi = (PBITMAPINFO)pbmi;
    old_bmp = (pbmi->cbFix == sizeof(BITMAPINFOHEADER));

    if (old_bmp) {
  	/* it is a BITMAPINFO */
  	switch(old_pbmi->cBitCount) {
  	  case 24:
  	    pbm->palsize = 0;
  	    break;
  	  case 8:
  	    pbm->palsize = 256;
  	    break;
  	  case 4:
  	    pbm->palsize = 16;
  	    break;
  	  case 1:
  	    pbm->palsize = 2;
  	    break;
  	  default:
  	    error_message("scan_bitmap: wrong number of bits"); /* panic */
  	    return FALSE;
	}
	pbm->palimportant = pbm->palsize;
	pbm->palsize = pbm->palsize * sizeof(RGB);
        pbm->bits   = (PBYTE)old_pbmi + old_pbmi->cbFix + pbm->palsize;
	pbm->width  = old_pbmi->cx;
	pbm->height = old_pbmi->cy;
	pbm->planes = old_pbmi->cPlanes;
	pbm->depth  = old_pbmi->cBitCount;
    }
    else {
 	/* it is a BITMAPINFO2 */
  	switch(pbmi->cBitCount) {
  	  case 24:
  	    pbm->palsize = 0;
  	    break;
  	  case 8:
  	    pbm->palsize = 256;
  	    break;
  	  case 4:
  	    pbm->palsize = 16;
  	    break;
  	  case 1:
  	    pbm->palsize = 2;
  	    break;
  	  default:
  	    error_message("scan_bitmap: wrong number of bits"); /* panic */
  	    return FALSE;
	}
	if ( (pbmi->cbFix > (&(pbmi->cclrUsed) - &(pbmi->cbFix)))
		&& (pbmi->cclrUsed != 0) && (pbmi->cBitCount != 24) )
	    pbm->palsize = pbmi->cclrUsed;
	pbm->palimportant = pbm->palsize;
	if ( (pbmi->cbFix > (&(pbmi->cclrImportant) - &(pbmi->cbFix)))
		&& (pbmi->cclrImportant != 0) && (pbmi->cBitCount != 24) )
	    pbm->palimportant = pbmi->cclrImportant;
	pbm->palsize = pbm->palsize * sizeof(RGB2);
        pbm->bits   = (PBYTE)pbmi + pbmi->cbFix + pbm->palsize;
	pbm->width  = pbmi->cx;
	pbm->height = pbmi->cy;
	pbm->planes = pbmi->cPlanes;
	pbm->depth  = pbmi->cBitCount;
    }

    if ((pbm->palsize != pbm->old_palsize) || (pbm->palimportant != pbm->old_palimportant)) {
	if ( (pbm->depth == 8) && display.hasPalMan )
	    make_palette(pbm);
	pbm->old_palimportant = pbm->palimportant;
    }

⌨️ 快捷键说明

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