Skip to content

AFNI/NIfTI Server

Sections
Personal tools
You are here: Home » AFNI » Documentation

Doxygen Source Code Documentation


Main Page   Alphabetical List   Data Structures   File List   Data Fields   Globals   Search  

glut_menu.c File Reference

#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <unistd.h>
#include <assert.h>
#include <X11/Xlib.h>
#include <X11/cursorfont.h>
#include <GL/glut.h>
#include "glutint.h"
#include "layerutil.h"

Go to the source code of this file.


Defines

#define MENU_BORDER   1
#define MENU_GAP   2
#define MENU_ARROW_GAP   6
#define MENU_ARROW_WIDTH   8

Functions

void noFaultXAllocColor (Display *dpy, Colormap cmap, int cmapSize, XColor *color)
void menuVisualSetup (void)
void menuSetup (void)
void menuGraphicsContextSetup (Window win)
void glutMenuStateFunc (GLUTmenuStateCB menuStateFunc)
void glutMenuStatusFunc (GLUTmenuStatusCB menuStatusFunc)
void __glutSetMenu (GLUTmenu *menu)
void unmapMenu (GLUTmenu *menu)
void __glutFinishMenu (Window win, int x, int y)
void mapMenu (GLUTmenu *menu, int x, int y)
void __glutStartMenu (GLUTmenu *menu, GLUTwindow *window, int x, int y, int x_win, int y_win)
void paintSubMenuArrow (Window win, int x, int y)
void paintMenuItem (GLUTmenuItem *item, int num)
void __glutPaintMenu (GLUTmenu *menu)
GLUTmenuItem__glutGetMenuItem (GLUTmenu *menu, Window win, int *which)
int getMenuItemIndex (GLUTmenuItem *item)
GLUTmenu__glutGetMenu (Window win)
GLUTmenu__glutGetMenuByNum (int menunum)
int getUnusedMenuSlot (void)
void menuModificationError (void)
int glutCreateMenu (GLUTselectCB selectFunc)
void glutDestroyMenu (int menunum)
int glutGetMenu (void)
void glutSetMenu (int menuid)
void setMenuItem (GLUTmenuItem *item, char *label, int value, Bool isTrigger)
void glutAddMenuEntry (char *label, int value)
void glutAddSubMenu (char *label, int menu)
void glutChangeToMenuEntry (int num, char *label, int value)
void glutChangeToSubMenu (int num, char *label, int menu)
void glutRemoveMenuItem (int num)
void glutAttachMenu (int button)
void glutDetachMenu (int button)
void __glutMenuItemEnterOrLeave (GLUTmenuItem *item, int num, int type)

Variables

GLUTmenu__glutCurrentMenu = NULL
void(* __glutMenuStatusFunc )(int, int, int)
GLUTmenu__glutMappedMenu
GLUTwindow__glutMenuWindow
GLUTmenuItem__glutItemSelected
GLUTmenu ** menuList = NULL
int menuListSize = 0
XFontStruct * menuFont = NULL
Cursor menuCursor
Colormap menuColormap
Visual * menuVisual
int menuDepth
int fontHeight
GC blackGC
GC grayGC
GC whiteGC
unsigned long menuBlack
unsigned long menuWhite
unsigned long menuGray
unsigned long useSaveUnders

Define Documentation

#define MENU_ARROW_GAP   6
 

Definition at line 326 of file glut_menu.c.

Referenced by __glutMenuItemEnterOrLeave(), __glutPaintMenu(), mapMenu(), and paintMenuItem().

#define MENU_ARROW_WIDTH   8
 

Definition at line 327 of file glut_menu.c.

Referenced by __glutMenuItemEnterOrLeave(), mapMenu(), paintMenuItem(), and paintSubMenuArrow().

#define MENU_BORDER   1
 

Definition at line 324 of file glut_menu.c.

Referenced by __glutMenuItemEnterOrLeave(), and glutCreateMenu().

#define MENU_GAP   2
 

Definition at line 325 of file glut_menu.c.

Referenced by __glutMenuItemEnterOrLeave(), __glutPaintMenu(), glutAddMenuEntry(), glutAddSubMenu(), mapMenu(), and paintMenuItem().


Function Documentation

void __glutFinishMenu Window    win,
int    x,
int    y
 

Definition at line 271 of file glut_menu.c.

References __glutMenuStatusFunc, __glutSetMenu(), __glutSetWindow(), dummy, GLUT_MENU_NOT_IN_USE, _GLUTmenuItem::isTrigger, _GLUTmenuItem::menu, _GLUTmenu::select, unmapMenu(), _GLUTmenuItem::value, win, and _GLUTwindow::win.

Referenced by processEvents().

00272 {
00273   Window dummy;
00274   int rc;
00275 
00276   unmapMenu(__glutMappedMenu);
00277   XUngrabPointer(__glutDisplay, CurrentTime);
00278 
00279   /* This XFlush is needed to to make sure the pointer is
00280      really ungrabbed when the application's menu callback is
00281      called. Otherwise, a deadlock might happen because the
00282      application may try to read from an terminal window, but
00283      yet the ungrab hasn't really happened since it hasn't been
00284      flushed out. */
00285   XFlush(__glutDisplay);
00286 
00287   if (__glutMenuStatusFunc) {
00288     if (win != __glutMenuWindow->win) {
00289       /* The button release may have occurred in a window other
00290          than the window requesting the pop-up menu (for
00291          example, one of the submenu windows).  In this case, we
00292          need to translate the coordinates into the coordinate
00293          system of the window associated with the window. */
00294       rc = XTranslateCoordinates(__glutDisplay, win, __glutMenuWindow->win,
00295         x, y, &x, &y, &dummy);
00296       assert(rc != False);  /* Will always be on same screen. */
00297     }
00298     __glutSetWindow(__glutMenuWindow);
00299     __glutSetMenu(__glutMappedMenu);
00300 
00301     /* Setting __glutMappedMenu to NULL permits operations that
00302        change menus or destroy the menu window again. */
00303     __glutMappedMenu = NULL;
00304 
00305     __glutMenuStatusFunc(GLUT_MENU_NOT_IN_USE, x, y);
00306   }
00307   /* Setting __glutMappedMenu to NULL permits operations that
00308      change menus or destroy the menu window again. */
00309   __glutMappedMenu = NULL;
00310 
00311   /* If an item is selected and it is not a submenu trigger,
00312      generate menu callback. */
00313   if (__glutItemSelected && !__glutItemSelected->isTrigger) {
00314     __glutSetWindow(__glutMenuWindow);
00315     /* When menu callback is triggered, current menu should be
00316        set to the callback menu. */
00317     __glutSetMenu(__glutItemSelected->menu);
00318     __glutItemSelected->menu->select(
00319       __glutItemSelected->value);
00320   }
00321   __glutMenuWindow = NULL;
00322 }

