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