diff --git a/kernel/src/holeybytes/ecah.rs b/kernel/src/holeybytes/ecah.rs index ab45e64..8a03816 100644 --- a/kernel/src/holeybytes/ecah.rs +++ b/kernel/src/holeybytes/ecah.rs @@ -182,7 +182,7 @@ pub fn handler(vm: &mut Vm) { } else { unsafe { let ptr = map_ptr as *mut u8; - ptr.copy_from(msg.as_ptr(), msg.len()); + ptr.copy_from_nonoverlapping(msg.as_ptr(), msg.len()); } debug!("Recieve {:?} from Buffer({})", msg, buffer_id); diff --git a/sysdata/libraries/intouch/src/lib.hb b/sysdata/libraries/intouch/src/lib.hb index dca49d4..a6c5a91 100644 --- a/sysdata/libraries/intouch/src/lib.hb +++ b/sysdata/libraries/intouch/src/lib.hb @@ -15,7 +15,7 @@ recieve_mouse_event := fn(): ?MouseEvent { buf_id := buffer.search("PS/2 Mouse\0") // Read out of the Mouse buffer here - buffer.recv(MouseEvent, buf_id, @bitcast(&mevent)) + buffer.recv(MouseEvent, buf_id, &mevent) if mevent.x_change != 0 | mevent.y_change != 0 | mevent.left | mevent.middle | mevent.right { return mevent diff --git a/sysdata/libraries/stn/src/buffer.hb b/sysdata/libraries/stn/src/buffer.hb index 1912c59..aa16637 100644 --- a/sysdata/libraries/stn/src/buffer.hb +++ b/sysdata/libraries/stn/src/buffer.hb @@ -1,6 +1,6 @@ string := @use("string.hb") -recv := fn($Expr: type, buffer_id: uint, memory_map_location: ^u8): void { +recv := fn($Expr: type, buffer_id: uint, memory_map_location: ^Expr): void { return @eca(4, buffer_id, memory_map_location, @sizeof(Expr)) } diff --git a/sysdata/libraries/stn/src/memory.hb b/sysdata/libraries/stn/src/memory.hb index 821e46f..5bebd68 100644 --- a/sysdata/libraries/stn/src/memory.hb +++ b/sysdata/libraries/stn/src/memory.hb @@ -2,15 +2,8 @@ PAGE_SIZE := 4096 MAX_ALLOC := 0xFF MAX_FREE := 0xFF -is_uninit := fn($Expr: type, ptr: ^Expr): bool { - i := 0 - loop if *(@as(^u8, @bitcast(ptr)) + i) != 0 return false else if i + 1 == @sizeof(Expr) return true else i += 1 -} - -uninit := fn($Expr: type): Expr { - empty := @as(Expr, idk) - @inline(set, u8, &0, @bitcast(&empty), @sizeof(Expr)) - return empty +uninit := fn($Expr: type): ?Expr { + return null } dangling := fn($Expr: type): ^Expr { diff --git a/sysdata/libraries/sunset_proto/src/client.hb b/sysdata/libraries/sunset_proto/src/client.hb index da1950c..bc23e0d 100644 --- a/sysdata/libraries/sunset_proto/src/client.hb +++ b/sysdata/libraries/sunset_proto/src/client.hb @@ -1,62 +1,79 @@ .{math: .{Vec2}, buffer, log, memory} := @use("../../stn/src/lib.hb"); .{Surface, new_surface} := @use("../../render/src/lib.hb"); -.{WindowWrapper, WindowID, WindowProps, WindowMessage, message, BUFFER} := @use("./lib.hb") +.{Window, WindowData, WindowProps, MessageHeader, message, BUFFER} := @use("./lib.hb") -buffer_id := @as(?uint, null) - -new_window := fn(props: WindowProps): ?WindowWrapper { - if buffer_id == null { - log.error("client: (request_new) buffer id is null. did you init the client?\0") - return null - } - buf := memory.uninit(?WindowWrapper) - buffer.write(WindowMessage, &.(message.new, 0, @sizeof(WindowProps), @bitcast(&props), @bitcast(&buf)), @unwrap(buffer_id)) - loop if memory.is_uninit(?WindowWrapper, &buf) == false break else { - } - // loop until i write a better socket - i := 0 - loop if i >= 1000 break else i += 1 - return buf -} - -update_window_props := fn(wrapper: WindowWrapper): ?WindowProps { - log.error("todo: sunset_proto/src/client/update_window_props.hb\0") - if buffer_id == null { - log.error("client: (request_update_properties) buffer id is null. did you init the client?\0") - return null - } - // TODO: buffer.write(WINDOWING_BUFFER, update properties) request - return null -} - -request_shutdown := fn(): ?bool { - if buffer_id == null { - log.error("client: (request_shutdown) buffer id is null. did you init the client?\0") - return null - } - buf := memory.uninit(?u8) - buffer.write(WindowMessage, &.(message.shutdown, 0, 0, memory.dangling(u8), @bitcast(&buf)), @unwrap(buffer_id)) - loop if memory.is_uninit(?u8, &buf) == false break else { - } - // loop until i write a better socket - i := 0 - loop if i >= 1000 break else i += 1 - // had to do ?u8 here, ?bool didnt work - if buf == null | @unwrap(buf) != 255 { - return false - } else { - return true - } -} +server_id := @as(?uint, null) init := fn(): void { log.info("client: waiting for server\0") id := 0 loop if id != 0 { - buffer_id = id + server_id = id log.info("client: done waiting\0") return } else { id = buffer.search(BUFFER) } +} + +// wait_for_message := fn($Expr: type, ptr: ^?Expr, buffer_id: uint): bool { +// timer := 0 +// loop if timer < 1000 { +// buffer.recv(?Expr, buffer_id, ptr) +// if *ptr != null { +// return true +// } +// timer -= 1 +// } +// return false +// } + +new := fn(props: WindowProps): ?Window { + if server_id == null { + init() + } + buffer.write(?MessageHeader, &@as(?MessageHeader, .(message.syn, @sizeof(WindowProps))), @unwrap(server_id)) + log.info("client: sent syn\0") + + timer := 0 + response := memory.uninit(MessageHeader) + // if wait_for_message(MessageHeader, &response, @unwrap(server_id)) == false { + // return null + // } + loop if timer < 1000 { + buffer.recv(?MessageHeader, @unwrap(server_id), &response) + if response != null { + break + } + timer += 1 + } else { + log.error("client: no response in timeout\0") + return null + } + if response.kind != message.ack { + log.error("client: refused\0") + return null + } + log.info("client: received ack\0") + + buffer_id := response.data + buffer.write(?WindowProps, &@as(?WindowProps, props), buffer_id) + log.info("client: sent props\0") + + timer = 0 + response2 := memory.uninit(WindowData) + loop if timer < 1000 { + buffer.recv(?WindowData, buffer_id, &response2) + + if response2 != null { + log.info("client: received window data\0") + surface := new_surface( + response2.props.dimensions.x, + response2.props.dimensions.y, + ) + return .(@as(WindowData, response2), surface) + } + timer += 1 + } + return null } \ No newline at end of file diff --git a/sysdata/libraries/sunset_proto/src/lib.hb b/sysdata/libraries/sunset_proto/src/lib.hb index 7006f7d..b5f8a95 100644 --- a/sysdata/libraries/sunset_proto/src/lib.hb +++ b/sysdata/libraries/sunset_proto/src/lib.hb @@ -7,30 +7,24 @@ client := @use("./client.hb") server := @use("./server.hb") message := @use("./message.hb") -WindowID := uint -MessageKind := uint - -WindowMessage := packed struct { - kind: MessageKind, - id: WindowID, - length: uint, - data_ptr: ^u8, - // need to replace this with a buffer id - callback: ^u8, +MessageHeader := packed struct { + kind: uint, + data: uint, } WindowProps := struct { position: Vec2(uint), dimensions: Vec2(uint), + // replace with owned string type later title: ^u8, } -WindowWrapper := struct { - id: WindowID, +WindowData := struct { props: WindowProps, + buffer_id: uint, } Window := struct { + data: WindowData, surface: Surface, - props: WindowProps, } \ No newline at end of file diff --git a/sysdata/libraries/sunset_proto/src/message.hb b/sysdata/libraries/sunset_proto/src/message.hb index 700ab52..9c69092 100644 --- a/sysdata/libraries/sunset_proto/src/message.hb +++ b/sysdata/libraries/sunset_proto/src/message.hb @@ -1,4 +1,6 @@ -$new := 0 -$destroy := 1 -$update_props := 2 -$shutdown := 3 \ No newline at end of file +$syn := 1 +$ack := 2 +$refused := 3 +$quit := 4 +$update_props := 5 +$shutdown := 6 \ No newline at end of file diff --git a/sysdata/libraries/sunset_proto/src/server.hb b/sysdata/libraries/sunset_proto/src/server.hb index 4581571..46d4617 100644 --- a/sysdata/libraries/sunset_proto/src/server.hb +++ b/sysdata/libraries/sunset_proto/src/server.hb @@ -1,32 +1,63 @@ .{math, log, string, random, buffer, memory} := @use("../../stn/src/lib.hb"); .{Surface, new_surface} := @use("../../render/src/lib.hb"); -.{WindowWrapper, WindowID, WindowProps, WindowMessage, BUFFER} := @use("./lib.hb") +.{Window, WindowProps, WindowData, MessageHeader, BUFFER, message} := @use("./lib.hb") -WindowServer := struct {window_count: uint, buffer_id: uint} +WindowServer := struct { + window_count: uint, + id: uint, + // replace this with an actual collection when we get an allocator + windows: ^WindowData, +} server := @as(?WindowServer, null) -new_window_id := fn(): WindowID { - return random.any(uint) -} - -init := fn(): bool { +init := fn(): void { + if server != null { + return + } log.info("server: starting server\0") - server = .(0, buffer.create(BUFFER)) - return true + windows := memory.alloc(WindowData, 10) + server = .(0, buffer.create(BUFFER), windows) } -recieve := fn(): ?WindowMessage { +handle_connections := fn(): bool { if server == null { - log.error("server: (request_new) server is null. did you init the client?\0") - return null + return false } - buf := memory.uninit(WindowMessage) - buffer.recv(WindowMessage, @unwrap(server).buffer_id, @bitcast(&buf)) - if memory.is_uninit(WindowMessage, &buf) { - return null + recv := memory.uninit(MessageHeader) + buffer.recv(?MessageHeader, @unwrap(server).id, &recv) + if recv == null { + return true + } else if recv.kind == message.syn { + buffer_id := buffer.create("asdf\0") + buffer.write(?MessageHeader, &@as(?MessageHeader, .(message.ack, buffer_id)), @unwrap(server).id) + log.info("server: sent ack\0") + + timer := 0 + resp := memory.uninit(WindowProps) + loop if timer < 1000 { + buffer.recv(?WindowProps, buffer_id, &resp) + if resp != null { + break + } + timer += 1 + } else { + log.error("server: no props in timeout\0") + return true + } + log.info("server: received props\0") + surface := new_surface(resp.dimensions.x, resp.dimensions.y) + data := WindowData.(@as(WindowProps, resp), buffer_id) + buffer.write(?WindowData, &@as(?WindowData, data), buffer_id) + log.info("server: sent window data\0"); + *(@unwrap(server).windows + @unwrap(server).window_count) = data + @unwrap(server).window_count += 1 + } else if recv.kind == message.quit { + // todo: quit + } else if recv.kind == message.shutdown { + return false } - return buf + return true } should_shutdown := fn(): bool { diff --git a/sysdata/programs/horizon/src/main.hb b/sysdata/programs/horizon/src/main.hb index 0666373..9ead559 100644 --- a/sysdata/programs/horizon/src/main.hb +++ b/sysdata/programs/horizon/src/main.hb @@ -96,7 +96,7 @@ main := fn(): int { // if mouse_event != null { - // log.warn("Mouse event recieved\0") + // log.warn("Mouse event received\0") change_x := @as(i16, mouse_event.x_change) change_x = change_x << 8 diff --git a/sysdata/programs/sunset_client/src/main.hb b/sysdata/programs/sunset_client/src/main.hb index a9def72..86b8ac7 100644 --- a/sysdata/programs/sunset_client/src/main.hb +++ b/sysdata/programs/sunset_client/src/main.hb @@ -2,23 +2,11 @@ sunset := @use("../../../libraries/sunset_proto/src/lib.hb") main := fn(): void { - sunset.client.init() - log.info("client: request new window\0") - window := sunset.client.new_window(.(.(100, 100), .(150, 150), "Hello, World!\0")) + window := sunset.client.new(.(.(100, 100), .(100, 100), "Hello, World!\0")) if window == null { - log.error("Could not create window\0") + log.error("client: window was null\0") return } - log.info("client: window created. title:\0") - log.info(window.props.title) - window.props.position = .(500, 500) - props := @unwrap(sunset.client.update_window_props(window)) - if props.position.x != window.props.position.x { - log.error("client: we did not update props\0") - } - log.info("client: sending shutdown request\0") - shutdown := sunset.client.request_shutdown() - if shutdown == null { - log.error("client: didnt shutdown the server\0") - } + log.info("client: window title:\0") + log.info(window.data.props.title) } \ No newline at end of file diff --git a/sysdata/programs/sunset_server/src/main.hb b/sysdata/programs/sunset_server/src/main.hb index c3e2011..98f421b 100644 --- a/sysdata/programs/sunset_server/src/main.hb +++ b/sysdata/programs/sunset_server/src/main.hb @@ -1,36 +1,7 @@ -.{log} := @use("../../../libraries/stn/src/lib.hb") -render := @use("../../../libraries/render/src/lib.hb"); -.{server, message, WindowWrapper, WindowProps} := @use("../../../libraries/sunset_proto/src/lib.hb") - -psf := @embed("../../../assets/consolefonts/tamsyn/10x20r.psf") +sunset := @use("../../../libraries/sunset_proto/src/lib.hb") main := fn(): void { - screen := render.init(false) - font := render.text.font_from_psf2(@bitcast(&psf), false) - if font == null { - return + sunset.server.init() + loop if sunset.server.handle_connections() { } - if server.init() == false { - log.error("Failed to create server\0") - return - } - loop if server.should_shutdown() break else { - recv := server.recieve() - if recv == null { - continue - } else if recv.kind == message.new { - props := *@as(^WindowProps, @bitcast(recv.data_ptr)); - *@as(^?WindowWrapper, @bitcast(recv.callback)) = WindowWrapper.(0, props) - render.put_rect(screen, props.position, props.dimensions, render.white) - render.put_text(screen, font, props.position + .(1, 1), render.white, props.title) - render.put_hline(screen, props.position.y + font.height + 2, props.position.x, props.position.x + props.dimensions.x, render.white) - log.info("server: made a new window\0") - } else if recv.kind == message.shutdown { - *@as(^?u8, @bitcast(recv.callback)) = 255 - break - } - } - - render.put_text(screen, font, .(0, 0), render.white, "Shutdown triggered\0") - log.info("Server shutdown\0") } \ No newline at end of file