Ejemplo n.º 1
0
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;
}
Ejemplo n.º 2
0
int GLUTAPIENTRY
glutEnterGameMode( void )
{
     DFBDisplayLayerConfig prev, cur;

     glutInit( NULL, NULL );
     
     primary->GetConfiguration( primary, &prev );
     primary->SetCooperativeLevel( primary, DLSCL_EXCLUSIVE );
     
     if (g_game)
          __glutDestroyWindow( g_game );
          
     g_game = __glutCreateWindow( GL_TRUE );
     if (!g_game)
          return 0;
          
     __glutSetWindow( g_game );
     g_game->cursor = GLUT_CURSOR_NONE;

     primary->GetConfiguration( primary, &cur );
     g_display_changed = (cur.width       != prev.width      || 
                          cur.height      != prev.height     ||
                          cur.pixelformat != prev.pixelformat);
     
     return g_game->id;
}
Ejemplo n.º 3
0
void GLUTAPIENTRY 
glutMainLoop( void )
{
     __glutAssert( events != NULL );
     
     __glutHandleWindows();
     
     while (GL_TRUE) {
          DFBEvent evt, prev;
          
          g_idle = GL_TRUE;
          
          __glutHandleTimers();

          prev.clazz = DFEC_NONE;
          
          while (events->GetEvent( events, &evt ) == DFB_OK) {
               g_idle = GL_FALSE;
               
               switch (evt.clazz) {
                    case DFEC_WINDOW:
                         if (prev.clazz == DFEC_WINDOW)
                              __glutWindowEvent( &evt.window, &prev.window );
                         else
                              __glutWindowEvent( &evt.window, NULL );
                         break;
                    case DFEC_INPUT:
                         if (prev.clazz == DFEC_INPUT)
                              __glutInputEvent( &evt.input, &prev.input );
                         else
                              __glutInputEvent( &evt.input, NULL );
                         break;
                    default:
                         __glutWarning( "unexpected event class %d!\n", evt.clazz );
                         break;
               }
               
               prev = evt;
                         
               __glutHandleTimers();
          }
          
          __glutHandleWindows();
          
          if (g_idle) {
               if (idle_func) {
                    idle_func();
               }
               else {
                    int msec;
                    __glutSetWindow( NULL );
                    if (__glutGetTimeout( &msec ))
                         events->WaitForEventWithTimeout( events, msec/1000, msec%1000 );
                    else
                         events->WaitForEvent( events );
               }
          }
     }
}
Ejemplo n.º 4
0
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);
}
Ejemplo n.º 5
0
/* CENTRY */
void GLUTAPIENTRY
glutSetWindow(int win)
{
  GLUTwindow *window;

  if (win < 1 || win > __glutWindowListSize) {
    __glutWarning("glutSetWindow attempted on bogus window.");
    return;
  }
  window = __glutWindowList[win - 1];
  if (!window) {
    __glutWarning("glutSetWindow attempted on bogus window.");
    return;
  }
  __glutSetWindow(window);
}
Ejemplo n.º 6
0
static void
markWindowHidden(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;
    }
  }
}
Ejemplo n.º 7
0
/* ARGSUSED5 */  /* Only Win32 uses gameMode parameter. */
GLUTwindow *
__glutCreateWindow(GLUTwindow * parent,
  int x, int y, int width, int height, int gameMode)
{
  GLUTwindow *window;
  XSetWindowAttributes wa;
  unsigned long attribMask;
  int winnum;
  int i;
#if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_fbconfig)
  GLXFBConfigSGIX fbc;
#else
  void *fbc;
#endif

#if defined(__OS2PM__)
 {
    extern HAB   hab;      /* PM anchor block handle         */
    CLASSINFO classinfo;

    if(!WinQueryClassInfo(hab,"GLUT", &classinfo) )
                               __glutOpenOS2Connection(NULL);
  }
#elif defined(_WIN32)
  WNDCLASS wc;
  int style;

  if (!GetClassInfo(GetModuleHandle(NULL), "GLUT", &wc)) {
    __glutOpenWin32Connection(NULL);
  }
#else
  if (!__glutDisplay) {
    __glutOpenXConnection(NULL);
  }
#endif

#ifndef __OS2PM__
  if (__glutGameModeWindow) {
    __glutFatalError("cannot create windows in game mode.");
  }
#endif

  winnum = getUnusedWindowSlot();
  window = (GLUTwindow *) malloc(sizeof(GLUTwindow));
  if (!window) {
    __glutFatalError("out of memory.");
  }
  window->num = winnum;

#if defined(__OS2PM__)
  /* Add this new window to the window list. */
  __glutWindowList[winnum] = window;
  window->shownState = -1;
#endif

#if !defined(_WIN32)  && !defined(__OS2PM__)
  window->vis = __glutDetermineWindowVisual(&window->treatAsSingle,
    &window->visAlloced, (void**) &fbc);
  if (!window->vis) {
    __glutFatalError(
      "visual with necessary capabilities not found.");
  }
  __glutSetupColormap(window->vis, &window->colormap, &window->cmap);
#endif
  window->eventMask = StructureNotifyMask | ExposureMask;

  attribMask = CWBackPixmap | CWBorderPixel | CWColormap | CWEventMask;
  wa.background_pixmap = None;
  wa.border_pixel = 0;
  wa.colormap = window->cmap;
  wa.event_mask = window->eventMask;
  if (parent) {
    if (parent->eventMask & GLUT_HACK_STOP_PROPAGATE_MASK)
      wa.event_mask |= GLUT_HACK_STOP_PROPAGATE_MASK;
    attribMask |= CWDontPropagate;
    wa.do_not_propagate_mask = parent->eventMask & GLUT_DONT_PROPAGATE_FILTER_MASK;
  } else {
    wa.do_not_propagate_mask = 0;
  }

  /* Stash width and height before Win32's __glutAdjustCoords
     possibly overwrites the values. */
  window->width = width;
  window->height = height;
  window->forceReshape = True;
  window->ignoreKeyRepeat = False;

#if defined(__OS2PM__)

 {  ULONG flStyle=0;
    int ii;
    ERRORID  erridErrorCode;/* last error id code */
    extern HAB   hab;      /* PM anchor block handle         */

  if (parent) {
    flStyle = WS_CLIPCHILDREN|WS_VISIBLE;
  } else {
    if (gameMode) {
      /* Game mode window should be a WS_POPUP window to
         ensure that the taskbar is hidden by it.  A standard
         WS_OVERLAPPEDWINDOW does not hide the task bar. */
      flStyle = FCF_STANDARD |  WS_MAXIMIZED;
    } else {
      /* A standard toplevel window with borders and such. */
      flStyle = FCF_STANDARD | WS_CLIPCHILDREN;
//      flStyle = WS_OVERLAPPEDWINDOW;
    }
  }
{
 HWND  hwnd;                           /* Window     */
 ULONG ListBoxId;                      /* Window id  */
                                       /* (supplied by application) */


 HWND hwndClient;        /* handle to the client                 */
 HWND hwndFrame;         /* handle to the frame                  */
 PFNWP GenericWndProc;
 FRAMECDATA  fcd;
 RECTL  rect;     /* Boundary rectangle                   */



/************************************************/
// flCreate = (FCF_STANDARD) & ~FCF_TASKLIST;
/**********************************/
  if (parent)
  {   window->frame = NULL;

 hwnd = WinCreateWindow(parent->win,  /* Parent window             */
                        "GLUTCHILD",        /* Class name                */
                        "",    /* Window text               */
                        flStyle,       /* Window style              */
                        x, y,          /* Position (x,y)            */
                        width, height,      /* Size (width,height)       */
                        parent->win,    /* Owner window              */
                        HWND_TOP,      /* Sibling window            */
                        0,             /* Window id                 */
                        NULL,          /* Control data              */
                        NULL);         /* Pres parameters           */

 erridErrorCode = WinGetLastError(hab);
    window->win = hwnd;

  window->hdc = WinOpenWindowDC(window->win);
  window->hpsBuffer = hpsCurrent;


 rect.xLeft = x;
 rect.xRight = x+width;
 rect.yBottom = y;
 rect.yTop = y + height;

/***** else parent *****************************/
  } else {
        hwnd = WinCreateStdWindow(HWND_DESKTOP,
           0,       /* WS_VISIBLE frame-window style        */
           &flStyle,        /* window style                 */
           "GLUT",          /* class name                   */
           "GLUT",/* window title                  */
            0L,                  /* default client style          */
            NULLHANDLE,          /* resource in executable file   */
            ID_WINDOW,           /* resource id                   */
            &hwndClient);        /* receives client window handle */

 erridErrorCode = WinGetLastError(hab);
       window->win = hwndClient;
       window->frame = hwnd;
  window->hdc = WinOpenWindowDC(window->win);

  window->hpsBuffer = hpsCurrent;


/* converts a client window's boundaries into  an equivalent frame rectangle */
 rect.xLeft = x;
 rect.xRight = x+width;
 rect.yBottom = y;
 rect.yTop = y + height;

 /* calculate equivalent frame boundary from boundary data */
  WinCalcFrameRect(window->frame, &rect, FALSE);
 }
/***** endof if(parent) *****************************/

  /* Must set the XHDC for fake glXChooseVisual & fake
     glXCreateContext & fake XAllocColorCells. */
  XHDC = window->hdc;
  XHWND = window->win;
  window->vis = __glutDetermineWindowVisual(&window->treatAsSingle,
    &window->visAlloced, &fbc);
    if (!window->vis)
    {   __glutFatalError(
        "pixel format with necessary capabilities not found.");
    }
    { int rc;
      rc = wglChoosePixelFormat(window->hdc, window->vis),

//     evglSetPixelFormat(2); /* int iPixelFormat 1 - doublebuffer/2 - single buffer ??*/
      wglSetPixelFormat(window->hdc,rc,window->vis);
    }
   __glutSetupColormap(window->vis, &window->colormap, &window->cmap);

  window->ctx = glXCreateContext(window->hpsBuffer, window->vis,
    None, __glutTryDirect);

  WinSetWindowPos(hwnd,
                  HWND_TOP,rect.xLeft,rect.yBottom,
                  rect.xRight-rect.xLeft, rect.yTop-rect.yBottom,
      SWP_ACTIVATE | SWP_MOVE | SWP_SIZE | SWP_SHOW|SWP_ZORDER); /* flags*/

  /* Make sure subwindows get a windowStatus callback. */
  if (parent)
       WinPostMsg(parent->win, WM_ACTIVATE, 0, 0);

  }
}

#elif defined(_WIN32)

  __glutAdjustCoords(parent ? parent->win : NULL,
    &x, &y, &width, &height);
  if (parent) {
    style = WS_CHILD;
  } else {
    if (gameMode) {
      /* Game mode window should be a WS_POPUP window to
         ensure that the taskbar is hidden by it.  A standard
         WS_OVERLAPPEDWINDOW does not hide the task bar. */
      style = WS_POPUP | WS_MAXIMIZE;
    } else {
      /* A standard toplevel window with borders and such. */
      style = WS_OVERLAPPEDWINDOW;
    }
  }
  window->win = CreateWindow("GLUT", "GLUT",
    WS_CLIPSIBLINGS | WS_CLIPCHILDREN | style,
    x, y, width, height, parent ? parent->win : __glutRoot,
    NULL, GetModuleHandle(NULL), 0);
  window->hdc = GetDC(window->win);
  /* Must set the XHDC for fake glXChooseVisual & fake
     glXCreateContext & fake XAllocColorCells. */
  XHDC = window->hdc;
  window->vis = __glutDetermineWindowVisual(&window->treatAsSingle,
    &window->visAlloced, &fbc);
  if (!window->vis) {
    __glutFatalError(
      "pixel format with necessary capabilities not found.");
  }
  if (!SetPixelFormat(window->hdc,
      ChoosePixelFormat(window->hdc, window->vis),
      window->vis)) {
    __glutFatalError("SetPixelFormat failed during window create.");
  }
  __glutSetupColormap(window->vis, &window->colormap, &window->cmap);
  /* Make sure subwindows get a windowStatus callback. */
  if (parent) {
    PostMessage(parent->win, WM_ACTIVATE, 0, 0);
  }
  window->renderDc = window->hdc;
#else
  window->win = XCreateWindow(__glutDisplay,
    parent == NULL ? __glutRoot : parent->win,
    x, y, width, height, 0,
    window->vis->depth, InputOutput, window->vis->visual,
    attribMask, &wa);
#endif
  window->renderWin = window->win;
#if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_fbconfig)
  if (fbc) {
    window->ctx = __glut_glXCreateContextWithConfigSGIX(__glutDisplay, fbc,
      GLX_RGBA_TYPE_SGIX, None, __glutTryDirect);
  } else
#endif
#if defined(__OS2PM__)
//    window->ctx = glXCreateContext(window->hpsBuffer, window->vis,
//      None, __glutTryDirect);
#else
    window->ctx = glXCreateContext(__glutDisplay, window->vis,
      None, __glutTryDirect);
#endif
  if (!window->ctx) {
    __glutFatalError(
      "failed to create OpenGL rendering context.");
  }
  window->renderCtx = window->ctx;
#if !defined(_WIN32) && !defined(__OS2PM__)
  window->isDirect = glXIsDirect(__glutDisplay, window->ctx);
  if (__glutForceDirect) {
    if (!window->isDirect)
      __glutFatalError("direct rendering not possible.");
  }
#endif

  window->parent = parent;
  if (parent) {
    window->siblings = parent->children;
    parent->children = window;
  } else {
    window->siblings = NULL;
  }
  window->overlay = NULL;
  window->children = NULL;
  window->display = __glutDefaultDisplay;
  window->reshape = __glutDefaultReshape;
  window->mouse = NULL;
  window->motion = NULL;
  window->passive = NULL;
  window->entry = NULL;
  window->keyboard = NULL;
  window->keyboardUp = NULL;
  window->windowStatus = NULL;
  window->visibility = NULL;
  window->special = NULL;
  window->specialUp = NULL;
  window->buttonBox = NULL;
  window->dials = NULL;
  window->spaceMotion = NULL;
  window->spaceRotate = NULL;
  window->spaceButton = NULL;
  window->tabletMotion = NULL;
  window->tabletButton = NULL;
#ifdef _WIN32
  window->joystick = NULL;
  window->joyPollInterval = 0;
#endif

#if defined(__OS2PM__)
  window->wm_command = NULL;
#endif

  window->tabletPos[0] = -1;
  window->tabletPos[1] = -1;
#if defined(__OS2PM__)
  if(window->shownState == -1)
           window->shownState = 0;
   window->visState =  window->shownState;
#else
  window->shownState = 0;
  window->visState = -1;  /* not VisibilityUnobscured,
                             VisibilityPartiallyObscured, or
                             VisibilityFullyObscured */
#endif
  window->entryState = -1;  /* not EnterNotify or LeaveNotify */

  window->desiredConfMask = 0;
  window->buttonUses = 0;
  window->cursor = GLUT_CURSOR_INHERIT;

  /* Setup window to be mapped when glutMainLoop starts. */
  window->workMask = GLUT_MAP_WORK;
#ifdef _WIN32
  if (gameMode) {
    /* When mapping a game mode window, just show
       the window.  We have already created the game
       mode window with a maximize flag at creation
       time.  Doing a ShowWindow(window->win, SW_SHOWNORMAL)
       would be wrong for a game mode window since it
       would unmaximize the window. */
    window->desiredMapState = GameModeState;
  } else {
    window->desiredMapState = NormalState;
  }
#else
  window->desiredMapState = NormalState;
#endif
  window->prevWorkWin = __glutWindowWorkList;
  __glutWindowWorkList = window;

  /* Initially, no menus attached. */
  for (i = 0; i < GLUT_MAX_MENUS; i++) {
    window->menu[i] = 0;
  }

  /* Add this new window to the window list. */
  __glutWindowList[winnum] = window;

  /* Make the new window the current window. */
  __glutSetWindow(window);

  __glutDetermineMesaSwapHackSupport();

  if (window->treatAsSingle) {
    /* We do this because either the window really is single
       buffered (in which case this is redundant, but harmless,
       because this is the initial single-buffered context
       state); or we are treating a double buffered window as a
       single-buffered window because the system does not appear
       to export any suitable single- buffered visuals (in which
       the following are necessary). */
    glDrawBuffer(GL_FRONT);
    glReadBuffer(GL_FRONT);
  }
  return window;
}
Ejemplo n.º 8
0
static GLUTwindow *
processWindowWorkList(GLUTwindow * window)
{
  int workMask;

  if (window->prevWorkWin) {
    window->prevWorkWin = processWindowWorkList(window->prevWorkWin);
  } else {
    beforeEnd = &window->prevWorkWin;
  }

  /* Capture work mask for work that needs to be done to this
     window, then clear the window's work mask (excepting the
     dummy work bit, see below).  Then, process the captured
     work mask.  This allows callbacks in the processing the
     captured work mask to set the window's work mask for
     subsequent processing. */

  workMask = window->workMask;
  assert((workMask & GLUT_DUMMY_WORK) == 0);

  /* Set the dummy work bit, clearing all other bits, to
     indicate that the window is currently on the window work
     list _and_ that the window's work mask is currently being
     processed.  This convinces __glutPutOnWorkList that this
     window is on the work list still. */
  window->workMask = GLUT_DUMMY_WORK;

  /* Optimization: most of the time, the work to do is a
     redisplay and not these other types of work.  Check for
     the following cases as a group to before checking each one
     individually one by one. This saves about 25 MIPS
     instructions in the common redisplay only case. */
  if (workMask & (GLUT_EVENT_MASK_WORK | GLUT_DEVICE_MASK_WORK |
      GLUT_CONFIGURE_WORK | GLUT_COLORMAP_WORK | GLUT_MAP_WORK)) {
#if !defined(_WIN32)
    /* Be sure to set event mask BEFORE map window is done. */
    if (workMask & GLUT_EVENT_MASK_WORK) {
      long eventMask;

      /* Make sure children are not propogating events this
         window is selecting for.  Be sure to do this before
         enabling events on the children's parent. */
      if (window->children) {
        GLUTwindow *child = window->children;
        unsigned long attribMask = CWDontPropagate;
        XSetWindowAttributes wa;

        wa.do_not_propagate_mask = window->eventMask & GLUT_DONT_PROPAGATE_FILTER_MASK;
        if (window->eventMask & GLUT_HACK_STOP_PROPAGATE_MASK) {
          wa.event_mask = child->eventMask | (window->eventMask & GLUT_HACK_STOP_PROPAGATE_MASK);
          attribMask |= CWEventMask;
        }
        do {
          XChangeWindowAttributes(__glutDisplay, child->win,
            attribMask, &wa);
          child = child->siblings;
        } while (child);
      }
      eventMask = window->eventMask;
      if (window->parent && window->parent->eventMask & GLUT_HACK_STOP_PROPAGATE_MASK)
        eventMask |= (window->parent->eventMask & GLUT_HACK_STOP_PROPAGATE_MASK);
      XSelectInput(__glutDisplay, window->win, eventMask);
      if (window->overlay)
        XSelectInput(__glutDisplay, window->overlay->win,
          window->eventMask & GLUT_OVERLAY_EVENT_FILTER_MASK);
    }
#endif /* !_WIN32 */
    /* Be sure to set device mask BEFORE map window is done. */
    if (workMask & GLUT_DEVICE_MASK_WORK) {
      __glutUpdateInputDeviceMaskFunc(window);
    }
    /* Be sure to configure window BEFORE map window is done. */
    if (workMask & GLUT_CONFIGURE_WORK) {
#if defined(_WIN32)
      RECT changes;
      POINT point;
      UINT flags = SWP_NOACTIVATE | SWP_NOMOVE | SWP_NOOWNERZORDER
	| SWP_NOSENDCHANGING | SWP_NOSIZE | SWP_NOZORDER;

      GetClientRect(window->win, &changes);
      
      /* If this window is a toplevel window, translate the 0,0 client
         coordinate into a screen coordinate for proper placement. */
      if (!window->parent) {
        point.x = 0;
        point.y = 0;
        ClientToScreen(window->win, &point);
        changes.left = point.x;
        changes.top = point.y;
      }
      if (window->desiredConfMask & (CWX | CWY)) {
        changes.left = window->desiredX;
        changes.top = window->desiredY;
	flags &= ~SWP_NOMOVE;
      }
      if (window->desiredConfMask & (CWWidth | CWHeight)) {
        changes.right = changes.left + window->desiredWidth;
        changes.bottom = changes.top + window->desiredHeight;
	flags &= ~SWP_NOSIZE;
	/* XXX If overlay exists, resize the overlay here, ie.
	   if (window->overlay) ... */
      }
      if (window->desiredConfMask & CWStackMode) {
	flags &= ~SWP_NOZORDER;
	/* XXX Overlay support might require something special here. */
      }

      /* Adjust the window rectangle because Win32 thinks that the x, y,
         width & height are the WHOLE window (including decorations),
         whereas GLUT treats the x, y, width & height as only the CLIENT
         area of the window.  Only do this to top level windows
         that are not in game mode (since game mode windows do
         not have any decorations). */
      if (!window->parent && window != __glutGameModeWindow) {
        AdjustWindowRect(&changes,
          WS_OVERLAPPEDWINDOW | WS_CLIPSIBLINGS | WS_CLIPCHILDREN,
          FALSE);
      }

      /* Do the repositioning, moving, and push/pop. */
      SetWindowPos(window->win,
        window->desiredStack == Above ? HWND_TOP : HWND_NOTOPMOST,
        changes.left, changes.top,
        changes.right - changes.left, changes.bottom - changes.top,
        flags);

      /* Zero out the mask. */
      window->desiredConfMask = 0;

      /* This hack causes the window to go back to the right position
         when it is taken out of fullscreen mode. */
      if (workMask & GLUT_FULL_SCREEN_WORK) {
        window->desiredConfMask |= CWX | CWY;
        window->desiredX = point.x;
        window->desiredY = point.y;
      }
#else /* !_WIN32 */
      XWindowChanges changes;

      changes.x = window->desiredX;
      changes.y = window->desiredY;
      if (window->desiredConfMask & (CWWidth | CWHeight)) {
        changes.width = window->desiredWidth;
        changes.height = window->desiredHeight;
        if (window->overlay)
          XResizeWindow(__glutDisplay, window->overlay->win,
            window->desiredWidth, window->desiredHeight);
        if (__glutMotifHints != None) {
          if (workMask & GLUT_FULL_SCREEN_WORK) {
            MotifWmHints hints;

            hints.flags = MWM_HINTS_DECORATIONS;
            hints.decorations = 0;  /* Absolutely no
                                       decorations. */
            XChangeProperty(__glutDisplay, window->win,
              __glutMotifHints, __glutMotifHints, 32,
              PropModeReplace, (unsigned char *) &hints, 4);
            if (workMask & GLUT_MAP_WORK) {
              /* Handle case where glutFullScreen is called
                 before the first time that the window is
                 mapped. Some window managers will randomly or
                 interactively position the window the first
                 time it is mapped if the window's
                 WM_NORMAL_HINTS property does not request an
                 explicit position. We don't want any such
                 window manager interaction when going
                 fullscreen.  Overwrite the WM_NORMAL_HINTS
                 property installed by glutCreateWindow's
                 XSetWMProperties property with one explicitly
                 requesting a fullscreen window. */
              XSizeHints hints;

              hints.flags = USPosition | USSize;
              hints.x = 0;
              hints.y = 0;
              hints.width = window->desiredWidth;
              hints.height = window->desiredHeight;
              XSetWMNormalHints(__glutDisplay, window->win, &hints);
            }
          } else {
            XDeleteProperty(__glutDisplay, window->win, __glutMotifHints);
          }
        }
      }
      if (window->desiredConfMask & CWStackMode) {
        changes.stack_mode = window->desiredStack;
        /* Do not let glutPushWindow push window beneath the
           underlay. */
        if (window->parent && window->parent->overlay
          && window->desiredStack == Below) {
          changes.stack_mode = Above;
          changes.sibling = window->parent->overlay->win;
          window->desiredConfMask |= CWSibling;
        }
      }
      XConfigureWindow(__glutDisplay, window->win,
        window->desiredConfMask, &changes);
      window->desiredConfMask = 0;
#endif
    }
#if !defined(_WIN32)
    /* Be sure to establish the colormaps BEFORE map window is
       done. */
    if (workMask & GLUT_COLORMAP_WORK) {
      __glutEstablishColormapsProperty(window);
    }
#endif
    if (workMask & GLUT_MAP_WORK) {
      switch (window->desiredMapState) {
      case WithdrawnState:
        if (window->parent) {
          XUnmapWindow(__glutDisplay, window->win);
        } else {
          XWithdrawWindow(__glutDisplay, window->win,
            __glutScreen);
        }
        window->shownState = 0;
        break;
      case NormalState:
        XMapWindow(__glutDisplay, window->win);
        window->shownState = 1;
        break;
#ifdef _WIN32
      case GameModeState:  /* Not an Xlib value. */
        ShowWindow(window->win, SW_SHOW);
        window->shownState = 1;
        break;
#endif
      case IconicState:
        XIconifyWindow(__glutDisplay, window->win, __glutScreen);
        window->shownState = 0;
        break;
      }
    }
  }
  if (workMask & (GLUT_REDISPLAY_WORK | GLUT_OVERLAY_REDISPLAY_WORK | GLUT_REPAIR_WORK | GLUT_OVERLAY_REPAIR_WORK)) {
    if (window->forceReshape) {
      /* Guarantee that before a display callback is generated
         for a window, a reshape callback must be generated. */
      __glutSetWindow(window);
      window->reshape(window->width, window->height);
      window->forceReshape = False;

      /* Setting the redisplay bit on the first reshape is
         necessary to make the "Mesa glXSwapBuffers to repair
         damage" hack operate correctly.  Without indicating a
         redisplay is necessary, there's not an initial back
         buffer render from which to blit from when damage
         happens to the window. */
      workMask |= GLUT_REDISPLAY_WORK;
    }
    /* The code below is more involved than otherwise necessary
       because it is paranoid about the overlay or entire window
       being removed or destroyed in the course of the callbacks.
       Notice how the global __glutWindowDamaged is used to record
       the layers' damage status.  See the code in glutLayerGet for
       how __glutWindowDamaged is used. The  point is to not have to
       update the "damaged" field after  the callback since the
       window (or overlay) may be destroyed (or removed) when the
       callback returns. */

    if (window->overlay && window->overlay->display) {
      int num = window->num;
      Window xid = window->overlay ? window->overlay->win : None;

      /* If an overlay display callback is registered, we
         differentiate between a redisplay needed for the
         overlay and/or normal plane.  If there is no overlay
         display callback registered, we simply use the
         standard display callback. */

      if (workMask & (GLUT_REDISPLAY_WORK | GLUT_REPAIR_WORK)) {
        if (__glutMesaSwapHackSupport) {
          if (window->usedSwapBuffers) {
            if ((workMask & (GLUT_REPAIR_WORK | GLUT_REDISPLAY_WORK)) == GLUT_REPAIR_WORK) {
	      SWAP_BUFFERS_WINDOW(window);
              goto skippedDisplayCallback1;
            }
          }
        }
        /* Render to normal plane. */
#ifdef _WIN32
        window->renderDc = window->hdc;
#endif
        window->renderWin = window->win;
        window->renderCtx = window->ctx;
        __glutWindowDamaged = (workMask & GLUT_REPAIR_WORK);
        __glutSetWindow(window);
        window->usedSwapBuffers = 0;
        window->display();
        __glutWindowDamaged = 0;

      skippedDisplayCallback1:;
      }
      if (workMask & (GLUT_OVERLAY_REDISPLAY_WORK | GLUT_OVERLAY_REPAIR_WORK)) {
        window = __glutWindowList[num];
        if (window && window->overlay &&
          window->overlay->win == xid && window->overlay->display) {

          /* Render to overlay. */
#ifdef _WIN32
          window->renderDc = window->overlay->hdc;
#endif
          window->renderWin = window->overlay->win;
          window->renderCtx = window->overlay->ctx;
          __glutWindowDamaged = (workMask & GLUT_OVERLAY_REPAIR_WORK);
          __glutSetWindow(window);
          window->overlay->display();
          __glutWindowDamaged = 0;
        } else {
          /* Overlay may have since been destroyed or the
             overlay callback may have been disabled during
             normal display callback. */
        }
      }
    } else {
      if (__glutMesaSwapHackSupport) {
        if (!window->overlay && window->usedSwapBuffers) {
          if ((workMask & (GLUT_REPAIR_WORK | GLUT_REDISPLAY_WORK)) == GLUT_REPAIR_WORK) {
	    SWAP_BUFFERS_WINDOW(window);
            goto skippedDisplayCallback2;
          }
        }
      }
      /* Render to normal plane (and possibly overlay). */
      __glutWindowDamaged = (workMask & (GLUT_OVERLAY_REPAIR_WORK | GLUT_REPAIR_WORK));
      __glutSetWindow(window);
      window->usedSwapBuffers = 0;
      window->display();
      __glutWindowDamaged = 0;

    skippedDisplayCallback2:;
    }
  }
  /* Combine workMask with window->workMask to determine what
     finish and debug work there is. */
  workMask |= window->workMask;

  if (workMask & GLUT_FINISH_WORK) {
    /* Finish work makes sure a glFinish gets done to indirect
       rendering contexts.  Indirect contexts tend to have much 
       longer latency because lots of OpenGL extension requests 
       can queue up in the X protocol stream. __glutSetWindow
       is where the finish works gets queued for indirect
       contexts. */
    __glutSetWindow(window);
#if !defined(_WIN32)
    if (!window->isDirect)
#endif
    {
       glFinish();
    }
  }
  if (workMask & GLUT_DEBUG_WORK) {
    __glutSetWindow(window);
    glutReportErrors();
  }
  /* Strip out dummy, finish, and debug work bits. */
  window->workMask &= ~(GLUT_DUMMY_WORK | GLUT_FINISH_WORK | GLUT_DEBUG_WORK);
  if (window->workMask) {
    /* Leave on work list. */
    return window;
  } else {
    /* Remove current window from work list. */
    return window->prevWorkWin;
  }
}
Ejemplo n.º 9
0
static void
processEventsAndTimeouts(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);
          /* added button check for mice with > 3 buttons */
          if (window) {
            GLUTmenu *menu;
	    int menuNum;

            if (event.xbutton.button <= GLUT_MAX_MENUS)
              menuNum = window->menu[event.xbutton.button - 1];
            else
              menuNum = 0;

            /* 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) {
              __glutSetWindow(window);
              __glutModifierMask = event.xbutton.state;
              window->mouse(event.xbutton.button - 1,
                event.type == ButtonRelease ?
                GLUT_UP : GLUT_DOWN,
                event.xbutton.x, event.xbutton.y);
              __glutModifierMask = ~0;
            } else {
              /* Stray mouse events.  Ignore. */
            }
          } else {
            /* Window might have been destroyed and all the 
               events for the window may not yet be received. */
          }
        }
        break;
      case MotionNotify:
        if (!__glutMappedMenu) {
          window = __glutGetWindow(event.xmotion.window);
          if (window) {
            /* If motion function registered _and_ buttons held 
               * down, call motion function...  */
            if (window->motion && event.xmotion.state &
              (Button1Mask | Button2Mask | Button3Mask)) {
              __glutSetWindow(window);
              window->motion(event.xmotion.x, event.xmotion.y);
            }
            /* If passive motion function registered _and_
               buttons not held down, call passive motion
               function...  */
            else if (window->passive &&
                ((event.xmotion.state &
                    (Button1Mask | Button2Mask | Button3Mask)) ==
                0)) {
              __glutSetWindow(window);
              window->passive(event.xmotion.x,
                event.xmotion.y);
            }
          }
        } else {
          /* Motion events are thrown away when a pop up menu
             is active. */
        }
        break;
      case KeyPress:
      case KeyRelease:
        window = __glutGetWindow(event.xkey.window);
        if (!window) {
          break;
        }
	if (event.type == KeyPress) {
	  keyboard = window->keyboard;
	} else {

	  /* If we are ignoring auto repeated keys for this window,
	     check if the next event in the X event queue is a KeyPress
	     for the exact same key (and at the exact same time) as the
	     key being released.  The X11 protocol will send auto
	     repeated keys as such KeyRelease/KeyPress pairs. */

	  if (window->ignoreKeyRepeat) {
	    if (XEventsQueued(__glutDisplay, QueuedAfterReading)) {
	      XPeekEvent(__glutDisplay, &ahead);
	      if (ahead.type == KeyPress
	        && ahead.xkey.window == event.xkey.window
	        && ahead.xkey.keycode == event.xkey.keycode
	        && ahead.xkey.time == event.xkey.time) {
		/* Pop off the repeated KeyPress and ignore
		   the auto repeated KeyRelease/KeyPress pair. */
	        XNextEvent(__glutDisplay, &event);
	        break;
	      }
	    }
	  }
	  keyboard = window->keyboardUp;
	}
        if (keyboard) {
          char tmp[1];
          int rc;

          rc = XLookupString(&event.xkey, tmp, sizeof(tmp),
            NULL, NULL);
          if (rc) {
            __glutSetWindow(window);
            __glutModifierMask = event.xkey.state;
            keyboard(tmp[0],
              event.xkey.x, event.xkey.y);
            __glutModifierMask = ~0;
            break;
          }
        }
	if (event.type == KeyPress) {
	  special = window->special;
        } else {
	  special = window->specialUp;
	}
        if (special) {
          KeySym ks;
          int key;

/* Introduced in X11R6:  (Partial list of) Keypad Functions.  Define
   in place in case compiling against an older pre-X11R6
   X11/keysymdef.h file. */
#ifndef XK_KP_Home
#define XK_KP_Home              0xFF95
#endif
#ifndef XK_KP_Left
#define XK_KP_Left              0xFF96
#endif
#ifndef XK_KP_Up
#define XK_KP_Up                0xFF97
#endif
#ifndef XK_KP_Right
#define XK_KP_Right             0xFF98
#endif
#ifndef XK_KP_Down
#define XK_KP_Down              0xFF99
#endif
#ifndef XK_KP_Prior
#define XK_KP_Prior             0xFF9A
#endif
#ifndef XK_KP_Next
#define XK_KP_Next              0xFF9B
#endif
#ifndef XK_KP_End
#define XK_KP_End               0xFF9C
#endif
#ifndef XK_KP_Insert
#define XK_KP_Insert            0xFF9E
#endif
#ifndef XK_KP_Delete
#define XK_KP_Delete            0xFF9F
#endif

          ks = XLookupKeysym((XKeyEvent *) & event, 0);
          /* XXX Verbose, but makes no assumptions about keysym
             layout. */
          switch (ks) {
/* *INDENT-OFF* */
          /* function keys */
          case XK_F1:    key = GLUT_KEY_F1; break;
          case XK_F2:    key = GLUT_KEY_F2; break;
          case XK_F3:    key = GLUT_KEY_F3; break;
          case XK_F4:    key = GLUT_KEY_F4; break;
          case XK_F5:    key = GLUT_KEY_F5; break;
          case XK_F6:    key = GLUT_KEY_F6; break;
          case XK_F7:    key = GLUT_KEY_F7; break;
          case XK_F8:    key = GLUT_KEY_F8; break;
          case XK_F9:    key = GLUT_KEY_F9; break;
          case XK_F10:   key = GLUT_KEY_F10; break;
          case XK_F11:   key = GLUT_KEY_F11; break;
          case XK_F12:   key = GLUT_KEY_F12; break;
          /* directional keys */
	  case XK_KP_Left:
          case XK_Left:  key = GLUT_KEY_LEFT; break;
	  case XK_KP_Up: /* Introduced in X11R6. */
          case XK_Up:    key = GLUT_KEY_UP; break;
	  case XK_KP_Right: /* Introduced in X11R6. */
          case XK_Right: key = GLUT_KEY_RIGHT; break;
	  case XK_KP_Down: /* Introduced in X11R6. */
          case XK_Down:  key = GLUT_KEY_DOWN; break;
/* *INDENT-ON* */

	  case XK_KP_Prior: /* Introduced in X11R6. */
          case XK_Prior:
            /* XK_Prior same as X11R6's XK_Page_Up */
            key = GLUT_KEY_PAGE_UP;
            break;
	  case XK_KP_Next: /* Introduced in X11R6. */
          case XK_Next:
            /* XK_Next same as X11R6's XK_Page_Down */
            key = GLUT_KEY_PAGE_DOWN;
            break;
	  case XK_KP_Home: /* Introduced in X11R6. */
          case XK_Home:
            key = GLUT_KEY_HOME;
            break;
#ifdef __hpux
          case XK_Select:
#endif
	  case XK_KP_End: /* Introduced in X11R6. */
          case XK_End:
            key = GLUT_KEY_END;
            break;
#ifdef __hpux
          case XK_InsertChar:
#endif
	  case XK_KP_Insert: /* Introduced in X11R6. */
          case XK_Insert:
            key = GLUT_KEY_INSERT;
            break;
#ifdef __hpux
          case XK_DeleteChar:
#endif
	  case XK_KP_Delete: /* Introduced in X11R6. */
            /* The Delete character is really an ASCII key. */
            __glutSetWindow(window);
            keyboard(127,  /* ASCII Delete character. */
              event.xkey.x, event.xkey.y);
            goto skip;
          default:
            goto skip;
          }
          __glutSetWindow(window);
          __glutModifierMask = event.xkey.state;
          special(key, event.xkey.x, event.xkey.y);
          __glutModifierMask = ~0;
        skip:;
        }
        break;
      case EnterNotify:
      case LeaveNotify:
        if (event.xcrossing.mode != NotifyNormal ||
          event.xcrossing.detail == NotifyNonlinearVirtual ||
          event.xcrossing.detail == NotifyVirtual) {

          /* Careful to ignore Enter/LeaveNotify events that
             come from the pop-up menu pointer grab and ungrab. 
             Also, ignore "virtual" Enter/LeaveNotify events
             since they represent the pointer passing through
             the window hierarchy without actually entering or
             leaving the actual real estate of a window.  */

          break;
        }
        if (__glutMappedMenu) {
          GLUTmenuItem *item;
          int num;

          item = __glutGetMenuItem(__glutMappedMenu,
            event.xcrossing.window, &num);
          if (item) {
            __glutMenuItemEnterOrLeave(item, num, event.type);
            break;
          }
        }
        window = __glutGetWindow(event.xcrossing.window);
        if (window) {
          if (window->entry) {
            if (event.type == EnterNotify) {

              /* With overlays established, X can report two
                 enter events for both the overlay and normal
                 plane window. Do not generate a second enter
                 callback if we reported one without an
                 intervening leave. */

              if (window->entryState != EnterNotify) {
                int num = window->num;
                Window xid = window->win;

                window->entryState = EnterNotify;
                __glutSetWindow(window);
                window->entry(GLUT_ENTERED);

                if (__glutMappedMenu) {

                  /* Do not generate any passive motion events
                     when menus are in use. */

                } else {

                  /* An EnterNotify event can result in a
                     "compound" callback if a passive motion
                     callback is also registered. In this case,
                     be a little paranoid about the possibility
                     the window could have been destroyed in the
                     entry callback. */

                  window = __glutWindowList[num];
                  if (window && window->passive && window->win == xid) {
                    __glutSetWindow(window);
                    window->passive(event.xcrossing.x, event.xcrossing.y);
                  }
                }
              }
            } else {
              if (window->entryState != LeaveNotify) {

                /* When an overlay is established for a window
                   already mapped and with the pointer in it,
                   the X server will generate a leave/enter
                   event pair as the pointer leaves (without
                   moving) from the normal plane X window to
                   the newly mapped overlay  X window (or vice
                   versa). This enter/leave pair should not be
                   reported to the GLUT program since the pair
                   is a consequence of creating (or destroying) 
                   the overlay, not an actual leave from the
                   GLUT window. */

                if (XEventsQueued(__glutDisplay, QueuedAfterReading)) {
                  XPeekEvent(__glutDisplay, &ahead);
                  if (ahead.type == EnterNotify &&
                    __glutGetWindow(ahead.xcrossing.window) == window) {
                    XNextEvent(__glutDisplay, &event);
                    break;
                  }
                }
                window->entryState = LeaveNotify;
                __glutSetWindow(window);
                window->entry(GLUT_LEFT);
              }
            }
          } else if (window->passive) {
            __glutSetWindow(window);
            window->passive(event.xcrossing.x, event.xcrossing.y);
          }
        }
        break;
      case UnmapNotify:
        /* MapNotify events are not needed to maintain
           visibility state since VisibilityNotify events will
           be delivered when a window becomes visible from
           mapping.  However, VisibilityNotify events are not
           delivered when a window is unmapped (for the window
           or its children). */
        window = __glutGetWindow(event.xunmap.window);
        if (window) {
          if (window->win != event.xconfigure.window) {
            /* Ignore UnmapNotify sent to the overlay planes.
               GLUT could get here because overlays select for
               StructureNotify events to receive DestroyNotify. 
             */
            break;
          }
          markWindowHidden(window);
        }
        break;
      case VisibilityNotify:
        window = __glutGetWindow(event.xvisibility.window);
        if (window) {
          /* VisibilityUnobscured+1 = GLUT_FULLY_RETAINED,
             VisibilityPartiallyObscured+1 =
             GLUT_PARTIALLY_RETAINED, VisibilityFullyObscured+1 
             =  GLUT_FULLY_COVERED. */
          int visState = event.xvisibility.state + 1;

          if (visState != window->visState) {
            if (window->windowStatus) {
              window->visState = visState;
              __glutSetWindow(window);
              window->windowStatus(visState);
            }
          }
        }
        break;
      case ClientMessage:
        if (event.xclient.data.l[0] == __glutWMDeleteWindow)
          exit(0);
        break;
      case DestroyNotify:
        purgeStaleWindow(event.xdestroywindow.window);
        break;
      case CirculateNotify:
      case CreateNotify:
      case GravityNotify:
      case ReparentNotify:
        /* Uninteresting to GLUT (but possible for GLUT to
           receive). */
        break;
      default:
        /* Pass events not directly handled by the GLUT main
           event loop to any event parsers that have been
           registered.  In this way, X Input extension events
           are passed to the correct handler without forcing
           all GLUT programs to support X Input event handling. 
         */
        parser = eventParserList;
        while (parser) {
          if (parser->func(&event))
            break;
          parser = parser->next;
        }
        break;
      }
    }