GLUTmenu* __glutGetMenu Window    win
 

Definition at line 545 of file glut_menu.c.

References _GLUTmenu::cascade, win, and _GLUTmenu::win.

Referenced by processEvents().

00546 {
00547   GLUTmenu *menu;
00548 
00549   menu = __glutMappedMenu;
00550   while (menu) {
00551     if (win == menu->win) {
00552       return menu;
00553     }
00554     menu = menu->cascade;
00555   }
00556   return NULL;
00557 }

GLUTmenu* __glutGetMenuByNum int    menunum
 

Definition at line 560 of file glut_menu.c.

References menuListSize.

Referenced by glutDestroyMenu(), and processEvents().

00561 {
00562   if (menunum < 1 || menunum > menuListSize) {
00563     return NULL;
00564   }
00565   return menuList[menunum - 1];
00566 }

GLUTmenuItem* __glutGetMenuItem GLUTmenu   menu,
Window    win,
int *    which
 

Definition at line 505 of file glut_menu.c.

References i, _GLUTmenuItem::isTrigger, _GLUTmenu::list, _GLUTmenuItem::next, _GLUTmenu::num, _GLUTmenuItem::value, win, and _GLUTmenuItem::win.

Referenced by processEvents().

00506 {
00507   GLUTmenuItem *item;
00508   int i;
00509 
00510   i = menu->num;
00511   item = menu->list;
00512   while (item) {
00513     if (item->win == win) {
00514       *which = i;
00515       return item;
00516     }
00517     if (item->isTrigger) {
00518       GLUTmenuItem *subitem;
00519 
00520       subitem = __glutGetMenuItem(menuList[item->value],
00521         win, which);
00522       if (subitem) {
00523         return subitem;
00524       }
00525     }
00526     i--;
00527     item = item->next;
00528   }
00529   return NULL;
00530 }

void __glutMenuItemEnterOrLeave GLUTmenuItem   item,
int    num,
int    type
 

Definition at line 914 of file glut_menu.c.

References _GLUTmenu::anchor, _GLUTmenu::cascade, fontHeight, getMenuItemIndex(), _GLUTmenu::highlighted, _GLUTmenuItem::isTrigger, mapMenu(), _GLUTmenuItem::menu, MENU_ARROW_GAP, MENU_ARROW_WIDTH, MENU_BORDER, MENU_GAP, paintMenuItem(), _GLUTmenu::pixwidth, unmapMenu(), _GLUTmenuItem::value, _GLUTmenu::x, and _GLUTmenu::y.

Referenced by processEvents().

00916 {
00917   int alreadyUp = 0;
00918 
00919   if (type == EnterNotify) {
00920     GLUTmenuItem *prevItem = item->menu->highlighted;
00921 
00922     if (prevItem && prevItem != item) {
00923       /* If there's an already higlighted item in this menu
00924          that is different from this one (we could be
00925          re-entering an item with an already cascaded
00926          submenu!), unhighlight the previous item. */
00927       item->menu->highlighted = NULL;
00928       paintMenuItem(prevItem, getMenuItemIndex(prevItem));
00929     }
00930     item->menu->highlighted = item;
00931     __glutItemSelected = item;
00932     if (item->menu->cascade) {
00933       if (!item->isTrigger) {
00934         /* Entered a menu item that is not a submenu trigger,
00935            so pop down the current submenu cascade of this
00936            menu.  */
00937         unmapMenu(item->menu->cascade);
00938         item->menu->cascade = NULL;
00939       } else {
00940         GLUTmenu *submenu = menuList[item->value];
00941 
00942         if (submenu->anchor == item) {
00943           /* We entered the submenu trigger for the submenu
00944              that is already up, so don't take down the
00945              submenu.  */
00946           alreadyUp = 1;
00947         } else {
00948           /* Submenu already popped up for some other submenu
00949              item of this menu; need to pop down that other
00950              submenu cascade.  */
00951           unmapMenu(item->menu->cascade);
00952           item->menu->cascade = NULL;
00953         }
00954       }
00955     }
00956     if (!alreadyUp) {
00957       /* Make sure the menu item gets painted with
00958          highlighting. */
00959       paintMenuItem(item, num);
00960     } else {
00961       /* If already up, should already be highlighted.  */
00962     }
00963   } else {
00964     /* LeaveNotify: Handle leaving a menu item...  */
00965     if (item->menu->cascade &&
00966       item->menu->cascade->anchor == item) {
00967       /* If there is a submenu casacaded from this item, do not
00968          change the highlighting on this item upon leaving. */
00969     } else {
00970       /* Unhighlight this menu item.  */
00971       item->menu->highlighted = NULL;
00972       paintMenuItem(item, num);
00973     }
00974     __glutItemSelected = NULL;
00975   }
00976   if (item->isTrigger) {
00977     if (type == EnterNotify && !alreadyUp) {
00978       GLUTmenu *submenu = menuList[item->value];
00979 
00980       mapMenu(submenu,
00981         item->menu->x + item->menu->pixwidth +
00982         MENU_ARROW_GAP + MENU_ARROW_WIDTH +
00983         MENU_GAP + MENU_BORDER,
00984         item->menu->y + fontHeight * (num - 1) + MENU_GAP);
00985       item->menu->cascade = submenu;
00986       submenu->anchor = item;
00987     }
00988   }
00989 }

void __glutPaintMenu GLUTmenu   menu
 

Definition at line 478 of file glut_menu.c.

References blackGC, fontHeight, _GLUTmenu::highlighted, i, _GLUTmenuItem::isTrigger, _GLUTmenuItem::label, _GLUTmenuItem::len, _GLUTmenu::list, _GLUTmenuItem::menu, MENU_ARROW_GAP, MENU_GAP, menuFont, _GLUTmenuItem::next, _GLUTmenu::num, paintMenuItem(), paintSubMenuArrow(), _GLUTmenu::pixwidth, and _GLUTmenu::win.

Referenced by processEvents().

