- case ConfigureNotify:
- /*
- * The window gets resized
- */
- fghReshapeWindowByHandle(
- event.xconfigure.window,
- event.xconfigure.width,
- event.xconfigure.height
- );
- break;
-
- case MappingNotify:
- /*
- * Have the client's keyboard knowledge updated (xlib.ps,
- * page 206, says that's a good thing to do)
- */
- XRefreshKeyboardMapping( (XMappingEvent *) &event );
- break;
-
- case VisibilityNotify:
- {
- /*
- * The window's visiblity might have changed
- */
- GETWINDOW( xvisibility );
-
- /*
- * Break now if no window status callback has been hooked to that window
- */
- if( window->Callbacks.WindowStatus == NULL )
- break;
-
- /*
- * We're going to send a callback to a window. Make it current.
- */
- glutSetWindow( window->ID );
-
- /*
- * Sending this event, the X server can notify us that the window has just
- * acquired one of the three possible visibility states: VisibilityUnobscured,
- * VisibilityPartiallyObscured or VisibilityFullyObscured
- */
- switch( event.xvisibility.state )
- {
- case VisibilityUnobscured:
- /*
- * We are fully visible...
- */
- window->Callbacks.WindowStatus( GLUT_FULLY_RETAINED );
- window->State.Visible = TRUE;
- break;
-
- case VisibilityPartiallyObscured:
- /*
- * The window is partially visible
- */
- window->Callbacks.WindowStatus( GLUT_PARTIALLY_RETAINED );
- window->State.Visible = TRUE;
- break;
-
- case VisibilityFullyObscured:
- /*
- * The window is totally obscured
- */
- window->Callbacks.WindowStatus( GLUT_FULLY_COVERED );
- window->State.Visible = FALSE;
- break;
- }
- }
- break;
-
- case EnterNotify:
- {
- /*
- * Mouse is over one of our windows
- */
- GETWINDOW( xcrossing ); GETMOUSE( xcrossing );
-
- /*
- * Is there an entry callback hooked to the window?
- */
- if( window->Callbacks.Entry != NULL )
- {
- /*
- * Yeah. Notify the window about having the mouse cursor over
- */
- window->Callbacks.Entry( GLUT_ENTERED );
- }
- }
- break;
-
- case LeaveNotify:
- {
- /*
- * Mouse is no longer over one of our windows
- */
- GETWINDOW( xcrossing ); GETMOUSE( xcrossing );
-
- /*
- * Is there an entry callback hooked to the window?
- */
- if( window->Callbacks.Entry != NULL )
- {
- /*
- * Yeah. Notify the window about having the mouse cursor over
- */
- window->Callbacks.Entry( GLUT_LEFT );
- }
- }
- break;
-
- case MotionNotify:
- {
- /*
- * The mouse cursor was moved...
- */
- GETWINDOW( xmotion ); GETMOUSE( xmotion );
-
- /*
- * What kind of a movement was it?
- */
- if( (event.xmotion.state & Button1Mask) || (event.xmotion.state & Button2Mask) ||
- (event.xmotion.state & Button3Mask) || (event.xmotion.state & Button4Mask) ||
- (event.xmotion.state & Button5Mask) )
- {
- /*
- * A mouse button was pressed during the movement...
- * Is there a motion callback hooked to the window?
- */
- if( window->Callbacks.Motion != NULL )
- {
- /*
- * Yup. Have it executed immediately
- */
- window->Callbacks.Motion( event.xmotion.x, event.xmotion.y );
- }
- }
- else
- {
- /*
- * Otherwise it was a passive movement...
- */
- if( window->Callbacks.Passive != NULL )
- {
- /*
- * That's right, and there is a passive callback, too.
- */
- window->Callbacks.Passive( event.xmotion.x, event.xmotion.y );
- }
- }
- }
- break;
-
- case ButtonRelease:
- case ButtonPress:
- {
- int button;
-
- /*
- * A mouse button has been pressed or released. Traditionally,
- * break if the window was found within the freeglut structures.
- */
- GETWINDOW( xbutton ); GETMOUSE( xbutton );
-
- /*
- * GLUT API assumes that you can't have more than three mouse buttons, so:
- */
- switch( event.xbutton.button )
- {
- /*
- * WARNING: this might be wrong, if we only have two mouse buttons,
- * Button2 might mean the right button, isn't that right?
- */
- case Button1: button = GLUT_LEFT_BUTTON; break;
- case Button2: button = GLUT_MIDDLE_BUTTON; break;
- case Button3: button = GLUT_RIGHT_BUTTON; break;
- default: button = -1; break;
- }
-
- /*
- * Skip the unwanted mouse buttons...
- */
- if( button == -1 )
- break;
-
- /*
- * Do not execute the callback if a menu is hooked to this key.
- * In that case an appropriate private call should be generated
- */
- if( window->Menu[ button ] != NULL )
- {
- /*
- * Set the current window
- */
- glutSetWindow( window->ID );
-
- if( event.type == ButtonPress )
- {
- /*
- * Activate the appropriate menu structure...
- */
- fgActivateMenu( button );
- }
- else
- {
- /*
- * There are two general cases generated when a menu button
- * is released -- it can provoke a menu call (when released
- * over a menu area) or just deactivate the menu (when released
- * somewhere else). Unfortunately, both cases must be checked
- * recursively due to the submenu possibilities.
- */
- fgDeactivateMenu( button );
- }
- break;
- }
-
- /*
- * Check if there is a mouse callback hooked to the window
- */
- if( window->Callbacks.Mouse == NULL )
- break;
-
- /*
- * Set the current window
- */
- glutSetWindow( window->ID );
-
- /*
- * Remember the current modifiers state
- */
- modifiers = 0;
- if (event.xbutton.state & (ShiftMask|LockMask))
- modifiers |= GLUT_ACTIVE_SHIFT;
- if (event.xbutton.state & ControlMask)
- modifiers |= GLUT_ACTIVE_CTRL;
- if (event.xbutton.state & Mod1Mask)
- modifiers |= GLUT_ACTIVE_ALT;
- window->State.Modifiers = modifiers;
-
- /*
- * Finally execute the mouse callback
- */
- window->Callbacks.Mouse(
- button,
- event.type == ButtonPress ? GLUT_DOWN : GLUT_UP,
- event.xbutton.x,
- event.xbutton.y
- );
-
- /*
- * Trash the modifiers state
- */
- window->State.Modifiers = 0xffffffff;
- }
- break;
-
- case KeyRelease:
- case KeyPress:
- {
- FGCBkeyboard keyboard_cb;
- FGCBspecial special_cb;
-
- /*
- * A key has been pressed, find the window that had the focus:
- */
- GETWINDOW( xkey ); GETMOUSE( xkey );
-
- if( event.type == KeyPress )
- {
- keyboard_cb = window->Callbacks.Keyboard;
- special_cb = window->Callbacks.Special;
- }
- else
- {
- keyboard_cb = window->Callbacks.KeyboardUp;
- special_cb = window->Callbacks.SpecialUp;
- }
-
- /*
- * Is there a keyboard/special callback hooked for this window?
- */
- if( (keyboard_cb != NULL) || (special_cb != NULL) )
- {
- XComposeStatus composeStatus;
- char asciiCode[ 32 ];
- KeySym keySym;
- int len;
-
- /*
- * Check for the ASCII/KeySym codes associated with the event:
- */
- len = XLookupString( &event.xkey, asciiCode, sizeof(asciiCode), &keySym, &composeStatus );
-
- /*
- * Get ready to calling the keyboard/special callbacks
- */
- glutSetWindow( window->ID );
-
- /*
- * GLUT API tells us to have two separate callbacks...
- */
- if( len > 0 )
- {
- /*
- * ...one for the ASCII translateable keypresses...
- */
- if( keyboard_cb != NULL )
- {
- /*
- * Remember the current modifiers state
- */
- modifiers = 0;
- if (event.xkey.state & (ShiftMask|LockMask))
- modifiers |= GLUT_ACTIVE_SHIFT;
- if (event.xkey.state & ControlMask)
- modifiers |= GLUT_ACTIVE_CTRL;
- if (event.xkey.state & Mod1Mask)
- modifiers |= GLUT_ACTIVE_ALT;
- window->State.Modifiers = modifiers;
-
- /*
- * Execute the callback
- */
- keyboard_cb( asciiCode[ 0 ], event.xkey.x, event.xkey.y );
-
- /*
- * Trash the modifiers state
- */
- window->State.Modifiers = 0xffffffff;
- }
- }
- else
- {
- int special = -1;
-
- /*
- * ...and one for all the others, which need to be translated to GLUT_KEY_Xs...
- */
- switch( keySym )
- {
- /*
- * First the function keys come:
- */
- case XK_F1: special = GLUT_KEY_F1; break;
- case XK_F2: special = GLUT_KEY_F2; break;
- case XK_F3: special = GLUT_KEY_F3; break;
- case XK_F4: special = GLUT_KEY_F4; break;
- case XK_F5: special = GLUT_KEY_F5; break;
- case XK_F6: special = GLUT_KEY_F6; break;
- case XK_F7: special = GLUT_KEY_F7; break;
- case XK_F8: special = GLUT_KEY_F8; break;
- case XK_F9: special = GLUT_KEY_F9; break;
- case XK_F10: special = GLUT_KEY_F10; break;
- case XK_F11: special = GLUT_KEY_F11; break;
- case XK_F12: special = GLUT_KEY_F12; break;
-
- /*
- * Then the arrows and stuff:
- */
- case XK_Left: special = GLUT_KEY_LEFT; break;
- case XK_Right: special = GLUT_KEY_RIGHT; break;
- case XK_Up: special = GLUT_KEY_UP; break;
- case XK_Down: special = GLUT_KEY_DOWN; break;
-
- case XK_KP_Prior:
- case XK_Prior: special = GLUT_KEY_PAGE_UP; break;
- case XK_KP_Next:
- case XK_Next: special = GLUT_KEY_PAGE_DOWN; break;
- case XK_KP_Home:
- case XK_Home: special = GLUT_KEY_HOME; break;
- case XK_KP_End:
- case XK_End: special = GLUT_KEY_END; break;
- case XK_KP_Insert:
- case XK_Insert: special = GLUT_KEY_INSERT; break;
- }
-
- /*
- * Execute the callback (if one has been specified),
- * given that the special code seems to be valid...
- */
- if( (special_cb != NULL) && (special != -1) )
- {
- /*
- * Remember the current modifiers state
- */
- modifiers = 0;
- if (event.xkey.state & (ShiftMask|LockMask))
- modifiers |= GLUT_ACTIVE_SHIFT;
- if (event.xkey.state & ControlMask)
- modifiers |= GLUT_ACTIVE_CTRL;
- if (event.xkey.state & Mod1Mask)
- modifiers |= GLUT_ACTIVE_ALT;
- window->State.Modifiers = modifiers;
-
- special_cb( special, event.xkey.x, event.xkey.y );
-
- /*
- * Trash the modifiers state
- */
- window->State.Modifiers = 0xffffffff;
- }
- }
- }
- }
- break;
- }