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
2+AR=ar
3+AS=as
4+RANLIB=ranlib
5+CC=gcc
6+CXX=g++
7+CFLAGS=-Wall -Wno-missing-braces -Wno-parentheses -ggdb -I$(ROOT) -I$(ROOT)/include -I$(ROOT)/kern -c -D_THREAD_SAFE -D_POSIX_C_SOURCE -O2
8+O=o
9+OS=posix
10+GUI=haiku
11+AUDIO=haiku
12+LDADD=-ggdb -lbe -lnetwork -lmedia -lstdc++
13+LDFLAGS=
14+TARG=drawterm
15+
16+
17+all: default
18+
19+libmachdep.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 @@
1+ROOT=..
2+include ../Make.config
3+LIB=libgui.a
4+
5+OFILES=screen.$O
6+
7+default: $(LIB)
8+$(LIB): $(OFILES)
9+ $(AR) r $(LIB) $(OFILES)
10+ $(RANLIB) $(LIB)
11+
12+screen.$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+
12+extern "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+
26+Memimage *gscreen = (Memimage *)nil;
27+
28+class View : public BView {
29+private:
30+ std::unique_ptr<BBitmap> bitmap;
31+ Mousestate ms;
32+
33+public:
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+
161+static 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+
169+static const uint32 kToggleFullScreen = 'TFSn';
170+
171+class Window : public BWindow {
172+private:
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+
193+public:
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+
240+class Application : public BApplication {
241+public:
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+
257+char *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+
276+int 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+
290+void 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+
297+Memdata *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+
308+void 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+
316+void setcolor(ulong i, ulong r, ulong g, ulong b) {}
317+
318+void 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+
334+void 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+
344+void 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+
354+static void cpuproc(void *arg) {
355+ rename_thread(find_thread(NULL), "cpu");
356+ cpubody();
357+}
358+
359+void guimain(void) {
360+ Application app;
361+ kproc("cpu", cpuproc, nil);
362+ app.Run();
363+}
364+
365+void 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__)
22 # include "unix.h"
33 # ifdef __APPLE__
44 # define panic dt_panic
kern/Makefile+2−0
@@ -48,3 +48,5 @@ $(LIB): $(OFILES) · 47 unmodified lines
4848 %.$O: %.c
4949 $(CC) $(CFLAGS) $*.c
5050
51+devaudio-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+
5+extern "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+
14+static struct {
15+ BLocker locker;
16+ std::unique_ptr<BSoundPlayer> player;
17+ uint8 buffer[44100 * 4 / 10];
18+ size_t written;
19+} snd;
20+
21+static 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+
34+void 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+
51+void audiodevclose(void) { snd.player.reset(nullptr); }
52+
53+int audiodevread(void *a, int n) {
54+ error("no reading");
55+ return -1;
56+}
57+
58+int 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+
83+void audiodevsetvol(int what, int left, int right) { error("not supported"); }
84+
85+void 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