mirror of
https://github.com/darlinghq/darling-glut.git
synced 2024-11-23 12:19:42 +00:00
309 lines
7.4 KiB
Objective-C
309 lines
7.4 KiB
Objective-C
|
|
/* Copyright (c) Dietmar Planitzer, 1998, 2002 */
|
|
|
|
/* 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. */
|
|
|
|
#import "macx_glut.h"
|
|
#import "GLUTMenu.h"
|
|
#import "GLUTApplication.h"
|
|
#import "GLUTView.h"
|
|
#import "GLUTWindow.h"
|
|
|
|
|
|
GLUTView * __glutMenuWindow = nil; // Window while menu is active
|
|
GLUTMenu * __glutMappedMenu = nil;
|
|
GLUTmenuStatusCB __glutMenuStatusFunc = NULL;
|
|
GLUTmenuStatusFCB __fglutMenuStatusFunc = NULL; /* fortran callback */
|
|
GLUTMenu * __glutCurrentMenu = nil;
|
|
static GLUTMenu ** __glutMenuList = NULL;
|
|
static int __glutMenuListSize = 0;
|
|
|
|
|
|
|
|
void __glutSetMenu(GLUTMenu *menu)
|
|
{
|
|
__glutCurrentMenu = menu;
|
|
}
|
|
|
|
GLUTMenu *__glutGetMenu(void)
|
|
{
|
|
return __glutCurrentMenu;
|
|
}
|
|
|
|
void __glutStartMenu(GLUTMenu *menu, GLUTView *window, NSPoint wMouseLoc)
|
|
{
|
|
/* User is about to start a menu tracking session. We install a special
|
|
timer which will execute the idle function while menu tracking is
|
|
going on because menu tracking happens in its own modal event loop. */
|
|
__glutStartIdleFuncTimer();
|
|
|
|
__glutMappedMenu = menu;
|
|
__glutMenuWindow = window;
|
|
if(__glutMenuStatusFunc) {
|
|
__glutSetMenu(menu);
|
|
__glutSetWindow(window);
|
|
|
|
wMouseLoc = [window convertPoint: wMouseLoc fromView: nil];
|
|
__glutMenuStatusFunc(GLUT_MENU_IN_USE, rint(wMouseLoc.x), rint(wMouseLoc.y));
|
|
}
|
|
}
|
|
|
|
void __glutFinishMenu(NSPoint sMouseLoc)
|
|
{
|
|
/* Setting __glutMappedMenu to NULL permits operations that
|
|
change menus or destroy the menu window again. */
|
|
__glutMappedMenu = nil;
|
|
if(__glutMenuStatusFunc) {
|
|
__glutSetWindow(__glutMenuWindow);
|
|
__glutSetMenu(__glutMappedMenu);
|
|
|
|
sMouseLoc = [[__glutMenuWindow window] convertScreenToBase: sMouseLoc];
|
|
sMouseLoc = [__glutMenuWindow convertPoint: sMouseLoc fromView: nil];
|
|
|
|
__glutMenuStatusFunc(GLUT_MENU_NOT_IN_USE, rint(sMouseLoc.x), rint(sMouseLoc.y));
|
|
}
|
|
}
|
|
|
|
static int __glutGetUnusedMenuSlot(void)
|
|
{
|
|
int i;
|
|
|
|
/* Look for allocated, unused slot. */
|
|
for(i = 0; i < __glutMenuListSize; i++) {
|
|
if(!__glutMenuList[i]) {
|
|
return i;
|
|
}
|
|
}
|
|
|
|
/* Allocate a new slot. */
|
|
__glutMenuListSize++;
|
|
__glutMenuList = (GLUTMenu **) realloc(__glutMenuList, __glutMenuListSize * sizeof(GLUTMenu *));
|
|
if(!__glutMenuList) {
|
|
__glutFatalError("out of memory.");
|
|
}
|
|
__glutMenuList[__glutMenuListSize - 1] = NULL;
|
|
return __glutMenuListSize - 1;
|
|
}
|
|
|
|
static GLUTMenu *__glutGetMenuByNum(int menunum)
|
|
{
|
|
if(menunum < 1 || menunum > __glutMenuListSize) {
|
|
return nil;
|
|
}
|
|
return __glutMenuList[menunum - 1];
|
|
}
|
|
|
|
static void __glutMenuModificationError(void)
|
|
{
|
|
/* XXX Remove the warning after GLUT 3.0. */
|
|
__glutWarning("The following is a new check for GLUT 3.0; update your code.");
|
|
__glutFatalError("menu manipulation not allowed while menus in use.");
|
|
}
|
|
|
|
/* CENTRY */
|
|
int APIENTRY glutCreateMenu(void (*func) (int value))
|
|
{
|
|
GLUTMenu * menu;
|
|
int menuid = 0;
|
|
|
|
GLUTAPI_DECLARATIONS
|
|
GLUTAPI_BEGIN
|
|
if(__glutMappedMenu) {
|
|
__glutMenuModificationError();
|
|
}
|
|
|
|
menuid = __glutGetUnusedMenuSlot();
|
|
menu = [[GLUTMenu alloc] initWithCallback: func menuID: menuid + 1];
|
|
if(menu == nil) {
|
|
__glutFatalError("out of memory."); // will exit
|
|
}
|
|
__glutMenuList[menuid] = menu;
|
|
__glutSetMenu(menu);
|
|
GLUTAPI_END
|
|
return menuid + 1;
|
|
}
|
|
|
|
int APIENTRY glutGetMenu(void)
|
|
{
|
|
if(__glutCurrentMenu) {
|
|
return [__glutCurrentMenu menuID];
|
|
} else {
|
|
return 0;
|
|
}
|
|
}
|
|
|
|
void APIENTRY glutSetMenu(int menuid)
|
|
{
|
|
GLUTMenu * menu = __glutGetMenuByNum(menuid);
|
|
|
|
if(!menu) {
|
|
__glutWarning("glutSetMenu attempted on bogus menu.");
|
|
return;
|
|
}
|
|
__glutSetMenu(menu);
|
|
}
|
|
|
|
void APIENTRY glutAddMenuEntry(const char *name, int value)
|
|
{
|
|
NSString * title;
|
|
|
|
GLUTAPI_DECLARATIONS
|
|
GLUTAPI_BEGIN
|
|
if(name == NULL) {
|
|
__glutFatalError("glutAddMenuEntry called with NULL name.");
|
|
}
|
|
if(__glutMappedMenu) {
|
|
__glutMenuModificationError();
|
|
}
|
|
|
|
title = [NSString stringWithUTF8String: name];
|
|
if(!title) {
|
|
__glutFatalError("out of memory");
|
|
}
|
|
[__glutCurrentMenu addMenuItemWithTitle: title tag: value];
|
|
GLUTAPI_END
|
|
}
|
|
|
|
void APIENTRY glutAddSubMenu(const char *name, int menu)
|
|
{
|
|
GLUTMenu * submenu;
|
|
NSString * title;
|
|
|
|
GLUTAPI_DECLARATIONS
|
|
GLUTAPI_BEGIN
|
|
if(name == NULL) {
|
|
__glutFatalError("glutAddSubMenu called with NULL name.");
|
|
}
|
|
if(__glutMappedMenu) {
|
|
__glutMenuModificationError();
|
|
}
|
|
|
|
title = [NSString stringWithUTF8String: name];
|
|
if(!title) {
|
|
__glutFatalError("out of memory");
|
|
}
|
|
|
|
submenu = __glutGetMenuByNum(menu);
|
|
if(!submenu) {
|
|
__glutWarning("glutAddSubMenu attempted on bogus menu.");
|
|
GLUTAPI_VOIDRETURN;
|
|
}
|
|
[__glutCurrentMenu addSubMenuWithTitle: title menu: submenu];
|
|
GLUTAPI_END
|
|
}
|
|
|
|
void APIENTRY glutAttachMenu(int button)
|
|
{
|
|
GLUTAPI_DECLARATIONS
|
|
GLUTAPI_BEGIN
|
|
if(__glutMappedMenu) {
|
|
__glutMenuModificationError();
|
|
}
|
|
[__glutCurrentView attachMenu: __glutCurrentMenu toButton: button];
|
|
GLUTAPI_END
|
|
}
|
|
|
|
void APIENTRY glutDetachMenu(int button)
|
|
{
|
|
GLUTAPI_DECLARATIONS
|
|
GLUTAPI_BEGIN
|
|
if(__glutMappedMenu) {
|
|
__glutMenuModificationError();
|
|
}
|
|
[__glutCurrentView detachMenuFromButton: button];
|
|
GLUTAPI_END
|
|
}
|
|
|
|
void APIENTRY glutDestroyMenu(int menu)
|
|
{
|
|
GLUTMenu * menuObj;
|
|
|
|
menuObj = __glutGetMenuByNum(menu);
|
|
if(!menuObj) {
|
|
__glutWarning("glutDestroyMenu attempted on bogus menu %d.", menu);
|
|
return;
|
|
}
|
|
if(__glutMappedMenu) {
|
|
__glutMenuModificationError();
|
|
}
|
|
|
|
if(menuObj == __glutCurrentMenu) {
|
|
__glutCurrentMenu = nil;
|
|
}
|
|
[menuObj release];
|
|
__glutMenuList[menu - 1] = NULL;
|
|
}
|
|
|
|
void APIENTRY glutChangeToMenuEntry(int entry, const char *name, int value)
|
|
{
|
|
NSString * title;
|
|
|
|
GLUTAPI_DECLARATIONS
|
|
GLUTAPI_BEGIN
|
|
if(name == NULL) {
|
|
__glutFatalError("glutChangeToMenuEntry called with NULL name.");
|
|
}
|
|
if(__glutMappedMenu) {
|
|
__glutMenuModificationError();
|
|
}
|
|
|
|
title = [NSString stringWithUTF8String: name];
|
|
if(!title) {
|
|
__glutFatalError("out of memory");
|
|
}
|
|
[__glutCurrentMenu setMenuItemAtIndex: entry - 1 toTitle: title tag: value];
|
|
GLUTAPI_END
|
|
}
|
|
|
|
void APIENTRY glutChangeToSubMenu(int entry, const char *name, int menu)
|
|
{
|
|
GLUTMenu * submenu;
|
|
NSString * title;
|
|
|
|
GLUTAPI_DECLARATIONS
|
|
GLUTAPI_BEGIN
|
|
if(name == NULL) {
|
|
__glutFatalError("glutChangeToSubMenu called with NULL name.");
|
|
}
|
|
if(__glutMappedMenu) {
|
|
__glutMenuModificationError();
|
|
}
|
|
|
|
submenu = __glutGetMenuByNum(menu);
|
|
if(!submenu) {
|
|
__glutWarning("glutChangeToSubMenu attempted on bogus menu.");
|
|
GLUTAPI_VOIDRETURN;
|
|
}
|
|
title = [NSString stringWithUTF8String: name];
|
|
if(!title) {
|
|
__glutFatalError("out of memory");
|
|
}
|
|
[__glutCurrentMenu setMenuItemAtIndex: entry - 1 toTitle: title menu: submenu];
|
|
GLUTAPI_END
|
|
}
|
|
|
|
void APIENTRY glutRemoveMenuItem(int entry)
|
|
{
|
|
GLUTAPI_DECLARATIONS
|
|
GLUTAPI_BEGIN
|
|
if(__glutMappedMenu) {
|
|
__glutMenuModificationError();
|
|
}
|
|
|
|
[__glutCurrentMenu removeMenuItemAtIndex: entry - 1];
|
|
GLUTAPI_END
|
|
}
|
|
|
|
void APIENTRY glutMenuStatusFunc(void (*func)(int status, int x, int y))
|
|
{
|
|
__glutMenuStatusFunc = func;
|
|
}
|
|
|
|
void APIENTRY glutMenuStateFunc(void (*func)(int status))
|
|
{
|
|
__glutMenuStatusFunc = (GLUTmenuStatusCB) func;
|
|
}
|
|
/* ENDCENTRY */
|