summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--CONTRIBUTING.md15
-rw-r--r--docs/api-policy.md4
-rw-r--r--docs/getting-started.md6
-rw-r--r--docs/guide.md20
-rw-r--r--docs/migrating.md19
-rw-r--r--examples/game.c2
-rw-r--r--examples/hello.c12
-rw-r--r--examples/notepad.c2
-rw-r--r--examples/simple_window.c16
-rw-r--r--examples/tablet.c8
-rw-r--r--include/yasl/native.h5
-rw-r--r--include/yasl/yasl.h25
-rw-r--r--meson.build3
-rw-r--r--src/cocoa/meson.build1
-rw-r--r--src/common/app.c28
-rw-r--r--src/common/backend.c17
-rw-r--r--src/common/backend.h10
-rw-r--r--src/common/keyboard.c399
-rw-r--r--src/common/keyboard.h4
-rw-r--r--src/common/meson.build2
-rw-r--r--src/common/native.c38
-rw-r--r--src/meson.build10
-rw-r--r--src/platform/cocoa/api.h (renamed from src/cocoa/api.h)4
-rw-r--r--src/platform/cocoa/keycodes.h (renamed from src/cocoa/keycodes.h)0
-rw-r--r--src/platform/cocoa/keymap.c128
-rw-r--r--src/platform/cocoa/keymap.h8
-rw-r--r--src/platform/cocoa/meson.build1
-rw-r--r--src/platform/cocoa/window.m (renamed from src/cocoa/window.m)19
-rw-r--r--src/platform/meson.build15
-rw-r--r--src/platform/posix/loop.c (renamed from src/common/loop.c)2
-rw-r--r--src/platform/posix/meson.build3
-rw-r--r--src/platform/posix/yasl_platform_sync.h28
-rw-r--r--src/platform/sync.h10
-rw-r--r--src/platform/wayland/api.h (renamed from src/wayland/api.h)4
-rw-r--r--src/platform/wayland/backend.c (renamed from src/wayland/backend.c)6
-rw-r--r--src/platform/wayland/buffer.c (renamed from src/wayland/buffer.c)0
-rw-r--r--src/platform/wayland/clipboard.c (renamed from src/wayland/clipboard.c)0
-rw-r--r--src/platform/wayland/clipboard.h (renamed from src/wayland/clipboard.h)0
-rw-r--r--src/platform/wayland/drag.c (renamed from src/wayland/drag.c)0
-rw-r--r--src/platform/wayland/ime.c (renamed from src/wayland/ime.c)0
-rw-r--r--src/platform/wayland/internal.h (renamed from src/wayland/internal.h)2
-rw-r--r--src/platform/wayland/keyboard.c (renamed from src/wayland/keyboard.c)1
-rw-r--r--src/platform/wayland/keymap.c136
-rw-r--r--src/platform/wayland/keymap.h8
-rw-r--r--src/platform/wayland/meson.build (renamed from src/wayland/meson.build)2
-rw-r--r--src/platform/wayland/native.c14
-rw-r--r--src/platform/wayland/pointer.c (renamed from src/wayland/pointer.c)0
-rw-r--r--src/platform/wayland/popup.c (renamed from src/wayland/popup.c)0
-rw-r--r--src/platform/wayland/protocols/commit-timing-v1-client-protocol.h (renamed from src/wayland/protocols/commit-timing-v1-client-protocol.h)0
-rw-r--r--src/platform/wayland/protocols/commit-timing-v1-protocol.c (renamed from src/wayland/protocols/commit-timing-v1-protocol.c)0
-rw-r--r--src/platform/wayland/protocols/cursor-shape-v1-client-protocol.h (renamed from src/wayland/protocols/cursor-shape-v1-client-protocol.h)0
-rw-r--r--src/platform/wayland/protocols/cursor-shape-v1-protocol.c (renamed from src/wayland/protocols/cursor-shape-v1-protocol.c)0
-rw-r--r--src/platform/wayland/protocols/fifo-v1-client-protocol.h (renamed from src/wayland/protocols/fifo-v1-client-protocol.h)0
-rw-r--r--src/platform/wayland/protocols/fifo-v1-protocol.c (renamed from src/wayland/protocols/fifo-v1-protocol.c)0
-rw-r--r--src/platform/wayland/protocols/fractional-scale-v1-client-protocol.h (renamed from src/wayland/protocols/fractional-scale-v1-client-protocol.h)0
-rw-r--r--src/platform/wayland/protocols/fractional-scale-v1-protocol.c (renamed from src/wayland/protocols/fractional-scale-v1-protocol.c)0
-rw-r--r--src/platform/wayland/protocols/meson.build (renamed from src/wayland/protocols/meson.build)0
-rw-r--r--src/platform/wayland/protocols/presentation-time-client-protocol.h (renamed from src/wayland/protocols/presentation-time-client-protocol.h)0
-rw-r--r--src/platform/wayland/protocols/presentation-time-protocol.c (renamed from src/wayland/protocols/presentation-time-protocol.c)0
-rw-r--r--src/platform/wayland/protocols/primary-selection-unstable-v1-client-protocol.h (renamed from src/wayland/protocols/primary-selection-unstable-v1-client-protocol.h)0
-rw-r--r--src/platform/wayland/protocols/primary-selection-unstable-v1-protocol.c (renamed from src/wayland/protocols/primary-selection-unstable-v1-protocol.c)0
-rw-r--r--src/platform/wayland/protocols/tablet-v2-client-protocol.h (renamed from src/wayland/protocols/tablet-v2-client-protocol.h)0
-rw-r--r--src/platform/wayland/protocols/tablet-v2-protocol.c (renamed from src/wayland/protocols/tablet-v2-protocol.c)0
-rw-r--r--src/platform/wayland/protocols/tearing-control-v1-client-protocol.h (renamed from src/wayland/protocols/tearing-control-v1-client-protocol.h)0
-rw-r--r--src/platform/wayland/protocols/tearing-control-v1-protocol.c (renamed from src/wayland/protocols/tearing-control-v1-protocol.c)0
-rw-r--r--src/platform/wayland/protocols/text-input-unstable-v3-client-protocol.h (renamed from src/wayland/protocols/text-input-unstable-v3-client-protocol.h)0
-rw-r--r--src/platform/wayland/protocols/text-input-unstable-v3-protocol.c (renamed from src/wayland/protocols/text-input-unstable-v3-protocol.c)0
-rw-r--r--src/platform/wayland/protocols/viewporter-client-protocol.h (renamed from src/wayland/protocols/viewporter-client-protocol.h)0
-rw-r--r--src/platform/wayland/protocols/viewporter-protocol.c (renamed from src/wayland/protocols/viewporter-protocol.c)0
-rw-r--r--src/platform/wayland/protocols/xdg-decoration-client-protocol.h (renamed from src/wayland/protocols/xdg-decoration-client-protocol.h)0
-rw-r--r--src/platform/wayland/protocols/xdg-decoration-protocol.c (renamed from src/wayland/protocols/xdg-decoration-protocol.c)0
-rw-r--r--src/platform/wayland/protocols/xdg-shell-client-protocol.h (renamed from src/wayland/protocols/xdg-shell-client-protocol.h)0
-rw-r--r--src/platform/wayland/protocols/xdg-shell-protocol.c (renamed from src/wayland/protocols/xdg-shell-protocol.c)0
-rw-r--r--src/platform/wayland/protocols/xdg-toplevel-drag-v1-client-protocol.h (renamed from src/wayland/protocols/xdg-toplevel-drag-v1-client-protocol.h)0
-rw-r--r--src/platform/wayland/protocols/xdg-toplevel-drag-v1-protocol.c (renamed from src/wayland/protocols/xdg-toplevel-drag-v1-protocol.c)0
-rw-r--r--src/platform/wayland/shell.c (renamed from src/wayland/shell.c)0
-rw-r--r--src/platform/wayland/surface.c (renamed from src/wayland/surface.c)10
-rw-r--r--src/platform/x11/keymap.c137
-rw-r--r--src/platform/x11/keymap.h8
-rw-r--r--src/platform/x11/meson.build1
-rw-r--r--src/platform/x11/native.c14
-rw-r--r--src/platform/x11/window.c (renamed from src/x11/window.c)9
-rw-r--r--src/x11/meson.build1
-rw-r--r--tests/benchmark.c16
-rw-r--r--tests/cocoa/test_cursor.m2
-rw-r--r--tests/cocoa/test_keyboard.m2
-rw-r--r--tests/cocoa/test_native.c9
-rw-r--r--tests/cocoa/test_ownership.m2
-rw-r--r--tests/cocoa/test_tablet.m2
-rw-r--r--tests/common/test_app.c2
-rw-r--r--tests/common/test_backends.c29
-rw-r--r--tests/common/test_contracts.c12
-rw-r--r--tests/common/test_keyboard.c5
-rw-r--r--tests/common/test_timers.c2
-rw-r--r--tests/meson.build14
-rw-r--r--tests/test_api.cpp8
-rw-r--r--tests/test_lifecycle.c2
-rw-r--r--tests/wayland/test_app_input.c4
-rw-r--r--tests/wayland/test_clipboard.c2
-rw-r--r--tests/wayland/test_cursor.c4
-rw-r--r--tests/wayland/test_input.c2
-rw-r--r--tests/wayland/test_keyboard.c2
-rw-r--r--tests/wayland/test_tablet.c2
-rw-r--r--tests/x11/test_input.c4
-rw-r--r--tests/x11/test_tablet.c6
-rw-r--r--tests/x11/test_tablet_native.c4
-rw-r--r--yasl-gaps-report.md12
107 files changed, 780 insertions, 586 deletions
diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md
index 88674ca..939f4e4 100644
--- a/CONTRIBUTING.md
+++ b/CONTRIBUTING.md
@@ -5,6 +5,21 @@ Read the [API policy](docs/api-policy.md) and [application guide](docs/guide.md)
before changing public behavior. Keep backend details in native extensions and
make common operations usable through the portable headers.
+Shared API behavior and backend interfaces live in `src/common/`. Native
+windowing implementations, key mappings, and typed native accessors live in
+`src/platform/<backend>/`; keep their generated protocols with the backend.
+OS support shared by multiple backends lives separately in `src/platform/posix/`
+and is selected by `src/platform/meson.build`. It currently supplies the event
+loop and the private mutex implementation used through `platform/sync.h`.
+Common code should depend on these internal interfaces rather than native OS
+headers. Keep public headers in `include/yasl/` and tests in `tests/<backend>/`.
+
+For a future Win32 backend, add `src/platform/win32/`, select its event loop and
+`yasl_platform_sync.h` in the platform build, and register its backend through
+the common dispatch interface. Windows still needs build/dependency selection,
+public API/export support, and ports of POSIX-based examples and test harnesses;
+the directory structure alone does not provide Windows support.
+
For a bug report, include the revision, operating system, selected backend from
`yasl_display_backend()`, capability mask, compiler, build options, reproduction
steps, and a small example if possible. For input issues include the relevant
diff --git a/docs/api-policy.md b/docs/api-policy.md
index d5c7159..0c8f040 100644
--- a/docs/api-policy.md
+++ b/docs/api-policy.md
@@ -12,8 +12,8 @@ across releases, mix headers and binaries from different revisions, or persist
public structs as a file/network format. The package version is available through
`pkg-config --modversion yasl`.
-See [migration notes](migrating.md) for the portable keyboard and fractional
-scroll API changes.
+See [migration notes](migrating.md) for window creation, portable keyboard, and
+fractional scroll API changes.
API changes should keep ordinary CPU drawing usable with only `<yasl/yasl.h>`
and the C standard library. Prefer an explicit capability and an ordinary
diff --git a/docs/getting-started.md b/docs/getting-started.md
index ff40a9b..d21c9bd 100644
--- a/docs/getting-started.md
+++ b/docs/getting-started.md
@@ -78,9 +78,11 @@ can be included from C++11 or newer; the library itself builds as C23.
1. Open a display with `yasl_display_open(NULL, &spec)`. NULL creates a loop owned
by the display. Supply your own loop only when you need shared loop ownership.
-2. Create a toplevel with a positive **logical-pixel** size and install callbacks.
+2. Create a toplevel with `yasl_window_spec`: supply a positive **logical-pixel**
+ size, a `yasl_window_cbs` table in `cbs`, and callback userdata in `ud`.
Zero-initialize every option and callback struct. Callback tables are copied;
- userdata must remain alive. Registration can call back synchronously.
+ userdata must remain alive. The new window's callbacks start after creation
+ returns. Read initial geometry with `yasl_surface_geometry()`.
3. Schedule the initial redraw. `draw` receives a borrowed target. Fill every
pixel with premultiplied `0xAARRGGBB`, then present that exact target, once.
4. Dispatch, drain input for every live surface queue, update application state,
diff --git a/docs/guide.md b/docs/guide.md
index 43a7a1e..adcacc8 100644
--- a/docs/guide.md
+++ b/docs/guide.md
@@ -37,11 +37,29 @@ server. A capability does not guarantee every related action: Cocoa currently
returns false for interactive resize and window-menu requests even though
it advertises CSD. Check each result and provide an application fallback.
+## Window creation and callbacks
+
+Open the display with application-wide options and notifications in
+`yasl_display_spec`. Create each toplevel with `yasl_window_spec`, including its
+title, logical size, optional `yasl_window_cbs` table in `cbs`, and userdata in
+`ud`. One display can own multiple windows with separate callback tables.
+
+The window copies its callbacks during creation. Its callbacks cannot run before
+creation returns, so the application can store the returned surface first.
+Userdata stays borrowed until callbacks are replaced or the surface is destroyed.
+Read initial geometry with `yasl_surface_geometry()`; creation does not guarantee
+an initial `configure` notification. Request the first redraw once application
+state is ready. `yasl_surface_set_callbacks()` replaces callbacks later and also
+installs popup callbacks; the setter does not invoke the callbacks.
+
+When using `yasl_run()`, its runner installs callbacks for windows on its display.
+Use `yasl_app_desc.event` and `.frame` rather than `yasl_window_spec.cbs` and `.ud`.
+
## Geometry and scaling
| Value | Units |
| --- | --- |
-| Toplevel `yasl_surface_spec.size` | Logical pixels |
+| Toplevel `yasl_window_spec.size` | Logical pixels |
| `yasl_geometry.size`, framebuffer size | Device pixels |
| Pointer position, caret, window-menu position | Device pixels, relative to the surface |
| Damage rectangles | Device pixels, relative to the draw target |
diff --git a/docs/migrating.md b/docs/migrating.md
index d224cd4..da4e591 100644
--- a/docs/migrating.md
+++ b/docs/migrating.md
@@ -2,8 +2,23 @@
YASL 0.1 has no stable source or binary compatibility promise. Rebuild all
consumers against the matching installed headers and library after updating.
-The following changes replace backend-specific input fields with a common
-contract. See the [application guide](guide.md) for the full input workflow.
+See the [application guide](guide.md) for the full window and input workflow.
+
+## Window creation
+
+Rename `struct yasl_surface_spec` to `struct yasl_window_spec` and
+`struct yasl_surface_cbs` to `struct yasl_window_cbs`. Surface handles and
+functions retain their names. Supply the window's callback table in `spec.cbs`
+and its userdata in `spec.ud` when calling `yasl_surface_create_toplevel()` or
+`yasl_surface_create_native()`. Callback tables are copied, and userdata is
+borrowed. The new window's callbacks cannot run before creation returns; read
+initial geometry with `yasl_surface_geometry()` and request the first redraw
+after initializing application state.
+
+`yasl_surface_set_callbacks()` remains available to replace callbacks after
+creation and to configure popups. A NULL `spec.cbs` creates a window without
+callbacks. Displays owned by `yasl_run()` use the runner's callbacks instead;
+provide application notifications through `yasl_app_desc.event` and `.frame`.
## Keyboard events
diff --git a/examples/game.c b/examples/game.c
index bb6c729..7ec28e1 100644
--- a/examples/game.c
+++ b/examples/game.c
@@ -145,7 +145,7 @@ static int on_init(void *ud, struct yasl_display *d)
struct game_state *game = ud;
game->display = d;
- struct yasl_surface_spec spec = {
+ struct yasl_window_spec spec = {
.title = "YASL 3D Game Loop (Approach A)",
.size = {800, 600},
};
diff --git a/examples/hello.c b/examples/hello.c
index 67ac88b..0c474c2 100644
--- a/examples/hello.c
+++ b/examples/hello.c
@@ -72,17 +72,19 @@ int main(int argc, char **argv)
perror("yasl_display_open");
return 1;
}
- struct yasl_surface_spec spec = {.title = "Hello YASL", .size = {640, 480}};
+ struct yasl_window_cbs callbacks = {
+ .draw = draw, .configure = configure, .close = close_window,
+ };
+ struct yasl_window_spec spec = {
+ .title = "Hello YASL", .size = {640, 480},
+ .cbs = &callbacks, .ud = &app,
+ };
struct yasl_surface *surface = yasl_surface_create_toplevel(display, &spec);
if (!surface) {
perror("yasl_surface_create_toplevel");
yasl_display_close(display);
return 1;
}
- struct yasl_surface_cbs callbacks = {
- .draw = draw, .configure = configure, .close = close_window,
- };
- yasl_surface_set_callbacks(surface, &callbacks, &app);
yasl_surface_schedule_redraw(surface);
while (app.running) {
diff --git a/examples/notepad.c b/examples/notepad.c
index beb7051..6fb90e9 100644
--- a/examples/notepad.c
+++ b/examples/notepad.c
@@ -995,7 +995,7 @@ static int on_init(void *ud, struct yasl_display *d)
struct editor *ed = ud;
ed->display = d;
- struct yasl_surface_spec spec = {
+ struct yasl_window_spec spec = {
.title = "Untitled - YASL Notepad",
.size = {960, 640},
};
diff --git a/examples/simple_window.c b/examples/simple_window.c
index 85db04a..797de3b 100644
--- a/examples/simple_window.c
+++ b/examples/simple_window.c
@@ -120,23 +120,23 @@ int main(void)
return 1;
}
- struct yasl_surface_spec surf_spec = {
+ struct yasl_window_cbs window_cbs = {
+ .draw = on_draw,
+ .configure = on_configure,
+ .close = on_close,
+ };
+ struct yasl_window_spec window_spec = {
.title = "YASL Interactive Window (Pen & Touch Enabled)",
.size = { .x = 640, .y = 480 },
+ .cbs = &window_cbs,
};
- struct yasl_surface *s = yasl_surface_create_toplevel(d, &surf_spec);
+ struct yasl_surface *s = yasl_surface_create_toplevel(d, &window_spec);
if (!s) {
fprintf(stderr, "Failed to create surface\n");
yasl_display_close(d);
return 1;
}
- struct yasl_surface_cbs surf_cbs = {
- .draw = on_draw,
- .configure = on_configure,
- .close = on_close,
- };
- yasl_surface_set_callbacks(s, &surf_cbs, NULL);
yasl_surface_schedule_redraw(s);
printf("=== YASL Demo Running ===\n");
diff --git a/examples/tablet.c b/examples/tablet.c
index 0aae370..256d8f8 100644
--- a/examples/tablet.c
+++ b/examples/tablet.c
@@ -327,11 +327,13 @@ int main(int argc, char **argv)
if (!display) { perror("Cannot open display"); return 1; }
app.backend = yasl_display_backend(display);
app.tablet_supported = (yasl_display_caps(display) & YASL_CAP_TABLET) != 0;
- struct yasl_surface_spec spec = {.title = "YASL Tablet - pressure and tilt", .size = {900, 640}};
+ struct yasl_window_cbs callbacks = {.draw = draw, .configure = configure, .close = close_window};
+ struct yasl_window_spec spec = {
+ .title = "YASL Tablet - pressure and tilt", .size = {900, 640},
+ .cbs = &callbacks, .ud = &app,
+ };
struct yasl_surface *surface = yasl_surface_create_toplevel(display, &spec);
if (!surface) { perror("Cannot create surface"); yasl_display_close(display); return 1; }
- struct yasl_surface_cbs callbacks = {.draw = draw, .configure = configure, .close = close_window};
- yasl_surface_set_callbacks(surface, &callbacks, &app);
yasl_surface_set_cursor(surface, YASL_CURSOR_HIDDEN);
yasl_surface_schedule_redraw(surface);
printf("YASL tablet on %s: pressure changes brush width; eraser removes ink.\n"
diff --git a/include/yasl/native.h b/include/yasl/native.h
index d65f8d3..64bc161 100644
--- a/include/yasl/native.h
+++ b/include/yasl/native.h
@@ -48,15 +48,16 @@ YASL_API void *yasl_surface_get_native_handle(struct yasl_surface *s);
/**
* Create a toplevel for application-managed native rendering.
* @param d Display with YASL_CAP_NATIVE_GRAPHICS.
- * @param spec Copied toplevel options, with logical-pixel size.
+ * @param spec Copied window options, with logical-pixel size and optional callbacks.
* @param graphics_device Required native graphics device; currently id<MTLDevice> on Cocoa.
* @return Owned surface, or NULL with errno set: EINVAL for invalid arguments,
* ENOTSUP for an unsupported backend, or a backend error.
* Cocoa retains the device. Query the drawable during draw, submit/present it,
* then call yasl_surface_present() to record submission.
+ * Callback ownership and timing follow yasl_surface_create_toplevel().
*/
YASL_API struct yasl_surface *yasl_surface_create_native(struct yasl_display *d,
- const struct yasl_surface_spec *spec, void *graphics_device);
+ const struct yasl_window_spec *spec, void *graphics_device);
/** Borrowed native drawable for the current draw target, currently Cocoa/Metal. */
struct yasl_native_frame {
diff --git a/include/yasl/yasl.h b/include/yasl/yasl.h
index f40264e..e2c1d77 100644
--- a/include/yasl/yasl.h
+++ b/include/yasl/yasl.h
@@ -437,10 +437,11 @@ struct yasl_display_cbs {
void (*lost)(void *ud);
};
-/** Optional surface notifications, copied by yasl_surface_set_callbacks().
+/** Optional window/popup notifications, copied from yasl_window_spec.cbs or by
+yasl_surface_set_callbacks().
Callbacks may destroy their surface. They must then return without further use
of the surface or draw target. NULL members are ignored. */
-struct yasl_surface_cbs {
+struct yasl_window_cbs {
/** Initialize the entire target and optionally present. Requested through schedule_redraw/flush. */
void (*draw)(struct yasl_surface *s, struct yasl_frame *frame, void *ud);
/** Configured size/scale changed; reallocate application content and request a redraw. */
@@ -586,7 +587,7 @@ YASL_API void yasl_display_drag_cancel(struct yasl_display *d);
/* Surface Lifecycle */
/** Toplevel options. Zero-initialize, then supply a positive logical-pixel size. */
-struct yasl_surface_spec {
+struct yasl_window_spec {
/** Copied UTF-8 title; NULL uses backend defaults. */
const char *title;
/** Requested logical-pixel width and height; both must be positive. */
@@ -595,6 +596,10 @@ struct yasl_surface_spec {
bool fullscreen;
/** Permit unpaced presentation where supported; a hint, not a guarantee. */
bool tearing;
+ /** Copied optional window callbacks; NULL disables them. */
+ const struct yasl_window_cbs *cbs;
+ /** Borrowed window callback userdata. */
+ void *ud;
};
/** Popup options, entirely in device pixels, including size.
@@ -623,10 +628,16 @@ struct yasl_popup_spec {
* @return An owned surface, or NULL with errno set. EINVAL means invalid options,
* including a nonpositive dimension, a dimension above 32767, or a buffer above
* INT32_MAX bytes. ENODEV is the fallback backend failure. Actual configured
- * size may differ from the request. Install callbacks and schedule a redraw.
+ * size may differ from the request. The callback table in spec->cbs is copied;
+ * spec->ud stays borrowed until callbacks are replaced or the surface is destroyed.
+ * This window's callbacks cannot run before creation returns. Use
+ * yasl_surface_geometry() for initial geometry; an initial configure callback
+ * is not guaranteed. Schedule an initial redraw after setting up application state.
+ * On a display owned by yasl_run(), the runner installs its own callbacks instead;
+ * use yasl_app_desc.event and yasl_app_desc.frame for application notifications.
*/
YASL_API struct yasl_surface *yasl_surface_create_toplevel(struct yasl_display *d,
- const struct yasl_surface_spec *spec);
+ const struct yasl_window_spec *spec);
/**
* Create an owned popup attached to a parent surface.
* @param parent Borrowed parent; destroy the popup before the parent.
@@ -668,12 +679,12 @@ YASL_API struct yasl_display *yasl_surface_display(const struct yasl_surface *s)
* @param s Surface, or NULL for no action.
* @param cbs Table copied by value; NULL removes all callbacks. NULL members are ignored.
* @param ud Borrowed userdata passed to the installed callbacks.
- * Callbacks may run synchronously during this call; initialize userdata first.
+ * This call only replaces callbacks; it does not invoke them.
* Use yasl_surface_geometry() to read current geometry; do not rely on receiving
* an initial configure callback when registering.
*/
YASL_API void yasl_surface_set_callbacks(struct yasl_surface *s,
- const struct yasl_surface_cbs *cbs, void *ud);
+ const struct yasl_window_cbs *cbs, void *ud);
/**
* Replace the window title with copied UTF-8 text.
* @param s Surface.
diff --git a/meson.build b/meson.build
index b1fce24..201de74 100644
--- a/meson.build
+++ b/meson.build
@@ -40,10 +40,9 @@ if system == 'linux'
add_project_arguments('-DYASL_HAS_XRANDR=1', language: 'c')
endif
endif
- threads = dependency('threads')
m_dep = cc.find_library('m', required: false)
rt_dep = cc.find_library('rt', required: false)
- deps += [threads, m_dep, rt_dep]
+ deps += [m_dep, rt_dep]
if has_wayland
deps += [wl_client, wl_cursor, xkbcommon]
endif
diff --git a/src/cocoa/meson.build b/src/cocoa/meson.build
deleted file mode 100644
index 0bd40a3..0000000
--- a/src/cocoa/meson.build
+++ /dev/null
@@ -1 +0,0 @@
-sources += files('window.m')
diff --git a/src/common/app.c b/src/common/app.c
index 1916c5b..da9747d 100644
--- a/src/common/app.c
+++ b/src/common/app.c
@@ -1,8 +1,9 @@
#include "yasl/app.h"
#include "common/app_internal.h"
#include "common/backend.h"
+#include "platform/sync.h"
-#include <pthread.h>
+#include <errno.h>
#include <stdlib.h>
#include <string.h>
@@ -38,7 +39,7 @@ struct app_runner {
int surface_count;
struct app_surface *surfaces;
- pthread_mutex_t user_event_mutex;
+ yasl_mutex user_event_mutex;
struct user_event_node *user_event_head;
struct user_event_node *user_event_tail;
};
@@ -158,7 +159,7 @@ void app_runner_register_surface(void *runner, struct yasl_surface *s)
ar->surface_count++;
ar->had_surfaces = true;
- struct yasl_surface_cbs cbs = {
+ struct yasl_window_cbs cbs = {
.draw = app_runner_surface_draw,
.configure = app_runner_surface_configure,
.close = app_runner_surface_close,
@@ -264,7 +265,7 @@ bool yasl_post_event(struct yasl_display *d, struct yasl_surface *s,
node->size = size;
node->next = NULL;
- pthread_mutex_lock(&ar->user_event_mutex);
+ yasl_mutex_lock(&ar->user_event_mutex);
if (ar->user_event_tail) {
ar->user_event_tail->next = node;
ar->user_event_tail = node;
@@ -272,7 +273,7 @@ bool yasl_post_event(struct yasl_display *d, struct yasl_surface *s,
ar->user_event_head = node;
ar->user_event_tail = node;
}
- pthread_mutex_unlock(&ar->user_event_mutex);
+ yasl_mutex_unlock(&ar->user_event_mutex);
if (d->loop) {
yasl_loop_kick(d->loop);
@@ -312,11 +313,11 @@ void yasl_app_del_timer(struct yasl_display *d, yasl_timer_id id)
static void app_runner_dispatch_user_events(struct app_runner *ar)
{
- pthread_mutex_lock(&ar->user_event_mutex);
+ yasl_mutex_lock(&ar->user_event_mutex);
struct user_event_node *node = ar->user_event_head;
ar->user_event_head = NULL;
ar->user_event_tail = NULL;
- pthread_mutex_unlock(&ar->user_event_mutex);
+ yasl_mutex_unlock(&ar->user_event_mutex);
while (node && ar->running) {
struct user_event_node *next = node->next;
@@ -467,7 +468,12 @@ int yasl_run(const struct yasl_app_desc *desc)
.surface_count = 0,
.surfaces = NULL,
};
- pthread_mutex_init(&runner.user_event_mutex, NULL);
+ int sync_error = yasl_mutex_init(&runner.user_event_mutex);
+ if (sync_error) {
+ yasl_display_close(d);
+ errno = sync_error;
+ return -1;
+ }
d->app_runner = &runner;
if (desc->init(desc->userdata, d) == YASL_APP_QUIT) {
@@ -529,15 +535,15 @@ int yasl_run(const struct yasl_app_desc *desc)
d->app_runner = NULL;
- pthread_mutex_lock(&runner.user_event_mutex);
+ yasl_mutex_lock(&runner.user_event_mutex);
struct user_event_node *node = runner.user_event_head;
while (node) {
struct user_event_node *next = node->next;
free(node);
node = next;
}
- pthread_mutex_unlock(&runner.user_event_mutex);
- pthread_mutex_destroy(&runner.user_event_mutex);
+ yasl_mutex_unlock(&runner.user_event_mutex);
+ yasl_mutex_destroy(&runner.user_event_mutex);
yasl_display_close(d);
return 0;
diff --git a/src/common/backend.c b/src/common/backend.c
index e690697..be06136 100644
--- a/src/common/backend.c
+++ b/src/common/backend.c
@@ -152,7 +152,7 @@ void yasl_display_drag_cancel(struct yasl_display *d)
}
struct yasl_surface *yasl_create_toplevel(struct yasl_display *d,
- const struct yasl_surface_spec *spec, void *graphics_device)
+ const struct yasl_window_spec *spec, void *graphics_device)
{
if (!d || !d->ops->surface_create_toplevel || !spec ||
spec->size.x <= 0 || spec->size.y <= 0 ||
@@ -168,14 +168,19 @@ struct yasl_surface *yasl_create_toplevel(struct yasl_display *d,
errno = 0;
struct yasl_surface *s = d->ops->surface_create_toplevel(d, spec, graphics_device);
if (!s && !errno) errno = ENODEV;
- if (s && d->app_runner) {
- app_runner_register_surface(d->app_runner, s);
+ if (s) {
+ /* Native creation may dispatch events. Attach this window's callbacks
+ * only after it finishes, so callers can store the returned surface. */
+ if (d->app_runner)
+ app_runner_register_surface(d->app_runner, s);
+ else
+ yasl_surface_set_callbacks(s, spec->cbs, spec->ud);
}
return s;
}
struct yasl_surface *yasl_surface_create_toplevel(struct yasl_display *d,
- const struct yasl_surface_spec *spec)
+ const struct yasl_window_spec *spec)
{
return yasl_create_toplevel(d, spec, NULL);
}
@@ -246,11 +251,11 @@ struct yasl_display *yasl_surface_display(const struct yasl_surface *s)
return s ? s->display : NULL;
}
-void yasl_surface_set_callbacks(struct yasl_surface *s, const struct yasl_surface_cbs *cbs, void *ud)
+void yasl_surface_set_callbacks(struct yasl_surface *s, const struct yasl_window_cbs *cbs, void *ud)
{
if (!s)
return;
- s->callbacks = cbs ? *cbs : (struct yasl_surface_cbs){0};
+ s->callbacks = cbs ? *cbs : (struct yasl_window_cbs){0};
s->ud = ud;
if (s->display && s->display->ops && s->display->ops->surface_set_callbacks)
s->display->ops->surface_set_callbacks(s, cbs, ud);
diff --git a/src/common/backend.h b/src/common/backend.h
index b93547a..37fa167 100644
--- a/src/common/backend.h
+++ b/src/common/backend.h
@@ -24,7 +24,7 @@ struct yasl_surface {
uint32_t scale_120;
uint32_t state;
uint32_t bg_color;
- struct yasl_surface_cbs callbacks;
+ struct yasl_window_cbs callbacks;
void *ud;
uint64_t frame_generation;
struct input_queue input;
@@ -38,7 +38,7 @@ struct yasl_surface {
void yasl_surface_clear_timers(struct yasl_surface *s);
struct yasl_surface *yasl_create_toplevel(struct yasl_display *d,
- const struct yasl_surface_spec *spec, void *graphics_device);
+ const struct yasl_window_spec *spec, void *graphics_device);
static inline uint64_t yasl_frame_begin(struct yasl_surface *s)
{
@@ -58,13 +58,15 @@ struct yasl_backend_ops {
void (*display_paste)(struct yasl_display *d, enum yasl_selection sel, struct yasl_surface *target);
bool (*display_drag_start)(struct yasl_display *d, struct yasl_surface *origin, const struct yasl_drag_image *image, const struct yasl_drag_listener *l, void *ud);
void (*display_drag_cancel)(struct yasl_display *d);
+ /* Create with callbacks disabled; common code installs them after return. */
struct yasl_surface *(*surface_create_toplevel)(struct yasl_display *d,
- const struct yasl_surface_spec *spec, void *graphics_device);
+ const struct yasl_window_spec *spec, void *graphics_device);
struct yasl_surface *(*surface_create_popup)(struct yasl_surface *parent, const struct yasl_popup_spec *spec);
bool (*surface_popup_reposition)(struct yasl_surface *popup, const struct yasl_popup_spec *spec);
void (*surface_destroy)(struct yasl_surface *s);
struct yasl_display *(*surface_display)(const struct yasl_surface *s);
- void (*surface_set_callbacks)(struct yasl_surface *s, const struct yasl_surface_cbs *cbs, void *ud);
+ /* Copy only; must not invoke application callbacks. */
+ void (*surface_set_callbacks)(struct yasl_surface *s, const struct yasl_window_cbs *cbs, void *ud);
void (*surface_set_title)(struct yasl_surface *s, const char *title);
void (*surface_schedule_redraw)(struct yasl_surface *s);
bool (*surface_present)(struct yasl_surface *s, const struct yasl_framebuffer *fb, const struct yasl_damage_list *damage);
diff --git a/src/common/keyboard.c b/src/common/keyboard.c
deleted file mode 100644
index 80c6702..0000000
--- a/src/common/keyboard.c
+++ /dev/null
@@ -1,399 +0,0 @@
-#include "keyboard.h"
-#include "cocoa/keycodes.h"
-#include <string.h>
-
-/* Numeric Linux evdev codes; no platform headers are needed by this table. */
-enum yasl_key yasl_key_from_evdev(uint32_t code)
-{
- switch (code) {
- case 1: return YASL_KEY_ESCAPE; /* KEY_ESC */
- case 2: return YASL_KEY_1; /* KEY_1 */
- case 3: return YASL_KEY_2; /* KEY_2 */
- case 4: return YASL_KEY_3; /* KEY_3 */
- case 5: return YASL_KEY_4; /* KEY_4 */
- case 6: return YASL_KEY_5; /* KEY_5 */
- case 7: return YASL_KEY_6; /* KEY_6 */
- case 8: return YASL_KEY_7; /* KEY_7 */
- case 9: return YASL_KEY_8; /* KEY_8 */
- case 10: return YASL_KEY_9; /* KEY_9 */
- case 11: return YASL_KEY_0; /* KEY_0 */
- case 12: return YASL_KEY_MINUS; /* KEY_MINUS */
- case 13: return YASL_KEY_EQUAL; /* KEY_EQUAL */
- case 14: return YASL_KEY_BACKSPACE; /* KEY_BACKSPACE */
- case 15: return YASL_KEY_TAB; /* KEY_TAB */
- case 16: return YASL_KEY_Q; /* KEY_Q */
- case 17: return YASL_KEY_W; /* KEY_W */
- case 18: return YASL_KEY_E; /* KEY_E */
- case 19: return YASL_KEY_R; /* KEY_R */
- case 20: return YASL_KEY_T; /* KEY_T */
- case 21: return YASL_KEY_Y; /* KEY_Y */
- case 22: return YASL_KEY_U; /* KEY_U */
- case 23: return YASL_KEY_I; /* KEY_I */
- case 24: return YASL_KEY_O; /* KEY_O */
- case 25: return YASL_KEY_P; /* KEY_P */
- case 26: return YASL_KEY_LEFT_BRACKET; /* KEY_LEFTBRACE */
- case 27: return YASL_KEY_RIGHT_BRACKET; /* KEY_RIGHTBRACE */
- case 28: return YASL_KEY_ENTER; /* KEY_ENTER */
- case 29: return YASL_KEY_LEFT_CONTROL; /* KEY_LEFTCTRL */
- case 30: return YASL_KEY_A; /* KEY_A */
- case 31: return YASL_KEY_S; /* KEY_S */
- case 32: return YASL_KEY_D; /* KEY_D */
- case 33: return YASL_KEY_F; /* KEY_F */
- case 34: return YASL_KEY_G; /* KEY_G */
- case 35: return YASL_KEY_H; /* KEY_H */
- case 36: return YASL_KEY_J; /* KEY_J */
- case 37: return YASL_KEY_K; /* KEY_K */
- case 38: return YASL_KEY_L; /* KEY_L */
- case 39: return YASL_KEY_SEMICOLON; /* KEY_SEMICOLON */
- case 40: return YASL_KEY_APOSTROPHE; /* KEY_APOSTROPHE */
- case 41: return YASL_KEY_GRAVE; /* KEY_GRAVE */
- case 42: return YASL_KEY_LEFT_SHIFT; /* KEY_LEFTSHIFT */
- case 43: return YASL_KEY_BACKSLASH; /* KEY_BACKSLASH */
- case 44: return YASL_KEY_Z; /* KEY_Z */
- case 45: return YASL_KEY_X; /* KEY_X */
- case 46: return YASL_KEY_C; /* KEY_C */
- case 47: return YASL_KEY_V; /* KEY_V */
- case 48: return YASL_KEY_B; /* KEY_B */
- case 49: return YASL_KEY_N; /* KEY_N */
- case 50: return YASL_KEY_M; /* KEY_M */
- case 51: return YASL_KEY_COMMA; /* KEY_COMMA */
- case 52: return YASL_KEY_PERIOD; /* KEY_DOT */
- case 53: return YASL_KEY_SLASH; /* KEY_SLASH */
- case 54: return YASL_KEY_RIGHT_SHIFT; /* KEY_RIGHTSHIFT */
- case 55: return YASL_KEY_KP_MULTIPLY; /* KEY_KPASTERISK */
- case 56: return YASL_KEY_LEFT_ALT; /* KEY_LEFTALT */
- case 57: return YASL_KEY_SPACE; /* KEY_SPACE */
- case 58: return YASL_KEY_CAPS_LOCK; /* KEY_CAPSLOCK */
- case 59: return YASL_KEY_F1; /* KEY_F1 */
- case 60: return YASL_KEY_F2; /* KEY_F2 */
- case 61: return YASL_KEY_F3; /* KEY_F3 */
- case 62: return YASL_KEY_F4; /* KEY_F4 */
- case 63: return YASL_KEY_F5; /* KEY_F5 */
- case 64: return YASL_KEY_F6; /* KEY_F6 */
- case 65: return YASL_KEY_F7; /* KEY_F7 */
- case 66: return YASL_KEY_F8; /* KEY_F8 */
- case 67: return YASL_KEY_F9; /* KEY_F9 */
- case 68: return YASL_KEY_F10; /* KEY_F10 */
- case 69: return YASL_KEY_NUM_LOCK; /* KEY_NUMLOCK */
- case 70: return YASL_KEY_SCROLL_LOCK; /* KEY_SCROLLLOCK */
- case 71: return YASL_KEY_KP_7; /* KEY_KP7 */
- case 72: return YASL_KEY_KP_8; /* KEY_KP8 */
- case 73: return YASL_KEY_KP_9; /* KEY_KP9 */
- case 74: return YASL_KEY_KP_SUBTRACT; /* KEY_KPMINUS */
- case 75: return YASL_KEY_KP_4; /* KEY_KP4 */
- case 76: return YASL_KEY_KP_5; /* KEY_KP5 */
- case 77: return YASL_KEY_KP_6; /* KEY_KP6 */
- case 78: return YASL_KEY_KP_ADD; /* KEY_KPPLUS */
- case 79: return YASL_KEY_KP_1; /* KEY_KP1 */
- case 80: return YASL_KEY_KP_2; /* KEY_KP2 */
- case 81: return YASL_KEY_KP_3; /* KEY_KP3 */
- case 82: return YASL_KEY_KP_0; /* KEY_KP0 */
- case 83: return YASL_KEY_KP_DECIMAL; /* KEY_KPDOT */
- case 86: return YASL_KEY_ISO_BACKSLASH; /* KEY_102ND */
- case 87: return YASL_KEY_F11; /* KEY_F11 */
- case 88: return YASL_KEY_F12; /* KEY_F12 */
- case 89: return YASL_KEY_RO; /* KEY_RO */
- case 92: return YASL_KEY_CONVERT; /* KEY_HENKAN */
- case 93: return YASL_KEY_KANA; /* KEY_KATAKANAHIRAGANA */
- case 94: return YASL_KEY_NONCONVERT; /* KEY_MUHENKAN */
- case 96: return YASL_KEY_KP_ENTER; /* KEY_KPENTER */
- case 97: return YASL_KEY_RIGHT_CONTROL; /* KEY_RIGHTCTRL */
- case 98: return YASL_KEY_KP_DIVIDE; /* KEY_KPSLASH */
- case 99: return YASL_KEY_PRINT_SCREEN; /* KEY_SYSRQ */
- case 100: return YASL_KEY_RIGHT_ALT; /* KEY_RIGHTALT */
- case 102: return YASL_KEY_HOME; /* KEY_HOME */
- case 103: return YASL_KEY_UP; /* KEY_UP */
- case 104: return YASL_KEY_PAGE_UP; /* KEY_PAGEUP */
- case 105: return YASL_KEY_LEFT; /* KEY_LEFT */
- case 106: return YASL_KEY_RIGHT; /* KEY_RIGHT */
- case 107: return YASL_KEY_END; /* KEY_END */
- case 108: return YASL_KEY_DOWN; /* KEY_DOWN */
- case 109: return YASL_KEY_PAGE_DOWN; /* KEY_PAGEDOWN */
- case 110: return YASL_KEY_INSERT; /* KEY_INSERT */
- case 111: return YASL_KEY_DELETE; /* KEY_DELETE */
- case 113: return YASL_KEY_MUTE; /* KEY_MUTE */
- case 114: return YASL_KEY_VOLUME_DOWN; /* KEY_VOLUMEDOWN */
- case 115: return YASL_KEY_VOLUME_UP; /* KEY_VOLUMEUP */
- case 117: return YASL_KEY_KP_EQUAL; /* KEY_KPEQUAL */
- case 119: return YASL_KEY_PAUSE; /* KEY_PAUSE */
- case 121: return YASL_KEY_KP_COMMA; /* KEY_KPCOMMA */
- case 124: return YASL_KEY_YEN; /* KEY_YEN */
- case 125: return YASL_KEY_LEFT_SUPER; /* KEY_LEFTMETA */
- case 126: return YASL_KEY_RIGHT_SUPER; /* KEY_RIGHTMETA */
- case 127: return YASL_KEY_MENU; /* KEY_COMPOSE */
- case 183: return YASL_KEY_F13; /* KEY_F13 */
- case 184: return YASL_KEY_F14; /* KEY_F14 */
- case 185: return YASL_KEY_F15; /* KEY_F15 */
- case 186: return YASL_KEY_F16; /* KEY_F16 */
- case 187: return YASL_KEY_F17; /* KEY_F17 */
- case 188: return YASL_KEY_F18; /* KEY_F18 */
- case 189: return YASL_KEY_F19; /* KEY_F19 */
- case 190: return YASL_KEY_F20; /* KEY_F20 */
- case 191: return YASL_KEY_F21; /* KEY_F21 */
- case 192: return YASL_KEY_F22; /* KEY_F22 */
- case 193: return YASL_KEY_F23; /* KEY_F23 */
- case 194: return YASL_KEY_F24; /* KEY_F24 */
- default: return YASL_KEY_UNKNOWN;
- }
-}
-
-enum yasl_key yasl_key_from_cocoa(uint32_t code)
-{
- switch (code) {
- case kVK_ANSI_A: return YASL_KEY_A;
- case kVK_ANSI_B: return YASL_KEY_B;
- case kVK_ANSI_C: return YASL_KEY_C;
- case kVK_ANSI_D: return YASL_KEY_D;
- case kVK_ANSI_E: return YASL_KEY_E;
- case kVK_ANSI_F: return YASL_KEY_F;
- case kVK_ANSI_G: return YASL_KEY_G;
- case kVK_ANSI_H: return YASL_KEY_H;
- case kVK_ANSI_I: return YASL_KEY_I;
- case kVK_ANSI_J: return YASL_KEY_J;
- case kVK_ANSI_K: return YASL_KEY_K;
- case kVK_ANSI_L: return YASL_KEY_L;
- case kVK_ANSI_M: return YASL_KEY_M;
- case kVK_ANSI_N: return YASL_KEY_N;
- case kVK_ANSI_O: return YASL_KEY_O;
- case kVK_ANSI_P: return YASL_KEY_P;
- case kVK_ANSI_Q: return YASL_KEY_Q;
- case kVK_ANSI_R: return YASL_KEY_R;
- case kVK_ANSI_S: return YASL_KEY_S;
- case kVK_ANSI_T: return YASL_KEY_T;
- case kVK_ANSI_U: return YASL_KEY_U;
- case kVK_ANSI_V: return YASL_KEY_V;
- case kVK_ANSI_W: return YASL_KEY_W;
- case kVK_ANSI_X: return YASL_KEY_X;
- case kVK_ANSI_Y: return YASL_KEY_Y;
- case kVK_ANSI_Z: return YASL_KEY_Z;
- case kVK_ANSI_0: return YASL_KEY_0;
- case kVK_ANSI_1: return YASL_KEY_1;
- case kVK_ANSI_2: return YASL_KEY_2;
- case kVK_ANSI_3: return YASL_KEY_3;
- case kVK_ANSI_4: return YASL_KEY_4;
- case kVK_ANSI_5: return YASL_KEY_5;
- case kVK_ANSI_6: return YASL_KEY_6;
- case kVK_ANSI_7: return YASL_KEY_7;
- case kVK_ANSI_8: return YASL_KEY_8;
- case kVK_ANSI_9: return YASL_KEY_9;
- case kVK_Return: return YASL_KEY_ENTER;
- case kVK_Tab: return YASL_KEY_TAB;
- case kVK_Space: return YASL_KEY_SPACE;
- case kVK_Escape: return YASL_KEY_ESCAPE;
- case kVK_Home: return YASL_KEY_HOME;
- case kVK_End: return YASL_KEY_END;
- case kVK_Delete: return YASL_KEY_BACKSPACE;
- case kVK_ForwardDelete: return YASL_KEY_DELETE;
- case kVK_PageUp: return YASL_KEY_PAGE_UP;
- case kVK_PageDown: return YASL_KEY_PAGE_DOWN;
- case kVK_Help: return YASL_KEY_INSERT;
- case kVK_LeftArrow: return YASL_KEY_LEFT;
- case kVK_RightArrow: return YASL_KEY_RIGHT;
- case kVK_DownArrow: return YASL_KEY_DOWN;
- case kVK_UpArrow: return YASL_KEY_UP;
- case kVK_Command: return YASL_KEY_LEFT_SUPER;
- case kVK_Shift: return YASL_KEY_LEFT_SHIFT;
- case kVK_CapsLock: return YASL_KEY_CAPS_LOCK;
- case kVK_Option: return YASL_KEY_LEFT_ALT;
- case kVK_Control: return YASL_KEY_LEFT_CONTROL;
- case kVK_RightCommand: return YASL_KEY_RIGHT_SUPER;
- case kVK_RightShift: return YASL_KEY_RIGHT_SHIFT;
- case kVK_RightOption: return YASL_KEY_RIGHT_ALT;
- case kVK_RightControl: return YASL_KEY_RIGHT_CONTROL;
- case kVK_ContextualMenu: return YASL_KEY_MENU;
- case kVK_VolumeUp: return YASL_KEY_VOLUME_UP;
- case kVK_VolumeDown: return YASL_KEY_VOLUME_DOWN;
- case kVK_Mute: return YASL_KEY_MUTE;
- case kVK_ISO_Section: return YASL_KEY_ISO_BACKSLASH;
- case kVK_JIS_Yen: return YASL_KEY_YEN;
- case kVK_JIS_Underscore: return YASL_KEY_RO;
- case kVK_JIS_Eisu: return YASL_KEY_EISU;
- case kVK_JIS_Kana: return YASL_KEY_KANA;
- case kVK_JIS_KeypadComma: return YASL_KEY_KP_COMMA;
- case kVK_ANSI_Equal: return YASL_KEY_EQUAL;
- case kVK_ANSI_Minus: return YASL_KEY_MINUS;
- case kVK_ANSI_LeftBracket: return YASL_KEY_LEFT_BRACKET;
- case kVK_ANSI_RightBracket: return YASL_KEY_RIGHT_BRACKET;
- case kVK_ANSI_Quote: return YASL_KEY_APOSTROPHE;
- case kVK_ANSI_Semicolon: return YASL_KEY_SEMICOLON;
- case kVK_ANSI_Backslash: return YASL_KEY_BACKSLASH;
- case kVK_ANSI_Comma: return YASL_KEY_COMMA;
- case kVK_ANSI_Slash: return YASL_KEY_SLASH;
- case kVK_ANSI_Period: return YASL_KEY_PERIOD;
- case kVK_ANSI_Grave: return YASL_KEY_GRAVE;
- case kVK_F1: return YASL_KEY_F1;
- case kVK_F2: return YASL_KEY_F2;
- case kVK_F3: return YASL_KEY_F3;
- case kVK_F4: return YASL_KEY_F4;
- case kVK_F5: return YASL_KEY_F5;
- case kVK_F6: return YASL_KEY_F6;
- case kVK_F7: return YASL_KEY_F7;
- case kVK_F8: return YASL_KEY_F8;
- case kVK_F9: return YASL_KEY_F9;
- case kVK_F10: return YASL_KEY_F10;
- case kVK_F11: return YASL_KEY_F11;
- case kVK_F12: return YASL_KEY_F12;
- case kVK_F13: return YASL_KEY_F13;
- case kVK_F14: return YASL_KEY_F14;
- case kVK_F15: return YASL_KEY_F15;
- case kVK_F16: return YASL_KEY_F16;
- case kVK_F17: return YASL_KEY_F17;
- case kVK_F18: return YASL_KEY_F18;
- case kVK_F19: return YASL_KEY_F19;
- case kVK_F20: return YASL_KEY_F20;
- case kVK_ANSI_Keypad0: return YASL_KEY_KP_0;
- case kVK_ANSI_Keypad1: return YASL_KEY_KP_1;
- case kVK_ANSI_Keypad2: return YASL_KEY_KP_2;
- case kVK_ANSI_Keypad3: return YASL_KEY_KP_3;
- case kVK_ANSI_Keypad4: return YASL_KEY_KP_4;
- case kVK_ANSI_Keypad5: return YASL_KEY_KP_5;
- case kVK_ANSI_Keypad6: return YASL_KEY_KP_6;
- case kVK_ANSI_Keypad7: return YASL_KEY_KP_7;
- case kVK_ANSI_Keypad8: return YASL_KEY_KP_8;
- case kVK_ANSI_Keypad9: return YASL_KEY_KP_9;
- case kVK_ANSI_KeypadDecimal: return YASL_KEY_KP_DECIMAL;
- case kVK_ANSI_KeypadMultiply: return YASL_KEY_KP_MULTIPLY;
- case kVK_ANSI_KeypadPlus: return YASL_KEY_KP_ADD;
- case kVK_ANSI_KeypadClear: return YASL_KEY_KP_CLEAR;
- case kVK_ANSI_KeypadDivide: return YASL_KEY_KP_DIVIDE;
- case kVK_ANSI_KeypadEnter: return YASL_KEY_KP_ENTER;
- case kVK_ANSI_KeypadMinus: return YASL_KEY_KP_SUBTRACT;
- case kVK_ANSI_KeypadEquals: return YASL_KEY_KP_EQUAL;
- default: return YASL_KEY_UNKNOWN;
- }
-}
-
-/* XKB standard physical key names, independent of server numeric keycodes. */
-enum yasl_key yasl_key_from_xkb_name(const char name[4])
-{
- static const struct { char name[4]; enum yasl_key key; } keys[] = {
- {{'T', 'L', 'D', 'E'}, YASL_KEY_GRAVE},
- {{'A', 'E', '0', '1'}, YASL_KEY_1},
- {{'A', 'E', '0', '2'}, YASL_KEY_2},
- {{'A', 'E', '0', '3'}, YASL_KEY_3},
- {{'A', 'E', '0', '4'}, YASL_KEY_4},
- {{'A', 'E', '0', '5'}, YASL_KEY_5},
- {{'A', 'E', '0', '6'}, YASL_KEY_6},
- {{'A', 'E', '0', '7'}, YASL_KEY_7},
- {{'A', 'E', '0', '8'}, YASL_KEY_8},
- {{'A', 'E', '0', '9'}, YASL_KEY_9},
- {{'A', 'E', '1', '0'}, YASL_KEY_0},
- {{'A', 'E', '1', '1'}, YASL_KEY_MINUS},
- {{'A', 'E', '1', '2'}, YASL_KEY_EQUAL},
- {{'B', 'K', 'S', 'P'}, YASL_KEY_BACKSPACE},
- {{'T', 'A', 'B', 0}, YASL_KEY_TAB},
- {{'A', 'D', '0', '1'}, YASL_KEY_Q},
- {{'A', 'D', '0', '2'}, YASL_KEY_W},
- {{'A', 'D', '0', '3'}, YASL_KEY_E},
- {{'A', 'D', '0', '4'}, YASL_KEY_R},
- {{'A', 'D', '0', '5'}, YASL_KEY_T},
- {{'A', 'D', '0', '6'}, YASL_KEY_Y},
- {{'A', 'D', '0', '7'}, YASL_KEY_U},
- {{'A', 'D', '0', '8'}, YASL_KEY_I},
- {{'A', 'D', '0', '9'}, YASL_KEY_O},
- {{'A', 'D', '1', '0'}, YASL_KEY_P},
- {{'A', 'D', '1', '1'}, YASL_KEY_LEFT_BRACKET},
- {{'A', 'D', '1', '2'}, YASL_KEY_RIGHT_BRACKET},
- {{'B', 'K', 'S', 'L'}, YASL_KEY_BACKSLASH},
- {{'R', 'T', 'R', 'N'}, YASL_KEY_ENTER},
- {{'C', 'A', 'P', 'S'}, YASL_KEY_CAPS_LOCK},
- {{'A', 'C', '0', '1'}, YASL_KEY_A},
- {{'A', 'C', '0', '2'}, YASL_KEY_S},
- {{'A', 'C', '0', '3'}, YASL_KEY_D},
- {{'A', 'C', '0', '4'}, YASL_KEY_F},
- {{'A', 'C', '0', '5'}, YASL_KEY_G},
- {{'A', 'C', '0', '6'}, YASL_KEY_H},
- {{'A', 'C', '0', '7'}, YASL_KEY_J},
- {{'A', 'C', '0', '8'}, YASL_KEY_K},
- {{'A', 'C', '0', '9'}, YASL_KEY_L},
- {{'A', 'C', '1', '0'}, YASL_KEY_SEMICOLON},
- {{'A', 'C', '1', '1'}, YASL_KEY_APOSTROPHE},
- {{'L', 'F', 'S', 'H'}, YASL_KEY_LEFT_SHIFT},
- {{'L', 'S', 'G', 'T'}, YASL_KEY_ISO_BACKSLASH},
- {{'A', 'B', '0', '1'}, YASL_KEY_Z},
- {{'A', 'B', '0', '2'}, YASL_KEY_X},
- {{'A', 'B', '0', '3'}, YASL_KEY_C},
- {{'A', 'B', '0', '4'}, YASL_KEY_V},
- {{'A', 'B', '0', '5'}, YASL_KEY_B},
- {{'A', 'B', '0', '6'}, YASL_KEY_N},
- {{'A', 'B', '0', '7'}, YASL_KEY_M},
- {{'A', 'B', '0', '8'}, YASL_KEY_COMMA},
- {{'A', 'B', '0', '9'}, YASL_KEY_PERIOD},
- {{'A', 'B', '1', '0'}, YASL_KEY_SLASH},
- {{'R', 'T', 'S', 'H'}, YASL_KEY_RIGHT_SHIFT},
- {{'L', 'C', 'T', 'L'}, YASL_KEY_LEFT_CONTROL},
- {{'L', 'W', 'I', 'N'}, YASL_KEY_LEFT_SUPER},
- {{'L', 'A', 'L', 'T'}, YASL_KEY_LEFT_ALT},
- {{'S', 'P', 'C', 'E'}, YASL_KEY_SPACE},
- {{'R', 'A', 'L', 'T'}, YASL_KEY_RIGHT_ALT},
- {{'R', 'W', 'I', 'N'}, YASL_KEY_RIGHT_SUPER},
- {{'C', 'O', 'M', 'P'}, YASL_KEY_MENU},
- {{'R', 'C', 'T', 'L'}, YASL_KEY_RIGHT_CONTROL},
- {{'E', 'S', 'C', 0}, YASL_KEY_ESCAPE},
- {{'F', 'K', '0', '1'}, YASL_KEY_F1},
- {{'F', 'K', '0', '2'}, YASL_KEY_F2},
- {{'F', 'K', '0', '3'}, YASL_KEY_F3},
- {{'F', 'K', '0', '4'}, YASL_KEY_F4},
- {{'F', 'K', '0', '5'}, YASL_KEY_F5},
- {{'F', 'K', '0', '6'}, YASL_KEY_F6},
- {{'F', 'K', '0', '7'}, YASL_KEY_F7},
- {{'F', 'K', '0', '8'}, YASL_KEY_F8},
- {{'F', 'K', '0', '9'}, YASL_KEY_F9},
- {{'F', 'K', '1', '0'}, YASL_KEY_F10},
- {{'F', 'K', '1', '1'}, YASL_KEY_F11},
- {{'F', 'K', '1', '2'}, YASL_KEY_F12},
- {{'P', 'R', 'S', 'C'}, YASL_KEY_PRINT_SCREEN},
- {{'S', 'C', 'L', 'K'}, YASL_KEY_SCROLL_LOCK},
- {{'P', 'A', 'U', 'S'}, YASL_KEY_PAUSE},
- {{'I', 'N', 'S', 0}, YASL_KEY_INSERT},
- {{'H', 'O', 'M', 'E'}, YASL_KEY_HOME},
- {{'P', 'G', 'U', 'P'}, YASL_KEY_PAGE_UP},
- {{'D', 'E', 'L', 'E'}, YASL_KEY_DELETE},
- {{'E', 'N', 'D', 0}, YASL_KEY_END},
- {{'P', 'G', 'D', 'N'}, YASL_KEY_PAGE_DOWN},
- {{'U', 'P', 0, 0}, YASL_KEY_UP},
- {{'L', 'E', 'F', 'T'}, YASL_KEY_LEFT},
- {{'D', 'O', 'W', 'N'}, YASL_KEY_DOWN},
- {{'R', 'G', 'H', 'T'}, YASL_KEY_RIGHT},
- {{'N', 'M', 'L', 'K'}, YASL_KEY_NUM_LOCK},
- {{'K', 'P', 'D', 'V'}, YASL_KEY_KP_DIVIDE},
- {{'K', 'P', 'M', 'U'}, YASL_KEY_KP_MULTIPLY},
- {{'K', 'P', 'S', 'U'}, YASL_KEY_KP_SUBTRACT},
- {{'K', 'P', '7', 0}, YASL_KEY_KP_7},
- {{'K', 'P', '8', 0}, YASL_KEY_KP_8},
- {{'K', 'P', '9', 0}, YASL_KEY_KP_9},
- {{'K', 'P', 'A', 'D'}, YASL_KEY_KP_ADD},
- {{'K', 'P', '4', 0}, YASL_KEY_KP_4},
- {{'K', 'P', '5', 0}, YASL_KEY_KP_5},
- {{'K', 'P', '6', 0}, YASL_KEY_KP_6},
- {{'K', 'P', '1', 0}, YASL_KEY_KP_1},
- {{'K', 'P', '2', 0}, YASL_KEY_KP_2},
- {{'K', 'P', '3', 0}, YASL_KEY_KP_3},
- {{'K', 'P', 'E', 'N'}, YASL_KEY_KP_ENTER},
- {{'K', 'P', '0', 0}, YASL_KEY_KP_0},
- {{'K', 'P', 'D', 'L'}, YASL_KEY_KP_DECIMAL},
- {{'K', 'P', 'E', 'Q'}, YASL_KEY_KP_EQUAL},
- {{'F', 'K', '1', '3'}, YASL_KEY_F13},
- {{'F', 'K', '1', '4'}, YASL_KEY_F14},
- {{'F', 'K', '1', '5'}, YASL_KEY_F15},
- {{'F', 'K', '1', '6'}, YASL_KEY_F16},
- {{'F', 'K', '1', '7'}, YASL_KEY_F17},
- {{'F', 'K', '1', '8'}, YASL_KEY_F18},
- {{'F', 'K', '1', '9'}, YASL_KEY_F19},
- {{'F', 'K', '2', '0'}, YASL_KEY_F20},
- {{'F', 'K', '2', '1'}, YASL_KEY_F21},
- {{'F', 'K', '2', '2'}, YASL_KEY_F22},
- {{'F', 'K', '2', '3'}, YASL_KEY_F23},
- {{'F', 'K', '2', '4'}, YASL_KEY_F24},
- {{'H', 'K', 'T', 'G'}, YASL_KEY_KANA},
- {{'A', 'B', '1', '1'}, YASL_KEY_RO},
- {{'H', 'E', 'N', 'K'}, YASL_KEY_CONVERT},
- {{'M', 'U', 'H', 'E'}, YASL_KEY_NONCONVERT},
- {{'A', 'E', '1', '3'}, YASL_KEY_YEN},
- {{'M', 'U', 'T', 'E'}, YASL_KEY_MUTE},
- {{'I', '1', '2', '9'}, YASL_KEY_KP_COMMA},
- };
- for (size_t i = 0; i < sizeof(keys) / sizeof(keys[0]); i++)
- if (memcmp(keys[i].name, name, 4) == 0) return keys[i].key;
- return YASL_KEY_UNKNOWN;
-}
diff --git a/src/common/keyboard.h b/src/common/keyboard.h
index 50ddbb3..77c6380 100644
--- a/src/common/keyboard.h
+++ b/src/common/keyboard.h
@@ -3,10 +3,6 @@
#include "yasl/yasl.h"
-enum yasl_key yasl_key_from_evdev(uint32_t code);
-enum yasl_key yasl_key_from_xkb_name(const char name[4]);
-enum yasl_key yasl_key_from_cocoa(uint32_t code);
-
/* Layout labels omit controls, invalid Unicode, and Cocoa function-key PUA. */
static inline uint32_t yasl_key_label(uint32_t cp)
{
diff --git a/src/common/meson.build b/src/common/meson.build
index e3986cd..015c61c 100644
--- a/src/common/meson.build
+++ b/src/common/meson.build
@@ -1 +1 @@
-sources += files('app.c', 'backend.c', 'input.c', 'keyboard.c', 'loop.c', 'native.c', 'timing.c', 'utf8.c')
+sources += files('app.c', 'backend.c', 'input.c', 'native.c', 'timing.c', 'utf8.c')
diff --git a/src/common/native.c b/src/common/native.c
index 33837e4..42b065c 100644
--- a/src/common/native.c
+++ b/src/common/native.c
@@ -1,13 +1,5 @@
#include "backend.h"
-#if YASL_HAS_WAYLAND
-#include "yasl/native/wayland.h"
-#endif
-
-#if YASL_HAS_X11
-#include "yasl/native/x11.h"
-#endif
-
#include <errno.h>
void *yasl_display_get_native_handle(struct yasl_display *d)
@@ -26,36 +18,8 @@ void *yasl_surface_get_native_handle(struct yasl_surface *s)
s->display->ops->surface_get_native_handle(s) : NULL;
}
-#if YASL_HAS_WAYLAND
-struct wl_display *yasl_wayland_display_get_wl_display(struct yasl_display *d)
-{
- return (d && yasl_display_backend(d) == YASL_BACKEND_WAYLAND) ?
- (struct wl_display *)yasl_display_get_native_handle(d) : NULL;
-}
-
-struct wl_surface *yasl_wayland_surface_get_wl_surface(struct yasl_surface *s)
-{
- return (s && s->display && yasl_display_backend(s->display) == YASL_BACKEND_WAYLAND) ?
- (struct wl_surface *)yasl_surface_get_native_handle(s) : NULL;
-}
-#endif
-
-#if YASL_HAS_X11
-Display *yasl_x11_display_get_display(struct yasl_display *d)
-{
- return (d && yasl_display_backend(d) == YASL_BACKEND_X11) ?
- (Display *)yasl_display_get_native_handle(d) : NULL;
-}
-
-uintptr_t yasl_x11_surface_get_window(struct yasl_surface *s)
-{
- return (s && s->display && yasl_display_backend(s->display) == YASL_BACKEND_X11) ?
- (uintptr_t)yasl_surface_get_native_handle(s) : 0;
-}
-#endif
-
struct yasl_surface *yasl_surface_create_native(struct yasl_display *d,
- const struct yasl_surface_spec *spec, void *graphics_device)
+ const struct yasl_window_spec *spec, void *graphics_device)
{
if (!graphics_device) {
errno = EINVAL;
diff --git a/src/meson.build b/src/meson.build
index 0dae030..4c06e5f 100644
--- a/src/meson.build
+++ b/src/meson.build
@@ -1,10 +1,2 @@
subdir('common')
-if has_wayland
- subdir('wayland')
-endif
-if has_x11
- subdir('x11')
-endif
-if has_cocoa
- subdir('cocoa')
-endif
+subdir('platform')
diff --git a/src/cocoa/api.h b/src/platform/cocoa/api.h
index 59372cf..802a039 100644
--- a/src/cocoa/api.h
+++ b/src/platform/cocoa/api.h
@@ -17,12 +17,12 @@ void cocoa_display_paste(struct cocoa_display *d, enum yasl_selection sel, struc
bool cocoa_display_drag_start(struct cocoa_display *d, struct cocoa_surface *origin, const struct yasl_drag_image *image, const struct yasl_drag_listener *l, void *ud);
void cocoa_display_drag_cancel(struct cocoa_display *d);
struct cocoa_surface *cocoa_surface_create_toplevel(struct cocoa_display *d,
- const struct yasl_surface_spec *spec, void *graphics_device);
+ const struct yasl_window_spec *spec, void *graphics_device);
struct cocoa_surface *cocoa_surface_create_popup(struct cocoa_surface *parent, const struct yasl_popup_spec *spec);
bool cocoa_surface_popup_reposition(struct cocoa_surface *popup, const struct yasl_popup_spec *spec);
void cocoa_surface_destroy(struct cocoa_surface *s);
struct cocoa_display *cocoa_surface_display(const struct cocoa_surface *s);
-void cocoa_surface_set_callbacks(struct cocoa_surface *s, const struct yasl_surface_cbs *cbs, void *ud);
+void cocoa_surface_set_callbacks(struct cocoa_surface *s, const struct yasl_window_cbs *cbs, void *ud);
void cocoa_surface_set_title(struct cocoa_surface *s, const char *title);
void cocoa_surface_schedule_redraw(struct cocoa_surface *s);
bool cocoa_surface_present(struct cocoa_surface *s, const struct yasl_framebuffer *fb, const struct yasl_damage_list *damage);
diff --git a/src/cocoa/keycodes.h b/src/platform/cocoa/keycodes.h
index f3c06be..f3c06be 100644
--- a/src/cocoa/keycodes.h
+++ b/src/platform/cocoa/keycodes.h
diff --git a/src/platform/cocoa/keymap.c b/src/platform/cocoa/keymap.c
new file mode 100644
index 0000000..b81c364
--- /dev/null
+++ b/src/platform/cocoa/keymap.c
@@ -0,0 +1,128 @@
+#include "keymap.h"
+#include "keycodes.h"
+
+enum yasl_key yasl_key_from_cocoa(uint32_t code)
+{
+ switch (code) {
+ case kVK_ANSI_A: return YASL_KEY_A;
+ case kVK_ANSI_B: return YASL_KEY_B;
+ case kVK_ANSI_C: return YASL_KEY_C;
+ case kVK_ANSI_D: return YASL_KEY_D;
+ case kVK_ANSI_E: return YASL_KEY_E;
+ case kVK_ANSI_F: return YASL_KEY_F;
+ case kVK_ANSI_G: return YASL_KEY_G;
+ case kVK_ANSI_H: return YASL_KEY_H;
+ case kVK_ANSI_I: return YASL_KEY_I;
+ case kVK_ANSI_J: return YASL_KEY_J;
+ case kVK_ANSI_K: return YASL_KEY_K;
+ case kVK_ANSI_L: return YASL_KEY_L;
+ case kVK_ANSI_M: return YASL_KEY_M;
+ case kVK_ANSI_N: return YASL_KEY_N;
+ case kVK_ANSI_O: return YASL_KEY_O;
+ case kVK_ANSI_P: return YASL_KEY_P;
+ case kVK_ANSI_Q: return YASL_KEY_Q;
+ case kVK_ANSI_R: return YASL_KEY_R;
+ case kVK_ANSI_S: return YASL_KEY_S;
+ case kVK_ANSI_T: return YASL_KEY_T;
+ case kVK_ANSI_U: return YASL_KEY_U;
+ case kVK_ANSI_V: return YASL_KEY_V;
+ case kVK_ANSI_W: return YASL_KEY_W;
+ case kVK_ANSI_X: return YASL_KEY_X;
+ case kVK_ANSI_Y: return YASL_KEY_Y;
+ case kVK_ANSI_Z: return YASL_KEY_Z;
+ case kVK_ANSI_0: return YASL_KEY_0;
+ case kVK_ANSI_1: return YASL_KEY_1;
+ case kVK_ANSI_2: return YASL_KEY_2;
+ case kVK_ANSI_3: return YASL_KEY_3;
+ case kVK_ANSI_4: return YASL_KEY_4;
+ case kVK_ANSI_5: return YASL_KEY_5;
+ case kVK_ANSI_6: return YASL_KEY_6;
+ case kVK_ANSI_7: return YASL_KEY_7;
+ case kVK_ANSI_8: return YASL_KEY_8;
+ case kVK_ANSI_9: return YASL_KEY_9;
+ case kVK_Return: return YASL_KEY_ENTER;
+ case kVK_Tab: return YASL_KEY_TAB;
+ case kVK_Space: return YASL_KEY_SPACE;
+ case kVK_Escape: return YASL_KEY_ESCAPE;
+ case kVK_Home: return YASL_KEY_HOME;
+ case kVK_End: return YASL_KEY_END;
+ case kVK_Delete: return YASL_KEY_BACKSPACE;
+ case kVK_ForwardDelete: return YASL_KEY_DELETE;
+ case kVK_PageUp: return YASL_KEY_PAGE_UP;
+ case kVK_PageDown: return YASL_KEY_PAGE_DOWN;
+ case kVK_Help: return YASL_KEY_INSERT;
+ case kVK_LeftArrow: return YASL_KEY_LEFT;
+ case kVK_RightArrow: return YASL_KEY_RIGHT;
+ case kVK_DownArrow: return YASL_KEY_DOWN;
+ case kVK_UpArrow: return YASL_KEY_UP;
+ case kVK_Command: return YASL_KEY_LEFT_SUPER;
+ case kVK_Shift: return YASL_KEY_LEFT_SHIFT;
+ case kVK_CapsLock: return YASL_KEY_CAPS_LOCK;
+ case kVK_Option: return YASL_KEY_LEFT_ALT;
+ case kVK_Control: return YASL_KEY_LEFT_CONTROL;
+ case kVK_RightCommand: return YASL_KEY_RIGHT_SUPER;
+ case kVK_RightShift: return YASL_KEY_RIGHT_SHIFT;
+ case kVK_RightOption: return YASL_KEY_RIGHT_ALT;
+ case kVK_RightControl: return YASL_KEY_RIGHT_CONTROL;
+ case kVK_ContextualMenu: return YASL_KEY_MENU;
+ case kVK_VolumeUp: return YASL_KEY_VOLUME_UP;
+ case kVK_VolumeDown: return YASL_KEY_VOLUME_DOWN;
+ case kVK_Mute: return YASL_KEY_MUTE;
+ case kVK_ISO_Section: return YASL_KEY_ISO_BACKSLASH;
+ case kVK_JIS_Yen: return YASL_KEY_YEN;
+ case kVK_JIS_Underscore: return YASL_KEY_RO;
+ case kVK_JIS_Eisu: return YASL_KEY_EISU;
+ case kVK_JIS_Kana: return YASL_KEY_KANA;
+ case kVK_JIS_KeypadComma: return YASL_KEY_KP_COMMA;
+ case kVK_ANSI_Equal: return YASL_KEY_EQUAL;
+ case kVK_ANSI_Minus: return YASL_KEY_MINUS;
+ case kVK_ANSI_LeftBracket: return YASL_KEY_LEFT_BRACKET;
+ case kVK_ANSI_RightBracket: return YASL_KEY_RIGHT_BRACKET;
+ case kVK_ANSI_Quote: return YASL_KEY_APOSTROPHE;
+ case kVK_ANSI_Semicolon: return YASL_KEY_SEMICOLON;
+ case kVK_ANSI_Backslash: return YASL_KEY_BACKSLASH;
+ case kVK_ANSI_Comma: return YASL_KEY_COMMA;
+ case kVK_ANSI_Slash: return YASL_KEY_SLASH;
+ case kVK_ANSI_Period: return YASL_KEY_PERIOD;
+ case kVK_ANSI_Grave: return YASL_KEY_GRAVE;
+ case kVK_F1: return YASL_KEY_F1;
+ case kVK_F2: return YASL_KEY_F2;
+ case kVK_F3: return YASL_KEY_F3;
+ case kVK_F4: return YASL_KEY_F4;
+ case kVK_F5: return YASL_KEY_F5;
+ case kVK_F6: return YASL_KEY_F6;
+ case kVK_F7: return YASL_KEY_F7;
+ case kVK_F8: return YASL_KEY_F8;
+ case kVK_F9: return YASL_KEY_F9;
+ case kVK_F10: return YASL_KEY_F10;
+ case kVK_F11: return YASL_KEY_F11;
+ case kVK_F12: return YASL_KEY_F12;
+ case kVK_F13: return YASL_KEY_F13;
+ case kVK_F14: return YASL_KEY_F14;
+ case kVK_F15: return YASL_KEY_F15;
+ case kVK_F16: return YASL_KEY_F16;
+ case kVK_F17: return YASL_KEY_F17;
+ case kVK_F18: return YASL_KEY_F18;
+ case kVK_F19: return YASL_KEY_F19;
+ case kVK_F20: return YASL_KEY_F20;
+ case kVK_ANSI_Keypad0: return YASL_KEY_KP_0;
+ case kVK_ANSI_Keypad1: return YASL_KEY_KP_1;
+ case kVK_ANSI_Keypad2: return YASL_KEY_KP_2;
+ case kVK_ANSI_Keypad3: return YASL_KEY_KP_3;
+ case kVK_ANSI_Keypad4: return YASL_KEY_KP_4;
+ case kVK_ANSI_Keypad5: return YASL_KEY_KP_5;
+ case kVK_ANSI_Keypad6: return YASL_KEY_KP_6;
+ case kVK_ANSI_Keypad7: return YASL_KEY_KP_7;
+ case kVK_ANSI_Keypad8: return YASL_KEY_KP_8;
+ case kVK_ANSI_Keypad9: return YASL_KEY_KP_9;
+ case kVK_ANSI_KeypadDecimal: return YASL_KEY_KP_DECIMAL;
+ case kVK_ANSI_KeypadMultiply: return YASL_KEY_KP_MULTIPLY;
+ case kVK_ANSI_KeypadPlus: return YASL_KEY_KP_ADD;
+ case kVK_ANSI_KeypadClear: return YASL_KEY_KP_CLEAR;
+ case kVK_ANSI_KeypadDivide: return YASL_KEY_KP_DIVIDE;
+ case kVK_ANSI_KeypadEnter: return YASL_KEY_KP_ENTER;
+ case kVK_ANSI_KeypadMinus: return YASL_KEY_KP_SUBTRACT;
+ case kVK_ANSI_KeypadEquals: return YASL_KEY_KP_EQUAL;
+ default: return YASL_KEY_UNKNOWN;
+ }
+}
diff --git a/src/platform/cocoa/keymap.h b/src/platform/cocoa/keymap.h
new file mode 100644
index 0000000..1aba70b
--- /dev/null
+++ b/src/platform/cocoa/keymap.h
@@ -0,0 +1,8 @@
+#ifndef YASL_COCOA_KEYMAP_H
+#define YASL_COCOA_KEYMAP_H
+
+#include "yasl/yasl.h"
+
+enum yasl_key yasl_key_from_cocoa(uint32_t code);
+
+#endif
diff --git a/src/platform/cocoa/meson.build b/src/platform/cocoa/meson.build
new file mode 100644
index 0000000..8230376
--- /dev/null
+++ b/src/platform/cocoa/meson.build
@@ -0,0 +1 @@
+sources += files('window.m', 'keymap.c')
diff --git a/src/cocoa/window.m b/src/platform/cocoa/window.m
index 028ba64..3c8519a 100644
--- a/src/cocoa/window.m
+++ b/src/platform/cocoa/window.m
@@ -2,12 +2,13 @@
#import <Metal/Metal.h>
#import <QuartzCore/QuartzCore.h>
-#include "cocoa/api.h"
+#include "platform/cocoa/api.h"
#include "yasl/native/cocoa.h"
#include "common/timing.h"
#include "common/loop.h"
-#include "cocoa/keycodes.h"
+#include "platform/cocoa/keycodes.h"
#include "common/keyboard.h"
+#include "keymap.h"
#include <assert.h>
#include <math.h>
@@ -62,7 +63,7 @@ struct cocoa_surface {
bool is_popup;
struct yasl_vector2i content_offset;
- const struct yasl_surface_cbs *cbs;
+ const struct yasl_window_cbs *cbs;
void *ud;
uint64_t frames_skipped;
@@ -1315,7 +1316,7 @@ uint32_t cocoa_display_caps(const struct cocoa_display *d)
}
struct cocoa_surface *cocoa_surface_create_toplevel(struct cocoa_display *d,
- const struct yasl_surface_spec *spec, void *graphics_device)
+ const struct yasl_window_spec *spec, void *graphics_device)
{
assert([NSThread isMainThread]);
if (!d || !d->open || !spec)
@@ -1453,7 +1454,7 @@ void cocoa_surface_destroy(struct cocoa_surface *w)
w->tablet_down = false;
darwin_ctx.depth++;
bool native_closed = w->closed;
- static const struct yasl_surface_cbs no_callbacks = {0};
+ static const struct yasl_window_cbs no_callbacks = {0};
w->destroyed = true;
w->closed = true;
w->cbs = &no_callbacks;
@@ -1921,10 +1922,10 @@ void *cocoa_surface_get_native_handle(struct cocoa_surface *s)
void cocoa_surface_set_callbacks(struct cocoa_surface *w,
- const struct yasl_surface_cbs *cbs, void *ud)
+ const struct yasl_window_cbs *cbs, void *ud)
{
if (!w || w->closed) return;
- w->base.callbacks = cbs ? *cbs : (struct yasl_surface_cbs){0};
+ w->base.callbacks = cbs ? *cbs : (struct yasl_window_cbs){0};
w->cbs = &w->base.callbacks;
w->ud = ud;
}
@@ -2021,7 +2022,7 @@ static void impl_display_drag_cancel(struct yasl_display *d)
}
static struct yasl_surface *impl_surface_create_toplevel(struct yasl_display *d,
- const struct yasl_surface_spec *spec, void *graphics_device)
+ const struct yasl_window_spec *spec, void *graphics_device)
{
struct cocoa_surface *result = cocoa_surface_create_toplevel((struct cocoa_display *)d, spec, graphics_device);
return result ? &result->base : NULL;
@@ -2049,7 +2050,7 @@ static struct yasl_display *impl_surface_display(const struct yasl_surface *s)
return result ? &result->base : NULL;
}
-static void impl_surface_set_callbacks(struct yasl_surface *s, const struct yasl_surface_cbs *cbs, void *ud)
+static void impl_surface_set_callbacks(struct yasl_surface *s, const struct yasl_window_cbs *cbs, void *ud)
{
cocoa_surface_set_callbacks((struct cocoa_surface *)s, cbs, ud);
}
diff --git a/src/platform/meson.build b/src/platform/meson.build
new file mode 100644
index 0000000..892969f
--- /dev/null
+++ b/src/platform/meson.build
@@ -0,0 +1,15 @@
+# Select OS support independently of the windowing backends. A future Win32
+# port supplies its own loop and yasl_platform_sync.h here.
+if system == 'linux' or system == 'darwin'
+ subdir('posix')
+endif
+
+if has_wayland
+ subdir('wayland')
+endif
+if has_x11
+ subdir('x11')
+endif
+if has_cocoa
+ subdir('cocoa')
+endif
diff --git a/src/common/loop.c b/src/platform/posix/loop.c
index 1c6a612..88454d8 100644
--- a/src/common/loop.c
+++ b/src/platform/posix/loop.c
@@ -1,6 +1,6 @@
#define _GNU_SOURCE
#define _POSIX_C_SOURCE 200809L
-#include "loop.h"
+#include "common/loop.h"
#include <errno.h>
#include <fcntl.h>
diff --git a/src/platform/posix/meson.build b/src/platform/posix/meson.build
new file mode 100644
index 0000000..51bfa2b
--- /dev/null
+++ b/src/platform/posix/meson.build
@@ -0,0 +1,3 @@
+sources += files('loop.c')
+inc = [inc, include_directories('.')]
+deps += dependency('threads')
diff --git a/src/platform/posix/yasl_platform_sync.h b/src/platform/posix/yasl_platform_sync.h
new file mode 100644
index 0000000..f94a25d
--- /dev/null
+++ b/src/platform/posix/yasl_platform_sync.h
@@ -0,0 +1,28 @@
+#ifndef YASL_POSIX_SYNC_H
+#define YASL_POSIX_SYNC_H
+
+#include <pthread.h>
+
+typedef pthread_mutex_t yasl_mutex;
+
+static inline int yasl_mutex_init(yasl_mutex *mutex)
+{
+ return pthread_mutex_init(mutex, NULL);
+}
+
+static inline void yasl_mutex_destroy(yasl_mutex *mutex)
+{
+ pthread_mutex_destroy(mutex);
+}
+
+static inline void yasl_mutex_lock(yasl_mutex *mutex)
+{
+ pthread_mutex_lock(mutex);
+}
+
+static inline void yasl_mutex_unlock(yasl_mutex *mutex)
+{
+ pthread_mutex_unlock(mutex);
+}
+
+#endif
diff --git a/src/platform/sync.h b/src/platform/sync.h
new file mode 100644
index 0000000..1dcf28f
--- /dev/null
+++ b/src/platform/sync.h
@@ -0,0 +1,10 @@
+#ifndef YASL_PLATFORM_SYNC_H
+#define YASL_PLATFORM_SYNC_H
+
+/* The OS support directory selected by Meson provides yasl_mutex and the
+ * yasl_mutex_init/destroy/lock/unlock operations. Init returns zero on success
+ * or an errno value on failure. The other operations require an initialized
+ * mutex. Native types and calls stay in the selected implementation header. */
+#include "yasl_platform_sync.h"
+
+#endif
diff --git a/src/wayland/api.h b/src/platform/wayland/api.h
index e68aca7..c3e5676 100644
--- a/src/wayland/api.h
+++ b/src/platform/wayland/api.h
@@ -18,12 +18,12 @@ void wayland_display_paste(struct wayland_display *d, enum yasl_selection sel, s
bool wayland_display_drag_start(struct wayland_display *d, struct wayland_surface *origin, const struct yasl_drag_image *image, const struct yasl_drag_listener *l, void *ud);
void wayland_display_drag_cancel(struct wayland_display *d);
struct wayland_surface *wayland_surface_create_toplevel(struct wayland_display *d,
- const struct yasl_surface_spec *spec, void *graphics_device);
+ const struct yasl_window_spec *spec, void *graphics_device);
struct wayland_surface *wayland_surface_create_popup(struct wayland_surface *parent, const struct yasl_popup_spec *spec);
bool wayland_surface_popup_reposition(struct wayland_surface *popup, const struct yasl_popup_spec *spec);
void wayland_surface_destroy(struct wayland_surface *s);
struct wayland_display *wayland_surface_display(const struct wayland_surface *s);
-void wayland_surface_set_callbacks(struct wayland_surface *s, const struct yasl_surface_cbs *cbs, void *ud);
+void wayland_surface_set_callbacks(struct wayland_surface *s, const struct yasl_window_cbs *cbs, void *ud);
void wayland_surface_set_title(struct wayland_surface *s, const char *title);
void wayland_surface_schedule_redraw(struct wayland_surface *s);
bool wayland_surface_present(struct wayland_surface *s, const struct yasl_framebuffer *fb, const struct yasl_damage_list *damage);
diff --git a/src/wayland/backend.c b/src/platform/wayland/backend.c
index 5c34def..c0c7c83 100644
--- a/src/wayland/backend.c
+++ b/src/platform/wayland/backend.c
@@ -1,4 +1,4 @@
-#include "wayland/internal.h"
+#include "platform/wayland/internal.h"
static struct yasl_display *impl_display_open(struct yasl_loop *loop, const struct yasl_display_spec *spec)
{
@@ -52,7 +52,7 @@ static void impl_display_drag_cancel(struct yasl_display *d)
}
static struct yasl_surface *impl_surface_create_toplevel(struct yasl_display *d,
- const struct yasl_surface_spec *spec, void *graphics_device)
+ const struct yasl_window_spec *spec, void *graphics_device)
{
struct wayland_surface *result = wayland_surface_create_toplevel((struct wayland_display *)d, spec, graphics_device);
return result ? &result->base : NULL;
@@ -80,7 +80,7 @@ static struct yasl_display *impl_surface_display(const struct yasl_surface *s)
return result ? &result->base : NULL;
}
-static void impl_surface_set_callbacks(struct yasl_surface *s, const struct yasl_surface_cbs *cbs, void *ud)
+static void impl_surface_set_callbacks(struct yasl_surface *s, const struct yasl_window_cbs *cbs, void *ud)
{
wayland_surface_set_callbacks((struct wayland_surface *)s, cbs, ud);
}
diff --git a/src/wayland/buffer.c b/src/platform/wayland/buffer.c
index 142f85f..142f85f 100644
--- a/src/wayland/buffer.c
+++ b/src/platform/wayland/buffer.c
diff --git a/src/wayland/clipboard.c b/src/platform/wayland/clipboard.c
index a6922c4..a6922c4 100644
--- a/src/wayland/clipboard.c
+++ b/src/platform/wayland/clipboard.c
diff --git a/src/wayland/clipboard.h b/src/platform/wayland/clipboard.h
index 9fefa8e..9fefa8e 100644
--- a/src/wayland/clipboard.h
+++ b/src/platform/wayland/clipboard.h
diff --git a/src/wayland/drag.c b/src/platform/wayland/drag.c
index 989dbb6..989dbb6 100644
--- a/src/wayland/drag.c
+++ b/src/platform/wayland/drag.c
diff --git a/src/wayland/ime.c b/src/platform/wayland/ime.c
index bd9375b..bd9375b 100644
--- a/src/wayland/ime.c
+++ b/src/platform/wayland/ime.c
diff --git a/src/wayland/internal.h b/src/platform/wayland/internal.h
index b687a61..51f51eb 100644
--- a/src/wayland/internal.h
+++ b/src/platform/wayland/internal.h
@@ -276,7 +276,7 @@ struct wayland_surface {
struct wp_fifo_v1 *fifo;
struct wp_commit_timer_v1 *commit_timer;
struct wl_callback *frame_cb;
- const struct yasl_surface_cbs *cbs;
+ const struct yasl_window_cbs *cbs;
void *ud;
uint64_t frames_skipped;
uint64_t outputs;
diff --git a/src/wayland/keyboard.c b/src/platform/wayland/keyboard.c
index f1170c6..86c8f07 100644
--- a/src/wayland/keyboard.c
+++ b/src/platform/wayland/keyboard.c
@@ -1,5 +1,6 @@
#include "internal.h"
#include "common/keyboard.h"
+#include "keymap.h"
#define XKB_EVDEV_OFFSET 8
#define KEYMAP_MAX_BYTES (8u * 1024 * 1024)
diff --git a/src/platform/wayland/keymap.c b/src/platform/wayland/keymap.c
new file mode 100644
index 0000000..d626f30
--- /dev/null
+++ b/src/platform/wayland/keymap.c
@@ -0,0 +1,136 @@
+#include "keymap.h"
+
+/* Numeric Linux evdev codes; no platform headers are needed by this table. */
+enum yasl_key yasl_key_from_evdev(uint32_t code)
+{
+ switch (code) {
+ case 1: return YASL_KEY_ESCAPE; /* KEY_ESC */
+ case 2: return YASL_KEY_1; /* KEY_1 */
+ case 3: return YASL_KEY_2; /* KEY_2 */
+ case 4: return YASL_KEY_3; /* KEY_3 */
+ case 5: return YASL_KEY_4; /* KEY_4 */
+ case 6: return YASL_KEY_5; /* KEY_5 */
+ case 7: return YASL_KEY_6; /* KEY_6 */
+ case 8: return YASL_KEY_7; /* KEY_7 */
+ case 9: return YASL_KEY_8; /* KEY_8 */
+ case 10: return YASL_KEY_9; /* KEY_9 */
+ case 11: return YASL_KEY_0; /* KEY_0 */
+ case 12: return YASL_KEY_MINUS; /* KEY_MINUS */
+ case 13: return YASL_KEY_EQUAL; /* KEY_EQUAL */
+ case 14: return YASL_KEY_BACKSPACE; /* KEY_BACKSPACE */
+ case 15: return YASL_KEY_TAB; /* KEY_TAB */
+ case 16: return YASL_KEY_Q; /* KEY_Q */
+ case 17: return YASL_KEY_W; /* KEY_W */
+ case 18: return YASL_KEY_E; /* KEY_E */
+ case 19: return YASL_KEY_R; /* KEY_R */
+ case 20: return YASL_KEY_T; /* KEY_T */
+ case 21: return YASL_KEY_Y; /* KEY_Y */
+ case 22: return YASL_KEY_U; /* KEY_U */
+ case 23: return YASL_KEY_I; /* KEY_I */
+ case 24: return YASL_KEY_O; /* KEY_O */
+ case 25: return YASL_KEY_P; /* KEY_P */
+ case 26: return YASL_KEY_LEFT_BRACKET; /* KEY_LEFTBRACE */
+ case 27: return YASL_KEY_RIGHT_BRACKET; /* KEY_RIGHTBRACE */
+ case 28: return YASL_KEY_ENTER; /* KEY_ENTER */
+ case 29: return YASL_KEY_LEFT_CONTROL; /* KEY_LEFTCTRL */
+ case 30: return YASL_KEY_A; /* KEY_A */
+ case 31: return YASL_KEY_S; /* KEY_S */
+ case 32: return YASL_KEY_D; /* KEY_D */
+ case 33: return YASL_KEY_F; /* KEY_F */
+ case 34: return YASL_KEY_G; /* KEY_G */
+ case 35: return YASL_KEY_H; /* KEY_H */
+ case 36: return YASL_KEY_J; /* KEY_J */
+ case 37: return YASL_KEY_K; /* KEY_K */
+ case 38: return YASL_KEY_L; /* KEY_L */
+ case 39: return YASL_KEY_SEMICOLON; /* KEY_SEMICOLON */
+ case 40: return YASL_KEY_APOSTROPHE; /* KEY_APOSTROPHE */
+ case 41: return YASL_KEY_GRAVE; /* KEY_GRAVE */
+ case 42: return YASL_KEY_LEFT_SHIFT; /* KEY_LEFTSHIFT */
+ case 43: return YASL_KEY_BACKSLASH; /* KEY_BACKSLASH */
+ case 44: return YASL_KEY_Z; /* KEY_Z */
+ case 45: return YASL_KEY_X; /* KEY_X */
+ case 46: return YASL_KEY_C; /* KEY_C */
+ case 47: return YASL_KEY_V; /* KEY_V */
+ case 48: return YASL_KEY_B; /* KEY_B */
+ case 49: return YASL_KEY_N; /* KEY_N */
+ case 50: return YASL_KEY_M; /* KEY_M */
+ case 51: return YASL_KEY_COMMA; /* KEY_COMMA */
+ case 52: return YASL_KEY_PERIOD; /* KEY_DOT */
+ case 53: return YASL_KEY_SLASH; /* KEY_SLASH */
+ case 54: return YASL_KEY_RIGHT_SHIFT; /* KEY_RIGHTSHIFT */
+ case 55: return YASL_KEY_KP_MULTIPLY; /* KEY_KPASTERISK */
+ case 56: return YASL_KEY_LEFT_ALT; /* KEY_LEFTALT */
+ case 57: return YASL_KEY_SPACE; /* KEY_SPACE */
+ case 58: return YASL_KEY_CAPS_LOCK; /* KEY_CAPSLOCK */
+ case 59: return YASL_KEY_F1; /* KEY_F1 */
+ case 60: return YASL_KEY_F2; /* KEY_F2 */
+ case 61: return YASL_KEY_F3; /* KEY_F3 */
+ case 62: return YASL_KEY_F4; /* KEY_F4 */
+ case 63: return YASL_KEY_F5; /* KEY_F5 */
+ case 64: return YASL_KEY_F6; /* KEY_F6 */
+ case 65: return YASL_KEY_F7; /* KEY_F7 */
+ case 66: return YASL_KEY_F8; /* KEY_F8 */
+ case 67: return YASL_KEY_F9; /* KEY_F9 */
+ case 68: return YASL_KEY_F10; /* KEY_F10 */
+ case 69: return YASL_KEY_NUM_LOCK; /* KEY_NUMLOCK */
+ case 70: return YASL_KEY_SCROLL_LOCK; /* KEY_SCROLLLOCK */
+ case 71: return YASL_KEY_KP_7; /* KEY_KP7 */
+ case 72: return YASL_KEY_KP_8; /* KEY_KP8 */
+ case 73: return YASL_KEY_KP_9; /* KEY_KP9 */
+ case 74: return YASL_KEY_KP_SUBTRACT; /* KEY_KPMINUS */
+ case 75: return YASL_KEY_KP_4; /* KEY_KP4 */
+ case 76: return YASL_KEY_KP_5; /* KEY_KP5 */
+ case 77: return YASL_KEY_KP_6; /* KEY_KP6 */
+ case 78: return YASL_KEY_KP_ADD; /* KEY_KPPLUS */
+ case 79: return YASL_KEY_KP_1; /* KEY_KP1 */
+ case 80: return YASL_KEY_KP_2; /* KEY_KP2 */
+ case 81: return YASL_KEY_KP_3; /* KEY_KP3 */
+ case 82: return YASL_KEY_KP_0; /* KEY_KP0 */
+ case 83: return YASL_KEY_KP_DECIMAL; /* KEY_KPDOT */
+ case 86: return YASL_KEY_ISO_BACKSLASH; /* KEY_102ND */
+ case 87: return YASL_KEY_F11; /* KEY_F11 */
+ case 88: return YASL_KEY_F12; /* KEY_F12 */
+ case 89: return YASL_KEY_RO; /* KEY_RO */
+ case 92: return YASL_KEY_CONVERT; /* KEY_HENKAN */
+ case 93: return YASL_KEY_KANA; /* KEY_KATAKANAHIRAGANA */
+ case 94: return YASL_KEY_NONCONVERT; /* KEY_MUHENKAN */
+ case 96: return YASL_KEY_KP_ENTER; /* KEY_KPENTER */
+ case 97: return YASL_KEY_RIGHT_CONTROL; /* KEY_RIGHTCTRL */
+ case 98: return YASL_KEY_KP_DIVIDE; /* KEY_KPSLASH */
+ case 99: return YASL_KEY_PRINT_SCREEN; /* KEY_SYSRQ */
+ case 100: return YASL_KEY_RIGHT_ALT; /* KEY_RIGHTALT */
+ case 102: return YASL_KEY_HOME; /* KEY_HOME */
+ case 103: return YASL_KEY_UP; /* KEY_UP */
+ case 104: return YASL_KEY_PAGE_UP; /* KEY_PAGEUP */
+ case 105: return YASL_KEY_LEFT; /* KEY_LEFT */
+ case 106: return YASL_KEY_RIGHT; /* KEY_RIGHT */
+ case 107: return YASL_KEY_END; /* KEY_END */
+ case 108: return YASL_KEY_DOWN; /* KEY_DOWN */
+ case 109: return YASL_KEY_PAGE_DOWN; /* KEY_PAGEDOWN */
+ case 110: return YASL_KEY_INSERT; /* KEY_INSERT */
+ case 111: return YASL_KEY_DELETE; /* KEY_DELETE */
+ case 113: return YASL_KEY_MUTE; /* KEY_MUTE */
+ case 114: return YASL_KEY_VOLUME_DOWN; /* KEY_VOLUMEDOWN */
+ case 115: return YASL_KEY_VOLUME_UP; /* KEY_VOLUMEUP */
+ case 117: return YASL_KEY_KP_EQUAL; /* KEY_KPEQUAL */
+ case 119: return YASL_KEY_PAUSE; /* KEY_PAUSE */
+ case 121: return YASL_KEY_KP_COMMA; /* KEY_KPCOMMA */
+ case 124: return YASL_KEY_YEN; /* KEY_YEN */
+ case 125: return YASL_KEY_LEFT_SUPER; /* KEY_LEFTMETA */
+ case 126: return YASL_KEY_RIGHT_SUPER; /* KEY_RIGHTMETA */
+ case 127: return YASL_KEY_MENU; /* KEY_COMPOSE */
+ case 183: return YASL_KEY_F13; /* KEY_F13 */
+ case 184: return YASL_KEY_F14; /* KEY_F14 */
+ case 185: return YASL_KEY_F15; /* KEY_F15 */
+ case 186: return YASL_KEY_F16; /* KEY_F16 */
+ case 187: return YASL_KEY_F17; /* KEY_F17 */
+ case 188: return YASL_KEY_F18; /* KEY_F18 */
+ case 189: return YASL_KEY_F19; /* KEY_F19 */
+ case 190: return YASL_KEY_F20; /* KEY_F20 */
+ case 191: return YASL_KEY_F21; /* KEY_F21 */
+ case 192: return YASL_KEY_F22; /* KEY_F22 */
+ case 193: return YASL_KEY_F23; /* KEY_F23 */
+ case 194: return YASL_KEY_F24; /* KEY_F24 */
+ default: return YASL_KEY_UNKNOWN;
+ }
+}
diff --git a/src/platform/wayland/keymap.h b/src/platform/wayland/keymap.h
new file mode 100644
index 0000000..26a5cd6
--- /dev/null
+++ b/src/platform/wayland/keymap.h
@@ -0,0 +1,8 @@
+#ifndef YASL_WAYLAND_KEYMAP_H
+#define YASL_WAYLAND_KEYMAP_H
+
+#include "yasl/yasl.h"
+
+enum yasl_key yasl_key_from_evdev(uint32_t code);
+
+#endif
diff --git a/src/wayland/meson.build b/src/platform/wayland/meson.build
index ca83755..d56970e 100644
--- a/src/wayland/meson.build
+++ b/src/platform/wayland/meson.build
@@ -6,6 +6,8 @@ sources += wl_protocol_src + files(
'drag.c',
'ime.c',
'keyboard.c',
+ 'keymap.c',
+ 'native.c',
'pointer.c',
'popup.c',
'shell.c',
diff --git a/src/platform/wayland/native.c b/src/platform/wayland/native.c
new file mode 100644
index 0000000..55ce445
--- /dev/null
+++ b/src/platform/wayland/native.c
@@ -0,0 +1,14 @@
+#include "common/backend.h"
+#include "yasl/native/wayland.h"
+
+struct wl_display *yasl_wayland_display_get_wl_display(struct yasl_display *d)
+{
+ return (d && yasl_display_backend(d) == YASL_BACKEND_WAYLAND) ?
+ (struct wl_display *)yasl_display_get_native_handle(d) : NULL;
+}
+
+struct wl_surface *yasl_wayland_surface_get_wl_surface(struct yasl_surface *s)
+{
+ return (s && s->display && yasl_display_backend(s->display) == YASL_BACKEND_WAYLAND) ?
+ (struct wl_surface *)yasl_surface_get_native_handle(s) : NULL;
+}
diff --git a/src/wayland/pointer.c b/src/platform/wayland/pointer.c
index 90b7ecc..90b7ecc 100644
--- a/src/wayland/pointer.c
+++ b/src/platform/wayland/pointer.c
diff --git a/src/wayland/popup.c b/src/platform/wayland/popup.c
index 3a85435..3a85435 100644
--- a/src/wayland/popup.c
+++ b/src/platform/wayland/popup.c
diff --git a/src/wayland/protocols/commit-timing-v1-client-protocol.h b/src/platform/wayland/protocols/commit-timing-v1-client-protocol.h
index 20dc94c..20dc94c 100644
--- a/src/wayland/protocols/commit-timing-v1-client-protocol.h
+++ b/src/platform/wayland/protocols/commit-timing-v1-client-protocol.h
diff --git a/src/wayland/protocols/commit-timing-v1-protocol.c b/src/platform/wayland/protocols/commit-timing-v1-protocol.c
index 6755745..6755745 100644
--- a/src/wayland/protocols/commit-timing-v1-protocol.c
+++ b/src/platform/wayland/protocols/commit-timing-v1-protocol.c
diff --git a/src/wayland/protocols/cursor-shape-v1-client-protocol.h b/src/platform/wayland/protocols/cursor-shape-v1-client-protocol.h
index ff60edd..ff60edd 100644
--- a/src/wayland/protocols/cursor-shape-v1-client-protocol.h
+++ b/src/platform/wayland/protocols/cursor-shape-v1-client-protocol.h
diff --git a/src/wayland/protocols/cursor-shape-v1-protocol.c b/src/platform/wayland/protocols/cursor-shape-v1-protocol.c
index c76190d..c76190d 100644
--- a/src/wayland/protocols/cursor-shape-v1-protocol.c
+++ b/src/platform/wayland/protocols/cursor-shape-v1-protocol.c
diff --git a/src/wayland/protocols/fifo-v1-client-protocol.h b/src/platform/wayland/protocols/fifo-v1-client-protocol.h
index 8c2eeec..8c2eeec 100644
--- a/src/wayland/protocols/fifo-v1-client-protocol.h
+++ b/src/platform/wayland/protocols/fifo-v1-client-protocol.h
diff --git a/src/wayland/protocols/fifo-v1-protocol.c b/src/platform/wayland/protocols/fifo-v1-protocol.c
index 5c31da3..5c31da3 100644
--- a/src/wayland/protocols/fifo-v1-protocol.c
+++ b/src/platform/wayland/protocols/fifo-v1-protocol.c
diff --git a/src/wayland/protocols/fractional-scale-v1-client-protocol.h b/src/platform/wayland/protocols/fractional-scale-v1-client-protocol.h
index 65adbd0..65adbd0 100644
--- a/src/wayland/protocols/fractional-scale-v1-client-protocol.h
+++ b/src/platform/wayland/protocols/fractional-scale-v1-client-protocol.h
diff --git a/src/wayland/protocols/fractional-scale-v1-protocol.c b/src/platform/wayland/protocols/fractional-scale-v1-protocol.c
index b8c1a63..b8c1a63 100644
--- a/src/wayland/protocols/fractional-scale-v1-protocol.c
+++ b/src/platform/wayland/protocols/fractional-scale-v1-protocol.c
diff --git a/src/wayland/protocols/meson.build b/src/platform/wayland/protocols/meson.build
index 6e20a6c..6e20a6c 100644
--- a/src/wayland/protocols/meson.build
+++ b/src/platform/wayland/protocols/meson.build
diff --git a/src/wayland/protocols/presentation-time-client-protocol.h b/src/platform/wayland/protocols/presentation-time-client-protocol.h
index 720027d..720027d 100644
--- a/src/wayland/protocols/presentation-time-client-protocol.h
+++ b/src/platform/wayland/protocols/presentation-time-client-protocol.h
diff --git a/src/wayland/protocols/presentation-time-protocol.c b/src/platform/wayland/protocols/presentation-time-protocol.c
index b7eef14..b7eef14 100644
--- a/src/wayland/protocols/presentation-time-protocol.c
+++ b/src/platform/wayland/protocols/presentation-time-protocol.c
diff --git a/src/wayland/protocols/primary-selection-unstable-v1-client-protocol.h b/src/platform/wayland/protocols/primary-selection-unstable-v1-client-protocol.h
index 01dd0e3..01dd0e3 100644
--- a/src/wayland/protocols/primary-selection-unstable-v1-client-protocol.h
+++ b/src/platform/wayland/protocols/primary-selection-unstable-v1-client-protocol.h
diff --git a/src/wayland/protocols/primary-selection-unstable-v1-protocol.c b/src/platform/wayland/protocols/primary-selection-unstable-v1-protocol.c
index 8c99e28..8c99e28 100644
--- a/src/wayland/protocols/primary-selection-unstable-v1-protocol.c
+++ b/src/platform/wayland/protocols/primary-selection-unstable-v1-protocol.c
diff --git a/src/wayland/protocols/tablet-v2-client-protocol.h b/src/platform/wayland/protocols/tablet-v2-client-protocol.h
index d3aa023..d3aa023 100644
--- a/src/wayland/protocols/tablet-v2-client-protocol.h
+++ b/src/platform/wayland/protocols/tablet-v2-client-protocol.h
diff --git a/src/wayland/protocols/tablet-v2-protocol.c b/src/platform/wayland/protocols/tablet-v2-protocol.c
index 4a1f57b..4a1f57b 100644
--- a/src/wayland/protocols/tablet-v2-protocol.c
+++ b/src/platform/wayland/protocols/tablet-v2-protocol.c
diff --git a/src/wayland/protocols/tearing-control-v1-client-protocol.h b/src/platform/wayland/protocols/tearing-control-v1-client-protocol.h
index 48f9861..48f9861 100644
--- a/src/wayland/protocols/tearing-control-v1-client-protocol.h
+++ b/src/platform/wayland/protocols/tearing-control-v1-client-protocol.h
diff --git a/src/wayland/protocols/tearing-control-v1-protocol.c b/src/platform/wayland/protocols/tearing-control-v1-protocol.c
index afedad8..afedad8 100644
--- a/src/wayland/protocols/tearing-control-v1-protocol.c
+++ b/src/platform/wayland/protocols/tearing-control-v1-protocol.c
diff --git a/src/wayland/protocols/text-input-unstable-v3-client-protocol.h b/src/platform/wayland/protocols/text-input-unstable-v3-client-protocol.h
index 2c4c23b..2c4c23b 100644
--- a/src/wayland/protocols/text-input-unstable-v3-client-protocol.h
+++ b/src/platform/wayland/protocols/text-input-unstable-v3-client-protocol.h
diff --git a/src/wayland/protocols/text-input-unstable-v3-protocol.c b/src/platform/wayland/protocols/text-input-unstable-v3-protocol.c
index 7683650..7683650 100644
--- a/src/wayland/protocols/text-input-unstable-v3-protocol.c
+++ b/src/platform/wayland/protocols/text-input-unstable-v3-protocol.c
diff --git a/src/wayland/protocols/viewporter-client-protocol.h b/src/platform/wayland/protocols/viewporter-client-protocol.h
index a7818d3..a7818d3 100644
--- a/src/wayland/protocols/viewporter-client-protocol.h
+++ b/src/platform/wayland/protocols/viewporter-client-protocol.h
diff --git a/src/wayland/protocols/viewporter-protocol.c b/src/platform/wayland/protocols/viewporter-protocol.c
index 12c9527..12c9527 100644
--- a/src/wayland/protocols/viewporter-protocol.c
+++ b/src/platform/wayland/protocols/viewporter-protocol.c
diff --git a/src/wayland/protocols/xdg-decoration-client-protocol.h b/src/platform/wayland/protocols/xdg-decoration-client-protocol.h
index 4cbc976..4cbc976 100644
--- a/src/wayland/protocols/xdg-decoration-client-protocol.h
+++ b/src/platform/wayland/protocols/xdg-decoration-client-protocol.h
diff --git a/src/wayland/protocols/xdg-decoration-protocol.c b/src/platform/wayland/protocols/xdg-decoration-protocol.c
index db0a29d..db0a29d 100644
--- a/src/wayland/protocols/xdg-decoration-protocol.c
+++ b/src/platform/wayland/protocols/xdg-decoration-protocol.c
diff --git a/src/wayland/protocols/xdg-shell-client-protocol.h b/src/platform/wayland/protocols/xdg-shell-client-protocol.h
index 1cb6016..1cb6016 100644
--- a/src/wayland/protocols/xdg-shell-client-protocol.h
+++ b/src/platform/wayland/protocols/xdg-shell-client-protocol.h
diff --git a/src/wayland/protocols/xdg-shell-protocol.c b/src/platform/wayland/protocols/xdg-shell-protocol.c
index 9dc1f61..9dc1f61 100644
--- a/src/wayland/protocols/xdg-shell-protocol.c
+++ b/src/platform/wayland/protocols/xdg-shell-protocol.c
diff --git a/src/wayland/protocols/xdg-toplevel-drag-v1-client-protocol.h b/src/platform/wayland/protocols/xdg-toplevel-drag-v1-client-protocol.h
index e5d6860..e5d6860 100644
--- a/src/wayland/protocols/xdg-toplevel-drag-v1-client-protocol.h
+++ b/src/platform/wayland/protocols/xdg-toplevel-drag-v1-client-protocol.h
diff --git a/src/wayland/protocols/xdg-toplevel-drag-v1-protocol.c b/src/platform/wayland/protocols/xdg-toplevel-drag-v1-protocol.c
index 1411819..1411819 100644
--- a/src/wayland/protocols/xdg-toplevel-drag-v1-protocol.c
+++ b/src/platform/wayland/protocols/xdg-toplevel-drag-v1-protocol.c
diff --git a/src/wayland/shell.c b/src/platform/wayland/shell.c
index 4c1caad..4c1caad 100644
--- a/src/wayland/shell.c
+++ b/src/platform/wayland/shell.c
diff --git a/src/wayland/surface.c b/src/platform/wayland/surface.c
index ca9db72..1820642 100644
--- a/src/wayland/surface.c
+++ b/src/platform/wayland/surface.c
@@ -321,7 +321,7 @@ static void conn_unlink(struct wayland_surface *w)
}
-static bool spec_valid(const struct yasl_surface_spec *spec)
+static bool spec_valid(const struct yasl_window_spec *spec)
{
size_t bytes;
return spec && spec->size.x > 0 && spec->size.y > 0 &&
@@ -329,7 +329,7 @@ static bool spec_valid(const struct yasl_surface_spec *spec)
}
struct wayland_surface *wayland_surface_create_toplevel(struct wayland_display *c,
- const struct yasl_surface_spec *spec, void *graphics_device)
+ const struct yasl_window_spec *spec, void *graphics_device)
{
(void)graphics_device;
if (!c || c->lost || !spec_valid(spec))
@@ -388,10 +388,10 @@ err:
return NULL;
}
-void wayland_surface_set_callbacks(struct wayland_surface *w, const struct yasl_surface_cbs *cbs, void *ud)
+void wayland_surface_set_callbacks(struct wayland_surface *w, const struct yasl_window_cbs *cbs, void *ud)
{
if (w && !w->closed) {
- w->base.callbacks = cbs ? *cbs : (struct yasl_surface_cbs){0};
+ w->base.callbacks = cbs ? *cbs : (struct yasl_window_cbs){0};
w->cbs = &w->base.callbacks;
w->ud = ud;
}
@@ -424,7 +424,7 @@ void wayland_surface_destroy(struct wayland_surface *w)
}
struct wayland_display *c = w->conn;
conn_unlink(w);
- static const struct yasl_surface_cbs no_callbacks = {0};
+ static const struct yasl_window_cbs no_callbacks = {0};
*w = (struct wayland_surface){
.base = w->base,
.conn_next = w->conn_next,
diff --git a/src/platform/x11/keymap.c b/src/platform/x11/keymap.c
new file mode 100644
index 0000000..3c566b3
--- /dev/null
+++ b/src/platform/x11/keymap.c
@@ -0,0 +1,137 @@
+#include "keymap.h"
+#include <string.h>
+
+/* XKB standard physical key names, independent of server numeric keycodes. */
+enum yasl_key yasl_key_from_xkb_name(const char name[4])
+{
+ static const struct { char name[4]; enum yasl_key key; } keys[] = {
+ {{'T', 'L', 'D', 'E'}, YASL_KEY_GRAVE},
+ {{'A', 'E', '0', '1'}, YASL_KEY_1},
+ {{'A', 'E', '0', '2'}, YASL_KEY_2},
+ {{'A', 'E', '0', '3'}, YASL_KEY_3},
+ {{'A', 'E', '0', '4'}, YASL_KEY_4},
+ {{'A', 'E', '0', '5'}, YASL_KEY_5},
+ {{'A', 'E', '0', '6'}, YASL_KEY_6},
+ {{'A', 'E', '0', '7'}, YASL_KEY_7},
+ {{'A', 'E', '0', '8'}, YASL_KEY_8},
+ {{'A', 'E', '0', '9'}, YASL_KEY_9},
+ {{'A', 'E', '1', '0'}, YASL_KEY_0},
+ {{'A', 'E', '1', '1'}, YASL_KEY_MINUS},
+ {{'A', 'E', '1', '2'}, YASL_KEY_EQUAL},
+ {{'B', 'K', 'S', 'P'}, YASL_KEY_BACKSPACE},
+ {{'T', 'A', 'B', 0}, YASL_KEY_TAB},
+ {{'A', 'D', '0', '1'}, YASL_KEY_Q},
+ {{'A', 'D', '0', '2'}, YASL_KEY_W},
+ {{'A', 'D', '0', '3'}, YASL_KEY_E},
+ {{'A', 'D', '0', '4'}, YASL_KEY_R},
+ {{'A', 'D', '0', '5'}, YASL_KEY_T},
+ {{'A', 'D', '0', '6'}, YASL_KEY_Y},
+ {{'A', 'D', '0', '7'}, YASL_KEY_U},
+ {{'A', 'D', '0', '8'}, YASL_KEY_I},
+ {{'A', 'D', '0', '9'}, YASL_KEY_O},
+ {{'A', 'D', '1', '0'}, YASL_KEY_P},
+ {{'A', 'D', '1', '1'}, YASL_KEY_LEFT_BRACKET},
+ {{'A', 'D', '1', '2'}, YASL_KEY_RIGHT_BRACKET},
+ {{'B', 'K', 'S', 'L'}, YASL_KEY_BACKSLASH},
+ {{'R', 'T', 'R', 'N'}, YASL_KEY_ENTER},
+ {{'C', 'A', 'P', 'S'}, YASL_KEY_CAPS_LOCK},
+ {{'A', 'C', '0', '1'}, YASL_KEY_A},
+ {{'A', 'C', '0', '2'}, YASL_KEY_S},
+ {{'A', 'C', '0', '3'}, YASL_KEY_D},
+ {{'A', 'C', '0', '4'}, YASL_KEY_F},
+ {{'A', 'C', '0', '5'}, YASL_KEY_G},
+ {{'A', 'C', '0', '6'}, YASL_KEY_H},
+ {{'A', 'C', '0', '7'}, YASL_KEY_J},
+ {{'A', 'C', '0', '8'}, YASL_KEY_K},
+ {{'A', 'C', '0', '9'}, YASL_KEY_L},
+ {{'A', 'C', '1', '0'}, YASL_KEY_SEMICOLON},
+ {{'A', 'C', '1', '1'}, YASL_KEY_APOSTROPHE},
+ {{'L', 'F', 'S', 'H'}, YASL_KEY_LEFT_SHIFT},
+ {{'L', 'S', 'G', 'T'}, YASL_KEY_ISO_BACKSLASH},
+ {{'A', 'B', '0', '1'}, YASL_KEY_Z},
+ {{'A', 'B', '0', '2'}, YASL_KEY_X},
+ {{'A', 'B', '0', '3'}, YASL_KEY_C},
+ {{'A', 'B', '0', '4'}, YASL_KEY_V},
+ {{'A', 'B', '0', '5'}, YASL_KEY_B},
+ {{'A', 'B', '0', '6'}, YASL_KEY_N},
+ {{'A', 'B', '0', '7'}, YASL_KEY_M},
+ {{'A', 'B', '0', '8'}, YASL_KEY_COMMA},
+ {{'A', 'B', '0', '9'}, YASL_KEY_PERIOD},
+ {{'A', 'B', '1', '0'}, YASL_KEY_SLASH},
+ {{'R', 'T', 'S', 'H'}, YASL_KEY_RIGHT_SHIFT},
+ {{'L', 'C', 'T', 'L'}, YASL_KEY_LEFT_CONTROL},
+ {{'L', 'W', 'I', 'N'}, YASL_KEY_LEFT_SUPER},
+ {{'L', 'A', 'L', 'T'}, YASL_KEY_LEFT_ALT},
+ {{'S', 'P', 'C', 'E'}, YASL_KEY_SPACE},
+ {{'R', 'A', 'L', 'T'}, YASL_KEY_RIGHT_ALT},
+ {{'R', 'W', 'I', 'N'}, YASL_KEY_RIGHT_SUPER},
+ {{'C', 'O', 'M', 'P'}, YASL_KEY_MENU},
+ {{'R', 'C', 'T', 'L'}, YASL_KEY_RIGHT_CONTROL},
+ {{'E', 'S', 'C', 0}, YASL_KEY_ESCAPE},
+ {{'F', 'K', '0', '1'}, YASL_KEY_F1},
+ {{'F', 'K', '0', '2'}, YASL_KEY_F2},
+ {{'F', 'K', '0', '3'}, YASL_KEY_F3},
+ {{'F', 'K', '0', '4'}, YASL_KEY_F4},
+ {{'F', 'K', '0', '5'}, YASL_KEY_F5},
+ {{'F', 'K', '0', '6'}, YASL_KEY_F6},
+ {{'F', 'K', '0', '7'}, YASL_KEY_F7},
+ {{'F', 'K', '0', '8'}, YASL_KEY_F8},
+ {{'F', 'K', '0', '9'}, YASL_KEY_F9},
+ {{'F', 'K', '1', '0'}, YASL_KEY_F10},
+ {{'F', 'K', '1', '1'}, YASL_KEY_F11},
+ {{'F', 'K', '1', '2'}, YASL_KEY_F12},
+ {{'P', 'R', 'S', 'C'}, YASL_KEY_PRINT_SCREEN},
+ {{'S', 'C', 'L', 'K'}, YASL_KEY_SCROLL_LOCK},
+ {{'P', 'A', 'U', 'S'}, YASL_KEY_PAUSE},
+ {{'I', 'N', 'S', 0}, YASL_KEY_INSERT},
+ {{'H', 'O', 'M', 'E'}, YASL_KEY_HOME},
+ {{'P', 'G', 'U', 'P'}, YASL_KEY_PAGE_UP},
+ {{'D', 'E', 'L', 'E'}, YASL_KEY_DELETE},
+ {{'E', 'N', 'D', 0}, YASL_KEY_END},
+ {{'P', 'G', 'D', 'N'}, YASL_KEY_PAGE_DOWN},
+ {{'U', 'P', 0, 0}, YASL_KEY_UP},
+ {{'L', 'E', 'F', 'T'}, YASL_KEY_LEFT},
+ {{'D', 'O', 'W', 'N'}, YASL_KEY_DOWN},
+ {{'R', 'G', 'H', 'T'}, YASL_KEY_RIGHT},
+ {{'N', 'M', 'L', 'K'}, YASL_KEY_NUM_LOCK},
+ {{'K', 'P', 'D', 'V'}, YASL_KEY_KP_DIVIDE},
+ {{'K', 'P', 'M', 'U'}, YASL_KEY_KP_MULTIPLY},
+ {{'K', 'P', 'S', 'U'}, YASL_KEY_KP_SUBTRACT},
+ {{'K', 'P', '7', 0}, YASL_KEY_KP_7},
+ {{'K', 'P', '8', 0}, YASL_KEY_KP_8},
+ {{'K', 'P', '9', 0}, YASL_KEY_KP_9},
+ {{'K', 'P', 'A', 'D'}, YASL_KEY_KP_ADD},
+ {{'K', 'P', '4', 0}, YASL_KEY_KP_4},
+ {{'K', 'P', '5', 0}, YASL_KEY_KP_5},
+ {{'K', 'P', '6', 0}, YASL_KEY_KP_6},
+ {{'K', 'P', '1', 0}, YASL_KEY_KP_1},
+ {{'K', 'P', '2', 0}, YASL_KEY_KP_2},
+ {{'K', 'P', '3', 0}, YASL_KEY_KP_3},
+ {{'K', 'P', 'E', 'N'}, YASL_KEY_KP_ENTER},
+ {{'K', 'P', '0', 0}, YASL_KEY_KP_0},
+ {{'K', 'P', 'D', 'L'}, YASL_KEY_KP_DECIMAL},
+ {{'K', 'P', 'E', 'Q'}, YASL_KEY_KP_EQUAL},
+ {{'F', 'K', '1', '3'}, YASL_KEY_F13},
+ {{'F', 'K', '1', '4'}, YASL_KEY_F14},
+ {{'F', 'K', '1', '5'}, YASL_KEY_F15},
+ {{'F', 'K', '1', '6'}, YASL_KEY_F16},
+ {{'F', 'K', '1', '7'}, YASL_KEY_F17},
+ {{'F', 'K', '1', '8'}, YASL_KEY_F18},
+ {{'F', 'K', '1', '9'}, YASL_KEY_F19},
+ {{'F', 'K', '2', '0'}, YASL_KEY_F20},
+ {{'F', 'K', '2', '1'}, YASL_KEY_F21},
+ {{'F', 'K', '2', '2'}, YASL_KEY_F22},
+ {{'F', 'K', '2', '3'}, YASL_KEY_F23},
+ {{'F', 'K', '2', '4'}, YASL_KEY_F24},
+ {{'H', 'K', 'T', 'G'}, YASL_KEY_KANA},
+ {{'A', 'B', '1', '1'}, YASL_KEY_RO},
+ {{'H', 'E', 'N', 'K'}, YASL_KEY_CONVERT},
+ {{'M', 'U', 'H', 'E'}, YASL_KEY_NONCONVERT},
+ {{'A', 'E', '1', '3'}, YASL_KEY_YEN},
+ {{'M', 'U', 'T', 'E'}, YASL_KEY_MUTE},
+ {{'I', '1', '2', '9'}, YASL_KEY_KP_COMMA},
+ };
+ for (size_t i = 0; i < sizeof(keys) / sizeof(keys[0]); i++)
+ if (memcmp(keys[i].name, name, 4) == 0) return keys[i].key;
+ return YASL_KEY_UNKNOWN;
+}
diff --git a/src/platform/x11/keymap.h b/src/platform/x11/keymap.h
new file mode 100644
index 0000000..2ec4295
--- /dev/null
+++ b/src/platform/x11/keymap.h
@@ -0,0 +1,8 @@
+#ifndef YASL_X11_KEYMAP_H
+#define YASL_X11_KEYMAP_H
+
+#include "yasl/yasl.h"
+
+enum yasl_key yasl_key_from_xkb_name(const char name[4]);
+
+#endif
diff --git a/src/platform/x11/meson.build b/src/platform/x11/meson.build
new file mode 100644
index 0000000..6b85e46
--- /dev/null
+++ b/src/platform/x11/meson.build
@@ -0,0 +1 @@
+sources += files('window.c', 'keymap.c', 'native.c')
diff --git a/src/platform/x11/native.c b/src/platform/x11/native.c
new file mode 100644
index 0000000..249adec
--- /dev/null
+++ b/src/platform/x11/native.c
@@ -0,0 +1,14 @@
+#include "common/backend.h"
+#include "yasl/native/x11.h"
+
+Display *yasl_x11_display_get_display(struct yasl_display *d)
+{
+ return (d && yasl_display_backend(d) == YASL_BACKEND_X11) ?
+ (Display *)yasl_display_get_native_handle(d) : NULL;
+}
+
+uintptr_t yasl_x11_surface_get_window(struct yasl_surface *s)
+{
+ return (s && s->display && yasl_display_backend(s->display) == YASL_BACKEND_X11) ?
+ (uintptr_t)yasl_surface_get_native_handle(s) : 0;
+}
diff --git a/src/x11/window.c b/src/platform/x11/window.c
index c00a449..7891fff 100644
--- a/src/x11/window.c
+++ b/src/platform/x11/window.c
@@ -3,6 +3,7 @@
#include "common/backend.h"
#include "common/input.h"
#include "common/keyboard.h"
+#include "keymap.h"
#include "common/utf8.h"
#include "common/timing.h"
@@ -51,7 +52,7 @@ struct x11_surface {
bool shm_active;
XShmSegmentInfo shm_info;
struct yasl_vector2i size;
- const struct yasl_surface_cbs *cbs;
+ const struct yasl_window_cbs *cbs;
void *ud;
struct input_queue input;
struct yasl_frame frame;
@@ -625,11 +626,11 @@ static void surface_destroy(struct yasl_surface *base)
}
static void set_callbacks(struct yasl_surface *base,
- const struct yasl_surface_cbs *cbs, void *ud)
+ const struct yasl_window_cbs *cbs, void *ud)
{
struct x11_surface *s = (struct x11_surface *)base;
if (s->destroyed) return;
- s->base.callbacks = cbs ? *cbs : (struct yasl_surface_cbs){0};
+ s->base.callbacks = cbs ? *cbs : (struct yasl_window_cbs){0};
s->cbs = &s->base.callbacks;
s->ud = ud;
}
@@ -658,7 +659,7 @@ static void net_message(struct x11_surface *s, Atom type,
}
static struct yasl_surface *create_toplevel(struct yasl_display *base,
- const struct yasl_surface_spec *spec, void *graphics_device)
+ const struct yasl_window_spec *spec, void *graphics_device)
{
(void)graphics_device;
if (!spec) return NULL;
diff --git a/src/x11/meson.build b/src/x11/meson.build
deleted file mode 100644
index e1a38f0..0000000
--- a/src/x11/meson.build
+++ /dev/null
@@ -1 +0,0 @@
-sources += files('window.c')
diff --git a/tests/benchmark.c b/tests/benchmark.c
index eecccc5..8cea45c 100644
--- a/tests/benchmark.c
+++ b/tests/benchmark.c
@@ -59,7 +59,7 @@ static void bench_surface_lookup(void) {
if (d) {
for (int i = 0; i < num_surfaces; i++) {
- struct yasl_surface_spec sspec = {
+ struct yasl_window_spec sspec = {
.title = "Benchmark",
.size = { .x = 320, .y = 240 },
};
@@ -99,7 +99,7 @@ static void bench_output_follow(void) {
struct yasl_display *d = yasl_display_open(NULL, &spec);
struct yasl_surface *s = NULL;
if (d) {
- struct yasl_surface_spec sspec = {
+ struct yasl_window_spec sspec = {
.title = "Benchmark",
.size = { .x = 320, .y = 240 },
};
@@ -209,7 +209,7 @@ static void bench_timers(void) {
static void bench_window_cold_create(void) {
const int iters = 200;
struct yasl_display_spec dspec = { .app_id = "org.yasl.bench.cold" };
- struct yasl_surface_spec sspec = {
+ struct yasl_window_spec sspec = {
.title = "Benchmark Cold",
.size = { .x = 320, .y = 240 },
};
@@ -252,7 +252,7 @@ static void bench_window_warm_create(void) {
return;
}
- struct yasl_surface_spec sspec = {
+ struct yasl_window_spec sspec = {
.title = "Benchmark Warm",
.size = { .x = 320, .y = 240 },
};
@@ -285,7 +285,7 @@ static void bench_window_shutdown_single(void) {
return;
}
- struct yasl_surface_spec sspec = {
+ struct yasl_window_spec sspec = {
.title = "Benchmark Shutdown Single",
.size = { .x = 320, .y = 240 },
};
@@ -321,7 +321,7 @@ static void bench_window_shutdown_all(void) {
return;
}
- struct yasl_surface_spec sspec = {
+ struct yasl_window_spec sspec = {
.title = "Benchmark Bulk Window",
.size = { .x = 320, .y = 240 },
};
@@ -367,7 +367,7 @@ static void bench_window_title_update(void) {
return;
}
- struct yasl_surface_spec sspec = {
+ struct yasl_window_spec sspec = {
.title = "Initial Title",
.size = { .x = 320, .y = 240 },
};
@@ -422,7 +422,7 @@ static void bench_window_resize(void) {
uint64_t t0 = get_time_ns();
int count = 0;
for (int i = 0; i < iters; i++) {
- struct yasl_surface_spec sspec = {
+ struct yasl_window_spec sspec = {
.title = "Resize Bench",
.size = sizes[i % num_sizes],
};
diff --git a/tests/cocoa/test_cursor.m b/tests/cocoa/test_cursor.m
index 7a328f2..aaca815 100644
--- a/tests/cocoa/test_cursor.m
+++ b/tests/cocoa/test_cursor.m
@@ -17,7 +17,7 @@ int main(void)
@autoreleasepool {
struct yasl_display *display = yasl_display_open(NULL, NULL);
assert(display);
- struct yasl_surface_spec spec = {.title = "Cursor test", .size = {320, 240}};
+ struct yasl_window_spec spec = {.title = "Cursor test", .size = {320, 240}};
struct yasl_surface *surface = yasl_surface_create_toplevel(display, &spec);
assert(surface);
NSWindow *window = (NSWindow *)yasl_surface_get_native_handle(surface);
diff --git a/tests/cocoa/test_keyboard.m b/tests/cocoa/test_keyboard.m
index 4854065..d6a1336 100644
--- a/tests/cocoa/test_keyboard.m
+++ b/tests/cocoa/test_keyboard.m
@@ -50,7 +50,7 @@ int main(void)
@autoreleasepool {
struct yasl_display *display = yasl_display_open(NULL, NULL);
assert(display);
- struct yasl_surface_spec spec = {.title = "Keyboard test", .size = {320, 240}};
+ struct yasl_window_spec spec = {.title = "Keyboard test", .size = {320, 240}};
struct yasl_surface *surface = yasl_surface_create_toplevel(display, &spec);
assert(surface);
NSWindow *window = (NSWindow *)yasl_surface_get_native_handle(surface);
diff --git a/tests/cocoa/test_native.c b/tests/cocoa/test_native.c
index 0c101dd..674513d 100644
--- a/tests/cocoa/test_native.c
+++ b/tests/cocoa/test_native.c
@@ -48,11 +48,14 @@ static void test_window(enum yasl_backend request, bool null_spec)
struct state state = {.display = yasl_display_open(NULL, null_spec ? NULL : &spec)};
assert(state.display);
assert(yasl_display_backend(state.display) == YASL_BACKEND_COCOA);
- struct yasl_surface_spec surface = {.title = "Native backend test", .size = {160, 100}};
+ struct yasl_window_cbs callbacks = {.draw = draw};
+ struct yasl_window_spec surface = {
+ .title = "Native backend test", .size = {160, 100},
+ .cbs = &callbacks, .ud = &state,
+ };
state.surface = yasl_surface_create_toplevel(state.display, &surface);
assert(state.surface);
- struct yasl_surface_cbs callbacks = {.draw = draw};
- yasl_surface_set_callbacks(state.surface, &callbacks, &state);
+ assert(!state.draws);
callbacks.draw = NULL;
yasl_surface_schedule_redraw(state.surface);
uint64_t deadline = yasl_loop_now_ns() + 3000000000ull;
diff --git a/tests/cocoa/test_ownership.m b/tests/cocoa/test_ownership.m
index 2b2f52d..4e3bbd6 100644
--- a/tests/cocoa/test_ownership.m
+++ b/tests/cocoa/test_ownership.m
@@ -10,7 +10,7 @@ int main(void)
{
struct yasl_display *d = yasl_display_open(NULL, NULL);
assert(d);
- struct yasl_surface_spec spec = {.title = "Ownership test", .size = {160, 100}};
+ struct yasl_window_spec spec = {.title = "Ownership test", .size = {160, 100}};
struct yasl_surface *s = yasl_surface_create_toplevel(d, &spec);
assert(s);
assert(yasl_display_get_native_handle(d) == (void *)NSApp);
diff --git a/tests/cocoa/test_tablet.m b/tests/cocoa/test_tablet.m
index f1489a1..ed6dc64 100644
--- a/tests/cocoa/test_tablet.m
+++ b/tests/cocoa/test_tablet.m
@@ -49,7 +49,7 @@ int main(void)
@autoreleasepool {
struct yasl_display *display = yasl_display_open(NULL, NULL);
assert(display && (yasl_display_caps(display) & YASL_CAP_TABLET));
- struct yasl_surface_spec spec = {.title = "Tablet test", .size = {320, 240}};
+ struct yasl_window_spec spec = {.title = "Tablet test", .size = {320, 240}};
struct yasl_surface *surface = yasl_surface_create_toplevel(display, &spec);
assert(surface);
NSWindow *window = (NSWindow *)yasl_surface_get_native_handle(surface);
diff --git a/tests/common/test_app.c b/tests/common/test_app.c
index 661620c..23c9a93 100644
--- a/tests/common/test_app.c
+++ b/tests/common/test_app.c
@@ -43,7 +43,7 @@ static int on_init(void *ud, struct yasl_display *d)
state->display = d;
state->init_called = true;
- struct yasl_surface_spec spec = {
+ struct yasl_window_spec spec = {
.title = "App Runner Test",
.size = {320, 240},
};
diff --git a/tests/common/test_backends.c b/tests/common/test_backends.c
index cf5b1f9..28f2f52 100644
--- a/tests/common/test_backends.c
+++ b/tests/common/test_backends.c
@@ -121,13 +121,13 @@ static void close_window(struct yasl_surface *s, void *ud)
w->surface = NULL;
}
-static const struct yasl_surface_cbs callbacks = {
+static const struct yasl_window_cbs callbacks = {
.draw = draw, .configure = configure, .close = close_window,
};
static void attach(struct window *w)
{
- struct yasl_surface_cbs temporary = callbacks;
+ struct yasl_window_cbs temporary = callbacks;
yasl_surface_set_callbacks(w->surface, &temporary, w);
temporary.draw = NULL;
temporary.configure = NULL;
@@ -136,7 +136,7 @@ static void attach(struct window *w)
static struct window create(struct yasl_display *d)
{
- struct yasl_surface_spec spec = {.title = "Backend test", .size = {160, 100}};
+ struct yasl_window_spec spec = {.title = "Backend test", .size = {160, 100}};
struct yasl_surface *s = yasl_surface_create_toplevel(d, &spec);
assert(s);
assert(yasl_display_get_native_handle(d));
@@ -146,6 +146,27 @@ static struct window create(struct yasl_display *d)
return (struct window){.surface = s, .display = d};
}
+static void test_window_spec(struct yasl_loop *loop, struct yasl_display *d)
+{
+ struct window w = {.display = d, .destroy_on_draw = true};
+ {
+ struct yasl_window_cbs temporary = callbacks;
+ struct yasl_window_spec spec = {
+ .title = "Callbacks at creation", .size = {160, 100},
+ .cbs = &temporary, .ud = &w,
+ };
+ w.surface = yasl_surface_create_toplevel(d, &spec);
+ assert(w.surface);
+ assert(!w.draws && !w.configures && !w.closes);
+ /* Neither the spec nor its callback table needs to outlive creation. */
+ memset(&temporary, 0, sizeof(temporary));
+ memset(&spec, 0, sizeof(spec));
+ }
+ yasl_surface_schedule_redraw(w.surface);
+ pump(loop, d, NULL);
+ assert(w.draws == 1 && !w.surface);
+}
+
static void x11_behavior(struct yasl_loop *loop, struct yasl_display *d, struct window *w)
{
Display *native = yasl_display_get_native_handle(d);
@@ -371,6 +392,8 @@ int main(int argc, char **argv)
spec.backend = YASL_BACKEND_X11;
struct yasl_display *b = yasl_display_open(loop, &spec);
assert(a && b);
+ test_window_spec(loop, a);
+ test_window_spec(loop, b);
struct window wa = create(a), wb = create(b);
#if YASL_HAS_WAYLAND
assert(yasl_wayland_display_get_wl_display(a) != NULL);
diff --git a/tests/common/test_contracts.c b/tests/common/test_contracts.c
index 8580dd6..ac0065c 100644
--- a/tests/common/test_contracts.c
+++ b/tests/common/test_contracts.c
@@ -114,7 +114,7 @@ static void copy(struct yasl_display *d, enum yasl_selection sel, const char *te
{ (void)d; (void)sel; (void)text; copies++; }
static void paste(struct yasl_display *d, enum yasl_selection sel, struct yasl_surface *s)
{ (void)d; (void)sel; (void)s; pastes++; }
-static struct yasl_surface *create(struct yasl_display *d, const struct yasl_surface_spec *spec, void *graphics_device)
+static struct yasl_surface *create(struct yasl_display *d, const struct yasl_window_spec *spec, void *graphics_device)
{ (void)d; (void)spec; (void)graphics_device; creates++; return NULL; }
static void *native_device;
@@ -123,7 +123,7 @@ static struct yasl_surface native_surface;
static uint32_t native_caps(const struct yasl_display *d)
{ (void)d; return YASL_CAP_NATIVE_GRAPHICS; }
static struct yasl_surface *native_create(struct yasl_display *d,
- const struct yasl_surface_spec *spec, void *device)
+ const struct yasl_window_spec *spec, void *device)
{
(void)spec;
native_device = device;
@@ -144,7 +144,7 @@ static void test_native(void)
const struct yasl_backend_ops ops = {.display_caps = native_caps,
.surface_create_toplevel = native_create, .surface_get_native_frame = native_frame};
struct yasl_display d = {.ops = &ops};
- struct yasl_surface_spec spec = {.size = {100, 80}};
+ struct yasl_window_spec spec = {.size = {100, 80}};
assert(yasl_surface_create_toplevel(&d, &spec) == &native_surface);
assert(!native_device);
assert(yasl_surface_create_native(&d, &spec, &d) == &native_surface);
@@ -209,7 +209,7 @@ static void test_validation(void)
yasl_display_copy(&d, YASL_CLIPBOARD, "yes");
yasl_display_paste(&d, YASL_CLIPBOARD, &s);
assert(copies == 1 && pastes == 1);
- struct yasl_surface_spec spec = {.size = {100, 80}};
+ struct yasl_window_spec spec = {.size = {100, 80}};
assert(!yasl_surface_create_native(&d, &spec, &d) && errno == ENOTSUP);
assert(!yasl_surface_create_native(&d, &spec, NULL) && errno == EINVAL);
spec.size.x = 0;
@@ -257,7 +257,7 @@ static int dispatch_failure(struct yasl_display *d, int timeout)
{ (void)d; (void)timeout; return -1; }
static struct yasl_surface *create_failure(struct yasl_display *d,
- const struct yasl_surface_spec *spec, void *device)
+ const struct yasl_window_spec *spec, void *device)
{ (void)d; (void)spec; (void)device; return NULL; }
static int drag_starts;
@@ -310,7 +310,7 @@ static void test_errors(void)
d.ops = &ops;
errno = ERANGE;
assert(yasl_display_dispatch(&d, 0) == -1 && errno == EIO);
- struct yasl_surface_spec toplevel = {.size = {120, 80}};
+ struct yasl_window_spec toplevel = {.size = {120, 80}};
errno = ERANGE;
assert(!yasl_surface_create_toplevel(&d, &toplevel) && errno == ENODEV);
assert(yasl_display_drag_start(&d, &s, NULL, NULL, NULL));
diff --git a/tests/common/test_keyboard.c b/tests/common/test_keyboard.c
index 5a7f18e..f2fc8f2 100644
--- a/tests/common/test_keyboard.c
+++ b/tests/common/test_keyboard.c
@@ -1,5 +1,8 @@
#include "common/keyboard.h"
-#include "cocoa/keycodes.h"
+#include "platform/wayland/keymap.h"
+#include "platform/x11/keymap.h"
+#include "platform/cocoa/keymap.h"
+#include "platform/cocoa/keycodes.h"
#include <assert.h>
int main(void)
diff --git a/tests/common/test_timers.c b/tests/common/test_timers.c
index 4e95c5a..f321b2c 100644
--- a/tests/common/test_timers.c
+++ b/tests/common/test_timers.c
@@ -234,7 +234,7 @@ static void test_surface_timers(void)
assert(yasl_display_loop(d) == loop);
- struct yasl_surface_spec sspec = {
+ struct yasl_window_spec sspec = {
.title = "Timer Surface",
.size = { .x = 160, .y = 100 },
};
diff --git a/tests/meson.build b/tests/meson.build
index c06fcca..26bb5cb 100644
--- a/tests/meson.build
+++ b/tests/meson.build
@@ -79,7 +79,19 @@ contracts_test = executable(
)
test('contracts', contracts_test)
-keyboard_test = executable('yasl-keyboard-test', 'common/test_keyboard.c',
+# Exercise the SDK-independent mappings even when their backend is disabled.
+# Enabled backends already provide their mapping through yasl_dep.
+keyboard_test_sources = files('common/test_keyboard.c')
+if not has_wayland
+ keyboard_test_sources += files('../src/platform/wayland/keymap.c')
+endif
+if not has_x11
+ keyboard_test_sources += files('../src/platform/x11/keymap.c')
+endif
+if not has_cocoa
+ keyboard_test_sources += files('../src/platform/cocoa/keymap.c')
+endif
+keyboard_test = executable('yasl-keyboard-test', keyboard_test_sources,
include_directories: inc, dependencies: yasl_dep,
)
test('keyboard', keyboard_test)
diff --git a/tests/test_api.cpp b/tests/test_api.cpp
index 129a41e..c45932a 100644
--- a/tests/test_api.cpp
+++ b/tests/test_api.cpp
@@ -15,6 +15,14 @@
int main()
{
+ yasl_window_cbs callbacks{};
+ yasl_window_spec window{};
+ window.size = {640, 480};
+ window.cbs = &callbacks;
+ window.ud = &window;
+ assert(!yasl_surface_create_toplevel(nullptr, &window));
+ assert(!yasl_surface_create_native(nullptr, &window, &window));
+
yasl_timing timing = yasl_surface_timing(nullptr);
assert(timing.source == YASL_TIMING_UNKNOWN);
assert(yasl_scale_to_device(10.0, 240) == 20);
diff --git a/tests/test_lifecycle.c b/tests/test_lifecycle.c
index d04662f..c54abd0 100644
--- a/tests/test_lifecycle.c
+++ b/tests/test_lifecycle.c
@@ -47,7 +47,7 @@ static void test_display_lifecycle_standalone(void)
struct yasl_display *d = yasl_display_open(NULL, &spec);
if (!d) return; /* Headless CI without Wayland */
- struct yasl_surface_spec sspec = {
+ struct yasl_window_spec sspec = {
.title = "Test Window",
.size = { .x = 320, .y = 240 },
};
diff --git a/tests/wayland/test_app_input.c b/tests/wayland/test_app_input.c
index 24b8b64..2cacb5e 100644
--- a/tests/wayland/test_app_input.c
+++ b/tests/wayland/test_app_input.c
@@ -1,7 +1,7 @@
/* An input event callback that destroys its own surface. The app runner
* must not touch the surface's entry after the callback, and must not
* deliver the surface's remaining input. Needs a Wayland compositor. */
-#include "wayland/internal.h"
+#include "platform/wayland/internal.h"
#include "yasl/app.h"
#include <assert.h>
@@ -25,7 +25,7 @@ static int on_init(void *ud, struct yasl_display *d)
{
(void)ud;
struct yasl_surface *s = yasl_surface_create_toplevel(d,
- &(struct yasl_surface_spec){ .title = "App Input Test", .size = {64, 64} });
+ &(struct yasl_window_spec){ .title = "App Input Test", .size = {64, 64} });
assert(s);
push_key(s);
push_key(s);
diff --git a/tests/wayland/test_clipboard.c b/tests/wayland/test_clipboard.c
index 553e84d..825564e 100644
--- a/tests/wayland/test_clipboard.c
+++ b/tests/wayland/test_clipboard.c
@@ -1,4 +1,4 @@
-#include "../../src/wayland/clipboard.c"
+#include "../../src/platform/wayland/clipboard.c"
#include <assert.h>
struct received { int count; size_t len; char text[32]; };
diff --git a/tests/wayland/test_cursor.c b/tests/wayland/test_cursor.c
index f7a7ba7..a4a522e 100644
--- a/tests/wayland/test_cursor.c
+++ b/tests/wayland/test_cursor.c
@@ -1,4 +1,4 @@
-#include "wayland/internal.h"
+#include "platform/wayland/internal.h"
#include <assert.h>
/* Record cursor requests without a compositor or tablet hardware. */
@@ -47,7 +47,7 @@ static uint32_t pointer_version(struct wl_pointer *pointer)
#define zwp_tablet_tool_v2_set_cursor tool_cursor
#define wp_cursor_shape_device_v1_set_shape cursor_shape
#define wl_pointer_get_version pointer_version
-#include "../../src/wayland/pointer.c"
+#include "../../src/platform/wayland/pointer.c"
int main(void)
{
diff --git a/tests/wayland/test_input.c b/tests/wayland/test_input.c
index 7b91a9d..feff2f3 100644
--- a/tests/wayland/test_input.c
+++ b/tests/wayland/test_input.c
@@ -1,4 +1,4 @@
-#include "wayland/internal.h"
+#include "platform/wayland/internal.h"
#include <assert.h>
static void test_popup_bounds(void)
diff --git a/tests/wayland/test_keyboard.c b/tests/wayland/test_keyboard.c
index dbe0a94..6921322 100644
--- a/tests/wayland/test_keyboard.c
+++ b/tests/wayland/test_keyboard.c
@@ -1,4 +1,4 @@
-#include "../../src/wayland/keyboard.c"
+#include "../../src/platform/wayland/keyboard.c"
#include <assert.h>
static struct yasl_input_event next(struct wayland_surface *w, enum yasl_input_kind kind)
diff --git a/tests/wayland/test_tablet.c b/tests/wayland/test_tablet.c
index f8982b0..8723df2 100644
--- a/tests/wayland/test_tablet.c
+++ b/tests/wayland/test_tablet.c
@@ -1,4 +1,4 @@
-#include "../../src/wayland/pointer.c"
+#include "../../src/platform/wayland/pointer.c"
#include <assert.h>
static struct yasl_mouse_event next(struct wayland_surface *surface)
diff --git a/tests/x11/test_input.c b/tests/x11/test_input.c
index af45e76..80a6451 100644
--- a/tests/x11/test_input.c
+++ b/tests/x11/test_input.c
@@ -1,6 +1,6 @@
/* An isolated real X server supplies the keymap; disabling this surface's XIC
* deliberately exercises text insertion when no input method is available. */
-#include "../../src/x11/window.c"
+#include "../../src/platform/x11/window.c"
static void check_selection_encoding(struct x11_display *d, struct x11_surface *s)
{
@@ -71,7 +71,7 @@ int main(void)
struct yasl_display *base = yasl_display_open(NULL, &ds);
assert(base);
struct x11_display *d = (struct x11_display *)base;
- struct yasl_surface_spec spec = {.title = "Keyboard fallback", .size = {100, 100}};
+ struct yasl_window_spec spec = {.title = "Keyboard fallback", .size = {100, 100}};
struct yasl_surface *surface = yasl_surface_create_toplevel(base, &spec);
assert(surface);
struct x11_surface *s = (struct x11_surface *)surface;
diff --git a/tests/x11/test_tablet.c b/tests/x11/test_tablet.c
index ba815cb..12c183e 100644
--- a/tests/x11/test_tablet.c
+++ b/tests/x11/test_tablet.c
@@ -1,5 +1,5 @@
/* Exercise native XI2 samples through the backend and public input queue. */
-#include "../../src/x11/window.c"
+#include "../../src/platform/x11/window.c"
static struct yasl_mouse_event next(struct x11_surface *surface)
{
@@ -113,8 +113,8 @@ static void test_x11_gaps(struct x11_display *d, struct x11_surface *s)
struct drag_test_recorder rec1 = {0};
struct drag_test_recorder rec2 = {0};
- struct yasl_surface_cbs cbs1 = {.drag = on_test_drag};
- struct yasl_surface_cbs cbs2 = {.drag = on_test_drag};
+ struct yasl_window_cbs cbs1 = {.drag = on_test_drag};
+ struct yasl_window_cbs cbs2 = {.drag = on_test_drag};
set_callbacks(&s->base, &cbs1, &rec1);
set_callbacks(&s2.base, &cbs2, &rec2);
diff --git a/tests/x11/test_tablet_native.c b/tests/x11/test_tablet_native.c
index 0ddb6d8..6e7eeb4 100644
--- a/tests/x11/test_tablet_native.c
+++ b/tests/x11/test_tablet_native.c
@@ -108,10 +108,10 @@ int main(int argc, char **argv)
struct yasl_display_spec ds = {.backend = YASL_BACKEND_X11};
struct yasl_display *display = yasl_display_open(NULL, &ds);
assert(display && (yasl_display_caps(display) & YASL_CAP_TABLET));
- struct yasl_surface_spec ss = {.title = "YASL native pressure test", .size = {500, 400}};
+ struct yasl_window_spec ss = {.title = "YASL native pressure test", .size = {500, 400}};
struct yasl_surface *surface = yasl_surface_create_toplevel(display, &ss);
assert(surface);
- struct yasl_surface_cbs cbs = {.draw = draw, .configure = configure};
+ struct yasl_window_cbs cbs = {.draw = draw, .configure = configure};
yasl_surface_set_callbacks(surface, &cbs, &app);
yasl_surface_schedule_redraw(surface);
Display *x = yasl_display_get_native_handle(display);
diff --git a/yasl-gaps-report.md b/yasl-gaps-report.md
index 0268913..fa09a04 100644
--- a/yasl-gaps-report.md
+++ b/yasl-gaps-report.md
@@ -22,8 +22,8 @@ yasl has these target events:
Only the Wayland backend sends them:
-- `src/wayland/clipboard.c`
-- `src/wayland/drag.c`
+- `src/platform/wayland/clipboard.c`
+- `src/platform/wayland/drag.c`
X11 and Cocoa send only the source-side end (`YASL_DRAG_DROPPED` or
`YASL_DRAG_CANCELLED`).
@@ -36,8 +36,8 @@ Needed in yasl: send the target events from the X11 and Cocoa drag code.
### 2. Drag images are ignored on X11 and Cocoa (yasl)
-- X11: `drag_start` in `src/x11/window.c` has `(void)image;`.
-- Cocoa: `cocoa_display_drag_start` in `src/cocoa/window.m` has `(void)image;`.
+- X11: `drag_start` in `src/platform/x11/window.c` has `(void)image;`.
+- Cocoa: `cocoa_display_drag_start` in `src/platform/cocoa/window.m` has `(void)image;`.
Effect: the drag image is not shown. The project does not use the image on
these backends today, because they report `YASL_CAP_DRAG_CARRY`. The
@@ -53,8 +53,8 @@ Needed in yasl: draw the image, or document that it is unsupported.
`YASL_INPUT_DROP_FILES` is sent only by:
- `src/common/input.c` (helper)
-- `src/cocoa/window.m`
-- `src/wayland/pointer.c`
+- `src/platform/cocoa/window.m`
+- `src/platform/wayland/pointer.c`
Effect: dropping files onto a terminal window does nothing on X11.