|
|
DataMuseum.dkPresents historical artifacts from the history of: Regnecentalen RC-900 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Regnecentalen RC-900 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: T U m
Length: 27207 (0x6a47)
Types: TextFile
Notes: UNIX file
Names: »motifb.c«
└─⟦a85bd4a7c⟧ Bits:30004636/disk2.imd INTERACTIVE Motif Environment Development System
└─⟦a85bd4a7c⟧ UNIX Filesystem
└─⟦this⟧ »xt/new/usr/lib/X11/examples/motifburger/motifb.c«
#ifdef REV_INFO
#ifndef lint
static char SCCSID[] = "OSF/Motif: @(#)motifb.c 1.1 - 89/08/30 - 11:48:08";
#endif /* lint */
#endif /* REV_INFO */
/******************************************************************************
*******************************************************************************
*
* (c) Copyright 1989, OPEN SOFTWARE FOUNDATION, INC.
* (c) Copyright 1989, DIGITAL EQUIPMENT CORPORATION, MAYNARD, MASS.
* ALL RIGHTS RESERVED
*
* THE INFORMATION IN THIS SOFTWARE IS SUBJECT TO CHANGE WITHOUT
* NOTICE AND SHOULD NOT BE CONSTRUED AS A COMMITMENT BY OPEN SOFTWARE
* FOUNDATION, INC. OR ITS THIRD PARTY SUPPLIERS
*
* OPEN SOFTWARE FOUNDATION, INC. AND ITS THIRD PARTY SUPPLIERS,
* ASSUME NO RESPONSIBILITY FOR THE USE OR INABILITY TO USE ANY OF ITS
* SOFTWARE . OSF SOFTWARE IS PROVIDED "AS IS" WITHOUT WARRANTY OF ANY
* KIND, AND OSF EXPRESSLY DISCLAIMS ALL IMPLIED WARRANTIES, INCLUDING
* BUT NOT LIMITED TO THE IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS FOR A PARTICULAR PURPOSE.
*
* Notice: Notwithstanding any other lease or license that may pertain to,
* or accompany the delivery of, this computer software, the rights of the
* Government regarding its use, reproduction and disclosure are as set
* forth in Section 52.227-19 of the FARS Computer Software-Restricted
* Rights clause.
*
* (c) Copyright 1989, Open Software Foundation, Inc. Unpublished - all
* rights reserved under the Copyright laws of the United States.
*
* RESTRICTED RIGHTS NOTICE: Use, duplication, or disclosure by the
* Government is subject to the restrictions as set forth in subparagraph
* (c)(1)(ii) of the Rights in Technical Data and Computer Software clause
* at DFARS 52.227-7013.
*
* Open Software Foundation, Inc.
* 11 Cambridge Center
* Cambridge, MA 02142
* (617)621-8700
*
* RESTRICTED RIGHTS LEGEND: This computer software is submitted with
* "restricted rights." Use, duplication or disclosure is subject to the
* restrictions as set forth in NASA FAR SUP 18-52.227-79 (April 1985)
* "Commercial Computer Software- Restricted Rights (April 1985)." Open
* Software Foundation, Inc., 11 Cambridge Center, Cambridge, MA 02142. If
* the contract contains the Clause at 18-52.227-74 "Rights in Data General"
* then the "Alternate III" clause applies.
*
* (c) Copyright 1989, Open Software Foundation, Inc.
* ALL RIGHTS RESERVED
*
*
* Open Software Foundation is a trademark of The Open Software Foundation, Inc.
* OSF is a trademark of Open Software Foundation, Inc.
* OSF/Motif is a trademark of Open Software Foundation, Inc.
* Motif is a trademark of Open Software Foundation, Inc.
* DEC is a registered trademark of Digital Equipment Corporation
* DIGITAL is a registered trademark of Digital Equipment Corporation
* X Window System is a trademark of the Massachusetts Institute of Technology
*
*******************************************************************************
******************************************************************************/
/*
* A sample program which uses UIL and MRM to create the interface.
*/
#include <stdio.h> /* For printf and so on. */
#include <Xm/Text.h>
#include <Mrm/MrmAppl.h> /* Motif Toolkit and MRM */
/*
* These numbers are matched with corresponding numbers in the DECburger
* UIL module.
*/
#define k_create_order 1
#define k_order_pdme 2
#define k_file_pdme 3
#define k_edit_pdme 4
#define k_nyi 5
#define k_apply 6
#define k_dismiss 7
#define k_noapply 8
#define k_cancel_order 9
#define k_submit_order 10
#define k_order_box 11
#define k_burger_min 12
#define k_burger_rare 12
#define k_burger_medium 13
#define k_burger_well 14
#define k_burger_ketchup 15
#define k_burger_mustard 16
#define k_burger_onion 17
#define k_burger_mayo 18
#define k_burger_pickle 19
#define k_burger_quantity 20
#define k_burger_max 20
#define k_fries_tiny 21
#define k_fries_small 22
#define k_fries_medium 23
#define k_fries_large 24
#define k_fries_huge 25
#define k_fries_quantity 26
#define k_drink_list 27
#define k_drink_add 28
#define k_drink_sub 29
#define k_drink_quantity 30
#define k_total_order 31
#define k_burger_label 32
#define k_fries_label 33
#define k_drink_label 34
#define k_menu_bar 35
#define k_file_menu 36
#define k_edit_menu 37
#define k_order_menu 38
#define k_max_widget 38
#define MAX_WIDGETS (k_max_widget + 1)
#define NUM_BOOLEAN (k_burger_max - k_burger_min + 1)
#define k_burger_index 0
#define k_fries_index 1
#define k_drinks_index 2
#define k_index_count 3
/*
* Global data
*/
static Widget toplevel_widget, /* Root widget ID of our */
/* application. */
main_window_widget, /* Root widget ID of main */
/* MRM fetch */
widget_array[MAX_WIDGETS]; /* Place to keep all other */
/* widget IDs */
static char toggle_array[NUM_BOOLEAN]; /* Our TRUTH about the state */
/* of user interface toggles. */
static XmString current_drink, /* Last selected drink name. */
current_fries, /* Last selected fries size. */
name_vector[k_index_count]; /* Miscellaneous names gotten from */
/* various widgets. */
static int quantity_vector[k_index_count]; /* Current quantities of */
/* burger, fries, drinks. */
static XmString latin_create; /* Variables for */
static XmString latin_dismiss; /* compound strings. */
static XmString latin_space;
static XmString latin_zero;
static MrmHierarchy s_MrmHierarchy; /* MRM database hierarchy ID */
static MrmType *dummy_class; /* and class variable. */
static char *db_filename_vec[] = /* Mrm.heirachy file list. */
{"motifburger.uid" /* There is only one UID file for */
}; /* this application. */
static int db_filename_num =
(sizeof db_filename_vec / sizeof db_filename_vec [0]);
/*
* Forward declarations
*/
static void s_error();
static void get_something();
static void set_something();
static void activate_proc();
static void create_proc();
static void list_proc();
static void quit_proc();
static void pull_proc();
static void scale_proc();
static void show_hide_proc();
static void show_label_proc();
static void toggle_proc();
/* The names and addresses of things that Mrm.has to bind. The names do
* not have to be in alphabetical order. */
static MRMRegisterArg reglist[] = {
{"activate_proc", (caddr_t) activate_proc},
{"create_proc", (caddr_t) create_proc},
{"list_proc", (caddr_t) list_proc},
{"pull_proc", (caddr_t) pull_proc},
{"quit_proc", (caddr_t) quit_proc},
{"scale_proc", (caddr_t) scale_proc},
{"show_hide_proc", (caddr_t) show_hide_proc},
{"show_label_proc", (caddr_t) show_label_proc},
{"toggle_proc", (caddr_t) toggle_proc}
};
static int reglist_num = (sizeof reglist / sizeof reglist [0]);
static font_unit = 400;
/*
* OS transfer point. The main routine does all the one-time setup and
* then calls XtMainLoop.
*/
unsigned int main(argc, argv)
unsigned int argc; /* Command line argument count. */
char *argv[]; /* Pointers to command line args. */
{
MrmInitialize(); /* Initialize MRM before initializing
/* the X Toolkit. */
/* If we had user-defined widgets, we would register them with Mrm.here. */
/* Initialize the X Toolkit. We get back a top level shell widget. */
toplevel_widget = XtInitialize("Welcome to DECburger",
/* Main window banner text. */
"example", /* Root class name. */
NULL, /* No option list. */
0, /* Number of options. */
&argc, /* Address of argc */
argv); /* argv */
/* Open the UID files (the output of the UIL compiler) in the hierarchy*/
if (MrmOpenHierarchy(db_filename_num, /* Number of files. */
db_filename_vec, /* Array of file names. */
NULL, /* Default OS extenstion. */
&s_MrmHierarchy) /* Pointer to returned MRM ID */
!=MrmSUCCESS)
s_error("can't open hierarchy");
init_application();
/* Register the items MRM needs to bind for us. */
MrmRegisterNames(reglist, reglist_num);
/* XmSetFontUnit(XtDisplay(toplevel_widget), font_unit);
*/
/* Go get the main part of the application. */
if (MrmFetchWidget(s_MrmHierarchy, "S_MAIN_WINDOW", toplevel_widget,
&main_window_widget, &dummy_class) != MrmSUCCESS)
s_error("can't fetch main window");
/* Manage the main part and realize everything. The interface comes up
* on the display now. */
XtManageChild(main_window_widget);
XtRealizeWidget(toplevel_widget);
/* Sit around forever waiting to process X-events. We never leave
* XtMainLoop. From here on, we only execute our callback routines. */
XtMainLoop();
}
/*
* One-time initialization of application data structures.
*/
static int init_application()
{
int k;
/* Initialize the application data structures. */
for (k = 0; k < MAX_WIDGETS; k++)
widget_array[k] = NULL;
for (k = 0; k < NUM_BOOLEAN; k++)
toggle_array[k] = FALSE;
/* Set the medium 'hamburger doneness' toggle button so that the
* radio box has one toggle button ON at startup. */
toggle_array[k_burger_medium - k_burger_min] = TRUE;
/* Initialize current values of various items to match their initial values
* in the DECburger UIL module. */
current_drink = XmStringLtoRCreate("Apple Juice","");
current_fries = XmStringLtoRCreate("Medium","");
/* Set up the compound strings that we need. */
latin_create = XmStringLtoRCreate("Create order box...","");
latin_dismiss = XmStringLtoRCreate("Dismiss order box...","");
latin_space = XmStringLtoRCreate(" ","");
latin_zero = XmStringLtoRCreate(" 0 ","");
}
/***************************************************************************
*
* These are some little utilities used by the callback routines.
*/
/*
* All errors are fatal.
*/
static void s_error(problem_string)
char *problem_string;
{
printf("%s\n", problem_string);
exit(0);
}
/*
* Simplified SET VALUE routine to use only when changing a single attribute.
* If we need to change more than one, all new values should be put
* into one arglist and we should make one XtSetValues call (which is MUCH
* more efficient).
*/
static void set_something(w, resource, value)
Widget w;
char *resource, *value;
{
Arg al[1];
XtSetArg(al[0], resource, value);
XtSetValues(w, al, 1);
}
/*
* Simplified GET VALUE routine to use only when retrieving a single attribute.
* If we need to retrieve more than one, all values should be put
* into one arglist and we should make one XtGetValues call (which is MUCH
* more efficient).
*/
static void get_something(w, resource, value)
Widget w;
char *resource, *value;
{
Arg al[1];
XtSetArg(al[0], resource, value);
XtGetValues(w, al, 1);
}
/*
* Keep our boolean array current with the user interface toggle buttons.
*/
static void set_boolean(i, state)
int i; /* Widget ID index. */
int state;
{
toggle_array[i - k_burger_min] = state;
XmToggleButtonSetState(widget_array[i],
/* Which widget */
state, /* state it should have. */
FALSE); /* Do not call me back now. */
}
/*
* Format and update the drink quantity widget.
*/
static void update_drink_display()
{
char drink_txt[50];
sprintf(drink_txt, " %d ", quantity_vector[k_drinks_index]);
set_something(widget_array[k_drink_quantity], XmNlabelString,
XmStringLtoRCreate(drink_txt,""));
}
/***************************************************************************
*
* This section contains callback routines.
*/
/*
* Reset the user interface and the application to a known state.
*/
static void reset_values()
{
int i;
/* Reset the toggle buttons and our boolean array. */
for (i = k_burger_min; i <= k_burger_max; i++) {
/* The radio box requires that one button be set; we choose medium. */
set_boolean(i, (i == k_burger_medium));
}
/* Reset the burger quantity scale widget and global value. */
set_something(widget_array[k_burger_quantity], XmNvalue, 0);
quantity_vector[k_burger_index] = 0;
/* Reset the fries quantity text widget. We do not have a global for this.
* We read the widget whenever we need to know the quantity. */
XmTextSetString(widget_array[k_fries_quantity], " 0 ");
/* Reset the drinks quantity text widget and global value. */
set_something(widget_array[k_drink_quantity], XmNlabelString, latin_zero);
quantity_vector[k_drinks_index] = 0;
}
/*
* Clear the order display area in the main window.
*/
static void clear_order()
{
Arg arglist[5];
int ac = 0;
XtSetArg(arglist[ac], XmNitemCount, 0);
ac++;
! XtSetArg(arglist[ac], XmNitems, NULL);
! ac++;
XtSetArg(arglist[ac], XmNselectedItemCount, 0);
ac++;
XtSetValues(widget_array[k_total_order], arglist, ac);
}
/*
* All push buttons in this application call back to this routine. We
* use the tag to tell us what widget it is, then react accordingly.
*/
static void activate_proc(w, tag, reason)
Widget w;
int *tag;
unsigned long *reason;
{
int widget_num = *tag; /* Convert tag to widget number. */
int i, value, fries_num;
char *txt, *fries_text, *list_txt, list_buffer[20];
switch (widget_num) {
case k_nyi:
/* The user activated a 'not yet implemented' push button. Send
* the user a message. */
if (widget_array[k_nyi] == NULL)
/* The first time, fetch from */
{ /* the data base. */
if (MrmFetchWidget(s_MrmHierarchy, "nyi", toplevel_widget,
&widget_array[k_nyi], &dummy_class) != MrmSUCCESS) {
s_error("can't fetch nyi widget");
}
}
/* Put up the message box saying 'not yet implemented'. */
XtManageChild(widget_array[k_nyi]);
break;
case k_submit_order:
/* This would send the order off to the kitchen. In this case,
* we just pretend the order was submitted. */
clear_order();
break;
case k_cancel_order:
/* Clear out the order display. */
clear_order();
break;
case k_dismiss:
/* Bring down the control box and reset the values to the default.
*/
XtUnmanageChild(widget_array[k_order_box]);
/* no break */
case k_noapply:
reset_values();
break;
case 333:
printf ("callback 333");
break;
case 334:
printf ("callback 334");
break;
case 335:
printf ("callback 335");
break;
case 336:
printf ("callback 336");
break;
case k_apply:
/* Take the current settings and write them into the list box. */
if (quantity_vector[k_burger_index] > 0) {
/* Put burger quantity in the display string. */
sprintf(list_buffer, "%d ", quantity_vector[k_burger_index]);
list_txt = XmStringLtoRCreate(list_buffer,"");
/* Collect hambuger attributes that are ON. */
for (i = k_burger_min; i <= k_burger_max; i++)
if (toggle_array[i - k_burger_min]) {
/* Get the name of the qualifier from the widget and
* add to the display string. */
get_something(widget_array[i], XmNlabelString, &txt);
list_txt = XmStringConcat(list_txt, txt);
list_txt = XmStringConcat(list_txt, latin_space);
}
/* Add hamburger name and add to the display string. */
list_txt = XmStringConcat(list_txt, name_vector[k_burger_index]);
XmListAddItem(widget_array[k_total_order], list_txt, 0);
}
/* Text widget does not have a callback. So we query the widget
* now to determine what its value is. Convert to an integer. */
fries_num = 0;
fries_text = XmTextGetString(widget_array[k_fries_quantity]);
sscanf(fries_text, "%d", &fries_num);
if (fries_num != 0) {
/* Put the fries quantity in the display string. */
sprintf(list_buffer, "%d ", fries_num);
list_txt = XmStringLtoRCreate(list_buffer,"");
/* Get all the qualifiers for the fries. */
list_txt = XmStringConcat(list_txt, current_fries);
list_txt = XmStringConcat(list_txt, latin_space);
/* Add fries name and display. */
list_txt = XmStringConcat(list_txt, name_vector[k_fries_index]);
XmListAddItem(widget_array[k_total_order], list_txt, 0);
}
if (quantity_vector[k_drinks_index] > 0) {
/* Put drinks quantity into the display string. */
sprintf(list_buffer, "%d ", quantity_vector[k_drinks_index]);
list_txt = XmStringLtoRCreate(list_buffer,"");
/* Now get the qualifiers for the drinks. */
list_txt = XmStringConcat(list_txt, current_drink);
list_txt = XmStringConcat(list_txt, latin_space);
/* Add the drink name to the display string. */
list_txt = XmStringConcat(list_txt, name_vector[k_drinks_index]);
XmListAddItem(widget_array[k_total_order], list_txt, 0);
}
break;
case k_fries_tiny:
case k_fries_small:
case k_fries_medium:
case k_fries_large:
case k_fries_huge:
/* Some fries size push button was activated, so get the string
* from the interface. Helps with internationalization. */
get_something(w, XmNlabelString, ¤t_fries);
break;
case k_drink_add:
/* Increment the drink quantity and update the display. */
quantity_vector[k_drinks_index]++;
update_drink_display();
break;
case k_drink_sub:
/* Decrement drink quantity, but do not let it go below zero. */
if (quantity_vector[k_drinks_index] > 0)
quantity_vector[k_drinks_index]--;
update_drink_display();
break;
default:
break;
}
}
/*
* The toggle buttons which control the 'hamburger doneness' and toppings
* call back to this procedure when they change state. Use the
* tag to index into the boolean array. Just keep the booleans current
* with the user interface.
*/
static void toggle_proc(w, tag, toggle)
Widget w;
int *tag;
XmToggleButtonCallbackStruct *toggle;
{
toggle_array[*tag - k_burger_min] = toggle->set;
}
/*
* The drink selection list box calls back to this procedure whenever the
* user selects a drink. Just keep the global current drink up to date.
*/
static void list_proc(w, tag, list)
Widget w;
int *tag;
XmListCallbackStruct *list;
{
XtFree(current_drink);
current_drink = XmStringCopy(list->item);
}
/*
* The hamburger quantity scale widget will call back to this procedure whenever
* the user changes it. Just keep the global hamburger quantity up to date.
*/
static void scale_proc(w, tag, scale)
Widget w;
int *tag;
XmScaleCallbackStruct *scale;
{
quantity_vector[k_burger_index] = scale->value;
}
/*
* The next two procedures put up and take down the order box and change
* the label in the pulldown menu from Create to Dismiss.
*/
/*
* The user selected the Order push button in the control pulldown menu.
* We just change the state of the order box. If the order box is
* currently displayed (managed), then remove (unmanage) it. Otherwise,
* we manage the order box.
*/
static void show_hide_proc(w, tag, reason)
Widget w;
int *tag;
unsigned long *reason;
{
if (XtIsManaged(widget_array[k_order_box]))
XtUnmanageChild(widget_array[k_order_box]);
else
XtManageChild(widget_array[k_order_box]);
}
/*
* This callback runs as the control pulldown menu is about to be pulled down.
* We use this opportunity to fetch the order box (if not done already)
* and to make sure the push button displays the correct label.
*/
static void show_label_proc(w, tag, reason)
Widget w;
int *tag;
unsigned long *reason;
{
if (widget_array[k_order_box] == NULL)
/* The first time, fetch order box. */
{
if (MrmFetchWidget(s_MrmHierarchy, "control_box", toplevel_widget,
&widget_array[k_order_box], &dummy_class) != MrmSUCCESS) {
s_error("can't fetch order box widget");
}
}
/* Now figure out what the label on the push button in the pulldown menu
* should be. */
if (XtIsManaged(widget_array[k_order_box]))
set_something(widget_array[k_create_order], XmNlabelString, latin_dismiss);
else
set_something(widget_array[k_create_order], XmNlabelString, latin_create);
}
/*
* All widgets that are created call back to this procedure. We just log the
* ID in the global array.
*/
static void create_proc(w, tag, reason)
Widget w;
int *tag;
unsigned long *reason;
{
int widget_num = *tag;
widget_array[widget_num] = w;
/* For internationalization ease, we capture a few strings from the
* widgets themselves. We could go out and fetch them as needed but
* since we use these all the time, this method if more efficient.
*/
switch (widget_num) {
case k_burger_label:
get_something(w, XmNlabelString, &name_vector[k_burger_index]);
break;
case k_fries_label:
get_something(w, XmNlabelString, &name_vector[k_fries_index]);
break;
case k_drink_label:
get_something(w, XmNlabelString, &name_vector[k_drinks_index]);
break;
default:
break;
}
}
/*
* The user pushed the quit button, so the application exits.
*/
static void quit_proc(w, tag, reason)
Widget w;
int *tag;
unsigned long *reason;
{
if (tag != NULL)
printf("Quitting - %s\n", tag);
exit(1);
}
/*
* This callback runs just as a pulldown menu is about to be pulled down.
* It fetches the menu if it is currently empty, and does other
* special processing as required.
* We use this opportunity to fetch the order box (if not done already)
* and to make sure the push button displays the correct label.
*/
static void pull_proc(w, tag, reason)
Widget w;
int *tag;
unsigned long *reason;
{
int widget_num = *tag;
switch (widget_num) {
case k_file_pdme:
if (widget_array[k_file_menu] == NULL) {
if (MrmFetchWidget(s_MrmHierarchy, "file_menu", widget_array[
k_menu_bar], &widget_array[k_file_menu], &dummy_class) !=
MrmSUCCESS)
s_error("can't fetch file pulldown menu widget");
set_something(widget_array[k_file_pdme], XmNsubMenuId,
widget_array[k_file_menu]);
}
break;
case k_edit_pdme:
if (widget_array[k_edit_menu] == NULL) {
if (MrmFetchWidget(s_MrmHierarchy, "edit_menu", widget_array[
k_menu_bar], &widget_array[k_edit_menu], &dummy_class) !=
MrmSUCCESS)
s_error("can't fetch edit pulldown menu widget");
set_something(widget_array[k_edit_pdme], XmNsubMenuId,
widget_array[k_edit_menu]);
}
break;
case k_order_pdme:
if (widget_array[k_order_menu] == NULL) {
if (MrmFetchWidget(s_MrmHierarchy, "order_menu", widget_array[
k_menu_bar], &widget_array[k_order_menu], &dummy_class) !=
MrmSUCCESS)
s_error("can't fetch order pulldown menu widget");
set_something(widget_array[k_order_pdme], XmNsubMenuId,
widget_array[k_order_menu]);
if (MrmFetchWidget(s_MrmHierarchy, "control_box",
toplevel_widget, &widget_array[k_order_box], &dummy_class) !=
MrmSUCCESS)
s_error("can't fetch order box widget");
}
/* Figure out what the label of the push button in the pulldown
* menu should be. */
if ( widget_array[k_order_box] == NULL )
if (MrmFetchWidget (
s_MrmHierarchy,
"control_box",
toplevel_widget,
&widget_array [k_order_box],
&dummy_class) != MrmSUCCESS)
s_error ("can't fetch order box widget");
if (XtIsManaged(widget_array[k_order_box]))
set_something(widget_array[k_create_order], XmNlabelString,
latin_dismiss);
else
set_something(widget_array[k_create_order], XmNlabelString,
latin_create);
break;
}
}