Add keyboard emulator.
authorbernie <bernie@38d2e660-2303-0410-9eaa-f027e97ec537>
Wed, 15 Feb 2006 09:13:42 +0000 (09:13 +0000)
committerbernie <bernie@38d2e660-2303-0410-9eaa-f027e97ec537>
Wed, 15 Feb 2006 09:13:42 +0000 (09:13 +0000)
git-svn-id: https://src.develer.com/svnoss/bertos/trunk@515 38d2e660-2303-0410-9eaa-f027e97ec537

emul/emul.h
emul/emulkbd.cpp [new file with mode: 0755]
emul/emulkbd.h [new file with mode: 0755]
emul/emulwin.cpp
hw/hw_kbd.h

index 05b486cccf08fd60aafb4d4288d85a991071b36f..b64013fd1c3e05eda0cfc3e3efb8893817232c74 100755 (executable)
@@ -15,6 +15,9 @@
 
 /*#*
  *#* $Log$
+ *#* Revision 1.4  2006/02/15 09:11:17  bernie
+ *#* Add keyboard emulator.
+ *#*
  *#* Revision 1.3  2006/01/23 23:12:08  bernie
  *#* Let Doxygen see through C++ protected section.
  *#*
@@ -38,7 +41,7 @@ class QApplication;
 class EmulWin;
 class EmulPRT;
 class EmulLCD;
-class EmulKBD;
+class EmulKbd;
 class QCheckBox;
 class QSlider;
 class QLabel;
@@ -47,11 +50,11 @@ class Emulator
 {
 // data members
 public:
-       QApplication    *emulApp;       ///< QT Application.
-       EmulWin                 *emulWin;       ///< Main window.
+       QApplication  *emulApp; ///< QT Application.
+       EmulWin       *emulWin; ///< Main window.
 
-       EmulLCD                 *emulLCD;       ///< Display emulator.
-       EmulKBD                 *emulKBD;       ///< Keyboard emulator.
+       EmulLCD       *emulLCD; ///< Display emulator.
+       EmulKbd       *emulKbd; ///< Keyboard emulator.
 
 // construction
        Emulator(int &argc, char **argv);
diff --git a/emul/emulkbd.cpp b/emul/emulkbd.cpp
new file mode 100755 (executable)
index 0000000..2c6c3f8
--- /dev/null
@@ -0,0 +1,206 @@
+/**
+ * \file
+ * <!--
+ * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 2001 Bernardo Innocenti <bernie@codewiz.org>
+ * This file is part of DevLib - See README.devlib for information.
+ * -->
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ *
+ * \brief QT-based widget for keyboard emulation (implementation)
+ */
+
+#include "emulkbd.h"
+#include "emul.h"
+
+#include <qpainter.h>
+#include <qpixmap.h>
+#include <qsizepolicy.h>
+#include <qsize.h>
+#include <qrect.h>
+#include <qlayout.h>
+#include <qobjectlist.h>
+
+
+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(QWidget::NoFocus);
+
+       // unused
+       connect(this, SIGNAL(pressed()), this, SLOT(keyPressed()));
+       connect(this, SIGNAL(released()), this, SLOT(keyReleased()));
+}
+
+
+EmulKey::~EmulKey()
+{
+       // nop
+}
+
+
+/**
+ * \reimp
+ * 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<EmulKbd *>(parent())->setKey(row, col, true);
+}
+
+
+// unused
+void EmulKey::keyReleased(void)
+{
+       static_cast<EmulKbd *>(parent())->setKey(row, col, false);
+}
+
+
+EmulKbd::EmulKbd(QWidget *parent, const char *name, WFlags f) :
+       QFrame(parent, name, WRepaintNoErase | WResizeNoErase | f),
+       layout(new QGridLayout(this, 4, 4, 4)),
+       active_row(0)
+{
+       setFrameStyle(QFrame::Box | QFrame::Sunken);
+       setLineWidth(1);
+       setFocusPolicy(StrongFocus);
+       frame_width = frameWidth();
+}
+
+
+EmulKbd::~EmulKbd()
+{
+       delete layout;
+}
+
+
+QSizePolicy EmulKbd::sizePolicy() const
+{
+       return QSizePolicy(QSizePolicy::Fixed, QSizePolicy::Fixed, false);
+}
+
+
+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<QKeyEvent *>(_e);
+                       int keycode = e->key();
+                       EmulKey *key;
+
+                       // ignore repeated keys
+                       if (!e->isAutoRepeat())
+                       {
+                               // scan all children
+                               for (QObjectListIt it(*children()); *it; ++it)
+                               {
+                                       // only keys, not other children!
+                                       if ((*it)->metaObject() == EmulKey::staticMetaObject())
+                                       // if ((key = dynamic_cast<EmulKey *>(*it)))
+                                       {
+                                               key = static_cast<EmulKey *>(*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(QLayoutIterator it(layout->iterator()); (item = it.current()); ++it)
+       {
+               key = static_cast<EmulKey *>(item->widget());
+               if (key->row == active_row)
+               {
+                       if (key->isDown())
+                               cols |= (1<<key->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"
diff --git a/emul/emulkbd.h b/emul/emulkbd.h
new file mode 100755 (executable)
index 0000000..1eb2432
--- /dev/null
@@ -0,0 +1,94 @@
+/**
+ * \file
+ * <!--
+ * Copyright 2006 Develer S.r.l. (http://www.develer.com/)
+ * Copyright 2001 Bernardo Innocenti <bernie@codewiz.org>
+ * This file is part of DevLib - See README.devlib for information.
+ * -->
+ *
+ * \version $Id$
+ *
+ * \author Bernardo Innocenti <bernie@develer.com>
+ *
+ * \brief QT-based widget for leyboard emulation (interface)
+ */
+
+#if !defined(EMULKBD_H)
+#define EMULKBD_H
+
+#if defined (_MSC_VER) && (_MSC_VER > 1000)
+#pragma once
+#endif // _MSC_VER > 1000
+
+#include <qframe.h>
+
+// fwd decl
+class QGridLayout;
+class EmulKey;
+
+class EmulKbd : public QFrame
+{
+       Q_OBJECT
+
+// Data members
+protected:
+       QGridLayout *layout;
+       int frame_width;
+       int active_row;
+
+// Construction
+public:
+       EmulKbd(QWidget *parent = 0, const char *name = 0, WFlags f = 0);
+       virtual ~EmulKbd();
+
+// Public methods
+       void addKey(const char *label, int keycode, int row, int col, int matrix_row = -1, int matrix_col = -1);
+       void setRow(int row);
+       int readCols(void);
+
+// Protected methods
+protected:
+       void setKey(int row, int col, bool on);
+
+// Base class overrides
+protected:
+       virtual QSizePolicy sizePolicy() const;
+       virtual void resizeEvent(QResizeEvent *e);
+       virtual bool event(QEvent *e);
+
+// Friends
+       friend class EmulKey;
+};
+
+
+// Private helper class for EmulKbd
+// NOTE: with protected inheritance, dynamic_cast<> does not work (gcc 2.96)
+#include <qpushbutton.h>
+class EmulKey : public QPushButton
+{
+       Q_OBJECT
+
+// Data members
+protected:
+       int row, col;
+       int keycode;
+
+// Construction
+public:
+       EmulKey(EmulKbd *parent, const char *label, int keycode, int _row, int _col);
+       virtual ~EmulKey();
+
+// superclass overrides
+       void setDown(bool enable);
+
+protected slots:
+       void keyPressed(void);
+       void keyReleased(void);
+
+// Friends
+public:
+       friend class EmulKbd;
+};
+
+#endif // !defined(EMULKBD_H)
+
index f03fc06c49aa3343eb656f8b750e263f6c961b7e..b2bdc62fd3d012df577bbcf196db1ce68ba3833b 100755 (executable)
@@ -15,6 +15,9 @@
 
 /*#*
  *#* $Log$
+ *#* Revision 1.3  2006/02/15 09:11:17  bernie
+ *#* Add keyboard emulator.
+ *#*
  *#* Revision 1.2  2006/01/16 03:51:51  bernie
  *#* Fix boilerplate.
  *#*
@@ -27,6 +30,7 @@
 
 #include <drv/lcd_gfx_qt.h>
 #include <emul/emul.h>
+#include <emul/emulkbd.h>
 
 #include <cassert>
 #include <qlayout.h>
@@ -40,7 +44,7 @@
 #include <qtimer.h>
 #include <qapplication.h>
 
-EmulWin::EmulWin(Emulator *e) : QMainWindow(0, "SarfEmul", WDestructiveClose)
+EmulWin::EmulWin(Emulator *e) : QMainWindow(0, "DevLibEmul", WDestructiveClose)
 {
        // "File" menu
        QPopupMenu * file = new QPopupMenu(this);
@@ -69,6 +73,16 @@ EmulWin::EmulWin(Emulator *e) : QMainWindow(0, "SarfEmul", WDestructiveClose)
                // LCD
                QHBoxLayout *lay_lcd = new QHBoxLayout(box_right, 4);
                lay_lcd->addWidget(e->emulLCD = new EmulLCD(central));
+
+               // Keyboard
+               QHBoxLayout *lay_kbd = new QHBoxLayout(box_right, 4);
+                       lay_kbd->addWidget(e->emulKbd = new EmulKbd(central));
+
+       // Setup keyboard: Label   Keycode     Row Col MRow MCol
+       e->emulKbd->addKey("^",    Key_Up,     0,  0,  0,   0);
+       e->emulKbd->addKey("v",    Key_Down,   1,  0,  0,   1);
+       e->emulKbd->addKey("OK",   Key_Return, 0,  1,  0,   2);
+       e->emulKbd->addKey("ESC",  Key_Escape, 1,  1,  0,   3);
 }
 
 
index 8908db2786a8e98e4d143d22cec5ad8d92125c37..f73c7c2ed59d5ba1216ea723037279a41b85e4bb 100755 (executable)
@@ -16,6 +16,9 @@
 
 /*#*
  *#* $Log$
+ *#* Revision 1.2  2006/02/15 09:13:42  bernie
+ *#* Add keyboard emulator.
+ *#*
  *#* Revision 1.1  2006/02/10 12:31:03  bernie
  *#* Add templates for hw definitions.
  *#*
 #ifndef HW_KBD_H
 #define HW_KBD_H
 
-
 #include "kbd_map.h"
 #include <cfg/macros.h>
-#include <cfg/debug.h>
-
-
- /*!
- * \name CPU ports <-> switches assignement
- * @{
- */
 
 #define K_RPT_MASK (K_UP | K_DOWN | K_OK | K_CANCEL)
-/*@}*/
-
 
 #define KBD_HW_INIT \
        do { \
        } while (0)
 
+extern "C" int emul_kbdReadCols(void);
 
-/*!
+/**
  * Read the keyboard ports and return the mask of
  * depressed keys.
  */
 INLINE keymask_t kbd_readkeys(void)
 {
-       keymask_t key = 0;
-
-       uint32_t mask = 0xF;
-
-       if (!(mask & 1))
-               key |= K_OK;
-       if (!(mask & 2))
-               key |= K_CANCEL;
-       if (!(mask & 4))
-               key |= K_UP;
-       if (!(mask & 8))
-               key |= K_DOWN;
-
-       return key;
+       return (keymask_t)emul_kbdReadCols();
 }
 
 #endif /* HW_KBD_H */