1 /*
2  * synergy -- mouse and keyboard sharing utility
3  * Copyright (C) 2012-2016 Symless Ltd.
4  * Copyright (C) 2011 Nick Bolton
5  *
6  * This package is free software; you can redistribute it and/or
7  * modify it under the terms of the GNU General Public License
8  * found in the file LICENSE that should have accompanied this file.
9  *
10  * This package is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  * GNU General Public License for more details.
14  *
15  * You should have received a copy of the GNU General Public License
16  * along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 
19 #define TEST_ENV
20 
21 #include "test/mock/synergy/MockEventQueue.h"
22 #include "test/mock/synergy/MockKeyMap.h"
23 #include "platform/MSWindowsKeyState.h"
24 #include "platform/MSWindowsDesks.h"
25 #include "platform/MSWindowsScreen.h"
26 #include "platform/MSWindowsScreenSaver.h"
27 #include "base/TMethodJob.h"
28 
29 #include "test/global/gtest.h"
30 #include "test/global/gmock.h"
31 
32 // wParam = flags, HIBYTE(lParam) = virtual key, LOBYTE(lParam) = scan code
33 #define SYNERGY_MSG_FAKE_KEY		SYNERGY_HOOK_LAST_MSG + 4
34 
35 using ::testing::_;
36 using ::testing::NiceMock;
37 
38 class MSWindowsKeyStateTests : public ::testing::Test
39 {
40 protected:
SetUp()41 	virtual void SetUp()
42 	{
43 		m_hook.loadLibrary();
44 		m_screensaver = new MSWindowsScreenSaver();
45 	}
46 
TearDown()47 	virtual void TearDown()
48 	{
49 		delete m_screensaver;
50 	}
51 
newDesks(IEventQueue * eventQueue)52 	MSWindowsDesks* newDesks(IEventQueue* eventQueue)
53 	{
54 		return new MSWindowsDesks(
55             true, false, m_screensaver, eventQueue,
56 			new TMethodJob<MSWindowsKeyStateTests>(
57 				this, &MSWindowsKeyStateTests::updateKeysCB), false);
58 	}
59 
getEventTarget() const60 	void* getEventTarget() const
61 	{
62 		return const_cast<MSWindowsKeyStateTests*>(this);
63 	}
64 
65 private:
updateKeysCB(void *)66 	void updateKeysCB(void*) { }
67 	IScreenSaver* m_screensaver;
68 	MSWindowsHook m_hook;
69 };
70 
TEST_F(MSWindowsKeyStateTests,disable_eventQueueNotUsed)71 TEST_F(MSWindowsKeyStateTests, disable_eventQueueNotUsed)
72 {
73 	NiceMock<MockEventQueue> eventQueue;
74 	MSWindowsDesks* desks = newDesks(&eventQueue);
75 	MockKeyMap keyMap;
76 	MSWindowsKeyState keyState(desks, getEventTarget(), &eventQueue, keyMap);
77 
78 	EXPECT_CALL(eventQueue, removeHandler(_, _)).Times(0);
79 
80 	keyState.disable();
81 	delete desks;
82 }
83 
TEST_F(MSWindowsKeyStateTests,testAutoRepeat_noRepeatAndButtonIsZero_resultIsTrue)84 TEST_F(MSWindowsKeyStateTests, testAutoRepeat_noRepeatAndButtonIsZero_resultIsTrue)
85 {
86 	NiceMock<MockEventQueue> eventQueue;
87 	MSWindowsDesks* desks = newDesks(&eventQueue);
88 	MockKeyMap keyMap;
89 	MSWindowsKeyState keyState(desks, getEventTarget(), &eventQueue, keyMap);
90 	keyState.setLastDown(1);
91 
92 	bool actual = keyState.testAutoRepeat(true, false, 1);
93 
94 	ASSERT_TRUE(actual);
95 	delete desks;
96 }
97 
TEST_F(MSWindowsKeyStateTests,testAutoRepeat_pressFalse_lastDownIsZero)98 TEST_F(MSWindowsKeyStateTests, testAutoRepeat_pressFalse_lastDownIsZero)
99 {
100 	NiceMock<MockEventQueue> eventQueue;
101 	MSWindowsDesks* desks = newDesks(&eventQueue);
102 	MockKeyMap keyMap;
103 	MSWindowsKeyState keyState(desks, getEventTarget(), &eventQueue, keyMap);
104 	keyState.setLastDown(1);
105 
106 	keyState.testAutoRepeat(false, false, 1);
107 
108 	ASSERT_EQ(0, keyState.getLastDown());
109 	delete desks;
110 }
111 
TEST_F(MSWindowsKeyStateTests,saveModifiers_noModifiers_savedModifiers0)112 TEST_F(MSWindowsKeyStateTests, saveModifiers_noModifiers_savedModifiers0)
113 {
114 	NiceMock<MockEventQueue> eventQueue;
115 	MSWindowsDesks* desks = newDesks(&eventQueue);
116 	MockKeyMap keyMap;
117 	MSWindowsKeyState keyState(desks, getEventTarget(), &eventQueue, keyMap);
118 
119 	keyState.saveModifiers();
120 
121 	ASSERT_EQ(0, keyState.getSavedModifiers());
122 	delete desks;
123 }
124 
TEST_F(MSWindowsKeyStateTests,testKoreanLocale_inputModeKey_resultCorrectKeyID)125 TEST_F(MSWindowsKeyStateTests, testKoreanLocale_inputModeKey_resultCorrectKeyID)
126 {
127 	NiceMock<MockEventQueue> eventQueue;
128 	MSWindowsDesks* desks = newDesks(&eventQueue);
129 	MockKeyMap keyMap;
130 	MSWindowsKeyState keyState(desks, getEventTarget(), &eventQueue, keyMap);
131 
132 	keyState.setKeyLayout((HKL)0x00000412u);	// for ko-KR local ID
133 	ASSERT_EQ(0xEF31, keyState.getKeyID(0x15u, 0x1f2u));	// VK_HANGUL from Hangul key
134 	ASSERT_EQ(0xEF34, keyState.getKeyID(0x19u, 0x1f1u));	// VK_HANJA from Hanja key
135 	ASSERT_EQ(0xEF31, keyState.getKeyID(0x15u, 0x11du));	// VK_HANGUL from R-Alt key
136 	ASSERT_EQ(0xEF34, keyState.getKeyID(0x19u, 0x138u));	// VK_HANJA from R-Ctrl key
137 
138 	keyState.setKeyLayout((HKL)0x00000411); // for ja-jp locale ID
139 	ASSERT_EQ(0xEF26, keyState.getKeyID(0x15u, 0x1du));	// VK_KANA
140 	ASSERT_EQ(0xEF2A, keyState.getKeyID(0x19u, 0x38u));	// VK_KANJI
141 
142 	delete desks;
143 }
144 
145