1/* 2 Copyright 2007, Francois Revol. All Rights Reserved. 3 This file may be used under the terms of the Be Sample Code License. 4*/ 5 6//#define DEBUG 1 7 8#include <stdlib.h> 9#include <string.h> 10#include <ctype.h> 11 12#include <Debug.h> 13#include <List.h> 14#include <Message.h> 15#include <OS.h> 16 17#include <Application.h> 18#include <Menu.h> 19#include <MenuItem.h> 20#include <Region.h> 21 22#if DEBUG 23//#include <File.h> 24#include <Alert.h> 25#include <Button.h> 26#include <TextView.h> 27#include <StringIO.h> 28#include "DumpMessage.h" 29#endif 30 31#include <add-ons/input_server/InputServerDevice.h> 32#include <add-ons/input_server/InputServerMethod.h> 33 34#include "PenIcon.h" 35 36#include "PenInputServerMethod.h" 37#include "PenInputLooper.h" 38#include "PenInputStrings.h" 39 40BInputServerMethod* instantiate_input_method() 41{ 42 PRINT(("%s\n", __FUNCTION__)); 43 return (new PenInputServerMethod()); 44} 45 46 47PenInputServerMethod::PenInputServerMethod() 48 : BInputServerMethod("Pen", PenIconData), 49 fEnabled(false) 50{ 51 PRINT(("%s\n", __FUNCTION__)); 52#if DEBUG 53 //fDebugFile.SetTo("/tmp/PenInputMethodMessages.txt", B_READ_WRITE|B_CREATE_FILE); 54 fDebugAlert = new BAlert("PenInput Debug", "Plip \n\n\n\n\n\n\n\n\n\n\n\n\n", "OK"); 55 fDebugAlert->SetLook(B_TITLED_WINDOW_LOOK); 56 fDebugAlert->SetFlags(fDebugAlert->Flags() | B_CLOSE_ON_ESCAPE); 57 fDebugAlert->TextView()->MakeSelectable(); 58 fDebugAlert->TextView()->SelectAll(); 59 fDebugAlert->TextView()->Delete(); 60 fDebugAlert->ButtonAt(0)->SetEnabled(false); 61 BRegion r; 62 GetScreenRegion(&r); 63 BString s; 64 s << r.CountRects() << " rects\n"; 65 fDebugAlert->TextView()->Insert(s.String()); 66 fDebugAlert->Go(NULL); 67 68 69#endif 70} 71 72PenInputServerMethod::~PenInputServerMethod() 73{ 74 PRINT(("%s\n", __FUNCTION__)); 75 SetMenu(NULL, BMessenger()); 76#if DEBUG 77 fDebugAlert->Lock(); 78 fDebugAlert->Quit(); 79#endif 80 BLooper *looper = NULL; 81 fLooper.Target(&looper); 82 if (looper != NULL) 83 { 84 if (looper->Lock()) 85 looper->Quit(); 86 } 87} 88 89status_t PenInputServerMethod::InitCheck() 90{ 91 PenInputLooper *looper; 92 status_t err; 93 PRINT(("%s\n", __FUNCTION__)); 94 looper = new PenInputLooper(this); 95 looper->Lock(); 96 err = looper->InitCheck(); 97 looper->Unlock(); 98 fLooper = BMessenger(NULL, looper); 99 return err; 100} 101 102 103filter_result PenInputServerMethod::Filter(BMessage *message, BList *outList) 104{ 105 status_t err; 106 filter_result res = B_DISPATCH_MESSAGE; 107 108 if (!IsEnabled()) 109 return B_DISPATCH_MESSAGE; 110 111 112#if 0//DEBUG 113 //message->Flatten(&fDebugFile); 114 BStringIO sio; 115 DumpMessageToStream(message, sio); 116 fDebugAlert->Lock(); 117 fDebugAlert->TextView()->Insert(sio.String()); 118 fDebugAlert->Unlock(); 119#endif 120 switch (message->what) { 121 case B_KEY_UP: 122 case B_KEY_DOWN: 123 case B_UNMAPPED_KEY_UP: 124 case B_UNMAPPED_KEY_DOWN: 125 case B_MODIFIERS_CHANGED: 126 case B_MOUSE_WHEEL_CHANGED: 127 return B_DISPATCH_MESSAGE; 128 default: 129 //case B_MOUSE_MOVED: 130 fLooper.SendMessage(message); 131 return B_SKIP_MESSAGE; 132 } 133 134 135#if 0 136 if (message->what == B_MOUSE_MOVED) { 137 BMessage *mDown = new BMessage(B_KEY_DOWN); 138 BMessage *mUp; 139 char states[16]; 140 mDown->AddInt32("modifiers", 0x0); 141 mDown->AddInt32("key", 94); 142 mDown->AddInt32("raw_char", 32); 143 mDown->AddData("states", 'UBYT', states, sizeof(states)); 144 mDown->AddString("bytes", " "); 145 mDown->AddData("byte", 'BYTE', " ", 1); 146 mUp = new BMessage(*mDown); 147 mUp->what = B_KEY_UP; 148 outList->AddItem(mDown); 149 outList->AddItem(mUp); 150 } 151#endif 152 if (message->what == B_MOUSE_DOWN) { 153 int32 buttons; 154 int32 modifiers; 155 BPoint where; 156 if (message->FindInt32("buttons", &buttons) == B_OK) { 157 /* replace first with a button that likely won't exist, 158 * and so shouldn't cause any side effect (hmm err...) */ 159 /* XXX: use get_mouse_map() ? */ 160 if (buttons == B_PRIMARY_MOUSE_BUTTON) 161 //message->ReplaceInt32("buttons", 0x0000); 162 message->what = B_MOUSE_UP; 163 } 164 165#if 0 166 outList->AddItem(new BMessage(*message)); 167 BMessage *m = new BMessage(B_MOUSE_MOVED); 168 if (message->FindInt32("buttons", &buttons) == B_OK) 169 m->AddInt32("buttons", buttons); 170 if (message->FindInt32("modifiers", &modifiers) == B_OK) 171 m->AddInt32("modifiers", modifiers); 172 if (message->FindPoint("where", &where) == B_OK) 173 m->AddPoint("where", where); 174 outList->AddItem(m); 175#endif 176#if DEBUG 177 fDebugAlert->Lock(); 178 fDebugAlert->TextView()->Insert(">>>\n"); 179 fDebugAlert->Unlock(); 180#endif 181#if 0 182 m = new BMessage(B_INPUT_METHOD_EVENT); 183 m->AddInt32("be:opcode", B_INPUT_METHOD_STARTED); 184 m->AddMessenger("be:reply_to", this); 185 EnqueueMessage(m); 186 m = new BMessage(B_INPUT_METHOD_EVENT); 187 m->AddInt32("be:opcode", B_INPUT_METHOD_LOCATION_REQUEST); 188 m->AddString("be:string", " "); 189 EnqueueMessage(m); 190 m = new BMessage(B_INPUT_METHOD_EVENT); 191 m->AddInt32("be:opcode", B_INPUT_METHOD_STOPPED); 192 EnqueueMessage(m); 193 sleep(3); 194#endif 195#if DEBUG 196 fDebugAlert->Lock(); 197 fDebugAlert->TextView()->Insert("<<<\n"); 198 fDebugAlert->Unlock(); 199#endif 200 } 201 202 203 204 return (res); 205} 206 207status_t PenInputServerMethod::MethodActivated(bool active) 208{ 209 fEnabled = active; 210 211 BMessage msg(MSG_METHOD_ACTIVATED); 212 if (active) 213 msg.AddBool(MSGF_ACTIVE, true); 214 fLooper.SendMessage( &msg ); 215 216 return B_OK; 217} 218 219