#endif /* _WIN32 */
    if (__glutTimerList) {
      handleTimeouts();
    }
  }
  while (XPending(__glutDisplay));
}
Ejemplo n.º 10
0
/* ARGSUSED5 */  /* Only Win32 uses gameMode parameter. */
GLUTwindow *
__glutCreateWindow(GLUTwindow * parent,
  int x, int y, int width, int height, int gameMode)
{
  GLUTwindow *window;
  XSetWindowAttributes wa;
  unsigned long attribMask;
  int winnum;
  int i;
  void *fbc;

#if defined(_WIN32)
  WNDCLASS wc;
  int style;

  if (!GetClassInfo(GetModuleHandle(NULL), TEXT("GLUT"), &wc)) {
    __glutOpenWin32Connection(NULL);
  }
#else
  if (!__glutDisplay) {
    __glutOpenXConnection(NULL);
  }
#endif
  if (__glutGameModeWindow) {
    __glutFatalError("cannot create windows in game mode.");
  }
  winnum = getUnusedWindowSlot();
  window = (GLUTwindow *) malloc(sizeof(GLUTwindow));
  if (!window) {
    __glutFatalError("out of memory.");
  }
  window->num = winnum;

#if !defined(_WIN32)
  window->vis = __glutDetermineWindowVisual(&window->treatAsSingle,
    &window->visAlloced, &fbc);
  if (!window->vis) {
    __glutFatalError(
      "visual with necessary capabilities not found.");
  }
  __glutSetupColormap(window->vis, &window->colormap, &window->cmap);
#endif
  window->eventMask = StructureNotifyMask | ExposureMask;

  attribMask = CWBackPixmap | CWBorderPixel | CWColormap | CWEventMask;
  wa.background_pixmap = None;
  wa.border_pixel = 0;
  wa.colormap = window->cmap;
  wa.event_mask = window->eventMask;
  if (parent) {
    if (parent->eventMask & GLUT_HACK_STOP_PROPAGATE_MASK)
      wa.event_mask |= GLUT_HACK_STOP_PROPAGATE_MASK;
    attribMask |= CWDontPropagate;
    wa.do_not_propagate_mask = parent->eventMask & GLUT_DONT_PROPAGATE_FILTER_MASK;
  } else {
    wa.do_not_propagate_mask = 0;
  }

  /* Stash width and height before Win32's __glutAdjustCoords
     possibly overwrites the values. */
  window->width = width;
  window->height = height;
  window->forceReshape = True;
  window->ignoreKeyRepeat = False;

#if defined(_WIN32)
  __glutAdjustCoords(parent ? parent->win : NULL,
    &x, &y, &width, &height);
  if (parent) {
    style = WS_CHILD;
  } else {
    if (gameMode) {
      /* Game mode window should be a WS_POPUP window to
         ensure that the taskbar is hidden by it.  A standard
         WS_OVERLAPPEDWINDOW does not hide the task bar. */
      style = WS_POPUP | WS_MAXIMIZE;
    } else {
      /* A standard toplevel window with borders and such. */
      style = WS_OVERLAPPEDWINDOW;
    }
  }
  window->win = CreateWindow(TEXT("GLUT"), TEXT("GLUT"),
    WS_CLIPSIBLINGS | WS_CLIPCHILDREN | style,
    x, y, width, height, parent ? parent->win : __glutRoot,
    NULL, GetModuleHandle(NULL), 0);
  window->hdc = GetDC(window->win);
  /* Must set the XHDC for fake glXChooseVisual & fake
     glXCreateContext & fake XAllocColorCells. */
  XHDC = window->hdc;
  window->vis = __glutDetermineWindowVisual(&window->treatAsSingle,
    &window->visAlloced, &fbc);
  if (!window->vis) {
    __glutFatalError(
      "pixel format with necessary capabilities not found.");
  }
  if (!SetPixelFormat(window->hdc,
      ChoosePixelFormat(window->hdc, window->vis),
      window->vis)) {
    __glutFatalError("SetPixelFormat failed during window create.");
  }
  __glutSetupColormap(window->vis, &window->colormap, &window->cmap);
  /* Make sure subwindows get a windowStatus callback. */
  if (parent) {
    PostMessage(parent->win, WM_ACTIVATE, 0, 0);
  }
  window->renderDc = window->hdc;
#else
  window->win = XCreateWindow(__glutDisplay,
    parent == NULL ? __glutRoot : parent->win,
    x, y, width, height, 0,
    window->vis->depth, InputOutput, window->vis->visual,
    attribMask, &wa);
#endif
  window->renderWin = window->win;
#if defined(GLX_VERSION_1_1) && defined(GLX_SGIX_fbconfig)
  if (fbc) {
    window->ctx = __glut_glXCreateContextWithConfigSGIX(__glutDisplay, fbc,
      GLX_RGBA_TYPE_SGIX, None, __glutTryDirect);
  } else
#endif
  {
    window->ctx = glXCreateContext(__glutDisplay, window->vis,
      None, __glutTryDirect);
  }
  if (!window->ctx) {
    __glutFatalError(
      "failed to create OpenGL rendering context.");
  }
  window->renderCtx = window->ctx;
#if !defined(_WIN32)
  window->isDirect = glXIsDirect(__glutDisplay, window->ctx);
  if (__glutForceDirect) {
    if (!window->isDirect)
      __glutFatalError("direct rendering not possible.");
  }
#endif

  window->parent = parent;
  if (parent) {
    window->siblings = parent->children;
    parent->children = window;
  } else {
    window->siblings = NULL;
  }
  window->overlay = NULL;
  window->children = NULL;
  window->display = __glutDefaultDisplay;
  window->reshape = __glutDefaultReshape;
  window->mouse = NULL;
  window->motion = NULL;
  window->passive = NULL;
  window->entry = NULL;
  window->keyboard = NULL;
  window->keyboardUp = NULL;
  window->windowStatus = NULL;
  window->visibility = NULL;
  window->special = NULL;
  window->specialUp = NULL;
  window->buttonBox = NULL;
  window->dials = NULL;
  window->spaceMotion = NULL;
  window->spaceRotate = NULL;
  window->spaceButton = NULL;
  window->tabletMotion = NULL;
  window->tabletButton = NULL;
#ifdef _WIN32
  window->joystick = NULL;
  window->joyPollInterval = 0;
#endif
  window->tabletPos[0] = -1;
  window->tabletPos[1] = -1;
  window->shownState = 0;
  window->visState = -1;  /* not VisibilityUnobscured,
                             VisibilityPartiallyObscured, or
                             VisibilityFullyObscured */
  window->entryState = -1;  /* not EnterNotify or LeaveNotify */

  window->desiredConfMask = 0;
  window->buttonUses = 0;
  window->cursor = GLUT_CURSOR_INHERIT;

  /* Setup window to be mapped when glutMainLoop starts. */
  window->workMask = GLUT_MAP_WORK;
#ifdef _WIN32
  if (gameMode) {
    /* When mapping a game mode window, just show
       the window.  We have already created the game
       mode window with a maximize flag at creation
       time.  Doing a ShowWindow(window->win, SW_SHOWNORMAL)
       would be wrong for a game mode window since it
       would unmaximize the window. */
    window->desiredMapState = GameModeState;
  } else {
    window->desiredMapState = NormalState;
  }
#else
  window->desiredMapState = NormalState;
#endif
  window->prevWorkWin = __glutWindowWorkList;
  __glutWindowWorkList = window;

  /* Initially, no menus attached. */
  for (i = 0; i < GLUT_MAX_MENUS; i++) {
    window->menu[i] = 0;
  }

  /* Add this new window to the window list. */
  __glutWindowList[winnum] = window;

  /* Make the new window the current window. */
  __glutSetWindow(window);

  __glutDetermineMesaSwapHackSupport();

  if (window->treatAsSingle) {
    /* We do this because either the window really is single
       buffered (in which case this is redundant, but harmless,
       because this is the initial single-buffered context
       state); or we are treating a double buffered window as a
       single-buffered window because the system does not appear
       to export any suitable single- buffered visuals (in which
       the following are necessary). */
    glDrawBuffer(GL_FRONT);
    glReadBuffer(GL_FRONT);
  }
  return window;
}
Ejemplo n.º 11
0
LONG WINAPI __glutWindowProc(HWND hwnd, UINT msg, WPARAM wParam, LPARAM lParam)
{ 
  POINT         point;			/* Point structure. */
  PAINTSTRUCT   ps;			/* Paint structure. */
  LPMINMAXINFO  minmax;			/* Minimum/maximum info structure. */
  GLUTwindow*   window;			/* GLUT window associated with message. */
  GLUTmenu*     menu;			/* GLUT menu associated with message. */
  int x, y, width, height, key;
  int button = -1;

  switch(msg) {
  case WM_CREATE:
    return 0;

  case WM_CLOSE:
    PostQuitMessage(0);
    return 0;

  case WM_DESTROY:
#if 0
    /* TODO: need to add this. */
    purgeStaleWindow(hwnd);
#endif
    return 0;

  case WM_PAINT:
    window = __glutGetWindow(hwnd);
    if (window) {
      BeginPaint(hwnd, &ps);		/* Must have this for some Win32 reason. */
#if TAKE_THIS_OUT
      if (window->colormap) {
	SelectPalette(window->hdc, window->colormap->cmap, FORCE_FOREGROUND);
	RealizePalette(window->hdc);	       /* Remap the custom palette. */
      }
#endif
      EndPaint(hwnd, &ps);
      if (window->win == hwnd) {
	__glutPostRedisplay(window, GLUT_REPAIR_WORK);
      } else if (window->overlay && window->overlay->win == hwnd) {
	__glutPostRedisplay(window, GLUT_OVERLAY_REPAIR_WORK);
      }
    }
    return 0;

  case WM_SYSCHAR:
  case WM_CHAR:
    window = __glutGetWindow(hwnd);
    if (!window) {
      break;
    }
    /* Win32 is dumb and sends these messages only to the parent
       window.  Therefore, find out if we're in a child window and
       call the child windows keyboard callback if we are. */
    if (window->parent) {
	GetCursorPos(&point);
	ScreenToClient(hwnd, &point);
	hwnd = ChildWindowFromPoint(hwnd, point);
	window = __glutGetWindow(hwnd);
    }
    if (window->keyboard) {
      GetCursorPos(&point);
      ScreenToClient(window->win, &point);
      __glutSetWindow(window);
      __glutModifierMask = 0;
      if (GetKeyState(VK_SHIFT) < 0)	/* < 0 = high order bit is on */
	__glutModifierMask |= ShiftMask;
      if (GetKeyState(VK_CONTROL) < 0)
	__glutModifierMask |= ControlMask;
      if (GetKeyState(VK_MENU) < 0)
	__glutModifierMask |= Mod1Mask;
      window->keyboard((char)wParam, point.x, point.y);
      __glutModifierMask = (unsigned int) ~0;
    }
    return 0;

  case WM_SYSKEYDOWN:
  case WM_KEYDOWN:
    window = __glutGetWindow(hwnd);
    if (!window) {
      break;
    }
    /* Win32 is dumb and sends these messages only to the parent
       window.  Therefore, find out if we're in a child window and
       call the child windows keyboard callback if we are. */
    if (window->parent) {
	GetCursorPos(&point);
	ScreenToClient(hwnd, &point);
	hwnd = ChildWindowFromPoint(hwnd, point);
	window = __glutGetWindow(hwnd);
    }
    if (window->special) {
      switch (wParam) {
	/* *INDENT-OFF* */
	/* function keys */
	case VK_F1:     key = GLUT_KEY_F1; break;
	case VK_F2:     key = GLUT_KEY_F2; break;
	case VK_F3:     key = GLUT_KEY_F3; break;
	case VK_F4:     key = GLUT_KEY_F4; break;
	case VK_F5:     key = GLUT_KEY_F5; break;
	case VK_F6:     key = GLUT_KEY_F6; break;
	case VK_F7:     key = GLUT_KEY_F7; break;
	case VK_F8:     key = GLUT_KEY_F8; break;
	case VK_F9:     key = GLUT_KEY_F9; break;
	case VK_F10:    key = GLUT_KEY_F10; break;
	case VK_F11:    key = GLUT_KEY_F11; break;
	case VK_F12:    key = GLUT_KEY_F12; break;
	/* directional keys */
	case VK_LEFT:   key = GLUT_KEY_LEFT; break;
	case VK_UP:     key = GLUT_KEY_UP; break;
	case VK_RIGHT:  key = GLUT_KEY_RIGHT; break;
	case VK_DOWN:   key = GLUT_KEY_DOWN; break;
	/* *INDENT-ON* */

	case VK_PRIOR:
	  /* VK_PRIOR is Win32's Page Up */
	  key = GLUT_KEY_PAGE_UP;
	  break;
	case VK_NEXT:
	  /* VK_NEXT is Win32's Page Down */
	  key = GLUT_KEY_PAGE_DOWN;
	  break;
	case VK_HOME:
	  key = GLUT_KEY_HOME;
	  break;
	case VK_END:
	  key = GLUT_KEY_END;
	  break;
	case VK_INSERT:
	  key = GLUT_KEY_INSERT;
	  break;
	default:
	  goto defproc;
      }
      GetCursorPos(&point);
      ScreenToClient(window->win, &point);
      __glutSetWindow(window);
      __glutModifierMask = 0;
      if (GetKeyState(VK_SHIFT) < 0)	/* < 0 = high order bit is on */
	__glutModifierMask |= ShiftMask;
      if (GetKeyState(VK_CONTROL) < 0)
	__glutModifierMask |= ControlMask;
      if (GetKeyState(VK_MENU) < 0)
	__glutModifierMask |= Mod1Mask;
      window->special(key, point.x, point.y);
      __glutModifierMask = (unsigned int) ~0;
    }
    return 0;

  case WM_LBUTTONDOWN:
    button = GLUT_LEFT_BUTTON;
  case WM_MBUTTONDOWN:
    if (button < 0)
      button = GLUT_MIDDLE_BUTTON;
  case WM_RBUTTONDOWN:
    if (button < 0)
      button = GLUT_RIGHT_BUTTON;
    
    /* finish the menu if we get a button down message (user must have
       cancelled the menu). */
    if (__glutMappedMenu) {
      /* TODO: take this out once the menu on middle mouse stuff works
	 properly. */
      if (button == GLUT_MIDDLE_BUTTON)
	return 0;
      GetCursorPos(&point);
      ScreenToClient(hwnd, &point);
      __glutItemSelected = NULL;
      __glutFinishMenu(hwnd, point.x, point.y);
      return 0;
    }

    /* set the capture so we can get mouse events outside the window */
    SetCapture(hwnd);

    /* Win32 doesn't return the same numbers as X does when the mouse
       goes beyond the upper or left side of the window.  roll the
       Win32's 0..2^16 pointer co-ord range to 0 +/- 2^15. */
    x = LOWORD(lParam);
    y = HIWORD(lParam);
    if(x & 1 << 15) x -= (1 << 16);
    if(y & 1 << 15) y -= (1 << 16);
	
    window = __glutGetWindow(hwnd);
    if (window) {
      menu = __glutGetMenuByNum(window->menu[button]);
      if (menu) {
	point.x = LOWORD(lParam); point.y = HIWORD(lParam);
	ClientToScreen(window->win, &point);
	__glutMenuButton = button == GLUT_RIGHT_BUTTON ? TPM_RIGHTBUTTON :
                           button == GLUT_LEFT_BUTTON  ? TPM_LEFTBUTTON :
                           0x0001;
	__glutStartMenu(menu, window, point.x, point.y, x, y);
      } else if (window->mouse) {
	
        __glutSetWindow(window);
	__glutModifierMask = 0;
	if (GetKeyState(VK_SHIFT) < 0)	/* < 0 = high order bit is on. */
	  __glutModifierMask |= ShiftMask;
	if (GetKeyState(VK_CONTROL) < 0)
	  __glutModifierMask |= ControlMask;
	if (GetKeyState(VK_MENU) < 0)
	  __glutModifierMask |= Mod1Mask;
	window->mouse(button, GLUT_DOWN, x, y);
	__glutModifierMask = (unsigned int)~0;
      } else {
	/* Stray mouse events.  Ignore. */
      }
    }
    return 0;

  case WM_LBUTTONUP:
    button = GLUT_LEFT_BUTTON;
  case WM_MBUTTONUP:
    if (button < 0)
      button = GLUT_MIDDLE_BUTTON;
  case WM_RBUTTONUP:
    if (button < 0)
      button = GLUT_RIGHT_BUTTON;

    /* Bail out if we're processing a menu. */
    if (__glutMappedMenu) {
      GetCursorPos(&point);
      ScreenToClient(hwnd, &point);
      /* if we're getting the middle button up signal, then something
	 on the menu was selected. */
      if (button == GLUT_MIDDLE_BUTTON) {
	return 0;
	/* For some reason, the code below always returns -1 even
	   though the point IS IN THE ITEM!  Therefore, just bail out if
	   we get a middle mouse up.  The user must select using the
	   left mouse button.  Stupid Win32. */
#if 0
 	int item = MenuItemFromPoint(hwnd, __glutHMenu, point);
 	printf("item = %d %d %d\n", item, point.x, point.y);
 	if (item != -1)
 	  __glutItemSelected = (GLUTmenuItem*)GetMenuItemID(__glutHMenu, item);
 	else
 	  __glutItemSelected = NULL;
 	__glutFinishMenu(hwnd, point.x, point.y);
#endif
      } else {
	__glutItemSelected = NULL;
	__glutFinishMenu(hwnd, point.x, point.y);
      }
      return 0;
    }

    /* Release the mouse capture. */
    ReleaseCapture();

    window = __glutGetWindow(hwnd);
    if (window && window->mouse) {
      /* Win32 doesn't return the same numbers as X does when the
	 mouse goes beyond the upper or left side of the window.  roll
	 the Win32's 0..2^16 pointer co-ord range to 0 +/- 2^15. */
      x = LOWORD(lParam);
      y = HIWORD(lParam);
      if(x & 1 << 15) x -= (1 << 16);
      if(y & 1 << 15) y -= (1 << 16);
      
      __glutSetWindow(window);
      __glutModifierMask = 0;
      if (GetKeyState(VK_SHIFT) < 0)	/* < 0 = high order bit is on */
	__glutModifierMask |= ShiftMask;
      if (GetKeyState(VK_CONTROL) < 0)
	__glutModifierMask |= ControlMask;
      if (GetKeyState(VK_MENU) < 0)
	__glutModifierMask |= Mod1Mask;
      window->mouse(button, GLUT_UP, x, y);
      __glutModifierMask = (unsigned int)~0;
    } else {
      /* Window might have been destroyed and all the 
	 events for the window may not yet be received. */
    }
    return 0;

  case WM_ENTERMENULOOP:
    /* KLUDGE: create a timer that fires every 100 ms when we start a
       menu so that we can still process the idle & timer events (that
       way, the timers will fire during a menu pick and so will the
       idle func. */
    SetTimer(hwnd, 1, 1, NULL);
    return 0;

  case WM_TIMER:
#if 0
    /* if the timer id is 2, then this is the timer that is set up in
       the main glut message processing loop, and we don't want to do
       anything but acknowledge that we got it.  It is used to prevent
       CPU spiking when an idle function is installed. */
    if (wParam == 2)
      return 0;
#endif

    /* only worry about the idle function and the timeouts, since
       these are the only events we expect to process during
       processing of a menu. */
    /* we no longer process the idle functions (as outlined in the
       README), since drawing can't be done until the menu has
       finished...it's pretty lame when the animation goes on, but
       doesn't update, so you get this weird jerkiness. */
#if 0    
     if (__glutIdleFunc)
       __glutIdleFunc();
#endif
    if (__glutTimerList)
      handleTimeouts();
    return 0;

  case WM_EXITMENULOOP:
    /* nuke the above created timer...we don't need it anymore, since
       the menu is gone now. */
    KillTimer(hwnd, 1);
    return 0;

  case WM_MENUSELECT:
    if (lParam != 0)
      __glutHMenu = (HMENU)lParam;
    return 0;

  case WM_COMMAND:
    if (__glutMappedMenu) {
      if (GetSubMenu(__glutHMenu, LOWORD(wParam)))
	__glutItemSelected = NULL;
      else
	__glutItemSelected = 
	  __glutGetUniqueMenuItem(__glutMappedMenu, LOWORD(wParam));
      GetCursorPos(&point);
      ScreenToClient(hwnd, &point);
      __glutFinishMenu(hwnd, point.x, point.y);
    } 
    return 0;

  case WM_MOUSEMOVE:
    if (!__glutMappedMenu) {
      window = __glutGetWindow(hwnd);
      if (window) {
          /* If motion function registered _and_ buttons held *
             down, call motion function...  */
	x = LOWORD(lParam);
	y = HIWORD(lParam);

	/* Win32 doesn't return the same numbers as X does when the
	   mouse goes beyond the upper or left side of the window.
	   roll the Win32's 0..2^16 pointer co-ord range to 0..+/-2^15. */
	if(x & 1 << 15) x -= (1 << 16);
	if(y & 1 << 15) y -= (1 << 16);

	if (window->motion && wParam &
            (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON)) {
	  __glutSetWindow(window);
	  window->motion(x, y);
	}
	/* If passive motion function registered _and_
	   buttons not held down, call passive motion
	   function...  */
	else if (window->passive &&
		 ((wParam &
		   (MK_LBUTTON | MK_MBUTTON | MK_RBUTTON)) ==
		  0)) {
	  __glutSetWindow(window);
	  window->passive(x, y);
	}
      }
    } else {
      /* Motion events are thrown away when a pop up menu is
	 active. */
    }
    return 0;

  case WM_GETMINMAXINFO:
    /* this voodoo is brought to you by Win32 (again).  It allows the
       window to be bigger than the screen, and smaller than 100x100
       (although it doesn't seem to help the y minimum). */
    minmax = (LPMINMAXINFO)lParam;
    minmax->ptMaxSize.x = __glutScreenWidth;
    minmax->ptMaxSize.y = __glutScreenHeight;
    minmax->ptMinTrackSize.x = 0;
    minmax->ptMinTrackSize.y = 0;
    minmax->ptMaxTrackSize.x = __glutScreenWidth + 
      GetSystemMetrics(SM_CXSIZE) * 2;
    minmax->ptMaxTrackSize.y = __glutScreenHeight + 
      GetSystemMetrics(SM_CXSIZE) * 2 + GetSystemMetrics(SM_CYCAPTION);
    return 0;

  case WM_SIZE:
    window = __glutGetWindow(hwnd);
    if (window) {
#if 0
      if (window->win != hwnd) {
	/* Ignore ConfigureNotify sent to the overlay planes.
	   GLUT could get here because overlays select for
	   StructureNotify events to receive DestroyNotify. */
	break;
      }
#endif
      width = LOWORD(lParam);
      height = HIWORD(lParam);
      if (width != window->width || height != window->height) {
#if 0
 	if (window->overlay) {
 	  XResizeWindow(__glutDisplay, window->overlay->win, width, height);
 	}
#endif
	window->width = width;
	window->height = height;
	__glutSetWindow(window);
	/* Do not execute OpenGL out of sequence with respect
	   to the SetWindowPos request! */
	GdiFlush();
	window->reshape(width, height);
	window->forceReshape = FALSE;
	/* A reshape should be considered like posting a
	   repair request. */
	__glutPostRedisplay(window, GLUT_REPAIR_WORK);
      }
    }
    return 0;

  case WM_SETCURSOR:
    /* If the cursor is not in the client area, then we want to send
       this message to the default window procedure ('cause its
       probably in the border or title, and we don't handle that
       cursor.  otherwise, set our cursor.  Win32 makes us set the
       cursor every time the mouse moves (DUMB!). */
    if(LOWORD(lParam) != HTCLIENT)
      goto defproc;
    window = __glutGetWindow(hwnd);
    if (window) {
      /* Since Win32 allows the parent to control a child windows
	 cursor, if the cursor is in a child of this window, bail
	 out. */
      GetCursorPos(&point);
      ScreenToClient(hwnd, &point);
      if (hwnd != ChildWindowFromPoint(hwnd, point))
	break;
      __glutCurrentWindow = window;
      glutSetCursor(window->cursor);
    }
    /* TODO: check out the info in DevStudio on WM_SETCURSOR in the
       DefaultAction section. */
    return 1;

  case WM_SETFOCUS:
    window = __glutGetWindow(hwnd);
    if (window) {
      if (window->entry) {
	window->entryState = WM_SETFOCUS;
	__glutSetWindow(window);
	window->entry(GLUT_ENTERED);
	/* XXX Generation of fake passive notify?  See how    much
	   work the X11 code does to support fake passive    notify
	   callbacks. */
      }
    }
    return 0;

  case WM_KILLFOCUS:
    window = __glutGetWindow(hwnd);
    if (window) {
      if (window->entry) {
	window->entryState = WM_KILLFOCUS;
	__glutSetWindow(window);
	window->entry(GLUT_LEFT);
      }
    }
    return 0;

  case WM_ACTIVATE:
    window = __glutGetWindow(hwnd);
    /* make sure we re-select the correct palette if needed */
    if (LOWORD(wParam)) {
      PostMessage(hwnd, WM_PALETTECHANGED, 0, 0);
    }
    if (window) {
      GLUTwindow* child;
      int visState;
      visState = !IsIconic(window->win);
      if (visState) {			/* Not iconic. */
	visState = IsWindowVisible(window->win);
      }
      if (visState != window->visState) {
	if (window->windowStatus) {
	  window->visState = visState;
	  __glutSetWindow(window);
	  window->windowStatus(visState);
	}
	/* Since Win32 only sends an activate for the toplevel window,
	   update the visibility for all the child windows. */
	child = window->children;
	while (child) {
	  child->visState = visState;
	  if (child->windowStatus) {
	    child->visState = visState;
	    __glutSetWindow(child);
	    child->windowStatus(visState);
	  }
	  child = child->siblings;
	}
      }
    }
    return 0;

  /* Colour Palette Management */
  case WM_PALETTECHANGED:
    if (hwnd == (HWND)wParam)  /* don't respond to the message that we sent! */
      break;
    /* fall through to WM_QUERYNEWPALETTE */

  case WM_QUERYNEWPALETTE:
    window = __glutGetWindow(hwnd);
    if (window && window->colormap) {
      UnrealizeObject(window->colormap->cmap);
      SelectPalette(window->hdc, window->colormap->cmap, FALSE);
      RealizePalette(window->hdc);
      return TRUE;
    }
    return FALSE;

#if 0
  /* Miscellaneous messages (don't really need to enumerate them,
     but it's good to know what you're not getting sometimes.) */
  case WM_NCHITTEST:
    /* this event is generated by every mouse move event. */
    goto defproc;
  case WM_NCMOUSEMOVE:
    goto defproc;
  case WM_NCACTIVATE:
    goto defproc;
  case WM_NCPAINT:
    goto defproc;
  case WM_NCCALCSIZE:
    goto defproc;
  case WM_NCCREATE:
    goto defproc;
  case WM_NCDESTROY:
    goto defproc;
  case WM_NCLBUTTONDOWN:
    goto defproc;
  case WM_SETTEXT:
    goto defproc;
  case WM_GETTEXT:
    goto defproc;
  case WM_ACTIVATEAPP:
    goto defproc;
  case WM_GETICON:
    goto defproc;
  case WM_ERASEBKGND:
    goto defproc;
  case WM_WINDOWPOSCHANGING:
    goto defproc;
  case WM_WINDOWPOSCHANGED:
    goto defproc;
  case WM_MOUSEACTIVATE:
    goto defproc;
  case WM_SHOWWINDOW:
    goto defproc;
  case WM_MOVING:
    goto defproc;
  case WM_MOVE:
    goto defproc;
  case WM_KEYUP:
    goto defproc;
  case WM_CAPTURECHANGED:
    goto defproc;
  case WM_SYSCOMMAND:
    goto defproc;
  case WM_ENTERSIZEMOVE:
    goto defproc;
  case WM_ENTERIDLE:
    goto defproc;
#endif

  default: 
    goto defproc;
  }

defproc:    
  return DefWindowProc(hwnd, msg, wParam, lParam); 
} 
Ejemplo n.º 12
0
GLUTwindow *
__glutCreateWindow(GLUTwindow * parent,
  int x, int y, int width, int height)
{
  GLUTwindow *window;
  XSetWindowAttributes wa;
  unsigned long attribMask;
  int winnum;
  int i;

#if defined(WIN32)
  WNDCLASS wc;
  if (!GetClassInfo(GetModuleHandle(NULL), "GLUT", &wc))
    __glutOpenWin32Connection(NULL);
#else
  if (!__glutDisplay)
    __glutOpenXConnection(NULL);
#endif
  winnum = getUnusedWindowSlot();
  window = (GLUTwindow *) malloc(sizeof(GLUTwindow));
  if (!window)
    __glutFatalError("out of memory.");
  window->num = winnum;

#if !defined(WIN32)
  window->vis = __glutDetermineWindowVisual(&window->treatAsSingle,
    &window->visAlloced);
  if (!window->vis) {
    __glutFatalError(
      "visual with necessary capabilities not found.");
  }
  __glutSetupColormap(window->vis, &window->colormap, &window->cmap);
#endif
  window->eventMask = StructureNotifyMask | ExposureMask;

  attribMask = CWBackPixmap | CWBorderPixel | CWColormap | CWEventMask;
  wa.background_pixmap = None;
  wa.border_pixel = 0;
  wa.colormap = window->cmap;
  wa.event_mask = window->eventMask;
  if (parent) {
    if (parent->eventMask & GLUT_HACK_STOP_PROPAGATE_MASK)
      wa.event_mask |= GLUT_HACK_STOP_PROPAGATE_MASK;
    attribMask |= CWDontPropagate;
    wa.do_not_propagate_mask = parent->eventMask & GLUT_DONT_PROPAGATE_FILTER_MASK;
  } else {
    wa.do_not_propagate_mask = 0;
  }

  /* Stash width and height before Win32's __glutAdjustCoords
     possibly overwrites the values. */
  window->width = width;
  window->height = height;
  window->forceReshape = True;

#if defined(WIN32)
  __glutAdjustCoords(parent ? parent->win : NULL, &x, &y, &width, &height);
  window->win = XCreateWindow(__glutDisplay,
    parent == NULL ? __glutRoot : parent->win,
    x, y, width, height, 0,
    0, InputOutput, 0,
    attribMask, &wa);
  window->hdc = GetDC(window->win);
  /* Must set the XHDC for fake glXChooseVisual & fake
     glXCreateContext & fake XAllocColorCells. */
  XHDC = window->hdc;
  window->vis = __glutDetermineWindowVisual(&window->treatAsSingle,
    &window->visAlloced);
  if (!window->vis) {
    __glutFatalError(
      "visual with necessary capabilities not found.");
  }
  if (!SetPixelFormat(window->hdc,
      ChoosePixelFormat(window->hdc, window->vis),
      window->vis))
    __glutFatalError("SetPixelFormat() failed in glutCreateWindow().");
  __glutSetupColormap(window->vis, &window->colormap, &window->cmap);
  /* Make sure subwindows get a windowStatus callback. */
  if (parent)
    PostMessage(parent->win, WM_ACTIVATE, 0, 0);
#else
  window->win = XCreateWindow(__glutDisplay,
    parent == NULL ? __glutRoot : parent->win,
    x, y, width, height, 0,
    window->vis->depth, InputOutput, window->vis->visual,
    attribMask, &wa);
#endif
  window->renderWin = window->win;
  window->ctx = glXCreateContext(__glutDisplay, window->vis,
    None, __glutTryDirect);
  if (!window->ctx) {
    __glutFatalError(
      "failed to create OpenGL rendering context.");
  }
  window->renderCtx = window->ctx;
#if !defined(WIN32)
  window->isDirect = glXIsDirect(__glutDisplay, window->ctx);
  if (__glutForceDirect) {
    if (!window->isDirect)
      __glutFatalError("direct rendering not possible.");
  }
#endif

  window->parent = parent;
  if (parent) {
    window->siblings = parent->children;
    parent->children = window;
  } else {
    window->siblings = NULL;
  }
  window->overlay = NULL;
  window->children = NULL;
  window->display = __glutDefaultDisplay;
  window->reshape = __glutDefaultReshape;
  window->mouse = NULL;
  window->motion = NULL;
  window->windowStatus = NULL;
  window->visibility = NULL;
  window->passive = NULL;
  window->entry = NULL;
  window->special = NULL;
  window->buttonBox = NULL;
  window->dials = NULL;
  window->spaceMotion = NULL;
  window->spaceRotate = NULL;
  window->spaceButton = NULL;
  window->tabletMotion = NULL;
  window->tabletButton = NULL;
  window->tabletPos[0] = -1;
  window->tabletPos[1] = -1;
  window->keyboard = NULL;
  window->shownState = 0;
  window->visState = -1;  /* not VisibilityUnobscured,
                             VisibilityPartiallyObscured, or
                             VisibilityFullyObscured */
  window->entryState = -1;  /* not EnterNotify or LeaveNotify */
  window->workMask = GLUT_MAP_WORK;
  window->desiredMapState = NormalState;
  window->desiredConfMask = 0;
  window->buttonUses = 0;
  window->cursor = GLUT_CURSOR_INHERIT;
  window->prevWorkWin = __glutWindowWorkList;
  __glutWindowWorkList = window;
  for (i = 0; i < GLUT_MAX_MENUS; i++) {
    window->menu[i] = 0;
  }
  __glutWindowList[winnum] = window;
  __glutSetWindow(window);

  __glutDetermineMesaSwapHackSupport();

  if (window->treatAsSingle) {
    /* We do this because either the window really is single
       buffered (in which case this is redundant, but harmless,
       because this is the initial single-buffered context
       state); or we are treating a double buffered window as a
       single-buffered window because the system does not appear
       to export any suitable single- buffered visuals (in which
       the following are necessary). */
    glDrawBuffer(GL_FRONT);
    glReadBuffer(GL_FRONT);
  }
  return window;
}
Ejemplo n.º 13
0
static void 
__glutInputEvent( DFBInputEvent *e, DFBInputEvent *p )
{
     __glutAssert( g_game != NULL );
     
     switch (e->type) {
          case DIET_KEYPRESS:
               g_game->modifiers = __glutModifiers( e->modifiers );
               if (g_ignore_key_repeat && p) {
                    if (p->type       == DIET_KEYPRESS &&
                        p->key_symbol == e->key_symbol)
                         break;
               }
               if (DFB_KEY_IS_ASCII( e->key_symbol )) {
                    if (keyboard_func) {
                         __glutSetWindow( g_game );
                         keyboard_func( e->key_symbol, g_game->cx, g_game->cy );
                    }
               }
               else {
                    int key = __glutSpecialKey( e->key_symbol );
                    if (key && special_func) {
                         __glutSetWindow( g_game );
                         special_func( key, g_game->cx, g_game->cy );
                    }
               }
               break;
          case DIET_KEYRELEASE:
               g_game->modifiers = __glutModifiers( e->modifiers ); 
               if (DFB_KEY_IS_ASCII( e->key_symbol )) {
                    if (keyboard_up_func) {
                         __glutSetWindow( g_game );
                         keyboard_up_func( e->key_symbol, g_game->cx, g_game->cy );
                    }
               }
               else {
                    int key = __glutSpecialKey( e->key_symbol );
                    if (key && special_up_func) {
                         __glutSetWindow( g_game );
                         special_up_func( key, g_game->cx, g_game->cy );
                    }
               }
               break;
          case DIET_BUTTONPRESS:
               if (e->device_id == DIDID_JOYSTICK) {
                    g_game->buttons = e->buttons;
                    if (joystick_func) {
                         __glutSetWindow( g_game );
                         joystick_func( g_game->buttons,
                                        g_game->jx, g_game->jy, g_game->jz );
                    }
               }
               else {
                    if (mouse_func) {
                         __glutSetWindow( g_game );
                         mouse_func( __glutButton( e->button ), 
                                     GLUT_DOWN, g_game->cx, g_game->cy );
                    }
               }
               break;
          case DIET_BUTTONRELEASE:
               if (e->device_id == DIDID_JOYSTICK) {
                    g_game->buttons = e->buttons;
                    if (joystick_func) {
                         __glutSetWindow( g_game );
                         joystick_func( g_game->buttons,
                                        g_game->jx, g_game->jy, g_game->jz );
                    }
               }
               else {
                    if (mouse_func) {
                         __glutSetWindow( g_game );
                         mouse_func( __glutButton( e->button ), 
                                     GLUT_UP, g_game->cx, g_game->cy );
                    }
               }
               break;
          case DIET_AXISMOTION:
               if (e->device_id == DIDID_JOYSTICK) {
                    switch (e->axis) {
                         case DIAI_X:
                              if (e->flags & DIEF_AXISABS)
                                   g_game->jx = e->axisabs;
                              else if (e->flags & DIEF_AXISREL)
                                   g_game->jx += e->axisrel;
                              break;
                         case DIAI_Y:
                              if (e->flags & DIEF_AXISABS)
                                   g_game->jy = e->axisabs;
                              else if (e->flags & DIEF_AXISREL)
                                   g_game->jy += e->axisrel;
                              break;
                         case DIAI_Z:
                              if (e->flags & DIEF_AXISABS)
                                   g_game->jz = e->axisabs;
                              else if (e->flags & DIEF_AXISREL)
                                   g_game->jz += e->axisrel;
                              break;
                         default:
                              break;
                    } 
                    if (joystick_func) {
                         __glutSetWindow( g_game );
                         joystick_func( g_game->buttons,
                                        g_game->jx, g_game->jy, g_game->jz );
                    }
               }
               else {
                    switch (e->axis) {
                         case DIAI_X:
                              if (e->flags & DIEF_AXISABS)
                                   g_game->cx = e->axisabs;
                              else if (e->flags & DIEF_AXISREL)
                                   g_game->cx += e->axisrel;
                              break;
                         case DIAI_Y:
                              if (e->flags & DIEF_AXISABS)
                                   g_game->cy = e->axisabs;
                              else if (e->flags & DIEF_AXISREL)
                                   g_game->cy += e->axisrel;
                              break;
                         default:
                              return;
                    }
                    if (e->buttons && motion_func) {
                         __glutSetWindow( g_game );
                         motion_func( g_game->cx, g_game->cy );
                    }
                    else if (!e->buttons && passive_motion_func) {
                         __glutSetWindow( g_game );
                         passive_motion_func( g_game->cx, g_game->cy );
                    }
               }
               break;
          default:
               break;
     }
}
Ejemplo n.º 14
0
static void 
__glutWindowEvent( DFBWindowEvent *e, DFBWindowEvent *p )
{
     __GlutWindow *window;
     
     window = __glutFindWindow( e->window_id );
     if (!window) /* window was destroyed */
          return;
     
     switch (e->type) {
          case DWET_KEYDOWN:
               window->modifiers = __glutModifiers( e->modifiers );
               if (g_ignore_key_repeat && p) {
                    if (p->type       == DWET_KEYDOWN &&
                        p->window_id  == e->window_id &&
                        p->key_symbol == e->key_symbol)
                         break;
               }
               if (DFB_KEY_IS_ASCII( e->key_symbol )) {
                    if (keyboard_func) {
                         __glutSetWindow( window );
                         keyboard_func( e->key_symbol, e->x, e->y );
                    }
               }
               else {
                    int key = __glutSpecialKey( e->key_symbol );
                    if (key && special_func) {
                         __glutSetWindow( window );
                         special_func( key, e->x, e->y );
                    }
               }
               break;
          case DWET_KEYUP:
               window->modifiers = __glutModifiers( e->modifiers );
               if (DFB_KEY_IS_ASCII( e->key_symbol )) {
                    if (keyboard_up_func) {
                         __glutSetWindow( window );
                         keyboard_up_func( e->key_symbol, e->x, e->y );
                    }
               }
               else {
                    int key = __glutSpecialKey( e->key_symbol );
                    if (key && special_up_func) {
                         __glutSetWindow( window );
                         special_up_func( key, e->x, e->y );
                    }
               }
               break;
          case DWET_BUTTONDOWN:
               if (mouse_func) {
                    __glutSetWindow( window );
                    mouse_func( __glutButton( e->button ), GLUT_DOWN, e->x, e->y );
               }
               break;
          case DWET_BUTTONUP:
               if (mouse_func) {
                    __glutSetWindow( window );
                    mouse_func( __glutButton( e->button ), GLUT_UP, e->x, e->y );
               }
               break;
          case DWET_MOTION:
               if (e->buttons) {
                    if (motion_func) {
                         __glutSetWindow( window );
                         motion_func( e->cx, e->cy );
                    }
               }
               else {
                    if (passive_motion_func) {
                         __glutSetWindow( window );
                         passive_motion_func( e->cx, e->cy );
                    }
               }
               break;
          case DWET_ENTER:
               if (entry_func) {
                    __glutSetWindow( window );
                    entry_func( GLUT_ENTERED );
               }
               break;
          case DWET_LEAVE:
               if (entry_func) {
                    __glutSetWindow( window );
                    entry_func( GLUT_LEFT );
               }
               break;
          case DWET_SIZE:
               window->reshape = GL_TRUE;
               window->redisplay = GL_TRUE;
               break;
          default:
               break;
     }
}
Ejemplo n.º 15
0
/***********************************************************
 *	FUNCTION:	processEventsAndTimeouts
 *
 *	DESCRIPTION:  clear gBlock, then check all windows for events
 ***********************************************************/
