home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
The World of Computer Software
/
World_Of_Computer_Software-02-385-Vol-1of3.iso
/
s
/
stex2-18.zip
/
SeeTeX
/
Xtex
/
EzMenu.c
< prev
next >
Wrap
C/C++ Source or Header
|
1992-04-25
|
11KB
|
426 lines
#if ( !defined(lint) && !defined(SABER) )
static char Xrcsid[] = "$XConsortium: SimpleMenu.c,v 1.32 89/12/11 15:01:50 kit Exp $";
#endif
/*
* Copyright 1989 Massachusetts Institute of Technology
*
* Permission to use, copy, modify, distribute, and sell this software and its
* documentation for any purpose is hereby granted without fee, 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 M.I.T. not be used in advertising or
* publicity pertaining to distribution of the software without specific,
* written prior permission. M.I.T. makes no representations about the
* suitability of this software for any purpose. It is provided "as is"
* without express or implied warranty.
*
* M.I.T. DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO EVENT SHALL M.I.T.
* 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 <stdio.h>
#include <X11/Xlib.h>
#include <X11/Xos.h>
#include <X11/Intrinsic.h>
#include <X11/IntrinsicP.h>
#include <X11/StringDefs.h>
#include "EzMenuP.h"
#include <X11/Xaw/SimpleMenu.h>
#include <X11/Xaw/Sme.h>
#include "EzME.h"
#include <X11/Xaw/SmeBSB.h>
#include <X11/Xaw/SmeLine.h>
#include <X11/Xaw/Cardinals.h>
#include <ctype.h>
#define offset(field) XtOffset(EzMenuWidget, ez_menu.field)
static XtResource resources[] = {
{XtNmenu, XtCMenu, XtRString, sizeof(String),
offset(menu), XtRString, NULL},
};
#undef offset
/*
* Semi Public function definitions.
*/
static void Initialize();
static void Destroy();
static void Realize();
static Boolean SetValues();
#define superclass (&simpleMenuClassRec)
EzMenuClassRec ezMenuClassRec = {
{
/* superclass */ (WidgetClass) superclass,
/* class_name */ "EzMenu",
/* size */ sizeof(EzMenuRec),
/* class_initialize */ NULL,
/* class_part_initialize*/ NULL,
/* Class init'ed */ FALSE,
/* initialize */ Initialize,
/* initialize_hook */ NULL,
/* realize */ Realize,
/* actions */ NULL,
/* num_actions */ 0,
/* resources */ resources,
/* resource_count */ XtNumber(resources),
/* xrm_class */ NULLQUARK,
/* compress_motion */ TRUE,
/* compress_exposure */ TRUE,
/* compress_enterleave*/ TRUE,
/* visible_interest */ FALSE,
/* destroy */ Destroy,
/* resize */ XtInheritResize,
/* expose */ XtInheritExpose,
/* set_values */ SetValues,
/* set_values_hook */ NULL,
/* set_values_almost */ XtInheritSetValuesAlmost,
/* get_values_hook */ NULL,
/* accept_focus */ NULL,
/* intrinsics version */ XtVersion,
/* callback offsets */ NULL,
/* tm_table */ XtInheritTranslations,
/* query_geometry */ XtInheritQueryGeometry,
/* display_accelerator*/ XtInheritDisplayAccelerator,
/* extension */ NULL
},{
/* geometry_manager */ XtInheritGeometryManager,
/* change_managed */ XtInheritChangeManaged,
/* insert_child */ XtInheritInsertChild,
/* delete_child */ XtInheritDeleteChild,
/* extension */ NULL
},{
/* Shell extension */ NULL
},{
/* Override extension */ NULL
},{
/* Simple Menu extension*/ NULL
},{
/* Ez Menu extension*/ NULL
}
};
WidgetClass ezMenuWidgetClass = (WidgetClass)&ezMenuClassRec;
/************************************************************
*
* Semi-Public Functions.
*
************************************************************/
/*
* routines to process menus
*/
#define QUOTE '\"'
#define BACKSLASH '\\'
#define SKIPWHITE(cp) while (cp && *cp && isspace(*cp)) cp++
#define FINDPAREN(cp) while (cp && *cp && *cp != '(') cp++
#define FINDQUOTE(cp) while (cp && *cp && *cp != QUOTE) cp++
#define KEY_LEN 32
#define NAME_LEN 128
#define LABEL_LEN 128
/*
* Parse a main level menu decl. and add all children to that parent
*/
char *
EzMenuParseString(from, to, maxlen)
char *from;
char *to;
int maxlen;
{
char *oldto = to;
SKIPWHITE(from);
if ( from && *from == QUOTE ) {
maxlen--;
from++;
while (*from && *from != QUOTE && maxlen > 1) {
if ( *from == BACKSLASH) {
from++;
}
*to++ = *from++;
maxlen--;
}
if ( *from == QUOTE ) {
from++;
}
}
*to = 0;
return(from);
}
char *
EzMenuParseMenu(parent,menu,subMenuOk)
Widget parent;
char *menu;
Bool subMenuOk;
{
char *thisWidgetName[NAME_LEN];
char *thisWidgetLabel[LABEL_LEN];
*thisWidgetName = 0;
*thisWidgetLabel = 0;
while(menu && *menu) {
SKIPWHITE(menu);
if (!menu || *menu != '(') {
return( menu );
}
else {
menu++;
}
SKIPWHITE(menu);
if (isalpha(*menu)) {
char key[KEY_LEN+1];
char *p = key;
int keylen = 0;
while(isalpha(*menu) && keylen < KEY_LEN) {
*p++ = *menu++;
keylen++;
}
*p = 0;
if (strcmp(key, "action") == 0 ) {
char name[NAME_LEN];
Arg arglist[1];
Cardinal num_args = 0;
menu = EzMenuParseString(menu, name, NAME_LEN);
XtSetArg(arglist[num_args], XtNaction, name); num_args++;
XtSetValues(parent, arglist, num_args);
}
else if (strcmp(key, "blank") == 0 ) {
char name[NAME_LEN];
Widget entry;
*name = 0;
menu = EzMenuParseString(menu, name, NAME_LEN);
if ( *name == 0 ) {
static int counter = 0;
sprintf(name, "blank%d", counter);
}
entry = XtCreateManagedWidget(name, smeObjectClass,
parent, NULL, ZERO);
}
else if (strcmp(key, "line") == 0 ) {
char name[NAME_LEN];
Widget entry;
*name = 0;
menu = EzMenuParseString(menu, name, NAME_LEN);
if ( *name == 0 ) {
static int counter = 0;
sprintf(name, "line%d", counter);
}
entry = XtCreateManagedWidget(name, smeLineObjectClass, parent,
NULL, ZERO);
}
else if (strcmp(key, "item") == 0 || strcmp(key, "menu") == 0 ) {
char name[NAME_LEN];
char label[LABEL_LEN];
Widget entry;
Bool isMenu;
extern void MenuSelect();
Arg arglist[10];
Cardinal num_args = 0;
isMenu = (strcmp(key, "menu") == 0);
*name = 0;
menu = EzMenuParseString(menu, label, LABEL_LEN);
menu = EzMenuParseString(menu, name, NAME_LEN);
if ( *name == 0 ) {
static int counter = 0;
sprintf(name, "%s%d", key, counter);
}
if ( *label == 0 ) {
strcpy(label, name);
}
if ( isMenu ) {
char menu_name[NAME_LEN];
Widget menu_entry;
sprintf(menu_name,"%s-menu", name);
XtSetArg(arglist[num_args], XtNlabel, label); num_args++;
menu_entry = XtCreatePopupShell(menu_name, ezMenuWidgetClass,
parent, arglist, num_args);
/* now, parse their menu entry. This is gross, but beats
scanning ahead to find the stupid balanced parens */
menu = EzMenuParseMenu(menu_entry, menu, True);
num_args = 0;
XtSetArg(arglist[num_args], XtNlabel, label); num_args++;
XtSetArg(arglist[num_args], XtNmenu, menu_entry); num_args++;
entry = XtCreateManagedWidget(name, ezMEObjectClass, parent,
arglist, num_args);
}
else {
num_args = 0;
XtSetArg(arglist[num_args], XtNlabel, label); num_args++;
XtSetArg(arglist[num_args], XtNmenu, 0); num_args++;
entry = XtCreateManagedWidget(name, ezMEObjectClass, parent,
arglist, num_args);
}
menu = EzMenuParseMenu(entry, menu, isMenu);
}
SKIPWHITE(menu);
if (*menu != ')') {
char buffer[2048];
XtAppContext context =
XtWidgetToApplicationContext( parent );
sprintf(buffer, "unbalanced parens or bogus format: %s\n", menu);
XtAppError(context, buffer);
exit(1);
}
menu++;
}
}
return(menu);
}
/* Function Name: Initialize
* Description: Initializes the simple menu widget
* Arguments: request - the widget requested by the argument list.
* new - the new widget with both resource and non
* resource values.
* Returns: none.
*/
/* ARGSUSED */
static void
Initialize(request, new)
Widget request, new;
{
EzMenuWidget newez = (EzMenuWidget) new;
EzMenuWidget requestez = (EzMenuWidget) request;
#ifdef DEBUG
fprintf(stderr,"Initialize %s\n",
XtWidgetName(request);
#endif
/* just copy the string that will be used to initialize the menu */
newez -> ez_menu.menu = 0;
if (requestez -> ez_menu.menu ) {
int len = strlen(requestez -> ez_menu.menu);
newez -> ez_menu.menu = XtMalloc( len + 1 );
strcpy( newez -> ez_menu.menu, requestez -> ez_menu.menu);
}
if ( newez -> ez_menu.menu ) {
EzMenuParseMenu( newez, newez -> ez_menu.menu, True );
}
}
/* Function Name: Realize
* Description: Realizes the widget.
* Arguments: w - the simple menu widget.
* mask - value mask for the window to create.
* attrs - attributes for the window to create.
* Returns: none
*/
static void
Realize(w, mask, attrs)
Widget w;
XtValueMask * mask;
XSetWindowAttributes * attrs;
{
EzMenuWidget newez = (EzMenuWidget) w;
(*superclass->core_class.realize) (w, mask, attrs);
}
/* Function Name: SetValues
* Description: Relayout the menu when one of the resources is changed.
* Arguments: current - current state of the widget.
* request - what was requested.
* new - what the widget will become.
* Returns: none
*/
/* ARGSUSED */
static Boolean
SetValues(current, request, new)
Widget current, request, new;
{
EzMenuWidget ez_old = (EzMenuWidget) current;
EzMenuWidget ez_want = (EzMenuWidget) request;
EzMenuWidget ez_new = (EzMenuWidget) new;
Boolean ret_val = FALSE;
if (
/* no old menu, want one now */
( !ez_old -> ez_menu.menu && ez_want -> ez_menu.menu )
||
/* old menu, new one is different */
(ez_want -> ez_menu.menu
&& ez_old -> ez_menu.menu
&& ( strcmp( ez_old -> ez_menu.menu,
ez_want -> ez_menu.menu) != 0 ))
) {
int len = strlen(ez_old -> ez_menu.menu);
ez_new -> ez_menu.menu = XtMalloc( len + 1 );
strcpy( ez_new -> ez_menu.menu,
ez_old -> ez_menu.menu);
if ( XtIsRealized((Widget) ez_old) ) {
SimpleMenuWidget smw = (SimpleMenuWidget) ez_old;
SmeObject *entry;
ForAllChildren(smw, entry) {
XtDestroyWidget((Widget) entry);
}
EzMenuParseMenu(ez_new, ez_new -> ez_menu.menu, True);
ret_val = TRUE;
}
}
return(ret_val);
}
static void
Destroy(who)
EzMenuWidget who;
{
XtFree( who -> ez_menu.menu );
}