xref: /haiku/src/tests/servers/app/drawing_debugger/DrawingDebugger.cpp (revision cbe0a0c436162d78cc3f92a305b64918c839d079)
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 
33 class DrawingDebuggerView : public BView {
34 public:
35 								DrawingDebuggerView(BRect frame);
36 virtual							~DrawingDebuggerView();
37 
38 virtual	void					Draw(BRect updateRect);
39 
40 private:
41 static	int32					_PortListener(void *data);
42 
43 		BBitmap *				fBitmap;
44 		BView *					fOffscreenView;
45 		thread_id				fListenerThread;
46 		bool					fStopListener;
47 };
48 
49 
50 class DrawingDebuggerWindow : public BWindow {
51 public:
52 								DrawingDebuggerWindow(BRect frame);
53 
54 private:
55 		DrawingDebuggerView *	fView;
56 };
57 
58 
59 class DrawingDebuggerApp : public BApplication {
60 public:
61 								DrawingDebuggerApp();
62 
63 private:
64 		DrawingDebuggerWindow *	fWindow;
65 };
66 
67 
68 rgb_color
69 random_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 
79 DrawingDebuggerApp::DrawingDebuggerApp()
80 	:	BApplication("application/x.vnd-Haiku.DrawingDebugger")
81 {
82 	fWindow = new DrawingDebuggerWindow(BRect(200, 200, 999, 799));
83 	fWindow->Show();
84 }
85 
86 
87 DrawingDebuggerWindow::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 
96 DrawingDebuggerView::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 
111 DrawingDebuggerView::~DrawingDebuggerView()
112 {
113 	fStopListener = true;
114 	int32 returnCode = B_OK;
115 	wait_for_thread(fListenerThread, &returnCode);
116 	delete fBitmap;
117 }
118 
119 
120 void
121 DrawingDebuggerView::Draw(BRect updateRect)
122 {
123 	DrawBitmap(fBitmap, updateRect, updateRect);
124 }
125 
126 
127 int32
128 DrawingDebuggerView::_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 
181 int
182 main(int argc, const char *argv[])
183 {
184 	DrawingDebuggerApp *app = new DrawingDebuggerApp();
185 	app->Run();
186 	delete app;
187 	return 0;
188 }
189