X-Git-Url: https://git.ralfj.de/multypo.git/blobdiff_plain/d06ad1b372082777c92dbc4065c0a355bc2bef93..318e322c3cd72e6a7f692c6f7c7770c0e15720c8:/qt/multypo.cpp?ds=sidebyside diff --git a/qt/multypo.cpp b/qt/multypo.cpp index a5d8137..d58d247 100644 --- a/qt/multypo.cpp +++ b/qt/multypo.cpp @@ -2,8 +2,9 @@ #include #include -#include +#include #include +#include #include #include @@ -11,69 +12,157 @@ MultypoWindow::MultypoWindow(QWidget *parent) : QWidget(parent), + state(Naming), xiInited(false) { - QHBoxLayout *layout = new QHBoxLayout(this); - setLayout(layout); + /* Prepare colors */ + setStyleSheet("background-color: black; color: green; font-size: 45pt"); - mainLabel = new QLabel(this); - layout->addWidget(mainLabel); + /* Prepare conents */ + setLayout(new QVBoxLayout(this)); - setMinimumSize(300, 300); + mainLabel = new QLabel("Namen eingeben, dann Return", this); + layout()->addWidget(mainLabel); + + /* Fullscreen, no cursor */ + setWindowState(Qt::WindowFullScreen); + setCursor(QCursor(Qt::BlankCursor)); + + words.open(stdin,QIODevice::ReadOnly); } MultypoWindow::~MultypoWindow() { } -void MultypoWindow::showEvent ( QShowEvent * ) -{ - if (xiInited) return; - - Display *dpy = x11Info().display(); - - /* XInput Extension available? */ - int eventID, errorID; - if (!XQueryExtension(dpy, "XInputExtension", &xiOpcode, &eventID, &errorID)) { - qCritical() << "X Input extension not available"; - } - - /* Which version of XI2? We support 2.0 */ - int major = 2, minor = 0; - if (XIQueryVersion(dpy, &major, &minor) == BadRequest) { - qCritical() << "XI2 not available. Server supports" << major << "." << - minor; +void MultypoWindow::nextWord() { + QByteArray tmp = words.readLine().trimmed(); + currentWord = QString::fromUtf8(tmp); + qDebug() << "New word" << currentWord; + if (currentWord.isEmpty()) { // game over + mainLabel->setText("GAME OVER"); + for (QMap::Iterator it = players.begin(); it != players.end(); ++it) { + it.value()->showScore(); + } + state = Scoring; + } else { + for (QMap::Iterator it = players.begin(); it != players.end(); ++it) { + it.value()->nextWord(); + } + mainLabel->setText(currentWord); + state = Playing; } +} - qDebug() << "System is sane"; - - - // Now let's listen to keypress events - XIEventMask eventmask; - unsigned char mask [1] = { 0 }; // will change - eventmask.deviceid = XIAllMasterDevices; - eventmask.mask_len = sizeof (mask); // in bytes, for whatever reason... - eventmask.mask = mask; - XISetMask(mask, XI_KeyPress); - XISelectEvents (dpy, winId(), &eventmask, 1); +bool MultypoWindow::allPlayersWaiting() +{ + for (QMap::Iterator it = players.begin(); it != players.end(); ++it) { + if (it.value()->getState() != Player::Waiting) return false; + } + return true; +} - xiInited = true; +int MultypoWindow::typingPlayers() +{ + int n = 0; + for (QMap::Iterator it = players.begin(); it != players.end(); ++it) { + if (it.value()->getState() == Player::Typing) ++n; + } + return n; } void MultypoWindow::handleKeyPress(int device, QString string) { qDebug() << "Device" << device << "String" << string; - mainLabel->setText(QString("%1 pressed on %2").arg(string).arg(device)); + + if (string == "Escape") { + close(); + return; + } + + if (!players.contains(device)) { + if (state > Naming) + return; + players[device] = new Player(this); + } + Player *player = players[device]; + player->handleKey(string); + + if (state == Naming) { + // someone's still naming (or nobody's there yet) + qDebug() << "checking for game started"; + if (!players.empty() && allPlayersWaiting()) { + nextWord(); + } + } + else if (state == Playing) { // all players are waiting or typing + qDebug() << "current player line" << player->getCurrentWord(); + qDebug() << "current word" << currentWord; + if (player->getState() == Player::Typing && player->getCurrentWord() == currentWord) { + int points = typingPlayers()+1; + player->wordComplete(points); + QString readyString = QString("READY: %1 points").arg(points); + if (allPlayersWaiting()) { + nextWord(); + } + } + } } bool MultypoWindow::handleX11Event(XEvent *event) { - if (!xiInited) return false; Display *dpy = x11Info().display(); + /* Handle the first map event: We are finally visible! */ + if (!xiInited && event->type == MapNotify) { + /* XInput Extension available? */ + int eventID, errorID; + if (!XQueryExtension(dpy, "XInputExtension", &xiOpcode, &eventID, &errorID)) { + qCritical() << "X Input extension not available"; + } - if (event->xcookie.type == GenericEvent && event->xcookie.extension == xiOpcode - && event->xcookie.evtype == XI_KeyPress && XGetEventData(dpy, &event->xcookie)) { + /* Which version of XI2? We support 2.0 */ + int major = 2, minor = 1; + if (XIQueryVersion(dpy, &major, &minor) == BadRequest) { + qCritical() << "XI2 not available. Server supports" << major << "." << + minor; + } + qDebug() << "System supports XI2"; + + + // Now let's listen to keypress events + XIEventMask eventmask; + unsigned char mask [1] = { 0 }; // will change + eventmask.deviceid = XIAllMasterDevices; + eventmask.mask_len = sizeof (mask); // in bytes, for whatever reason... + eventmask.mask = mask; + XISetMask(mask, XI_KeyPress); + XISelectEvents (dpy, winId(), &eventmask, 1); + + // finally, grab all focuses + int ndevices; + XIDeviceInfo* devices = XIQueryDevice(dpy, XIAllMasterDevices, &ndevices); + for (int i = 0; i < ndevices; ++i) { + if (devices[i].use != XIMasterKeyboard) continue; + qDebug() << "Found master keyboard with ID" << devices[i].deviceid; + XISetFocus(dpy, devices[i].deviceid, winId(), CurrentTime); + } + XIFreeDeviceInfo(devices); + + xiInited = true; + + return false; + } + else if (xiInited && event->type == GenericEvent + && event->xcookie.type == GenericEvent && event->xcookie.extension == xiOpcode + && event->xcookie.evtype == XI_KeyPress) { + + if (XGetEventData(dpy, &event->xcookie) != True) { + qCritical() << "Error getting event data"; + // FIXME return true; + } + + /* Handle XI event */ XIDeviceEvent *d_ev = (XIDeviceEvent*) event->xcookie.data; KeyCode keycode = d_ev->detail; int kbdid = d_ev->deviceid; @@ -88,6 +177,7 @@ bool MultypoWindow::handleX11Event(XEvent *event) return true; } - - return false; + else { + return false; + } }