Doxygen Source Code Documentation
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.
Define Documentation
|
Definition at line 326 of file glut_menu.c. Referenced by __glutMenuItemEnterOrLeave(), __glutPaintMenu(), mapMenu(), and paintMenuItem(). |
|
Definition at line 327 of file glut_menu.c. Referenced by __glutMenuItemEnterOrLeave(), mapMenu(), paintMenuItem(), and paintSubMenuArrow(). |
|
Definition at line 324 of file glut_menu.c. Referenced by __glutMenuItemEnterOrLeave(), and glutCreateMenu(). |
|
Definition at line 325 of file glut_menu.c. Referenced by __glutMenuItemEnterOrLeave(), __glutPaintMenu(), glutAddMenuEntry(), glutAddSubMenu(), mapMenu(), and paintMenuItem(). |
Function Documentation
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
Definition at line 253 of file glut_menu.c. Referenced by __glutFinishMenu(), __glutStartMenu(), glutCreateMenu(), and glutSetMenu().
00254 { 00255 __glutCurrentMenu = menu; 00256 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
Definition at line 241 of file glut_menu.c. References __glutMenuStatusFunc, and GLUTmenuStateCB.
00242 { 00243 __glutMenuStatusFunc = (GLUTmenuStatusCB) menuStateFunc; 00244 } |
|
Definition at line 247 of file glut_menu.c. References __glutMenuStatusFunc, and GLUTmenuStatusCB.
00248 { 00249 __glutMenuStatusFunc = menuStatusFunc; 00250 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
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 } |
|
Definition at line 259 of file glut_menu.c. References _GLUTmenu::anchor, _GLUTmenu::cascade, _GLUTmenu::highlighted, and _GLUTmenu::win. Referenced by __glutFinishMenu(), and __glutMenuItemEnterOrLeave().
|
Variable Documentation
|
Definition at line 22 of file glut_menu.c. |
|
Definition at line 26 of file glut_menu.c. |
|
Definition at line 24 of file glut_menu.c. |
|
Definition at line 23 of file glut_menu.c. Referenced by __glutFinishMenu(), __glutStartMenu(), glutMenuStateFunc(), and glutMenuStatusFunc(). |
|
Definition at line 25 of file glut_menu.c. |
|
Definition at line 36 of file glut_menu.c. Referenced by __glutPaintMenu(), menuGraphicsContextSetup(), paintMenuItem(), and paintSubMenuArrow(). |
|
Definition at line 35 of file glut_menu.c. Referenced by __glutMenuItemEnterOrLeave(), __glutPaintMenu(), glutAddMenuEntry(), glutAddSubMenu(), mapMenu(), menuSetup(), and paintMenuItem(). |
|
Definition at line 36 of file glut_menu.c. Referenced by menuGraphicsContextSetup(), and paintMenuItem(). |
|
Definition at line 37 of file glut_menu.c. Referenced by glutCreateMenu(), menuGraphicsContextSetup(), and menuVisualSetup(). |
|
Definition at line 32 of file glut_menu.c. Referenced by glutCreateMenu(), mapMenu(), and menuVisualSetup(). |
|
Definition at line 31 of file glut_menu.c. Referenced by __glutStartMenu(), and menuSetup(). |
|
Definition at line 34 of file glut_menu.c. Referenced by glutCreateMenu(), and menuVisualSetup(). |
|
Definition at line 30 of file glut_menu.c. Referenced by __glutPaintMenu(), menuGraphicsContextSetup(), menuSetup(), paintMenuItem(), paintSubMenuArrow(), and setMenuItem(). |
|
Definition at line 37 of file glut_menu.c. Referenced by glutCreateMenu(), menuGraphicsContextSetup(), and menuVisualSetup(). |
|
Definition at line 28 of file glut_menu.c. |
|
Definition at line 29 of file glut_menu.c. Referenced by __glutGetMenuByNum(), getUnusedMenuSlot(), and glutSetMenu(). |
|
Definition at line 33 of file glut_menu.c. Referenced by glutCreateMenu(), and menuVisualSetup(). |
|
Definition at line 37 of file glut_menu.c. Referenced by menuGraphicsContextSetup(), and menuVisualSetup(). |
|
Definition at line 38 of file glut_menu.c. Referenced by glutCreateMenu(), and menuVisualSetup(). |
|
Definition at line 36 of file glut_menu.c. Referenced by menuGraphicsContextSetup(), paintMenuItem(), and paintSubMenuArrow(). |