Ticket #14860: method.cpp

File method.cpp, 6.4 KB (added by hanya, 5 years ago)

Test input method

Line 
1
2// method.cpp, build
3// g++ -o im_test method.cpp -lbe /boot/system/servers/input_server
4
5
6#include <Application.h>
7#include <Alert.h>
8#include <Menu.h>
9#include <MenuItem.h>
10#include <Messenger.h>
11#include <SupportDefs.h>
12
13#include <add-ons/input_server/InputServerMethod.h>
14
15// circle icon
16const uchar kCircle[] = {
170xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
180xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,
190xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,
200xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,
210xff,0xff,0x00,0x00,0x00,0x0d,0x1a,0x1f,0x1f,0x1a,0x0d,0x00,0x00,0x00,0xff,0xff,
220xff,0x00,0x00,0x00,0x0d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1e,0x0d,0x00,0x00,0x00,0xff,
230xff,0x00,0x00,0x00,0x1a,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1a,0x00,0x00,0x00,0xff,
240xff,0x00,0x00,0x00,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x00,0x00,0x00,0xff,
250xff,0x00,0x00,0x00,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x00,0x00,0x00,0xff,
260xff,0x00,0x00,0x00,0x1a,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1a,0x00,0x00,0x00,0xff,
270xff,0x00,0x00,0x00,0x0d,0x1e,0x1f,0x1f,0x1f,0x1f,0x1e,0x0d,0x00,0x00,0x00,0xff,
280xff,0xff,0x00,0x00,0x00,0x0d,0x1a,0x1f,0x1f,0x1a,0x0d,0x00,0x00,0x00,0xff,0xff,
290xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,
300xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,
310xff,0xff,0xff,0xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,0xff,0xff,0xff,
320xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
33};
34
35// square icon
36const uchar kSquare[] = {
370xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
380xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
390xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,
400xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,
410xff,0xff,0x00,0x00,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x00,0x00,0xff,0xff,
420xff,0xff,0x00,0x00,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x00,0x00,0xff,0xff,
430xff,0xff,0x00,0x00,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x00,0x00,0xff,0xff,
440xff,0xff,0x00,0x00,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x00,0x00,0xff,0xff,
450xff,0xff,0x00,0x00,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x00,0x00,0xff,0xff,
460xff,0xff,0x00,0x00,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x00,0x00,0xff,0xff,
470xff,0xff,0x00,0x00,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x00,0x00,0xff,0xff,
480xff,0xff,0x00,0x00,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x1f,0x00,0x00,0xff,0xff,
490xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,
500xff,0xff,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0xff,0xff,
510xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
520xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,0xff,
53};
54
55
56class TestMethod : public BInputServerMethod
57{
58public:
59 TestMethod();
60 virtual ~TestMethod();
61
62 virtual status_t InitCheck();
63 virtual filter_result Filter(BMessage* msg, BList* _list);
64 virtual status_t MethodActivated(bool active);
65
66 void UpdateMenu();
67private:
68 BMessenger fLooper;
69 BMenu* fDeskbarMenu;
70};
71
72
73extern "C" _EXPORT
74BInputServerMethod *instantiate_input_method()
75{
76 return new TestMethod();
77}
78
79
80enum {
81 IM_ALERT1 = 'Ima1',
82 IM_ALERT2 = 'Ima2',
83 IM_SQUARE = 'Imsq',
84 IM_CIRCLE = 'Imci',
85 IM_METHOD_ACTIVATED = 'Imac',
86 IM_METHOD_DEACTIVATED = 'Imda',
87};
88
89
90class TestLooper : public BLooper
91{
92public:
93 TestLooper(TestMethod* method);
94 virtual ~TestLooper();
95
96 virtual void MessageReceived(BMessage* msg);
97private:
98 TestMethod* fMethod;
99};
100
101TestLooper::TestLooper(TestMethod* method)
102 : BLooper("test_looper")
103 , fMethod(method)
104{
105 if (be_app) {
106 if (be_app->Lock()) {
107 be_app->AddHandler(this);
108 be_app->Unlock();
109 }
110 }
111
112 Run();
113}
114
115TestLooper::~TestLooper()
116{
117}
118
119void TestLooper::MessageReceived(BMessage* msg)
120{
121 switch(msg->what)
122 {
123 case IM_ALERT1:
124 {
125 BAlert* alert = new BAlert("title1", "Alert 1", "OK");
126 alert->Go();
127 // without updating the menu, any menuitem would not trigger any event
128 break;
129 }
130 case IM_ALERT2:
131 {
132 BAlert* alert = new BAlert("title2", "Alert 2 with set menu again", "OK");
133 alert->Go();
134 fMethod->UpdateMenu();
135 break;
136 }
137 case IM_SQUARE:
138 {
139 fMethod->SetIcon(kSquare);
140 fMethod->UpdateMenu();
141 break;
142 }
143 case IM_CIRCLE:
144 {
145 fMethod->SetIcon(kCircle);
146 fMethod->UpdateMenu();
147 break;
148 }
149 case IM_METHOD_ACTIVATED:
150 {
151 // try to set menu again when this IM is activated
152 fMethod->UpdateMenu();
153 break;
154 }
155 case IM_METHOD_DEACTIVATED:
156 {
157
158 break;
159 }
160 default:
161 break;
162 }
163}
164
165
166TestMethod::TestMethod()
167 : BInputServerMethod("im_test", kCircle)
168{
169 fDeskbarMenu = new BMenu("im_test");
170 fDeskbarMenu->AddItem(new BMenuItem("Alert 1", new BMessage(IM_ALERT1)));
171 fDeskbarMenu->AddItem(new BMenuItem("Alert 2", new BMessage(IM_ALERT2)));
172 fDeskbarMenu->AddSeparatorItem();
173 fDeskbarMenu->AddItem(new BMenuItem("Square", new BMessage(IM_SQUARE)));
174 fDeskbarMenu->AddItem(new BMenuItem("Circle", new BMessage(IM_CIRCLE)));
175}
176
177TestMethod::~TestMethod()
178{
179 SetMenu(NULL, BMessenger());
180 BLooper* looper = NULL;
181 fLooper.Target(&looper);
182 if (looper != NULL) {
183 if (looper->Lock()) {
184 looper->Quit();
185 }
186 delete looper;
187 looper = NULL;
188 }
189}
190
191void TestMethod::UpdateMenu()
192{
193 SetMenu(fDeskbarMenu, fLooper);
194}
195
196status_t TestMethod::InitCheck()
197{
198 TestLooper* looper = new TestLooper(this);
199 fLooper = BMessenger(NULL, looper);
200 UpdateMenu();
201 return B_OK;
202}
203
204filter_result TestMethod::Filter(BMessage* msg, BList* _list)
205{
206 if (msg->what == B_KEY_DOWN) {
207 fLooper.SendMessage(msg);
208 return B_SKIP_MESSAGE;
209 }
210 return B_DISPATCH_MESSAGE;
211}
212
213status_t TestMethod::MethodActivated(bool active)
214{
215 BMessage msg(active ? IM_METHOD_ACTIVATED : IM_METHOD_DEACTIVATED);
216 fLooper.SendMessage(&msg);
217 return BInputServerMethod::MethodActivated(active);
218}