home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Mega Top 1
/
os2_top1.zip
/
os2_top1
/
APPS
/
TEKST
/
GSPMSRC
/
SRC
/
GSOS2PM.C
< prev
next >
Wrap
C/C++ Source or Header
|
1993-12-23
|
19KB
|
591 lines
#define INCL_PM
#define INCL_DOS
#define INCL_WIN
#define INCL_GPI
#include <stdio.h>
#include <io.h>
#include <stdlib.h>
#include <string.h>
#include <process.h>
#include <os2.h>
#include "gsos2.h"
#define min(a, b) ((a) < (b) ? (a) : (b))
#define max(a, b) ((a) > (b) ? (a) : (b))
#define ID_GSPM 1
#define ENV_GSOS2_POS "GSOS2_POS"
#define ENV_GSOS2_MODE "GSOS2_MODE"
#define ENV_GSOS2_DEN "GSOS2_DPI"
#define ERR_OPEN_GSWININ "Error opening named pipe:\n gswinin"
#define ERR_OPEN_GSSTDOUT "Error opening named pipe:\n gsstdout"
#define ERR_OPEN_GSSTDIN "Error opening named pipe:\n gsstdin"
#define ERR_CREATE_THREAD "Error creating drawing thread"
#define ERR_CREATE_WINDOW "Error creating drawing window"
#define ERR_WINDOW_SIZE "Width and height of the window "\
"cannot be larger than width and "\
"height of the document, respectively."
#define DEFAULT_DRAWMODE 0
#define DEFAULT_XCLIENT 280
#define DEFAULT_YCLIENT 2
#define DEFAULT_CXCLIENT 340
#define DEFAULT_CYCLIENT 440
#define DEFAULT_CXIMAGE 680
#define DEFAULT_CYIMAGE 880
#define DEFAULT_DPI 40
#define STDOUT 1
#define STDERR 2
/*-----------------------------------------------------------------------*/
/* Variables and procedures shared with the Ghostscript PM driver. */
extern HPAL hpal;
extern float Xdpi, Ydpi;
extern HWND hwndFrame, hwndClient;
extern HEV hevWaitClient;
extern HEV hevPipesOpened;
extern LONG CXImage, CYImage;
extern ULONG DrawingMode;
int gsmain (int argc, const char *argv[]);
int repaint_window (int x0, int y0, int x1, int y1,
int x2, int y2, int x3, int y3);
/*-----------------------------------------------------------------------*/
CHAR ErrorOpenNPipeSem [80] = "Error opening event semaphore (named pipes)"
". Return code = ";
CHAR ErrorCreateWinSem [80] = "Error creating event semaphore (client window)"
". Return code = ";
void gsbegin (void *t);
LONG DisplayError (PSZ pszText);
void ExitGS (void);
HAB hab;
HMQ hmq;
LONG ThreadID;
MRESULT EXPENTRY ClientWndProc (HWND, ULONG, MPARAM, MPARAM);
int gs_argc;
const char **gs_argv;
FILE *gsos2_stdin, *gsos2_stdout, *gsos2_winin;
main (int argc, const char *argv[])
{
static CHAR szClientClass [] = "OS/2 Ghostscript";
static ULONG flFrameFlags = FCF_TITLEBAR | FCF_SYSMENU |
FCF_MINBUTTON | FCF_DLGBORDER |
FCF_TASKLIST | FCF_ICON |
FCF_AUTOICON;
QMSG qmsg;
char *WindowPos, *gsos2Mode, *s;
LONG XClient, YClient, CXClient, CYClient;
HWND hwndCmd;
char *PixelDensity;
APIRET rc;
RECTL rect;
/* Initialize the PM facilities. Must be the first PM call issued by */
/* any application using the PM facilities. */
hab = WinInitialize (0);
/* Create a message queue with default queue size of 10 messages. */
hmq = WinCreateMsgQueue (hab, 0);
WinSetPointer (HWND_DESKTOP,
WinQuerySysPointer (HWND_DESKTOP, SPTR_WAIT, TRUE));
/* Register the window class. */
WinRegisterClass (hab, szClientClass, ClientWndProc, 0, 0);
/* Must set hevPipesOpened to 0 before calling DosOpenEventSem bcause */
/* we are opening a shared named semaphore */
hevPipesOpened = 0;
rc = DosOpenEventSem (SEM_NAMED_PIPES, &hevPipesOpened);
if (rc != 0)
{
sprintf (ErrorOpenNPipeSem + strlen (ErrorOpenNPipeSem), "%lu.", rc);
DisplayError (ErrorOpenNPipeSem);
ExitGS ();
}
/* Set the drawing mode option for the PM driver. */
gsos2Mode = getenv (ENV_GSOS2_MODE);
if (gsos2Mode != NULL)
sscanf (gsos2Mode, "%lu", &DrawingMode);
else
DrawingMode = DEFAULT_DRAWMODE;
/* Set the pixel density option for the PM driver. */
PixelDensity = getenv (ENV_GSOS2_DEN);
if (PixelDensity != NULL)
sscanf (PixelDensity, "%f %f", &Xdpi, &Ydpi);
else
Xdpi = Ydpi = DEFAULT_DPI;
/* Set the window position option for the PM driver. */
WindowPos = getenv (ENV_GSOS2_POS);
if (WindowPos != NULL)
{
sscanf (WindowPos, "%ld %ld %ld %ld %ld %ld", &XClient,
&YClient, &CXClient, &CYClient,
&CXImage, &CYImage);
}
else
{
XClient = DEFAULT_XCLIENT;
YClient = DEFAULT_YCLIENT;
CXClient = DEFAULT_CXCLIENT;
CYClient = DEFAULT_CYCLIENT;
CXImage = DEFAULT_CXIMAGE;
CYImage = DEFAULT_CYIMAGE;
}
rect.yBottom = YClient;
rect.xLeft = XClient;
rect.yTop = YClient + CYClient;
rect.xRight = XClient + CXClient;
if (CXImage < CXClient || CYImage < CYClient)
{
DisplayError (ERR_WINDOW_SIZE);
ExitGS ();
}
if (CXImage > CXClient)
{
DrawingMode |= MODE_DRAW_BITMAP_ONLY;
flFrameFlags |= FCF_HORZSCROLL;
}
if (CYImage > CYClient)
{
DrawingMode |= MODE_DRAW_BITMAP_ONLY;
flFrameFlags |= FCF_VERTSCROLL;
}
gsos2_stdin = freopen (PIPE_GS_STDIN, "rb", stdin);
if (gsos2_stdin == NULL)
{
DisplayError (ERR_OPEN_GSSTDIN);
ExitGS ();
}
gsos2_stdout = freopen (PIPE_GS_STDOUT, "wb", stdout);
if (gsos2_stdout == NULL)
{
DisplayError (ERR_OPEN_GSSTDOUT);
ExitGS ();
}
dup2 (STDOUT, STDERR);
gsos2_winin = fopen (PIPE_GS_WININ, "wb");
if (gsos2_winin == NULL)
{
DisplayError (ERR_OPEN_GSWININ);
ExitGS ();
}
DosPostEventSem (hevPipesOpened);
hwndFrame = WinCreateStdWindow (HWND_DESKTOP, 0, &flFrameFlags,
szClientClass, "Ghostscript", 0L, 0,
ID_GSPM, &hwndClient);
if (hwndFrame == NULLHANDLE || hwndClient == NULLHANDLE)
{
DisplayError (ERR_CREATE_WINDOW);
ExitGS ();
}
WinCalcFrameRect (hwndFrame, &rect, FALSE);
hwndCmd = WinQueryActiveWindow (HWND_DESKTOP);
WinSetWindowPos (hwndFrame, hwndCmd, rect.xLeft, rect.yBottom,
rect.xRight - rect.xLeft, rect.yTop - rect.yBottom,
SWP_ZORDER | SWP_SIZE | SWP_MOVE);
WinSendMsg (hwndClient, WM_USER, (MPARAM) WM_USER_SETSCROLL, 0L);
rc = DosCreateEventSem (SEM_WAIT_CLIENT, &hevWaitClient, 0, TRUE);
if (rc != 0)
{
sprintf (ErrorCreateWinSem + strlen (ErrorCreateWinSem), "%lu.", rc);
DisplayError (ErrorCreateWinSem);
ExitGS ();
}
gs_argc = argc;
gs_argv = argv;
ThreadID = (LONG) _beginthread (gsbegin, NULL, 0x20000, NULL);
if (ThreadID == -1)
{
DisplayError (ERR_CREATE_THREAD);
ExitGS ();
}
WinSendMsg (hwndClient, WM_USER, (MPARAM) WM_USER_THREADID,
MPFROMLONG (ThreadID));
WinSetPointer (HWND_DESKTOP,
WinQuerySysPointer (HWND_DESKTOP, SPTR_ARROW, TRUE));
while (WinGetMsg (hab, &qmsg, 0, 0, 0))
WinDispatchMsg (hab, &qmsg);
ExitGS ();
}
void gsbegin (void *t)
{
gsmain (gs_argc, gs_argv);
}
MRESULT EXPENTRY ClientWndProc (HWND hwnd, ULONG msg, MPARAM mp1, MPARAM mp2)
{
HPS hps;
RECTL rcl;
PSWP pswp;
INT Rep, Processed, i;
ULONG ulclr;
HPAL hpalOld;
int x0, y0, x1, y1, x2, y2, x3, y3;
static SHORT sHscrollPos, sHscrollNewPos, sHscrollMax;
static SHORT sVscrollPos, sVscrollNewPos, sVscrollMax;
static HWND hwndHscroll, hwndVscroll, hwndParent;
static LONG WindowMinimized;
static LONG CXClient, CYClient;
static TID ThreadID = -1;
switch(msg)
{
case WM_USER:
switch ((ULONG) mp1)
{
case WM_USER_THREADID:
ThreadID = (TID) (LONGFROMMP (mp2));
return (0);
case WM_USER_WINTOTOP:
WinSetWindowPos (hwndParent, HWND_TOP, 0, 0, 0, 0, SWP_ACTIVATE);
DosPostEventSem (hevWaitClient);
return (0);
case WM_USER_SHOWWIN:
WinShowWindow (hwndParent, TRUE);
DosPostEventSem (hevWaitClient);
return (0);
case WM_USER_SHOWPAGE:
DosPostEventSem (hevWaitClient);
return (0);
case WM_USER_SYNCOUTPUT:
if (!WindowMinimized)
WinInvalidateRect (hwnd, NULL, FALSE);
DosPostEventSem (hevWaitClient);
return (0);
case WM_USER_SETSCROLL:
WinQueryWindowRect (hwnd, &rcl);
CXClient = rcl.xRight;
CYClient = rcl.yTop;
if (DrawingMode & MODE_DRAW_BITMAP_ONLY)
{
sHscrollPos = 0;
sHscrollNewPos = sHscrollPos;
sHscrollMax = CXImage - CXClient;
WinSendMsg (hwndHscroll, SBM_SETSCROLLBAR,
MPFROM2SHORT (sHscrollPos, 0),
MPFROM2SHORT (0, sHscrollMax));
WinSendMsg (hwndHscroll, SBM_SETTHUMBSIZE,
MPFROM2SHORT ((SHORT) CXClient,
(SHORT) CXImage), NULL);
sVscrollPos = 0;
sVscrollNewPos = sVscrollPos;
sVscrollMax = CYImage - CYClient;
WinSendMsg (hwndVscroll, SBM_SETSCROLLBAR,
MPFROM2SHORT (sVscrollPos, 0),
MPFROM2SHORT (0, sVscrollMax));
WinSendMsg (hwndVscroll, SBM_SETTHUMBSIZE,
MPFROM2SHORT ((SHORT) CYClient,
(SHORT) CYImage), NULL);
}
else
{
CXImage = CXClient;
CYImage = CYClient;
}
return (0);
default:
break;
}
return (0);
case WM_HSCROLL:
switch (SHORT2FROMMP (mp2))
{
case SB_LINELEFT:
sHscrollNewPos -= 10;
break;
case SB_LINERIGHT:
sHscrollNewPos += 10;
break;
case SB_PAGELEFT:
sHscrollNewPos -= CXClient;
break;
case SB_PAGERIGHT:
sHscrollNewPos += CXClient;
break;
case SB_SLIDERTRACK:
sHscrollNewPos = SHORT1FROMMP (mp2);
break;
default:
break;
}
sHscrollNewPos = min (max (0, sHscrollNewPos), sHscrollMax);
if (sHscrollNewPos != sHscrollPos)
{
#ifdef ACC_GRX_CARD
WinScrollWindow (hwnd, (LONG)(sHscrollPos - sHscrollNewPos), 0L,
NULL, NULL, NULLHANDLE, NULL, SW_INVALIDATERGN);
#endif
sHscrollPos = sHscrollNewPos;
WinSendMsg (hwndHscroll, SBM_SETPOS,
MPFROM2SHORT (sHscrollPos, 0), NULL);
#ifndef ACC_GRX_CARD
WinInvalidateRect (hwnd, NULL, FALSE);
#endif
}
return (0);
case WM_VSCROLL:
switch (SHORT2FROMMP (mp2))
{
case SB_LINEUP:
sVscrollNewPos -= 10;
break;
case SB_LINEDOWN:
sVscrollNewPos += 10;
break;
case SB_PAGEUP:
sVscrollNewPos -= CYClient;
break;
case SB_PAGEDOWN:
sVscrollNewPos += CYClient;
break;
case SB_SLIDERTRACK:
sVscrollNewPos = SHORT1FROMMP (mp2);
break;
default:
break;
}
sVscrollNewPos = min (max (0, sVscrollNewPos), sVscrollMax);
if (sVscrollNewPos != sVscrollPos)
{
#ifdef ACC_GRX_CARD
WinScrollWindow (hwnd, 0L, (LONG)(sVscrollNewPos - sVscrollPos),
NULL, NULL, NULLHANDLE, NULL, SW_INVALIDATERGN);
#endif
sVscrollPos = sVscrollNewPos;
WinSendMsg (hwndVscroll, SBM_SETPOS,
MPFROM2SHORT (sVscrollPos, 0), NULL);
#ifndef ACC_GRX_CARD
WinInvalidateRect (hwnd, NULL, FALSE);
#endif
}
return (0);
case WM_CHAR:
if (SHORT1FROMMP (mp1) & KC_KEYUP)
return (0);
if (SHORT1FROMMP (mp1) & KC_INVALIDCHAR)
return (0);
for (Rep = 0; Rep < CHAR3FROMMP (mp1); Rep++)
{
Processed = FALSE;
if (SHORT1FROMMP (mp1) & KC_VIRTUALKEY)
{
Processed = TRUE;
switch (SHORT2FROMMP (mp2))
{
case VK_LEFT:
case VK_RIGHT:
if (DrawingMode & MODE_DRAW_BITMAP_ONLY)
return (WinSendMsg (hwndHscroll, msg, mp1, mp2));
else
break;
case VK_UP:
case VK_DOWN:
case VK_PAGEUP:
case VK_PAGEDOWN:
if (DrawingMode & MODE_DRAW_BITMAP_ONLY)
return (WinSendMsg (hwndVscroll, msg, mp1, mp2));
else
break;
case VK_BACKSPACE:
fputc ('\b', gsos2_winin);
fflush (gsos2_winin);
break;
case VK_TAB:
break;
case VK_NEWLINE:
case VK_ENTER:
fputc ('\n', gsos2_winin);
fflush (gsos2_winin);
break;
default:
Processed = FALSE;
break;
}
}
if (!Processed && (SHORT1FROMMP (mp1) & KC_CHAR))
{
Processed = TRUE;
fputc ((int) (SHORT1FROMMP (mp2)), gsos2_winin);
fflush (gsos2_winin);
}
}
return (0);
case WM_REALIZEPALETTE:
if (DrawingMode & MODE_256_COLOR && !WindowMinimized)
{
hps = WinGetPS (hwnd);
hpalOld = GpiSelectPalette (hps, hpal);
if (WinRealizePalette (hwnd, hps, &ulclr) > 0)
WinInvalidateRect (hwnd, NULL, FALSE);
hpalOld = GpiSelectPalette (hps, NULLHANDLE);
WinReleasePS (hps);
}
return (0);
case WM_PAINT:
hps = WinBeginPaint (hwnd, NULLHANDLE, &rcl);
if (ThreadID != -1)
DosSuspendThread (ThreadID);
x0 = rcl.xLeft;
y0 = rcl.yBottom;
x1 = rcl.xRight - 1;
y1 = rcl.yTop - 1;
x2 = x0;
y2 = y0;
x3 = x1 + 1;
y3 = y1 + 1;
if (DrawingMode & MODE_DRAW_BITMAP_ONLY)
{
x2 += sHscrollPos;
y2 += sVscrollMax - sVscrollPos;
x3 += sHscrollPos;
y3 += sVscrollMax - sVscrollPos;
}
repaint_window (x0, y0, x1, y1, x2, y2, x3, y3);
if (ThreadID != -1)
DosResumeThread (ThreadID);
WinEndPaint (hps);
return (0);
case WM_MINMAXFRAME:
pswp = (PSWP) mp1;
if (pswp->fl & SWP_MINIMIZE)
WindowMinimized = TRUE;
else
WindowMinimized = FALSE;
return (0);
case WM_CREATE:
hwndParent = WinQueryWindow (hwnd, QW_PARENT);
if (DrawingMode & MODE_DRAW_BITMAP_ONLY)
{
hwndHscroll = WinWindowFromID (hwndParent, FID_HORZSCROLL);
hwndVscroll = WinWindowFromID (hwndParent, FID_VERTSCROLL);
}
WindowMinimized = FALSE;
return (0);
default:
break;
}
return WinDefWindowProc (hwnd, msg, mp1, mp2);
}
LONG DisplayError (PSZ pszText)
{
static CHAR szTitle [] = "OS/2 Ghostscript Error!";
WinMessageBox (HWND_DESKTOP, HWND_DESKTOP, pszText, szTitle, 0,
MB_OK | MB_ERROR | MB_SYSTEMMODAL | MB_MOVEABLE);
return (0);
}
void ExitGS ()
{
if (hwndFrame != NULLHANDLE)
WinDestroyWindow (hwndFrame);
WinDestroyMsgQueue (hmq);
if (hevPipesOpened != 0)
{
DosPostEventSem (hevPipesOpened);
DosCloseEventSem (hevPipesOpened);
}
/* As soon as we close gsos2_stdout, the process gsos2a.exe thinks the */
/* process gsos2b.exe is ending. */
if (gsos2_stdout != NULL)
{
close (STDERR);
fclose (gsos2_stdout);
}
if (gsos2_stdin != NULL)
fclose (gsos2_stdin);
if (gsos2_winin != NULL)
fclose (gsos2_winin);
WinTerminate (hab);
DosExit (EXIT_PROCESS, 0L);
}