This is ClockMain.c in view mode; [Download] [Up]
/* * $RCSfile: ClockMain.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 "Clock.h" /*************************************************************** ** ** DATA DECLARATIONS ** ***************************************************************/ /* ** Global pointers to the application name and data block */ AppDataType AppData; /* ** Global program state variables */ /* ** Global resource management data */ static MrmHierarchy SMrmHierarchy; /* MRM database hierarchy ID */ static MrmType *DummyClass; /* and class variable. */ static char *DbFilenameVec [] = /* Mrm.heirarchy file list. */ { "Clock.uid" }; static XrmOptionDescRec CommandLineOptions[] = { { "-trace", ".trace", XrmoptionNoArg, "true" }, { "-pixmap", ".pixmapBackground", XrmoptionNoArg, "true", }, { "-double", ".doubleBuffering", XrmoptionNoArg, "true", }, { "-gstates", ".graphicStates", XrmoptionNoArg, "true", }, { "-paths", ".serverPaths", XrmoptionNoArg, "true", }, { "-alarm", ".alarmOn", XrmoptionNoArg, "true", } }; XtResource ApplicationResources[] = { { /* PostScript Text Context Trace Resource */ "trace", "Trace", XtRBoolean, sizeof(Boolean), XtOffset (AppDataTypePtr, trace), XtRImmediate, (caddr_t) False },{ /* Clock Alarm Resource */ "alarm", "Alarm", XtRBoolean, sizeof(Boolean), XtOffset (AppDataTypePtr, alarmOn), XtRImmediate, (caddr_t) False },{ /* Graphic States Resource */ "graphicStates", "GraphicStates", XtRBoolean, sizeof (Boolean), XtOffset (AppDataTypePtr, graphicStates), XtRImmediate, (caddr_t) False },{ /* User Paths in Server Resource */ "serverPaths", "ServerPaths", XtRBoolean, sizeof (Boolean), XtOffset (AppDataTypePtr, serverPaths), XtRImmediate, (caddr_t) False },{ /* Face Pixmap Background Resource */ "pixmapBackground", "PixmapBackground", XtRBoolean, sizeof (Boolean), XtOffset (AppDataTypePtr, pixmapBackground), XtRImmediate, (caddr_t) False },{ /* Double Buffering Resource */ "doubleBuffering", "DoubleBuffering", XtRBoolean, sizeof (Boolean), XtOffset (AppDataTypePtr, doubleBuffering), XtRImmediate, (caddr_t) False } }; static void resizeWindow(), createProc(), quitApp(), traceProc(), optionSel(), timingProc(), alarmProc(), dismissTimingBox(), mapHandler(), refreshWindow(), mouseDown(); /* 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 }, {"optionSel" , (XtPointer) optionSel }, {"timingProc" , (XtPointer) timingProc }, {"alarmProc" , (XtPointer) alarmProc }, {"dismissTimingBox", (XtPointer) dismissTimingBox}, }; static int ringingAlarmBell = 0; /* alarm ringing countdown */ /*************************************************************** ** ** FUNCTION: main ** ** DESCRIPTION: OS transfer point. The main routine does all ** the one-time setup and then calls the dispatch loop ** ** PARAMETERS: argc command line argument count ** argv array of pointers to command line args. ** ** RETURN: None. ** ***************************************************************/ unsigned int main (argc, argv) uint argc; char *argv []; { Widget topLevel, mainWindow, timingShell, timingWindow; /* ** Initialize MRM before initializing the X Toolkit. */ MrmInitialize (); topLevel = XtVaAppInitialize (&AppData.appContext, "Clock", CommandLineOptions, XtNumber(CommandLineOptions), &argc, argv, NULL, XmNallowShellResize, True, NULL); XtAddEventHandler (topLevel, StructureNotifyMask, FALSE, mapHandler, NULL); XtVaGetApplicationResources (topLevel, &AppData, ApplicationResources, XtNumber(ApplicationResources), NULL); /* ** 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); } /* ** Get the timing box widget */ timingShell = XtVaCreatePopupShell ("ClockTiming", xmDialogShellWidgetClass, topLevel, XmNallowShellResize, True, XmNmappedWhenManaged, False, NULL); if (MrmFetchWidget (SMrmHierarchy, "TimingBox", timingShell, &AppData.timingBox, &DummyClass) != MrmSUCCESS) { fprintf (stderr, "Can't fetch timing window\n"); exit (1); } /* ** Manage and realize the clock (main window) */ XtManageChild (mainWindow); XtRealizeWidget (topLevel); /* ** Do all the post-realization DPSX processing here */ initDPSContext (); if (AppData.graphicStates) setGStates(); AppData.clockPixmap = AppData.facePixmap = None; /* ** 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: resizeWindow ** ** DESCRIPTION: Callback routine to handle resize events. ** The new size is obtained and the face is drawn. ** ** 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; { Dimension width, height; /* ** The window cannot be sized if it is not yet realized */ if (!XtIsRealized (w)) return; XtVaGetValues (w, XtNheight, &height, XtNwidth, &width, NULL); handleWindowResize(w, width, height); drawClockTime(); AppData.redrewAlready = True; } /* end resizeWindow () */ /*************************************************************** ** ** FUNCTION: refreshWindow ** ** DESCRIPTION: Callback routine to handle expose events. ** ** ** 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; { 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; } if (AppData.redrewAlready) return; drawClockTime(); } /* 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; { Widget button; int widgetNum = *(int *) clientData; /* ** Save widget IDs */ switch (widgetNum) { case cMainDrawArea: AppData.widget = w; /* ** Add event handler for the mouse button down event */ XtAddEventHandler (w, ButtonPressMask, FALSE, mouseDown, NULL); break; case cTimingText: AppData.timingText = w; break; case cTimingButton: AppData.timingButton = w; break; case cTraceToggle: AppData.traceToggle = w; XmToggleButtonSetState (w, AppData.trace, False); break; /* ** If option turned on by command line, set button */ case cOptionButton0: XmToggleButtonSetState (w, AppData.graphicStates, False); break; case cOptionButton1: XmToggleButtonSetState (w, AppData.serverPaths, False); break; case cOptionButton2: XmToggleButtonSetState (w, AppData.doubleBuffering, False); break; case cOptionButton3: XmToggleButtonSetState (w, AppData.pixmapBackground, False); break; default: 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; XtPointer callData; { XtDestroyApplicationContext(XtWidgetToApplicationContext(w)); exit (0); } /* end quitApp () */ /*************************************************************** ** ** FUNCTION: traceProc ** ** DESCRIPTION: Callback routine for the trace toggle button. ** ** 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; /* ** Chain text context for trace option if trace is on */ XDPSChainTextContext (AppData.dpsCtxt, toggle->set); } /* end traceProc () */ /*************************************************************** ** ** FUNCTION: setTimingValue ** ** DESCRIPTION: Routine to set timing value in options box. ** ** PARAMETERS: iTime timing value ** ** RETURN: None. ** ***************************************************************/ void setTimingValue (iTime) int iTime; { char cTime [15]; XEvent event; if (iTime == 0) strcpy (cTime, " - "); else sprintf (cTime, "%d", iTime); XtVaSetValues (AppData.timingText, XmNlabelString, XmStringCreateSimple(cTime), NULL); } /* end setTimingValue () */ /*************************************************************** ** ** FUNCTION: timingProc ** ** DESCRIPTION: Callback routine for the timing window push button. ** ** PARAMETERS: w callback widget ID ** clientData callback client data ** callData callback Motif data structure ** ** RETURN: None. ** ***************************************************************/ static void timingProc (w, clientData, callData) Widget w; XtPointer clientData, callData; { XmToggleButtonCallbackStruct *toggle = (XmToggleButtonCallbackStruct *) callData; int total, i; /* ** If timing window toggle is on, map the window to make it visible ** and update the timing value in the text widget */ if (toggle->set) { XtManageChild (AppData.timingBox); /* ** Update timing box with average of last N timings */ if (AppData.numIterations) { total = 0; for (i = 0; i < AppData.numIterations; i++) { total += AppData.lastTimes[i]; } setTimingValue (total / AppData.numIterations); } else setTimingValue (0); /* ** If timing window toggle is off, unmap the window to make it invisible */ } else XtUnmanageChild (AppData.timingBox); } /* end timingProc () */ /*************************************************************** ** ** FUNCTION: alarmProc ** ** DESCRIPTION: Callback routine for the alarm on push button. ** ** PARAMETERS: w callback widget ID ** clientData callback client data ** callData callback Motif data structure ** ** RETURN: None. ** ***************************************************************/ static void alarmProc (w, clientData, callData) Widget w; XtPointer clientData, callData; { XmToggleButtonCallbackStruct *toggle = (XmToggleButtonCallbackStruct *) callData; /* ** Mark the alarm on/off state */ AppData.alarmOn = toggle->set; /* ** Reset the alarm bell count which will turn off a ringing alarm */ ringingAlarmBell = 0; } /* end alarmProc () */ /*************************************************************** ** ** FUNCTION: optionSel ** ** DESCRIPTION: Callback routine for the option selection buttons. ** ** PARAMETERS: w callback widget ID ** clientData callback client data ** callData callback Motif data structure ** ** RETURN: None. ** ***************************************************************/ static void optionSel (w, clientData, callData) Widget w; XtPointer clientData, callData; { XmToggleButtonCallbackStruct *toggle = (XmToggleButtonCallbackStruct *) callData; int num = *(int *) clientData; switch (num) { case 0: /* graphic states */ AppData.graphicStates = toggle->set; setGStates(); break; case 1: /* user paths in server */ AppData.serverPaths = toggle->set; break; case 2: /* double buffering */ AppData.doubleBuffering = toggle->set; setBufferRendering(); break; case 3: /* Pixmap background */ AppData.pixmapBackground = toggle->set; break; } /* ** Reset the number of iterations and total time for drawing ** the clock time in the current mode */ AppData.numIterations = 0; AppData.redrewAlready = False; /* ** Reset the timing value in the display */ setTimingValue (0); } /* end optionSel () */ /*************************************************************** ** ** FUNCTION: clockTimeout ** ** DESCRIPTION: Callback routine for timer events. Causes the ** clock to be redrawn. Check if the clock needs ** to ring the alarm bell and rings it. ** ** PARAMETERS: clientData client data ** id timer id ** ** RETURN: None. ** ***************************************************************/ static void clockTimeout (clientData, id) XtPointer clientData; XtIntervalId id; { register int i; /* ** Check to see if the draw area window is mapped (visible) */ if (! AppData.mapped) return; /* ** If just redrew because of expose event, don't redraw this time */ AppData.redrewAlready = False; drawClockTime (); /* ** Check to see if alarm is turned on */ if (AppData.alarmOn) { /* ** If the alarm ringing counter is set, ring the bell and ** decrement the counter */ if (ringingAlarmBell) { for (i = 0; i < 4; i++) XBell (XtDisplay(AppData.widget), ALARM_LEVEL); ringingAlarmBell --; /* ** Otherwise, if the hour hand has moved into the alarm hand ** interval, start the alarm ringing on the next one second update */ } else if (checkAlarm ()) ringingAlarmBell = ALARM_REPEATS; } /* ** Reset the timer for next one second update */ (void) XtAppAddTimeOut (AppData.appContext, (AppData.milliSecs > 900) ? 1000 : 1000 - AppData.milliSecs, clockTimeout, (XtPointer) NULL); } /* end clockTimeout () */ /*************************************************************** ** ** FUNCTION: mouseDown ** ** DESCRIPTION: This function acts as the event handler for the ** ButtonDown event. If the alarm is ringing it is ** turned off. The mouse point is checked to see ** if it hits the alarm hand and if so the alarm ** hand is moved appropriately. ** ** PARAMETERS: w window widget ** clientData client data ** event event information ** goOn whether to continue processing ** ** RETURN: None ** ***************************************************************/ static void mouseDown (w, clientData, event, goOn) Widget w; XtPointer clientData; XEvent *event; Boolean *goOn; { Window window; uint button; XButtonEvent *bp; ringingAlarmBell = 0; bp = &(event->xbutton); if (isHit (bp->x, bp->y)) setAlarm (); } /* end mouseDown() */ /*************************************************************** ** ** FUNCTION: mapHandler ** ** DESCRIPTION: Call back routine for map notify and unmap ** notify events. A unmap notify indicates the ** window has been iconified at which time clock ** drawing is turned off. The map notify indicates ** the window has been made visible and clock ** drawing is turned back on. This results in ** a processing time savings since the clock is ** normally updated once a second. ** ** PARAMETERS: w callback widget ID ** clientData callback client data ** event event information ** goOn whether to continue processing ** ** RETURN: None ** ***************************************************************/ static void mapHandler (w, clientData, event, goOn) Widget w; XtPointer clientData; XEvent *event; Boolean *goOn; { switch (event -> type) { case MapNotify: AppData.mapped = TRUE; clockTimeout (NULL, 0); break; case UnmapNotify: AppData.mapped = FALSE; break; } } /* end mapHandler () */ /*************************************************************** ** ** FUNCTION: dismissTimingBox ** ** DESCRIPTION: callback routine to dismiss the timing box. ** ** PARAMETERS: w callback widget ID ** clientData callback client data ** callData callback Motif data structure ** ** RETURN: N/A ** ***************************************************************/ static void dismissTimingBox (w, clientData, callData) Widget w; XtPointer clientData, callData; { XtUnmanageChild (AppData.timingBox); XmToggleButtonGadgetSetState(AppData.timingButton, False, False); }
These are the contents of the former NiCE NeXT User Group NeXTSTEP/OpenStep software archive, currently hosted by Netfuture.ch.