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

📄 glut_menu.c

📁 mesa-6.5-minigui源码
💻 C
📖 第 1 页 / 共 2 页
字号:
  } else {    changes.x = x;  }  /* Rember where the menu is placed so submenus can be     properly placed relative to it. */  menu->x = changes.x;  menu->y = changes.y;  XConfigureWindow(__glutDisplay, menu->win, mask, &changes);  XInstallColormap(__glutDisplay, menuColormap);  /* XXX The XRaiseWindow below should not be necessary because     the XConfigureWindow requests an Above stack mode (same as     XRaiseWindow), but some Sun users complained this was still     necessary.  Probably some window manager or X server bug on     these machines?? */  XRaiseWindow(__glutDisplay, menu->win);  XMapWindow(__glutDisplay, menu->win);}static voidstartMenu(GLUTmenu * menu, GLUTwindow * window,  int x, int y, int x_win, int y_win){  int grab;  assert(__glutMappedMenu == NULL);  grab = XGrabPointer(__glutDisplay, __glutRoot, True,    ButtonPressMask | ButtonReleaseMask,    GrabModeAsync, GrabModeAsync,    __glutRoot, menuCursor, CurrentTime);  if (grab != GrabSuccess) {    /* Somebody else has pointer grabbed, ignore menu       activation. */    return;  }  __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);}static voidpaintSubMenuArrow(Window win, int x, int y){  XPoint p[5];  p[0].x = p[4].x = x;  p[0].y = p[4].y = y - menuFont->ascent + 1;  p[1].x = p[0].x + MENU_ARROW_WIDTH - 1;  p[1].y = p[0].y + (menuFont->ascent / 2) - 1;  p[2].x = p[1].x;  p[2].y = p[1].y + 1;  p[3].x = p[0].x;  p[3].y = p[0].y + menuFont->ascent - 2;  XFillPolygon(__glutDisplay, win,    whiteGC, p, 4, Convex, CoordModeOrigin);  XDrawLines(__glutDisplay, win, blackGC, p, 5, CoordModeOrigin);}static voidpaintMenuItem(GLUTmenuItem * item, int num){  Window win = item->menu->win;  GC gc;  int y;  int subMenuExtension;  if (item->menu->submenus > 0) {    subMenuExtension = MENU_ARROW_GAP + MENU_ARROW_WIDTH;  } else {    subMenuExtension = 0;  }  if (item->menu->highlighted == item) {    gc = whiteGC;  } else {    gc = grayGC;  }  y = MENU_GAP + fontHeight * num - menuFont->descent;  XFillRectangle(__glutDisplay, win, gc,    MENU_GAP, y - fontHeight + menuFont->descent,    item->menu->pixwidth + subMenuExtension, fontHeight);  XDrawString(__glutDisplay, win, blackGC,    MENU_GAP, y, item->label, item->len);  if (item->isTrigger) {    paintSubMenuArrow(win,      item->menu->pixwidth + MENU_ARROW_GAP + 1, y);  }}static voidpaintMenu(GLUTmenu * menu){  GLUTmenuItem *item;  int i = menu->num;  int y = MENU_GAP + fontHeight * i - menuFont->descent;  item = menu->list;  while (item) {    if (item->menu->highlighted == item) {      paintMenuItem(item, i);    } else {      /* Quick render of the menu item; assume background         already cleared to gray. */      XDrawString(__glutDisplay, menu->win, blackGC,        2, y, item->label, item->len);      if (item->isTrigger) {        paintSubMenuArrow(menu->win,          menu->pixwidth + MENU_ARROW_GAP + 1, y);      }    }    i--;    y -= fontHeight;    item = item->next;  }}static GLUTmenuItem *getMenuItem(GLUTmenu * menu, Window win, int *which){  GLUTmenuItem *item;  int i;  if (menu->searched) {    __glutFatalError("submenu infinite loop detected");  }  menu->searched = True;  i = menu->num;  item = menu->list;  while (item) {    if (item->win == win) {      *which = i;      menu->searched = False;      return item;    }    if (item->isTrigger) {      GLUTmenuItem *subitem;      subitem = __glutGetMenuItem(__glutMenuList[item->value],        win, which);      if (subitem) {        menu->searched = False;        return subitem;      }    }    i--;    item = item->next;  }  menu->searched = False;  return NULL;}static intgetMenuItemIndex(GLUTmenuItem * item){  int count = 0;  while (item) {    count++;    item = item->next;  }  return count;}static GLUTmenu *getMenu(Window win){  GLUTmenu *menu;  menu = __glutMappedMenu;  while (menu) {    if (win == menu->win) {      return menu;    }    menu = menu->cascade;  }  return NULL;}static GLUTmenu *getMenuByNum(int menunum){  if (menunum < 1 || menunum > menuListSize) {    return NULL;  }  return __glutMenuList[menunum - 1];}static intgetUnusedMenuSlot(void){  int i;  /* Look for allocated, unused slot. */  for (i = 0; i < menuListSize; i++) {    if (!__glutMenuList[i]) {      return i;    }  }  /* Allocate a new slot. */  menuListSize++;  if (__glutMenuList) {    __glutMenuList = (GLUTmenu **)      realloc(__glutMenuList, 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. */    __glutMenuList = (GLUTmenu **) malloc(sizeof(GLUTmenu *));  }  if (!__glutMenuList) {    __glutFatalError("out of memory.");  }  __glutMenuList[menuListSize - 1] = NULL;  return menuListSize - 1;}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.");}static voidmenuItemEnterOrLeave(GLUTmenuItem * item,  int num, int type){  int alreadyUp = 0;  if (type == EnterNotify) {    GLUTmenuItem *prevItem = item->menu->highlighted;    if (prevItem && prevItem != item) {      /* If there's an already higlighted item in this menu         that is different from this one (we could be         re-entering an item with an already cascaded         submenu!), unhighlight the previous item. */      item->menu->highlighted = NULL;      paintMenuItem(prevItem, getMenuItemIndex(prevItem));    }    item->menu->highlighted = item;    __glutItemSelected = item;    if (item->menu->cascade) {      if (!item->isTrigger) {        /* Entered a menu item that is not a submenu trigger,           so pop down the current submenu cascade of this           menu.  */        unmapMenu(item->menu->cascade);        item->menu->cascade = NULL;      } else {        GLUTmenu *submenu = __glutMenuList[item->value];        if (submenu->anchor == item) {          /* We entered the submenu trigger for the submenu             that is already up, so don't take down the             submenu.  */          alreadyUp = 1;        } else {          /* Submenu already popped up for some other submenu             item of this menu; need to pop down that other             submenu cascade.  */          unmapMenu(item->menu->cascade);          item->menu->cascade = NULL;        }      }    }    if (!alreadyUp) {      /* Make sure the menu item gets painted with         highlighting. */      paintMenuItem(item, num);    } else {      /* If already up, should already be highlighted.  */    }  } else {    /* LeaveNotify: Handle leaving a menu item...  */    if (item->menu->cascade &&      item->menu->cascade->anchor == item) {      /* If there is a submenu casacaded from this item, do not         change the highlighting on this item upon leaving. */    } else {      /* Unhighlight this menu item.  */      item->menu->highlighted = NULL;      paintMenuItem(item, num);    }    __glutItemSelected = NULL;  }  if (item->isTrigger) {    if (type == EnterNotify && !alreadyUp) {      GLUTmenu *submenu = __glutMenuList[item->value];      mapMenu(submenu,        item->menu->x + item->menu->pixwidth +        MENU_ARROW_GAP + MENU_ARROW_WIDTH +        MENU_GAP + MENU_BORDER,        item->menu->y + fontHeight * (num - 1) + MENU_GAP);      item->menu->cascade = submenu;      submenu->anchor = item;    }  }}/* Installs callback functions for use by glut_event.c  The point   of this is so that GLUT's menu code only gets linked into   GLUT binaries (assuming a static library) if the GLUT menu   API is used. */static voidinstallMenuCallbacks(void){  __glutMenuItemEnterOrLeave = menuItemEnterOrLeave;  __glutFinishMenu = finishMenu;  __glutPaintMenu = paintMenu;  __glutStartMenu = startMenu;  __glutGetMenuByNum = getMenuByNum;  __glutGetMenu = getMenu;  __glutGetMenuItem = getMenuItem;}int GLUTAPIENTRY glutCreateMenu(GLUTselectCB selectFunc){  XSetWindowAttributes wa;  GLUTmenu *menu;  int menuid;  if (__glutMappedMenu) {    __glutMenuModificationError();  }  if (!__glutDisplay) {    __glutOpenXConnection(NULL);  }  installMenuCallbacks();  menuid = getUnusedMenuSlot();  menu = (GLUTmenu *) malloc(sizeof(GLUTmenu));  if (!menu) {    __glutFatalError("out of memory.");  }  menu->id = menuid;  menu->num = 0;  menu->submenus = 0;  menu->managed = False;  menu->searched = False;  menu->pixwidth = 0;  menu->select = selectFunc;  menu->list = NULL;  menu->cascade = NULL;  menu->highlighted = NULL;  menu->anchor = NULL;  menuSetup();  wa.override_redirect = True;  wa.background_pixel = menuGray;  wa.border_pixel = menuBlack;  wa.colormap = menuColormap;  wa.event_mask = StructureNotifyMask | ExposureMask |    ButtonPressMask | ButtonReleaseMask |    EnterWindowMask | LeaveWindowMask;  /* Save unders really only enabled if useSaveUnders is set to     CWSaveUnder, ie. using Mesa 3D.  See earlier comments. */  wa.save_under = True;  menu->win = XCreateWindow(__glutDisplay, __glutRoot,  /* Real position determined when mapped. */    0, 0,  /* Real size will be determined when menu is manged. */    1, 1,    MENU_BORDER, menuDepth, InputOutput, menuVisual,    CWOverrideRedirect | CWBackPixel | CWBorderPixel |    CWEventMask | CWColormap | useSaveUnders,    &wa);  menuGraphicsContextSetup(menu->win);  __glutMenuList[menuid] = menu;  __glutSetMenu(menu);  return menuid + 1;}/* CENTRY */int GLUTAPIENTRY glutGetMenu(void){  if (__glutCurrentMenu) {    return __glutCurrentMenu->id + 1;  } else {    return 0;  }}void GLUTAPIENTRY glutSetMenu(int menuid){  GLUTmenu *menu;  if (menuid < 1 || menuid > menuListSize) {    __glutWarning("glutSetMenu attempted on bogus menu.");    return;  }  menu = __glutMenuList[menuid - 1];  if (!menu) {    __glutWarning("glutSetMenu attempted on bogus menu.");    return;  }  __glutSetMenu(menu);}/* ENDCENTRY */void__glutSetMenuItem(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->pixwidth = XTextWidth(menuFont, label, item->len) + 4;  if (item->pixwidth > menu->pixwidth) {    menu->pixwidth = item->pixwidth;  }  menu->managed = False;}/* CENTRY */void GLUTAPIENTRY glutAddMenuEntry(const char *label, int value){  XSetWindowAttributes wa;  GLUTmenuItem *entry;  if (__glutMappedMenu) {    __glutMenuModificationError();  }  entry = (GLUTmenuItem *) malloc(sizeof(GLUTmenuItem));  if (!entry) {    __glutFatalError("out of memory.");  }  entry->menu = __glutCurrentMenu;  __glutSetMenuItem(entry, label, value, False);  wa.event_mask = EnterWindowMask | LeaveWindowMask;  entry->win = XCreateWindow(__glutDisplay,    __glutCurrentMenu->win, MENU_GAP,    __glutCurrentMenu->num * fontHeight + MENU_GAP,  /* x & y */    entry->pixwidth, fontHeight,  /* width & height */    0, CopyFromParent, InputOnly, CopyFromParent,    CWEventMask, &wa);  XMapWindow(__glutDisplay, entry->win);  __glutCurrentMenu->num++;  entry->next = __glutCurrentMenu->list;  __glutCurrentMenu->list = entry;}void GLUTAPIENTRY glutAddSubMenu(const char *label, int menu){  XSetWindowAttributes wa;  GLUTmenuItem *submenu;  if (__glutMappedMenu) {    __glutMenuModificationError();  }  submenu = (GLUTmenuItem *) malloc(sizeof(GLUTmenuItem));  if (!submenu) {    __glutFatalError("out of memory.");  }  __glutCurrentMenu->submenus++;  submenu->menu = __glutCurrentMenu;  __glutSetMenuItem(submenu, label, /* base 0 */ menu - 1, True);  wa.event_mask = EnterWindowMask | LeaveWindowMask;  submenu->win = XCreateWindow(__glutDisplay,    __glutCurrentMenu->win, MENU_GAP,    __glutCurrentMenu->num * fontHeight + MENU_GAP,  /* x & y */    submenu->pixwidth, fontHeight,  /* width & height */    0, CopyFromParent, InputOnly, CopyFromParent,    CWEventMask, &wa);  XMapWindow(__glutDisplay, submenu->win);  __glutCurrentMenu->num++;  submenu->next = __glutCurrentMenu->list;  __glutCurrentMenu->list = submenu;}void GLUTAPIENTRY glutAttachMenu(int button){  if (__glutMappedMenu) {    __glutMenuModificationError();  }  installMenuCallbacks();  if (__glutCurrentWindow->menu[button] < 1) {    __glutCurrentWindow->buttonUses++;  }  __glutChangeWindowEventMask(    ButtonPressMask | ButtonReleaseMask, True);  __glutCurrentWindow->menu[button] = __glutCurrentMenu->id + 1;}/* ENDCENTRY */

⌨️ 快捷键说明

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