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