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 33extern "C" _EXPORT BInputServerMethod* instantiate_input_method(); 34 35enum T9Mode { 36 WordMode, 37 CharMode, 38 NumMode 39}; 40 41 42// modes: =Abc / Abc / 123 43// flags: Abc / ABC / abc 44 45class T9InputServerMethod : public BInputServerMethod, public BHandler 46{ 47public: 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); 57private: 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 68BInputServerMethod* instantiate_input_method() 69{ 70 PRINT(("%s\n", __FUNCTION__)); 71 return (new T9InputServerMethod()); 72} 73 74 75T9InputServerMethod::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 117T9InputServerMethod::~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 129filter_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 159status_t T9InputServerMethod::MethodActivated(bool active) 160{ 161 fEnabled = active; 162 return BInputServerMethod::MethodActivated(active); 163} 164 165void 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 192void 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