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 40 BInputServerMethod* instantiate_input_method() 41 { 42 PRINT(("%s\n", __FUNCTION__)); 43 return (new PenInputServerMethod()); 44 } 45 46 47 PenInputServerMethod::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->TextView()->MakeSelectable(); 57 fDebugAlert->TextView()->SelectAll(); 58 fDebugAlert->TextView()->Delete(); 59 fDebugAlert->ButtonAt(0)->SetEnabled(false); 60 BRegion r; 61 GetScreenRegion(&r); 62 BString s; 63 s << r.CountRects() << " rects\n"; 64 fDebugAlert->TextView()->Insert(s.String()); 65 fDebugAlert->Go(NULL); 66 67 68 #endif 69 } 70 71 PenInputServerMethod::~PenInputServerMethod() 72 { 73 PRINT(("%s\n", __FUNCTION__)); 74 SetMenu(NULL, BMessenger()); 75 #if DEBUG 76 fDebugAlert->Lock(); 77 fDebugAlert->Quit(); 78 #endif 79 BLooper *looper = NULL; 80 fLooper.Target(&looper); 81 if (looper != NULL) 82 { 83 if (looper->Lock()) 84 looper->Quit(); 85 } 86 } 87 88 status_t PenInputServerMethod::InitCheck() 89 { 90 PenInputLooper *looper; 91 status_t err; 92 PRINT(("%s\n", __FUNCTION__)); 93 looper = new PenInputLooper(this); 94 looper->Lock(); 95 err = looper->InitCheck(); 96 looper->Unlock(); 97 fLooper = BMessenger(NULL, looper); 98 return err; 99 } 100 101 102 filter_result PenInputServerMethod::Filter(BMessage *message, BList *outList) 103 { 104 status_t err; 105 filter_result res = B_DISPATCH_MESSAGE; 106 107 if (!IsEnabled()) 108 return B_DISPATCH_MESSAGE; 109 110 111 #if 0//DEBUG 112 //message->Flatten(&fDebugFile); 113 BStringIO sio; 114 DumpMessageToStream(message, sio); 115 fDebugAlert->Lock(); 116 fDebugAlert->TextView()->Insert(sio.String()); 117 fDebugAlert->Unlock(); 118 #endif 119 switch (message->what) { 120 case B_KEY_UP: 121 case B_KEY_DOWN: 122 case B_UNMAPPED_KEY_UP: 123 case B_UNMAPPED_KEY_DOWN: 124 case B_MODIFIERS_CHANGED: 125 case B_MOUSE_WHEEL_CHANGED: 126 return B_DISPATCH_MESSAGE; 127 default: 128 //case B_MOUSE_MOVED: 129 fLooper.SendMessage(message); 130 return B_SKIP_MESSAGE; 131 } 132 133 134 #if 0 135 if (message->what == B_MOUSE_MOVED) { 136 BMessage *mDown = new BMessage(B_KEY_DOWN); 137 BMessage *mUp; 138 char states[16]; 139 mDown->AddInt32("modifiers", 0x0); 140 mDown->AddInt32("key", 94); 141 mDown->AddInt32("raw_char", 32); 142 mDown->AddData("states", 'UBYT', states, sizeof(states)); 143 mDown->AddString("bytes", " "); 144 mDown->AddData("byte", 'BYTE', " ", 1); 145 mUp = new BMessage(*mDown); 146 mUp->what = B_KEY_UP; 147 outList->AddItem(mDown); 148 outList->AddItem(mUp); 149 } 150 #endif 151 if (message->what == B_MOUSE_DOWN) { 152 int32 buttons; 153 int32 modifiers; 154 BPoint where; 155 if (message->FindInt32("buttons", &buttons) == B_OK) { 156 /* replace first with a button that likely won't exist, 157 * and so shouldn't cause any side effect (hmm err...) */ 158 /* XXX: use get_mouse_map() ? */ 159 if (buttons == B_PRIMARY_MOUSE_BUTTON) 160 //message->ReplaceInt32("buttons", 0x0000); 161 message->what = B_MOUSE_UP; 162 } 163 164 #if 0 165 outList->AddItem(new BMessage(*message)); 166 BMessage *m = new BMessage(B_MOUSE_MOVED); 167 if (message->FindInt32("buttons", &buttons) == B_OK) 168 m->AddInt32("buttons", buttons); 169 if (message->FindInt32("modifiers", &modifiers) == B_OK) 170 m->AddInt32("modifiers", modifiers); 171 if (message->FindPoint("where", &where) == B_OK) 172 m->AddPoint("where", where); 173 outList->AddItem(m); 174 #endif 175 #if DEBUG 176 fDebugAlert->Lock(); 177 fDebugAlert->TextView()->Insert(">>>\n"); 178 fDebugAlert->Unlock(); 179 #endif 180 #if 0 181 m = new BMessage(B_INPUT_METHOD_EVENT); 182 m->AddInt32("be:opcode", B_INPUT_METHOD_STARTED); 183 m->AddMessenger("be:reply_to", this); 184 EnqueueMessage(m); 185 m = new BMessage(B_INPUT_METHOD_EVENT); 186 m->AddInt32("be:opcode", B_INPUT_METHOD_LOCATION_REQUEST); 187 m->AddString("be:string", " "); 188 EnqueueMessage(m); 189 m = new BMessage(B_INPUT_METHOD_EVENT); 190 m->AddInt32("be:opcode", B_INPUT_METHOD_STOPPED); 191 EnqueueMessage(m); 192 sleep(3); 193 #endif 194 #if DEBUG 195 fDebugAlert->Lock(); 196 fDebugAlert->TextView()->Insert("<<<\n"); 197 fDebugAlert->Unlock(); 198 #endif 199 } 200 201 202 203 return (res); 204 } 205 206 status_t PenInputServerMethod::MethodActivated(bool active) 207 { 208 fEnabled = active; 209 210 BMessage msg(MSG_METHOD_ACTIVATED); 211 if (active) 212 msg.AddBool(MSGF_ACTIVE, true); 213 fLooper.SendMessage( &msg ); 214 215 return B_OK; 216 } 217 218