00479 {
00480   GLUTmenuItem *item;
00481   int i = menu->num;
00482   int y = MENU_GAP + fontHeight * i - menuFont->descent;
00483 
00484   item = menu->list;
00485   while (item) {
00486     if (item->menu->highlighted == item) {
00487       paintMenuItem(item, i);
00488     } else {
00489       /* quick render of the menu item; assume background
00490          already cleared to gray */
00491       XDrawString(__glutDisplay, menu->win, blackGC,
00492         2, y, item->label, item->len);
00493       if (item->isTrigger) {
00494         paintSubMenuArrow(menu->win,
00495           menu->pixwidth + MENU_ARROW_GAP + 1, y);
00496       }
00497     }
00498     i--;
00499     y -= fontHeight;
00500     item = item->next;
00501   }
00502 }

void __glutSetMenu GLUTmenu   menu
 

Definition at line 253 of file glut_menu.c.

Referenced by __glutFinishMenu(), __glutStartMenu(), glutCreateMenu(), and glutSetMenu().

00254 {
00255   __glutCurrentMenu = menu;
00256 }

void __glutStartMenu GLUTmenu   menu,
GLUTwindow   window,
int    x,
int    y,
int    x_win,
int    y_win
 

Definition at line 403 of file glut_menu.c.

References __glutMenuStatusFunc, __glutSetMenu(), __glutSetWindow(), GLUT_MENU_IN_USE, mapMenu(), and menuCursor.

Referenced by processEvents().

00405 {
00406   int grab;
00407 
00408   assert(__glutMappedMenu == NULL);
00409   grab = XGrabPointer(__glutDisplay, __glutRoot, True,
00410     ButtonPressMask | ButtonReleaseMask,
00411     GrabModeAsync, GrabModeAsync,
00412     __glutRoot, menuCursor, CurrentTime);
00413   if (grab != GrabSuccess) {
00414     /* Somebody else has pointer grabbed, ignore menu
00415        activation. */
00416     return;
00417   }
00418   __glutMappedMenu = menu;
00419   __glutMenuWindow = window;
00420   __glutItemSelected = NULL;
00421   if (__glutMenuStatusFunc) {
00422     __glutSetMenu(menu);
00423     __glutSetWindow(window);
00424     __glutMenuStatusFunc(GLUT_MENU_IN_USE, x_win, y_win);
00425   }
00426   mapMenu(menu, x, y);
00427 }

int getMenuItemIndex GLUTmenuItem   item [static]
 

Definition at line 533 of file glut_menu.c.

References _GLUTmenuItem::next.

Referenced by __glutMenuItemEnterOrLeave().

00534 {
00535   int count = 0;
00536 
00537   while (item) {
00538     count++;
00539     item = item->next;
00540   }
00541   return count;
00542 }

int getUnusedMenuSlot void    [static]
 

Definition at line 569 of file glut_menu.c.

References __glutFatalError(), i, malloc, menuListSize, and realloc.

Referenced by glutCreateMenu().

00570 {
00571   int i;
00572 
00573   /* Look for allocated, unused slot. */
00574   for (i = 0; i < menuListSize; i++) {
00575     if (!menuList[i]) {
00576       return i;
00577     }
00578   }
00579   /* Allocate a new slot. */
00580   menuListSize++;
00581   if (menuList) {
00582     menuList = (GLUTmenu **)
00583       realloc(menuList, menuListSize * sizeof(GLUTmenu *));
00584   } else {
00585     /* XXX Some realloc's do not correctly perform a malloc
00586        when asked to perform a realloc on a NULL pointer,
00587        though the ANSI C library spec requires this. */
00588     menuList = (GLUTmenu **) malloc(sizeof(GLUTmenu *));
00589   }
00590   if (!menuList)
00591     __glutFatalError("out of memory.");
00592   menuList[menuListSize - 1] = NULL;
00593   return menuListSize - 1;
00594 }

void glutAddMenuEntry char *    label,
int    value
 

Definition at line 730 of file glut_menu.c.

References __glutFatalError(), fontHeight, _GLUTmenu::list, malloc, _GLUTmenuItem::menu, MENU_GAP, menuModificationError(), _GLUTmenuItem::next, _GLUTmenu::num, _GLUTmenuItem::pixwidth, setMenuItem(), _GLUTmenu::win, and _GLUTmenuItem::win.

00731 {
00732   XSetWindowAttributes wa;
00733   GLUTmenuItem *entry;
00734 
00735   if (__glutMappedMenu)
00736     menuModificationError();
00737   entry = (GLUTmenuItem *) malloc(sizeof(GLUTmenuItem));
00738   if (!entry)
00739     __glutFatalError("out of memory.");
00740   entry->menu = __glutCurrentMenu;
00741   setMenuItem(entry, label, value, False);
00742   wa.event_mask = EnterWindowMask | LeaveWindowMask;
00743   entry->win = XCreateWindow(__glutDisplay,
00744     __glutCurrentMenu->win, MENU_GAP,
00745     __glutCurrentMenu->num * fontHeight + MENU_GAP,  /* x & y */
00746     entry->pixwidth, fontHeight,  /* width & height */
00747     0, CopyFromParent, InputOnly, CopyFromParent,
00748     CWEventMask, &wa);
00749   XMapWindow(__glutDisplay, entry->win);
00750   __glutCurrentMenu->num++;
00751   entry->next = __glutCurrentMenu->list;
00752   __glutCurrentMenu->list = entry;
00753 }

void glutAddSubMenu char *    label,
int    menu
 

Definition at line 756 of file glut_menu.c.

References __glutFatalError(), fontHeight, _GLUTmenu::list, malloc, _GLUTmenuItem::menu, MENU_GAP, menuModificationError(), _GLUTmenuItem::next, _GLUTmenu::num, _GLUTmenuItem::pixwidth, setMenuItem(), _GLUTmenu::submenus, _GLUTmenu::win, and _GLUTmenuItem::win.

00757 {
00758   XSetWindowAttributes wa;
00759   GLUTmenuItem *submenu;
00760 
00761   if (__glutMappedMenu)
00762     menuModificationError();
00763   submenu = (GLUTmenuItem *) malloc(sizeof(GLUTmenuItem));
00764   if (!submenu)
00765     __glutFatalError("out of memory.");
00766   __glutCurrentMenu->submenus++;
00767   submenu->menu = __glutCurrentMenu;
00768   setMenuItem(submenu, label, /* base 0 */ menu - 1, True);
00769   wa.event_mask = EnterWindowMask | LeaveWindowMask;
00770   submenu->win = XCreateWindow(__glutDisplay,
00771     __glutCurrentMenu->win, MENU_GAP,
00772     __glutCurrentMenu->num * fontHeight + MENU_GAP,  /* x & y */
00773     submenu->pixwidth, fontHeight,  /* width & height */
00774     0, CopyFromParent, InputOnly, CopyFromParent,
00775     CWEventMask, &wa);
00776   XMapWindow(__glutDisplay, submenu->win);
00777   __glutCurrentMenu->num++;
00778   submenu->next = __glutCurrentMenu->list;
00779   __glutCurrentMenu->list = submenu;
00780 }

