1087bd9e8SFrançois Revol /*
2087bd9e8SFrançois Revol Copyright 2005, Francois Revol. All Rights Reserved.
3087bd9e8SFrançois Revol This file may be used under the terms of the Be Sample Code License.
4087bd9e8SFrançois Revol */
5087bd9e8SFrançois Revol
6087bd9e8SFrançois Revol #include <stdlib.h>
7087bd9e8SFrançois Revol #include <string.h>
8087bd9e8SFrançois Revol #include <ctype.h>
9087bd9e8SFrançois Revol
10087bd9e8SFrançois Revol #include <Debug.h>
11087bd9e8SFrançois Revol #include <List.h>
12087bd9e8SFrançois Revol #include <Message.h>
13087bd9e8SFrançois Revol #include <OS.h>
14087bd9e8SFrançois Revol
15087bd9e8SFrançois Revol #include <Alert.h>
16fe0bb0ecSFrançois Revol #include <Application.h>
17fe0bb0ecSFrançois Revol #include <Autolock.h>
18087bd9e8SFrançois Revol #include <Handler.h>
19087bd9e8SFrançois Revol #include <Locker.h>
20fe0bb0ecSFrançois Revol #include <Menu.h>
21fe0bb0ecSFrançois Revol #include <MenuItem.h>
22fe0bb0ecSFrançois Revol #include <String.h>
23087bd9e8SFrançois Revol
24087bd9e8SFrançois Revol
25087bd9e8SFrançois Revol #include <add-ons/input_server/InputServerMethod.h>
26087bd9e8SFrançois Revol
27087bd9e8SFrançois Revol #ifndef _T
28087bd9e8SFrançois Revol #define _T(s) s
29087bd9e8SFrançois Revol #endif
30087bd9e8SFrançois Revol
31087bd9e8SFrançois Revol #include "T9Icon.h"
32087bd9e8SFrançois Revol
33087bd9e8SFrançois Revol extern "C" _EXPORT BInputServerMethod* instantiate_input_method();
34087bd9e8SFrançois Revol
35087bd9e8SFrançois Revol enum T9Mode {
36087bd9e8SFrançois Revol WordMode,
37087bd9e8SFrançois Revol CharMode,
38087bd9e8SFrançois Revol NumMode
39087bd9e8SFrançois Revol };
40087bd9e8SFrançois Revol
41087bd9e8SFrançois Revol
42087bd9e8SFrançois Revol // modes: =Abc / Abc / 123
43087bd9e8SFrançois Revol // flags: Abc / ABC / abc
44087bd9e8SFrançois Revol
45087bd9e8SFrançois Revol class T9InputServerMethod : public BInputServerMethod, public BHandler
46087bd9e8SFrançois Revol {
47087bd9e8SFrançois Revol public:
48087bd9e8SFrançois Revol T9InputServerMethod();
49087bd9e8SFrançois Revol virtual ~T9InputServerMethod();
50087bd9e8SFrançois Revol virtual filter_result Filter(BMessage *message, BList *outList);
51087bd9e8SFrançois Revol virtual status_t MethodActivated(bool active);
52087bd9e8SFrançois Revol virtual void MessageReceived(BMessage *message);
53087bd9e8SFrançois Revol
IsEnabled() const54087bd9e8SFrançois Revol bool IsEnabled() const { return fEnabled; };
Mode() const55087bd9e8SFrançois Revol T9Mode Mode() const { return fMode; };
56087bd9e8SFrançois Revol void SetMode(T9Mode mode);
57087bd9e8SFrançois Revol private:
58087bd9e8SFrançois Revol bool fEnabled;
59087bd9e8SFrançois Revol T9Mode fMode;
60087bd9e8SFrançois Revol BMenu *fDeskbarMenu;
61087bd9e8SFrançois Revol BLocker fLocker;
62087bd9e8SFrançois Revol BString fTyped; /* what has been typed so far for the current word */
63087bd9e8SFrançois Revol };
64087bd9e8SFrançois Revol
65087bd9e8SFrançois Revol
66087bd9e8SFrançois Revol
67087bd9e8SFrançois Revol
instantiate_input_method()68087bd9e8SFrançois Revol BInputServerMethod* instantiate_input_method()
69087bd9e8SFrançois Revol {
70087bd9e8SFrançois Revol PRINT(("%s\n", __FUNCTION__));
71087bd9e8SFrançois Revol return (new T9InputServerMethod());
72087bd9e8SFrançois Revol }
73087bd9e8SFrançois Revol
74087bd9e8SFrançois Revol
T9InputServerMethod()75087bd9e8SFrançois Revol T9InputServerMethod::T9InputServerMethod()
76087bd9e8SFrançois Revol : BInputServerMethod("T9", T9IconData),
77087bd9e8SFrançois Revol BHandler("T9IMHandler"),
78087bd9e8SFrançois Revol fEnabled(false),
79087bd9e8SFrançois Revol fMode(WordMode),
80087bd9e8SFrançois Revol fDeskbarMenu(NULL),
81087bd9e8SFrançois Revol fLocker("T9IM")
82087bd9e8SFrançois Revol {
83087bd9e8SFrançois Revol PRINT(("%s\n", __FUNCTION__));
84087bd9e8SFrançois Revol
85087bd9e8SFrançois Revol if (be_app) {
86087bd9e8SFrançois Revol be_app->Lock();
87087bd9e8SFrançois Revol be_app->AddHandler(this);
88087bd9e8SFrançois Revol be_app->Unlock();
89087bd9e8SFrançois Revol }
90087bd9e8SFrançois Revol
91087bd9e8SFrançois Revol //
92087bd9e8SFrançois Revol fDeskbarMenu = new BMenu(_T("Mode"));
93087bd9e8SFrançois Revol
94087bd9e8SFrançois Revol
95087bd9e8SFrançois Revol BMessage *msg = new BMessage('SetM');
96087bd9e8SFrançois Revol msg->AddInt32("t9mode", WordMode);
97087bd9e8SFrançois Revol BMenuItem *item;
98fcc3e627SStephan Aßmus item = new BMenuItem(_T("Word mode"), msg);
99087bd9e8SFrançois Revol item->SetMarked(true);
100087bd9e8SFrançois Revol fDeskbarMenu->AddItem(item);
101087bd9e8SFrançois Revol msg = new BMessage('SetM');
102087bd9e8SFrançois Revol msg->AddInt32("t9mode", CharMode);
103fcc3e627SStephan Aßmus item = new BMenuItem(_T("Character mode"), msg);
104087bd9e8SFrançois Revol fDeskbarMenu->AddItem(item);
105087bd9e8SFrançois Revol msg = new BMessage('SetM');
106087bd9e8SFrançois Revol msg->AddInt32("t9mode", NumMode);
107fcc3e627SStephan Aßmus item = new BMenuItem(_T("Numeric mode"), msg);
108087bd9e8SFrançois Revol fDeskbarMenu->AddItem(item);
109087bd9e8SFrançois Revol fDeskbarMenu->SetFont(be_plain_font);
110087bd9e8SFrançois Revol // doesn't seem to work here
111087bd9e8SFrançois Revol //fDeskbarMenu->SetRadioMode(true);
112087bd9e8SFrançois Revol //fDeskbarMenu->SetLabelFromMarked(true);
113087bd9e8SFrançois Revol
114087bd9e8SFrançois Revol SetMenu(fDeskbarMenu, BMessenger(this));
115087bd9e8SFrançois Revol }
116087bd9e8SFrançois Revol
~T9InputServerMethod()117087bd9e8SFrançois Revol T9InputServerMethod::~T9InputServerMethod()
118087bd9e8SFrançois Revol {
119087bd9e8SFrançois Revol PRINT(("%s\n", __FUNCTION__));
120087bd9e8SFrançois Revol SetMenu(NULL, BMessenger());
121087bd9e8SFrançois Revol delete fDeskbarMenu;
122087bd9e8SFrançois Revol if (be_app) {
123087bd9e8SFrançois Revol be_app->Lock();
124087bd9e8SFrançois Revol be_app->RemoveHandler(this);
125087bd9e8SFrançois Revol be_app->Unlock();
126087bd9e8SFrançois Revol }
127087bd9e8SFrançois Revol }
128087bd9e8SFrançois Revol
Filter(BMessage * message,BList * outList)129087bd9e8SFrançois Revol filter_result T9InputServerMethod::Filter(BMessage *message, BList *outList)
130087bd9e8SFrançois Revol {
1310895a406SFrançois Revol //status_t err;
132087bd9e8SFrançois Revol filter_result res = B_DISPATCH_MESSAGE;
133087bd9e8SFrançois Revol bool keyUp = false;
134087bd9e8SFrançois Revol BString bytes;
135087bd9e8SFrançois Revol
136087bd9e8SFrançois Revol if (!IsEnabled())
137087bd9e8SFrançois Revol return B_DISPATCH_MESSAGE;
138087bd9e8SFrançois Revol
139087bd9e8SFrançois Revol switch (message->what) {
140087bd9e8SFrançois Revol case B_KEY_UP:
141087bd9e8SFrançois Revol keyUp = true;
142087bd9e8SFrançois Revol case B_KEY_DOWN:
143087bd9e8SFrançois Revol if (message->FindString("bytes", &bytes) < B_OK)
144087bd9e8SFrançois Revol break;
145087bd9e8SFrançois Revol if (bytes.Length() == 1) {
146087bd9e8SFrançois Revol BAutolock l(fLocker);
147087bd9e8SFrançois Revol
148087bd9e8SFrançois Revol if (fMode == NumMode)
149087bd9e8SFrançois Revol break;
150087bd9e8SFrançois Revol }
151087bd9e8SFrançois Revol break;
152087bd9e8SFrançois Revol default:
153087bd9e8SFrançois Revol break;
154087bd9e8SFrançois Revol }
155087bd9e8SFrançois Revol
156087bd9e8SFrançois Revol return (res);
157087bd9e8SFrançois Revol }
158087bd9e8SFrançois Revol
MethodActivated(bool active)159087bd9e8SFrançois Revol status_t T9InputServerMethod::MethodActivated(bool active)
160087bd9e8SFrançois Revol {
161087bd9e8SFrançois Revol fEnabled = active;
162087bd9e8SFrançois Revol return BInputServerMethod::MethodActivated(active);
163087bd9e8SFrançois Revol }
164087bd9e8SFrançois Revol
MessageReceived(BMessage * message)165087bd9e8SFrançois Revol void T9InputServerMethod::MessageReceived(BMessage *message)
166087bd9e8SFrançois Revol {
167087bd9e8SFrançois Revol int32 v;
168087bd9e8SFrançois Revol switch (message->what) {
169087bd9e8SFrançois Revol case 'SetM':
170087bd9e8SFrançois Revol if (message->FindInt32("t9mode", &v) < B_OK)
171087bd9e8SFrançois Revol break;
172087bd9e8SFrançois Revol SetMode((T9Mode)v);
173087bd9e8SFrançois Revol
174087bd9e8SFrançois Revol /*{
175087bd9e8SFrançois Revol BString s;
176087bd9e8SFrançois Revol s << v;
177087bd9e8SFrançois Revol s << " - ";
178087bd9e8SFrançois Revol s << (long) fDeskbarMenu->FindMarked();
179087bd9e8SFrançois Revol s << " - ";
180087bd9e8SFrançois Revol s << (long) fDeskbarMenu->ItemAt(v);
181fcc3e627SStephan Aßmus BAlert *a = new BAlert("Plop", s.String(), "OK");
182*aed35104SHumdinger a->SetFlags(a->Flags() | B_CLOSE_ON_ESCAPE);
183087bd9e8SFrançois Revol a->Go(NULL);
184087bd9e8SFrançois Revol }*/
185087bd9e8SFrançois Revol break;
186087bd9e8SFrançois Revol default:
187087bd9e8SFrançois Revol BHandler::MessageReceived(message);
188087bd9e8SFrançois Revol break;
189087bd9e8SFrançois Revol }
190087bd9e8SFrançois Revol }
191087bd9e8SFrançois Revol
SetMode(T9Mode mode)192087bd9e8SFrançois Revol void T9InputServerMethod::SetMode(T9Mode mode)
193087bd9e8SFrançois Revol {
194087bd9e8SFrançois Revol BAutolock l(fLocker);
195087bd9e8SFrançois Revol BMenuItem *item;
196087bd9e8SFrançois Revol // XXX: check
197087bd9e8SFrançois Revol fMode = mode;
198087bd9e8SFrançois Revol item = fDeskbarMenu->FindMarked();
199087bd9e8SFrançois Revol if (item)
200087bd9e8SFrançois Revol item->SetMarked(false);
201087bd9e8SFrançois Revol item = fDeskbarMenu->ItemAt((int32)mode);
202087bd9e8SFrançois Revol if (item)
203087bd9e8SFrançois Revol item->SetMarked(true);
204087bd9e8SFrançois Revol // necessary to update the copy used by the Deskbar icon.
205087bd9e8SFrançois Revol SetMenu(fDeskbarMenu, BMessenger(this));
206087bd9e8SFrançois Revol }
207