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

📄 glut_event.c

📁 mesa-6.5-minigui源码
💻 C
📖 第 1 页 / 共 3 页
字号:
/* Copyright (c) Mark J. Kilgard, 1994, 1995, 1996, 1997, 1998. *//* 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. */#ifdef __VMS#include <GL/vms_x_fix.h>#endif#include <stdlib.h>#include <stdio.h>#include <errno.h>#include <assert.h>#include <string.h>  /* Some FD_ZERO macros use memset without                        prototyping memset. *//* Much of the following #ifdef logic to include the proper   prototypes for the select system call is based on logic   from the X11R6.3 version of <X11/Xpoll.h>. */#if !defined(_WIN32)# ifdef __sgi#  include <bstring.h>    /* prototype for bzero used by FD_ZERO */# endif# if (defined(SVR4) || defined(CRAY) || defined(AIXV3)) && !defined(FD_SETSIZE)#  include <sys/select.h> /* select system call interface */#  ifdef luna#   include <sysent.h>#  endif# endif  /* AIX 4.2 fubar-ed <sys/select.h>, so go to heroic measures to get it */# if defined(AIXV4) && !defined(NFDBITS)#  include <sys/select.h># endif#endif /* !_WIN32 */#include <sys/types.h>#if !defined(_WIN32)# if defined(__vms) && ( __VMS_VER < 70000000 )#  include <sys/time.h># else#  ifndef __vms#   include <sys/time.h>#  endif# endif# include <unistd.h># include <X11/Xlib.h># include <X11/keysym.h>#else# ifdef __CYGWIN32__#  include <sys/time.h># else#  include <sys/timeb.h># endif# ifdef __hpux   /* XXX Bert Gijsbers <bert@mc.bio.uva.nl> reports that HP-UX      needs different keysyms for the End, Insert, and Delete keys      to work on an HP 715.  It would be better if HP generated      standard keysyms for standard keys. */#  include <X11/HPkeysym.h># endif#endif /* !_WIN32 */#include "glutint.h"#if defined(__vms) && ( __VMS_VER < 70000000 )#include <ssdef.h>#include <psldef.h>extern int SYS$CLREF(int efn);extern int SYS$SETIMR(unsigned int efn, struct timeval6 *timeout, void *ast,  unsigned int request_id, unsigned int flags);extern int SYS$WFLOR(unsigned int efn, unsigned int mask);extern int SYS$CANTIM(unsigned int request_id, unsigned int mode);#endif /* __vms, VMs 6.2 or earlier */static GLUTtimer *freeTimerList = NULL;GLUTidleCB __glutIdleFunc = NULL;GLUTtimer *__glutTimerList = NULL;#ifdef SUPPORT_FORTRANGLUTtimer *__glutNewTimer;#endifGLUTwindow *__glutWindowWorkList = NULL;GLUTmenu *__glutMappedMenu;GLUTmenu *__glutCurrentMenu = NULL;void (*__glutUpdateInputDeviceMaskFunc) (GLUTwindow *);#if !defined(_WIN32)void (*__glutMenuItemEnterOrLeave)(GLUTmenuItem * item, int num, int type) = NULL;void (*__glutFinishMenu)(Window win, int x, int y);void (*__glutPaintMenu)(GLUTmenu * menu);void (*__glutStartMenu)(GLUTmenu * menu, GLUTwindow * window, int x, int y, int x_win, int y_win);GLUTmenu * (*__glutGetMenuByNum)(int menunum);GLUTmenuItem * (*__glutGetMenuItem)(GLUTmenu * menu, Window win, int *which);GLUTmenu * (*__glutGetMenu)(Window win);#endifAtom __glutMotifHints = None;/* Modifier mask of ~0 implies not in core input callback. */unsigned int __glutModifierMask = (unsigned int) ~0;int __glutWindowDamaged = 0;void GLUTAPIENTRYglutIdleFunc(GLUTidleCB idleFunc){  __glutIdleFunc = idleFunc;}void GLUTAPIENTRYglutTimerFunc(unsigned int interval, GLUTtimerCB timerFunc, int value){  GLUTtimer *timer, *other;  GLUTtimer **prevptr;#ifdef OLD_VMS   struct timeval6 now;#else   struct timeval now;#endif     if (!timerFunc)    return;  if (freeTimerList) {    timer = freeTimerList;    freeTimerList = timer->next;  } else {    timer = (GLUTtimer *) malloc(sizeof(GLUTtimer));    if (!timer)      __glutFatalError("out of memory.");  }  timer->func = timerFunc;#if defined(__vms) && ( __VMS_VER < 70000000 )  /* VMS time is expressed in units of 100 ns */  timer->timeout.val = interval * TICKS_PER_MILLISECOND;#else  timer->timeout.tv_sec = (int) interval / 1000;  timer->timeout.tv_usec = (int) (interval % 1000) * 1000;#endif  timer->value = value;  timer->next = NULL;  GETTIMEOFDAY(&now);  ADD_TIME(timer->timeout, timer->timeout, now);  prevptr = &__glutTimerList;  other = *prevptr;  while (other && IS_AFTER(other->timeout, timer->timeout)) {    prevptr = &other->next;    other = *prevptr;  }  timer->next = other;#ifdef SUPPORT_FORTRAN  __glutNewTimer = timer;  /* for Fortran binding! */#endif  *prevptr = timer;}voidhandleTimeouts(void){#ifdef OLD_VMS   struct timeval6 now;#else   struct timeval now;#endif   GLUTtimer *timer;  /* Assumption is that __glutTimerList is already determined     to be non-NULL. */  GETTIMEOFDAY(&now);  while (IS_AT_OR_AFTER(__glutTimerList->timeout, now)) {    timer = __glutTimerList;    __glutTimerList = timer->next;    timer->func(timer->value);    timer->next = freeTimerList;    freeTimerList = timer;    if (!__glutTimerList)      break;  }}void__glutPutOnWorkList(GLUTwindow * window, int workMask){  if (window->workMask) {    /* Already on list; just OR in new workMask. */    window->workMask |= workMask;  } else {    /* Update work mask and add to window work list. */    window->workMask = workMask;    /* Assert that if the window does not have a       workMask already, the window should definitely       not be the head of the work list. */    assert(window != __glutWindowWorkList);    window->prevWorkWin = __glutWindowWorkList;    __glutWindowWorkList = window;  }}void__glutPostRedisplay(GLUTwindow * window, int layerMask){  int shown = (layerMask & (GLUT_REDISPLAY_WORK | GLUT_REPAIR_WORK)) ?    window->shownState : window->overlay->shownState;  /* Post a redisplay if the window is visible (or the     visibility of the window is unknown, ie. window->visState     == -1) _and_ the layer is known to be shown. */  if (window->visState != GLUT_HIDDEN    && window->visState != GLUT_FULLY_COVERED && shown) {    __glutPutOnWorkList(window, layerMask);  }}/* CENTRY */void GLUTAPIENTRYglutPostRedisplay(void){  __glutPostRedisplay(__glutCurrentWindow, GLUT_REDISPLAY_WORK);}/* The advantage of this routine is that it saves the cost of a   glutSetWindow call (entailing an expensive OpenGL context switch),   particularly useful when multiple windows need redisplays posted at   the same times.  See also glutPostWindowOverlayRedisplay. */void GLUTAPIENTRYglutPostWindowRedisplay(int win){  __glutPostRedisplay(__glutWindowList[win - 1], GLUT_REDISPLAY_WORK);}/* ENDCENTRY */static GLUTeventParser *eventParserList = NULL;/* __glutRegisterEventParser allows another module to register   to intercept X events types not otherwise acted on by the   GLUT processEventsAndTimeouts routine.  The X Input   extension support code uses an event parser for handling X   Input extension events.  */void__glutRegisterEventParser(GLUTeventParser * parser){  parser->next = eventParserList;  eventParserList = parser;}static voidmarkWindowHidden(GLUTwindow * window){  if (GLUT_HIDDEN != window->visState) {    GLUTwindow *child;    if (window->windowStatus) {      window->visState = GLUT_HIDDEN;      __glutSetWindow(window);      window->windowStatus(GLUT_HIDDEN);    }    /* An unmap is only reported on a single window; its       descendents need to know they are no longer visible. */    child = window->children;    while (child) {      markWindowHidden(child);      child = child->siblings;    }  }}#if !defined(_WIN32)static voidpurgeStaleWindow(Window win){  GLUTstale **pEntry = &__glutStaleWindowList;  GLUTstale *entry = __glutStaleWindowList;  /* Tranverse singly-linked stale window list look for the     window ID. */  while (entry) {    if (entry->win == win) {      /* Found it; delete it. */      *pEntry = entry->next;      free(entry);      return;    } else {      pEntry = &entry->next;      entry = *pEntry;    }  }}/* Unlike XNextEvent, if a signal arrives,   interruptibleXNextEvent will return (with a zero return   value).  This helps GLUT drop out of XNextEvent if a signal   is delivered.  The intent is so that a GLUT program can call    glutIdleFunc in a signal handler to register an idle func   and then immediately get dropped into the idle func (after   returning from the signal handler).  The idea is to make   GLUT's main loop reliably interruptible by signals. */static intinterruptibleXNextEvent(Display * dpy, XEvent * event){  fd_set fds;  int rc;  /* Flush X protocol since XPending does not do this     implicitly. */  XFlush(__glutDisplay);  for (;;) {    if (XPending(__glutDisplay)) {      XNextEvent(dpy, event);      return 1;    }#ifndef VMS    /* the combination ConectionNumber-select is buggy on VMS. Sometimes it     * fails. This part of the code hangs the program on VMS7.2. But even     * without it the program seems to run correctly.     * Note that this is a bug in the VMS/DECWindows run-time-libraries.     * Compaq engeneering does not want or is not able to make a fix.     * (last sentence is a quotation from Compaq when I reported the     * problem January 2000) */    FD_ZERO(&fds);    FD_SET(__glutConnectionFD, &fds);    rc = select(__glutConnectionFD + 1, &fds, NULL, NULL, NULL);    if (rc < 0) {      if (errno == EINTR) {        return 0;      } else {        __glutFatalError("select error.");      }    }#endif  }}#endifstatic voidprocessEventsAndTimeouts(void){  do {#if defined(_WIN32)    MSG event;    if(!GetMessage(&event, NULL, 0, 0))	/* bail if no more messages */      exit(0);    TranslateMessage(&event);		/* translate virtual-key messages */    DispatchMessage(&event);		/* call the window proc */    /* see win32_event.c for event (message) processing procedures */#else    static int mappedMenuButton;    GLUTeventParser *parser;    XEvent event, ahead;    GLUTwindow *window;    GLUTkeyboardCB keyboard;    GLUTspecialCB special;    int gotEvent, width, height;    gotEvent = interruptibleXNextEvent(__glutDisplay, &event);    if (gotEvent) {      switch (event.type) {      case MappingNotify:        XRefreshKeyboardMapping((XMappingEvent *) & event);        break;      case ConfigureNotify:        window = __glutGetWindow(event.xconfigure.window);        if (window) {          if (window->win != event.xconfigure.window) {            /* Ignore ConfigureNotify sent to the overlay               planes. GLUT could get here because overlays               select for StructureNotify events to receive               DestroyNotify. */            break;          }          width = event.xconfigure.width;          height = event.xconfigure.height;          if (width != window->width || height != window->height) {            if (window->overlay) {              XResizeWindow(__glutDisplay, window->overlay->win, width, height);            }            window->width = width;            window->height = height;            __glutSetWindow(window);            /* Do not execute OpenGL out of sequence with               respect to the XResizeWindow request! */            glXWaitX();            window->reshape(width, height);            window->forceReshape = False;            /* A reshape should be considered like posting a               repair; this is necessary for the "Mesa               glXSwapBuffers to repair damage" hack to operate               correctly.  Without it, there's not an initial               back buffer render from which to blit from when               damage happens to the window. */            __glutPostRedisplay(window, GLUT_REPAIR_WORK);          }        }        break;      case Expose:        /* compress expose events */        while (XEventsQueued(__glutDisplay, QueuedAfterReading)          > 0) {          XPeekEvent(__glutDisplay, &ahead);          if (ahead.type != Expose ||            ahead.xexpose.window != event.xexpose.window) {            break;          }          XNextEvent(__glutDisplay, &event);        }        if (event.xexpose.count == 0) {          GLUTmenu *menu;          if (__glutMappedMenu &&            (menu = __glutGetMenu(event.xexpose.window))) {            __glutPaintMenu(menu);          } else {            window = __glutGetWindow(event.xexpose.window);            if (window) {              if (window->win == event.xexpose.window) {                __glutPostRedisplay(window, GLUT_REPAIR_WORK);              } else if (window->overlay && window->overlay->win == event.xexpose.window) {                __glutPostRedisplay(window, GLUT_OVERLAY_REPAIR_WORK);              }            }          }        } else {          /* there are more exposes to read; wait to redisplay */        }        break;      case ButtonPress:      case ButtonRelease:        if (__glutMappedMenu && event.type == ButtonRelease          && mappedMenuButton == event.xbutton.button) {          /* Menu is currently popped up and its button is             released. */          __glutFinishMenu(event.xbutton.window, event.xbutton.x, event.xbutton.y);        } else {          window = __glutGetWindow(event.xbutton.window);          if (window) {            GLUTmenu *menu;	    int menuNum;            menuNum = window->menu[event.xbutton.button - 1];            /* Make sure that __glutGetMenuByNum is only called if there	       really is a menu present. */            if ((menuNum > 0) && (menu = __glutGetMenuByNum(menuNum))) {              if (event.type == ButtonPress && !__glutMappedMenu) {                __glutStartMenu(menu, window,                  event.xbutton.x_root, event.xbutton.y_root,                  event.xbutton.x, event.xbutton.y);                mappedMenuButton = event.xbutton.button;              } else {                /* Ignore a release of a button with a menu                   attatched to it when no menu is popped up,                   or ignore a press when another menu is                   already popped up. */              }            } else if (window->mouse) {

⌨️ 快捷键说明

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