1 /* 2 Copyright 2005, Francois Revol. All Rights Reserved. 3 This file may be used under the terms of the Be Sample Code License. 4 */ 5 6 #include <stdlib.h> 7 #include <string.h> 8 #include <ctype.h> 9 10 #include <Debug.h> 11 #include <List.h> 12 #include <Message.h> 13 #include <OS.h> 14 15 #include <Alert.h> 16 #include <Application.h> 17 #include <Autolock.h> 18 #include <Handler.h> 19 #include <Locker.h> 20 #include <Menu.h> 21 #include <MenuItem.h> 22 #include <String.h> 23 24 25 #include <add-ons/input_server/InputServerMethod.h> 26 27 #ifndef _T 28 #define _T(s) s 29 #endif 30 31 #include "T9Icon.h" 32 33 extern "C" _EXPORT BInputServerMethod* instantiate_input_method(); 34 35 enum T9Mode { 36 WordMode, 37 CharMode, 38 NumMode 39 }; 40 41 42 // modes: =Abc / Abc / 123 43 // flags: Abc / ABC / abc 44 45 class T9InputServerMethod : public BInputServerMethod, public BHandler 46 { 47 public: 48 T9InputServerMethod(); 49 virtual ~T9InputServerMethod(); 50 virtual filter_result Filter(BMessage *message, BList *outList); 51 virtual status_t MethodActivated(bool active); 52 virtual void MessageReceived(BMessage *message); 53 54 bool IsEnabled() const { return fEnabled; }; 55 T9Mode Mode() const { return fMode; }; 56 void SetMode(T9Mode mode); 57 private: 58 bool fEnabled; 59 T9Mode fMode; 60 BMenu *fDeskbarMenu; 61 BLocker fLocker; 62 BString fTyped; /* what has been typed so far for the current word */ 63 }; 64 65 66 67 68 BInputServerMethod* instantiate_input_method() 69 { 70 PRINT(("%s\n", __FUNCTION__)); 71 return (new T9InputServerMethod()); 72 } 73 74 75 T9InputServerMethod::T9InputServerMethod() 76 : BInputServerMethod("T9", T9IconData), 77 BHandler("T9IMHandler"), 78 fEnabled(false), 79 fMode(WordMode), 80 fDeskbarMenu(NULL), 81 fLocker("T9IM") 82 { 83 PRINT(("%s\n", __FUNCTION__)); 84 85 if (be_app) { 86 be_app->Lock(); 87 be_app->AddHandler(this); 88 be_app->Unlock(); 89 } 90 91 // 92 fDeskbarMenu = new BMenu(_T("Mode")); 93 94 95 BMessage *msg = new BMessage('SetM'); 96 msg->AddInt32("t9mode", WordMode); 97 BMenuItem *item; 98 item = new BMenuItem(_T("Word mode"), msg); 99 item->SetMarked(true); 100 fDeskbarMenu->AddItem(item); 101 msg = new BMessage('SetM'); 102 msg->AddInt32("t9mode", CharMode); 103 item = new BMenuItem(_T("Character mode"), msg); 104 fDeskbarMenu->AddItem(item); 105 msg = new BMessage('SetM'); 106 msg->AddInt32("t9mode", NumMode); 107 item = new BMenuItem(_T("Numeric mode"), msg); 108 fDeskbarMenu->AddItem(item); 109 fDeskbarMenu->SetFont(be_plain_font); 110 // doesn't seem to work here 111 //fDeskbarMenu->SetRadioMode(true); 112 //fDeskbarMenu->SetLabelFromMarked(true); 113 114 SetMenu(fDeskbarMenu, BMessenger(this)); 115 } 116 117 T9InputServerMethod::~T9InputServerMethod() 118 { 119 PRINT(("%s\n", __FUNCTION__)); 120 SetMenu(NULL, BMessenger()); 121 delete fDeskbarMenu; 122 if (be_app) { 123 be_app->Lock(); 124 be_app->RemoveHandler(this); 125 be_app->Unlock(); 126 } 127 } 128 129 filter_result T9InputServerMethod::Filter(BMessage *message, BList *outList) 130 { 131 //status_t err; 132 filter_result res = B_DISPATCH_MESSAGE; 133 bool keyUp = false; 134 BString bytes; 135 136 if (!IsEnabled()) 137 return B_DISPATCH_MESSAGE; 138 139 switch (message->what) { 140 case B_KEY_UP: 141 keyUp = true; 142 case B_KEY_DOWN: 143 if (message->FindString("bytes", &bytes) < B_OK) 144 break; 145 if (bytes.Length() == 1) { 146 BAutolock l(fLocker); 147 148 if (fMode == NumMode) 149 break; 150 } 151 break; 152 default: 153 break; 154 } 155 156 return (res); 157 } 158 159 status_t T9InputServerMethod::MethodActivated(bool active) 160 { 161 fEnabled = active; 162 return BInputServerMethod::MethodActivated(active); 163 } 164 165 void T9InputServerMethod::MessageReceived(BMessage *message) 166 { 167 int32 v; 168 switch (message->what) { 169 case 'SetM': 170 if (message->FindInt32("t9mode", &v) < B_OK) 171 break; 172 SetMode((T9Mode)v); 173 174 /*{ 175 BString s; 176 s << v; 177 s << " - "; 178 s << (long) fDeskbarMenu->FindMarked(); 179 s << " - "; 180 s << (long) fDeskbarMenu->ItemAt(v); 181 BAlert *a = new BAlert("Plop", s.String(), "OK"); 182 a->SetFlags(a->Flags() | B_CLOSE_ON_ESCAPE); 183 a->Go(NULL); 184 }*/ 185 break; 186 default: 187 BHandler::MessageReceived(message); 188 break; 189 } 190 } 191 192 void T9InputServerMethod::SetMode(T9Mode mode) 193 { 194 BAutolock l(fLocker); 195 BMenuItem *item; 196 // XXX: check 197 fMode = mode; 198 item = fDeskbarMenu->FindMarked(); 199 if (item) 200 item->SetMarked(false); 201 item = fDeskbarMenu->ItemAt((int32)mode); 202 if (item) 203 item->SetMarked(true); 204 // necessary to update the copy used by the Deskbar icon. 205 SetMenu(fDeskbarMenu, BMessenger(this)); 206 } 207