forked from KolibriOS/kolibrios
463 lines
11 KiB
C
463 lines
11 KiB
C
|
/*
|
||
|
Copyright (c) 1990-2000 Info-ZIP. All rights reserved.
|
||
|
|
||
|
See the accompanying file LICENSE, version 2000-Apr-09 or later
|
||
|
(the contents of which are also included in unzip.h) for terms of use.
|
||
|
If, for some reason, all these files are missing, the Info-ZIP license
|
||
|
also may be found at: ftp://ftp.info-zip.org/pub/infozip/license.html
|
||
|
*/
|
||
|
/*---------------------------------------------------------------------------
|
||
|
|
||
|
macscreen.c
|
||
|
This file is only linked into the standalone version (not SIOUX) of unzip.
|
||
|
Macintosh-GUI routines.
|
||
|
|
||
|
---------------------------------------------------------------------------*/
|
||
|
|
||
|
|
||
|
/*****************************************************************************/
|
||
|
/* Includes */
|
||
|
/*****************************************************************************/
|
||
|
|
||
|
#include <QuickDraw.h>
|
||
|
|
||
|
#include <stdio.h>
|
||
|
#include <stdarg.h>
|
||
|
#include <string.h>
|
||
|
|
||
|
|
||
|
/*****************************************************************************/
|
||
|
/* Macros, typedefs */
|
||
|
/*****************************************************************************/
|
||
|
|
||
|
#define bufferSize 4096
|
||
|
|
||
|
#define screenWindow 128
|
||
|
|
||
|
#define pauseOption 0x0001
|
||
|
#define scrollOption 0x0002
|
||
|
|
||
|
|
||
|
/*****************************************************************************/
|
||
|
/* Module level Vars */
|
||
|
/*****************************************************************************/
|
||
|
|
||
|
static Rect scrollRect, pauseRect;
|
||
|
static WindowPtr theWindow;
|
||
|
static RgnHandle scrollRgn;
|
||
|
|
||
|
static short fontHeight, fontWidth, screenHeight, screenWidth;
|
||
|
static short currentPosition, maxPosition, pausePosition;
|
||
|
|
||
|
static short *screenLength, startLine, endLine;
|
||
|
static char *screenImage, **screenLine;
|
||
|
|
||
|
static int screenOptions;
|
||
|
|
||
|
|
||
|
|
||
|
/*****************************************************************************/
|
||
|
/* Prototypes */
|
||
|
/*****************************************************************************/
|
||
|
|
||
|
void screenOpen(char *);
|
||
|
void screenControl(char *, int);
|
||
|
void screenClose(void);
|
||
|
void screenUpdate(WindowPtr);
|
||
|
void screenDisplay(char *);
|
||
|
void screenDump(char *, long);
|
||
|
|
||
|
char *macfgets(char *, int, FILE *);
|
||
|
int macfprintf(FILE *, char *, ...);
|
||
|
int macprintf(char *, ...);
|
||
|
int macgetch(void);
|
||
|
|
||
|
|
||
|
/*****************************************************************************/
|
||
|
/* Functions */
|
||
|
/*****************************************************************************/
|
||
|
|
||
|
void screenOpen(char *Title) {
|
||
|
FontInfo fontInfo;
|
||
|
int n;
|
||
|
short fontFamID;
|
||
|
|
||
|
theWindow = GetNewWindow(screenWindow, nil, (WindowPtr)(-1));
|
||
|
|
||
|
if ((Title != NULL) && (*Title != '\0')) {
|
||
|
c2pstr(Title);
|
||
|
SetWTitle(theWindow, (StringPtr)Title);
|
||
|
p2cstr((StringPtr)Title);
|
||
|
}
|
||
|
|
||
|
ShowWindow(theWindow);
|
||
|
|
||
|
SetPort(theWindow);
|
||
|
GetFNum( "\pMonaco", &fontFamID );
|
||
|
TextFont(fontFamID);
|
||
|
TextSize(9);
|
||
|
|
||
|
GetFontInfo(&fontInfo);
|
||
|
fontHeight = fontInfo.ascent + fontInfo.descent + fontInfo.leading;
|
||
|
fontWidth = fontInfo.widMax;
|
||
|
|
||
|
scrollRgn = NewRgn();
|
||
|
|
||
|
screenWidth = (theWindow->portRect.right - theWindow->portRect.left - 10) /
|
||
|
fontWidth;
|
||
|
screenHeight = (theWindow->portRect.bottom - theWindow->portRect.top) /
|
||
|
fontHeight;
|
||
|
maxPosition = screenHeight * fontHeight;
|
||
|
pausePosition = maxPosition - (currentPosition = fontHeight);
|
||
|
|
||
|
SetRect(&scrollRect, theWindow->portRect.left,
|
||
|
theWindow->portRect.top + fontInfo.descent,
|
||
|
theWindow->portRect.right,
|
||
|
theWindow->portRect.bottom);
|
||
|
SetRect(&pauseRect, theWindow->portRect.left,
|
||
|
pausePosition + fontInfo.descent,
|
||
|
theWindow->portRect.right,
|
||
|
theWindow->portRect.bottom);
|
||
|
|
||
|
MoveTo(5, currentPosition);
|
||
|
|
||
|
n = (sizeof(char *) + sizeof(short) + screenWidth) * screenHeight;
|
||
|
|
||
|
screenLine = (char **)NewPtr(n);
|
||
|
|
||
|
screenLength = (short *)&screenLine[screenHeight];
|
||
|
screenImage = (char *)&screenLength[screenHeight];
|
||
|
|
||
|
for (n = 0; n < screenHeight; n++) {
|
||
|
screenLine[n] = &screenImage[n * screenWidth];
|
||
|
screenLength[n] = 0;
|
||
|
}
|
||
|
|
||
|
startLine = endLine = 0;
|
||
|
|
||
|
screenOptions = 0;
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
void screenControl(char *options, int setting) {
|
||
|
int n = 0;
|
||
|
|
||
|
while (*options) {
|
||
|
switch (*options) {
|
||
|
case 'p':
|
||
|
n |= pauseOption;
|
||
|
break;
|
||
|
case 's':
|
||
|
n |= scrollOption;
|
||
|
break;
|
||
|
default:
|
||
|
break;
|
||
|
}
|
||
|
options += 1;
|
||
|
}
|
||
|
|
||
|
if (setting == 0)
|
||
|
screenOptions &= (n ^ (-1));
|
||
|
else
|
||
|
screenOptions |= n;
|
||
|
|
||
|
if ((pausePosition = maxPosition - currentPosition) == 0)
|
||
|
pausePosition = maxPosition - fontHeight;
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
void screenClose(void) {
|
||
|
DisposePtr((Ptr)screenLine);
|
||
|
|
||
|
DisposeWindow(theWindow);
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
void screenUpdate(WindowPtr window) {
|
||
|
GrafPort *savePort;
|
||
|
int m, n;
|
||
|
|
||
|
if (window == theWindow) {
|
||
|
BeginUpdate(window);
|
||
|
if (!EmptyRgn(window->visRgn)) {
|
||
|
GetPort(&savePort);
|
||
|
SetPort(window);
|
||
|
n = startLine;
|
||
|
for (m = 1; ; m++) {
|
||
|
MoveTo(5, m * fontHeight);
|
||
|
if (screenLength[n] != 0)
|
||
|
DrawText(screenLine[n], 0, screenLength[n]);
|
||
|
if (n == endLine) break;
|
||
|
if ((n += 1) == screenHeight) n = 0;
|
||
|
}
|
||
|
SetPort(savePort);
|
||
|
}
|
||
|
EndUpdate(window);
|
||
|
}
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
static void screenNewline(void) {
|
||
|
MoveTo(5, currentPosition += fontHeight);
|
||
|
if (currentPosition > maxPosition) {
|
||
|
if (screenOptions & scrollOption) {
|
||
|
ScrollRect(&scrollRect, 0, -fontHeight, scrollRgn);
|
||
|
MoveTo(5, currentPosition = maxPosition);
|
||
|
if ((startLine += 1) == screenHeight) startLine = 0;
|
||
|
} else {
|
||
|
ScrollRect(&scrollRect, 0, -maxPosition + fontHeight, scrollRgn);
|
||
|
MoveTo(5, currentPosition = fontHeight + fontHeight);
|
||
|
startLine = endLine;
|
||
|
}
|
||
|
}
|
||
|
pausePosition -= fontHeight;
|
||
|
|
||
|
if ((endLine += 1) == screenHeight) endLine = 0;
|
||
|
screenLength[endLine] = 0;
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
static char waitChar(void) {
|
||
|
WindowPtr whichWindow;
|
||
|
EventRecord theEvent;
|
||
|
|
||
|
for ( ; ; ) {
|
||
|
SystemTask();
|
||
|
if (GetNextEvent(everyEvent, &theEvent)) {
|
||
|
switch (theEvent.what) {
|
||
|
case keyDown:
|
||
|
if ((theEvent.modifiers & cmdKey) &&
|
||
|
((theEvent.message & charCodeMask) == '.'))
|
||
|
ExitToShell();
|
||
|
return(theEvent.message & charCodeMask);
|
||
|
case mouseDown:
|
||
|
if (FindWindow(theEvent.where, &whichWindow) == inSysWindow)
|
||
|
SystemClick(&theEvent, whichWindow);
|
||
|
break;
|
||
|
case updateEvt:
|
||
|
screenUpdate((WindowPtr)theEvent.message);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
static void screenPause(void) {
|
||
|
if (pausePosition == 0) {
|
||
|
if (screenOptions & pauseOption) {
|
||
|
DrawText("Press any key to continue ...", 0, 29);
|
||
|
memcpy(screenLine[endLine], "Press any key to continue ...", 29);
|
||
|
screenLength[endLine] = 29;
|
||
|
|
||
|
(void)waitChar();
|
||
|
|
||
|
EraseRect(&pauseRect);
|
||
|
MoveTo(5, currentPosition);
|
||
|
screenLength[endLine] = 0;
|
||
|
}
|
||
|
|
||
|
pausePosition = maxPosition - fontHeight;
|
||
|
}
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
void screenDisplay(char *s) {
|
||
|
GrafPort *savePort;
|
||
|
int m, n;
|
||
|
char *t;
|
||
|
|
||
|
GetPort(&savePort);
|
||
|
SetPort(theWindow);
|
||
|
|
||
|
while (*s) {
|
||
|
screenPause();
|
||
|
|
||
|
for (t = s; (*s) && (*s != '\n') && (*s != '\r'); s++)
|
||
|
; /* empty body */
|
||
|
|
||
|
if ((n = s - t) > (m = screenWidth - screenLength[endLine])) n = m;
|
||
|
|
||
|
if (n > 0) {
|
||
|
DrawText(t, 0, n);
|
||
|
memcpy(screenLine[endLine] + screenLength[endLine], t, n);
|
||
|
screenLength[endLine] += n;
|
||
|
}
|
||
|
|
||
|
if ((*s == '\n') || (*s == '\r')) {
|
||
|
screenNewline();
|
||
|
s += 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
SetPort(savePort);
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
void screenDump(char *s, long n) {
|
||
|
GrafPort *savePort;
|
||
|
int k, m;
|
||
|
char *t;
|
||
|
|
||
|
GetPort(&savePort);
|
||
|
SetPort(theWindow);
|
||
|
|
||
|
while (n) {
|
||
|
screenPause();
|
||
|
|
||
|
for (t = s; (n) && (*s != '\n') && (*s != '\r'); s++, n--)
|
||
|
; /* empty body */
|
||
|
|
||
|
if ((k = s - t) > (m = screenWidth - screenLength[endLine])) k = m;
|
||
|
|
||
|
if (k > 0) {
|
||
|
DrawText(t, 0, k);
|
||
|
memcpy(screenLine[endLine] + screenLength[endLine], t, k);
|
||
|
screenLength[endLine] += k;
|
||
|
}
|
||
|
|
||
|
if ((*s == '\n') || (*s == '\r')) {
|
||
|
screenNewline();
|
||
|
s += 1;
|
||
|
n -= 1;
|
||
|
}
|
||
|
}
|
||
|
|
||
|
SetPort(savePort);
|
||
|
|
||
|
return;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
char *macfgets(char *s, int n, FILE *stream) {
|
||
|
GrafPort *savePort;
|
||
|
char c, *t = s;
|
||
|
|
||
|
stream = stream;
|
||
|
|
||
|
GetPort(&savePort);
|
||
|
SetPort(theWindow);
|
||
|
|
||
|
for (n -= 1; (n > 0) && ((c = waitChar()) != '\r'); n -= 1) {
|
||
|
DrawChar(*t++ = c);
|
||
|
if (screenLength[endLine] < screenWidth)
|
||
|
screenLine[endLine][screenLength[endLine]++] = c;
|
||
|
}
|
||
|
|
||
|
if (c == '\r') screenNewline();
|
||
|
|
||
|
*t = '\0';
|
||
|
|
||
|
SetPort(savePort);
|
||
|
|
||
|
return(s);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
int macfprintf(FILE *stream, char *format, ...)
|
||
|
{
|
||
|
char buffer[bufferSize];
|
||
|
va_list ap;
|
||
|
int rc;
|
||
|
|
||
|
stream = stream;
|
||
|
|
||
|
va_start(ap, format);
|
||
|
rc = vsprintf(buffer, format, ap);
|
||
|
va_end(ap);
|
||
|
|
||
|
screenDisplay(buffer);
|
||
|
|
||
|
return rc;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
|
||
|
int macprintf(char *format, ...)
|
||
|
{
|
||
|
char buffer[bufferSize];
|
||
|
va_list ap;
|
||
|
int rc;
|
||
|
|
||
|
va_start(ap, format);
|
||
|
rc = vsprintf(buffer, format, ap);
|
||
|
va_end(ap);
|
||
|
|
||
|
screenDisplay(buffer);
|
||
|
|
||
|
return rc;
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
/***********************/
|
||
|
/* Function macgetch() */
|
||
|
/***********************/
|
||
|
|
||
|
int macgetch(void)
|
||
|
{
|
||
|
WindowPtr whichWindow;
|
||
|
EventRecord theEvent;
|
||
|
char c; /* one-byte buffer for read() to use */
|
||
|
|
||
|
do {
|
||
|
SystemTask();
|
||
|
if (!GetNextEvent(everyEvent, &theEvent))
|
||
|
theEvent.what = nullEvent;
|
||
|
else {
|
||
|
switch (theEvent.what) {
|
||
|
case keyDown:
|
||
|
c = theEvent.message & charCodeMask;
|
||
|
break;
|
||
|
case mouseDown:
|
||
|
if (FindWindow(theEvent.where, &whichWindow) ==
|
||
|
inSysWindow)
|
||
|
SystemClick(&theEvent, whichWindow);
|
||
|
break;
|
||
|
case updateEvt:
|
||
|
screenUpdate((WindowPtr)theEvent.message);
|
||
|
break;
|
||
|
}
|
||
|
}
|
||
|
} while (theEvent.what != keyDown);
|
||
|
|
||
|
macprintf("*");
|
||
|
|
||
|
return (int)c;
|
||
|
}
|