⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 win32_menu.c

📁 mesa-6.5-minigui源码
💻 C
字号:
/* Copyright (c) Mark J. Kilgard, 1994, 1997, 1998. *//* Copyright (c) Nate Robins, 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. *//* This file completely re-implements glut_menu.c and glut_menu2.c   for Win32.  Note that neither glut_menu.c nor glut_menu2.c are   compiled into Win32 GLUT. */#include <stdlib.h>#include <string.h>#include <stdio.h>#include <errno.h>#include <assert.h>#include "glutint.h"void (GLUTCALLBACK *__glutMenuStatusFunc) (int, int, int);GLUTmenu *__glutMappedMenu;GLUTwindow *__glutMenuWindow;GLUTmenuItem *__glutItemSelected;unsigned __glutMenuButton;static GLUTmenu **menuList = NULL;static int menuListSize = 0;static UINT uniqueMenuHandler = 1;/* DEPRICATED, use glutMenuStatusFunc instead. */void GLUTAPIENTRYglutMenuStateFunc(GLUTmenuStateCB menuStateFunc){  __glutMenuStatusFunc = (GLUTmenuStatusCB) menuStateFunc;}void GLUTAPIENTRYglutMenuStatusFunc(GLUTmenuStatusCB menuStatusFunc){  __glutMenuStatusFunc = menuStatusFunc;}void__glutSetMenu(GLUTmenu * menu){  __glutCurrentMenu = menu;}static voidunmapMenu(GLUTmenu * menu){  if (menu->cascade) {    unmapMenu(menu->cascade);    menu->cascade = NULL;  }  menu->anchor = NULL;  menu->highlighted = NULL;}void__glutFinishMenu(Window win, int x, int y){  unmapMenu(__glutMappedMenu);  /* XXX Put in a GdiFlush just in case.  Probably unnecessary. -mjk  */  GdiFlush();  if (__glutMenuStatusFunc) {    __glutSetWindow(__glutMenuWindow);    __glutSetMenu(__glutMappedMenu);    /* Setting __glutMappedMenu to NULL permits operations that       change menus or destroy the menu window again. */    __glutMappedMenu = NULL;    __glutMenuStatusFunc(GLUT_MENU_NOT_IN_USE, x, y);  }  /* Setting __glutMappedMenu to NULL permits operations that     change menus or destroy the menu window again. */  __glutMappedMenu = NULL;  /* If an item is selected and it is not a submenu trigger,     generate menu callback. */  if (__glutItemSelected && !__glutItemSelected->isTrigger) {    __glutSetWindow(__glutMenuWindow);    /* When menu callback is triggered, current menu should be       set to the callback menu. */    __glutSetMenu(__glutItemSelected->menu);    __glutItemSelected->menu->select(__glutItemSelected->value);  }  __glutMenuWindow = NULL;}static voidmapMenu(GLUTmenu * menu, int x, int y){  TrackPopupMenu((HMENU) menu->win, TPM_LEFTALIGN |    (__glutMenuButton == TPM_RIGHTBUTTON) ? TPM_RIGHTBUTTON : TPM_LEFTBUTTON,    x, y, 0, __glutCurrentWindow->win, NULL);}void__glutStartMenu(GLUTmenu * menu, GLUTwindow * window,		int x, int y, int x_win, int y_win){  assert(__glutMappedMenu == NULL);  __glutMappedMenu = menu;  __glutMenuWindow = window;  __glutItemSelected = NULL;  if (__glutMenuStatusFunc) {    __glutSetMenu(menu);    __glutSetWindow(window);    __glutMenuStatusFunc(GLUT_MENU_IN_USE, x_win, y_win);  }  mapMenu(menu, x, y);}GLUTmenuItem *__glutGetUniqueMenuItem(GLUTmenu * menu, UINT unique){  GLUTmenuItem *item;  int i;  i = menu->num;  item = menu->list;  while (item) {    if (item->unique == unique) {      return item;    }    if (item->isTrigger) {      GLUTmenuItem *subitem;      subitem = __glutGetUniqueMenuItem(menuList[item->value], unique);      if (subitem) {        return subitem;      }    }    i--;    item = item->next;  }  return NULL;}GLUTmenuItem *__glutGetMenuItem(GLUTmenu * menu, Window win, int *which){  GLUTmenuItem *item;  int i;  i = menu->num;  item = menu->list;  while (item) {    if (item->win == win) {      *which = i;      return item;    }    if (item->isTrigger) {      GLUTmenuItem *subitem;      subitem = __glutGetMenuItem(menuList[item->value],        win, which);      if (subitem) {        return subitem;      }    }    i--;    item = item->next;  }  return NULL;}GLUTmenu *__glutGetMenu(Window win){  GLUTmenu *menu;  menu = __glutMappedMenu;  while (menu) {    if (win == menu->win) {      return menu;    }    menu = menu->cascade;  }  return NULL;}GLUTmenu *__glutGetMenuByNum(int menunum){  if (menunum < 1 || menunum > menuListSize) {    return NULL;  }  return menuList[menunum - 1];}static intgetUnusedMenuSlot(void){  int i;  /* Look for allocated, unused slot. */  for (i = 0; i < menuListSize; i++) {    if (!menuList[i]) {      return i;    }  }  /* Allocate a new slot. */  menuListSize++;  if (menuList) {    menuList = (GLUTmenu **)      realloc(menuList, menuListSize * sizeof(GLUTmenu *));  } else {    /* XXX Some realloc's do not correctly perform a malloc       when asked to perform a realloc on a NULL pointer,       though the ANSI C library spec requires this. */    menuList = (GLUTmenu **) malloc(sizeof(GLUTmenu *));  }  if (!menuList) {    __glutFatalError("out of memory.");  }  menuList[menuListSize - 1] = NULL;  return menuListSize - 1;}static voidmenuModificationError(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.");}int GLUTAPIENTRYglutCreateMenu(GLUTselectCB selectFunc){  GLUTmenu *menu;  int menuid;  if (__glutMappedMenu) {    menuModificationError();  }  menuid = getUnusedMenuSlot();  menu = (GLUTmenu *) malloc(sizeof(GLUTmenu));  if (!menu) {    __glutFatalError("out of memory.");  }  menu->id = menuid;  menu->num = 0;  menu->submenus = 0;  menu->select = selectFunc;  menu->list = NULL;  menu->cascade = NULL;  menu->highlighted = NULL;  menu->anchor = NULL;  menu->win = (HWND) CreatePopupMenu();  menuList[menuid] = menu;  __glutSetMenu(menu);  return menuid + 1;}int GLUTAPIENTRY__glutCreateMenuWithExit(GLUTselectCB selectFunc, void (__cdecl *exitfunc)(int)){  __glutExitFunc = exitfunc;  return glutCreateMenu(selectFunc);}void GLUTAPIENTRYglutDestroyMenu(int menunum){  GLUTmenu *menu = __glutGetMenuByNum(menunum);  GLUTmenuItem *item, *next;  if (__glutMappedMenu) {    menuModificationError();  }  assert(menu->id == menunum - 1);  DestroyMenu( (HMENU) menu->win);  menuList[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);}int GLUTAPIENTRYglutGetMenu(void){  if (__glutCurrentMenu) {    return __glutCurrentMenu->id + 1;  } else {    return 0;  }}void GLUTAPIENTRYglutSetMenu(int menuid){  GLUTmenu *menu;  if (menuid < 1 || menuid > menuListSize) {    __glutWarning("glutSetMenu attempted on bogus menu.");    return;  }  menu = menuList[menuid - 1];  if (!menu) {    __glutWarning("glutSetMenu attempted on bogus menu.");    return;  }  __glutSetMenu(menu);}static voidsetMenuItem(GLUTmenuItem * item, const char *label,	    int value, Bool isTrigger){  GLUTmenu *menu;  menu = item->menu;  item->label = __glutStrdup(label);  if (!item->label) {    __glutFatalError("out of memory.");  }  item->isTrigger = isTrigger;  item->len = (int) strlen(label);  item->value = value;  item->unique = uniqueMenuHandler++;  if (isTrigger) {    AppendMenu((HMENU) menu->win, MF_POPUP, (UINT)item->win, label);  } else {    AppendMenu((HMENU) menu->win, MF_STRING, item->unique, label);  }}void GLUTAPIENTRYglutAddMenuEntry(const char *label, int value){  GLUTmenuItem *entry;  if (__glutMappedMenu) {    menuModificationError();  }  entry = (GLUTmenuItem *) malloc(sizeof(GLUTmenuItem));  if (!entry) {    __glutFatalError("out of memory.");  }  entry->menu = __glutCurrentMenu;  setMenuItem(entry, label, value, FALSE);  __glutCurrentMenu->num++;  entry->next = __glutCurrentMenu->list;  __glutCurrentMenu->list = entry;}void GLUTAPIENTRYglutAddSubMenu(const char *label, int menu){  GLUTmenuItem *submenu;  GLUTmenu     *popupmenu;  if (__glutMappedMenu) {    menuModificationError();  }  submenu = (GLUTmenuItem *) malloc(sizeof(GLUTmenuItem));  if (!submenu) {    __glutFatalError("out of memory.");  }  __glutCurrentMenu->submenus++;  submenu->menu = __glutCurrentMenu;  popupmenu = __glutGetMenuByNum(menu);  if (popupmenu) {    submenu->win = popupmenu->win;  }  setMenuItem(submenu, label, /* base 0 */ menu - 1, TRUE);  __glutCurrentMenu->num++;  submenu->next = __glutCurrentMenu->list;  __glutCurrentMenu->list = submenu;}void GLUTAPIENTRYglutChangeToMenuEntry(int num, const char *label, int value){  GLUTmenuItem *item;  int i;  if (__glutMappedMenu) {    menuModificationError();  }  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--;	/* Nuke the Win32 menu. */	DestroyMenu((HMENU) item->win);      }      free(item->label);      item->label = strdup(label);      if (!item->label)	__glutFatalError("out of memory");      item->isTrigger = FALSE;      item->len = (int) strlen(label);      item->value = value;      item->unique = uniqueMenuHandler++;      ModifyMenu((HMENU) __glutCurrentMenu->win, (UINT) i - 1,        MF_BYPOSITION | MFT_STRING, item->unique, label);      return;    }    i--;    item = item->next;  }  __glutWarning("Current menu has no %d item.", num);}void GLUTAPIENTRYglutChangeToSubMenu(int num, const char *label, int menu){  GLUTmenu *popupmenu;  GLUTmenuItem *item;  int i;  if (__glutMappedMenu) {    menuModificationError();  }  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++;	item->win = (HWND) CreatePopupMenu();      }      free(item->label);            item->label = strdup(label);      if (!item->label)	__glutFatalError("out of memory");      item->isTrigger = TRUE;      item->len = (int) strlen(label);      item->value = menu - 1;      item->unique = uniqueMenuHandler++;      popupmenu = __glutGetMenuByNum(menu);      if (popupmenu)	item->win = popupmenu->win;      ModifyMenu((HMENU) __glutCurrentMenu->win, (UINT) i - 1,        MF_BYPOSITION | MF_POPUP, (UINT) item->win, label);      return;    }    i--;    item = item->next;  }  __glutWarning("Current menu has no %d item.", num);}void GLUTAPIENTRYglutRemoveMenuItem(int num){  GLUTmenuItem *item, **prev;  int i;  if (__glutMappedMenu) {    menuModificationError();  }  i = __glutCurrentMenu->num;  prev = &__glutCurrentMenu->list;  item = __glutCurrentMenu->list;  while (item) {    if (i == num) {      /* Found the menu item in list to remove. */      __glutCurrentMenu->num--;      /* Patch up menu's item list. */      *prev = item->next;      RemoveMenu((HMENU) __glutCurrentMenu->win, (UINT) i - 1, MF_BYPOSITION);      free(item->label);      free(item);      return;    }    i--;    prev = &item->next;    item = item->next;  }  __glutWarning("Current menu has no %d item.", num);}void GLUTAPIENTRYglutAttachMenu(int button){  if (__glutCurrentWindow == __glutGameModeWindow) {    __glutWarning("cannot attach menus in game mode.");    return;  }  if (__glutMappedMenu) {    menuModificationError();  }  if (__glutCurrentWindow->menu[button] < 1) {    __glutCurrentWindow->buttonUses++;  }  __glutCurrentWindow->menu[button] = __glutCurrentMenu->id + 1;}void GLUTAPIENTRYglutDetachMenu(int button){  if (__glutMappedMenu) {    menuModificationError();  }  if (__glutCurrentWindow->menu[button] > 0) {    __glutCurrentWindow->buttonUses--;    __glutCurrentWindow->menu[button] = 0;  }}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -