blob: 969b8120b44dc2529cc8e8aca0b34f715580cb15 [file] [log] [blame]
/* Copyright (c) Mark J. Kilgard, 1994, 1997. */
/* This program is freely distributable without licensing fees
and is provided without guarantee or warrantee expressed or
implied. This program is -not- in the public domain. */
/* glut_menu2.c implements the little used GLUT menu calls in
a distinct file from glut_menu.c for slim static linking. */
/* The Win32 GLUT file win32_menu.c completely re-implements all
the menuing functionality implemented. This file is used only by
the X Window System version of GLUT. */
#ifdef __VMS
#include <GL/vms_x_fix.h>
#endif
#include <stdlib.h>
#include <string.h>
#include <stdio.h>
#include <errno.h>
#include <assert.h>
#include <X11/Xlib.h>
#include "glutint.h"
#include "layerutil.h"
/* CENTRY */
/* DEPRICATED, use glutMenuStatusFunc instead. */
void GLUTAPIENTRY
glutMenuStateFunc(GLUTmenuStateCB menuStateFunc)
{
__glutMenuStatusFunc = (GLUTmenuStatusCB) menuStateFunc;
}
void GLUTAPIENTRY
glutMenuStatusFunc(GLUTmenuStatusCB menuStatusFunc)
{
__glutMenuStatusFunc = menuStatusFunc;
}
void GLUTAPIENTRY
glutDestroyMenu(int menunum)
{
GLUTmenu *menu = __glutGetMenuByNum(menunum);
GLUTmenuItem *item, *next;
if (__glutMappedMenu)
__glutMenuModificationError();
assert(menu->id == menunum - 1);
XDestroySubwindows(__glutDisplay, menu->win);
XDestroyWindow(__glutDisplay, menu->win);
__glutMenuList[menunum - 1] = NULL;
/* free all menu entries */
item = menu->list;
while (item) {
assert(item->menu == menu);
next = item->next;
free(item->label);
free(item);
item = next;
}
if (__glutCurrentMenu == menu) {
__glutCurrentMenu = NULL;
}
free(menu);
}
void GLUTAPIENTRY
glutChangeToMenuEntry(int num, const char *label, int value)
{
GLUTmenuItem *item;
int i;
if (__glutMappedMenu)
__glutMenuModificationError();
i = __glutCurrentMenu->num;
item = __glutCurrentMenu->list;
while (item) {
if (i == num) {
if (item->isTrigger) {
/* If changing a submenu trigger to a menu entry, we
need to account for submenus. */
item->menu->submenus--;
}
free(item->label);
__glutSetMenuItem(item, label, value, False);
return;
}
i--;
item = item->next;
}
__glutWarning("Current menu has no %d item.", num);
}
void GLUTAPIENTRY
glutChangeToSubMenu(int num, const char *label, int menu)
{
GLUTmenuItem *item;
int i;
if (__glutMappedMenu)
__glutMenuModificationError();
i = __glutCurrentMenu->num;
item = __glutCurrentMenu->list;
while (item) {
if (i == num) {
if (!item->isTrigger) {
/* If changing a menu entry to as submenu trigger, we
need to account for submenus. */
item->menu->submenus++;
}
free(item->label);
__glutSetMenuItem(item, label, /* base 0 */ menu - 1, True);
return;
}
i--;
item = item->next;
}
__glutWarning("Current menu has no %d item.", num);
}
void GLUTAPIENTRY
glutRemoveMenuItem(int num)
{
GLUTmenuItem *item, **prev, *remaining;
int pixwidth, i;
if (__glutMappedMenu)
__glutMenuModificationError();
i = __glutCurrentMenu->num;
prev = &__glutCurrentMenu->list;
item = __glutCurrentMenu->list;
/* If menu item is removed, the menu's pixwidth may need to
be recomputed. */
pixwidth = 1;
while (item) {
if (i == num) {
/* If this menu item's pixwidth is as wide as the menu's
pixwidth, removing this menu item will necessitate
shrinking the menu's pixwidth. */
if (item->pixwidth >= __glutCurrentMenu->pixwidth) {
/* Continue recalculating menu pixwidth, first skipping
the removed item. */
remaining = item->next;
while (remaining) {
if (remaining->pixwidth > pixwidth) {
pixwidth = remaining->pixwidth;
}
remaining = remaining->next;
}
__glutCurrentMenu->pixwidth = pixwidth;
}
__glutCurrentMenu->num--;
__glutCurrentMenu->managed = False;
/* Patch up menu's item list. */
*prev = item->next;
free(item->label);
free(item);
return;
}
if (item->pixwidth > pixwidth) {
pixwidth = item->pixwidth;
}
i--;
prev = &item->next;
item = item->next;
}
__glutWarning("Current menu has no %d item.", num);
}
void GLUTAPIENTRY
glutDetachMenu(int button)
{
if (__glutMappedMenu)
__glutMenuModificationError();
if (__glutCurrentWindow->menu[button] > 0) {
__glutCurrentWindow->buttonUses--;
__glutChangeWindowEventMask(ButtonPressMask | ButtonReleaseMask,
__glutCurrentWindow->buttonUses > 0);
__glutCurrentWindow->menu[button] = 0;
}
}
/* ENDCENTRY */