History

add Haiku port

iyzsong committed 2 years ago

Commit 5ce54971 parent 31e15656 files · +498 −1Browse files

Unified · Split

6 files
  1. Make.haiku +21 −0
  2. gui-haiku/Makefile +13 −0
  3. gui-haiku/screen.cpp +376 −0
  4. include/dtos.h +1 −1
  5. kern/Makefile +2 −0
  6. kern/devaudio-haiku.cpp +85 −0
Make.haiku+21−0
@@ -0,0 +1,21 @@
1# Haiku
2AR=ar
3AS=as
4RANLIB=ranlib
5CC=gcc
6CXX=g++
7CFLAGS=-Wall -Wno-missing-braces -Wno-parentheses -ggdb -I$(ROOT) -I$(ROOT)/include -I$(ROOT)/kern -c -D_THREAD_SAFE -D_POSIX_C_SOURCE -O2
8O=o
9OS=posix
10GUI=haiku
11AUDIO=haiku
12LDADD=-ggdb -lbe -lnetwork -lmedia -lstdc++
13LDFLAGS=
14TARG=drawterm
15
16
17all: default
18
19libmachdep.a:
20 arch=`uname -m|sed 's/i.86/386/;s/Power Macintosh/power/; s/x86_64/amd64/; s/armv[567].*/arm/; s/aarch64/arm64/'`; \
21 (cd posix-$$arch && make)
gui-haiku/Makefile+13−0
@@ -0,0 +1,13 @@
1ROOT=..
2include ../Make.config
3LIB=libgui.a
4
5OFILES=screen.$O
6
7default: $(LIB)
8$(LIB): $(OFILES)
9 $(AR) r $(LIB) $(OFILES)
10 $(RANLIB) $(LIB)
11
12screen.$O: screen.cpp
13 $(CXX) -o $@ $(CFLAGS) $<
gui-haiku/screen.cpp+376−0
@@ -0,0 +1,376 @@
1#include <memory>
2#include <Autolock.h>
3#include <Application.h>
4#include <Bitmap.h>
5#include <Clipboard.h>
6#include <Screen.h>
7#include <Window.h>
8#include <Input.h>
9#include <private/input/InputServerTypes.h>
10#include <private/interface/input_globals.h>
11
12extern "C" {
13#include "u.h"
14#include "lib.h"
15#include "dat.h"
16#include "fns.h"
17#include "error.h"
18#include "devaudio.h"
19#include "draw.h"
20#include "memdraw.h"
21#include "cursor.h"
22#include "keyboard.h"
23#include "screen.h"
24}
25
26Memimage *gscreen = (Memimage *)nil;
27
28class View : public BView {
29private:
30 std::unique_ptr<BBitmap> bitmap;
31 Mousestate ms;
32
33public:
34 View(BRect frame)
35 : BView(frame, NULL, B_FOLLOW_ALL_SIDES,
36 B_WILL_DRAW | B_FRAME_EVENTS | B_FULL_UPDATE_ON_RESIZE) {
37 SetViewColor(B_TRANSPARENT_COLOR);
38 bitmap = std::make_unique<BBitmap>(frame, B_RGBA32);
39 }
40
41 void *GetFrameBuffer() { return bitmap->Bits(); }
42
43 void Draw(BRect updateRect) override {
44 qlock(&drawlock);
45 DrawBitmap(bitmap.get(), updateRect, updateRect);
46 qunlock(&drawlock);
47 }
48
49 void MessageReceived(BMessage *message) override {
50 switch (message->what) {
51 case B_VIEW_RESIZED: {
52 int32 width, height;
53 width = message->GetInt32("width", 0);
54 height = message->GetInt32("height", 0);
55 qlock(&drawlock);
56 bitmap = std::make_unique<BBitmap>(BRect(0, 0, width, height), B_RGBA32);
57 memset(bitmap->Bits(), 0xff, bitmap->BitsLength());
58 qunlock(&drawlock);
59 screenresize(Rect(0, 0, width + 1, height + 1));
60 break;
61 }
62
63 case B_KEY_DOWN:
64 case B_UNMAPPED_KEY_DOWN:
65 case B_KEY_UP:
66 case B_UNMAPPED_KEY_UP: {
67 static struct {
68 int8 byte;
69 int32 key;
70 Rune k;
71 } transtab[] = {
72 0x00, 0x3b, Kcaps,
73 0x00, 0x5C, Kctl,
74 0x00, 0x60, Kctl,
75 0x00, 0x4b, Kshift,
76 0x00, 0x56, Kshift,
77 0x00, 0x5d, Kalt,
78 0x00, 0x5f, Kalt,
79 0x00, 0x66, Kmod4,
80
81 0x10, B_F1_KEY, KF | 1,
82 0x10, B_F2_KEY, KF | 2,
83 0x10, B_F3_KEY, KF | 3,
84 0x10, B_F4_KEY, KF | 4,
85 0x10, B_F5_KEY, KF | 5,
86 0x10, B_F6_KEY, KF | 6,
87 0x10, B_F7_KEY, KF | 7,
88 0x10, B_F8_KEY, KF | 8,
89 0x10, B_F9_KEY, KF | 9,
90 0x10, B_F10_KEY, KF | 10,
91 0x10, B_F11_KEY, KF | 11,
92 0x10, B_F12_KEY, KF | 12,
93 0x10, B_PRINT_KEY, Kprint,
94 0x10, B_SCROLL_KEY, Kscroll,
95 0x10, B_PAUSE_KEY, Kbreak,
96
97 B_DELETE, 0x34, Kdel,
98 B_INSERT, 0x1f, Kins,
99 B_HOME, 0x20, Khome,
100 B_END, 0x35, Kend,
101 B_PAGE_UP, 0x21, Kpgup,
102 B_PAGE_DOWN, 0x36, Kpgdown,
103 B_UP_ARROW, 0x57, Kup,
104 B_RIGHT_ARROW, 0x63, Kright,
105 B_LEFT_ARROW, 0x61, Kleft,
106 B_DOWN_ARROW, 0x62, Kdown,
107 };
108 int32 key = message->GetInt32("key", 0);
109 int8 byte = message->GetInt8("byte", 0);
110 bool down =
111 message->what == B_KEY_DOWN || message->what == B_UNMAPPED_KEY_DOWN;
112 Rune k = 0;
113 for (int i = 0; i < nelem(transtab); i++){
114 if (key != transtab[i].key || byte != transtab[i].byte)
115 continue;
116 k = transtab[i].k;
117 break;
118 }
119 kbdkey(k == 0 ? byte : k, down);
120 break;
121 }
122
123 case B_MOUSE_MOVED: {
124 BPoint where = message->GetPoint("where", BPoint(0, 0));
125 ms.xy.x = where.x;
126 ms.xy.y = where.y;
127 ms.msec = message->GetInt64("when", 0) / 1000;
128 absmousetrack(ms.xy.x, ms.xy.y, ms.buttons, ms.msec);
129 break;
130 }
131
132 case B_MOUSE_WHEEL_CHANGED: {
133 float delta_y = message->GetFloat("be:wheel_delta_y", 0);
134 int32 buttons = delta_y < 0 ? 8 : 16;
135 ms.msec = message->GetInt64("when", 0) / 1000;
136 absmousetrack(ms.xy.x, ms.xy.y, buttons, ms.msec);
137 break;
138 }
139
140 case B_MOUSE_DOWN:
141 case B_MOUSE_UP: {
142 int32 buttons = message->GetInt32("buttons", 0);
143 ms.msec = message->GetInt64("when", 0) / 1000;
144 ms.buttons = 0;
145 if (buttons & B_MOUSE_BUTTON(1))
146 ms.buttons |= 1;
147 if (buttons & B_MOUSE_BUTTON(2))
148 ms.buttons |= 4;
149 if (buttons & B_MOUSE_BUTTON(3))
150 ms.buttons |= 2;
151 absmousetrack(ms.xy.x, ms.xy.y, ms.buttons, ms.msec);
152 break;
153 }
154
155 default:
156 BView::MessageReceived(message);
157 }
158 }
159};
160
161static void winproc(void *arg) {
162 BWindow *window = (BWindow *)arg;
163 thread_id tid = find_thread(NULL);
164 rename_thread(tid, "window");
165 BAutolock locker(window);
166 window->Loop();
167}
168
169static const uint32 kToggleFullScreen = 'TFSn';
170
171class Window : public BWindow {
172private:
173 BRect fSavedFrame;
174 bool fFullScreen;
175
176 void _ToggleFullScreen() {
177 if (fFullScreen) {
178 ResizeTo(fSavedFrame.Width(), fSavedFrame.Height());
179 MoveTo(fSavedFrame.left, fSavedFrame.top);
180 SetFlags(Flags() & ~(B_NOT_RESIZABLE | B_NOT_MOVABLE));
181 fFullScreen = false;
182 } else {
183 BScreen screen(this);
184 BRect frame = screen.Frame();
185 fSavedFrame = Frame();
186 ResizeTo(frame.Width() + 1, frame.Height() + 1);
187 MoveTo(frame.left, frame.top);
188 SetFlags(Flags() | (B_NOT_RESIZABLE | B_NOT_MOVABLE));
189 fFullScreen = true;
190 }
191 }
192
193public:
194 Window(BRect frame)
195 : BWindow(frame, "drawterm", B_TITLED_WINDOW, B_QUIT_ON_WINDOW_CLOSE) {
196 fFullScreen = false;
197
198 BMessage *message = new BMessage(kToggleFullScreen);
199 AddShortcut(B_ENTER, B_COMMAND_KEY, message);
200 }
201
202 ~Window() {
203 status_t exit_value;
204 wait_for_thread(Thread(), &exit_value);
205 }
206
207 thread_id Run() override {
208 thread_id tid = 0;
209 if (IsLocked()) {
210 kproc("window", winproc, this);
211 while (tid == 0) {
212 tid = find_thread("window");
213 osmsleep(10);
214 }
215 Unlock();
216 }
217 return tid;
218 }
219
220 bool QuitRequested() override {
221 status_t exit_value;
222 thread_id tid = find_thread("cpu");
223 audiodevclose();
224 kill_thread(tid);
225 wait_for_thread(tid, &exit_value);
226 return BLooper::QuitRequested();
227 }
228
229 void MessageReceived(BMessage *message) override {
230 switch (message->what) {
231 case kToggleFullScreen:
232 _ToggleFullScreen();
233 break;
234 default:
235 BWindow::MessageReceived(message);
236 }
237 }
238};
239
240class Application : public BApplication {
241public:
242 Window *window;
243 View *view;
244
245 Application() : BApplication("application/x-vnd.9front-drawterm") {
246 BRect frame(0, 0, 640 - 1, 480 - 1);
247 window = new Window(frame);
248 view = new View(frame);
249 window->AddChild(view);
250 window->CenterOnScreen();
251 view->MakeFocus();
252 window->Show();
253 }
254};
255#define sApp ((Application *)be_app)
256
257char *clipread(void) {
258 const void *data = NULL;
259 char *ret = NULL;
260 ssize_t textLen;
261 if (be_clipboard->Lock()) {
262 BMessage *clip = be_clipboard->Data();
263 if (clip){
264 clip->FindData("text/plain", B_MIME_TYPE, &data, &textLen);
265 ret = (char*)malloc(textLen + 1);
266 if (ret != NULL){
267 memcpy(ret, data, textLen);
268 ret[textLen] = '\0';
269 }
270 }
271 be_clipboard->Unlock();
272 }
273 return ret;
274}
275
276int clipwrite(char *text) {
277 ssize_t textLen = strlen(text);
278 if (be_clipboard->Lock()) {
279 BMessage *clip = be_clipboard->Data();
280 if (clip) {
281 be_clipboard->Clear();
282 clip->AddData("text/plain", B_MIME_TYPE, text, textLen);
283 be_clipboard->Commit();
284 }
285 be_clipboard->Unlock();
286 }
287 return textLen;
288}
289
290void flushmemscreen(Rectangle r) {
291 BRect rect(r.min.x, r.min.y, r.max.x - 1, r.max.y - 1);
292 BMessage message(B_INVALIDATE);
293 message.AddRect("be:area", rect);
294 sApp->window->PostMessage(&message, sApp->view);
295}
296
297Memdata *attachscreen(Rectangle *r, ulong *chan, int *depth, int *width,
298 int *softscreen) {
299 *r = gscreen->clipr;
300 *chan = gscreen->chan;
301 *depth = gscreen->depth;
302 *width = gscreen->width;
303 *softscreen = 1;
304 gscreen->data->ref++;
305 return gscreen->data;
306}
307
308void getcolor(ulong i, ulong *r, ulong *g, ulong *b) {
309 ulong v;
310 v = cmap2rgb(i);
311 *r = (v >> 16) & 0xFF;
312 *g = (v >> 8) & 0xFF;
313 *b = v & 0xFF;
314}
315
316void setcolor(ulong i, ulong r, ulong g, ulong b) {}
317
318void setcursor(void) {
319 static uint8 data[68];
320 uint8 *p = data;
321 lock(&cursor.lk);
322 *p++ = 16;
323 *p++ = 1;
324 *p++ = -cursor.offset.x;
325 *p++ = -cursor.offset.y;
326 for (int i = 0; i < 32; i++) {
327 p[i] = cursor.set[i];
328 p[i + 32] = cursor.set[i] | cursor.clr[i];
329 }
330 sApp->SetCursor(data);
331 unlock(&cursor.lk);
332}
333
334void mouseset(Point xy) {
335 BAutolock locker(sApp->window);
336 BMessage message(IS_SET_MOUSE_POSITION);
337 BMessage reply;
338 BPoint where(xy.x, xy.y);
339 sApp->view->ConvertToScreen(&where);
340 message.AddPoint("where", where);
341 _control_input_server_(&message, &reply);
342}
343
344void screeninit(void) {
345 BAutolock locker(sApp->window);
346 BRect bounds = sApp->view->Bounds();
347 Rectangle r = Rect(0, 0, bounds.right + 1, bounds.bottom + 1);
348 memimageinit();
349 screensize(r, XRGB32);
350 gscreen->clipr = r;
351 terminit();
352}
353
354static void cpuproc(void *arg) {
355 rename_thread(find_thread(NULL), "cpu");
356 cpubody();
357}
358
359void guimain(void) {
360 Application app;
361 kproc("cpu", cpuproc, nil);
362 app.Run();
363}
364
365void screensize(Rectangle r, ulong chan) {
366 static Memdata md = {
367 .base = 0,
368 .allocd = 0,
369 };
370 if (gscreen != nil)
371 freememimage(gscreen);
372 md.ref = 1;
373 md.bdata = (uchar *)sApp->view->GetFrameBuffer();
374 gscreen = allocmemimaged(r, chan, &md);
375 gscreen->clipr = ZR;
376}
include/dtos.h+1−1
@@ -1,4 +1,4 @@
1#if defined(linux) || defined(IRIX) || defined(SOLARIS) || defined(OSF1) || defined(__FreeBSD__) || defined(__APPLE__) || defined(__NetBSD__) || defined(__sun) || defined(sun) || defined(__OpenBSD__) || defined(__DragonFly__)1#if defined(linux) || defined(IRIX) || defined(SOLARIS) || defined(OSF1) || defined(__FreeBSD__) || defined(__APPLE__) || defined(__NetBSD__) || defined(__sun) || defined(sun) || defined(__OpenBSD__) || defined(__DragonFly__) || defined(__HAIKU__)
2# include "unix.h"2# include "unix.h"
3# ifdef __APPLE__3# ifdef __APPLE__
4# define panic dt_panic4# define panic dt_panic
kern/Makefile+2−0
@@ -48,3 +48,5 @@ $(LIB): $(OFILES) · 47 unmodified lines
48%.$O: %.c48%.$O: %.c
49 $(CC) $(CFLAGS) $*.c49 $(CC) $(CFLAGS) $*.c
50 50
51devaudio-haiku.$O: devaudio-haiku.cpp
52 $(CXX) $(CFLAGS) $<
kern/devaudio-haiku.cpp+85−0
@@ -0,0 +1,85 @@
1#include <Autolock.h>
2#include <SoundPlayer.h>
3#include <memory>
4
5extern "C" {
6#include "u.h"
7#include "lib.h"
8#include "dat.h"
9#include "fns.h"
10#include "error.h"
11#include "devaudio.h"
12}
13
14static struct {
15 BLocker locker;
16 std::unique_ptr<BSoundPlayer> player;
17 uint8 buffer[44100 * 4 / 10];
18 size_t written;
19} snd;
20
21static void play(void *cookie, void *buffer, size_t size,
22 const media_raw_audio_format &format) {
23 BAutolock locker(&snd.locker);
24 if (snd.written >= size) {
25 memcpy(buffer, snd.buffer, size);
26 snd.written -= size;
27 if (snd.written > 0)
28 memmove(snd.buffer, snd.buffer + size, snd.written);
29 } else {
30 memset(buffer, 0, size);
31 }
32}
33
34void audiodevopen(void) {
35 const media_raw_audio_format format = {
36 .frame_rate = 44100,
37 .channel_count = 2,
38 .format = media_raw_audio_format::B_AUDIO_SHORT,
39 .byte_order = B_MEDIA_LITTLE_ENDIAN,
40 .buffer_size = 4096,
41 };
42 snd.player = std::make_unique<BSoundPlayer>(&format, "devaudio", play);
43 snd.written = 0;
44 if (snd.player->InitCheck() != B_OK) {
45 snd.player.reset(nullptr);
46 return;
47 }
48 snd.player->Start();
49}
50
51void audiodevclose(void) { snd.player.reset(nullptr); }
52
53int audiodevread(void *a, int n) {
54 error("no reading");
55 return -1;
56}
57
58int audiodevwrite(void *a, int n) {
59 int w = n;
60 uint8 *p = (uint8 *)a;
61
62 if (snd.player.get() == nullptr)
63 return -1;
64
65 while (n > 0) {
66 snd.locker.Lock();
67 int max = sizeof(snd.buffer) - snd.written;
68 int x = n > max ? max : n;
69 if (x < 1) {
70 snd.locker.Unlock();
71 osmsleep(10);
72 } else {
73 memcpy(snd.buffer + snd.written, p, x);
74 snd.written += x;
75 p += x;
76 n -= x;
77 snd.locker.Unlock();
78 }
79 }
80 return w;
81}
82
83void audiodevsetvol(int what, int left, int right) { error("not supported"); }
84
85void audiodevgetvol(int what, int *left, int *right) { error("not supported"); }

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t