/* * Copyright (c) 1993-1997, Silicon Graphics, Inc. * ALL RIGHTS RESERVED * Permission to use, copy, modify, and distribute this software for * any purpose and without fee is hereby granted, provided that the above * copyright notice appear in all copies and that both the copyright notice * and this permission notice appear in supporting documentation, and that * the name of Silicon Graphics, Inc. not be used in advertising * or publicity pertaining to distribution of the software without specific, * written prior permission. * * THE MATERIAL EMBODIED ON THIS SOFTWARE IS PROVIDED TO YOU "AS-IS" * AND WITHOUT WARRANTY OF ANY KIND, EXPRESS, IMPLIED OR OTHERWISE, * INCLUDING WITHOUT LIMITATION, ANY WARRANTY OF MERCHANTABILITY OR * FITNESS FOR A PARTICULAR PURPOSE. IN NO EVENT SHALL SILICON * GRAPHICS, INC. BE LIABLE TO YOU OR ANYONE ELSE FOR ANY DIRECT, * SPECIAL, INCIDENTAL, INDIRECT OR CONSEQUENTIAL DAMAGES OF ANY * KIND, OR ANY DAMAGES WHATSOEVER, INCLUDING WITHOUT LIMITATION, * LOSS OF PROFIT, LOSS OF USE, SAVINGS OR REVENUE, OR THE CLAIMS OF * THIRD PARTIES, WHETHER OR NOT SILICON GRAPHICS, INC. HAS BEEN * ADVISED OF THE POSSIBILITY OF SUCH LOSS, HOWEVER CAUSED AND ON * ANY THEORY OF LIABILITY, ARISING OUT OF OR IN CONNECTION WITH THE * POSSESSION, USE OR PERFORMANCE OF THIS SOFTWARE. * * US Government Users Restricted Rights * Use, duplication, or disclosure by the Government is subject to * restrictions set forth in FAR 52.227.19(c)(2) or subparagraph * (c)(1)(ii) of the Rights in Technical Data and Computer Software * clause at DFARS 252.227-7013 and/or in similar or successor * clauses in the FAR or the DOD or NASA FAR Supplement. * Unpublished-- rights reserved under the copyright laws of the * United States. Contractor/manufacturer is Silicon Graphics, * Inc., 2011 N. Shoreline Blvd., Mountain View, CA 94039-7311. * * OpenGL(R) is a registered trademark of Silicon Graphics, Inc. */ #include #include #include #include extern int activemenu; extern int menuinuse; static muiObject *newmuiobj(void) { muiObject *newobj = (muiObject *)malloc(sizeof(muiObject)); newobj->active = 0; newobj->enable = 1; newobj->select = 0; newobj->locate = 0; newobj->visible = 1; newobj->callback = 0; muiSetUIList(newobj, muiGetActiveUIList()); muiAddToUIList(muiGetActiveUIList(), newobj); newobj->id = 0; return newobj; } muiObject *muiNewPulldown(void) { muiObject *newPD = newmuiobj(); newPD->type = MUI_PULLDOWN; newPD->xmin = 0; newPD->ymin = glutGet(GLUT_WINDOW_HEIGHT) - PULLDOWN_HEIGHT; newPD->xmax = glutGet(GLUT_WINDOW_WIDTH); newPD->ymax = glutGet(GLUT_WINDOW_HEIGHT); newPD->object = (void *)newpd(); newPD->handler = pdhandler; return newPD; } muiObject *muiNewButton(int xmin, int xmax, int ymin, int ymax) { muiObject *newb = newmuiobj(); newb->type = MUI_BUTTON; newb->xmin = xmin; newb->ymin = ymin; newb->xmax = xmax; newb->ymax = ymax; newb->object = (void *)newbut(); ((Button *)(newb->object))->object = newb; newb->handler = buttonhandler; return newb; } muiObject *muiNewRadioButton(int xmin, int ymin) { muiObject *newb = newmuiobj(); newb->type = MUI_RADIOBUTTON; newb->xmin = xmin; newb->ymin = ymin; newb->xmax = xmin+ RADIOWIDTH-1; newb->ymax = ymin+RADIOHEIGHT-1; newb->object = (void *)newradiobut(); ((Button *)(newb->object))->object = newb; newb->handler = buttonhandler; return newb; } muiObject *muiNewTinyRadioButton(int xmin, int ymin) { muiObject *newb = newmuiobj(); newb->type = MUI_TINYRADIOBUTTON; newb->xmin = xmin; newb->ymin = ymin; newb->xmax = xmin+ TINYRADIOWIDTH-1; newb->ymax = ymin+ TINYRADIOHEIGHT-1; newb->object = (void *)newradiobut(); ((Button *)(newb->object))->object = newb; newb->handler = buttonhandler; return newb; } muiObject *muiNewVSlider(int xmin, int ymin, int ymax, int scenter, int shalf) { muiObject *newvsl = newmuiobj(); newvsl->type = MUI_VSLIDER; newvsl->xmin = xmin; newvsl->ymin = ymin; newvsl->xmax = xmin+SLIDERWIDTH-1; newvsl->ymax = ymax; newvsl->object = (void *)newvs(newvsl, ymin, ymax, scenter, shalf); newvsl->handler = vshandler; return newvsl; } muiObject *muiNewHSlider(int xmin, int ymin, int xmax, int scenter, int shalf) { muiObject *newhsl = newmuiobj(); newhsl->type = MUI_HSLIDER; newhsl->xmin = xmin; newhsl->ymin = ymin; newhsl->xmax = xmax; newhsl->ymax = ymin+SLIDERWIDTH-1; newhsl->object = (void *)newhs(newhsl, xmin, xmax, scenter, shalf); newhsl->handler = hshandler; return newhsl; } muiObject *muiNewTextList(int xmin, int ymin, int xmax, int listheight) { muiObject *newtlo = newmuiobj(); newtlo->type = MUI_TEXTLIST; newtlo->xmin = xmin; newtlo->ymin = ymin; newtlo->xmax = xmax; newtlo->object = (void *)newtl(newtlo, listheight); newtlo->handler = tlhandler; return newtlo; } muiObject *muiNewLabel(int xmin, int ymin, char *label) { muiObject *newlbl = newmuiobj(); newlbl->type = MUI_LABEL; newlbl->xmin = xmin; newlbl->ymin = ymin; /* XXX maximums */ newlbl->object = (void *)newlabel(label); newlbl->handler = nullhandler; return newlbl; } muiObject *muiNewBoldLabel(int xmin, int ymin, char *label) { muiObject *newlbl = newmuiobj(); newlbl->type = MUI_BOLDLABEL; newlbl->xmin = xmin; newlbl->ymin = ymin; /* XXX maximums */ newlbl->object = (void *)newlabel(label); newlbl->handler = nullhandler; return newlbl; } muiObject *muiNewTextbox(int xmin, int xmax, int ymin) { muiObject *newtextbox = newmuiobj(); newtextbox->type = MUI_TEXTBOX; newtextbox->xmin = xmin; newtextbox->ymin = ymin; newtextbox->xmax = xmax; newtextbox->ymax = ymin + TEXTBOXHEIGHT - 1; newtextbox->object = (void *)newtb(xmin, xmax); newtextbox->handler = textboxhandler; return newtextbox; } void muiGetObjectSize(muiObject *obj, int *xmin, int *ymin, int *xmax, int *ymax) { *xmin = obj->xmin; *xmax = obj->xmax; *ymin = obj->ymin; *ymax = obj->ymax; } void muiFreeObject(muiObject *obj) { switch (obj->type) { case MUI_BUTTON: case MUI_RADIOBUTTON: case MUI_TINYRADIOBUTTON: case MUI_VSLIDER: case MUI_HSLIDER: case MUI_TEXTBOX: case MUI_TEXTLIST: case MUI_PULLDOWN: free(obj->object); break; case MUI_LABEL: case MUI_BOLDLABEL: break; } free(obj); } void muiSetID(muiObject *obj, int id) { obj->id = id; } int muiGetID(muiObject *obj) { return obj->id; } void muiSetCallback(muiObject *obj, void (*callback)(muiObject *, enum muiReturnValue)) { obj->callback = callback; } int muiInObject(muiObject *obj, int x, int y) { if (obj->xmin <= x && x <= obj->xmax && obj->ymin <= y && y <= obj->ymax) return 1; return 0; } int muiGetLocate(muiObject *obj) { return obj->locate; } void muiSetLocate(muiObject *obj, int state) { obj->locate = (short) state; } int muiGetSelect(muiObject *obj) { return obj->select; } void muiSetUIList(muiObject *obj, int list) { obj->uilist = list; } int muiGetUIList(muiObject *obj) { return obj->uilist; } void muiSetSelect(muiObject *obj, int state) { obj->select = (short) state; } int muiGetVisible(muiObject *obj) { return obj->visible; } void muiSetVisible(muiObject *obj, int state) { obj->visible = (short) state; } int muiGetActive(muiObject *obj) { return obj->active; } void muiSetActive(muiObject *obj, int state) { obj->active = (short) state; } int muiGetEnable(muiObject *obj) { return obj->enable; } void muiSetEnable(muiObject *obj, int state) { obj->enable = (short) state; } void muiDrawObject(muiObject *obj) { switch (obj->type) { case MUI_BUTTON: drawbut(obj); break; case MUI_RADIOBUTTON: drawradiobutton(obj); break; case MUI_TINYRADIOBUTTON: drawtinyradio(obj); break; case MUI_LABEL: drawlabel(obj); break; case MUI_BOLDLABEL: drawboldlabel(obj); break; case MUI_TEXTBOX: drawtb(obj); break; case MUI_VSLIDER: drawvs(obj); break; case MUI_HSLIDER: drawhs(obj); break; case MUI_TEXTLIST: drawtl(obj); break; case MUI_PULLDOWN: drawpulldown(obj); break; } } void muiError(char *s) { fprintf(stderr, "%s\n", s); exit(0); } #define MAX_UI_LISTS 50 static muiCons *muilist[MAX_UI_LISTS]; static int muilistindex[MAX_UI_LISTS]; void muiNewUIList(int listid) { static int inited = 0; int i; if (inited == 0) { inited = 1; for (i = 1; i < MAX_UI_LISTS; i++) muilistindex[i] = -1; muilistindex[0] = listid; muiSetActiveUIList(listid); return; } for (i = 0; i < MAX_UI_LISTS; i++) if (muilistindex[i] == -1) { muilistindex[i] = listid; muiSetActiveUIList(listid); return; } muiError("muiNewUIList: No more UI lists available"); } int muiGetListId(int uilist) { int i; for (i = 0; i < MAX_UI_LISTS; i++) { if (muilistindex[i] == uilist) return i; } muiError("muiAddToUIList: illegal UI list identifier"); return -1; } muiCons *muiGetListCons(int uilist) { int i; for (i = 0; i < MAX_UI_LISTS; i++) { if (muilistindex[i] == uilist) return muilist[i]; } muiError("muiGetListCons: illegal UI list identifier"); return (muiCons *)0; } void muiAddToUIList(int uilist, muiObject *obj) { int i; muiCons *mcons; if (uilist == 0) { muiError("muiAddToUIList: no active UI list"); } if ((i = muiGetListId(uilist)) == -1) return; mcons = (muiCons *)malloc(sizeof(muiCons)); mcons->next = muilist[i]; muilist[i] = mcons; mcons->object = obj; } static muiObject *muiFastHitInList(muiCons *mcons, int x, int y) { while (mcons) { if (muiInObject(mcons->object, x, y)) switch (mcons->object->type) { case MUI_BUTTON: case MUI_TEXTBOX: case MUI_VSLIDER: case MUI_HSLIDER: case MUI_TEXTLIST: case MUI_RADIOBUTTON: case MUI_TINYRADIOBUTTON: case MUI_PULLDOWN: return mcons->object; case MUI_LABEL: case MUI_BOLDLABEL: return 0; } mcons = mcons->next; } return (muiObject *)0; /* not found */ } muiObject *muiHitInList(int uilist, int x, int y) { muiCons *mcons; if ((mcons = muiGetListCons(uilist)) == (muiCons *)0) return (muiObject *)0; return muiFastHitInList(mcons, x, y); } void muiDrawUIList(int uilist) { muiCons *mcons; if ((mcons = muiGetListCons(uilist)) == (muiCons *)0) return; muiBackgroundClear(); while (mcons) { muiDrawObject(mcons->object); mcons = mcons->next; } } static muiObject *SelectedObj, *LocatedObj; static muiCons *ActiveCons; static int ActiveUIList = 0; static muiObject *ActiveSlider = 0; void muiSetActiveUIList(int i) { ActiveUIList = i; } int muiGetActiveUIList(void) { return ActiveUIList; } static void muiInitInteraction(int uilist) { muiCons *mcons; muiObject *obj; if ((mcons = muiGetListCons(uilist)) == (muiCons *)0) return; SelectedObj = LocatedObj = (muiObject *)0; ActiveCons = mcons; ActiveUIList = uilist; while (mcons) { obj = mcons->object; muiSetSelect(obj, 0); muiSetLocate(obj, 0); mcons = mcons->next; } } static void (*noncallback)(int, int) = 0; static void nonmuicallback(int x, int y) { if (noncallback == 0) return; noncallback(x, y); } void muiSetNonMUIcallback(void (*nc)(int, int)) { noncallback = nc; } void muiHandleEvent(int event, int value, int x, int y) { muiObject *obj; static int lastactive = 0; enum muiReturnValue retval; if (ActiveUIList == 0) { muiError("muiHandleEvent: no active UI list"); } if (lastactive != ActiveUIList) { muiInitInteraction(lastactive = ActiveUIList); } if ((event == MUI_KEYSTROKE)) { if (obj = muiGetActiveTB()) { retval = (obj->handler)(obj, event, value, x, y); if (retval && obj->callback) (obj->callback)(obj, retval); return; } /* may have to add text editors, et cetera */ return; } if (event == MUI_DEVICE_RELEASE && ActiveSlider) { retval = (ActiveSlider->handler)(ActiveSlider, event, value, x, y); if (retval && ActiveSlider->callback) (ActiveSlider->callback)(ActiveSlider, retval); ActiveSlider = 0; return; } ActiveCons = muiGetListCons(ActiveUIList); obj = muiFastHitInList(ActiveCons, x, y); if (obj == 0 && event == MUI_DEVICE_PRESS) { nonmuicallback(x, y); return; } if (event == MUI_DEVICE_UP && (!menuinuse) && (activemenu != -1) && (obj == 0 || obj->type != MUI_PULLDOWN)) { activemenu = -1; glutDetachMenu(GLUT_LEFT_BUTTON); } if (obj && (obj->type == MUI_VSLIDER || obj->type == MUI_HSLIDER) && event == MUI_DEVICE_PRESS) ActiveSlider = obj; if (obj == 0) { if (ActiveSlider) { retval = (ActiveSlider->handler)(ActiveSlider, event, value, x, y); if (retval && ActiveSlider->callback) (ActiveSlider->callback)(ActiveSlider, retval); return; } if (LocatedObj) { muiSetLocate(LocatedObj, 0); muiDrawObject(LocatedObj); LocatedObj = 0; } if ((event == MUI_DEVICE_RELEASE) && SelectedObj) { muiSetSelect(SelectedObj, 0); muiSetLocate(SelectedObj, 0); muiDrawObject(SelectedObj); LocatedObj = SelectedObj = 0; } return; } retval = (obj->handler)(obj, event, value, x, y); if (retval && obj->callback) (obj->callback)(obj, retval); return; } /* ARGSUSED2 */ enum muiReturnValue buttonhandler(muiObject *obj, int event, int value, int x, int y) { if (!muiGetEnable(obj) || !muiGetVisible(obj)) return MUI_NO_ACTION; switch (event) { case MUI_DEVICE_DOWN: return MUI_NO_ACTION; case MUI_DEVICE_UP: if (LocatedObj != obj) { if (LocatedObj) { muiSetLocate(LocatedObj, 0); muiDrawObject(LocatedObj); } muiSetLocate(obj, 1); muiDrawObject(obj); LocatedObj = obj; } return MUI_NO_ACTION; case MUI_DEVICE_PRESS: muiSetSelect(obj, 1); muiSetLocate(obj, 1); SelectedObj = LocatedObj = obj; muiDrawObject(obj); return MUI_NO_ACTION; case MUI_DEVICE_RELEASE: if (SelectedObj != obj) { muiSetSelect(SelectedObj, 0); muiSetLocate(SelectedObj, 0); muiDrawObject(SelectedObj); muiSetLocate(obj, 1); LocatedObj = obj; muiDrawObject(obj); return MUI_NO_ACTION; } if (obj->type == MUI_RADIOBUTTON || obj->type == MUI_TINYRADIOBUTTON) { Button *b = (Button *)obj->object, *b1; if (b->link) { muiSetActive(obj, 1); b1 = b->link; while (b1 != b) { muiSetActive(b1->object, 0); b1 = b1->link; } } else { muiSetActive(obj, ( muiGetActive(obj) ? 0 : 1 ) ); } } muiSetSelect(obj, 0); muiDrawObject(obj); return MUI_BUTTON_PRESS; case MUI_DEVICE_CLICK: muiSetSelect(obj, 0); muiSetLocate(obj, 1); LocatedObj = obj; muiDrawObject(obj); return MUI_BUTTON_PRESS; case MUI_DEVICE_DOUBLE_CLICK: muiSetSelect(obj, 0); muiSetLocate(obj, 1); LocatedObj = obj; muiDrawObject(obj); return MUI_BUTTON_PRESS; /* XXX this may not be right; */ case MUI_KEYSTROKE: return MUI_NO_ACTION; default: muiError("buttonhandler: wacko event"); return MUI_NO_ACTION; } } /* ARGSUSED */ enum muiReturnValue nullhandler(muiObject *obj, int event, int value, int x, int y) { return MUI_NO_ACTION; }