diff --git a/main.cpp b/main.cpp index 6e5db56c..416a76fd 100644 --- a/main.cpp +++ b/main.cpp @@ -3,11 +3,10 @@ int main(int argc, char *argv[]) { - PIDir dir(""); - PIVector el = dir.entries(); - /*piCout << el.size(); - piForeachC (PIFile::FileInfo & i, el) - piCout << i;*/ + PIKbdListener kbd; + kbd.enableExitCapture(); + kbd.start(); + WAIT_FOR_EXIT return 0; } diff --git a/src_main/console/pikbdlistener.cpp b/src_main/console/pikbdlistener.cpp index 3a223a6c..75a62bc0 100644 --- a/src_main/console/pikbdlistener.cpp +++ b/src_main/console/pikbdlistener.cpp @@ -122,8 +122,9 @@ const PIKbdListener::EscSeq PIKbdListener::esc_seq[] = { PRIVATE_DEFINITION_START(PIKbdListener) #ifdef WINDOWS - void * hIn; + void * hIn, * hOut; DWORD smode, tmode; + CONSOLE_SCREEN_BUFFER_INFO sbi; #else struct termios sterm, tterm; #endif @@ -141,6 +142,7 @@ PIKbdListener::PIKbdListener(KBFunc slot, void * _d, bool startNow): PIThread() _object = this; #ifdef WINDOWS PRIVATE->hIn = GetStdHandle(STD_INPUT_HANDLE); + PRIVATE->hOut = GetStdHandle(STD_OUTPUT_HANDLE); GetConsoleMode(PRIVATE->hIn, &PRIVATE->smode); #else tcgetattr(0, &PRIVATE->sterm); @@ -162,7 +164,7 @@ PIKbdListener::~PIKbdListener() { void PIKbdListener::begin() { #ifdef WINDOWS GetConsoleMode(PRIVATE->hIn, &PRIVATE->tmode); - SetConsoleMode(PRIVATE->hIn, ENABLE_PROCESSED_INPUT); + SetConsoleMode(PRIVATE->hIn, ENABLE_PROCESSED_INPUT | ENABLE_MOUSE_INPUT | ENABLE_EXTENDED_FLAGS); #else struct termios term; tcgetattr(0, &term); @@ -174,6 +176,30 @@ void PIKbdListener::begin() { } +#ifdef WINDOWS +PIKbdListener::KeyModifiers getModifiers(DWORD v, bool * shift = 0) { + PIKbdListener::KeyModifiers ret; + bool ctrl = v & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED); + bool shi = v & SHIFT_PRESSED; + bool alt = v & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED); + if (ctrl) ret |= PIKbdListener::Ctrl; + if (shi) ret |= PIKbdListener::Shift; + if (alt) ret |= PIKbdListener::Alt; + //if (meta) ret |= PIKbdListener::Meta; + if (v & CAPSLOCK_ON) shi = !shi; + if (shift) *shift = shi; + return ret; +} +PIKbdListener::MouseButtons getButtons(DWORD v) { + PIKbdListener::MouseButtons ret; + if (v & FROM_LEFT_1ST_BUTTON_PRESSED) ret |= PIKbdListener::MouseLeft; + if (v & RIGHTMOST_BUTTON_PRESSED) ret |= PIKbdListener::MouseRight; + if (v & FROM_LEFT_2ND_BUTTON_PRESSED) ret |= PIKbdListener::MouseMiddle; + return ret; +} +#endif + + void PIKbdListener::readKeyboard() { ke.key = 0; ke.modifiers = 0; @@ -181,17 +207,13 @@ void PIKbdListener::readKeyboard() { #ifdef WINDOWS INPUT_RECORD ir; ReadConsoleInput(PRIVATE->hIn, &ir, 1, &(PRIVATE->ret)); - if (ir.EventType == KEY_EVENT) { + //piCout << ir.EventType; + switch (ir.EventType) { + case KEY_EVENT: { KEY_EVENT_RECORD ker = ir.Event.KeyEvent; if (ker.bKeyDown) { - bool ctrl = ker.dwControlKeyState & (LEFT_CTRL_PRESSED | RIGHT_CTRL_PRESSED); - bool shift = ker.dwControlKeyState & SHIFT_PRESSED; - bool alt = ker.dwControlKeyState & (LEFT_ALT_PRESSED | RIGHT_ALT_PRESSED); - if (ctrl) ke.modifiers |= Ctrl; - if (shift) ke.modifiers |= Shift; - if (alt) ke.modifiers |= Alt; - //if (meta) ke.modifiers |= Meta; - if (ker.dwControlKeyState & CAPSLOCK_ON) shift = !shift; + bool shift = false; + ke.modifiers = getModifiers(ker.dwControlKeyState, &shift); //piCout << "key" << int(ker.wVirtualKeyCode) << int(ker.uChar.AsciiChar); switch (ker.wVirtualKeyCode) { case 8: PRIVATE->ret = 1; ke.key = Backspace; break; @@ -233,7 +255,48 @@ void PIKbdListener::readKeyboard() { } if (ke.key == 0) {piMSleep(10); return;} } else {piMSleep(10); return;} - } else {piMSleep(10); return;} + } + break; + case MOUSE_EVENT: { + MOUSE_EVENT_RECORD mer = ir.Event.MouseEvent; + GetConsoleScreenBufferInfo(PRIVATE->hOut, &PRIVATE->sbi); + //height = PRIVATE->sbi.srWindow.Bottom - ; + me.modifiers = getModifiers(mer.dwControlKeyState); + MouseButtons mb = getButtons(mer.dwButtonState); + //me.action = getButtons(mer.dwButtonState); + me.x = mer.dwMousePosition.X; + me.y = mer.dwMousePosition.Y - PRIVATE->sbi.srWindow.Top; + if (mer.dwEventFlags & MOUSE_WHEELED) { + memcpy(&we, &me, sizeof(me)); + we.action = MouseWheel; + we.direction = short((mer.dwButtonState >> 8) & 0xFFFF) > 0; + piCout << "wheel" << we.direction; + wheelEvent(we, kbddata_); + break; + } else { + bool move = mer.dwEventFlags & MOUSE_MOVED; + if (move && (me.action == MouseButtonRelease)) { + me.action = MouseMove; + return; + } + if (!move) { + if (mb > me.buttons) me.action = MouseButtonPress; + else if (mb < me.buttons) me.action = MouseButtonRelease; + else {piCoutObj << "WTF"; break;} + } else + me.action = MouseMove; + me.buttons = mb; + PIString _s[] = {"press", "release", "move"}; + piCoutObj << _s[me.action] << me.buttons << ":" << me.x << me.y; + mouseEvent(me, kbddata_); + break; + } + } + break; + default: + piMSleep(10); + return; + } /*if (lc == 0) { ReadConsole(hIn, &rc, 1, &(PRIVATE->ret), 0); //cout << "read console" << endl; diff --git a/src_main/console/pikbdlistener.h b/src_main/console/pikbdlistener.h index caf9374c..779858aa 100644 --- a/src_main/console/pikbdlistener.h +++ b/src_main/console/pikbdlistener.h @@ -87,6 +87,51 @@ public: KeyModifiers modifiers; }; + //! Mouse buttons + enum MouseButton { + MouseLeft /** Left button */ = 0x01, + MouseRight /** Right button */ = 0x02, + MouseMiddle /** Middle button */ = 0x04 + }; + + //! Mouse actions + enum MouseAction { + MouseButtonPress /** Mouse button pressed */, + MouseButtonRelease /** Mouse button released */, + MouseMove /** Mouse moved */, + MouseWheel /** Mouse wheel rotated */ + }; + + typedef PIFlags MouseButtons; + + //! This struct contains information about mouse action + struct MouseEvent { + MouseEvent(MouseAction a = MouseButtonPress, MouseButtons b = 0, KeyModifiers m = 0) {x = y = 0; action = a; buttons = b; modifiers = m;} + + //! Event X coordinate in view-space, from 0 + int x; + + //! Event Y coordinate in view-space, from 0 + int y; + + //! Mouse action type + MouseAction action; + + //! Pressed buttons. It contains PIKbdListener::MouseButton bitfields + MouseButtons buttons; + + //! Active keyboard modifiers. It contains PIKbdListener::KeyModifier bitfields + KeyModifiers modifiers; + }; + + //! This struct contains information about mouse wheel action + struct WheelEvent: public MouseEvent { + WheelEvent(): MouseEvent() {direction = false;} + + //! Wheel direction, /b true - up, /b fasle - down + bool direction; + }; + typedef void (*KBFunc)(KeyEvent, void * ); @@ -123,6 +168,8 @@ public: EVENT_HANDLER1(void, setActive, bool, yes); EVENT2(keyPressed, PIKbdListener::KeyEvent, key, void * , data) + EVENT2(mouseEvent, PIKbdListener::MouseEvent, mouse, void * , data) + EVENT2(wheelEvent, PIKbdListener::WheelEvent, wheel, void * , data) //! \handlers //! \{ @@ -182,14 +229,20 @@ private: void * kbddata_; char rc[8]; KeyEvent ke; + MouseEvent me; + WheelEvent we; static PIKbdListener * _object; }; -inline PIByteArray & operator <<(PIByteArray & s, const PIKbdListener::KeyEvent & v) {s << v.key << int(v.modifiers); return s;} +inline PIByteArray & operator <<(PIByteArray & s, const PIKbdListener::KeyEvent & v) {s << v.key << v.modifiers; return s;} +inline PIByteArray & operator <<(PIByteArray & s, const PIKbdListener::MouseEvent & v) {s << v.x << v.y << (int)v.action << v.buttons << v.modifiers; return s;} +inline PIByteArray & operator <<(PIByteArray & s, const PIKbdListener::WheelEvent & v) {s << (*(PIKbdListener::MouseEvent*)&v) << (uchar)v.direction; return s;} -inline PIByteArray & operator >>(PIByteArray & s, PIKbdListener::KeyEvent & v) {int m(0); s >> v.key >> m; v.modifiers = m; return s;} +inline PIByteArray & operator >>(PIByteArray & s, PIKbdListener::KeyEvent & v) {s >> v.key >> v.modifiers; return s;} +inline PIByteArray & operator >>(PIByteArray & s, PIKbdListener::MouseEvent & v) {int a(0); s >> v.x >> v.y >> a >> v.buttons >> v.modifiers; v.action = (PIKbdListener::MouseAction)a; return s;} +inline PIByteArray & operator >>(PIByteArray & s, PIKbdListener::WheelEvent & v) {uchar d(0); s >> (*(PIKbdListener::MouseEvent*)&v) >> d; v.direction = d; return s;} #endif // PIKBDLISTENER_H