Example #1
0
void CSMQT4GLWidget::mouseMoveEvent(QMouseEvent *pEvent)
{
    if(_pOSGWindow != NULL)
    {
        _pOSGWindow->motion(pEvent->x(), 
                            pEvent->y(),
                            mapModifier(pEvent->modifiers()));
    }
}
Example #2
0
void CSMQT4GLWidget::mouseReleaseEvent(QMouseEvent *pEvent)
{
    if(_pOSGWindow != NULL)
    {
        _pOSGWindow->mouse(mapButton(pEvent->button()),
                           MouseData::ButtonUp,
                           mapModifier(pEvent->modifiers()),
                           pEvent->x(),
                           pEvent->y());
    }
}
Example #3
0
void CSMQT4GLWidget::wheelEvent(QWheelEvent *pEvent)
{
    if(_pOSGWindow != NULL)
    {
        if(pEvent->delta() < 0)
        {
            _pOSGWindow->mouse(MouseData::WheelUpButton,
                               MouseData::ButtonDown,
                               mapModifier(pEvent->modifiers()),
                               pEvent->x(),
                               pEvent->y());
        }
        else
        {
            _pOSGWindow->mouse(MouseData::WheelDownButton,
                               MouseData::ButtonDown,
                               mapModifier(pEvent->modifiers()),
                               pEvent->x(),
                               pEvent->y());
        }
    }
}
Example #4
0
void CSMNativeWindow::xMainLoop(void)
{
    XEvent event;
    char   buffer[31];
    KeySym keysym;

    // Sleep 2 sec to open the window;
    //sleep(_uiCreateNapTime);
    //sleep(1);
    osgSleep(100);

    while(_bRun == true)
    {
        WindowListIt      winIt  = _vWindowList.begin();
        WindowListConstIt winEnd = _vWindowList.end  ();
        
        while(winIt != winEnd)
        {
            Display *pDisplay = (*winIt)->getDisplay();

            while(XPending(pDisplay))
            {
                XNextEvent(pDisplay, &event);

                switch(event.type) 
                {
                    case KeyPress:           
                        
                        XLookupString(&event.xkey, buffer, 30, &keysym, NULL);
                        
#if 0
                        fprintf(stderr, "%x %x %x\n", 
                                keysym, 
                                XK_F12,
                                XK_Home);
#endif

                        if(keysym == XK_Escape) 
                        {
                            _bRun = false;
                            
                        }
                        else if(keysym == XK_End)
                        {
                            fprintf(stderr, "Dump\n");

                            (*winIt)->getWindow()->getShaderCache()->dump();
                        }
                        else if(keysym == XK_F12) 
                        {
                            FieldContainerFactory::the()->dump();
                        }
                        else if(keysym == XK_F11) 
                        {
                            fprintf(stderr, "dump vp[0] root\n");

                            Window *pWin = (*winIt)->getWindow();

                            if(pWin != NULL)
                            {
                                Viewport *pPort = pWin->getPort(0);

                                if(pPort != NULL)
                                {
                                    fprintf(stderr, "root %p\n",
                                            static_cast<void *>(
                                                pPort->getRoot()));

                                    DotFileGeneratorGraphOpRefPtr pGO =
                                        DotFileGeneratorGraphOp::create();

                                    pGO->traverse(pPort->getRoot());
                                }
                                else
                                {
                                    fprintf(stderr, "viewport NULL\n");
                                }
                            }
                            else
                            {
                                fprintf(stderr, "win NULL\n");
                            }
                        }
                        else if(keysym == XK_F10) 
                        {
                            fprintf(stderr, "osg dump vp[0] root\n");

                            Window *pWin = (*winIt)->getWindow();

                            if(pWin != NULL)
                            {
                                Viewport *pPort = pWin->getPort(0);

                                if(pPort != NULL)
                                {
                                    fprintf(stderr, "root %p\n",
                                            static_cast<void *>(
                                                pPort->getRoot()));

                                    SceneFileHandler::the()->write(
                                        pPort->getRoot(),
                                        "/tmp/csm.osg");

                                }
                                else
                                {
                                    fprintf(stderr, "viewport NULL\n");
                                }
                            }
                            else
                            {
                                fprintf(stderr, "win NULL\n");
                            }
                        }
                        else if(keysym == XK_F8) 
                        {
                            fprintf(stderr, "pass mask pool\n");
                            fprintf(stderr, "================\n");

                            PassMaskPool::the()->dump();

                            fprintf(stderr, "render prop pool\n");
                            fprintf(stderr, "================\n");

                            RenderPropertiesPool::the()->dump();
                        }
                        else if(keysym == XK_Home) 
                        {
                            ComplexSceneManager::the()->resetScene();
                        }
                        else if((XK_space      <= keysym) && 
                                (XK_asciitilde >= keysym))
                        {
                            ComplexSceneManager::the()->key(
                                event.xkey.x,
                                event.xkey.y,
                                CSMKeyData::ButtonDown,
                                Char8(keysym));
                        }
                        break;

                    case KeyRelease:           
                        
                        XLookupString(&event.xkey, buffer, 30, &keysym, NULL);
                        
                        //fprintf(stderr, "%x\n", keysym);

                        if(keysym == XK_Escape) 
                        {
                        }
                        else if((XK_space      <= keysym) && 
                                (XK_asciitilde >= keysym))
                        {
                            ComplexSceneManager::the()->key(
                                event.xkey.x,
                                event.xkey.y,
                                CSMKeyData::ButtonUp,
                                Char8(keysym));
                        }
                        break;


                    case ButtonPress:
                        
                        (*winIt)->mouse(event.xbutton.button - 1,
                                        MouseData::ButtonDown,
                                        mapModifier(event.xbutton.state),
                                        event.xbutton.x,
                                        event.xbutton.y);

                        break;

                    case ButtonRelease:

                        (*winIt)->mouse(event.xbutton.button - 1,
                                        MouseData::ButtonUp,
                                        mapModifier(event.xbutton.state),
                                        event.xbutton.x,
                                        event.xbutton.y);

                    break;

                    case MotionNotify:

                        (*winIt)->motion(event.xbutton.x, 
                                         event.xbutton.y,
                                         mapModifier(event.xbutton.state));

                    break;

                    case ConfigureNotify:
                    {
                        (*winIt)->reshape(event.xconfigure.width,
                                          event.xconfigure.height);
                    }                
                    break;

                    default:
                        break;
                }
                
            }
            
            ++winIt;
        }

        ComplexSceneManager::the()->frame();
        
        Thread::getCurrentChangeList()->commitChangesAndClear();
    }

    ComplexSceneManager::the()->terminate();
}
bool
CXWindowsPrimaryScreen::onEvent(CEvent* event)
{
	assert(event != NULL);
	XEvent& xevent = event->m_event;

	// let input methods try to handle event first
	if (m_ic != NULL) {
		// XFilterEvent() may eat the event and generate a new KeyPress
		// event with a keycode of 0 because there isn't an actual key
		// associated with the keysym.  but the KeyRelease may pass
		// through XFilterEvent() and keep its keycode.  this means
		// there's a mismatch between KeyPress and KeyRelease keycodes.
		// since we use the keycode on the client to detect when a key
		// is released this won't do.  so we remember the keycode on
		// the most recent KeyPress (and clear it on a matching
		// KeyRelease) so we have a keycode for a synthesized KeyPress.
		if (xevent.type == KeyPress && xevent.xkey.keycode != 0) {
			m_lastKeycode = xevent.xkey.keycode;
		}
		else if (xevent.type == KeyRelease &&
			xevent.xkey.keycode == m_lastKeycode) {
			m_lastKeycode = 0;
		}

		// now filter the event
		if (XFilterEvent(&xevent, None)) {
			return true;
		}
	}

	// handle event
	switch (xevent.type) {
	case CreateNotify:
		{
			// select events on new window
			CDisplayLock display(m_screen);
			selectEvents(display, xevent.xcreatewindow.window);
		}
		return true;

	case MappingNotify:
		// keyboard mapping changed
		updateKeys();
		return true;

	case KeyPress:
		{
			LOG((CLOG_DEBUG1 "event: KeyPress code=%d, state=0x%04x", xevent.xkey.keycode, xevent.xkey.state));
			const KeyModifierMask mask = mapModifier(xevent.xkey.state);
			KeyID key                  = mapKey(&xevent.xkey);
			if (key != kKeyNone) {
				// check for ctrl+alt+del emulation
				if ((key == kKeyPause || key == kKeyBreak) &&
					(mask & (KeyModifierControl | KeyModifierAlt)) ==
							(KeyModifierControl | KeyModifierAlt)) {
					// pretend it's ctrl+alt+del
					LOG((CLOG_DEBUG "emulate ctrl+alt+del"));
					key = kKeyDelete;
				}

				// get which button.  see call to XFilterEvent() above
				// for more info.
				KeyCode keycode = xevent.xkey.keycode;
				if (keycode == 0) {
					keycode = m_lastKeycode;
				}

				// handle key
				m_receiver->onKeyDown(key, mask,
								static_cast<KeyButton>(keycode));
				if (key == kKeyCapsLock && m_capsLockHalfDuplex) {
					m_receiver->onKeyUp(key, mask | KeyModifierCapsLock,
								static_cast<KeyButton>(keycode));
				}
				else if (key == kKeyNumLock && m_numLockHalfDuplex) {
					m_receiver->onKeyUp(key, mask | KeyModifierNumLock,
								static_cast<KeyButton>(keycode));
				}
			}
		}
		return true;

	case KeyRelease:
		{
			const KeyModifierMask mask = mapModifier(xevent.xkey.state);
			KeyID key                  = mapKey(&xevent.xkey);
			if (key != kKeyNone) {
				// check if this is a key repeat by getting the next
				// KeyPress event that has the same key and time as
				// this release event, if any.  first prepare the
				// filter info.
				CKeyEventInfo filter;
				filter.m_event   = KeyPress;
				filter.m_window  = xevent.xkey.window;
				filter.m_time    = xevent.xkey.time;
				filter.m_keycode = xevent.xkey.keycode;

				// now check for event
				bool hasPress;
				{
					XEvent xevent2;
					CDisplayLock display(m_screen);
					hasPress = (XCheckIfEvent(display, &xevent2,
									&CXWindowsPrimaryScreen::findKeyEvent,
									(XPointer)&filter) == True);
				}

				// check for ctrl+alt+del emulation
				if ((key == kKeyPause || key == kKeyBreak) &&
					(mask & (KeyModifierControl | KeyModifierAlt)) ==
							(KeyModifierControl | KeyModifierAlt)) {
					// pretend it's ctrl+alt+del and ignore autorepeat
					LOG((CLOG_DEBUG "emulate ctrl+alt+del"));
					key      = kKeyDelete;
					hasPress = false;
				}


				if (!hasPress) {
					// no press event follows so it's a plain release
					LOG((CLOG_DEBUG1 "event: KeyRelease code=%d, state=0x%04x", xevent.xkey.keycode, xevent.xkey.state));
					if (key == kKeyCapsLock && m_capsLockHalfDuplex) {
						m_receiver->onKeyDown(key, mask,
								static_cast<KeyButton>(xevent.xkey.keycode));
					}
					else if (key == kKeyNumLock && m_numLockHalfDuplex) {
						m_receiver->onKeyDown(key, mask,
								static_cast<KeyButton>(xevent.xkey.keycode));
					}
					m_receiver->onKeyUp(key, mask,
								static_cast<KeyButton>(xevent.xkey.keycode));
				}
				else {
					// found a press event following so it's a repeat.
					// we could attempt to count the already queued
					// repeats but we'll just send a repeat of 1.
					// note that we discard the press event.
					LOG((CLOG_DEBUG1 "event: repeat code=%d, state=0x%04x", xevent.xkey.keycode, xevent.xkey.state));
					m_receiver->onKeyRepeat(key, mask, 1,
								static_cast<KeyButton>(xevent.xkey.keycode));
				}
			}
		}
		return true;

	case ButtonPress:
		{
			LOG((CLOG_DEBUG1 "event: ButtonPress button=%d", xevent.xbutton.button));
			const ButtonID button = mapButton(xevent.xbutton.button);
			if (button != kButtonNone) {
				m_receiver->onMouseDown(button);
			}
		}
		return true;

	case ButtonRelease:
		{
			LOG((CLOG_DEBUG1 "event: ButtonRelease button=%d", xevent.xbutton.button));
			const ButtonID button = mapButton(xevent.xbutton.button);
			if (button != kButtonNone) {
				m_receiver->onMouseUp(button);
			}
			else if (xevent.xbutton.button == 4) {
				// wheel forward (away from user)
				m_receiver->onMouseWheel(120);
			}
			else if (xevent.xbutton.button == 5) {
				// wheel backward (toward user)
				m_receiver->onMouseWheel(-120);
			}
		}
		return true;

	case MotionNotify:
		{
			LOG((CLOG_DEBUG2 "event: MotionNotify %d,%d", xevent.xmotion.x_root, xevent.xmotion.y_root));

			// compute motion delta (relative to the last known
			// mouse position)
			SInt32 x = xevent.xmotion.x_root - m_x;
			SInt32 y = xevent.xmotion.y_root - m_y;

			// save position to compute delta of next motion
			m_x = xevent.xmotion.x_root;
			m_y = xevent.xmotion.y_root;

			if (xevent.xmotion.send_event) {
				// we warped the mouse.  discard events until we
				// find the matching sent event.  see
				// warpCursorNoFlush() for where the events are
				// sent.  we discard the matching sent event and
				// can be sure we've skipped the warp event.
				CDisplayLock display(m_screen);
				do {
					XMaskEvent(display, PointerMotionMask, &xevent);
				} while (!xevent.xmotion.send_event);
			}
			else if (!isActive()) {
				// motion on primary screen
				m_receiver->onMouseMovePrimary(m_x, m_y);
			}
			else {
				// motion on secondary screen.  warp mouse back to
				// center.
				//
				// my lombard (powerbook g3) running linux and
				// using the adbmouse driver has two problems:
				// first, the driver only sends motions of +/-2
				// pixels and, second, it seems to discard some
				// physical input after a warp.  the former isn't a
				// big deal (we're just limited to every other
				// pixel) but the latter is a PITA.  to work around
				// it we only warp when the mouse has moved more
				// than s_size pixels from the center.
				static const SInt32 s_size = 32;
				if (xevent.xmotion.x_root - m_xCenter < -s_size ||
					xevent.xmotion.x_root - m_xCenter >  s_size ||
					xevent.xmotion.y_root - m_yCenter < -s_size ||
					xevent.xmotion.y_root - m_yCenter >  s_size) {
					CDisplayLock display(m_screen);
					warpCursorNoFlush(display, m_xCenter, m_yCenter);
				}

				// send event if mouse moved.  do this after warping
				// back to center in case the motion takes us onto
				// the primary screen.  if we sent the event first
				// in that case then the warp would happen after
				// warping to the primary screen's enter position,
				// effectively overriding it.
				if (x != 0 || y != 0) {
					m_receiver->onMouseMoveSecondary(x, y);
				}
			}
		}
		return true;
	}

	return false;
}