void glutAttachMenu int    button
 

Definition at line 888 of file glut_menu.c.

References __glutChangeWindowEventMask(), _GLUTmenu::id, and menuModificationError().

00889 {
00890   if (__glutMappedMenu)
00891     menuModificationError();
00892   if (__glutCurrentWindow->menu[button] < 1) {
00893     __glutCurrentWindow->buttonUses++;
00894   }
00895   __glutChangeWindowEventMask(
00896     ButtonPressMask | ButtonReleaseMask, True);
00897   __glutCurrentWindow->menu[button] = __glutCurrentMenu->id + 1;
00898 }

void glutChangeToMenuEntry int    num,
char *    label,
int    value
 

Definition at line 783 of file glut_menu.c.

References __glutWarning(), free, i, _GLUTmenuItem::isTrigger, _GLUTmenuItem::label, _GLUTmenu::list, _GLUTmenuItem::menu, menuModificationError(), _GLUTmenuItem::next, _GLUTmenu::num, setMenuItem(), and _GLUTmenu::submenus.

00784 {
00785   GLUTmenuItem *item;
00786   int i;
00787 
00788   if (__glutMappedMenu)
00789     menuModificationError();
00790   i = __glutCurrentMenu->num;
00791   item = __glutCurrentMenu->list;
00792   while (item) {
00793     if (i == num) {
00794       if (item->isTrigger) {
00795         /* If changing a submenu trigger to a menu entry, we
00796            need to account for submenus.  */
00797         item->menu->submenus--;
00798       }
00799       free(item->label);
00800       setMenuItem(item, label, value, False);
00801       return;
00802     }
00803     i--;
00804     item = item->next;
00805   }
00806   __glutWarning("Current menu has no %d item.", num);
00807 }

void glutChangeToSubMenu int    num,
char *    label,
int    menu
 

Definition at line 810 of file glut_menu.c.

References __glutWarning(), free, i, _GLUTmenuItem::isTrigger, _GLUTmenuItem::label, _GLUTmenu::list, _GLUTmenuItem::menu, menuModificationError(), _GLUTmenuItem::next, _GLUTmenu::num, setMenuItem(), and _GLUTmenu::submenus.

00811 {
00812   GLUTmenuItem *item;
00813   int i;
00814 
00815   if (__glutMappedMenu)
00816     menuModificationError();
00817   i = __glutCurrentMenu->num;
00818   item = __glutCurrentMenu->list;
00819   while (item) {
00820     if (i == num) {
00821       if (!item->isTrigger) {
00822         /* If changing a menu entry to as submenu trigger, we
00823            need to account for submenus.  */
00824         item->menu->submenus++;
00825       }
00826       free(item->label);
00827       setMenuItem(item, label, /* base 0 */ menu - 1, True);
00828       return;
00829     }
00830     i--;
00831     item = item->next;
00832   }
00833   __glutWarning("Current menu has no %d item.", num);
00834 }

int glutCreateMenu GLUTselectCB    selectFunc
 

Definition at line 605 of file glut_menu.c.

References __glutFatalError(), __glutOpenXConnection(), __glutSetMenu(), _GLUTmenu::anchor, _GLUTmenu::cascade, getUnusedMenuSlot(), GLUTselectCB, _GLUTmenu::highlighted, _GLUTmenu::id, _GLUTmenu::list, malloc, _GLUTmenu::managed, MENU_BORDER, menuBlack, menuColormap, menuDepth, menuGraphicsContextSetup(), menuGray, menuModificationError(), menuSetup(), menuVisual, _GLUTmenu::num, _GLUTmenu::pixwidth, _GLUTmenu::select, _GLUTmenu::submenus, useSaveUnders, and _GLUTmenu::win.

00606 {
00607   XSetWindowAttributes wa;
00608   GLUTmenu *menu;
00609   int menuid;
00610 
00611   if (__glutMappedMenu)
00612     menuModificationError();
00613   if (!__glutDisplay)
00614     __glutOpenXConnection(NULL);
00615   menuid = getUnusedMenuSlot();
00616   menu = (GLUTmenu *) malloc(sizeof(GLUTmenu));
00617   if (!menu)
00618     __glutFatalError("out of memory.");
00619   menu->id = menuid;
00620   menu->num = 0;
00621   menu->submenus = 0;
00622   menu->managed = False;
00623   menu->pixwidth = 0;
00624   menu->select = selectFunc;
00625   menu->list = NULL;
00626   menu->cascade = NULL;
00627   menu->highlighted = NULL;
00628   menu->anchor = NULL;
00629   menuSetup();
00630   wa.override_redirect = True;
00631   wa.background_pixel = menuGray;
00632   wa.border_pixel = menuBlack;
00633   wa.colormap = menuColormap;
00634   wa.event_mask = StructureNotifyMask | ExposureMask |
00635     ButtonPressMask | ButtonReleaseMask |
00636     EnterWindowMask | LeaveWindowMask;
00637   /* Save unders really only enabled if useSaveUnders is set to
00638      CWSaveUnder, ie. using Mesa 3D.  See earlier comments. */
00639   wa.save_under = True;
00640   menu->win = XCreateWindow(__glutDisplay, __glutRoot,
00641   /* real position determined when mapped */
00642     0, 0,
00643   /* real size will be determined when menu is manged */
00644     1, 1,
00645     MENU_BORDER, menuDepth, InputOutput, menuVisual,
00646     CWOverrideRedirect | CWBackPixel | CWBorderPixel |
00647     CWEventMask | CWColormap | useSaveUnders,
00648     &wa);
00649   menuGraphicsContextSetup(menu->win);
00650   menuList[menuid] = menu;
00651   __glutSetMenu(menu);
00652   return menuid + 1;
00653 }

void glutDestroyMenu int    menunum
 

Definition at line 656 of file glut_menu.c.

References __glutGetMenuByNum(), free, _GLUTmenu::id, _GLUTmenuItem::label, _GLUTmenu::list, _GLUTmenuItem::menu, menuModificationError(), _GLUTmenuItem::next, and _GLUTmenu::win.

