This is TextMain.c in view mode; [Download] [Up]
/*
* $RCSfile: TextMain.c,v $
*
* Copyright (C) 1992 by Adobe Systems Incorporated.
* 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 notices appear in all copies and that
* both those copyright notices and this permission notice appear in
* supporting documentation and that the name of Adobe Systems
* Incorporated not be used in advertising or publicity pertaining to
* distribution of the software without specific, written prior
* permission. If any portion of this software is changed, it cannot be
* marketed under Adobe's trademarks and/or copyrights unless Adobe, in
* its sole discretion, approves by a prior writing the quality of the
* resulting implementation.
*
* ADOBE MAKES NO REPRESENTATIONS ABOUT THE SUITABILITY OF THE SOFTWARE FOR
* ANY PURPOSE. IT IS PROVIDED "AS IS" WITHOUT EXPRESS OR IMPLIED WARRANTY.
* ADOBE DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
* IMPLIED WARRANTIES OF MERCHANTABILITY FITNESS FOR A PARTICULAR PURPOSE AND
* NON-INFRINGEMENT OF THIRD PARTY RIGHTS. IN NO EVENT SHALL ADOBE BE LIABLE
* TO YOU OR ANY OTHER PARTY FOR ANY SPECIAL, INDIRECT, OR CONSEQUENTIAL
* DAMAGES OR ANY DAMAGES WHATSOEVER WHETHER IN AN ACTION OF CONTRACT,
* NEGLIGENCE, STRICT LIABILITY OR ANY OTHER ACTION ARISING OUT OF OR IN
* CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. ADOBE WILL NOT
* PROVIDE ANY TRAINING OR OTHER SUPPORT FOR THE SOFTWARE.
*
* PostScript, Display PostScript, and Adobe are trademarks of Adobe Systems
* Incorporated registered in the U.S.A. and other countries.
*
* Author: Adobe Systems Incorporated
*/
/***************************************************************
**
** INCLUDE FILES
**
***************************************************************/
#include "Text.h"
#include "zoom.xbm"
#include "zoom_mask.xbm"
#include <X11/cursorfont.h>
#include <DPS/PSres.h>
/***************************************************************
**
** DATA DECLARATIONS
**
***************************************************************/
/*
** Global pointers to the application data block
*/
AppDataType AppData;
/*
** Global resource management data
*/
static MrmHierarchy SMrmHierarchy; /* MRM database hierarchy ID */
static MrmType *DummyClass; /* and class variable. */
static char *DbFilenameVec[] = /* Mrm.heirarchy file list. */
{
"Text.uid"
};
static void mouseDown(), traceProc(), reshowProc(), justifySel(), spacingSel(),
showSel(), sizeSel(), issuesSel(), compSel(), magSel(),
resizeWindow(), refreshWindow(), createProc(), quitApp();
/*
** Names and addresses for Mrm to bind
*/
static MrmRegisterArg RegList[] =
{
{"resizeWindow" , (XtPointer) resizeWindow },
{"refreshWindow" , (XtPointer) refreshWindow },
{"createProc" , (XtPointer) createProc },
{"quitApp" , (XtPointer) quitApp },
{"traceProc" , (XtPointer) traceProc },
{"reshowProc" , (XtPointer) reshowProc },
{"justifySel" , (XtPointer) justifySel },
{"spacingSel" , (XtPointer) spacingSel },
{"showSel" , (XtPointer) showSel },
{"sizeSel" , (XtPointer) sizeSel },
{"issuesSel" , (XtPointer) issuesSel },
{"compSel" , (XtPointer) compSel },
{"magSel" , (XtPointer) magSel },
{"scrollProc" , (XtPointer) scrollProc },
};
/*
** Font sizes supported in text application
*/
float FontSizes[NUM_SIZES] = { 10, 11, 12 };
static XrmOptionDescRec CommandLineOptions[] = {
{ "-trace", ".trace", XrmoptionNoArg, (caddr_t)"True",},
};
static XtResource Resources[] = {
{ "trace",
"Trace",
XtRBoolean,
sizeof (Boolean),
XtOffset (AppDataTypePtr, trace),
XtRImmediate,
(caddr_t) False
}
};
static Cursor zoomCursor; /* cursor for zooming window */
/***************************************************************
**
** FUNCTION: main
**
** DESCRIPTION: OS transfer point. The main routine does all
** the one-time setup and then calls dispatching loop
**
** PARAMETERS: argc command line argument count
** argv array of pointers to command line args.
**
** RETURN: None.
**
***************************************************************/
main (argc, argv)
unsigned int argc;
char *argv[];
{
XtAppContext appContext;
Widget toplevel;
Widget mainWindow;
Widget optionShell;
/*
** Initialize MRM before initializing the X Toolkit.
*/
MrmInitialize ();
/*
** Initialize the X Toolkit. We get back a top level shell widget.
*/
toplevel = XtAppInitialize (
&appContext, "Text", CommandLineOptions,
XtNumber(CommandLineOptions), &argc, argv,
(String) NULL, (ArgList) NULL, 0);
XtGetApplicationResources (
toplevel, (XtPointer) &AppData, Resources,
XtNumber(Resources), (ArgList) NULL, 0
);
if (!XDPSExtensionPresent(XtDisplay(toplevel)))
{
fprintf (stderr, "%s: DPS extension not in server\n", argv[0]);
exit (1);
}
/*
** Open the UID files (the output of the UIL compiler)
*/
if (MrmOpenHierarchy (XtNumber(DbFilenameVec), DbFilenameVec, NULL,
&SMrmHierarchy) != MrmSUCCESS) {
fprintf (stderr, "Can't open heirarchy\n");
exit (1);
}
/*
** Register the items MRM needs to bind for us.
*/
MrmRegisterNames (RegList, XtNumber(RegList));
/*
** Get the main window for the application.
*/
if (MrmFetchWidget (SMrmHierarchy, "MainWindow", toplevel,
&mainWindow, &DummyClass) != MrmSUCCESS)
{
fprintf (stderr, "Can't fetch main window\n");
exit (1);
}
/*
** Create a shell for the option box
*/
optionShell = XtVaCreatePopupShell("TextOptions",
xmDialogShellWidgetClass,
toplevel,
XmNallowShellResize, True,
XmNmappedWhenManaged, False,
NULL);
/*
** Get the option box widget
*/
if (MrmFetchWidget(SMrmHierarchy, "OptionBox", optionShell,
&AppData.optionBox, &DummyClass) != MrmSUCCESS)
{
fprintf(stderr, "Can't fetch option window\n");
exit(1);
}
/*
** Manage the main window and option box and realize everything.
** The interface comes up on the display now.
*/
XtManageChild(mainWindow);
XtManageChild(AppData.optionBox);
XtVaSetValues(
optionShell,
XmNmwmFunctions,
MWM_FUNC_ALL | MWM_FUNC_RESIZE | MWM_FUNC_MAXIMIZE | MWM_FUNC_CLOSE,
XmNmwmDecorations,
MWM_DECOR_ALL | MWM_DECOR_MAXIMIZE | MWM_DECOR_RESIZEH,
NULL
);
XtRealizeWidget(toplevel);
/*
** Perform onetime initialization of application data structures.
*/
initApplication();
/*
** Do all the post-realization DPSX processing here
*/
initDPSContext();
/*
** Draw the initial page into the buffer
*/
drawSelf();
/*
** Sit around forever waiting to process X-events.
** From here on, we only execute our callback routines.
*/
while (1) {
XEvent event;
XtAppNextEvent(appContext, &event);
if (!XDPSDispatchEvent(&event)) (void) XtDispatchEvent(&event);
}
}
static int pkdCmp (a, b)
AFMPairKernData *a, *b;
{
int rc = strcmp ( a->name1, b->name1 );
return rc ? rc : strcmp ( a->name2, b->name2 );
}
static int cmiCmp (a, b)
AFMCharMetricInfo *a, *b;
{
return strcmp ( a->name, b->name );
}
static AFMFontInfo *parseAFMFile()
{
AFMFontInfo *fi;
FILE *AFMfp;
char **afmNames, **afmFiles;
int numFiles;
SetPSResourcePolicy(PSSaveReturnValues, 0, NULL);
numFiles = ListPSResourceFiles(NULL, ".", PSResFontAFM, "Times-Roman",
&afmNames, &afmFiles);
if (numFiles == 0) {
fprintf(stderr, "Can't locate Times-Roman AFM file\n");
exit(1);
}
AFMfp = fopen (afmFiles[0], "r");
if (AFMfp == NULL) {
fprintf(stderr, "Can't open Times-Roman AFM file\n");
exit(1);
}
AFMParseFile (AFMfp, &fi, AFM_GMP);
fclose (AFMfp);
free(afmFiles);
free(afmNames);
FreePSResourceStorage(1);
return fi;
}
static void initFontMetrics()
{
int s, n, c, code, kernIndex, numOfChars, numOfPairs;
AFMCharMetricInfo *cmi;
AFMPairKernData *pkd;
AFMFontInfo *fi;
int maxChar;
/*
** Parse the font metrics file
*/
fi = parseAFMFile();
/*
** Re-index the font metrics data structure so it is easier to find
** character widths and kern pairs
*/
numOfChars = fi->numOfChars;
numOfPairs = fi->numOfPairs;
AppData.metrics.numOfChars = numOfChars;
AppData.metrics.numOfPairs = numOfPairs;
/*
** Quicksort the pair kern data and the char metrics data for easy access
** The cmi array is sorted by character name (a string)
** The pkd array is sorted primarily on name1, and secondarily on name2
*/
qsort (fi->cmi, numOfChars, sizeof(AFMCharMetricInfo), cmiCmp);
qsort (fi->pkd, numOfPairs, sizeof(AFMPairKernData), pkdCmp);
maxChar = 0;
for (c = 0; c < numOfChars; c++) maxChar = MAX(fi->cmi[c].code, maxChar);
AppData.metrics.maxChar = maxChar;
/*
** Allocate space for the widths and kern-pairs
*/
AppData.metrics.widths = (float *) XtCalloc (maxChar+1, sizeof (float));
AppData.metrics.kernIndex = (int *) XtCalloc (maxChar+1, sizeof (int));
AppData.metrics.numKernPairs = (int *) XtCalloc (maxChar+1, sizeof (int));
AppData.metrics.kernPairs =
(KernPair *) XtCalloc (numOfPairs, sizeof (KernPair));
/*
** Step through the array of characters
*/
for (c = kernIndex = 0, pkd = fi->pkd; c < numOfChars; c++) {
/*
** Get the character metrics for this character
*/
cmi = &(fi->cmi[c]);
/*
** Get its ascii code
*/
code = cmi->code;
/*
** This application does not deal with unencoded characters
*/
if (code == -1) continue;
/*
** Store its width in the widths array indexed by ascii value
*/
AppData.metrics.widths[code] = (fi->cmi[c].wx) / 1000.0;
/*
** Assume its kern pairs start at the next kern pair index
*/
AppData.metrics.kernIndex[code] = kernIndex;
/*
** Step down the kern pair array sent back from the parser
** until the first character no longer matches the current
** character. (note the characters are stored as strings)
** (note that the loop may have 0 iterations)
*/
for (n = 0, s = 0;
kernIndex < numOfPairs && !strcmp (cmi->name, pkd->name1);
pkd++, kernIndex++, n++) {
/*
** Step down the character metrics array looking for the
** second character in the kern pair for its ascii code
*/
for (; s < numOfChars; s++) {
if (!strcmp (fi->cmi[s].name, pkd->name2)) {
/*
** Found it in the character metrics, put the ascii
** code into the kern pair array, along with the
** amount to kern by
*/
AppData.metrics.kernPairs[kernIndex].code
= fi->cmi[s].code;
AppData.metrics.kernPairs[kernIndex].dx
= pkd->xamt / 1000.0;
break;
}
}
} /* end for */
/*
** The number of iterations in the loop on n is the number of
** kern pairs for this character. (could be 0)
*/
AppData.metrics.numKernPairs[code] = n;
} /* end for */
}
/***************************************************************
**
** FUNCTION: initApplication
**
** DESCRIPTION: One-time initialization of application data
** structures.
**
** PARAMETERS: None.
**
** RETURN: None.
**
***************************************************************/
static void initApplication ()
{
Display *dpy = XtDisplay(AppData.drawingArea);
Window win = XtWindow(AppData.drawingArea);
XGCValues values;
Pixmap cursor, mask;
XColor fore, back;
/*
** Allocate space for the show struct used in show varients
*/
AllocShowStruct(&AppData.s);
/*
** Allocate space for the list of coordinates used in xshow
*/
AppData.charspace = (float*) XtCalloc (sizeof (float), MAX_XSHOW);
/*
** Initialize the initial button selections
*/
AppData.justify = False; /* No justification */
AppData.scrolling = False; /* Not in a scroll redraw */
AppData.zooming = False;
AppData.spacing = 0; /* No kerning or tracking */
AppData.show = show_xshow; /* use xshow */
AppData.fontNum = NUM_SIZES - 1; /* largest font */
AppData.fontSize = FontSizes[NUM_SIZES - 1];
AppData.issues = CACHE; /* Font cache on */
AppData.comp = 0; /* No comparisons */
AppData.scale = 1.0; /* 100 magnificaton */
AppData.magnify = 100; /* 100 magnificaton */
AppData.screen = True; /* Use screen widths */
initFontMetrics();
/*
** Create a GC for copying
*/
AppData.gc = XCreateGC(dpy, win, 0, &values);
/*
** Create a zoom cursor
*/
cursor = XCreateBitmapFromData(dpy, win, zoom_bits,
zoom_width, zoom_height);
mask = XCreateBitmapFromData(dpy, win, zoom_mask_bits,
zoom_mask_width, zoom_mask_height);
if (cursor != None && mask != None) {
fore.red = fore.green = fore.blue = 0;
back.red = back.green = back.blue = 65535;
fore.flags = back.flags = DoRed | DoGreen | DoBlue;
zoomCursor = XCreatePixmapCursor(dpy, cursor, mask, &fore, &back,
zoom_x_hot, zoom_y_hot);
XFreePixmap(dpy, cursor);
XFreePixmap(dpy, mask);
} else zoomCursor = None;
/*
** Create wait cursor
*/
AppData.waitCursor = XCreateFontCursor(dpy, XC_watch);
} /* end initApplication () */
/***************************************************************
**
** FUNCTION: resizeWindow
**
** DESCRIPTION: Callback routine to handle resize events.
**
** PARAMETERS: w callback widget ID
** clientData callback client data
** callData callback Motif data structure
**
** RETURN: None.
**
***************************************************************/
static void resizeWindow(w, clientData, callData)
Widget w;
XtPointer clientData, callData;
{
int depth;
Display *dpy = XtDisplay(w);
XPoint xpoint;
Point point;
if (!XtIsRealized(w)) return;
/*
** Convert upper left corner into PS units so we can keep it fixed
*/
xpoint.x = 0;
xpoint.y = 0;
convertToDPS(&xpoint, &point);
/*
** Get new size of drawing area
*/
XtVaGetValues(AppData.drawingArea, XtNheight, &AppData.drawingHeight,
XtNwidth, &AppData.drawingWidth,
XtNdepth, &depth, NULL);
/*
** Resizing automatically moved the y offset
*/
AppData.yOffset = AppData.drawingHeight;
/*
** Create new pixmap to match the drawable
*/
XFreePixmap(dpy, AppData.buf);
AppData.buf = XCreatePixmap(dpy, XtWindow(w), AppData.drawingWidth,
AppData.drawingHeight, depth);
/*
** Clear pixmaps
*/
XFillRectangle(dpy, AppData.buf, AppData.gc, 0, 0,
AppData.drawingWidth, AppData.drawingHeight);
/*
** Update the context to reflect the new pixmap
*/
XDPSSetContextDrawable(AppData.dpsCtxt, AppData.buf,
AppData.drawingHeight);
PSscale(AppData.scale, AppData.scale);
/*
** Move the drawing area so the top left corner
** of the image remains located at the top left corner
*/
positionDrawingArea(point.x, point.y, 0, 0);
drawSelfAndUpdate();
} /* end resizeWindow() */
/***************************************************************
**
** FUNCTION: refreshWindow
**
** DESCRIPTION: Callback routine to handle regular expose events
** to the main window. Causes the window to be
** refreshed.
**
** PARAMETERS: w callback widget ID
** clientData callback client data
** callData callback Motif data structure
**
** RETURN: None.
**
***************************************************************/
static void refreshWindow(w, clientData, callData)
Widget w;
XtPointer clientData, callData;
{
XmDrawingAreaCallbackStruct *callback =
(XmDrawingAreaCallbackStruct *) callData;
XExposeEvent *e = &callback->event->xexpose;
/*
** Only update exposed areas
*/
XCopyArea(XtDisplay(w), AppData.buf, XtWindow(w), AppData.gc,
e->x, e->y, e->width, e->height, e->x, e->y);
} /* end refreshWindow() */
/***************************************************************
**
** FUNCTION: createProc
**
** DESCRIPTION: Callback routine for widget creation.
** Saves the widget id in an array.
**
** PARAMETERS: w callback widget ID
** clientData callback client data
** callData callback Motif data structure
**
** RETURN: None.
**
***************************************************************/
static void createProc(w, clientData, callData)
Widget w;
XtPointer clientData, callData;
{
int widgetNum = *(int *) clientData;
switch (widgetNum) {
case cMainDrawArea:
/*
** Save widget ID in application data structure
*/
AppData.drawingArea = w;
XtAddEventHandler(w, ButtonPressMask, False, mouseDown, NULL);
XtAddRawEventHandler(w, 0, True, graphicExpose, NULL);
break;
case cTraceToggle:
if (AppData.trace) XtVaSetValues(w, XmNset, True, NULL);
break;
case cTimingText0: AppData.time = w; break;
case cTimingText1: AppData.numChars = w; break;
case cTimingText2: AppData.kernPairs = w; break;
case cStatusText0: AppData.cacheStatus[0] = w; break;
case cStatusText1: AppData.cacheStatus[1] = w; break;
case cStatusText2: AppData.cacheStatus[2] = w; break;
case cStatusText3: AppData.cacheStatus[3] = w; break;
case cStatusText4: AppData.cacheStatus[4] = w; break;
case cStatusText5: AppData.cacheStatus[5] = w; break;
case cStatusText6: AppData.cacheStatus[6] = w; break;
case cHsb: AppData.hScroll = w; break;
case cVsb: AppData.vScroll = w; break;
} /* end switch */
} /* end createProc () */
/***************************************************************
**
** FUNCTION: quitApp
**
** DESCRIPTION: Callback routine for "quit" command menu
** selection. Exits from the application.
**
** PARAMETERS: w callback widget ID
** clientData callback client data
** callData callback Motif data structure
**
** RETURN: Returns to OS.
**
***************************************************************/
static void quitApp (w, clientData, callData)
Widget w;
XtPointer clientData, callData;
{
XtDestroyApplicationContext(XtWidgetToApplicationContext(w));
exit(0);
} /* end quitApp () */
/***************************************************************
**
** FUNCTION: traceProc
**
** DESCRIPTION: Callback routine for widget creation.
** Saves the widget id in an array.
**
** PARAMETERS: w callback widget ID
** clientData callback client data
** callData callback Motif data structure
**
** RETURN: None.
**
***************************************************************/
static void traceProc(w, clientData, callData)
Widget w;
XtPointer clientData, callData;
{
XmToggleButtonCallbackStruct *toggle =
(XmToggleButtonCallbackStruct *) callData;
XDPSChainTextContext (AppData.dpsCtxt, toggle->set);
} /* end traceProc() */
/***************************************************************
**
** FUNCTION: reshowProc
**
** DESCRIPTION: Callback routine for redraw button pushed.
** Redraws the text and displays the time.
**
** PARAMETERS: w callback widget ID
** clientData callback client data
** callData callback Motif data structure
**
** RETURN: None.
**
***************************************************************/
static void reshowProc (w, clientData, callData)
Widget w;
XtPointer clientData, callData;
{
/*
** Redraw the page and time fields
*/
drawSelfAndUpdate();
} /* end reshowProc () */
/***************************************************************
**
** FUNCTION: justifySel
**
** DESCRIPTION: Callback routine for activating justify buttons
** Sets the justify button number
**
** PARAMETERS: w callback widget ID
** clientData callback client data
** callData callback Motif data structure
**
** RETURN: None.
**
***************************************************************/
static void justifySel(w, clientData, callData)
Widget w;
XtPointer clientData, callData;
{
int num = *(int *) clientData;
XmToggleButtonCallbackStruct *toggle =
(XmToggleButtonCallbackStruct *) callData;
/*
** Change the selected radio button if toggle state is set
*/
if (toggle->set && AppData.justify != (num != 0)) {
AppData.justify = (num != 0);
reshowProc(w, NULL, NULL);
}
} /* end justifySel () */
/***************************************************************
**
** FUNCTION: spacingSel
**
** DESCRIPTION: Callback routine for activating spacing buttons
** Sets the spacing bits
**
** PARAMETERS: w callback widget ID
** clientData callback client data
** callData callback Motif data structure
**
** RETURN: None.
**
***************************************************************/
static void spacingSel(w, clientData, callData)
Widget w;
XtPointer clientData, callData;
{
int num = *(int *) clientData;
XmToggleButtonCallbackStruct *toggle =
(XmToggleButtonCallbackStruct *) callData;
/*
** Change the state of the toggle button
*/
if ( toggle->set ) AppData.spacing |= (1 << num);
else AppData.spacing &= ~(1 << num);
reshowProc(w, NULL, NULL);
} /* end spacingSel () */
/***************************************************************
**
** FUNCTION: showSel
**
** DESCRIPTION: Callback routine for activating show buttons
** Sets the show manner
**
** PARAMETERS: w callback widget ID
** clientData callback client data
** callData callback Motif data structure
**
** RETURN: None.
**
***************************************************************/
static void showSel(w, clientData, callData)
Widget w;
XtPointer clientData, callData;
{
int num = *(int *) clientData;
XmToggleButtonCallbackStruct *toggle =
(XmToggleButtonCallbackStruct *) callData;
/*
** Change the selected radio button if toggle state is set
*/
if (toggle->set && AppData.show != num) {
AppData.show = num;
reshowProc(w, NULL, NULL);
}
} /* end showSel () */
/***************************************************************
**
** FUNCTION: sizeSel
**
** DESCRIPTION: Callback routine for picking a new font size
** Sets the font size
**
** PARAMETERS: w callback widget ID
** clientData callback client data
** callData callback Motif data structure
**
** RETURN: None.
**
***************************************************************/
static void sizeSel(w, clientData, callData)
Widget w;
XtPointer clientData, callData;
{
int num = *(int *) clientData;
/*
** Set the new font size
*/
if (AppData.fontSize != FontSizes[num]) {
AppData.fontNum = num;
AppData.fontSize = FontSizes[num];
reshowProc(w, NULL, NULL);
}
} /* end sizeSel () */
/***************************************************************
**
** FUNCTION: issuesSel
**
** DESCRIPTION: Callback routine for activating issues buttons
** Sets the font issues
**
** PARAMETERS: w callback widget ID
** clientData callback client data
** callData callback Motif data structure
**
** RETURN: None.
**
***************************************************************/
static void issuesSel(w, clientData, callData)
Widget w;
XtPointer clientData, callData;
{
int num = *(int *) clientData;
XmToggleButtonCallbackStruct *toggle =
(XmToggleButtonCallbackStruct *) callData;
/*
** Change the state of the toggle button
*/
if (toggle->set) AppData.issues |= (1 << num);
else AppData.issues &= ~(1 << num);
/*
** Set the cache low if it is not in use
*/
if (num == 0) {
if (toggle->set) {
PSWSetcacheparams(AppData.size, AppData.lower, AppData.upper);
} else PSWSetcacheparams(0, 0, 0);
/*
** Set flag indicating use of outline widths or bitmap widths
*/
} else AppData.screen = !toggle->set;
reshowProc(w, NULL, NULL);
} /* end issuesSel () */
/***************************************************************
**
** FUNCTION: compSel
**
** DESCRIPTION: Callback routine for activating comparisons buttons
** Sets the comparison bits
**
** PARAMETERS: w callback widget ID
** clientData callback client data
** callData callback Motif data structure
**
** RETURN: None.
**
***************************************************************/
static void compSel(w, clientData, callData)
Widget w;
XtPointer clientData, callData;
{
int num = *(int *) clientData;
XmToggleButtonCallbackStruct *toggle =
(XmToggleButtonCallbackStruct *) callData;
/*
** Change the state of the toggle push button
*/
AppData.comp = (toggle->set) ? (num + 1) : 0;
reshowProc(w, NULL, NULL);
} /* end compSel () */
/***************************************************************
**
** FUNCTION: magSel
**
** DESCRIPTION: Callback routine for activating magnify buttons
** Sets the magnification, makes the cursor the zoom
** cursor, and sets the zooming flag for the later click
**
** PARAMETERS: w callback widget ID
** clientData callback client data
** callData callback Motif data structure
**
** RETURN: None.
**
***************************************************************/
static void magSel(w, clientData, callData)
Widget w;
XtPointer clientData, callData;
{
int num = *(int *) clientData;
XmToggleButtonCallbackStruct *toggle =
(XmToggleButtonCallbackStruct *) callData;
/*
** Change the selected radio button if toggle state is set
*/
if (toggle->set && AppData.magnify != num) {
AppData.zooming = True;
AppData.magnify = num;
if (zoomCursor != None) {
XDefineCursor(XtDisplay(AppData.drawingArea),
XtWindow(AppData.drawingArea), zoomCursor);
}
}
} /* end magSel () */
/***************************************************************
**
** FUNCTION: mouseDown
**
** DESCRIPTION: This function acts as the event handler for the
** ButtonDown event. If the magnification is being
** changed (zooming), then scale and position the
** drawing view.
**
** PARAMETERS: w window widget
** clientData clientdata
** event event information
** goOn continue to dispatch
**
** RETURN: None
**
***************************************************************/
static void mouseDown(w, clientData, event, goOn)
Widget w;
XtPointer clientData;
XEvent *event;
Boolean *goOn;
{
XPoint xpoint;
Point point;
XButtonPressedEvent *bp = (XButtonPressedEvent *) event;
if (event->xany.window != XtWindow(AppData.drawingArea)) return;
xpoint.x = bp->x;
xpoint.y = bp->y;
/*
** If zooming, rescale so clicked-on point remains fixed
*/
if (AppData.zooming) {
/*
** Convert point to PS units and scale
*/
convertToDPS(&xpoint, &point);
scaleDrawingArea(point.x, point.y, xpoint.x, xpoint.y);
drawSelfAndUpdate();
AppData.zooming = False;
if (zoomCursor != None) {
XUndefineCursor(XtDisplay(w), XtWindow(w));
}
}
} /* end mouseDown() */
static XmString blank = NULL;
/***************************************************************
**
** FUNCTION: eraseFields
**
** DESCRIPTION: Routine to clear the XmText widgets for timing and status
**
** PARAMETERS: None
**
** RETURN: None.
**
***************************************************************/
void eraseFields ()
{
int i;
if (blank == NULL) blank = XmStringCreateSimple("");
AppData.timingInfo.chars = 0;
AppData.timingInfo.kerns = 0;
AppData.timingInfo.time = 0;
XtVaSetValues(AppData.time, XmNlabelString, blank, NULL);
XtVaSetValues(AppData.numChars, XmNlabelString, blank, NULL);
XtVaSetValues(AppData.kernPairs, XmNlabelString, blank, NULL);
for (i = 0; i < 7; i++) {
XtVaSetValues(AppData.cacheStatus[i], XmNlabelString, blank, NULL);
}
} /* end eraseFields() */
/***************************************************************
**
** FUNCTION: displayFields
**
** DESCRIPTION: Routine to set the XmText widgets for timing and status
**
** PARAMETERS:
**
** RETURN: None.
**
***************************************************************/
void displayFields ()
{
int i, cvalues[7];
char field[7];
Timing *t = &AppData.timingInfo;
if (t->time != 0) {
sprintf (field, "%d", t->time);
XtVaSetValues(AppData.time,
XmNlabelString, XmStringCreateSimple(field), NULL);
sprintf (field, "%d", t->chars);
XtVaSetValues(AppData.numChars,
XmNlabelString, XmStringCreateSimple(field), NULL);
sprintf (field, "%d", t->kerns);
XtVaSetValues(AppData.kernPairs,
XmNlabelString, XmStringCreateSimple(field), NULL);
}
/*
** Get the cache status from PS
*/
PSWCachestatus(cvalues);
/*
** Fill the 7 status fields
*/
for (i = 0; i < 7; i++) {
sprintf (field, "%d", cvalues[i]);
XtVaSetValues(AppData.cacheStatus[i],
XmNlabelString, XmStringCreateSimple(field), NULL);
}
} /* end displayFields() */
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.