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
PenInputLooper(PenInputServerMethod * method)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
Quit()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
DispatchMessage(BMessage * message,BHandler * handler)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
MessageReceived(BMessage * message)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
EnqueueMessage(BMessage * message)236 void PenInputLooper::EnqueueMessage(BMessage *message)
237 {
238 fOwner->EnqueueMessage(message);
239 }
240
InitCheck()241 status_t PenInputLooper::InitCheck()
242 {
243 return B_OK;
244 }
245
HandleMethodActivated(bool active)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