00657 {
00658   GLUTmenu *menu = __glutGetMenuByNum(menunum);
00659   GLUTmenuItem *item, *next;
00660 
00661   if (__glutMappedMenu)
00662     menuModificationError();
00663   assert(menu->id == menunum - 1);
00664   XDestroySubwindows(__glutDisplay, menu->win);
00665   XDestroyWindow(__glutDisplay, menu->win);
00666   menuList[menunum - 1] = NULL;
00667   /* free all menu entries */
00668   item = menu->list;
00669   while (item) {
00670     assert(item->menu == menu);
00671     next = item->next;
00672     free(item->label);
00673     free(item);
00674     item = next;
00675   }
00676   if (__glutCurrentMenu == menu) {
00677     __glutCurrentMenu = NULL;
00678   }
00679   free(menu);
00680 }

void glutDetachMenu int    button
 

Definition at line 901 of file glut_menu.c.

References __glutChangeWindowEventMask(), and menuModificationError().

00902 {
00903   if (__glutMappedMenu)
00904     menuModificationError();
00905   if (__glutCurrentWindow->menu[button] > 0) {
00906     __glutCurrentWindow->buttonUses--;
00907     __glutChangeWindowEventMask(ButtonPressMask | ButtonReleaseMask,
00908       __glutCurrentWindow->buttonUses > 0);
00909     __glutCurrentWindow->menu[button] = 0;
00910   }
00911 }

int glutGetMenu void   
 

Definition at line 683 of file glut_menu.c.

References _GLUTmenu::id.

00684 {
00685   if (__glutCurrentMenu) {
00686     return __glutCurrentMenu->id + 1;
00687   } else {
00688     return 0;
00689   }
00690 }

void glutMenuStateFunc GLUTmenuStateCB    menuStateFunc
 

Definition at line 241 of file glut_menu.c.

References __glutMenuStatusFunc, and GLUTmenuStateCB.

00242 {
00243   __glutMenuStatusFunc = (GLUTmenuStatusCB) menuStateFunc;
00244 }

void glutMenuStatusFunc GLUTmenuStatusCB    menuStatusFunc
 

Definition at line 247 of file glut_menu.c.

References __glutMenuStatusFunc, and GLUTmenuStatusCB.

00248 {
00249   __glutMenuStatusFunc = menuStatusFunc;
00250 }

void glutRemoveMenuItem int    num
 

Definition at line 837 of file glut_menu.c.

References __glutWarning(), free, i, _GLUTmenuItem::label, _GLUTmenu::list, _GLUTmenu::managed, menuModificationError(), _GLUTmenuItem::next, _GLUTmenu::num, _GLUTmenu::pixwidth, and _GLUTmenuItem::pixwidth.

00838 {
00839   GLUTmenuItem *item, **prev, *remaining;
00840   int pixwidth, i;
00841 
00842   if (__glutMappedMenu)
00843     menuModificationError();
00844   i = __glutCurrentMenu->num;
00845   prev = &__glutCurrentMenu->list;
00846   item = __glutCurrentMenu->list;
00847   /* If menu item is removed, the menu's pixwidth may need to
00848      be recomputed. */
00849   pixwidth = 0;
00850   while (item) {
00851     if (i == num) {
00852       /* If this menu item's pixwidth is as wide as the menu's
00853          pixwidth, removing this menu item will necessitate
00854          shrinking the menu's pixwidth. */
00855       if (item->pixwidth >= __glutCurrentMenu->pixwidth) {
00856         /* Continue recalculating menu pixwidth, first skipping
00857            the removed item. */
00858         remaining = item->next;
00859         while (remaining) {
00860           if (remaining->pixwidth > pixwidth) {
00861             pixwidth = remaining->pixwidth;
00862           }
00863           remaining = remaining->next;
00864         }
00865       }
00866       __glutCurrentMenu->num--;
00867       __glutCurrentMenu->managed = False;
00868       __glutCurrentMenu->pixwidth = pixwidth;
00869 
00870       /* Patch up menu's item list. */
00871       *prev = item->next;
00872 
00873       free(item->label);
00874       free(item);
00875       return;
00876     }
00877     if (item->pixwidth > pixwidth) {
00878       pixwidth = item->pixwidth;
00879     }
00880     i--;
00881     prev = &item->next;
00882     item = item->next;
00883   }
00884   __glutWarning("Current menu has no %d item.", num);
00885 }

void glutSetMenu int    menuid
 

Definition at line 693 of file glut_menu.c.

References __glutSetMenu(), __glutWarning(), and menuListSize.

00694 {
00695   GLUTmenu *menu;
00696 
00697   if (menuid < 1 || menuid > menuListSize) {
00698     __glutWarning("glutSetMenu attempted on bogus menu.");
00699     return;
00700   }
00701   menu = menuList[menuid - 1];
00702   if (!menu) {
00703     __glutWarning("glutSetMenu attempted on bogus menu.");
00704     return;
00705   }
00706   __glutSetMenu(menu);
00707 }

void mapMenu GLUTmenu   menu,
int    x,
int    y
[static]
 

Definition at line 330 of file glut_menu.c.

References fontHeight, _GLUTmenu::list, _GLUTmenu::managed, MENU_ARROW_GAP, MENU_ARROW_WIDTH, MENU_GAP, menuColormap, _GLUTmenuItem::next, _GLUTmenu::num, _GLUTmenu::pixheight, _GLUTmenu::pixwidth, _GLUTmenu::submenus, _GLUTmenu::win, _GLUTmenuItem::win, _GLUTmenu::x, and _GLUTmenu::y.

Referenced by __glutMenuItemEnterOrLeave(), and __glutStartMenu().

