1#include <Application.h>
2#include <Bitmap.h>
3#include <View.h>
4#include <Window.h>
5#include <malloc.h>
6#include <stdio.h>
7
8
9#if 0
10{
11	// usage example for simple rects
12	port_id port = find_port("drawing_debugger_port");
13	if (port >= 0) {
14		write_port_etc(port, 'RECT', &interestingRect, sizeof(BRect),
15			B_RELATIVE_TIMEOUT, 0);
16	}
17
18
19	// usage example for regions
20	port_id port = find_port("drawing_debugger_port");
21	if (port >= 0) {
22		int32 rectCount = region->CountRects();
23		for (int32 i = 0; i < rectCount; i++) {
24			BRect interestingRect = region->RectAt(i);
25			write_port_etc(port, 'RECT', &interestingRect, sizeof(BRect),
26				B_RELATIVE_TIMEOUT, 0);
27		}
28	}
29}
30#endif
31
32
33class DrawingDebuggerView : public BView {
34public:
35								DrawingDebuggerView(BRect frame);
36virtual							~DrawingDebuggerView();
37
38virtual	void					Draw(BRect updateRect);
39
40private:
41static	int32					_PortListener(void *data);
42
43		BBitmap *				fBitmap;
44		BView *					fOffscreenView;
45		thread_id				fListenerThread;
46		bool					fStopListener;
47};
48
49
50class DrawingDebuggerWindow : public BWindow {
51public:
52								DrawingDebuggerWindow(BRect frame);
53
54private:
55		DrawingDebuggerView *	fView;
56};
57
58
59class DrawingDebuggerApp : public BApplication {
60public:
61								DrawingDebuggerApp();
62
63private:
64		DrawingDebuggerWindow *	fWindow;
65};
66
67
68rgb_color
69random_color()
70{
71	rgb_color result;
72	result.red = system_time() % 256;
73	result.green = (system_time() >> 8) % 256;
74	result.blue = (system_time() >> 16) % 256;
75	return result;
76}
77
78
79DrawingDebuggerApp::DrawingDebuggerApp()
80	:	BApplication("application/x.vnd-Haiku.DrawingDebugger")
81{
82	fWindow = new DrawingDebuggerWindow(BRect(200, 200, 999, 799));
83	fWindow->Show();
84}
85
86
87DrawingDebuggerWindow::DrawingDebuggerWindow(BRect frame)
88	:	BWindow(frame, "DrawingDebugger", B_TITLED_WINDOW,
89			B_QUIT_ON_WINDOW_CLOSE)
90{
91	fView = new DrawingDebuggerView(frame.OffsetToSelf(0, 0));
92	AddChild(fView);
93}
94
95
96DrawingDebuggerView::DrawingDebuggerView(BRect frame)
97	:	BView(frame, "DrawingDebuggerView", B_FOLLOW_ALL, B_WILL_DRAW)
98{
99	fBitmap = new BBitmap(frame, B_RGB32, true);
100	fOffscreenView= new BView(frame, "OffscreenView", B_FOLLOW_NONE, 0);
101	fOffscreenView->SetViewColor(B_TRANSPARENT_32_BIT);
102	fBitmap->AddChild(fOffscreenView);
103
104	fStopListener = false;
105	fListenerThread = spawn_thread(_PortListener, "port_listener",
106		B_NORMAL_PRIORITY, this);
107	resume_thread(fListenerThread);
108}
109
110
111DrawingDebuggerView::~DrawingDebuggerView()
112{
113	fStopListener = true;
114	int32 returnCode = B_OK;
115	wait_for_thread(fListenerThread, &returnCode);
116	delete fBitmap;
117}
118
119
120void
121DrawingDebuggerView::Draw(BRect updateRect)
122{
123	DrawBitmap(fBitmap, updateRect, updateRect);
124}
125
126
127int32
128DrawingDebuggerView::_PortListener(void *data)
129{
130	DrawingDebuggerView *view = (DrawingDebuggerView *)data;
131	port_id port = create_port(1000, "drawing_debugger_port");
132	if (port < 0) {
133		printf("failed to create port\n");
134		return port;
135	}
136
137	size_t bufferSize = 1024;
138	uint8 *buffer = (uint8 *)malloc(bufferSize);
139	if (buffer == NULL)
140		return B_NO_MEMORY;
141
142	while (!view->fStopListener) {
143		int32 code = 0;
144		status_t result = read_port_etc(port, &code, buffer, bufferSize,
145			B_RELATIVE_TIMEOUT, 100000);
146		if (result == B_INTERRUPTED || result == B_TIMED_OUT)
147			continue;
148		if (result < B_OK) {
149			printf("failed to read from port\n");
150			return result;
151		}
152
153		switch (code) {
154			case 'RECT':
155			{
156				BRect *rect = (BRect *)buffer;
157				view->fBitmap->Lock();
158				view->fOffscreenView->SetHighColor(random_color());
159				view->fOffscreenView->FillRect(*rect, B_SOLID_HIGH);
160				view->fOffscreenView->Sync();
161				view->fBitmap->Unlock();
162
163				view->LockLooper();
164				view->Invalidate(*rect);
165				view->UnlockLooper();
166				break;
167			}
168
169			default:
170				printf("unsupported code '%.4s'\n", (char *)&code);
171				break;
172		}
173	}
174
175	free(buffer);
176	delete_port(port);
177	return 0;
178}
179
180
181int
182main(int argc, const char *argv[])
183{
184	DrawingDebuggerApp *app = new DrawingDebuggerApp();
185	app->Run();
186	delete app;
187	return 0;
188}
189