void CSVRender::WorldspaceWidget::mouseReleaseEvent (QMouseEvent *event) { std::string button = mapButton (event); mDragMode.clear(); if (button=="p-edit" || button=="s-edit" || button=="p-select" || button=="s-select") { if (mDragging) { EditMode& editMode = dynamic_cast<CSVRender::EditMode&> (*mEditMode->getCurrent()); editMode.dragCompleted(); mDragging = false; } else { osg::ref_ptr<TagBase> tag = mousePick (event->pos()); handleMouseClick (tag, button, event->modifiers() & Qt::ShiftModifier); } } else SceneWidget::mouseReleaseEvent(event); }
static void handle(Display * dpy, Window win, XIC xic, XEvent * e) { switch(e->type) { case ClientMessage: cvInject(CVE_CLOSE, 0, 0); break; case ConfigureNotify: cvInject(CVE_RESIZE, e->xconfigure.width, e->xconfigure.height); break; case ButtonPress: cvInject(CVE_DOWN, mapButton(e->xbutton.button), 0); break; case ButtonRelease: cvInject(CVE_UP, mapButton(e->xbutton.button), 0); break; case MotionNotify: cvInject(CVE_MOTION, e->xmotion.x, e->xmotion.y); break; case KeyPress: { wchar_t buf[64]; KeySym ks; Status st; int i; int n; cvInject(CVE_DOWN, mapkeycode(e->xkey.keycode), 0); n = XwcLookupString(xic, &e->xkey, buf, sizeof(buf) / sizeof(wchar_t), &ks, &st); if (st == XLookupChars || st == XLookupBoth) for (i = 0; i < n; i++) cvInject(CVE_UNICODE, buf[i], 0); } break; case KeyRelease: if (!isAutoRepeat(dpy, win, e)) cvInject(CVE_UP, mapkeycode(e->xkey.keycode), 0); default: break; } }
void CSMQT4GLWidget::mouseReleaseEvent(QMouseEvent *pEvent) { if(_pOSGWindow != NULL) { _pOSGWindow->mouse(mapButton(pEvent->button()), MouseData::ButtonUp, mapModifier(pEvent->modifiers()), pEvent->x(), pEvent->y()); } }
void CSVRender::WorldspaceWidget::mousePressEvent (QMouseEvent *event) { std::string button = mapButton (event); if (button=="p-edit" || button=="s-edit" || button=="p-select" || button=="s-select") { if (!mDragging) mDragMode = button; } else SceneWidget::mousePressEvent(event); }
int main(int argc, char** argv) { std::setbuf(stdout, NULL); // used to always flush std::cout auto sdl_init_status = SDL_Init(SDL_INIT_EVENTS | SDL_INIT_JOYSTICK | SDL_INIT_GAMECONTROLLER); assert(sdl_init_status==0); bool sampleQuit = false; auto inputproc = std::unique_ptr<sdli::Processor>(new sdli::Processor(SampleContext::MAX_COUNT)); auto& keyboard = inputproc->getKeyboard(); auto& pad = inputproc->getGamecontroller(0); // auto& pad = inputproc->getGamecontroller(0); SDL_Window* w = SDL_CreateWindow("SampleWindow", SDL_WINDOWPOS_UNDEFINED, SDL_WINDOWPOS_UNDEFINED, 800, 600, SDL_WindowFlags::SDL_WINDOW_SHOWN|SDL_WindowFlags::SDL_WINDOW_OPENGL); auto sdl_glContext = SDL_GL_CreateContext(w); auto ctx = inputproc->createContext(SampleContext::Game); auto climb = inputproc->createContext(SampleContext::GameMod); /* [BEG] Bind Axes */ ctx->mapAxis(SDL_SCANCODE_LEFT, SDL_SCANCODE_RIGHT, SampleInputAxis::Horizontal); ctx->mapAxis(SDL_SCANCODE_A, SDL_SCANCODE_D, SampleInputAxis::Horizontal); ctx->mapAxis(SDL_SCANCODE_W, SDL_SCANCODE_S, SampleInputAxis::Vertical); ctx->mapAxis(SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_LEFT, SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_RIGHT, SampleInputAxis::Horizontal); ctx->mapAxis(SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_UP, SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_DPAD_DOWN, SampleInputAxis::Vertical); ctx->mapAxis(SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_LEFTX, SampleInputAxis::Horizontal); ctx->mapAxis(SDL_GameControllerAxis::SDL_CONTROLLER_AXIS_LEFTY, SampleInputAxis::Vertical); /* [END] Bind Axes */ /* [BEG] Bind Buttons */ ctx->mapButton(SDL_SCANCODE_E, SampleInputActions::Shoot); ctx->mapButton(SDL_SCANCODE_F, SampleInputActions::CHANGE_CTX); ctx->mapButton(SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_A, SampleInputActions::Shoot); ctx->mapButton(SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_B, SampleInputActions::CHANGE_CTX); /* [END] Bind Buttons */ ctx->addCallback(sdli::CallType::OnPress, SampleInputActions::CHANGE_CTX, [=,&keyboard, &pad](){ keyboard.pushContext(climb); pad.pushContext(climb); }); climb->mapButton(SDL_SCANCODE_F, SampleInputActions::CHANGE_CTX); climb->mapButton(SDL_GameControllerButton::SDL_CONTROLLER_BUTTON_B, SampleInputActions::CHANGE_CTX); climb->addCallback(sdli::CallType::OnRelease, SampleInputActions::CHANGE_CTX, [=,&keyboard, &pad](){ keyboard.popContext(); pad.popContext(); }); keyboard.pushContext(ctx); pad.pushContext(ctx); /* Sample Data */ const int trailCount = 300; float aspectRatio = 600.0f/800.0f; float dx = 0.025f * aspectRatio; float dy = 0.025f; float color[trailCount][4]; color[0][0] = 1.0f; color[0][1] = 1.0f; color[0][2] = 1.0f; color[0][3] = 1.0f; for(int i=1;i<trailCount;++i) { color[i][0] = 0.5f + i*(1.5f/trailCount); color[i][1] = 1.0f; color[i][2] = 1.0f; color[i][3] = 1.0f - i*(2.0f/trailCount); } struct Test { float x{0.0f}, y{0.0f}; } player[trailCount]; float add = -0.01f; SDL_Event event; while(!sampleQuit) { while(SDL_PollEvent(&event)) { switch(event.type) { case SDL_QUIT: sampleQuit = true; break; } inputproc->handleSdlEvents(event); } inputproc->poll(); inputproc->dispatch(); for(int i=trailCount-1;i>0;--i) { player[i].x = player[i-1].x; player[i].y = player[i-1].y; } float movDir[2]; movDir[0] = pad.getAxis(SampleInputAxis::Horizontal) + keyboard.getAxis(SampleInputAxis::Horizontal); movDir[1] = pad.getAxis(SampleInputAxis::Vertical) + keyboard.getAxis(SampleInputAxis::Vertical); float len = sqrtf((movDir[0]*movDir[0])+(movDir[1]*movDir[1])); if(!isnan(len) && len!=0.0f) // Character Control { float dmx = (movDir[0] / len) * 0.002f * fabs(movDir[0]); float dmy = (movDir[1] / len) * 0.002f * fabs(movDir[1]); player[0].x = sdli::clamp(player[0].x + dmx, -1.0f +dx, 1.0f -dx); player[0].y = sdli::clamp(player[0].y - dmy, -1.0f + dy, 1.0f -dy); } if(pad.isPressed(SampleInputActions::Shoot) || keyboard.isPressed(SampleInputActions::Shoot)) { printf("shoot\n"); add = 0.001f; } if(pad.isReleased(SampleInputActions::Shoot) || keyboard.isReleased(SampleInputActions::Shoot)) { printf("unshoot\n"); add = -0.001f; } color[0][1] = sdli::clamp(color[0][1] + add, 0.5f, 1.0f); color[0][0] = keyboard.isDown(SampleInputActions::CHANGE_CTX)||pad.isDown(SampleInputActions::CHANGE_CTX)?1.0f:0.0f; glClearColor(0,0,0,1); glClear(GL_DEPTH_BUFFER_BIT|GL_COLOR_BUFFER_BIT); glEnable(GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); // int i = 0; for(int i=trailCount-1;i>=0;--i) { glColor4fv((const GLfloat*)color[i]); glBegin(GL_TRIANGLE_STRIP); glVertex2f(player[i].x - dx * (1.0f - i*(1.0f/trailCount)), player[i].y - dy * (1.0f - i*(1.0f/trailCount))); glVertex2f(player[i].x + dx * (1.0f - i*(1.0f/trailCount)), player[i].y - dy * (1.0f - i*(1.0f/trailCount))); glVertex2f(player[i].x - dx * (1.0f - i*(1.0f/trailCount)), player[i].y + dy * (1.0f - i*(1.0f/trailCount))); glVertex2f(player[i].x + dx * (1.0f - i*(1.0f/trailCount)), player[i].y + dy * (1.0f - i*(1.0f/trailCount))); glEnd(); } glDisable(GL_BLEND); inputproc->swap(); SDL_GL_SwapWindow(w); } SDL_GL_DeleteContext(sdl_glContext); SDL_DestroyWindow(w); return 0; }
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; }