/** * \file * * * * \author Bernie Innocenti * * \brief QT-based widget for keyboard emulation (implementation) */ #include "emulkbd.h" #include "emul.h" #include #include #include #include #include #include #include #include EmulKey::EmulKey(EmulKbd *kbd, const char *label, int _keycode, int _row, int _col) : QPushButton(label, kbd), row(_row), col(_col), keycode(_keycode) { // don't let the widget get focus setFocusPolicy(Qt::NoFocus); // unused connect(this, SIGNAL(pressed()), this, SLOT(keyPressed())); connect(this, SIGNAL(released()), this, SLOT(keyReleased())); } EmulKey::~EmulKey() { // nop } /** * Override standad QButton behaviour: we must also emit the signals. */ // unused void EmulKey::setDown(bool enable) { // let our superclass do everything else QPushButton::setDown(enable); if (enable) emit pressed(); else emit released(); } // unused void EmulKey::keyPressed(void) { static_cast(parent())->setKey(row, col, true); } // unused void EmulKey::keyReleased(void) { static_cast(parent())->setKey(row, col, false); } EmulKbd::EmulKbd(QWidget *parent, Qt::WFlags f) : QFrame(parent, f), layout(new QGridLayout(this)), active_row(0) { setFrameStyle(QFrame::Box | QFrame::Sunken); setLineWidth(1); setFocusPolicy(Qt::StrongFocus); frame_width = frameWidth(); } EmulKbd::~EmulKbd() { delete layout; } QSizePolicy EmulKbd::sizePolicy() const { return QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed); } void EmulKbd::resizeEvent(QResizeEvent *event) { // Let our superclass process the event first QFrame::resizeEvent(event); } // handle key presses for all keys in keyboard bool EmulKbd::event(QEvent *_e) { switch (_e->type()) { case QEvent::KeyPress: case QEvent::KeyRelease: { QKeyEvent *e = static_cast(_e); int keycode = e->key(); EmulKey *key; // ignore repeated keys if (!e->isAutoRepeat()) { // scan all children for (QObjectList::const_iterator it(children().begin()); it != children().end(); ++it) { // only keys, not other children! if ((*it)->metaObject() == &EmulKey::staticMetaObject) // if ((key = dynamic_cast(*it))) { key = static_cast(*it); // same key? if (key->keycode == keycode) { // yes, tell key to go down (or up) key->setDown(_e->type() == QEvent::KeyPress); break; } } } } return true; } default: // let superclass process this event return QFrame::event(_e); } // end switch(_e->type()) } void EmulKbd::addKey(const char *label, int keycode, int row, int col, int matrix_row, int matrix_col) { if (matrix_row == -1) matrix_row = row; if (matrix_col == -1) matrix_col = col; layout->addWidget(new EmulKey(this, label, keycode, matrix_row, matrix_col), row, col); } // unused void EmulKbd::setKey(int /*row*/, int /*col*/, bool /*on*/) { } void EmulKbd::setRow(int r) { active_row = r; } int EmulKbd::readCols(void) { QLayoutItem *item; EmulKey *key; int cols = 0; for (int i = 0; (item = layout->itemAt(i)); ++i) { key = static_cast(item->widget()); if (key->row == active_row) { if (key->isDown()) cols |= (1<col); } } return cols; } extern "C" void emul_kbdSetRows(int r) { emul->emulKbd->setRow(r); } extern "C" int emul_kbdReadCols(void) { return emul->emulKbd->readCols(); } #include "emulkbd_moc.cpp"