static void
processEventsAndTimeouts(void)
{
	gBlock.WaitEvent();		// if there is already an event, returns
							// immediately, otherwise wait forever
	gBlock.ClearEvents();
	
	if(gState.quitAll)
		exit(0);		// exit handler cleans up windows and quits nicely
	
	if (gState.currentWindow)
		gState.currentWindow->LockGL();
	for(int i=0; i<gState.windowListSize; i++) {
		if (gState.windowList[i]) {
			GlutWindow *win = gState.windowList[i];
			// NOTE: we can use win as a shortcut for gState.windowList[i]
			// in callbacks, EXCEPT we need to check the original variable
			// after each callback to make sure the window hasn't been destroyed
			if (win->anyevents) {
				win->anyevents = false;
				if (win->reshapeEvent) {
					win->reshapeEvent = false;
					__glutSetWindow(win);
					win->reshape(win->m_width, win->m_height);
				}
				if (!gState.windowList[i])
					continue;	// window was destroyed by callback!

				if (win->displayEvent) {
					win->displayEvent = false;
					__glutSetWindow(win);
					win->display();
				}
				if (!gState.windowList[i])
					continue;	// window was destroyed by callback!

				if (win->mouseEvent) {
					win->mouseEvent = false;
					__glutSetWindow(win);
					if (win->mouse) {
						gState.modifierKeys = win->modifierKeys;
						win->mouse(win->button, win->mouseState, win->mouseX, win->mouseY);
						gState.modifierKeys = ~0;
					}
				}
				if (!gState.windowList[i])
					continue;	// window was destroyed by callback!

				if (win->menuEvent) {
					win->menuEvent = false;
					__glutSetWindow(win);
					GlutMenu *menu = __glutGetMenuByNum(win->menuNumber);
					if (menu) {
						gState.currentMenu = menu;
						menu->select(win->menuValue);
					}
				}
				if (!gState.windowList[i])
					continue;	// window was destroyed by callback!

				if (win->statusEvent) {
					win->statusEvent = false;
					__glutSetWindow(win);
					if (gState.menuStatus) {
						gState.currentMenu = __glutGetMenuByNum(win->menuNumber);
						gState.menuStatus(win->menuStatus, win->statusX, win->statusY);
					}
				}
				if (!gState.windowList[i])
					continue;	// window was destroyed by callback!

				if (win->motionEvent) {
					win->motionEvent = false;
					__glutSetWindow(win);
					if (win->motion)
						win->motion(win->motionX, win->motionY);
				}
				if (!gState.windowList[i])
					continue;	// window was destroyed by callback!

				if (win->passiveEvent) {
					win->passiveEvent = false;
					__glutSetWindow(win);
					if (win->passive)
						win->passive(win->passiveX, win->passiveY);
				}
				if (!gState.windowList[i])
					continue;	// window was destroyed by callback!

				if (win->keybEvent) {
					win->keybEvent = false;
					__glutSetWindow(win);
					if (win->keyboard) {
						gState.modifierKeys = win->modifierKeys;
						win->keyboard(win->key, win->keyX, win->keyY);
						gState.modifierKeys = ~0;
					}
				}
				if (!gState.windowList[i])
					continue;	// window was destroyed by callback!

				if (win->specialEvent) {
					win->specialEvent = false;
					__glutSetWindow(win);
					if (win->special) {
						gState.modifierKeys = win->modifierKeys;
						win->special(win->specialKey, win->specialX, win->specialY);
						gState.modifierKeys = ~0;
					}
				}
				if (!gState.windowList[i])
					continue;	// window was destroyed by callback!

				if (win->keybUpEvent) {
					win->keybUpEvent = false;
					__glutSetWindow(win);
					if (win->keyboardUp) {
						gState.modifierKeys = win->modifierKeys;
						win->keyboardUp(win->key, win->keyX, win->keyY);
						gState.modifierKeys = ~0;
					}
				}
				if (!gState.windowList[i])
					continue;	// window was destroyed by callback!

				if (win->specialUpEvent) {
					win->specialUpEvent = false;
					__glutSetWindow(win);
					if (win->specialUp) {
						gState.modifierKeys = win->modifierKeys;
						win->specialUp(win->specialKey, win->specialX, win->specialY);
						gState.modifierKeys = ~0;
					}
				}
				if (!gState.windowList[i])
					continue;	// window was destroyed by callback!


				if (win->entryEvent) {
					win->entryEvent = false;
					__glutSetWindow(win);
					if (win->entry)
						win->entry(win->entryState);
				}
				if (!gState.windowList[i])
					continue;	// window was destroyed by callback!

				if (win->windowStatusEvent) {
					win->windowStatusEvent = false;
					__glutSetWindow(win);
					if (win->windowStatus)
						win->windowStatus(win->visState);
				}
				if (!gState.windowList[i])
					continue;	// window was destroyed by callback!
			}
		}
	}
	if (gState.currentWindow)
		gState.currentWindow->UnlockGL();

	// This code isn't necessary since BGLView automatically traps errors
#if 0
	if(gState.debug) {
		for(int i=0; i<gState.windowListSize; i++) {
			if (gState.windowList[i]) {
				gState.windowList[i]->LockGL();
				glutReportErrors();
				gState.windowList[i]->UnlockGL();
			}
		}
	}
#endif
	if (__glutTimerList) {
      handleTimeouts();
    }
}