void Manager::handlePutBottom(ValueEvent<PutBottomMsg>* e) { auto v = e->value(); Seat* s = seat(v.seat()); std::vector<Card> bottom; for (auto c : v.card()) { bottom.push_back(c); } if (mStatus != PickBottom) { notifyPutBottomFail(s, bottom, ErrorCode::StatusError); return; } if (s->seat() != mDealer) { notifyPutBottomFail(s, bottom, ErrorCode::PerformerError); return; } try { mChecker->putBottom(s, bottom); mRes.putBottom(bottom); mStatus = BottomFinish; notifyFixBottom(s, bottom, FixBottomReason::Normal); } catch (Exception& e) { notifyPutBottomFail(s, bottom, e.code()); } }
void Manager::handleClaimMaster(ValueEvent<ClaimMasterMsg>* e) { auto v = e->value(); Seat* s = seat(v.seat()); Card::Suit suit = (Card::Suit)v.suit(); if (mStatus != Deal && mStatus != DealWait && mStatus != DealFinish && mStatus != ChangeDealer) { notifyClaimMasterFail(s, ErrorCode::StatusError); return; } try { mChecker->claimMaster(mMaster, s, suit); notifyFixMaster(mMaster); } catch (Exception& excp) { notifyClaimMasterFail(s, excp.code()); } }
void ServPlayer::handle(Message* m) { if (m->type() == MsgType::Attach) { auto msg = m->get<AttachMsg>(); Seat* s = manager()->seat(msg->seat()); msg->set_self(s->player() == this); } mHdler->send(new Message(*m)); }
void Display::startAuth(const QString &user, const QString &password, const Session &session) { m_passPhrase = password; // sanity check if (!session.isValid()) { qCritical() << "Invalid session" << session.fileName(); return; } if (session.xdgSessionType().isEmpty()) { qCritical() << "Failed to find XDG session type for session" << session.fileName(); return; } if (session.exec().isEmpty()) { qCritical() << "Failed to find command for session" << session.fileName(); return; } // cache last session m_lastSession = session; // save session desktop file name, we'll use it to set the // last session later, in slotAuthenticationFinished() m_sessionName = session.fileName(); // some information qDebug() << "Session" << m_sessionName << "selected, command:" << session.exec(); // create new VT for Wayland sessions otherwise use greeter vt int vt = terminalId(); if (session.xdgSessionType() == QLatin1String("wayland")) vt = VirtualTerminal::setUpNewVt(); m_lastSession.setVt(vt); QProcessEnvironment env; env.insert(QStringLiteral("PATH"), mainConfig.Users.DefaultPath.get()); if (session.xdgSessionType() == QLatin1String("x11")) env.insert(QStringLiteral("DISPLAY"), name()); env.insert(QStringLiteral("XDG_SEAT"), seat()->name()); env.insert(QStringLiteral("XDG_SEAT_PATH"), daemonApp->displayManager()->seatPath(seat()->name())); env.insert(QStringLiteral("XDG_SESSION_PATH"), daemonApp->displayManager()->sessionPath(QStringLiteral("Session%1").arg(daemonApp->newSessionId()))); env.insert(QStringLiteral("XDG_VTNR"), QString::number(vt)); env.insert(QStringLiteral("DESKTOP_SESSION"), session.desktopSession()); env.insert(QStringLiteral("XDG_CURRENT_DESKTOP"), session.desktopNames()); env.insert(QStringLiteral("XDG_SESSION_CLASS"), QStringLiteral("user")); env.insert(QStringLiteral("XDG_SESSION_TYPE"), session.xdgSessionType()); env.insert(QStringLiteral("XDG_SESSION_DESKTOP"), session.desktopNames()); m_auth->insertEnvironment(env); m_auth->setUser(user); m_auth->setSession(session.exec()); m_auth->start(); }
void ManagerBase::detach(Player* p) { int id = p->seat(); Seat* s = seat(id); if (s) { if (s->player() == p) { s->setPlayer(nullptr); } p->setSeat(NoneSeat); detach((ManagerObserver*)p); notifyDetach(p, id); } }
void ManagerBase::attach(Player* p, int id) { Seat* s = seat(id); if (!s) { throw Exception(ManagerBaseExcp, ErrorCode::InvalidSeat, "Invalid seat(%d)", id); } if (s->player()) { if (s->player() == p) { return; } throw Exception(ManagerBaseExcp, ErrorCode::SeatOccupied, "Current seat(%d) has been occupied", id); } detach(p); s->setPlayer(p); p->setSeat(id); attach((ManagerObserver*)p); notifyAttach(p, id); }
void Manager::handleDiscardRequest(ValueEvent<DiscardRequestMsg>* e) { Seat* s = seat(e->value().seat()); std::vector<Card> cards; for (auto c : e->value().card()) { cards.push_back(c); } if (mStatus != DiscardWait) { notifyDiscardFail(s, cards, ErrorCode::StatusError); return; } if (mPerformer != s) { notifyDiscardFail(s, cards, ErrorCode::PerformerError); return; } CardContainer res; bool isMax = false; try { isMax = mChecker->discard(mRes, s, cards, res); } catch (Exception& excp) { if (excp.code() == ErrorCode::ThrowFail) { mStatus = ThrowFail; mRes.putThrowFail(s->id(), res); } notifyDiscardFail(s, cards, excp.code()); return; } DiscardActionMsg m; m.set_seat(s->seat()); m.set_max(isMax); m.set_reason(DiscardActionMsg::Normal); m.set_order(mRes.resNumber()); m.set_score(0); mRes.put(s->seat(), res, isMax); if (mRes.resNumber() == 0) { mPerformer = seat(mRes.lastCircle().max()->seat); if ((mPerformer->id() & 1) != (mDealer & 1)) { int score = mRes.lastCircle().score(); if (score > 0) { mRes.addScore(score); m.set_score(score); } } } else { mPerformer = mPerformer->next(); } m << cards; notifyDiscardAction(m); if (mRes.resCnt() == 100) { mStatus = DiscardFinish; std::vector<Card> b; mGen.getBottom(b); Seat* s = seat(mRes.lastCircle().max()->seat); int score = 0; int factor = 0; if ((s->id() & 1) != (mDealer & 1)) { const CardContainer& cc = mRes.lastCircle().max()->cards; if (mOpt.slaveCanCatchBottom || cc.mask().hasOnlySuit() == CardMask::Master) { for (auto& i : b) { score += i.score(); } factor = cc.factor(); if (mOpt.doubleBottomScore) { factor <<= 1; } mRes.addScore(score * factor); } } mPerformer = NULL; notifyDiscardFinish(mRes, score, factor); } else { mStatus = DiscardNotify; } }
int X11Backend::eventLoop() { xcb_generic_event_t* event; int count = 0; while((event = xcb_poll_for_event(xConnection_))) { switch(event->response_type & ~0x80) { case XCB_EXPOSE: { xcb_expose_event_t* ev = (xcb_expose_event_t*) event; auto* outp = outputForWindow(ev->window); if(!outp) { ny::sendWarning("xcb_expose: invalid xcb window"); break; } outp->scheduleRepaint(); break; } case XCB_CLIENT_MESSAGE: { xcb_client_message_event_t* ev = (xcb_client_message_event_t*) event; if(ev->data.data32[0] == atoms::deleteWindow) { auto* outp = outputForWindow(ev->window); if(!outp) { ny::sendWarning("xcb_client_message: invalid xcb window"); break; } destroyOutput(*outp); if(outputs_.empty()) { compositor().exit(); return count + 1; } } break; } case XCB_BUTTON_PRESS: { if(!seat().pointer()) break; xcb_button_press_event_t* ev = (xcb_button_press_event_t*) event; unsigned int code = (ev->detail == 2 ? BTN_MIDDLE : (ev->detail == 3 ? BTN_RIGHT : ev->detail + BTN_LEFT - 1)); seat().pointer()->sendButton(code, 1); break; } case XCB_BUTTON_RELEASE: { if(!seat().pointer()) break; xcb_button_release_event_t* ev = (xcb_button_release_event_t*) event; unsigned int code = (ev->detail == 2 ? BTN_MIDDLE : (ev->detail == 3 ? BTN_RIGHT : ev->detail + BTN_LEFT - 1)); seat().pointer()->sendButton(code, 0); break; } case XCB_MOTION_NOTIFY: { if(!seat().pointer()) break; xcb_motion_notify_event_t* ev = (xcb_motion_notify_event_t*) event; seat().pointer()->sendMove({ev->event_x, ev->event_y}); break; } case XCB_KEY_PRESS: { if(!seat().keyboard()) break; xcb_key_press_event_t* ev = (xcb_key_press_event_t*) event; seat().keyboard()->sendKey(ev->detail - 8, true); break; } case XCB_KEY_RELEASE: { if(!seat().keyboard()) break; xcb_key_press_event_t* ev = (xcb_key_press_event_t*) event; seat().keyboard()->sendKey(ev->detail - 8, false); break; } case XCB_FOCUS_IN: { break; } case XCB_FOCUS_OUT: { break; } case XCB_ENTER_NOTIFY: { break; } case XCB_LEAVE_NOTIFY: { break; } default: break; } if(event->response_type == xkbEventBase_) { xcb_xkb_state_notify_event_t *ev = (xcb_xkb_state_notify_event_t*)event; if(ev->xkbType == XCB_XKB_STATE_NOTIFY) { if(seat().keyboard()) { auto& kb = *seat().keyboard(); xkb_state_update_mask(&kb.xkbState(), kb.modMask(ev->baseMods), kb.modMask(ev->latchedMods), kb.modMask(ev->lockedMods), 0, 0, ev->group); seat().keyboard()->updateModifiers(); } } } free(event); ++count; } return count; }
void Display::startAuth(const QString &user, const QString &password, const QString &session) { QString sessionFileName = session; QString sessionName; QString xdgSessionName; QString command; m_passPhrase = password; // session directory QDir dir(mainConfig.XDisplay.SessionDir.get()); if (!sessionFileName.endsWith(".desktop")) { // prefer a .desktop file if it exists if (QFile::exists(dir.absoluteFilePath(sessionFileName + QStringLiteral(".desktop")))) sessionFileName += QStringLiteral(".desktop"); } if (sessionFileName.endsWith(".desktop")) { qDebug() << "Reading from" << sessionFileName; // session file QFile file(dir.absoluteFilePath(sessionFileName)); // open file if (file.open(QIODevice::ReadOnly)) { // read line-by-line QTextStream in(&file); while (!in.atEnd()) { QString line = in.readLine(); // line starting with Exec if (line.startsWith("Exec=")) command = line.mid(5); // Desktop names, change the separator if (line.startsWith("DesktopNames=")) { xdgSessionName = line.mid(13); xdgSessionName.replace(';', ':'); } } // close file file.close(); } // remove extension sessionName = sessionFileName.left(sessionFileName.lastIndexOf(".")); } else { command = sessionFileName; sessionName = sessionFileName; } if (command.isEmpty()) { qCritical() << "Failed to find command for session:" << sessionFileName; return; } // save session desktop file name, we'll use it to set the // last session later, in slotAuthenticationFinished() m_sessionName = sessionFileName; QProcessEnvironment env; env.insert("PATH", mainConfig.Users.DefaultPath.get()); env.insert("DISPLAY", name()); env.insert("XDG_SEAT", seat()->name()); env.insert("XDG_SEAT_PATH", daemonApp->displayManager()->seatPath(seat()->name())); env.insert("XDG_SESSION_PATH", daemonApp->displayManager()->sessionPath(QString("Session%1").arg(daemonApp->newSessionId()))); env.insert("XDG_VTNR", QString::number(terminalId())); env.insert("DESKTOP_SESSION", sessionName); env.insert("XDG_CURRENT_DESKTOP", xdgSessionName); env.insert("XDG_SESSION_CLASS", "user"); env.insert("XDG_SESSION_TYPE", m_displayServer->sessionType()); env.insert("XDG_SESSION_DESKTOP", xdgSessionName); m_auth->insertEnvironment(env); m_auth->setUser(user); m_auth->setSession(command); m_auth->start(); }