This is LineMain.c in view mode; [Download] [Up]
/* * $RCSfile: LineMain.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 "Line.h" /*************************************************************** ** ** DATA DECLARATIONS ** ***************************************************************/ /* ** Global pointers to the application name and 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. */ { "Line.uid" }; static void initApplication(), resetProc(), scaleValueChanged(), textValueChanged(), refreshWindow(), createProc(), quitApp(), traceProc(), drawProc(), colorWidthProc(), numLineSel(), markStartTime(); static long getElapsedTime(); static XtResource Resources[] = { { "trace", "Trace", XtRBoolean, sizeof(Boolean), XtOffset(AppDataTypePtr,trace), XtRImmediate, (XtPointer)False }, }; static XrmOptionDescRec CommandLineOptions[] = { { "-trace", /* PostScript trace command line option */ ".trace", /* resource identifier */ XrmoptionNoArg, (XtPointer)"true" }, }; static String FallbackResources[] = { NULL }; /* Names and addresses for Mrm to bind */ static MrmRegisterArg RegList [] = { {"resetProc", (caddr_t) resetProc }, {"textValueChanged", (caddr_t) textValueChanged }, {"refreshWindow", (caddr_t) refreshWindow }, {"createProc", (caddr_t) createProc }, {"quitApp", (caddr_t) quitApp }, {"traceProc", (caddr_t) traceProc }, {"colorWidthProc", (caddr_t) colorWidthProc }, {"drawProc", (caddr_t) drawProc }, {"numLineSel", (caddr_t) numLineSel }, {"scaleValueChanged", (caddr_t) scaleValueChanged } }; /*************************************************************** ** ** FUNCTION: main ** ** DESCRIPTION: OS transfer point. The main routine does all ** the one-time setup and then goes into its dispatching ** loop. ** ** PARAMETERS: argc command line argument count ** argv array of pointers to command line args. ** ** RETURN: None. ** ***************************************************************/ unsigned int main (argc, argv) unsigned int argc; char *argv []; { Widget toplevel; Widget mainWindow; /* ** Initialize MRM before initializing the X Toolkit. */ MrmInitialize (); /* ** Initialize the X Toolkit. We get back a top level shell widget. */ toplevel = XtAppInitialize ( &AppData.appContext, "Line", (XrmOptionDescList)CommandLineOptions, (Cardinal)XtNumber(CommandLineOptions), &argc, argv, (String *)FallbackResources, (ArgList)NULL, 0 ); XtGetApplicationResources ( toplevel, (XtPointer)&AppData, (XtResourceList)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); } /* ** Perform onetime initialization of application data structures. */ initApplication (); /* ** 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); } /* ** Manage the main window and option box and realize everything. ** The interface comes up on the display now. */ XtManageChild (mainWindow); XtVaSetValues( toplevel, 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); /* ** Do all the post-realization DPSX processing here */ initDPSContext (toplevel); /* ** Sit around forever waiting to process X-events. ** From here on, we only execute our callback routines. */ while (1) { XEvent event; XtAppNextEvent(AppData.appContext, &event); if (!XDPSDispatchEvent(&event)) (void) XtDispatchEvent(&event); } } /*************************************************************** ** ** FUNCTION: initApplication ** ** DESCRIPTION: One-time initialization of application data ** structures. ** ** PARAMETERS: None. ** ** RETURN: None. ** ***************************************************************/ static void initApplication () { /* ** initialize the random number generator seed */ srandom (time((long )NULL)); /* ** Initialize application state variables */ AppData.numberChanged = False; AppData.numberOfLines = 0; } /* end initApplication () */ /*************************************************************** ** ** FUNCTION: refreshWindow ** ** DESCRIPTION: Callback routine to handle expose events. ** 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; { int i = 7; register Display *dpy = XtDisplay(w); register Window window = XtWindow(w); XEvent event; /* ** Pseudo Exposure event compression for the Drawing Area Widget */ if (XPending(dpy) > 0) { XPeekEvent(dpy, &event); if (event.type == Expose && event.xany.window == XtWindow(w)) return; } drawProc (w, &i, NULL); } /* 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: AppData.drawingArea = w; break; case cTimingText0: AppData.timing0 = w; break; case cTimingText1: AppData.timing1 = w; break; case cTimingText2: AppData.timing2 = w; break; case cTimingText3: AppData.timing3 = w; break; case cTimingText4: AppData.timing4 = w; break; case cTimingText5: AppData.timing5 = w; break; case cScaleForm: AppData.scaleForm = w; break; case cTotalText: AppData.totalText = w; break; case cColorWidthButton: AppData.colorWidthButton = w; break; case cColorScale: AppData.colorScale = w; break; case cWidthScale: AppData.widthScale = w; break; case cTraceToggle: if (AppData.trace) XtVaSetValues (w, XmNset, True, NULL); 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 the trace toggle button. ** Enables or disables text trace. ** ** 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; /* ** Change the state of the toggle button */ XDPSChainTextContext (AppData.dpsCtxt, toggle->set); } /* end traceProc () */ /*************************************************************** ** ** FUNCTION: colorWidthProc ** ** DESCRIPTION: Callback routine for the color/width toggle button. ** Enables or disables sliders and fills color and ** width arrays. ** ** PARAMETERS: w callback widget ID ** clientData callback client data ** callData callback Motif data structure ** ** RETURN: None. ** ***************************************************************/ static void colorWidthProc (w, clientData, callData) Widget w; XtPointer clientData, callData; { XmToggleButtonCallbackStruct *toggle = (XmToggleButtonCallbackStruct *) callData; XtSetSensitive (AppData.scaleForm, (Boolean) toggle->set); makeColorWidth(AppData.numberOfLines); } /* end colorWidthProc () */ /*************************************************************** ** ** FUNCTION: scaleValueChanged ** ** DESCRIPTION: Callback routine when either the line width or color ** scale widget values have been changed. Fills color ** and width arrays. ** ** PARAMETERS: w callback widget ID ** clientData callback client data ** callData callback Motif data structure ** ** RETURN: None. ** ***************************************************************/ static void scaleValueChanged (w, clientData, callData) Widget w; XtPointer clientData, callData; { makeColorWidth(AppData.numberOfLines); } /*************************************************************** ** ** FUNCTION: setTimingValue ** ** DESCRIPTION: Routine to set timing value in options box. ** ** PARAMETERS: ** w label widget to change ** iTime timing value ** ** RETURN: None. ** ***************************************************************/ void setTimingValue (w, iTime) Widget w; long iTime; { char cTime [15]; XEvent event; if (iTime == 0) strcpy (cTime, " "); else sprintf (cTime, "%d", iTime); XtVaSetValues (w, XmNlabelString, XmStringCreateSimple(cTime), NULL); } /*************************************************************** ** ** FUNCTION: doDraw ** ** DESCRIPTION: Draw using a method and update timing window ** ** PARAMETERS: timing timing window to update ** proc drawingProcedure ** ** RETURN: None. ** ***************************************************************/ static void doDraw(timing, proc) Widget timing; void (*proc)(); { struct timeval start; setTimingValue (timing, 0); DPSWaitContext(AppData.dpsCtxt); markStartTime (&start); (*proc) (AppData.numberOfLines); DPSWaitContext(AppData.dpsCtxt); setTimingValue (timing, getElapsedTime(&start)); } /*************************************************************** ** ** FUNCTION: flushTiming ** ** DESCRIPTION: Forces an update of the timing windows by syncing and ** dispatching the resulting Expose events. Yuck ** ** PARAMETERS: dpy Display to flush ** ** RETURN: None. ** ***************************************************************/ static void flushTiming(dpy) Display *dpy; { XEvent event; XSync(dpy, False); while (XtAppPending(AppData.appContext)) { XtAppNextEvent(AppData.appContext, &event); if (!XDPSDispatchEvent(&event)) (void) XtDispatchEvent (&event); } XFlush(dpy); } /*************************************************************** ** ** FUNCTION: drawProc ** ** DESCRIPTION: Callback routine for redraw button pushed. ** Redraws the lines and displays the time. ** ** PARAMETERS: ** w callback widget ID ** clientData callback client data ** callData callback Motif data structure ** ** RETURN: None. ** ***************************************************************/ static void drawProc (w, clientData, callData) Widget w; XtPointer clientData; XtPointer callData; { int i; int buttonID = *(int *)clientData; if (AppData.numberOfLines == 0) { erasePage (); return; } if (AppData.numberChanged) { makeLines (AppData.numberOfLines); makeColorWidth (AppData.numberOfLines); AppData.numberChanged = False; } /* ** Redraw the lines */ switch (buttonID) { case 0: /* DPSPrintf */ doDraw(AppData.timing0, drawDPSPrintf); break; case 1: /* single operations */ doDraw(AppData.timing1, drawSingleOps); break; case 2: /* wraps */ doDraw(AppData.timing2, drawSimpleWraps); break; case 3: /* wraps w/binding */ doDraw(AppData.timing3, drawWrapsBind); break; case 4: /* wraps w/repeat */ doDraw(AppData.timing4, drawWrapsRepeat); break; case 5: /* wraps optimized */ doDraw(AppData.timing5, drawOptimizedStroke); break; case 6: /* draw all */ for (i = 0; i < 6; i++) { drawProc (w, &i, callData); flushTiming (XtDisplay(w)); } break; case 7: /* special for expose events */ drawOptimizedStroke(AppData.numberOfLines); break; default: erasePage(); break; } } /* end drawProc () */ /*************************************************************** ** ** FUNCTION: numLineSel ** ** DESCRIPTION: Callback routine for number of lines buttons. ** Sets the number in the text field; the callback ** routine for the field actually does the work. ** ** PARAMETERS: w callback widget ID ** clientData callback client data ** callData callback Motif data structure ** ** RETURN: None. ** ***************************************************************/ static void numLineSel (w, clientData, callData) Widget w; XtPointer clientData, callData; { static int numLinesArray[] = { 10, 100, 500, 1000, 0 }; int num = *((int *) clientData); char cCount [15]; int numLines; if ((num >= 0) && (num < 5)) numLines = numLinesArray[num]; else numLines = 0; sprintf (cCount, "%d", numLines); XmTextSetString (AppData.totalText, cCount); } /* end numLineSel () */ /*************************************************************** ** ** FUNCTION: markStartTime ** ** DESCRIPTION: routine to set the start time of the DPS drawing method ** ** PARAMETERS: ** startTime - pointer to struct timeval where current time is stored ** ** RETURN: None. ** ***************************************************************/ static void markStartTime (startTime) struct timeval *startTime; { struct timezone timeZone; gettimeofday (startTime, &timeZone); } /*************************************************************** ** ** FUNCTION: getElapsedTime ** ** DESCRIPTION: Returns milliseconds since startTime ** ** PARAMETERS: ** startTime - pointer to struct timeval where the start time is kept ** ** RETURN: ** long - the elapsed time since the start in milliseconds ** ***************************************************************/ static long getElapsedTime (startTime) struct timeval *startTime; { struct timezone timeZone; struct timeval finishTime; long elapsedSeconds, elapsedMicroseconds; gettimeofday (&finishTime, &timeZone); elapsedSeconds = finishTime.tv_sec - startTime->tv_sec; elapsedMicroseconds = finishTime.tv_usec - startTime->tv_usec; return ((long)(elapsedSeconds * 1000 + (elapsedMicroseconds/1000))); } /*************************************************************** ** ** FUNCTION: textValueChanged ** ** DESCRIPTION: Callback routine for any value change in the text widget ** where the total number of lines to draw is kept. ** ** PARAMETERS: ** w callback widget ID ** clientData callback client data ** callData callback Motif data structure ** ** RETURN: None. ** ***************************************************************/ static void textValueChanged (w, clientData, callData) Widget w; XtPointer clientData, callData; { char newText[256]; String string; int numLines; static Boolean recurring; /* ** Handle bad numeric input by converting string to an integer and ** printing the result in the text field. This will cause a recursive ** call, which we ignore. */ if (recurring) return; string = XmTextGetString (AppData.totalText); numLines = atoi (string); XtFree (string); if (numLines > MAXARRAY) numLines = MAXARRAY; if (numLines < 0) numLines = 0; recurring = True; (void) sprintf (newText, "%d", numLines); XmTextSetString (AppData.totalText, newText); XmTextSetInsertionPosition (AppData.totalText, strlen(newText)); recurring = False; AppData.numberChanged = True; AppData.numberOfLines = numLines; } /*************************************************************** ** ** FUNCTION: resetProc ** ** DESCRIPTION: Callback routine for the reset button activation ** ** PARAMETERS: ** w callback widget ID ** clientData callback client data ** callData callback Motif data structure ** ** RETURN: None. ** ***************************************************************/ static void resetProc (w, clientData, callData) Widget w; XtPointer clientData, callData; { XmTextSetString (AppData.totalText, "0"); XmScaleSetValue (AppData.colorScale, 0); XmScaleSetValue (AppData.widthScale, 200); XmToggleButtonSetState (AppData.colorWidthButton, True, True); setTimingValue(AppData.timing0, 0); setTimingValue(AppData.timing1, 0); setTimingValue(AppData.timing2, 0); setTimingValue(AppData.timing3, 0); setTimingValue(AppData.timing4, 0); erasePage(); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.