/*
* @(#)AbacusD.c
*
* Copyright 1999 - 2017 David A. Bagley, bagleyd AT verizon.net
*
* Abacus demo and neat pointers from
* Copyright 1991 - 1998 Luis Fernandes, elf AT ee.ryerson.ca
*
* All rights reserved.
*
* Permission to use, copy, modify, and distribute this software and
* its documentation for any purpose and without fee is hereby granted,
* provided that the above copyright notice appear in all copies and
* that both that copyright notice and this permission notice appear in
* supporting documentation, and that the name of the author not be
* used in advertising or publicity pertaining to distribution of the
* software without specific, written prior permission.
*
* This program is distributed in the hope that it will be "useful",
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
*/
/* Methods demo file for Abacus */
#include "file.h"
#include "AbacusP.h"
#ifndef WINVER
static int displayedError = 0;
static void initializeAbacusDemo(Widget request, Widget renew);
static void exposeAbacusDemo(Widget renew, XEvent *event, Region region);
#if 0
static void resizeAbacusDemo(AbacusWidget w);
#endif
static void destroyAbacusDemo(Widget old);
static Boolean setValuesAbacusDemo(Widget current, Widget request, Widget renew);
static void quitAbacusDemo(AbacusWidget w, XEvent *event, char **args, int nArgs);
static void hideAbacusDemo(AbacusWidget w, XEvent *event, char **args, int nArgs);
static void selectAbacusDemo(AbacusWidget w, XEvent *event, char **args, int nArgs);
static void clearAbacusDemo(AbacusWidget w);
static void toggleDemoAbacusDemo(AbacusWidget w, XEvent *event, char **args, int nArgs);
static void showNextAbacusDemo(AbacusWidget w, XEvent *event, char **args, int nArgs);
static void showRepeatAbacusDemo(AbacusWidget w, XEvent *event, char **args, int nArgs);
static void showJumpAbacusDemo(AbacusWidget w, XEvent *event, char **args, int nArgs);
static void showMoreAbacusDemo(AbacusWidget w, XEvent *event, char **args, int nArgs);
static void incAbacusDemo(AbacusWidget w, XEvent *event, char **args, int nArgs);
static void decAbacusDemo(AbacusWidget w, XEvent *event, char **args, int nArgs);
static void addAbacusDemo(AbacusWidget w, XEvent *event, char **args, int nArgs);
static void subAbacusDemo(AbacusWidget w, XEvent *event, char **args, int nArgs);
static void multAbacusDemo(AbacusWidget w, XEvent *event, char **args, int nArgs);
static void divAbacusDemo(AbacusWidget w, XEvent *event, char **args, int nArgs);
static void sqrtAbacusDemo(AbacusWidget w, XEvent *event, char **args, int nArgs);
static void cbrtAbacusDemo(AbacusWidget w, XEvent *event, char **args, int nArgs);
static char translationsDemo[] =
"<KeyPress>q: Quit()\n\
Ctrl<KeyPress>C: Quit()\n\
<KeyPress>osfCancel: Hide()\n\
<KeyPress>Escape: Hide()\n\
<KeyPress>osfEscape: Hide()\n\
Ctrl<KeyPress>[: Hide()\n\
<KeyPress>0x1B: Hide()\n\
<Btn1Down>: Select()\n\
<KeyPress>c: Select()\n\
<KeyPress>o: Demo()\n\
<KeyPress>n: Next()\n\
<KeyPress>r: Repeat()\n\
<KeyPress>j: Jump()\n\
<KeyPress>0x20: More()\n\
<KeyPress>KP_Space: More()\n\
<KeyPress>Return: More()\n\
<KeyPress>1: IncChapter()\n\
<KeyPress>2: DecChapter()\n\
<KeyPress>3: AddChapter()\n\
<KeyPress>4: SubChapter()\n\
<KeyPress>5: MultChapter()";
/* <KeyPress>6: DivChapter()\n\
<KeyPress>7: SqrtChapter()\n\
<KeyPress>8: CbrtChapter()";*/
/* KP_Space does not work here
0x20 is SP (' ') in ASCII (DP in EBCDIC)
0x40 is SP (' ') in EBCDIC ('@' in ASCII)
<KeyPress>0x27: Hide()\n\
<KeyPress>0x40: More()\n\
*/
static XtActionsRec actionsListDemo[] =
{
{(char *) "Quit", (XtActionProc) quitAbacusDemo},
{(char *) "Hide", (XtActionProc) hideAbacusDemo},
{(char *) "Select", (XtActionProc) selectAbacusDemo},
{(char *) "Demo", (XtActionProc) toggleDemoAbacusDemo},
{(char *) "Next", (XtActionProc) showNextAbacusDemo},
{(char *) "Repeat", (XtActionProc) showRepeatAbacusDemo},
{(char *) "Jump", (XtActionProc) showJumpAbacusDemo},
{(char *) "More", (XtActionProc) showMoreAbacusDemo},
{(char *) "IncChapter", (XtActionProc) incAbacusDemo},
{(char *) "DecChapter", (XtActionProc) decAbacusDemo},
{(char *) "AddChapter", (XtActionProc) addAbacusDemo},
{(char *) "SubChapter", (XtActionProc) subAbacusDemo},
{(char *) "MultChapter", (XtActionProc) multAbacusDemo},
{(char *) "DivChapter", (XtActionProc) divAbacusDemo},
{(char *) "SqrtChapter", (XtActionProc) sqrtAbacusDemo},
{(char *) "CbrtChapter", (XtActionProc) cbrtAbacusDemo}
};
/* Bug in Lesstif # 2801540 */
static XtResource resourcesDemo[] =
{
{XtNwidth, XtCWidth, XtRDimension, sizeof (Dimension),
XtOffset(AbacusWidget, core.width),
XtRString, (caddr_t) "436"},
{XtNheight, XtCHeight, XtRDimension, sizeof (Dimension),
XtOffset(AbacusWidget, core.height),
XtRString, (caddr_t) "134"},
{XtNmono, XtCMono, XtRBoolean, sizeof (Boolean),
XtOffset(AbacusWidget, abacus.mono),
XtRString, (caddr_t) "FALSE"},
{XtNreverseVideo, XtCReverseVideo, XtRBoolean, sizeof (Boolean),
XtOffset(AbacusWidget, abacus.reverse),
XtRString, (caddr_t) "FALSE"},
{XtNdemoPath, XtCDemoPath, XtRString, sizeof (String),
XtOffset(AbacusWidget, abacusDemo.path),
XtRString, (caddr_t) DEMOPATH},
{XtNdemoFont, XtCFont, XtRString, sizeof (String),
XtOffset(AbacusWidget, abacusDemo.font),
XtRString, (caddr_t) "-*-times-*-r-*-*-*-180-*-*-*-*"},
{XtNdemoForeground, XtCForeground, XtRPixel, sizeof (Pixel),
XtOffset(AbacusWidget, abacusDemo.foreground),
XtRString, (caddr_t) XtDefaultForeground},
{XtNdemoBackground, XtCBackground, XtRPixel, sizeof (Pixel),
XtOffset(AbacusWidget, abacusDemo.background),
XtRString, (caddr_t) XtDefaultBackground},
{XtNdeck, XtCDeck, XtRInt, sizeof (int),
XtOffset(AbacusWidget, abacus.deck),
XtRString, (caddr_t) "-1"}, /* IGNORE_DECK */
{XtNrail, XtCRail, XtRInt, sizeof (int),
XtOffset(AbacusWidget, abacus.rail),
XtRString, (caddr_t) "0"},
{XtNnumber, XtCNumber, XtRInt, sizeof (int),
XtOffset(AbacusWidget, abacus.number),
XtRString, (caddr_t) "0"},
{XtNframed, XtCFramed, XtRBoolean, sizeof (Boolean),
XtOffset(AbacusWidget, abacusDemo.framed),
XtRString, (caddr_t) "FALSE"},
{XtNmode, XtCMode, XtRInt, sizeof (int),
XtOffset(AbacusWidget, abacus.mode),
XtRString, (caddr_t) "0"}, /* CHINESE */
{XtNselectCallback, XtCCallback, XtRCallback, sizeof (caddr_t),
XtOffset(AbacusWidget, abacus.select),
XtRCallback, (caddr_t) NULL}
};
static AbacusClassRec abacusDemoClassRec =
{
{
(WidgetClass) & widgetClassRec, /* superclass */
(char *) "AbacusDemo", /* class name */
sizeof (AbacusRec), /* widget size */
NULL, /* class initialize */
NULL, /* class part initialize */
FALSE, /* class inited */
(XtInitProc) initializeAbacusDemo, /* initialize */
NULL, /* initialize hook */
XtInheritRealize, /* realize */
actionsListDemo, /* actions */
XtNumber(actionsListDemo), /* num actions */
resourcesDemo, /* resources */
XtNumber(resourcesDemo), /* num resources */
NULLQUARK, /* xrm class */
TRUE, /* compress motion */
TRUE, /* compress exposure */
TRUE, /* compress enterleave */
TRUE, /* visible interest */
(XtWidgetProc) destroyAbacusDemo, /* destroy */
#if 0
(XtWidgetProc) resizeAbacusDemo, /* resize */
#else
NULL, /* resize */
#endif
(XtExposeProc) exposeAbacusDemo, /* expose */
(XtSetValuesFunc) setValuesAbacusDemo, /* set values */
NULL, /* set values hook */
XtInheritSetValuesAlmost, /* set values almost */
NULL, /* get values hook */
NULL, /* accept focus */
XtVersion, /* version */
NULL, /* callback private */
translationsDemo, /* tm table */
NULL, /* query geometry */
NULL, /* display accelerator */
NULL /* extension */
},
{
0 /* ignore */
}
};
WidgetClass abacusDemoWidgetClass = (WidgetClass) & abacusDemoClassRec;
static void
setAllColors(AbacusWidget w, Boolean init)
{
XGCValues values;
XtGCMask valueMask;
valueMask = GCForeground | GCBackground;
if (w->abacus.mono) {
if (w->abacus.reverse) {
values.background = w->abacus.foreground;
values.foreground = w->core.background_pixel;
} else {
values.foreground = w->abacus.foreground;
values.background = w->core.background_pixel;
}
} else {
if (w->abacus.reverse) {
values.foreground = w->abacusDemo.background;
values.background = w->abacusDemo.foreground;
} else {
values.background = w->abacusDemo.background;
values.foreground = w->abacusDemo.foreground;
}
}
if (!init)
XtReleaseGC((Widget) w, w->abacusDemo.foregroundGC);
w->abacusDemo.foregroundGC = XtGetGC((Widget) w, valueMask, &values);
if (w->abacus.mono) {
if (w->abacus.reverse) {
values.foreground = w->abacus.foreground;
values.background = w->core.background_pixel;
} else {
values.background = w->abacus.foreground;
values.foreground = w->core.background_pixel;
}
} else {
if (w->abacus.reverse) {
values.background = w->abacusDemo.background;
values.foreground = w->abacusDemo.foreground;
} else {
values.foreground = w->abacusDemo.background;
values.background = w->abacusDemo.foreground;
}
}
if (!init)
XtReleaseGC((Widget) w, w->abacusDemo.inverseGC);
w->abacusDemo.inverseGC = XtGetGC((Widget) w, valueMask, &values);
if (w->abacusDemo.fontInfo)
VOID XSetFont(XtDisplay(w), w->abacusDemo.foregroundGC,
w->abacusDemo.fontInfo->fid);
}
static void
loadFont(AbacusWidget w)
{
/*const char *fontname = "-*-times-*-r-*-*-*-180-*"; */
Display *display = XtDisplay(w);
const char *altfontname = "8x13";
char buf[512];
/* Access font */
if (w->abacusDemo.font && (w->abacusDemo.fontInfo =
XLoadQueryFont(display, w->abacusDemo.font)) == NULL) {
(void) sprintf(buf,
"Can not open %s font.\nAttempting %s font as alternate\n",
w->abacusDemo.font, altfontname);
DISPLAY_WARNING(buf);
if ((w->abacusDemo.fontInfo = XLoadQueryFont(display,
altfontname)) == NULL) {
(void) sprintf(buf,
"Can not open %s alternate font.\nUse the -demofont option to specify a font to use.\n",
altfontname);
DISPLAY_ERROR(buf);
}
}
w->abacusDemo.fontHeight = w->abacusDemo.fontInfo->max_bounds.ascent +
w->abacusDemo.fontInfo->max_bounds.descent;
}
#endif
#define setAbacusDemo(w,r) setAbacus(w,r)
typedef enum {
INTRO, BOOK, CHAPTER, QUERY, DISPLAY, CONCL
} TextType;
static const char *introFramelessText[LINES] =
{
"Place this window below the abacus, then click & leave",
"the pointer in the abacus window to begin the demo.",
"During the demo, use the Space-bar to step.",
"Type `o' to toggle demo or `q' to quit.",
};
static const char *introFramedText[LINES] =
{
"Click & leave the pointer in the abacus window",
"to begin the demo.",
"During the demo, use the Space-bar to step.",
"Type `o' to toggle demo or `q' to quit.",
};
static const char *bookText[LINES] =
{
" ",
"Type: `r' to Read this book",
" `n' to Next book",
" `q' to Quit the demo",
};
static const char *chapterText[LINES] =
{
" ",
"Type: `r' to Read this chapter",
" `n' to Next chapter",
" `q' to Quit the demo",
};
static const char *queryText[LINES] =
{
"Type: `n' for the Next lesson",
" `r' to Repeat previous lesson",
" `j' to Jump to next chapter",
" `q' to Quit the demo",
};
static const char *conclLesson[LINES] =
{
"Here Endth The Lesson",
"",
"",
"",
};
/* This array represents 4 lines of text that are to be displayed in the
* demo window; the module drawDemoWindow() will be passed a pointer to this
* array */
static char displayText[LINES][CHARS] = {"", "", "", ""};
static Boolean fallback = True;
#if 0
static const char *
postfixType(int mode)
{
switch (mode) {
case CHINESE:
return ""; /* cn */
case JAPANESE:
return "jp";
case KOREAN:
return "ko";
case ROMAN:
return "jp"; /* ro */
case RUSSIAN:
return "ru";
case DANISH:
return "ru"; /* dk */
case MEDIEVAL:
return ""; /* cn, me, ge, uk */
default:
return "";
}
}
#endif
static unsigned int
commonEdition(unsigned int mode)
{
unsigned int edition;
switch (mode) {
case ROMAN:
edition = JAPANESE;
break;
case DANISH:
edition = RUSSIAN;
break;
case MEDIEVAL:
edition = CHINESE;
break;
default:
edition = mode;
}
return edition;
}
static unsigned int getNumberBooks(void) {
if (fallback)
return getFallbackBooks();
return abacusLibrary.books;
}
static unsigned int getNumberEditions(AbacusWidget w) {
if (fallback)
return getFallbackEditions();
if (abacusLibrary.book == NULL)
return 0;
return abacusLibrary.book[w->abacusDemo.bookCount].editions;
}
static unsigned int getEdition(AbacusWidget w) {
unsigned int edition = commonEdition((unsigned int) w->abacus.mode);
unsigned int editions = getNumberEditions(w);
if (edition >= editions) {
#ifdef DEBUG
(void) fprintf(stderr, " getEdition forcing : %d\n", CHINESE);
#endif
return CHINESE;
}
#ifdef DEBUG
(void) fprintf(stderr, " getEdition returning : %d\n", edition);
#endif
return edition;
}
static unsigned int getNumberChapters(AbacusWidget w) {
if (fallback)
return getFallbackChapters();
if (abacusLibrary.book[w->abacusDemo.bookCount].edition == NULL)
return 0;
return abacusLibrary.book[w->abacusDemo.bookCount].edition[getEdition(w)].chapters;
}
static unsigned int getNumberLessons(AbacusWidget w) {
unsigned int edition = getEdition(w);
if (fallback) {
return getFallbackLessons(w->abacusDemo.chapterCount);
} else {
if (abacusLibrary.book[w->abacusDemo.bookCount].edition[edition].chapter == NULL)
return 0;
return abacusLibrary.book[w->abacusDemo.bookCount].edition[edition].chapter[w->abacusDemo.chapterCount].lessons;
}
}
static unsigned int getNumberMoves(AbacusWidget w) {
unsigned int edition = getEdition(w);
if (fallback) {
return getFallbackMoves(edition, w->abacusDemo.chapterCount, w->abacusDemo.lessonCount);
} else {
if (abacusLibrary.book[w->abacusDemo.bookCount].edition[edition].chapter[w->abacusDemo.chapterCount].lesson == NULL)
return 0;
return abacusLibrary.book[w->abacusDemo.bookCount].edition[edition].chapter[w->abacusDemo.chapterCount].lesson[w->abacusDemo.lessonCount].moves;
}
}
static void drawLineText(AbacusWidget w, const char* line, int i)
{
#ifdef WINVER
#ifdef DEMO_FRAMED
(void) SetTextColor(w->core.hDC, w->abacusDemo.foregroundGC);
(void) SetBkMode(w->core.hDC, TRANSPARENT);
(void) TextOut(w->core.hDC,
1,
w->core.height + w->abacusDemo.fontHeight * i - 1,
line, (signed) strlen(line));
#else
drawDemoText(line, i);
#endif
#else
(void) XDrawString(XtDisplay(w), XtWindow(w),
w->abacusDemo.foregroundGC,
1, w->abacusDemo.fontHeight +
(w->abacusDemo.fontHeight * i),
line, strlen(line));
FLUSH(w);
#endif
}
static void
drawText(AbacusWidget w, TextType textType)
{
unsigned int edition = getEdition(w);
int line;
#if 0
#if (defined(WINVER) && defined(DEMO_FRAMED) || !defined(WINVER))
else
#endif
#endif
#ifdef WINVER
#ifdef DEMO_FRAMED
{
Pixmap dr = 0;
FILLRECTANGLE(w, dr, w->abacus.inverseGC,
0, w->core.height, w->core.width,
w->core.height + LINES * w->abacusDemo.fontHeight - 1);
}
#endif
#else
{
Pixmap dr = 0;
FILLRECTANGLE(w, dr, w->abacusDemo.inverseGC,
0, 0, w->core.width, w->core.height);
}
#endif
if (textType == BOOK) {
unsigned int realMode = (unsigned int) w->abacus.mode;
unsigned int forcedMode = getEdition(w);
edition = forcedMode;
/* Korean and Japanese are similar and may be OK */
if (forcedMode == 0 &&
(realMode == RUSSIAN || realMode == DANISH)) {
(void) fprintf(stderr, "No Russian edition, expect errors.\n");
}
}
for (line = 0; line < w->abacusDemo.lines; line++) {
const char* temp;
switch (textType) {
case INTRO:
if (w->abacusDemo.framed)
temp = introFramedText[line];
else
temp = introFramelessText[line];
#ifdef DEBUG
(void) fprintf(stderr, " INTRO: %s\n", temp);
#endif
w->abacusDemo.chapter = False;
w->abacusDemo.book = True;
break;
case BOOK:
if (fallback) {
temp = bookTextFallback[w->abacusDemo.bookCount][line];
#ifdef DEBUG
(void) fprintf(stderr, " BOOK: %s\n", temp);
#endif
} else {
temp = bookText[line];
#ifdef DEBUG
(void) fprintf(stderr, " BOOK: %s\n", temp);
#endif
if (line == 0) {
char buf[512];
sprintf(buf, "%s%s by %s", temp,
abacusLibrary.book[w->abacusDemo.bookCount].name,
abacusLibrary.book[w->abacusDemo.bookCount].author);
drawLineText(w, buf, line);
continue;
}
}
break;
case CHAPTER:
if (fallback) {
temp = chapterTextFallback[w->abacusDemo.bookCount][w->abacusDemo.chapterCount][line];
#ifdef DEBUG
(void) fprintf(stderr, " CHAPTER: %s\n", temp);
#endif
} else {
temp = chapterText[line];
#ifdef DEBUG
(void) fprintf(stderr, " CHAPTER: %s\n", temp);
#endif
if (line == 0) {
char buf[512];
sprintf(buf, "%s%s", temp,
abacusLibrary.book[w->abacusDemo.bookCount].edition[edition].chapter[w->abacusDemo.chapterCount].name);
drawLineText(w, buf, line);
continue;
}
}
break;
case CONCL:
w->abacusDemo.started = False;
temp = conclLesson[line];
#ifdef DEBUG
(void) fprintf(stderr, " CONCL: %s\n", temp);
#endif
break;
case QUERY:
w->abacusDemo.query = True;
temp = queryText[line];
#ifdef DEBUG
(void) fprintf(stderr, " QUERY: %s\n", temp);
#endif
break;
default:
temp = displayText[line];
#ifdef DEBUG
(void) fprintf(stderr, " DISPLAY: %s\n", temp);
#endif
break;
}
drawLineText(w, temp, line);
}
}
static void
doLesson(AbacusWidget w)
{
int line;
/* load first instance */
unsigned int edition = getEdition(w);
const char *tmp;
unsigned int numberMoves = getNumberMoves(w);
if (w->abacusDemo.moveCount < numberMoves) {
if (w->abacusDemo.lessonCount >= getNumberLessons(w)) {
#ifdef DEBUG
(void) fprintf(stderr, "returning doLesson:\n");
#endif
w->abacusDemo.chapter = True;
return;
}
if (fallback) {
tmp = lessonTextFallback[w->abacusDemo.bookCount][edition][w->abacusDemo.chapterCount][w->abacusDemo.lessonCount][w->abacusDemo.moveCount][0];
} else {
tmp = abacusLibrary.book[w->abacusDemo.bookCount].edition[edition].chapter[w->abacusDemo.chapterCount].lesson[w->abacusDemo.lessonCount].move[w->abacusDemo.moveCount].code;
}
(void) sscanf(tmp, "%d %d %d %d %d",
&(w->abacusDemo.aux),
&(w->abacusDemo.deck), &(w->abacusDemo.rail),
&(w->abacusDemo.number), &(w->abacusDemo.lines));
#ifdef DEBUG
(void) fprintf(stderr,
"aux = %d, deck = %d, rail = %d, number = %d, lines = %d\n",
w->abacusDemo.aux,
w->abacusDemo.deck, w->abacusDemo.rail,
w->abacusDemo.number, w->abacusDemo.lines);
#endif
if (w->abacusDemo.lines > LINES)
w->abacusDemo.lines = LINES;
for (line = 0; line < w->abacusDemo.lines; line++) {
if (fallback) {
tmp = lessonTextFallback[w->abacusDemo.bookCount][edition][w->abacusDemo.chapterCount][w->abacusDemo.lessonCount][w->abacusDemo.moveCount][line + 1];
} else {
tmp = abacusLibrary.book[w->abacusDemo.bookCount].edition[edition].chapter[w->abacusDemo.chapterCount].lesson[w->abacusDemo.lessonCount].move[w->abacusDemo.moveCount].lineText[line]; // 64 char
}
(void) strcpy(displayText[line], tmp);
displayText[line][strlen(displayText[line])] = '\0';
}
}
/* A '0' in demo number signifies that only the text is to be
* displayed (i.e. nothing is to be added or subtracted).
*/
if (w->abacusDemo.moveCount <= numberMoves) {
setAbacusMove(w, ACTION_MOVE, w->abacusDemo.aux,
w->abacusDemo.deck, w->abacusDemo.rail,
w->abacusDemo.number);
if (w->abacusDemo.highlightAux >= 0 &&
w->abacusDemo.highlightRail >= 0) {
setAbacusHighlightRail(w, ACTION_UNHIGHLIGHT_RAIL,
w->abacusDemo.highlightAux,
w->abacusDemo.highlightRail);
w->abacusDemo.highlightAux = -1;
w->abacusDemo.highlightRail = -1;
}
if (w->abacusDemo.aux >= 0 &&
w->abacusDemo.rail >= 0) {
if (w->abacusDemo.number == 0) {
w->abacusDemo.highlightAux = -1;
w->abacusDemo.highlightRail = -1;
} else {
w->abacusDemo.highlightAux = w->abacusDemo.aux;
w->abacusDemo.highlightRail = w->abacusDemo.rail;
setAbacusHighlightRail(w, ACTION_HIGHLIGHT_RAIL,
w->abacusDemo.aux, w->abacusDemo.rail);
}
}
}
#ifdef DEBUG
(void) fprintf(stderr, " doLesson:\n");
#endif
if (++w->abacusDemo.moveCount > numberMoves) {
//(void) fclose(w->abacusDemo.fp);
drawText(w, CONCL);
Sleep(2000);
if (w->abacusDemo.aux >= 0) {
setAbacusHighlightRails(w, w->abacusDemo.aux);
w->abacusDemo.highlightAux = -1;
}
drawText(w, QUERY);
setAbacusDemo(w, ACTION_CLEAR_NODEMO);
} else if (w->abacusDemo.started) {
if (w->abacusDemo.book) {
drawText(w, BOOK);
} else if (w->abacusDemo.chapter) {
drawText(w, CHAPTER);
} else {
drawText(w, DISPLAY);
}
} else if (w->abacusDemo.query) {
drawText(w, QUERY);
} else {
drawText(w, INTRO);
}
}
static void
queryDemo(AbacusWidget w, Boolean advance)
{
#ifdef DEBUG
(void) fprintf(stderr, "queryDemo: advance %d\n",
advance);
#endif
w->abacusDemo.started = True;
if (w->abacusDemo.book) {
if (advance) {
w->abacusDemo.bookCount++;
if (w->abacusDemo.bookCount >= getNumberBooks())
w->abacusDemo.bookCount = 0;
drawText(w, BOOK);
} else {
/* got a Read */
w->abacusDemo.book = False;
w->abacusDemo.chapter = True;
w->abacusDemo.chapterCount = 0;
w->abacusDemo.query = False;
drawText(w, CHAPTER);
}
} else if (w->abacusDemo.chapter) {
if (advance) {
w->abacusDemo.chapterCount++;
if (w->abacusDemo.chapterCount >= getNumberChapters(w)) {
w->abacusDemo.chapterCount = 0;
w->abacusDemo.bookCount++;
if (w->abacusDemo.bookCount >= getNumberBooks()) {
w->abacusDemo.bookCount = 0;
}
w->abacusDemo.book = True;
drawText(w, BOOK);
} else {
drawText(w, CHAPTER);
}
} else {
/* got a Read */
w->abacusDemo.chapter = False;
w->abacusDemo.lessonCount = 0;
w->abacusDemo.moveCount = 0;
w->abacusDemo.query = False;
doLesson(w);
}
} else {
if (w->abacusDemo.query) {
w->abacusDemo.started = True;
w->abacusDemo.query = False;
w->abacusDemo.moveCount = 0;
if (advance) {
w->abacusDemo.lessonCount++;
if (w->abacusDemo.lessonCount >= getNumberLessons(w)) {
w->abacusDemo.lessonCount = 0;
w->abacusDemo.chapterCount++;
if (w->abacusDemo.chapterCount >= getNumberChapters(w)) {
w->abacusDemo.chapterCount = 0;
w->abacusDemo.bookCount++;
if (w->abacusDemo.bookCount >= getNumberBooks()) {
w->abacusDemo.bookCount = 0;
}
w->abacusDemo.book = True;
drawText(w, BOOK);
} else {
w->abacusDemo.chapter = True;
drawText(w, CHAPTER);
}
}
}
doLesson(w);
}
}
}
static void
jumpDemo(AbacusWidget w)
{
if (!w->abacusDemo.chapter) {
w->abacusDemo.chapter = True;
w->abacusDemo.started = True;
w->abacusDemo.moveCount = 0;
w->abacusDemo.lessonCount = 0;
w->abacusDemo.chapterCount++;
if (w->abacusDemo.chapterCount >= getNumberChapters(w)) {
w->abacusDemo.chapterCount = 0;
w->abacusDemo.bookCount++;
if (w->abacusDemo.bookCount >= getNumberBooks()) {
w->abacusDemo.bookCount = 0;
}
w->abacusDemo.book = True;
drawText(w, BOOK);
} else {
drawText(w, CHAPTER);
}
}
}
static void
chapterDemo(AbacusWidget w, unsigned int chapt)
{
if (w->abacusDemo.started && w->abacusDemo.chapter) {
w->abacusDemo.moveCount = 0;
w->abacusDemo.lessonCount = 0;
w->abacusDemo.chapterCount = chapt;
if (w->abacusDemo.chapterCount >= getNumberChapters(w))
w->abacusDemo.chapterCount = 0;
drawText(w, CHAPTER);
}
}
static void
moreDemo(AbacusWidget w)
{
if (!w->abacusDemo.book && !w->abacusDemo.chapter &&
w->abacusDemo.started && !w->abacusDemo.query) {
doLesson(w);
}
}
#ifndef WINVER
static
#endif
void
initializeAbacusDemo(
#ifdef WINVER
AbacusWidget w
#else
Widget request, Widget renew
#endif
)
{
#ifndef WINVER
AbacusWidget w = (AbacusWidget) renew;
w->abacus.mono = (DefaultDepthOfScreen(XtScreen(w)) < 2 ||
w->abacus.mono);
loadFont(w);
setAllColors(w, True);
#if 0
resizeAbacusDemo(w);
#endif
#else
#if 0
hBrush = CreateSolidBrush(w->abacusDemo.background);
SETBACK(w->core.hWnd, hBrush);
#endif
#endif
w->abacusDemo.started = False;
w->abacusDemo.query = False;
w->abacusDemo.chapter = False;
w->abacusDemo.book = True;
w->abacusDemo.bookCount = 0;
w->abacusDemo.chapterCount = 0;
w->abacusDemo.lessonCount = 0;
w->abacusDemo.moveCount = 0;
w->abacusDemo.lines = LINES;
w->abacusDemo.highlightAux = -1;
w->abacusDemo.highlightRail = -1;
readParseFile(XML_FILE);
if (abacusLibrary.book != NULL) {
fallback = False;
#ifndef WINVER
/* always true in Windows version, some runtime issue with libraries */
} else {
if (displayedError == 0) {
(void) fprintf(stderr, "Trouble using XML, using the static fallback single book demo.\n");
displayedError = 1;
}
#endif
}
}
#ifndef WINVER
static Boolean
setValuesAbacusDemo(Widget current, Widget request, Widget renew)
{
AbacusWidget c = (AbacusWidget) current, w = (AbacusWidget) renew;
Boolean redraw = False;
#if 0
Boolean redrawText = False;
#endif
if (w->abacus.mode != c->abacus.mode) {
redraw = True;
}
if (w->core.background_pixel != c->core.background_pixel ||
w->abacusDemo.background != c->abacusDemo.background ||
w->abacusDemo.foreground != c->abacusDemo.foreground ||
w->abacus.reverse != c->abacus.reverse ||
w->abacus.mono != c->abacus.mono) {
setAllColors(w, False);
redraw = True;
#if 0
redrawText = True;
#endif
}
#if 0
if (!redraw && XtIsRealized(renew) && renew->core.visible) {
/* Redraw text */
}
#endif
switch (w->abacus.deck) {
case CLEAR_DECK:
w->abacus.deck = IGNORE_DECK;
clearAbacusDemo(w);
break;
case NEXT_DECK:
w->abacus.deck = IGNORE_DECK;
queryDemo(w, True);
break;
case REPEAT_DECK:
w->abacus.deck = IGNORE_DECK;
queryDemo(w, False);
break;
case JUMP_DECK:
w->abacus.deck = IGNORE_DECK;
jumpDemo(w);
break;
case MORE_DECK:
w->abacus.deck = IGNORE_DECK;
moreDemo(w);
break;
}
return (redraw);
}
static void
quitAbacusDemo(AbacusWidget w, XEvent *event, char **args, int nArgs)
{
setAbacusDemo(w, ACTION_DEMO);
}
static void
destroyAbacusDemo(Widget old)
{
AbacusWidget w = (AbacusWidget) old;
if (abacusLibrary.book != NULL) {
freeAbacus(abacusLibrary.book, abacusLibrary.books);
abacusLibrary.book = NULL;
abacusLibrary.books = 0;
}
XtReleaseGC(old, w->abacusDemo.foregroundGC);
XtReleaseGC(old, w->abacusDemo.inverseGC);
XtRemoveCallbacks(old, XtNselectCallback, w->abacus.select);
VOID XFreeFont(XtDisplay(w), w->abacusDemo.fontInfo);
}
#else
#if 0
void
destroyAbacusDemo(HBRUSH hBrush)
{
(void) DeleteObject(hBrush);
PostQuitMessage((int) NULL);
}
#endif
#endif
#if 0
static void
resizeAbacusDemo(AbacusWidget w)
{
}
#endif
#ifndef WINVER
static
#endif
void
exposeAbacusDemo(
#ifdef WINVER
AbacusWidget w
#else
Widget renew, XEvent *event, Region region
#endif
)
{
#ifdef WINVER
#ifdef DEMO_FRAMED
{
Pixmap dr = 0;
FILLRECTANGLE(w, dr, w->abacus.inverseGC,
0, w->core.height, w->core.width,
w->core.height + LINES * w->abacusDemo.fontHeight - 1);
}
#endif
#else
AbacusWidget w = (AbacusWidget) renew;
Pixmap dr = 0;
if (!w->core.visible)
return;
FILLRECTANGLE(w, dr, w->abacusDemo.inverseGC,
0, 0, w->core.width, w->core.height);
#endif
if (w->abacusDemo.started) {
if (w->abacusDemo.book) {
drawText(w, BOOK);
} else if (w->abacusDemo.chapter) {
drawText(w, CHAPTER);
} else {
drawText(w, DISPLAY);
}
} else if (w->abacusDemo.query) {
drawText(w, QUERY);
} else {
drawText(w, BOOK);
}
}
#ifndef WINVER
static
void
hideAbacusDemo(AbacusWidget w
, XEvent *event, char **args, int nArgs
)
{
setAbacusDemo(w, ACTION_HIDE);
if (abacusLibrary.book != NULL) {
freeAbacus(abacusLibrary.book, abacusLibrary.books);
abacusLibrary.book = NULL;
abacusLibrary.books = 0;
}
}
static
void
selectAbacusDemo(AbacusWidget w
, XEvent *event, char **args, int nArgs
)
{
/*clearAbacusDemo(w);*/
}
#endif
#ifndef WINVER
static
#endif
void
clearAbacusDemo(AbacusWidget w)
{
#ifdef DEBUG
(void) fprintf(stderr, " CLEAR\n");
#endif
w->abacusDemo.started = True;
/*w->abacusDemo.query = True;*/
w->abacusDemo.moveCount = 0;
if (w->abacusDemo.highlightAux >= 0 &&
w->abacusDemo.highlightRail >= 0) {
setAbacusHighlightRail(w, ACTION_UNHIGHLIGHT_RAIL,
w->abacusDemo.highlightAux,
w->abacusDemo.highlightRail);
w->abacusDemo.highlightAux = -1;
w->abacusDemo.highlightRail = -1;
}
}
#ifndef WINVER
static
#endif
void
toggleDemoAbacusDemo(AbacusWidget w
#ifndef WINVER
, XEvent *event, char **args, int nArgs
#endif
)
{
#ifdef WINVER
w->abacus.demo = !w->abacus.demo;
if (w->abacus.demo) {
setAbacusDemo(w, ACTION_DEMO_DEFAULT);
w->abacusDemo.started = False;
w->abacusDemo.bookCount = 0;
w->abacusDemo.chapterCount = 0;
w->abacusDemo.lessonCount = 0;
w->abacusDemo.moveCount = 0;
w->abacusDemo.query = True;
w->abacusDemo.chapter = False;
w->abacusDemo.book = False;
}
#else
setAbacusDemo(w, ACTION_DEMO);
#endif
}
#ifndef WINVER
static
#endif
void
showNextAbacusDemo(AbacusWidget w
#ifndef WINVER
, XEvent *event, char **args, int nArgs
#endif
)
{
queryDemo(w, True);
}
#ifndef WINVER
static
#endif
void
showRepeatAbacusDemo(AbacusWidget w
#ifndef WINVER
, XEvent *event, char **args, int nArgs
#endif
)
{
queryDemo(w, False);
}
#ifndef WINVER
static
#endif
void
showJumpAbacusDemo(AbacusWidget w
#ifndef WINVER
, XEvent *event, char **args, int nArgs
#endif
)
{
jumpDemo(w);
}
#ifndef WINVER
static
#endif
void
showMoreAbacusDemo(AbacusWidget w
#ifndef WINVER
, XEvent *event, char **args, int nArgs
#endif
)
{
moreDemo(w);
}
#ifdef WINVER
void
showChapterAbacusDemo(AbacusWidget w, unsigned int chapt)
{
chapterDemo(w, chapt);
}
#else
static void
incAbacusDemo(AbacusWidget w , XEvent *event, char **args, int nArgs)
{
chapterDemo(w, 0);
}
static void
decAbacusDemo(AbacusWidget w, XEvent *event, char **args, int nArgs)
{
chapterDemo(w, 1);
}
static void
addAbacusDemo(AbacusWidget w, XEvent *event, char **args, int nArgs)
{
chapterDemo(w, 2);
}
static void
subAbacusDemo(AbacusWidget w, XEvent *event, char **args, int nArgs)
{
chapterDemo(w, 3);
}
static void
multAbacusDemo(AbacusWidget w, XEvent *event, char **args, int nArgs)
{
chapterDemo(w, 4);
}
static void
divAbacusDemo(AbacusWidget w, XEvent *event, char **args, int nArgs)
{
chapterDemo(w, 5);
}
static void
sqrtAbacusDemo(AbacusWidget w, XEvent *event, char **args, int nArgs)
{
chapterDemo(w, 6);
}
static void
cbrtAbacusDemo(AbacusWidget w, XEvent *event, char **args, int nArgs)
{
chapterDemo(w, 7);
}
#endif