📄 gvpgs.c
字号:
/* Copyright (C) 1996-2001, 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.
*/
/* gvpgs.c */
/* Ghostscript DLL interface for GSview */
/* Usage: gvpgs [/d] dllname option filename
* dllname pathname of GS DLL, e.g. c:\gs3.33\gsdll2.dll
* option name of file containing options, one per line
* This will be given to GS as @option
* filename input file for GS
*
* WARNING: option and filename WILL BE DELETED on exit!
* gvpgs is meant to be called with temporary files
*/
#define DEBUG
#define INCL_DOS
#define INCL_WIN
#define INCL_GPI
#define INCL_DOSERRORS
#include <os2.h>
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <unistd.h>
#include "gvcrc.h"
#define P0() void
#define P1(t1) t1
#define P2(t1,t2) t1,t2
#define P3(t1,t2,t3) t1,t2,t3
#define P4(t1,t2,t3,t4) t1,t2,t3,t4
#define P5(t1,t2,t3,t4,t5) t1,t2,t3,t4,t5
#define P6(t1,t2,t3,t4,t5,t6) t1,t2,t3,t4,t5,t6
#include "errors.h"
#include "iapi.h"
#include "gvpgs.h"
MRESULT EXPENTRY ClientWndProc(HWND hwnd, ULONG mess, MPARAM mp1, MPARAM mp2);
void text_update(void);
void gs_addmess(const char *str);
void gs_addmess_count(const char *str, int count);
int parse_arg(int argc, char *argv[]);
void gs_thread(void *arg);
void show_about(void);
void saveas(void);
int init_window(HAB hab);
int message_box(char *str, int icon);
#define TWLENGTH 16384
#define TWSCROLL 1024
char twbuf[TWLENGTH];
int twend;
char stdinbuf[MAXSTR];
char *szAppName = "GSview Print";
unsigned long lsize, ldone;
int pcdone;
char title[64];
HWND hwnd_frame;
HWND hwnd_client;
HWND hwnd_text;
POINTL char_size;
int status_height;
char gsarg[2048];
TID gstid;
GSDLL gsdll;
HMTX text_mutex;
/* command line options */
int debug = 0; /* don't shut down or delete files if debugging */
char *gsdllname;
char *option;
char *filename;
FILE *infile;
char *szClass = "GSPGS_CLASS";
ULONG frame_flags =
FCF_TITLEBAR | /* have a title bar */
FCF_SIZEBORDER | /* have a sizeable window */
FCF_MINMAX | /* have a min and max button */
FCF_SYSMENU | /* include a system menu */
FCF_TASKLIST | /* show it in window list */
FCF_ICON | /* Load icon from resources */
FCF_MENU; /* Load menu from resources */
int
main(int argc, char *argv[])
{
HAB hab;
HMQ hmq;
QMSG qmsg;
DosSetProcessCp(850);
hab = WinInitialize(0);
hmq = WinCreateMsgQueue(hab, 0);
WinSetCp(hmq, 850);
if (!init_window(hab)) {
if (parse_arg(argc, argv)) {
gstid = _beginthread(gs_thread, NULL, 131072, NULL);
}
text_update();
}
while (WinGetMsg(hab, &qmsg, NULLHANDLE, 0, 0))
WinDispatchMsg(hab, &qmsg);
if (!debug) {
if (option)
unlink(option);
if (filename)
unlink(filename);
}
if (gstid)
DosKillThread(gstid);
DosCloseMutexSem(text_mutex);
WinDestroyWindow(hwnd_frame);
WinDestroyMsgQueue(hmq);
WinTerminate(hab);
return 0;
}
/* Create windows */
int
init_window(HAB hab)
{
HPS hps;
FONTMETRICS fm;
SWP swp;
RECTL rect;
if (DosCreateMutexSem(NULL, &text_mutex, 0, FALSE) != 0)
return FALSE;
if (!WinRegisterClass( /* register this window class */
hab, /* anchor block */
(PSZ)szClass, /* class name */
(PFNWP) ClientWndProc, /* window function */
CS_SIZEREDRAW, /* window style */
0)) /* no storage */
{
message_box("Can't register window class", 0);
return -1;
}
WinRegisterClass(hab, (PCSZ)"GVPGS", ClientWndProc, 0L, 0);
hwnd_frame = WinCreateStdWindow(
HWND_DESKTOP, /* window type */
0, /* frame style is not WS_VISIBLE */
&frame_flags,
(PSZ)szClass, /* client class */
(PSZ)szAppName, /* title */
WS_VISIBLE, /* client style */
0, /* resource module */
ID_GSVIEW, /* resource identifier */
&hwnd_client); /* pointer to client */
/* find out default text size */
hps = WinGetPS(hwnd_client);
GpiQueryFontMetrics(hps, sizeof(FONTMETRICS), &fm);
char_size.y = fm.lMaxAscender + fm.lMaxDescender + fm.lExternalLeading + 2;
char_size.x = fm.lAveCharWidth;
WinReleasePS(hwnd_client);
/* position window */
WinQueryTaskSizePos(hab, 0, &swp);
swp.y += swp.cy; /* keep top left in suggest position */
swp.cx = 70 * char_size.x;
swp.cy = 15 * char_size.y;
swp.y -= swp.cy;
swp.fl = SWP_MOVE | SWP_SIZE;
WinSetWindowPos(hwnd_frame, HWND_TOP,
swp.x, swp.y, swp.cx, swp.cy, swp.fl);
WinQueryWindowRect(hwnd_client, &rect);
status_height = 0 /* char_size.y */;
hwnd_text = WinCreateWindow(
hwnd_client,
WC_MLE,
(PCSZ)"",
MLS_BORDER | MLS_READONLY | MLS_HSCROLL | MLS_VSCROLL |
WS_VISIBLE | WS_TABSTOP,
0, status_height,
rect.xRight-rect.xLeft, rect.yTop-rect.yBottom - status_height,
hwnd_client,
HWND_TOP,
TEXTWIN_MLE,
NULL,
NULL);
/* show window */
swp.fl = SWP_ACTIVATE | SWP_SHOW;
WinSetWindowPos(hwnd_frame, HWND_TOP,
swp.x, swp.y, swp.cx, swp.cy, swp.fl);
WinSetFocus(HWND_DESKTOP, hwnd_client);
return 0;
}
/* display message box */
int
message_box(char *str, int icon)
{
return WinMessageBox(HWND_DESKTOP, hwnd_client ? hwnd_client : HWND_DESKTOP,
(PCSZ)str, (PCSZ)"GVPGS", 0, icon | MB_MOVEABLE | MB_OK);
}
/* Update MLE to match twbuf */
void
text_update()
{
IPT ipt = 0;
if (hwnd_text == (HWND)NULL)
return;
if (DosRequestMutexSem(text_mutex, 10000) == ERROR_TIMEOUT)
DosBeep(100, 100);
WinEnableWindowUpdate(hwnd_text, FALSE);
WinSendMsg( hwnd_text, MLM_DISABLEREFRESH, 0, 0);
/* delete current contents */
ipt = (IPT)WinSendMsg( hwnd_text, MLM_QUERYTEXTLENGTH, 0, 0); /* get current length */
WinSendMsg( hwnd_text, MLM_SETSEL, (MPARAM)0, (MPARAM)ipt);
WinSendMsg( hwnd_text, MLM_CLEAR, (MPARAM)0, (MPARAM)0);
/* add udpated buffer */
ipt = 0;
WinSendMsg(hwnd_text, MLM_SETIMPORTEXPORT, (MPARAM)twbuf, (MPARAM)sizeof(twbuf));
WinSendMsg( hwnd_text, MLM_IMPORT, (MPARAM)&ipt, (MPARAM)twend);
WinSendMsg( hwnd_text, MLM_SETSEL, (MPARAM)twend, (MPARAM)twend);
WinSendMsg( hwnd_text, MLM_ENABLEREFRESH, 0, 0);
WinEnableWindowUpdate(hwnd_text, TRUE);
DosReleaseMutexSem(text_mutex);
WinInvalidateRect(hwnd_text, (PRECTL)NULL, TRUE);
WinUpdateWindow(hwnd_text);
}
/* The main WndProc */
MRESULT EXPENTRY
ClientWndProc(HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
{
switch(msg) {
case WM_CREATE:
/* should create child windows here */
break;
case WM_TEXTUPDATE:
text_update();
break;
case WM_PCUPDATE:
sprintf(title, "%d%% - %s",
(int)(mp1) > 100 ? 100 : (int)(mp1) , szAppName);
WinSetWindowText( hwnd_frame, (PCSZ)title);
return 0;
case WM_SIZE:
{SWP swp;
swp.y = status_height;
swp.x = 0;
swp.cx = SHORT1FROMMP(mp2);
swp.cy = SHORT2FROMMP(mp2) - status_height;
swp.fl = SWP_MOVE | SWP_SIZE;
WinSetWindowPos(hwnd_text, HWND_TOP,
swp.x, swp.y, swp.cx, swp.cy, swp.fl);
}
break;
case WM_COMMAND:
switch(SHORT1FROMMP(mp1)) {
case IDM_SAVEAS:
saveas();
break;
case IDM_EXIT:
WinPostMsg(hwnd, WM_CLOSE, 0, 0);
break;
case IDM_ABOUT:
show_about();
return (MRESULT)TRUE;
case IDM_COPYCLIP:
{MRESULT mr;
mr = WinSendMsg( WinWindowFromID(hwnd, TEXTWIN_MLE),
MLM_QUERYSEL, (MPARAM)MLFQS_MINMAXSEL, (MPARAM)0);
if (SHORT1FROMMP(mr) == SHORT2FROMMP(mr)) /* no selection so select all */
WinSendMsg( WinWindowFromID(hwnd, TEXTWIN_MLE),
MLM_SETSEL, 0, (MPARAM)strlen(twbuf));
WinSendMsg( WinWindowFromID(hwnd, TEXTWIN_MLE),
MLM_COPY, (MPARAM)0, (MPARAM)0);
WinSendMsg( WinWindowFromID(hwnd, TEXTWIN_MLE),
MLM_SETSEL, (MPARAM)strlen(twbuf), (MPARAM)strlen(twbuf));
}
return (MRESULT)TRUE;
}
break;
case WM_ERASEBACKGROUND:
WinFillRect((HPS)mp1, (PRECTL)mp2, SYSCLR_DIALOGBACKGROUND);
return (MRESULT)FALSE; /* we have erased it */
}
return WinDefWindowProc(hwnd, msg, mp1, mp2);
}
/* Add string for Ghostscript message window */
void
gs_addmess_count(const char *str, int count)
{
if (DosRequestMutexSem(text_mutex, 10000) == ERROR_TIMEOUT)
DosBeep(100, 100);
if (count >= TWSCROLL)
return; /* too large */
if (count + twend >= TWLENGTH-1) {
/* scroll buffer */
twend -= TWSCROLL;
memmove(twbuf, twbuf+TWSCROLL, twend);
}
memmove(twbuf+twend, str, count);
twend += count;
*(twbuf+twend) = '\0';
DosReleaseMutexSem(text_mutex);
/* tell main thread to update the MLE */
WinPostMsg(hwnd_client, WM_TEXTUPDATE, 0, 0);
}
void
gs_addmess(const char *str)
{
gs_addmess_count(str, strlen(str));
}
/* Parse command line arguments */
/* Return 0 if error */
int
parse_arg(int argc, char *argv[])
{
char buf[MAXSTR];
char *usage="Usage: gvpgs [/d] dllpath optionfile inputfile\n\
optionfile and inputfile will be deleted on exit\n\
It is intended that gvpgs be called with temporary files\n";
if (argc == 5) {
if ( ((argv[1][0] == '/') || (argv[1][0] == '-')) &&
((argv[1][1] == 'd') || (argv[1][0] == 'D')) ) {
debug = 1;
argv++;
argc--;
}
else {
gs_addmess(usage);
return FALSE;
}
}
if (argc != 4) {
gs_addmess(usage);
return FALSE;
}
gsdllname = argv[1];
option = argv[2];
filename = argv[3];
if (debug) {
sprintf(buf, "gsdllname=%s\n", gsdllname);
gs_addmess(buf);
sprintf(buf, "option file=%s\n", option);
gs_addmess(buf);
sprintf(buf, "input file=%s\n", filename);
gs_addmess(buf);
}
if (debug) {
FILE *optfile = fopen(option, "r");
if (optfile == NULL) {
gs_addmess(usage);
sprintf(gsarg, "Can't find file '%s'\n", option);
gs_addmess(gsarg);
return FALSE;
}
sprintf(buf, "Option file contents:\n");
gs_addmess(buf);
while (fgets(buf, sizeof(buf)-1, optfile)) {
gs_addmess(" ");
gs_addmess(buf);
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -