|
DataMuseum.dkPresents historical artifacts from the history of: DKUUG/EUUG Conference tapes |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about DKUUG/EUUG Conference tapes Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - downloadIndex: C T
Length: 14579 (0x38f3) Types: TextFile Names: »Command.c«
└─⟦3d0c2be1b⟧ Bits:30001254 ISODE-5.0 Tape └─⟦eba4602b1⟧ »./isode-5.0.tar.Z« └─⟦d3ac74d73⟧ └─⟦this⟧ »isode-5.0/others/max/Command.c« └─⟦2d1937cfd⟧ Bits:30007241 EUUGD22: P.P 5.0 └─⟦35176feda⟧ »EurOpenD22/isode/isode-6.tar.Z« └─⟦de7628f85⟧ └─⟦this⟧ »isode-6.0/others/max/Command.c«
#ifndef lint static char *sccsid = "@(#)Command.c 1.41 6/1/87"; #endif lint /* * Copyright 1987 by Digital Equipment Corporation, Maynard, Massachusetts. * * 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 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 Equipment * Corporation not be used in advertising or publicity pertaining to * distribution of the software without specific, written prior permission. * * DIGITAL DISCLAIMS 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 <stdio.h> #include <strings.h> #include <X/Xlib.h> #include "Intrinsic.h" #include "Command.h" #include "Atoms.h" /* Private Definitions */ static XtContext commandContext; typedef void (*CommandProc)(); typedef struct _WidgetDataRec { Window mywin; /* widget window */ int x, y; /* Location of widget. */ int borderWidth; /* border width in pixels */ int width, height; /* width/height in pixels */ int ibw, ibh; /* internal border width/height in pixels */ char *text; /* button text */ int fgpixel; /* color index for text */ int bgpixel; /* color index for background */ Pixmap brpixmap; /* color for border */ Boolean enabled; /* user actions processed */ Boolean highlighted; /* are we border highlighted? */ Boolean set; /* are we text highlighted */ Boolean needsfreeing; /* were we destroyed by the notify proc? */ int eventlevels; /* recursion levels of event processing */ FontInfo *fontinfo; /* font for text */ int twidth, theight;/* text width/height */ XtJustify justify; /* text justification */ CommandProc proc; /* command procedure to invoke on notify */ caddr_t tag; /* widget client data */ unsigned long reason; /* reason for callback */ XtEventsPtr eventTable; /* Table for translation manager. */ caddr_t state; /* Translation manager state handle. */ } WidgetDataRec, *WidgetData; static WidgetDataRec globaldata; extern void Dummy(); static WidgetDataRec globalinit = { NULL, /* Window mywin; */ 0, 0, /* int x, y; */ 1, /* int borderWidth; */ 0, 0, /* int width, height; */ 4, 2, /* int ibw, ibh; */ NULL, /* char *text; */ NULL, /* int fgpixel; */ /* init proc */ NULL, /* int bgpixel; */ /* init proc */ NULL, /* int brpixel; */ /* init proc */ TRUE, /* int enabled; */ FALSE, /* int highlighted; */ FALSE, /* int set; */ FALSE, /* int needsfreeing; */ 0, /* int eventlevels; */ NULL, /* XFontStruct *fontstruct; */ /* init proc */ 0, 0, /* int twidth, theight; */ XtjustifyCenter, /* text justification */ Dummy, /* void (*Proc) (); */ NULL, /* caddr_t tag; */ NULL, /* unsigned long reason; */ NULL, /* XtEventsPtr eventTable; */ /* init proc */ NULL, /* caddr_t state; */ }; /* Private Data */ static Resource resources[] = { {XtNwindow, XtCWindow, XtRWindow, sizeof(Window), (caddr_t)&globaldata.mywin, (caddr_t)NULL}, {XtNx, XtCX, XtRInt, sizeof(int), (caddr_t)&globaldata.x, (caddr_t)NULL}, {XtNy, XtCY, XtRInt, sizeof(int), (caddr_t)&globaldata.y, (caddr_t)NULL}, {XtNborderWidth, XtCBorderWidth, XtRInt, sizeof(int), (caddr_t)&globaldata.borderWidth, (caddr_t)NULL}, {XtNwidth, XtCWidth, XtRInt, sizeof(int), (caddr_t)&globaldata.width, (caddr_t)NULL}, {XtNheight, XtCHeight, XtRInt, sizeof(int), (caddr_t)&globaldata.height, (caddr_t)NULL}, {XtNinternalWidth, XtCWidth, XtRInt, sizeof(int), (caddr_t)&globaldata.ibw, (caddr_t)NULL}, {XtNinternalHeight, XtCHeight, XtRInt, sizeof(int), (caddr_t)&globaldata.ibh, (caddr_t)NULL}, {XtNlabel, XtCLabel, XtRString, sizeof(char *), (caddr_t)&globaldata.text, (caddr_t)NULL}, {XtNforeground, XtCColor, XtRPixel, sizeof(int), (caddr_t)&globaldata.fgpixel, (caddr_t)&XtDefaultFGPixel}, {XtNbackground, XtCColor, XtRPixel, sizeof(int), (caddr_t)&globaldata.bgpixel, (caddr_t)&XtDefaultBGPixel}, {XtNborder, XtCColor, XtRPixmap, sizeof(Pixmap), (caddr_t)&globaldata.brpixmap, (caddr_t)&XtDefaultFGPixmap}, {XtNfont, XtCFont, XtRFontInfo, sizeof(FontInfo *), (caddr_t)&globaldata.fontinfo, (caddr_t)NULL}, {XtNjustify, XtCJustify, XtRJustify, sizeof(XtJustify), (caddr_t)&globaldata.justify, (caddr_t)NULL}, {XtNfunction, XtCFunction, XtRFunction, sizeof(CommandProc), (caddr_t)&globaldata.proc, (caddr_t)NULL}, {XtNparameter, XtCParameter, XtRPointer, sizeof(caddr_t), (caddr_t)&globaldata.tag, (caddr_t)NULL}, {XtNreason, XtCReason, XtRLong, sizeof(long), (caddr_t)&globaldata.reason, (caddr_t)NULL}, {XtNsensitive, XtCBoolean, XtRBoolean, sizeof(Boolean), (caddr_t)&globaldata.enabled, NULL}, {XtNeventBindings, XtCEventBindings, XtREventBindings, sizeof(caddr_t), (caddr_t)&globaldata.eventTable, NULL}, }; static char *defaultEventBindings[] = { "<BtnDown>left: set\n", "<BtnUp>left: notify unset\n", "<EnterWindow>: highlight\n", "<LeaveWindow>: unhighlight unset\n", NULL }; static int stipplew = 16; static int stippleh = 16; static unsigned short stippledata[] = { 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555, 0xaaaa, 0x5555 }; static Bitmap stipplemap; /**************************************************************** * * Private Procedures * ****************************************************************/ static Boolean initialized = FALSE; /* initialization flag */ static void CommandInitialize () { if (initialized) return; initialized = TRUE; commandContext = XtUniqueContext(); globalinit.fontinfo = XOpenFont("helv10b"); globalinit.eventTable = XtParseEventBindings(defaultEventBindings); stipplemap = XStoreBitmap (stipplew, stippleh, stippledata); } /*ARGSUSED*/ static void Dummy(p) /* default call back proc */ caddr_t p; { (void) printf("dummy call back for Command\n"); } static void Ignore() {} static WidgetData CommandDataFromWindow(w) Window w; { WidgetData result; if (XtFindContext(w, commandContext, (caddr_t *)&result)) return NULL; return result; } /* * * Repaint the widget window * */ static void Redisplay(data) WidgetData data; { int textx, texty; Window w = data->mywin; /* * Calculate Text x,y given window width and text width * to the specified justification */ if (data->needsfreeing) return; if (data->justify == XtjustifyLeft) textx = 2; else if (data->justify == XtjustifyRight) textx = data->width - data->twidth - 2; else textx = ((data->width - data->twidth) / 2); if (textx < 0) textx = 0; texty = (data->height - data->theight) / 2; XPixSet ( w, 0, 0, data->width, data->height, ((data->highlighted || data->set) ? data->fgpixel : data->bgpixel)); if (data->highlighted && !data->set) XPixSet ( w, data->ibw, data->ibh, data->width-2*data->ibw, data->height-2*data->ibh, data->bgpixel); XTextMask( w, textx, texty, data->text, strlen (data->text), data->fontinfo->id, (data->set ? data->bgpixel : data->fgpixel)); if (!data->enabled) XStippleFill (w, textx, texty, data->twidth, data->theight, data->bgpixel, stipplemap, GXcopy, AllPlanes); } extern void Destroy(); /* * * Generic widget event handler * */ static XtEventReturnCode EventHandler(event, eventdata) XEvent *event; caddr_t eventdata; { WidgetData data = (WidgetData) eventdata; XtActionTokenPtr actionList; CommandProc proc; data->eventlevels++; switch (event->type) { case ResizeWindow: data->height = ((XExposeEvent *)event)->height; data->width = ((XExposeEvent *)event)->width; break; case DestroyWindow: Destroy(data); break; case ExposeWindow: Redisplay(data); break; default: if (!data->enabled) break; actionList = (XtActionTokenPtr) XtTranslateEvent(event, data->state); for ( ; actionList != NULL; actionList = actionList->next) { if (actionList->type == XttokenAction) { proc = (CommandProc) XtInterpretAction(data->state,actionList->value.action); (*(proc))(data); } } break; } data->eventlevels--; if (data->needsfreeing && data->eventlevels == 0) { XtClearEventHandlers(data->mywin); XtFree((char *) data); } return (XteventHandled); } /* * * Widget hilight event handler * */ static void Highlight(data) WidgetData data; { data->highlighted = TRUE; Redisplay(data); } /* * * Widget un-hilight event handler * */ static void UnHighlight(data) WidgetData data; { data->highlighted = FALSE; Redisplay(data); } /* * * Widget set event handler * */ static void Set(data) WidgetData data; { data->set = TRUE; Redisplay(data); } /* * * Widget un-set event handler * */ static void UnSet(data) WidgetData data; { data->set = FALSE; Redisplay(data); } /* * * Widget notify event handler * */ static void Notify(data) WidgetData data; { XFlush(); if (data -> highlighted) (*(data->proc))(data->tag, data->reason); } /* * * Destroy the widget; the window's been destroyed already. * */ static void Destroy(data) WidgetData data; { data->needsfreeing = TRUE; XtDeleteContext(data->mywin, commandContext); } /**************************************************************** * * Public Procedures * ****************************************************************/ Window XtCommandCreate(parent, args, argCount) Window parent; ArgList args; int argCount; { WidgetData data; XtNameList names; XtClassList classes; static XtActionsRec actionsTable[] = { {"set", (caddr_t)Set}, {"unset", (caddr_t)UnSet}, {"highlight", (caddr_t)Highlight}, {"unhighlight", (caddr_t)UnHighlight}, {"notify", (caddr_t)Notify}, {NULL, NULL} }; if (!initialized) CommandInitialize (); data = (WidgetData) XtMalloc (sizeof (WidgetDataRec)); /* Set Default Values */ globaldata = globalinit; XtGetResources(resources, XtNumber(resources), args, argCount, parent, "command", "Command", &names, &classes); *data = globaldata; data->state = XtSetActionBindings(data->eventTable, actionsTable, Ignore); if (data->text == NULL) data->text = XtNameToAtom(names[XtNameListLength(names) - 1]); data->text = strcpy( XtMalloc ((unsigned) strlen(data->text) + 1), data->text); /* obtain text dimensions and calculate the window size */ data->twidth = XStringWidth (data->text, data->fontinfo, 0, 0); data->theight = data->fontinfo->height; if (data->width == 0) data->width = data->twidth + 2*data->ibw; if (data->height == 0) data->height = data->theight + 2*data->ibh; if (data->mywin != NULL) { WindowInfo wi; /* set global data from window parameters */ if (! XQueryWindow(data->mywin, &wi)) { data->mywin = NULL; } else { data->borderWidth = wi.bdrwidth; data->width = wi.width; data->height = wi.height; } } if (data->mywin == NULL) { data->mywin = XCreateWindow(parent, data->x, data->y, data->width, data->height, data->borderWidth, data->brpixmap, XMakeTile(data->bgpixel)); } XtSetNameAndClass(data->mywin, names, classes); XtFreeNameList(names); XtFreeClassList(classes); (void) XtSaveContext(data->mywin, commandContext, (caddr_t)data); /* set window according to args */ XtCommandSetValues(data->mywin, args, argCount); /* set handler for expose, resize, and message events */ /* HACK -- translation mgr should somehow do the event selection, not us! */ XtSetEventHandler (data->mywin, (XtEventHandler)EventHandler, EnterWindow | LeaveWindow | ButtonReleased | ButtonPressed | ExposeWindow, (caddr_t)data); return (data->mywin); } /* * * Get Attributes * */ void XtCommandGetValues (w, args, argCount) Window w; ArgList args; int argCount; { WidgetData data; if ((data = CommandDataFromWindow(w)) == NULL) return; globaldata = *data; XtGetValues(resources, XtNumber(resources), args, argCount); } /* * * Set Attributes * */ void XtCommandSetValues (w, args, argCount) Window w; ArgList args; int argCount; { WidgetData data; if ((data = CommandDataFromWindow(w)) == NULL) return; globaldata = *data; XtSetValues(resources, XtNumber(resources), args, argCount); if (strcmp (data->text, globaldata.text) || data->fontinfo != globaldata.fontinfo) { XtGeometryReturnCode reply; WindowBox reqbox, replybox; globaldata.text = strcpy( XtMalloc ((unsigned) strlen(globaldata.text) + 1), globaldata.text); XtFree ((char *) data->text); /* obtain text dimensions and calculate the window size */ globaldata.twidth = XStringWidth (globaldata.text, globaldata.fontinfo, 0, 0); globaldata.theight = globaldata.fontinfo->height; reqbox.width = globaldata.twidth + 2*globaldata.ibw; reqbox.height = globaldata.theight + 2*globaldata.ibh; reply = XtMakeGeometryRequest(globaldata.mywin, geometryRESIZE, &reqbox, &replybox); if (reply == XtgeometryAlmost) { reqbox = replybox; (void) XtMakeGeometryRequest(globaldata.mywin, geometryRESIZE, &reqbox, &replybox); } } *data = globaldata; if (!data->enabled) data->set = data->highlighted = FALSE; Redisplay (data); }