00331 {
00332   XWindowChanges changes;
00333   unsigned int mask;
00334   int subMenuExtension, num;
00335 
00336   /* If there are submenus, we need to provide extra space for
00337      the submenu pull arrow.  */
00338   if (menu->submenus > 0) {
00339     subMenuExtension = MENU_ARROW_GAP + MENU_ARROW_WIDTH;
00340   } else {
00341     subMenuExtension = 0;
00342   }
00343 
00344   changes.stack_mode = Above;
00345   mask = CWStackMode | CWX | CWY;
00346   /* If the menu isn't managed (ie, validated so all the
00347      InputOnly subwindows are the right size), do so.  */
00348   if (!menu->managed) {
00349     GLUTmenuItem *item;
00350 
00351     item = menu->list;
00352     num = menu->num;
00353     while (item) {
00354       XWindowChanges itemupdate;
00355 
00356       itemupdate.y = (num - 1) * fontHeight + MENU_GAP;
00357       itemupdate.width = menu->pixwidth;
00358       itemupdate.width += subMenuExtension;
00359       XConfigureWindow(__glutDisplay, item->win,
00360         CWWidth | CWY, &itemupdate);
00361       item = item->next;
00362       num--;
00363     }
00364     menu->pixheight = MENU_GAP +
00365       fontHeight * menu->num + MENU_GAP;
00366     changes.height = menu->pixheight;
00367     changes.width = MENU_GAP +
00368       menu->pixwidth + subMenuExtension + MENU_GAP;
00369     mask |= CWWidth | CWHeight;
00370     menu->managed = True;
00371   }
00372   /* make sure menu appears fully on screen */
00373   if (y + menu->pixheight >= __glutScreenHeight) {
00374     changes.y = __glutScreenHeight - menu->pixheight;
00375   } else {
00376     changes.y = y;
00377   }
00378   if (x + menu->pixwidth + subMenuExtension >=
00379     __glutScreenWidth) {
00380     changes.x = __glutScreenWidth -
00381       menu->pixwidth + subMenuExtension;
00382   } else {
00383     changes.x = x;
00384   }
00385 
00386   /* Rember where the menu is placed so submenus can be
00387      properly placed relative to it. */
00388   menu->x = changes.x;
00389   menu->y = changes.y;
00390 
00391   XConfigureWindow(__glutDisplay, menu->win, mask, &changes);
00392   XInstallColormap(__glutDisplay, menuColormap);
00393   /* XXX The XRaiseWindow below should not be necessary because
00394      the XConfigureWindow requests an Above stack mode (same as
00395      XRaiseWindow), but some Sun users complained this was still
00396      necessary.  Probably some window manager or X server bug on
00397      these machines?? */
00398   XRaiseWindow(__glutDisplay, menu->win);
00399   XMapWindow(__glutDisplay, menu->win);
00400 }

void menuGraphicsContextSetup Window    win [static]
 

Definition at line 223 of file glut_menu.c.

References blackGC, grayGC, menuBlack, menuFont, menuGray, menuWhite, whiteGC, and win.

Referenced by glutCreateMenu().

00224 {
00225   XGCValues gcvals;
00226 
00227   if (blackGC != None)
00228     return;
00229   gcvals.font = menuFont->fid;
00230   gcvals.foreground = menuBlack;
00231   blackGC = XCreateGC(__glutDisplay, win,
00232     GCFont | GCForeground, &gcvals);
00233   gcvals.foreground = menuGray;
00234   grayGC = XCreateGC(__glutDisplay, win, GCForeground, &gcvals);
00235   gcvals.foreground = menuWhite;
00236   whiteGC = XCreateGC(__glutDisplay, win, GCForeground, &gcvals);
00237 }

void menuModificationError void    [static]
 

Definition at line 597 of file glut_menu.c.

References __glutFatalError(), and __glutWarning().

Referenced by glutAddMenuEntry(), glutAddSubMenu(), glutAttachMenu(), glutChangeToMenuEntry(), glutChangeToSubMenu(), glutCreateMenu(), glutDestroyMenu(), glutDetachMenu(), and glutRemoveMenuItem().

00598 {
00599   /* XXX Remove the warning after GLUT 3.0. */
00600   __glutWarning("The following is a new check for GLUT 3.0; update your code.");
00601   __glutFatalError("menu manipulation not allowed while menus in use");
00602 }

void menuSetup void    [static]
 

Definition at line 202 of file glut_menu.c.

References __glutFatalError(), fontHeight, menuCursor, menuFont, and menuVisualSetup().

Referenced by glutCreateMenu().

00203 {
00204   if (menuFont) {
00205     /* menuFont overload to indicate menu initalization */
00206     return;
00207   }
00208   menuFont = XLoadQueryFont(__glutDisplay,
00209     "-*-helvetica-bold-o-normal--14-*-*-*-p-*-iso8859-1");
00210   if (!menuFont) {
00211     /* try back up font */
00212     menuFont = XLoadQueryFont(__glutDisplay, "fixed");
00213   }
00214   if (!menuFont) {
00215     __glutFatalError("could not load font.");
00216   }
00217   menuVisualSetup();
00218   fontHeight = menuFont->ascent + menuFont->descent;
00219   menuCursor = XCreateFontCursor(__glutDisplay, XC_arrow);
00220 }

void menuVisualSetup void    [static]
 

Definition at line 97 of file glut_menu.c.

References __glutXGetLayerVisualInfo(), Bool, color, dummy, i, menuBlack, menuColormap, menuDepth, menuGray, menuVisual, menuWhite, noFaultXAllocColor(), useSaveUnders, _XLayerVisualInfo::vinfo, and VisualLayerMask.

Referenced by menuSetup().

