home *** CD-ROM | disk | FTP | other *** search
- /***********************************************************
- Copyright 1990 by Digital Equipment Corporation, Maynard, Massachusetts.
-
- All Rights Reserved
-
- Permission to use, copy, modify, and distribute these examples 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 Digital not be used in advertising or publicity
- pertaining to distribution of the software without specific, written
- prior permission.
-
- DIGITAL AND THE AUTHORS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS
- SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
- FITNESS, IN NO EVENT SHALL DIGITAL BE LIABLE FOR ANY SPECIAL, INDIRECT
- OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS
- OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
- OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE
- OR PERFORMANCE OF THIS SOFTWARE.
-
- ******************************************************************/
-
- #include <X11/Intrinsic.h>
- #include <X11/StringDefs.h>
- #include <X11/Shell.h>
- #include <X11/Xatom.h>
-
- #include "Box.h"
- #include "Pushbutton.h"
- #include "MenuItem.h"
- #include "Menu.h"
-
- /* Calculator variables */
- double currentInput = 0, total = 0;
- Boolean inputDecimal = FALSE, inputNumber = FALSE;
- double scale;
- double *numberToDisplay = &total;
-
- /* Pending operation */
- typedef enum {Start, Equal, Add, Sub, Mul, Div} operation;
- operation lastOp = Start;
-
- /* Interface variables */
- XtAppContext app;
- Widget display; /* Calculator's display */
- Widget menuShell;
- Boolean hasSelection = FALSE;
-
- void CreateInterface(), InputDigit(), InputDecimal(), Function(),
- Clear(), RefreshDisplay(), RepositionMenu(), Quit(), Select(),
- Paste(), PasteData(), LoseSelection();
-
- XtActionsRec actions[] = {
- {"RepositionMenu", RepositionMenu}
- };
-
- int main(argc, argv)
- int argc;
- char *argv[];
- {
- Widget toplevel;
-
- toplevel = XtAppInitialize(&app, "DemoCalc",
- (XrmOptionDescList) NULL, 0, &argc, argv,
- (String *) NULL, (ArgList) NULL, 0);
-
- XtAppAddActions(app, actions, XtNumber(actions));
-
- /* Make XtMenuPopup synchronous */
- XtRegisterGrabAction(XtMenuPopupAction, FALSE,
- ButtonPressMask | ButtonReleaseMask, GrabModeSync,
- GrabModeAsync);
-
- CreateInterface(toplevel);
- RefreshDisplay();
- XtRealizeWidget(toplevel);
- XtAppMainLoop(app);
- }
-
- void CreateInterface(toplevel)
- Widget toplevel;
- {
- Widget main, widget, menu;
-
- main = XtCreateManagedWidget("main", boxWidgetClass,
- toplevel, (Arg *) NULL, 0);
- display = XtCreateManagedWidget("display", pushbuttonWidgetClass,
- main, (Arg *) NULL, 0);
- XtAddCallback(display, XtNloseSelection,
- LoseSelection, (XtPointer) NULL);
-
- #define CreatePushbutton(name, callback, data) \
- widget = XtCreateManagedWidget(name, pushbuttonWidgetClass, \
- main, (Arg *) NULL, 0); \
- XtAddCallback(widget, XtNcallback, callback, (XtPointer) data);
-
- CreatePushbutton("button0", InputDigit, 0);
- CreatePushbutton("button1", InputDigit, 1);
- CreatePushbutton("button2", InputDigit, 2);
- CreatePushbutton("button3", InputDigit, 3);
- CreatePushbutton("button4", InputDigit, 4);
- CreatePushbutton("button5", InputDigit, 5);
- CreatePushbutton("button6", InputDigit, 6);
- CreatePushbutton("button7", InputDigit, 7);
- CreatePushbutton("button8", InputDigit, 8);
- CreatePushbutton("button9", InputDigit, 9);
-
- CreatePushbutton("decimal", InputDecimal, NULL);
-
- CreatePushbutton("plus", Function, Add);
- CreatePushbutton("minus", Function, Sub);
- CreatePushbutton("times", Function, Mul);
- CreatePushbutton("divide", Function, Div);
- CreatePushbutton("equals", Function, Equal);
-
- CreatePushbutton("clearEntry", Clear, FALSE);
- CreatePushbutton("clear", Clear, TRUE);
- #undef CreatePushbutton
-
- menuShell = XtCreatePopupShell("menuShell",
- overrideShellWidgetClass, main, (Arg *) NULL, 0);
- menu = XtCreateManagedWidget("menu", menuWidgetClass, menuShell,
- (Arg *) NULL, 0);
-
- #define CreateMenuItem(name, callback) \
- widget = XtCreateManagedWidget(name, menuItemWidgetClass, \
- menu, (Arg *) NULL, 0); \
- XtAddCallback(widget, XtNcallback, callback, (XtPointer) NULL);
-
- CreateMenuItem("select", Select);
- CreateMenuItem("paste", Paste);
- CreateMenuItem("quit", Quit);
- #undef CreateMenuItem
- XtInstallAllAccelerators(main, main);
- }
-
- void InputDigit(w, client_data, call_data)
- Widget w;
- XtPointer client_data; /* Digit to input */
- XtPointer call_data;
- {
- int num = (int) client_data;
-
- if (inputDecimal) {
- currentInput += num * scale;
- scale /= 10;
- } else currentInput = currentInput * 10 + num;
-
- numberToDisplay = ¤tInput;
- RefreshDisplay();
- inputNumber = TRUE;
- }
-
- void InputDecimal(w, client_data, call_data)
- Widget w;
- XtPointer client_data, call_data;
- {
- inputDecimal = inputNumber = TRUE;
- scale = 0.1;
- numberToDisplay = ¤tInput;
- RefreshDisplay();
- }
-
- void Function(w, client_data, call_data)
- Widget w;
- XtPointer client_data; /* Operation code */
- XtPointer call_data;
- {
- switch (lastOp) {
- case Add:
- total += currentInput;
- break;
- case Sub:
- total -= currentInput;
- break;
- case Mul:
- total *= currentInput;
- break;
- case Div:
- if (currentInput == 0.0) XBell(XtDisplay(display), 100);
- else total /= currentInput;
- break;
- case Equal:
- if (inputNumber) total = currentInput;
- break;
- case Start:
- total = currentInput;
- break;
- }
- lastOp = (operation) client_data;
- currentInput = 0;
- inputDecimal = inputNumber = FALSE;
-
- numberToDisplay = &total;
- RefreshDisplay();
- }
-
- void Clear(w, client_data, call_data)
- Widget w;
- XtPointer client_data; /* FALSE for Clear Entry */
- XtPointer call_data;
- {
- currentInput = 0;
- if ((Boolean) client_data) {
- total = 0;
- lastOp = Start;
- }
- inputDecimal = inputNumber = FALSE;
-
- numberToDisplay = ¤tInput;
- RefreshDisplay();
- }
-
- void RefreshDisplay()
- {
- char buffer[100];
- Arg args[10];
- int i = 0;
-
- if (hasSelection) { /* Get rid of it */
- LabelSelectText(display, XA_PRIMARY, FALSE);
- /* LoseSelection resets hasSelection and uninverts display */
- }
-
- sprintf(buffer, "%g", *numberToDisplay);
- XtSetArg(args[i], XtNlabel, buffer); i++;
- XtSetValues(display, args, i);
- }
-
- void RepositionMenu(w, event, params, num_params)
- Widget w;
- XEvent *event;
- String *params;
- Cardinal *num_params;
- {
- XButtonEvent *b = &event->xbutton;
- Dimension width, height, border;
- Arg arg[25];
- int n;
-
- if (event->type != ButtonPress) return;
-
- /* Size isn't valid before realizing */
- XtRealizeWidget(menuShell);
-
- /* Fetch size */
- n = 0;
- XtSetArg(arg[n], XtNwidth, &width); n++;
- XtSetArg(arg[n], XtNheight, &height); n++;
- XtSetArg(arg[n], XtNborderWidth, &border); n++;
- XtGetValues(menuShell, arg, n);
-
- /* Reposition menu */
- n = 0;
- XtSetArg(arg[n], XtNx, b->x_root - width/2 - border); n++;
- XtSetArg(arg[n], XtNy, b->y_root - height/2 - border); n++;
- XtSetValues(menuShell, arg, n);
- }
-
- void Quit(w, client_data, call_data)
- Widget w;
- XtPointer client_data, call_data;
- {
- exit(0);
- }
-
- void Select(w, client_data, call_data)
- Widget w;
- XtPointer client_data, call_data;
- {
- if (hasSelection) return;
-
- /* Ask for selection */
- if (LabelSelectText(display, XA_PRIMARY, TRUE)) {
- hasSelection = TRUE;
-
- /* Invert display widget */
- XtCallActionProc(display, "invert", (XEvent *) NULL,
- (String *) NULL, 0);
- }
- }
-
- void LoseSelection(w, client_data, call_data)
- Widget w;
- XtPointer client_data, call_data;
- {
- hasSelection = FALSE;
-
- /* Uninvert the display */
- XtCallActionProc(display, "uninvert", (XEvent *) NULL,
- (String *) NULL, 0);
- }
-
- void Paste(w, client_data, call_data)
- Widget w;
- XtPointer client_data, call_data;
- {
- XtGetSelectionValue(display, XA_PRIMARY, XA_STRING, PasteData,
- (XtPointer) NULL, XtLastTimestampProcessed(XtDisplay(w)));
- }
-
- void PasteData(w, client_data, selection, type, value, length, format)
- Widget w;
- XtPointer client_data;
- Atom *selection, *type;
- XtPointer value;
- unsigned long *length;
- int *format;
- {
- register int i;
- char *ch = (char *) value;
-
- /* Make sure we got what we expected */
- if (*selection != XA_PRIMARY || *type != XA_STRING ||
- *format != 8 || value == NULL) return;
-
- for (i = 0; i < *length; i++) {
- if (ch[i] >= '0' && ch[i] <= '9') {
- InputDigit(display, (XtPointer) (ch[i] - '0'),
- (XtPointer) NULL);
- } else switch (ch[i]) {
- case '+':
- Function(display, (XtPointer) Add, (XtPointer) NULL);
- break;
- case '-':
- Function(display, (XtPointer) Sub, (XtPointer) NULL);
- break;
- case '*':
- Function(display, (XtPointer) Mul, (XtPointer) NULL);
- break;
- case '/':
- Function(display, (XtPointer) Div, (XtPointer) NULL);
- break;
- case '=':
- Function(display, (XtPointer) Equal, (XtPointer) NULL);
- break;
- case '.':
- InputDecimal(display, (XtPointer) NULL,
- (XtPointer) NULL);
- break;
- default:
- return;
- }
- }
- Function(display, (XtPointer) Equal, (XtPointer) NULL);
-
- XtFree((XtPointer) value);
- }
-