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 32extern "C" _EXPORT BInputServerMethod* instantiate_input_method(); 33 34enum T9Mode { 35 WordMode, 36 CharMode, 37 NumMode 38}; 39 40 41// modes: =Abc / Abc / 123 42// flags: Abc / ABC / abc 43 44class T9InputServerMethod : public BInputServerMethod, public BHandler 45{ 46public: 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); 56private: 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 67BInputServerMethod* instantiate_input_method() 68{ 69 PRINT(("%s\n", __FUNCTION__)); 70 return (new T9InputServerMethod()); 71} 72 73 74T9InputServerMethod::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 116T9InputServerMethod::~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 128filter_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 158status_t T9InputServerMethod::MethodActivated(bool active) 159{ 160 fEnabled = active; 161 return BInputServerMethod::MethodActivated(active); 162} 163 164void 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->SetFlags(a->Flags() | B_CLOSE_ON_ESCAPE); 182 a->Go(NULL); 183 }*/ 184 break; 185 default: 186 BHandler::MessageReceived(message); 187 break; 188 } 189} 190 191void T9InputServerMethod::SetMode(T9Mode mode) 192{ 193 BAutolock l(fLocker); 194 BMenuItem *item; 195 // XXX: check 196 fMode = mode; 197 item = fDeskbarMenu->FindMarked(); 198 if (item) 199 item->SetMarked(false); 200 item = fDeskbarMenu->ItemAt((int32)mode); 201 if (item) 202 item->SetMarked(true); 203 // necessary to update the copy used by the Deskbar icon. 204 SetMenu(fDeskbarMenu, BMessenger(this)); 205} 206