00098 {
00099   XLayerVisualInfo template, *visual, *overlayVisuals;
00100   XColor color;
00101   Status status;
00102   Bool presumablyMesa;
00103   int layer, nVisuals, i, dummy;
00104 
00105   for (layer = 3; layer > 0; layer--) {
00106     template.layer = layer;
00107     template.vinfo.screen = __glutScreen;
00108     overlayVisuals = __glutXGetLayerVisualInfo(__glutDisplay,
00109       VisualScreenMask | VisualLayerMask, &template, &nVisuals);
00110     if (overlayVisuals) {
00111       for (i = 0; i < nVisuals; i++) {
00112         visual = &overlayVisuals[i];
00113         if (visual->vinfo.colormap_size >= 3) {
00114           menuColormap = XCreateColormap(__glutDisplay, __glutRoot,
00115             visual->vinfo.visual, AllocNone);
00116           /* Allocate overlay colormap cells in defined order:
00117              gray, black, white to match the IRIS GL allocation
00118              scheme.  Increases likelihood of less overlay
00119              colormap flashing. */
00120           /* XXX nice if these 3 AllocColor's could be done in
00121              one protocol round-trip */
00122           color.red = color.green = color.blue = 0xaa00;
00123           status = XAllocColor(__glutDisplay,
00124             menuColormap, &color);
00125           if (!status) {
00126             XFreeColormap(__glutDisplay, menuColormap);
00127             continue;
00128           }
00129           menuGray = color.pixel;
00130           color.red = color.green = color.blue = 0x0000;
00131           status = XAllocColor(__glutDisplay,
00132             menuColormap, &color);
00133           if (!status) {
00134             XFreeColormap(__glutDisplay, menuColormap);
00135             continue;
00136           }
00137           menuBlack = color.pixel;
00138           color.red = color.green = color.blue = 0xffff;
00139           status = XAllocColor(__glutDisplay,
00140             menuColormap, &color);
00141           if (!status) {
00142             XFreeColormap(__glutDisplay, menuColormap);
00143             continue;
00144           }
00145           menuWhite = color.pixel;
00146           menuVisual = visual->vinfo.visual;
00147           menuDepth = visual->vinfo.depth;
00148           /* If using overlays, avoid requesting "save unders". 
00149            */
00150           useSaveUnders = 0;
00151           XFree(overlayVisuals);
00152           return;
00153         }
00154       }
00155       XFree(overlayVisuals);
00156     }
00157   }
00158   /* settle for default visual */
00159   menuVisual = DefaultVisual(__glutDisplay, __glutScreen);
00160   menuDepth = DefaultDepth(__glutDisplay, __glutScreen);
00161   menuColormap = DefaultColormap(__glutDisplay, __glutScreen);
00162   menuBlack = BlackPixel(__glutDisplay, __glutScreen);
00163   menuWhite = WhitePixel(__glutDisplay, __glutScreen);
00164   color.red = color.green = color.blue = 0xaa00;
00165   noFaultXAllocColor(__glutDisplay, menuColormap,
00166     menuVisual->map_entries, &color);
00167   menuGray = color.pixel;
00168 
00169   /* When no overlays are supported, we would like to use X
00170      "save unders" to avoid exposes to windows obscured by
00171      pop-up menus.  However, OpenGL's direct rendering support
00172      means OpenGL interacts poorly with X backing store and
00173      save unders.  X servers do not (in implementation
00174      practice) redirect OpenGL rendering destined to obscured
00175      window regions into backing store.
00176 
00177      Implementation solutions exist for this problem, but they
00178      are expensive and high-end OpenGL implementations
00179      typically provide fast rendering and/or overlays to
00180      obviate the problem associated of user interfaces (pop-up
00181      menus) forcing redraws of complex normal plane scenes.
00182      (See support for overlays pop-up menus above.)
00183 
00184      Mesa 3D, however, does not support direct rendering.
00185      Overlays are often unavailable to Mesa, and Mesa is also
00186      relatively slow.  For these reasons, Mesa-rendering GLUT
00187      programs can and should use X save unders.
00188 
00189      Look for the GLX extension.  If _not_ supported, we are
00190      presumably using Mesa so enable save unders. */
00191 
00192   presumablyMesa = !XQueryExtension(__glutDisplay, "GLX",
00193     &dummy, &dummy, &dummy);
00194 
00195   if (presumablyMesa)
00196     useSaveUnders = CWSaveUnder;
00197   else
00198     useSaveUnders = 0;
00199 }

void noFaultXAllocColor Display *    dpy,
Colormap    cmap,
int    cmapSize,
XColor *    color
[static]
 

Definition at line 46 of file glut_menu.c.

References cmap, color, dpy, free, i, and malloc.

Referenced by menuVisualSetup().

00048 {
00049   XColor *ctable, subColor;
00050   int i, bestmatch;
00051   double mindist;       /* 3*2^16^2 exceeds long int precision. 
00052                          */
00053 
00054   for (;;) {
00055     /* First try just using XAllocColor. */
00056     if (XAllocColor(dpy, cmap, color))
00057       return;
00058 
00059     /* Retrieve color table entries. */
00060     /* XXX alloca canidate. */
00061     ctable = (XColor *) malloc(cmapSize * sizeof(XColor));
00062     for (i = 0; i < cmapSize; i++)
00063       ctable[i].pixel = i;
00064     XQueryColors(dpy, cmap, ctable, cmapSize);
00065 
00066     /* Find best match. */
00067     bestmatch = -1;
00068     mindist = 0.0;
00069     for (i = 0; i < cmapSize; i++) {
00070       double dr = (double) color->red - (double) ctable[i].red;
00071       double dg = (double) color->green - (double) ctable[i].green;
00072       double db = (double) color->blue - (double) ctable[i].blue;
00073       double dist = dr * dr + dg * dg + db * db;
00074       if (bestmatch < 0 || dist < mindist) {
00075         bestmatch = i;
00076         mindist = dist;
00077       }
00078     }
00079 
00080     /* Return result. */
00081     subColor.red = ctable[bestmatch].red;
00082     subColor.green = ctable[bestmatch].green;
00083     subColor.blue = ctable[bestmatch].blue;
00084     free(ctable);
00085     if (XAllocColor(dpy, cmap, &subColor)) {
00086       *color = subColor;
00087       return;
00088     }
00089     /* Extremely unlikely, but possibly color was deallocated
00090        and reallocated by someone else before we could
00091        XAllocColor the color cell we located.  If so, loop
00092        again... */
00093   }
00094 }

void paintMenuItem GLUTmenuItem   item,
int    num
[static]
 

Definition at line 448 of file glut_menu.c.

References blackGC, fontHeight, grayGC, _GLUTmenu::highlighted, _GLUTmenuItem::isTrigger, _GLUTmenuItem::label, _GLUTmenuItem::len, _GLUTmenuItem::menu, MENU_ARROW_GAP, MENU_ARROW_WIDTH, MENU_GAP, menuFont, paintSubMenuArrow(), _GLUTmenu::pixwidth, _GLUTmenu::submenus, whiteGC, _GLUTmenu::win, and win.

Referenced by __glutMenuItemEnterOrLeave(), and __glutPaintMenu().

00449 {
00450   Window win = item->menu->win;
00451   GC gc;
00452   int y;
00453   int subMenuExtension;
00454 
00455   if (item->menu->submenus > 0) {
00456     subMenuExtension = MENU_ARROW_GAP + MENU_ARROW_WIDTH;
00457   } else {
00458     subMenuExtension = 0;
00459   }
00460   if (item->menu->highlighted == item) {
00461     gc = whiteGC;
00462   } else {
00463     gc = grayGC;
00464   }
00465   y = MENU_GAP + fontHeight * num - menuFont->descent;
00466   XFillRectangle(__glutDisplay, win, gc,
00467     MENU_GAP, y - fontHeight + menuFont->descent,
00468     item->menu->pixwidth + subMenuExtension, fontHeight);
00469   XDrawString(__glutDisplay, win, blackGC,
00470     MENU_GAP, y, item->label, item->len);
00471   if (item->isTrigger) {
00472     paintSubMenuArrow(win,
00473       item->menu->pixwidth + MENU_ARROW_GAP + 1, y);
00474   }
00475 }

