home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Fresh Fish 5
/
FreshFish_July-August1994.bin
/
bbs
/
gnu
/
gs-2.6.1.4-src.lha
/
src
/
amiga
/
gs-2.6.1.4
/
gp_mswtx.c
< prev
next >
Wrap
C/C++ Source or Header
|
1994-01-27
|
20KB
|
772 lines
/* Copyright (C) 1993 Russell Lang
Permission to use, copy, modify, distribute, and sell this
software and its documentation for any purpose is hereby granted
without fee, provided that the above copyright notice and this
permission notice appear in all copies of the software and related
documentation.
*/
/* gp_mswtx.c */
/*
* Microsoft Windows 3.n text window for Ghostscript.
* Original version by Russell Lang
*/
#define STRICT
#include "windows_.h"
#include <windowsx.h>
#if WINVER >= 0x030a
#include <commdlg.h>
#include <shellapi.h>
#endif
#include "ctype_.h"
#include "memory_.h"
#include "string_.h" /* use only far items */
#include <stdlib.h>
#include "dos_.h"
#include "gp_mswin.h"
#include "gp_mswtx.h"
/* sysmenu */
#define M_COPY_CLIP 1
/* font stuff */
#define TEXTFONTSIZE 9
#define TEXTFONTNAME "Terminal"
/* limits */
POINT ScreenMinSize = {16,4};
LRESULT CALLBACK _export WndTextProc(HWND hwnd, UINT message, WPARAM wParam, LPARAM lParam);
char szNoMemory[] = "out of memory";
LPSTR szTextClass = "gstext_class";
void
TextMessage(void)
{
MSG msg;
while (PeekMessage(&msg, 0, 0, 0, PM_REMOVE))
{
TranslateMessage(&msg);
DispatchMessage(&msg);
}
return;
}
void
CreateTextClass(LPTW lptw)
{
WNDCLASS wndclass;
static BOOL init = FALSE;
if (init)
return;
wndclass.style = CS_HREDRAW | CS_VREDRAW;
wndclass.lpfnWndProc = WndTextProc;
wndclass.cbClsExtra = 0;
wndclass.cbWndExtra = sizeof(void FAR *);
wndclass.hInstance = lptw->hInstance;
if (lptw->hIcon)
wndclass.hIcon = lptw->hIcon;
else
wndclass.hIcon = LoadIcon(NULL, IDI_APPLICATION);
wndclass.hCursor = LoadCursor(NULL, IDC_ARROW);
wndclass.hbrBackground = GetStockBrush(WHITE_BRUSH);
wndclass.lpszMenuName = NULL;
wndclass.lpszClassName = szTextClass;
RegisterClass(&wndclass);
init = TRUE;
}
/* make text window */
int
TextInit(LPTW lptw)
{
HMENU sysmenu;
HGLOBAL hglobal;
if (!lptw->hPrevInstance)
CreateTextClass(lptw);
if (lptw->KeyBufSize == 0)
lptw->KeyBufSize = 256;
if (lptw->ScreenSize.x < ScreenMinSize.x)
lptw->ScreenSize.x = ScreenMinSize.x;
if (lptw->ScreenSize.y < ScreenMinSize.y)
lptw->ScreenSize.y = ScreenMinSize.y;
lptw->CursorPos.x = lptw->CursorPos.y = 0;
lptw->bFocus = FALSE;
lptw->bGetCh = FALSE;
lptw->CaretHeight = 0;
if (!lptw->nCmdShow)
lptw->nCmdShow = SW_SHOWNORMAL;
hglobal = GlobalAlloc(GHND, lptw->ScreenSize.x * lptw->ScreenSize.y);
lptw->ScreenBuffer = (BYTE FAR *)GlobalLock(hglobal);
if (lptw->ScreenBuffer == (BYTE FAR *)NULL) {
MessageBox((HWND)NULL,szNoMemory,(LPSTR)NULL, MB_ICONHAND | MB_SYSTEMMODAL);
return(1);
}
_fmemset(lptw->ScreenBuffer, ' ', lptw->ScreenSize.x * lptw->ScreenSize.y);
hglobal = GlobalAlloc(LHND, lptw->KeyBufSize);
lptw->KeyBuf = (BYTE FAR *)GlobalLock(hglobal);
if (lptw->KeyBuf == (BYTE FAR *)NULL) {
MessageBox((HWND)NULL,szNoMemory,(LPSTR)NULL, MB_ICONHAND | MB_SYSTEMMODAL);
return(1);
}
lptw->KeyBufIn = lptw->KeyBufOut = lptw->KeyBuf;
lptw->hWndText = CreateWindow(szTextClass, lptw->Title,
WS_OVERLAPPEDWINDOW | WS_VSCROLL | WS_HSCROLL,
CW_USEDEFAULT, CW_USEDEFAULT,
CW_USEDEFAULT, CW_USEDEFAULT,
NULL, NULL, lptw->hInstance, lptw);
if (lptw->hWndText == (HWND)NULL) {
MessageBox((HWND)NULL,"Couldn't open text window",(LPSTR)NULL, MB_ICONHAND | MB_SYSTEMMODAL);
return(1);
}
ShowWindow(lptw->hWndText, lptw->nCmdShow);
sysmenu = GetSystemMenu(lptw->hWndText,0); /* get the sysmenu */
AppendMenu(sysmenu, MF_SEPARATOR, 0, NULL);
AppendMenu(sysmenu, MF_STRING, M_COPY_CLIP, "Copy to Clip&board");
return(0);
}
/* close a text window */
void
TextClose(LPTW lptw)
{
HGLOBAL hglobal;
/* close window */
if (lptw->hWndText)
DestroyWindow(lptw->hWndText);
TextMessage();
hglobal = (HGLOBAL)GlobalHandle( SELECTOROF(lptw->ScreenBuffer) );
if (hglobal) {
GlobalUnlock(hglobal);
GlobalFree(hglobal);
}
hglobal = (HGLOBAL)GlobalHandle( SELECTOROF(lptw->KeyBuf) );
if (hglobal) {
GlobalUnlock(hglobal);
GlobalFree(hglobal);
}
lptw->hWndText = (HWND)NULL;
}
/* Bring Cursor into text window */
void
TextToCursor(LPTW lptw)
{
int nXinc=0;
int nYinc=0;
int cxCursor;
int cyCursor;
cyCursor = lptw->CursorPos.y * lptw->CharSize.y;
if ( (cyCursor + lptw->CharSize.y > lptw->ScrollPos.y + lptw->ClientSize.y)
|| (cyCursor < lptw->ScrollPos.y) ) {
nYinc = max(0, cyCursor + lptw->CharSize.y - lptw->ClientSize.y) - lptw->ScrollPos.y;
nYinc = min(nYinc, lptw->ScrollMax.y - lptw->ScrollPos.y);
}
cxCursor = lptw->CursorPos.x * lptw->CharSize.x;
if ( (cxCursor + lptw->CharSize.x > lptw->ScrollPos.x + lptw->ClientSize.x)
|| (cxCursor < lptw->ScrollPos.x) ) {
nXinc = max(0, cxCursor + lptw->CharSize.x - lptw->ClientSize.x/2) - lptw->ScrollPos.x;
nXinc = min(nXinc, lptw->ScrollMax.x - lptw->ScrollPos.x);
}
if (nYinc || nXinc) {
lptw->ScrollPos.y += nYinc;
lptw->ScrollPos.x += nXinc;
ScrollWindow(lptw->hWndText,-nXinc,-nYinc,NULL,NULL);
SetScrollPos(lptw->hWndText,SB_VERT,lptw->ScrollPos.y,TRUE);
SetScrollPos(lptw->hWndText,SB_HORZ,lptw->ScrollPos.x,TRUE);
UpdateWindow(lptw->hWndText);
}
}
void
NewLine(LPTW lptw)
{
lptw->CursorPos.x = 0;
lptw->CursorPos.y++;
if (lptw->CursorPos.y >= lptw->ScreenSize.y) {
int i = lptw->ScreenSize.x * (lptw->ScreenSize.y - 1);
_fmemmove(lptw->ScreenBuffer, lptw->ScreenBuffer+lptw->ScreenSize.x, i);
_fmemset(lptw->ScreenBuffer + i, ' ', lptw->ScreenSize.x);
lptw->CursorPos.y--;
ScrollWindow(lptw->hWndText,0,-lptw->CharSize.y,NULL,NULL);
UpdateWindow(lptw->hWndText);
}
if (lptw->CursorFlag)
TextToCursor(lptw);
TextMessage();
}
/* Update count characters in window at cursor position */
/* Updates cursor position */
void
UpdateText(LPTW lptw, int count)
{
HDC hdc;
int xpos, ypos;
xpos = lptw->CursorPos.x*lptw->CharSize.x - lptw->ScrollPos.x;
ypos = lptw->CursorPos.y*lptw->CharSize.y - lptw->ScrollPos.y;
hdc = GetDC(lptw->hWndText);
SelectFont(hdc, lptw->hfont);
TextOut(hdc,xpos,ypos,
(LPSTR)(lptw->ScreenBuffer + lptw->CursorPos.y*lptw->ScreenSize.x +
lptw->CursorPos.x), count);
(void)ReleaseDC(lptw->hWndText,hdc);
lptw->CursorPos.x += count;
if (lptw->CursorPos.x >= lptw->ScreenSize.x)
NewLine(lptw);
}
int
TextPutCh(LPTW lptw, BYTE ch)
{
int pos;
switch(ch) {
case '\r':
lptw->CursorPos.x = 0;
if (lptw->CursorFlag)
TextToCursor(lptw);
break;
case '\n':
NewLine(lptw);
break;
case 7:
MessageBeep(-1);
if (lptw->CursorFlag)
TextToCursor(lptw);
break;
case '\t':
{
int n;
for ( n = 8 - (lptw->CursorPos.x % 8); n>0; n-- )
TextPutCh(lptw, ' ');
}
break;
case 0x08:
case 0x7f:
lptw->CursorPos.x--;
if (lptw->CursorPos.x < 0) {
lptw->CursorPos.x = lptw->ScreenSize.x - 1;
lptw->CursorPos.y--;
}
if (lptw->CursorPos.y < 0)
lptw->CursorPos.y = 0;
break;
default:
pos = lptw->CursorPos.y*lptw->ScreenSize.x + lptw->CursorPos.x;
lptw->ScreenBuffer[pos] = ch;
UpdateText(lptw, 1);
}
return ch;
}
void
TextWriteBuf(LPTW lptw, LPSTR str, int cnt)
{
BYTE FAR *p;
int count, limit;
while (cnt>0) {
p = lptw->ScreenBuffer + lptw->CursorPos.y*lptw->ScreenSize.x + lptw->CursorPos.x;
limit = lptw->ScreenSize.x - lptw->CursorPos.x;
for (count=0; (count < limit) && (cnt>0) && (isprint(*str) || *str=='\t'); count++) {
if (*str=='\t') {
int n;
for ( n = 8 - ((lptw->CursorPos.x+count) % 8); (count < limit) & (n>0); n--, count++ ) {
*p++ = ' ';
}
str++;
count--;
}
else {
*p++ = *str++;
}
cnt--;
}
if (count>0) {
UpdateText(lptw, count);
}
if (cnt > 0) {
if (*str=='\n') {
NewLine(lptw);
str++;
cnt--;
}
else if (!isprint(*str) && *str!='\t') {
TextPutCh(lptw, *str++);
cnt--;
}
}
}
}
/* TRUE if key hit, FALSE if no key */
int
TextKBHit(LPTW lptw)
{
return (lptw->KeyBufIn != lptw->KeyBufOut);
}
/* get character from keyboard, no echo */
/* need to add extended codes */
int
TextGetCh(LPTW lptw)
{
int ch;
TextToCursor(lptw);
lptw->bGetCh = TRUE;
if (lptw->bFocus) {
SetCaretPos(lptw->CursorPos.x*lptw->CharSize.x - lptw->ScrollPos.x,
lptw->CursorPos.