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 <MessageRunner.h> 21 #include <Region.h> 22 #include <Screen.h> 23 24 #if DEBUG 25 //#include <File.h> 26 #include <Alert.h> 27 #include <Button.h> 28 #include <TextView.h> 29 #include <StringIO.h> 30 #include "DumpMessage.h" 31 #endif 32 33 #include "PenInputLooper.h" 34 #include "PenInputBackend.h" 35 #include "PenInputInkWindow.h" 36 #include "PenInputServerMethod.h" 37 #include "PenInputStrings.h" 38 39 PenInputLooper::PenInputLooper(PenInputServerMethod *method) 40 : BLooper("PenInputLooper", B_NORMAL_PRIORITY), 41 fOwner(method), 42 fInkWindow(NULL), 43 fBackend(NULL), 44 fDeskbarMenu(NULL), 45 fMouseDown(false), 46 fStroking(false), 47 fThresholdRunner(NULL), 48 fCachedMouseDown(NULL), 49 fShowInk(true), 50 fMouseDownThreshold(100000) 51 { 52 PRINT(("%s\n", __FUNCTION__)); 53 54 // 55 fDeskbarMenu = new BMenu(_T("Options")); 56 BMenu *subMenu; 57 58 59 subMenu = new BMenu(_T("Backend")); 60 61 BMessage *msg; 62 msg = new BMessage(MSG_SET_BACKEND); 63 BMenuItem *item; 64 // for (i = 0; i < fBackends.CountItems(); i++) ... 65 item = new BMenuItem(_T("Default"), msg); 66 item->SetMarked(true); 67 subMenu->AddItem(item); 68 69 item = new BMenuItem(subMenu); 70 fDeskbarMenu->AddItem(item); 71 72 msg = new BMessage(MSG_SHOW_INK); 73 item = new BMenuItem(_T("Show Ink"), msg); 74 item->SetMarked(true); 75 fDeskbarMenu->AddItem(item); 76 77 fDeskbarMenu->SetFont(be_plain_font); 78 fOwner->SetMenu(fDeskbarMenu, BMessenger(NULL, this)); 79 80 #if 0 81 BRegion region; 82 fOwner->GetScreenRegion(®ion); 83 fInkWindow = new PenInputInkWindow(region.Frame()); 84 #endif 85 BScreen screen; 86 fInkWindow = new PenInputInkWindow(screen.Frame()); 87 fInkWindow->Show(); 88 fInkWindow->Lock(); 89 fInkWindow->Hide(); 90 fInkWindow->Unlock(); 91 fInkWindowMsgr = BMessenger(NULL, fInkWindow); 92 93 BMessage m(MSG_CHECK_PEN_DOWN); 94 fThresholdRunner = new BMessageRunner(BMessenger(NULL, this), &m, fMouseDownThreshold, 0); 95 96 Run(); 97 } 98 99 void PenInputLooper::Quit() 100 { 101 PRINT(("%s\n", __FUNCTION__)); 102 delete fThresholdRunner; 103 fInkWindow->Lock(); 104 fInkWindow->Quit(); 105 fOwner->SetMenu(NULL, BMessenger()); 106 delete fDeskbarMenu; 107 BLooper::Quit(); 108 } 109 110 111 void PenInputLooper::DispatchMessage(BMessage *message, BHandler *handler) 112 { 113 switch (message->what) { 114 #if 0 115 case B_MOUSE_MOVED: 116 case B_MOUSE_DOWN: 117 case B_MOUSE_UP: 118 119 case B_INPUT_METHOD_EVENT: 120 //case B_REPLY: 121 if (fBackend) { 122 fBackend->MessageReceived(message); 123 return; 124 } 125 #endif 126 default: 127 return BLooper::DispatchMessage(message, handler); 128 } 129 } 130 131 void PenInputLooper::MessageReceived(BMessage *message) 132 { 133 int32 v; 134 int32 buttons; 135 bool b; 136 #if 1 137 { 138 //message->Flatten(&fDebugFile); 139 BStringIO sio; 140 DumpMessageToStream(message, sio); 141 fInkWindow->Lock(); 142 sio << BString("StrokesCount: "); 143 BString tmp; 144 tmp << fInkWindow->fStrokeCount; 145 sio << tmp; 146 sio << BString("\nStrokes.Bounds: "); 147 sio << (fInkWindow->fStrokes.Bounds()); 148 sio << BString("\n"); 149 fInkWindow->Unlock(); 150 fOwner->fDebugAlert->Lock(); 151 fOwner->fDebugAlert->TextView()->Insert("Looper:\n"); 152 fOwner->fDebugAlert->TextView()->Insert(sio.String()); 153 fOwner->fDebugAlert->Unlock(); 154 } 155 #endif 156 switch (message->what) { 157 case MSG_CHECK_PEN_DOWN: 158 if (fCachedMouseDown) { 159 /* nothing happened, we want to move the mouse */ 160 EnqueueMessage(fCachedMouseDown); 161 fCachedMouseDown = NULL; 162 } 163 break; 164 case B_MOUSE_MOVED: 165 if (!fMouseDown) { /* definitely not writing */ 166 /* pass it along */ 167 EnqueueMessage(DetachCurrentMessage()); 168 break; 169 } 170 if (fShowInk) { 171 BMessage *msg = new BMessage(*message); 172 fInkWindowMsgr.SendMessage(msg); 173 } 174 if (fBackend) 175 fBackend->MessageReceived(message); 176 else 177 EnqueueMessage(DetachCurrentMessage()); 178 break; 179 case B_MOUSE_DOWN: 180 if (message->FindInt32("buttons", &buttons) == B_OK) { 181 if (!(buttons & B_PRIMARY_MOUSE_BUTTON)) { 182 /* pass it along */ 183 EnqueueMessage(DetachCurrentMessage()); 184 break; 185 } 186 } 187 fMouseDown = true; 188 if (fShowInk) { 189 { 190 BMessage *msg = new BMessage(MSG_BEGIN_INK); 191 fInkWindowMsgr.SendMessage(msg); 192 } 193 BMessage *msg = new BMessage(*message); 194 fInkWindowMsgr.SendMessage(msg); 195 } 196 if (fBackend) 197 fBackend->MessageReceived(message); 198 break; 199 case B_MOUSE_UP: 200 if (message->FindInt32("buttons", &buttons) == B_OK) { 201 if (!fMouseDown || (buttons & B_PRIMARY_MOUSE_BUTTON)) { 202 /* pass it along */ 203 EnqueueMessage(DetachCurrentMessage()); 204 break; 205 } 206 } 207 fMouseDown = false; 208 if (fShowInk) { 209 BMessage *msg = new BMessage(*message); 210 fInkWindowMsgr.SendMessage(msg); 211 { 212 BMessage *msg = new BMessage(MSG_END_INK); 213 fInkWindowMsgr.SendMessage(msg); 214 } 215 } 216 if (fBackend) 217 fBackend->MessageReceived(message); 218 break; 219 case B_INPUT_METHOD_EVENT: 220 if (fBackend) 221 fBackend->MessageReceived(message); 222 break; 223 case MSG_METHOD_ACTIVATED: 224 if (message->FindBool(MSGF_ACTIVE, &b) < B_OK) 225 b = false; 226 HandleMethodActivated(b); 227 break; 228 case B_REPLY: 229 230 default: 231 BLooper::MessageReceived(message); 232 break; 233 } 234 } 235 236 void PenInputLooper::EnqueueMessage(BMessage *message) 237 { 238 fOwner->EnqueueMessage(message); 239 } 240 241 status_t PenInputLooper::InitCheck() 242 { 243 return B_OK; 244 } 245 246 void PenInputLooper::HandleMethodActivated(bool active) 247 { 248 /* 249 if (fShowInk && active) 250 fInkWindowMsgr.SendMessage(MSG_SHOW_WIN); 251 if (fShowInk && !active) 252 fInkWindowMsgr.SendMessage(MSG_END_INK); 253 */ 254 } 255 256