summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMitchell Hashimoto <mitchell.hashimoto@gmail.com>2023-02-17 22:12:03 -0800
committerMitchell Hashimoto <mitchell.hashimoto@gmail.com>2023-02-19 10:44:56 -0800
commit573b163636d5c76ff2592d07bfdff434d2671dd0 (patch)
tree2abd8d8ca99a8979d72ac0d03cdb9d8a944f837d
parent074664398a1c30f1f75bb8f363a86234b927150c (diff)
start input, its broken but we're getting there
-rw-r--r--include/ghostty.h150
-rw-r--r--macos/Sources/TerminalSurfaceView.swift7
-rw-r--r--src/App.zig11
-rw-r--r--src/apprt/embedded.zig13
-rw-r--r--src/input/key.zig21
-rw-r--r--src/termio/Exec.zig2
6 files changed, 199 insertions, 5 deletions
diff --git a/include/ghostty.h b/include/ghostty.h
index 5bf1fd588..c7d65e4b0 100644
--- a/include/ghostty.h
+++ b/include/ghostty.h
@@ -14,8 +14,19 @@ extern "C" {
#include <stdint.h>
+//-------------------------------------------------------------------
+// Macros
+
#define GHOSTTY_SUCCESS 0
+// Masks for input modifiers
+#define GHOSTTY_INPUT_SHIFT 1
+#define GHOSTTY_INPUT_CTRL 2
+#define GHOSTTY_INPUT_ALT 4
+#define GHOSTTY_INPUT_SUPER 8
+#define GHOSTTY_INPUT_CAPS 16
+#define GHOSTTY_INPUT_NUM 32
+
//-------------------------------------------------------------------
// Types
@@ -23,15 +34,153 @@ extern "C" {
// structs. To find the Zig struct, grep for this type name. The documentation
// for all of these types is available in the Zig source.
typedef void (*ghostty_runtime_wakeup_cb)(void *);
+
typedef struct {
void *userdata;
ghostty_runtime_wakeup_cb wakeup_cb;
} ghostty_runtime_config_s;
+
typedef struct {
void *nsview;
double scale_factor;
} ghostty_surface_config_s;
+typedef enum { release, press, repeat } ghostty_input_action_e;
+typedef enum {
+ invalid,
+
+ // a-z
+ a,
+ b,
+ c,
+ d,
+ e,
+ f,
+ g,
+ h,
+ i,
+ j,
+ k,
+ l,
+ m,
+ n,
+ o,
+ p,
+ q,
+ r,
+ s,
+ t,
+ u,
+ v,
+ w,
+ x,
+ y,
+ z,
+
+ // numbers
+ zero,
+ one,
+ two,
+ three,
+ four,
+ five,
+ six,
+ seven,
+ eight,
+ nine,
+
+ // puncuation
+ semicolon,
+ space,
+ apostrophe,
+ comma,
+ grave_accent, // `
+ period,
+ slash,
+ minus,
+ equal,
+ left_bracket, // [
+ right_bracket, // ]
+ backslash, // /
+
+ // control
+ up,
+ down,
+ right,
+ left,
+ home,
+ end,
+ insert,
+ delete,
+ caps_lock,
+ scroll_lock,
+ num_lock,
+ page_up,
+ page_down,
+ escape,
+ enter,
+ tab,
+ backspace,
+ print_screen,
+ pause,
+
+ // function keys
+ f1,
+ f2,
+ f3,
+ f4,
+ f5,
+ f6,
+ f7,
+ f8,
+ f9,
+ f10,
+ f11,
+ f12,
+ f13,
+ f14,
+ f15,
+ f16,
+ f17,
+ f18,
+ f19,
+ f20,
+ f21,
+ f22,
+ f23,
+ f24,
+ f25,
+
+ // keypad
+ kp_0,
+ kp_1,
+ kp_2,
+ kp_3,
+ kp_4,
+ kp_5,
+ kp_6,
+ kp_7,
+ kp_8,
+ kp_9,
+ kp_decimal,
+ kp_divide,
+ kp_multiply,
+ kp_subtract,
+ kp_add,
+ kp_enter,
+ kp_equal,
+
+ // modifiers
+ left_shift,
+ left_control,
+ left_alt,
+ left_super,
+ right_shift,
+ right_control,
+ right_alt,
+ right_super,
+} ghostty_input_key_e;
+
// Opaque types
typedef void *ghostty_app_t;
typedef void *ghostty_config_t;
@@ -56,6 +205,7 @@ void ghostty_surface_free(ghostty_surface_t);
void ghostty_surface_refresh(ghostty_surface_t);
void ghostty_surface_set_content_scale(ghostty_surface_t, double, double);
void ghostty_surface_set_size(ghostty_surface_t, uint32_t, uint32_t);
+void ghostty_surface_key(ghostty_surface_t, ghostty_input_action_e, ghostty_input_key_e, uint8_t);
#ifdef __cplusplus
}
diff --git a/macos/Sources/TerminalSurfaceView.swift b/macos/Sources/TerminalSurfaceView.swift
index 822c2beff..f8c51a860 100644
--- a/macos/Sources/TerminalSurfaceView.swift
+++ b/macos/Sources/TerminalSurfaceView.swift
@@ -96,6 +96,13 @@ class TerminalSurfaceView_Real: NSView, ObservableObject {
override func keyDown(with event: NSEvent) {
print("Key down: \(event)")
+
+ if let surface = self.surface {
+ if (event.keyCode == 36) {
+ ghostty_surface_key(surface, press, enter, 0)
+ }
+ }
+
self.interpretKeyEvents([event])
}
diff --git a/src/App.zig b/src/App.zig
index 71793666c..e28f3b76e 100644
--- a/src/App.zig
+++ b/src/App.zig
@@ -11,6 +11,7 @@ const build_config = @import("build_config.zig");
const apprt = @import("apprt.zig");
const Window = @import("Window.zig");
const tracy = @import("tracy");
+const input = @import("input.zig");
const Config = @import("config.zig").Config;
const BlockingQueue = @import("./blocking_queue.zig").BlockingQueue;
const renderer = @import("renderer.zig");
@@ -412,4 +413,14 @@ pub const CAPI = struct {
export fn ghostty_surface_set_content_scale(win: *Window, x: f64, y: f64) void {
win.window.updateContentScale(x, y);
}
+
+ /// Tell the surface that it needs to schedule a render
+ export fn ghostty_surface_key(
+ win: *Window,
+ action: input.Action,
+ key: input.Key,
+ mods: input.Mods,
+ ) void {
+ win.window.keyCallback(action, key, mods);
+ }
};
diff --git a/src/apprt/embedded.zig b/src/apprt/embedded.zig
index d53b4a80d..0cb101b0e 100644
--- a/src/apprt/embedded.zig
+++ b/src/apprt/embedded.zig
@@ -10,6 +10,7 @@ const assert = std.debug.assert;
const Allocator = std.mem.Allocator;
const objc = @import("objc");
const apprt = @import("../apprt.zig");
+const input = @import("../input.zig");
const CoreApp = @import("../App.zig");
const CoreWindow = @import("../Window.zig");
@@ -143,4 +144,16 @@ pub const Window = struct {
return;
};
}
+
+ pub fn keyCallback(
+ self: *const Window,
+ action: input.Action,
+ key: input.Key,
+ mods: input.Mods,
+ ) void {
+ self.core_win.keyCallback(action, key, mods) catch |err| {
+ log.err("error in key callback err={}", .{err});
+ return;
+ };
+ }
};
diff --git a/src/input/key.zig b/src/input/key.zig
index 78b5175da..6892fc72a 100644
--- a/src/input/key.zig
+++ b/src/input/key.zig
@@ -3,7 +3,7 @@ const Allocator = std.mem.Allocator;
/// A bitmask for all key modifiers. This is taken directly from the
/// GLFW representation, but we use this generically.
-pub const Mods = packed struct {
+pub const Mods = packed struct(u8) {
shift: bool = false,
ctrl: bool = false,
alt: bool = false,
@@ -11,10 +11,21 @@ pub const Mods = packed struct {
caps_lock: bool = false,
num_lock: bool = false,
_padding: u2 = 0,
+
+ // For our own understanding
+ test {
+ const testing = std.testing;
+ try testing.expectEqual(@bitCast(u8, Mods{}), @as(u8, 0b0));
+ try testing.expectEqual(
+ @bitCast(u8, Mods{ .shift = true }),
+ @as(u8, 0b0000_0001),
+ );
+ }
};
-/// The action associated with an input event.
-pub const Action = enum {
+/// The action associated with an input event. This is backed by a c_int
+/// so that we can use the enum as-is for our embedding API.
+pub const Action = enum(c_int) {
release,
press,
repeat,
@@ -25,7 +36,9 @@ pub const Action = enum {
/// this only needs to accomodate what maps to a key. If a key is not bound
/// to anything and the key can be mapped to a printable character, then that
/// unicode character is sent directly to the pty.
-pub const Key = enum {
+///
+/// This is backed by a c_int so we can use this as-is for our embedding API.
+pub const Key = enum(c_int) {
invalid,
// a-z
diff --git a/src/termio/Exec.zig b/src/termio/Exec.zig
index c6e382750..d4fc39abb 100644
--- a/src/termio/Exec.zig
+++ b/src/termio/Exec.zig
@@ -529,7 +529,7 @@ const ReadThread = struct {
return;
};
- // log.info("DATA: {d}", .{n});
+ log.info("DATA: {d}", .{n});
@call(.always_inline, process, .{ ev, buf[0..n] });
}
}