void paintSubMenuArrow Window    win,
int    x,
int    y
[static]
 

Definition at line 430 of file glut_menu.c.

References blackGC, MENU_ARROW_WIDTH, menuFont, p, whiteGC, and win.

Referenced by __glutPaintMenu(), and paintMenuItem().

00431 {
00432   XPoint p[5];
00433 
00434   p[0].x = p[4].x = x;
00435   p[0].y = p[4].y = y - menuFont->ascent + 1;
00436   p[1].x = p[0].x + MENU_ARROW_WIDTH - 1;
00437   p[1].y = p[0].y + (menuFont->ascent / 2) - 1;
00438   p[2].x = p[1].x;
00439   p[2].y = p[1].y + 1;
00440   p[3].x = p[0].x;
00441   p[3].y = p[0].y + menuFont->ascent - 2;
00442   XFillPolygon(__glutDisplay, win,
00443     whiteGC, p, 4, Convex, CoordModeOrigin);
00444   XDrawLines(__glutDisplay, win, blackGC, p, 5, CoordModeOrigin);
00445 }

void setMenuItem GLUTmenuItem   item,
char *    label,
int    value,
Bool    isTrigger
[static]
 

Definition at line 710 of file glut_menu.c.

References __glutFatalError(), Bool, _GLUTmenuItem::isTrigger, _GLUTmenuItem::label, _GLUTmenuItem::len, _GLUTmenu::managed, _GLUTmenuItem::menu, menuFont, _GLUTmenu::pixwidth, _GLUTmenuItem::pixwidth, and _GLUTmenuItem::value.

Referenced by glutAddMenuEntry(), glutAddSubMenu(), glutChangeToMenuEntry(), and glutChangeToSubMenu().

00712 {
00713   GLUTmenu *menu;
00714 
00715   menu = item->menu;
00716   item->label = strdup(label);
00717   if (!item->label)
00718     __glutFatalError("out of memory.");
00719   item->isTrigger = isTrigger;
00720   item->len = (int) strlen(label);
00721   item->value = value;
00722   item->pixwidth = XTextWidth(menuFont, label, item->len) + 4;
00723   if (item->pixwidth > menu->pixwidth) {
00724     menu->pixwidth = item->pixwidth;
00725   }
00726   menu->managed = False;
00727 }

void unmapMenu GLUTmenu   menu [static]
 

Definition at line 259 of file glut_menu.c.

References _GLUTmenu::anchor, _GLUTmenu::cascade, _GLUTmenu::highlighted, and _GLUTmenu::win.

Referenced by __glutFinishMenu(), and __glutMenuItemEnterOrLeave().

00260 {
00261   if (menu->cascade) {
00262     unmapMenu(menu->cascade);
00263     menu->cascade = NULL;
00264   }
00265   menu->anchor = NULL;
00266   menu->highlighted = NULL;
00267   XUnmapWindow(__glutDisplay, menu->win);
00268 }

Variable Documentation

GLUTmenu* __glutCurrentMenu = NULL
 

Definition at line 22 of file glut_menu.c.

GLUTmenuItem* __glutItemSelected
 

Definition at line 26 of file glut_menu.c.

GLUTmenu* __glutMappedMenu
 

Definition at line 24 of file glut_menu.c.

void(* __glutMenuStatusFunc)(int, int, int)
 

Definition at line 23 of file glut_menu.c.

Referenced by __glutFinishMenu(), __glutStartMenu(), glutMenuStateFunc(), and glutMenuStatusFunc().

GLUTwindow* __glutMenuWindow
 

Definition at line 25 of file glut_menu.c.

GC blackGC [static]
 

Definition at line 36 of file glut_menu.c.

Referenced by __glutPaintMenu(), menuGraphicsContextSetup(), paintMenuItem(), and paintSubMenuArrow().

int fontHeight [static]
 

Definition at line 35 of file glut_menu.c.

Referenced by __glutMenuItemEnterOrLeave(), __glutPaintMenu(), glutAddMenuEntry(), glutAddSubMenu(), mapMenu(), menuSetup(), and paintMenuItem().

GC grayGC [static]
 

Definition at line 36 of file glut_menu.c.

Referenced by menuGraphicsContextSetup(), and paintMenuItem().

unsigned long menuBlack [static]
 

Definition at line 37 of file glut_menu.c.

Referenced by glutCreateMenu(), menuGraphicsContextSetup(), and menuVisualSetup().

Colormap menuColormap [static]
 

Definition at line 32 of file glut_menu.c.

Referenced by glutCreateMenu(), mapMenu(), and menuVisualSetup().

Cursor menuCursor [static]
 

Definition at line 31 of file glut_menu.c.

Referenced by __glutStartMenu(), and menuSetup().

int menuDepth [static]
 

Definition at line 34 of file glut_menu.c.

Referenced by glutCreateMenu(), and menuVisualSetup().

XFontStruct* menuFont = NULL [static]
 

Definition at line 30 of file glut_menu.c.

Referenced by __glutPaintMenu(), menuGraphicsContextSetup(), menuSetup(), paintMenuItem(), paintSubMenuArrow(), and setMenuItem().

unsigned long menuGray [static]
 

Definition at line 37 of file glut_menu.c.

Referenced by glutCreateMenu(), menuGraphicsContextSetup(), and menuVisualSetup().

GLUTmenu** menuList = NULL [static]
 

Definition at line 28 of file glut_menu.c.

int menuListSize = 0 [static]
 

Definition at line 29 of file glut_menu.c.

Referenced by __glutGetMenuByNum(), getUnusedMenuSlot(), and glutSetMenu().

Visual* menuVisual [static]
 

Definition at line 33 of file glut_menu.c.

Referenced by glutCreateMenu(), and menuVisualSetup().

unsigned long menuWhite [static]
 

Definition at line 37 of file glut_menu.c.

Referenced by menuGraphicsContextSetup(), and menuVisualSetup().

unsigned long useSaveUnders [static]
 

Definition at line 38 of file glut_menu.c.

Referenced by glutCreateMenu(), and menuVisualSetup().

GC whiteGC [static]
 

Definition at line 36 of file glut_menu.c.

Referenced by menuGraphicsContextSetup(), paintMenuItem(), and paintSubMenuArrow().

 

Powered by Plone

This site conforms to the following standards: