xref: /haiku/src/add-ons/input_server/methods/pen/PenInputLooper.cpp (revision 2b76973fa2401f7a5edf68e6470f3d3210cbcff3)
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(&region);
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